diff --git a/app/pods/components/add-soundcloud-sound-modal/component.js b/app/pods/components/add-soundcloud-sound-modal/component.js index b489bd8..8907117 100644 --- a/app/pods/components/add-soundcloud-sound-modal/component.js +++ b/app/pods/components/add-soundcloud-sound-modal/component.js @@ -2,11 +2,31 @@ import Em from 'ember'; export default Em.Component.extend({ actions: { - close: function () { + close () { this.sendAction(); + }, + add (){ + this.sendAction('action', this.get('url')); } }, + + url: null, + + onIsShowingModalChange: function(){ + this.set('url', null); + }.observes('isShowingModal'), + + didInsertElement: function() { + var self = this; + + Em.$(document).keypress(function(event) { + if(!self.get('saveDisabled') && event.which === 13) { + self.send('add'); + } + }); + }, + saveDisabled: function(){ - return Em.isNone(this.get('groupName')) || Em.isEmpty(this.get('selectedLights')) || Em.isEmpty(this.get('groupName').trim()); - }.property('groupName', 'selectedLights.[]') + return Em.isEmpty(this.get('url').trim()) + }.property('url') }); diff --git a/app/pods/components/add-soundcloud-sound-modal/template.hbs b/app/pods/components/add-soundcloud-sound-modal/template.hbs index fce97f1..d3b5a59 100644 --- a/app/pods/components/add-soundcloud-sound-modal/template.hbs +++ b/app/pods/components/add-soundcloud-sound-modal/template.hbs @@ -1,10 +1,13 @@ {{#if isShowingModal}} - {{#modal-dialog close="close" alignment="center" translucentOverlay=true}} + {{#modal-dialog close="close" alignment="center" translucentOverlay=true attachment="center" targetAttachment="center"}} -

Enter a SoundCloud URL for a track or a playlist/set

+

Enter a SoundCloud track or playlist/set URL

+

( ex. https://soundcloud.com/mrsuicidesheep/danrell-x-smaland-hostage )

+ + {{paper-input label="SoundCloud URL" icon="search" value=url}} {{#paper-button action="close"}}Close{{/paper-button}} - {{#paper-button class="pull-right" action="delete" primary=true}}Add Music{{/paper-button}} + {{#paper-button class="pull-right" action="add" primary=true}}Add Music{{/paper-button}} {{/modal-dialog}} {{/if}} \ No newline at end of file diff --git a/app/pods/components/music-tab/component.js b/app/pods/components/music-tab/component.js index f013467..dad3243 100644 --- a/app/pods/components/music-tab/component.js +++ b/app/pods/components/music-tab/component.js @@ -16,13 +16,46 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, { }.observes('active'), actions: { - toggleIsShowingAddSoundCloudModal: function() { + handleNewSoundCloudURL(URL){ + SC.resolve(URL).then((resultObj)=>{ + var processResult = (result)=>{ + if(result.kind === 'user'){ + this.get('notify').alert({html: this.get('scUserNotSupportedHtml')}); + } else if(result.kind === 'track') { + if(result.streamable === true){ + this.get('playQueue').pushObject({url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), artist: result.user.username, artistUrl: result.user.permalink_url, title: result.title, artworkUrl: result.artwork_url, fromSoundCloud: true }); + // make sure to init the first song + if(this.get('playQueue').length > 0 && this.get('playQueuePointer') === -1){ + this.send('goToSong', 0, true); + } + } else { + this.get('notify').alert({html: this.get('notStreamableHtml')(result.title)}); + } + } else if(result.kind === 'playlist'){ + if(result.streamable === true){ + result.tracks.forEach(processResult); + } else { + this.get('notify').alert({html: this.get('notStreamableHtml')(result.title)}); + } + } + }; + + if(resultObj instanceof Array){ + resultObj.forEach(processResult); + } else { + processResult(resultObj); + } + }); + + this.set('isShowingAddSoundCloudModal', false); + }, + toggleIsShowingAddSoundCloudModal() { this.toggleProperty('isShowingAddSoundCloudModal'); }, - toggleDimming: function(){ + toggleDimming(){ this.changePlayerControl('dimmerEnabled', !this.get('dimmerEnabled')); }, - useLocalAudio: function(){ + useLocalAudio(){ var audioStream = this.get('audioStream'); this.changePlayerControl('audioMode', 0); @@ -56,6 +89,7 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, { goToSong(index, playSong){ var dancer = this.get('dancer'), audio = new Audio(); audio.src = this.get('playQueue')[index].url; + audio.crossOrigin = "anonymous"; if(dancer.audio) { this.clearCurrentAudio(true); @@ -290,7 +324,10 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, { this.saveSongBeatPreferences(); } - this.get('kick').set(options); + // filter the threshold manually + if(name !== 'threshold'){ + this.get('kick').set(options); + } } this.get('storage').set('huegasm.' + name, value); @@ -428,70 +465,82 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, { }, simulateKick(mag) { - var activeLights = this.get('activeLights'), - transitionTime = this.get('transitionTime') * 10, - onBeatBriAndColor = this.get('onBeatBriAndColor'), - self = this, - color = null, - stimulateLight = function (light, brightness, hue) { - var options = {'bri': brightness, 'transitiontime': transitionTime}; + var validBeat = (this.get('threshold') < mag); - if(!Em.isNone(hue)) { - options.hue = hue; - } + if(validBeat){ + var activeLights = this.get('activeLights'), + transitionTime = this.get('transitionTime') * 10, + onBeatBriAndColor = this.get('onBeatBriAndColor'), + self = this, + color = null, + stimulateLight = function (light, brightness, hue) { + var options = {'bri': brightness, 'transitiontime': transitionTime}; - Em.$.ajax(self.get('apiURL') + '/lights/' + light + '/state', { - data: JSON.stringify(options), - contentType: 'application/json', - type: 'PUT' - }); - }; - - if(activeLights.length > 0){ - var lastLightBopIndex = this.get('lastLightBopIndex'), - randomTransition = this.get('randomTransition'), - lightBopIndex, - light; - - if(randomTransition) { - lightBopIndex = Math.floor(Math.random() * activeLights.length); - - // let's try not to select the same light twice in a row - if(activeLights.length > 1) { - while(lightBopIndex === lastLightBopIndex) { - lightBopIndex = Math.floor(Math.random() * activeLights.length); + if(!Em.isNone(hue)) { + options.hue = hue; } + + Em.$.ajax(self.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify(options), + contentType: 'application/json', + type: 'PUT' + }); + }; + + if(activeLights.length > 0){ + var lastLightBopIndex = this.get('lastLightBopIndex'), + randomTransition = this.get('randomTransition'), + lightBopIndex, + light; + + if(randomTransition) { + lightBopIndex = Math.floor(Math.random() * activeLights.length); + + // let's try not to select the same light twice in a row + if(activeLights.length > 1) { + while(lightBopIndex === lastLightBopIndex) { + lightBopIndex = Math.floor(Math.random() * activeLights.length); + } + } + } else { + lightBopIndex = (lastLightBopIndex + 1) % activeLights.length; } - } else { - lightBopIndex = (lastLightBopIndex + 1) % activeLights.length; + + light = activeLights[lightBopIndex]; + this.set('lastLightBopIndex', lightBopIndex); + + if(onBeatBriAndColor) { + color = Math.floor(Math.random() * 65535); + } + + stimulateLight(light, 254, color); + setTimeout(stimulateLight, transitionTime + 50, light, 1); + + this.set('paused', true); + + setTimeout(function () { + self.set('paused', false); + }, 150); } - - light = activeLights[lightBopIndex]; - this.set('lastLightBopIndex', lightBopIndex); - - if(onBeatBriAndColor) { - color = Math.floor(Math.random() * 65535); - } - - stimulateLight(light, 254, color); - setTimeout(stimulateLight, transitionTime + 50, light, 1); - - this.set('paused', true); - - setTimeout(function () { - self.set('paused', false); - }, 150); } //work the music beat area if(this.get('speakerViewed')){ - // simulate the speaker vibration by running a CSS animation on it - Em.$('#beatSpeakerCenterOuter').removeClass('vibrateOuter').prop('offsetWidth', Em.$('#beatSpeakerCenterOuter').prop('offsetWidth')).addClass('vibrateOuter'); - Em.$('#beatSpeakerCenterInner').removeClass('vibrateInner').prop('offsetWidth', Em.$('#beatSpeakerCenterInner').prop('offsetWidth')).addClass('vibrateInner'); + if(validBeat){ + // simulate the speaker vibration by running a CSS animation on it + Em.$('#beatSpeakerCenterOuter').removeClass('vibrateOuter').prop('offsetWidth', Em.$('#beatSpeakerCenterOuter').prop('offsetWidth')).addClass('vibrateOuter'); + Em.$('#beatSpeakerCenterInner').removeClass('vibrateInner').prop('offsetWidth', Em.$('#beatSpeakerCenterInner').prop('offsetWidth')).addClass('vibrateInner'); + } } else { - var beatHistory = self.get('beatHistory'), - maxSize = self.get('maxBeatHistorySize'); - beatHistory.unshiftObjects('Beat intesity of ' + mag.toFixed(3) + ' at ' + self.get('timeElapsedTxt') + ''); + var beatHistory = this.get('beatHistory'), + debugFiltered = this.get('debugFiltered'), + maxSize = this.get('maxBeatHistorySize'), + html = 'Beat intesity of ' + mag.toFixed(3) + ' at ' + this.get('timeElapsedTxt') + ''; + + if(!validBeat && debugFiltered){ + html = '' + html + ' ( filtered ) '; + } + beatHistory.unshiftObjects(html); if(beatHistory.length > maxSize){ beatHistory.popObject(); @@ -505,11 +554,10 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, { var dancer = new Dancer(), storage = new window.Locally.Store(), self = this, - threshold = this.get('threshold'), decay = this.get('decay'), frequency = this.get('frequency'), kick = dancer.createKick({ - threshold: threshold, + threshold: this.beatOptions.threshold.range.min, decay: decay, frequency: frequency, onKick: function (mag) { @@ -566,7 +614,7 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, { }); SC.initialize({ - client_id: 'aeec0034f58ecd85c2bd1deaecc41594' + client_id: this.get('SC_CLIENT_ID') }); }, diff --git a/app/pods/components/music-tab/mixins/music-tab.js b/app/pods/components/music-tab/mixins/music-tab.js index 5e19456..4287361 100644 --- a/app/pods/components/music-tab/mixins/music-tab.js +++ b/app/pods/components/music-tab/mixins/music-tab.js @@ -7,7 +7,7 @@ export default Em.Mixin.create({ beatOptions: { threshold: { - range: {min: 0.1, max: 0.9}, + range: {min: 0.1, max: 1.0}, step: 0.01, defaultValue: 0.3, pips: { @@ -72,7 +72,7 @@ export default Em.Mixin.create({ playQueuePointer: -1, playQueue: Em.A(), beatHistory: Em.A(), - maxBeatHistorySize: 30, + maxBeatHistorySize: 100, timeElapsed: 0, timeTotal: 0, lastLightBopIndex: 0, @@ -93,7 +93,12 @@ export default Em.Mixin.create({ dimmerEnabled: false, isShowingAddSoundCloudModal: false, + SC_CLIENT_ID: 'aeec0034f58ecd85c2bd1deaecc41594', notFoundHtml: '', + scUserNotSupportedHtml: '', + notStreamableHtml: function(fileName){ + return ''; + }, playQueueEmpty: Em.computed.empty('playQueue'), playQueueNotEmpty: Em.computed.notEmpty('playQueue'), @@ -131,6 +136,7 @@ export default Em.Mixin.create({ }.property('playing'), speakerViewed: true, + debugFiltered: true, speakerLabel: function() { if(this.get('speakerViewed')){ return 'Speaker View'; @@ -138,6 +144,13 @@ export default Em.Mixin.create({ return 'Debug View'; } }.property('speakerViewed'), + debugFilteredText: function(){ + if(this.get('debugFiltered')){ + return 'View Filtered'; + } else { + return 'Hide Filtered'; + } + }.property('debugFiltered'), randomTransition: true, randomTransitionLabel: function() { diff --git a/app/pods/components/music-tab/template.hbs b/app/pods/components/music-tab/template.hbs index 28e1ef5..be9d33d 100644 --- a/app/pods/components/music-tab/template.hbs +++ b/app/pods/components/music-tab/template.hbs @@ -102,83 +102,87 @@ {{/if}}
-
+
{{threshold}}
{{range-slider start=threshold orientation="vertical" step=beatOptions.threshold.step range=beatOptions.threshold.range slide="thresholdChanged" pips=beatOptions.threshold.pips}} - Max. Intensity + Treshold
-
+{{!-- +
{{decay}}
- {{range-slider start=decay orientation="vertical" step=beatOptions.decay.step range=beatOptions.decay.range slide="decayChanged" pips=beatOptions.decay.pips}} + {{range-slider start=decay orientation="vertical" step=beatOptions.decay.step range=beatOptions.decay.range slide="decayChanged" pips=beatOptions.decay.pips}} Decay Rate -
- -
-
[{{#each frequency as |item index|}}{{item}}{{#unless index}} - ,{{/unless}}{{/each}} - ] -
- {{range-slider start=frequency orientation="vertical" step=beatOptions.frequency.step range=beatOptions.frequency.range connect=true slide="frequencyChanged" pips=beatOptions.frequency.pips}} - Frequency Range -
- -
-
{{transitionTime}} sec
- {{range-slider start=transitionTime orientation="vertical" step=beatOptions.transitionTime.step range=beatOptions.transitionTime.range slide="transitionTimeChanged" pips=beatOptions.transitionTime.pips}} - Transition Time -
+{{/if}} + --}} -
-
- {{#paper-button raised=true warn=true action="defaultControls"}}Default{{/paper-button}} -
-
- {{#paper-switch checked=randomTransition disabled=trial}}{{randomTransitionLabel}}{{/paper-switch}} -
-
- {{#paper-switch checked=onBeatBriAndColor disabled=trial}} {{onBeatBriAndColorLabel}}{{/paper-switch}} -
+
+
[{{#each frequency as |item index|}}{{item}}{{#unless index}} + ,{{/unless}}{{/each}} + ] +
+ {{range-slider start=frequency orientation="vertical" step=beatOptions.frequency.step range=beatOptions.frequency.range connect=true slide="frequencyChanged" pips=beatOptions.frequency.pips}} + Frequency Range +
+ +
+
{{transitionTime}} sec
+ {{range-slider start=transitionTime orientation="vertical" step=beatOptions.transitionTime.step range=beatOptions.transitionTime.range slide="transitionTimeChanged" pips=beatOptions.transitionTime.pips}} + Transition Time +
+
+ +
+
+ {{#paper-button raised=true warn=true action="defaultControls"}}Default{{/paper-button}} +
+
+ {{#paper-switch checked=randomTransition disabled=trial}}{{randomTransitionLabel}}{{/paper-switch}} +
+
+ {{#paper-switch checked=onBeatBriAndColor disabled=trial}} {{onBeatBriAndColorLabel}}{{/paper-switch}} +
+
+
+ +
+{{#if speakerViewed}} +
+
+
+
+
+
+
+
+
+ +
+
+
+{{else}} +
+ {{#each beatHistory as |item|}} +

{{{item}}}

+ {{/each}} +
+ {{#paper-switch checked=debugFiltered class="debugFilteredSwitch"}} {{debugFilteredText}} {{/paper-switch}} +{{/if}} -
- {{#if speakerViewed}} -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- {{else}} -
- {{#each beatHistory as |item|}} -

{{{item}}}

- {{/each}} -
- {{/if}} - - {{#paper-switch checked=speakerViewed}} {{speakerLabel}} {{/paper-switch}} -
+{{#paper-switch checked=speakerViewed class="speakerSwitch"}} {{speakerLabel}} {{/paper-switch}} +
{{ember-notify closeAfter=5000}}
-{{add-soundcloud-sound-modal action="toggleIsShowingAddSoundCloudModal" isShowingModal=isShowingAddSoundCloudModal}} \ No newline at end of file +{{add-soundcloud-sound-modal action="handleNewSoundCloudURL" isShowingModal=isShowingAddSoundCloudModal}} \ No newline at end of file diff --git a/app/styles/app.scss b/app/styles/app.scss index 4ca5eaa..18cfce4 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -711,8 +711,16 @@ md-switch.md-default-theme.md-checked .md-thumb { -webkit-transform: translate3d(0, 0, 0); // hack for chrome to force hardware acceleration and stop flickering padding: 0; height: $playerBottomHeight; - md-switch { + .speakerSwitch { top: 0; + left: 0; + position: absolute; + margin-left: 0; + margin-bottom: 10px; + } + .debugFilteredSwitch { + top: 0; + right: 0; position: absolute; margin-left: 0; margin-bottom: 10px; @@ -738,11 +746,17 @@ md-switch.md-default-theme.md-checked .md-thumb { height: 85%; background-color: white; border-radius: 10px; - width: 285px; + width: 300px; margin: 40px auto 0 auto; overflow: auto; padding: 10px; box-shadow: 5px 10px 15px 5px rgba(0, 0, 0, 0.1); + p { + margin-bottom: 5px; + } + .filterBeat { + font-style: italic; + } } // FANCY SPEAKER @@ -934,8 +948,13 @@ $vibrateblurouter: 2px; background: #171717 !important; } +.noUi-value-vertical { + margin-top: -10px; +} + .noUi-value-vertical, .noUi-pips { color: inherit !important; + font: 400 14px 'Slabo 27px'; } .noUi-vertical .noUi-handle { @@ -972,3 +991,7 @@ button.md-warn { color: #f70 !important; } } + +.ember-modal-dialog { + padding: 20px; +} diff --git a/config/environment.js b/config/environment.js index fe27e6f..633c7cc 100644 --- a/config/environment.js +++ b/config/environment.js @@ -25,7 +25,7 @@ module.exports = function(environment) { 'font-src': "'self' fonts.gstatic.com", 'connect-src': "'self' *", 'img-src': "'self' data:", - 'media-src': "'self' blob:", + 'media-src': "'self' api.soundcloud.com *.sndcdn.com blob:", 'style-src': "'self' 'unsafe-inline' fonts.googleapis.com", 'object-src': "'self' connect.soundcloud.com", 'frame-src': "'self'"