From b9866ab16473442d863f40ab651e803ec944092a Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 13 Sep 2015 23:06:26 -0700 Subject: [PATCH] weekend werk --- app/components/bridge-controls.js | 23 ++++--- app/components/controls/group-control.js | 3 +- app/components/controls/music-control.js | 67 ++++++++++++++++--- app/components/mixins/music-control.js | 34 ++++++++-- app/templates/components/bridge-controls.hbs | 5 +- .../components/controls/light-control.hbs | 1 - .../components/controls/music-control.hbs | 42 ++++++++---- bower.json | 6 +- ember-cli-build.js | 1 + package.json | 7 +- 10 files changed, 144 insertions(+), 45 deletions(-) diff --git a/app/components/bridge-controls.js b/app/components/bridge-controls.js index 0164335..b16e52a 100644 --- a/app/components/bridge-controls.js +++ b/app/components/bridge-controls.js @@ -1,7 +1,7 @@ import Em from 'ember'; export default Em.Component.extend({ - classNames: ['bridgeControls'], + classNames: ['bridgeControls', 'container-fluid'], bridgeIp: null, manualBridgeIp: null, @@ -12,6 +12,19 @@ export default Em.Component.extend({ lightsData: null, activeLights: [], + groupControlDisplayed: false, + + actions: { + changeTab: function(tabName){ + var index = this.get('tabList').indexOf(tabName); + this.set('selectedTab', index); + localStorage.setItem('huegasm.selectedTab', index); + }, + + toggleGroupControl: function(){ + this.toggleProperty('groupControlDisplayed'); + } + }, apiURL: function(){ return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername'); @@ -70,14 +83,6 @@ export default Em.Component.extend({ lightsTabSelected: Em.computed.equal('selectedTab', 0), musicTabSelected: Em.computed.equal('selectedTab', 1), - actions: { - changeTab: function(tabName){ - var index = this.get('tabList').indexOf(tabName) - this.set('selectedTab', index); - localStorage.setItem('huegasm.selectedTab', index); - } - }, - updateLightData: function(){ var self = this; diff --git a/app/components/controls/group-control.js b/app/components/controls/group-control.js index 4f43df7..4becc80 100644 --- a/app/components/controls/group-control.js +++ b/app/components/controls/group-control.js @@ -1,7 +1,8 @@ import Em from 'ember'; export default Em.Component.extend({ - classNames: ['innerControlFrame', 'groupControl'], + classNameBindings: ['groupControlDisplayed:on'], + classNames: ['innerControlFrame', 'groupControls'], tagName: null, diff --git a/app/components/controls/music-control.js b/app/components/controls/music-control.js index b202826..e5171f2 100644 --- a/app/components/controls/music-control.js +++ b/app/components/controls/music-control.js @@ -5,6 +5,20 @@ export default Em.Component.extend(musicControlMixin, { classNames: ['innerControlFrame'], actions: { + goToSong: function(index){ + var a = new Audio(); + a.src = this.get('playQueue')[index].url; + this.get('dancer').load(a); + this.set('playQueuePointer', index); + this.send('play'); + }, + removeAudio: function(index){ + this.get('playQueue').removeAt(index); + + //if(index === this.get('playQueuePointer')){ + // this.get('dancer') + //} + }, defaultControls: function(){ var beatOptions = this.get('beatOptions'); @@ -15,6 +29,11 @@ export default Em.Component.extend(musicControlMixin, { clickLight:function() { debugger; }, + playerAreaPlay: function(){ + if(Em.isEmpty(Em.$('#playerControls:hover'))){ + this.send('play'); + } + }, play: function () { var dancer = this.get('dancer'), playQueue = this.get('playQueue'); @@ -35,6 +54,8 @@ export default Em.Component.extend(musicControlMixin, { this.set('incrementElapseTimeHandle', window.setInterval(this.incrementElapseTime.bind(this), 1000)); this.toggleProperty('playing'); } + + Em.$('#playerArea').removeClass('material-icons').prop('offsetWidth', Em.$('#playerArea').prop('offsetWidth')).addClass('material-icons'); }, volumeChanged: function (value) { this.changePlayerControl('volume', value); @@ -51,9 +72,12 @@ export default Em.Component.extend(musicControlMixin, { fullscreen: function () { }, - seekChanged: function () { - + seekChanged: function (position) { + var audioPosition = Math.floor(this.get('timeTotal') * position / 100); + this.get('dancer').source.currentTime = audioPosition; + this.set('timeElapsed', audioPosition); }, + volumeMutedChanged: function (value) { var dancer = this.get('dancer'), volumeMuted = Em.isNone(value) ? !this.get('volumeMuted') : value; @@ -86,6 +110,14 @@ export default Em.Component.extend(musicControlMixin, { addAudio: function () { Em.$('#fileInput').click(); }, + playListAreaAddAudio: function(){ + if(this.get('playQueue').length === 0){ + this.send('addAudio'); + } + }, + speakerViewedChanged: function(value){ + this.set('speakerViewed', value); + }, clickSpeaker: function(){ // simulate the speaker vibration by running a CSS animation on it Em.$('#beatSpeakerCenter').removeClass('pop').prop('offsetWidth', Em.$('#beatSpeakerCenter').prop('offsetWidth')).addClass('pop'); @@ -141,9 +173,16 @@ export default Em.Component.extend(musicControlMixin, { self.set('paused', false); }, 150); - self.send('clickSpeaker'); - - console.log('Kick at ' + mag); + if(self.get('speakerViewed')){ + self.send('clickSpeaker'); + } else { + var beatHistory = self.get('beatHistory'), + maxSize = self.get('maxBeatHistorySize'); + beatHistory.unshiftObjects('Beat strength of ' + mag.toFixed(3) + ' at ' + self.get('timeElapsedTxt') + ''); + if(beatHistory.length > maxSize){ + beatHistory.popObject(); + } + } } } @@ -161,7 +200,7 @@ export default Em.Component.extend(musicControlMixin, { kick: kick }); - ['volume', 'shuffle', 'repeat', 'volumeMuted', 'threshold', 'decay', 'frequency'].forEach(function (item) { + ['volume', 'shuffle', 'repeat', 'volumeMuted', 'threshold', 'decay', 'frequency', 'speakerViewed'].forEach(function (item) { if (localStorage.getItem('huegasm.' + item)) { var itemVal = localStorage.getItem('huegasm.' + item); if (item === 'repeat' || item === 'volume' || item === 'decay' || item === 'threshold') { @@ -191,9 +230,7 @@ export default Em.Component.extend(musicControlMixin, { // make sure to init the first song if(playQueue.length > 0 && !self.get('dancer').isLoaded()){ - var a = new Audio(); - a.src = playQueue[0].url; - self.get('dancer').load(a); + self.send('goToSong', 0); } }; @@ -208,9 +245,19 @@ export default Em.Component.extend(musicControlMixin, { } }); + // initialize bootstrap tooltips Em.$('[data-toggle="tooltip"]').tooltip(); // prevent space/text selection when the user repeatedly clicks on the center - Em.$('#beatSpeakerCenter').mousedown(function(event) { + Em.$('#beatSpeakerContainer').on('mousedown', '#beatSpeakerCenter', function(event) { + event.preventDefault(); + }); + Em.$('#playerArea').on('mousewheel', function(event) { + var scrollSize = 5; + + if(event.deltaY < 0) { + scrollSize *= -1; + } + self.send('volumeChanged', self.get('volume') + scrollSize); event.preventDefault(); }); }, diff --git a/app/components/mixins/music-control.js b/app/components/mixins/music-control.js index 4dc48d7..babe139 100644 --- a/app/components/mixins/music-control.js +++ b/app/components/mixins/music-control.js @@ -51,9 +51,19 @@ export default Em.Mixin.create({ decay: 0.02, frequency: [0,5], - playQueue: [], + playQueuePointer: 0, + playQueue: Em.A(), + beatHistory: Em.A(), + maxBeatHistorySize: 30, timeElapsed: 0, timeTotal: 0, + + playQueueEmpty: Ember.computed.empty('playQueue'), + playQueueNotEmpty: Ember.computed.notEmpty('playQueue'), + playQueueMultiple: function(){ + return this.get('playQueue.length') > 1; + }.property('playQueue'), + seekPosition: function() { var timeTotal = this.get('timeTotal'), timeElapsed = this.get('timeElapsed'); @@ -69,9 +79,20 @@ export default Em.Mixin.create({ shuffle: false, volumeMuted: false, volume: 100, + // beat detection related pausing paused: false, + // audio: playing or paused playing: false, + speakerViewed: true, + speakerLabel: function() { + if(this.get('speakerViewed')){ + return 'Speaker View'; + } else { + return 'Debug View'; + } + }.property('speakerViewed'), + incrementElapseTimeHandle: null, incrementElapseTime: function(){ this.incrementProperty('timeElapsed'); @@ -115,6 +136,11 @@ export default Em.Mixin.create({ } }.property('volumeMuted', 'volume'), + onSpeakerViewedChange: function(){ + localStorage.setItem('huegasm.speakerViewed', this.get('speakerViewed')); + this.get('beatHistory').clear(); + }.observes('speakerViewed'), + onRepeatChange: function () { var tooltipTxt = 'Repeat all', type = 'repeat'; @@ -174,10 +200,6 @@ export default Em.Mixin.create({ this.set(type + 'TooltipTxt', text); }, - nextPrevEnabled: function () { - return this.get('playQueue').length > 1; - }.property('playQueue.[]'), - timeElapsedTxt: function(){ return this.formatTime(this.get('timeElapsed')); }.property('timeElapsed'), @@ -190,5 +212,5 @@ export default Em.Mixin.create({ return this.pad(Math.floor(time/60), 2) + ':' + this.pad(time%60, 2); }, - pad: function(num, size){ return ('000000000' + num).substr(-size); }, + pad: function(num, size){ return ('000000000' + num).substr(-size); } }); diff --git a/app/templates/components/bridge-controls.hbs b/app/templates/components/bridge-controls.hbs index a898062..7be1f09 100644 --- a/app/templates/components/bridge-controls.hbs +++ b/app/templates/components/bridge-controls.hbs @@ -1,6 +1,9 @@ {{#if ready}} + + {{paper-icon icon="menu"}} + - {{controls/group-control lightsData=lightsData groupsData=groupsData activeLights=activeLights apiURL=apiURL updateGroupsData=updateGroupsData}} + {{controls/group-control lightsData=lightsData groupsData=groupsData activeLights=activeLights apiURL=apiURL updateGroupsData=updateGroupsData groupControlDisplayed=groupControlDisplayed}}