From 0c33eba2a31935bf34f18d354fee0864b87a25d0 Mon Sep 17 00:00:00 2001 From: Egor Philippov Date: Wed, 9 Sep 2015 16:48:39 -0700 Subject: [PATCH] reorganizing the music-control component, working on audio seek --- app/components/bridge-finder.js | 32 ++- app/components/controls/music-control.js | 187 +---------------- app/components/mixins/music-control.js | 194 ++++++++++++++++++ app/components/modals/add-group-modal.js | 10 + app/styles/app.scss | 23 ++- app/templates/components/bridge-finder.hbs | 8 +- .../components/controls/music-control.hbs | 2 +- 7 files changed, 260 insertions(+), 196 deletions(-) create mode 100644 app/components/mixins/music-control.js diff --git a/app/components/bridge-finder.js b/app/components/bridge-finder.js index fdf0190..9ede351 100644 --- a/app/components/bridge-finder.js +++ b/app/components/bridge-finder.js @@ -21,22 +21,49 @@ export default Em.Component.extend({ bridgePingIntervalHandle: null, bridgeAuthenticateReachedStatus: null, + manualBridgeIp: null, + manualBridgeIpNotFound: false, + actions: { retry: function(){ this.onBridgeIpChange(); }, findBridgeByIp: function() { - if (this.get('manualBridgeIp').toLowerCase() === 'trial') { + var manualBridgeIp = this.get('manualBridgeIp'), self = this; + + if (manualBridgeIp.toLowerCase() === 'trial') { this.setProperties({ trial: true, bridgeIp: 'trial', bridgeUsername: 'trial' }); + } else { + Em.$.ajax('http://' + manualBridgeIp + '/api', { + data: JSON.stringify({"devicetype": "huegasm"}), + contentType: 'application/json', + type: 'POST' + }).fail(function () { + self.set('manualBridgeIpNotFound', true); + setTimeout(function(){ self.set('manualBridgeIpNotFound', false); }, 5000); + }).then(function () { + debugger; + self.set('bridgeIp', manualBridgeIp); + }); } } }, + didInsertElement: function() { + var self = this; + + Em.$(document).keypress(function(event) { + if(!Em.isNone(self.get('manualBridgeIp')) && event.which === 13) { + self.send('findBridgeByIp'); + } + }); + }, + // find the bridge ip here init: function () { this._super(); @@ -73,7 +100,8 @@ export default Em.Component.extend({ }.observes('bridgeIp'), pingBridgeUser: function () { - var bridgeIp = this.get('bridgeIp'), self = this, bridgeUserNamePingIntervalProgress = this.get('bridgeUserNamePingIntervalProgress'), bridgeUsernamePingMaxTime = this.get('bridgeUsernamePingMaxTime'); + var bridgeIp = this.get('bridgeIp'), self = this, bridgeUserNamePingIntervalProgress = this.get('bridgeUserNamePingIntervalProgress'), + bridgeUsernamePingMaxTime = this.get('bridgeUsernamePingMaxTime'); if (bridgeIp !== null && bridgeUserNamePingIntervalProgress < 100) { Em.$.ajax('http://' + bridgeIp + '/api', { diff --git a/app/components/controls/music-control.js b/app/components/controls/music-control.js index 6081742..c5bba3e 100644 --- a/app/components/controls/music-control.js +++ b/app/components/controls/music-control.js @@ -1,75 +1,9 @@ import Em from 'ember'; +import musicControlMixin from '../mixins/music-control'; -export default Em.Component.extend({ - dancer: null, - +export default Em.Component.extend(musicControlMixin, { classNames: ['container-fluid', 'innerControlFrame'], - beatOptions: { - threshold: { - range: {min: 0.1, max: 0.6}, - defaultValue: 0.3, - pips: { - mode: 'positions', - values: [0,20,40,60,80,100], - density: 3, - format: { - to: function ( value ) {return value;}, - from: function ( value ) { return value; } - } - } - }, - decay: { - range: {min: 0, max: 0.1}, - step: 0.01, - defaultValue: 0.02, - pips: { - mode: 'positions', - values: [0,20,40,60,80,100], - density: 3, - format: { - to: function ( value ) {return value;}, - from: function ( value ) { return value; } - } - } - }, - frequency: { - range: {min: 0, max: 10}, - step: 1, - defaultValue: [0,5], - pips: { - mode: 'values', - values: [0,2,4,6,8,10], - density: 10, - format: { - to: function ( value ) {return value;}, - from: function ( value ) { return value; } - } - } - } - }, - - threshold: 0.3, - decay: 0.02, - frequency: [0,5], - - playQueue: [], - timeElapsed: 0, - timeTotal: 0, - - // 0 - no repeat, 1 - repeat all, 2 - repeat one - repeat: 0, - shuffle: false, - volumeMuted: false, - volume: 100, - paused: false, - playing: false, - - incrementElapseTimeHandle: null, - incrementElapseTime: function(){ - this.incrementProperty('timeElapsed'); - }, - actions: { defaultControls: function(){ var beatOptions = this.get('beatOptions'); @@ -169,119 +103,6 @@ export default Em.Component.extend({ localStorage.setItem('huegasm.' + name, value); }, - repeatIcon: function () { - if (this.get('repeat') === 2) { - return 'repeat-one'; - } - - return 'repeat'; - }.property('repeat'), - - playingIcon: function () { - if (this.get('playing')) { - return 'pause'; - } else { - return 'play-arrow'; - } - }.property('playing'), - - repeatClass: function () { - return this.get('repeat') !== 0 ? 'playerControllIcon active' : 'playerControllIcon'; - }.property('repeat'), - - shuffleClass: function () { - return this.get('shuffle') ? 'playerControllIcon active' : 'playerControllIcon'; - }.property('shuffle'), - - volumeClass: function () { - var volume = this.get('volume'); - - if (this.get('volumeMuted')) { - return "volume-off"; - } else if (volume >= 70) { - return "volume-up"; - } else if (volume > 10) { - return "volume-down"; - } else { - return 'volume-mute'; - } - }.property('volumeMuted', 'volume'), - - onRepeatChange: function () { - var tooltipTxt = 'Repeat all', type = 'repeat'; - - if (this.get(type) === 1) { - tooltipTxt = 'Repeat one'; - } else if (this.get(type) === 2) { - tooltipTxt = 'Repeat off'; - } - - this.changeTooltipText(type, tooltipTxt); - }.observes('repeat').on('init'), - - onShuffleChange: function () { - var tooltipTxt = 'Shuffle', type = 'shuffle'; - - if (this.get(type)) { - tooltipTxt = 'Unshuffle'; - } - - this.changeTooltipText(type, tooltipTxt); - }.observes('shuffle').on('init'), - - onVolumeMutedChange: function () { - var tooltipTxt = 'Mute', type = 'volumeMuted', - volumeMuted = this.get(type), dancer = this.get('dancer'), - volume=0; - - if (volumeMuted) { - tooltipTxt = 'Unmute'; - volume = 0; - } else { - volume = this.get('volume')/100; - } - - if(this.get('playing')){ - dancer.setVolume(volume); - } - - this.changeTooltipText(type, tooltipTxt); - }.observes('volumeMuted').on('init'), - - onPlayingChange: function () { - var tooltipTxt = 'Play', type = 'playing'; - - if (this.get(type)) { - tooltipTxt = 'Pause'; - } - - this.changeTooltipText(type, tooltipTxt); - }.observes('playing').on('init'), - - changeTooltipText: function (type, text) { - // change the tooltip text if it's already visible - Em.$('#' + type + 'Tooltip + .tooltip .tooltip-inner').html(text); - //change the tooltip text for hover - Em.$('#' + type + 'Tooltip').attr('data-original-title', text).attr('title', text); - 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'), - timeTotalTxt: function() { - return this.formatTime(this.get('timeTotal')); - }.property('timeTotal'), - - formatTime: function(time){ - return this.pad(Math.floor(time/60), 2) + ':' + this.pad(time%60, 2); - }, - pad: function(num, size){ return ('000000000' + num).substr(-size); }, - init: function () { this._super(); @@ -388,6 +209,10 @@ export default Em.Component.extend({ }); Em.$('[data-toggle="tooltip"]').tooltip(); + // prevent space/text selection when the user repeatedly clicks on the center + Em.$('#beatSpeakerCenter').mousedown(function(event) { + event.preventDefault(); + }); }, // component clean up diff --git a/app/components/mixins/music-control.js b/app/components/mixins/music-control.js new file mode 100644 index 0000000..4dc48d7 --- /dev/null +++ b/app/components/mixins/music-control.js @@ -0,0 +1,194 @@ +import Em from 'ember'; + +export default Em.Mixin.create({ + dancer: null, + + beatOptions: { + threshold: { + range: {min: 0.1, max: 0.6}, + defaultValue: 0.3, + pips: { + mode: 'positions', + values: [0,20,40,60,80,100], + density: 3, + format: { + to: function ( value ) {return value;}, + from: function ( value ) { return value; } + } + } + }, + decay: { + range: {min: 0, max: 0.1}, + step: 0.01, + defaultValue: 0.02, + pips: { + mode: 'positions', + values: [0,20,40,60,80,100], + density: 3, + format: { + to: function ( value ) {return value;}, + from: function ( value ) { return value; } + } + } + }, + frequency: { + range: {min: 0, max: 10}, + step: 1, + defaultValue: [0,5], + pips: { + mode: 'values', + values: [0,2,4,6,8,10], + density: 10, + format: { + to: function ( value ) {return value;}, + from: function ( value ) { return value; } + } + } + } + }, + + threshold: 0.3, + decay: 0.02, + frequency: [0,5], + + playQueue: [], + timeElapsed: 0, + timeTotal: 0, + seekPosition: function() { + var timeTotal = this.get('timeTotal'), timeElapsed = this.get('timeElapsed'); + + if (timeTotal === 0) { + return 0; + } + + return timeElapsed/timeTotal*100; + }.property('timeElapsed', 'timeTotal'), + + // 0 - no repeat, 1 - repeat all, 2 - repeat one + repeat: 0, + shuffle: false, + volumeMuted: false, + volume: 100, + paused: false, + playing: false, + + incrementElapseTimeHandle: null, + incrementElapseTime: function(){ + this.incrementProperty('timeElapsed'); + }, + + repeatIcon: function () { + if (this.get('repeat') === 2) { + return 'repeat-one'; + } + + return 'repeat'; + }.property('repeat'), + + playingIcon: function () { + if (this.get('playing')) { + return 'pause'; + } else { + return 'play-arrow'; + } + }.property('playing'), + + repeatClass: function () { + return this.get('repeat') !== 0 ? 'playerControllIcon active' : 'playerControllIcon'; + }.property('repeat'), + + shuffleClass: function () { + return this.get('shuffle') ? 'playerControllIcon active' : 'playerControllIcon'; + }.property('shuffle'), + + volumeClass: function () { + var volume = this.get('volume'); + + if (this.get('volumeMuted')) { + return "volume-off"; + } else if (volume >= 70) { + return "volume-up"; + } else if (volume > 10) { + return "volume-down"; + } else { + return 'volume-mute'; + } + }.property('volumeMuted', 'volume'), + + onRepeatChange: function () { + var tooltipTxt = 'Repeat all', type = 'repeat'; + + if (this.get(type) === 1) { + tooltipTxt = 'Repeat one'; + } else if (this.get(type) === 2) { + tooltipTxt = 'Repeat off'; + } + + this.changeTooltipText(type, tooltipTxt); + }.observes('repeat').on('init'), + + onShuffleChange: function () { + var tooltipTxt = 'Shuffle', type = 'shuffle'; + + if (this.get(type)) { + tooltipTxt = 'Unshuffle'; + } + + this.changeTooltipText(type, tooltipTxt); + }.observes('shuffle').on('init'), + + onVolumeMutedChange: function () { + var tooltipTxt = 'Mute', type = 'volumeMuted', + volumeMuted = this.get(type), dancer = this.get('dancer'), + volume=0; + + if (volumeMuted) { + tooltipTxt = 'Unmute'; + volume = 0; + } else { + volume = this.get('volume')/100; + } + + if(this.get('playing')){ + dancer.setVolume(volume); + } + + this.changeTooltipText(type, tooltipTxt); + }.observes('volumeMuted').on('init'), + + onPlayingChange: function () { + var tooltipTxt = 'Play', type = 'playing'; + + if (this.get(type)) { + tooltipTxt = 'Pause'; + } + + this.changeTooltipText(type, tooltipTxt); + }.observes('playing').on('init'), + + changeTooltipText: function (type, text) { + // change the tooltip text if it's already visible + Em.$('#' + type + 'Tooltip + .tooltip .tooltip-inner').html(text); + //change the tooltip text for hover + Em.$('#' + type + 'Tooltip').attr('data-original-title', text).attr('title', text); + 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'), + + timeTotalTxt: function() { + return this.formatTime(this.get('timeTotal')); + }.property('timeTotal'), + + formatTime: function(time){ + return this.pad(Math.floor(time/60), 2) + ':' + this.pad(time%60, 2); + }, + + pad: function(num, size){ return ('000000000' + num).substr(-size); }, +}); diff --git a/app/components/modals/add-group-modal.js b/app/components/modals/add-group-modal.js index 45fb635..5660917 100644 --- a/app/components/modals/add-group-modal.js +++ b/app/components/modals/add-group-modal.js @@ -35,6 +35,16 @@ export default Em.Component.extend({ } }, + didInsertElement: function() { + var self = this; + + Em.$(document).keypress(function(event) { + if(!self.get('saveDisabled') && event.which === 13) { + self.send('save'); + } + }); + }, + groupName: null, selectedLights: [], diff --git a/app/styles/app.scss b/app/styles/app.scss index 01ca690..08b9fe1 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -236,7 +236,7 @@ md-toolbar { position: absolute; bottom: 0; left: 0; - padding: 10px; + padding: 0.714em; width: 100%; color: white !important; z-index: 20; @@ -246,14 +246,14 @@ md-toolbar { #playerTimeControls { position: relative; font-size: 12px; - top: 2px; - margin-left: 10px; + top: 0.167em; + margin-left: 0.833em; } .playerControllIcon { color: $playerDefaultIconColor !important; transition-duration: 0.1s; - margin-right: 5px; + margin-right: 0.208em; cursor: pointer; } @@ -298,8 +298,8 @@ md-toolbar { } #volumeBar { - width: 100px; - height: 8px; + width: 7.143em; + height: 0.571em; display: inline-block; } @@ -308,10 +308,10 @@ md-toolbar { } .noUi-horizontal .noUi-handle { - width: 7px; - height: 21px; - left: -1px; - top: -8px; + width: 0.500em; + height: 1.500em; + left: -0.071em; + top: -0.571em; transition-duration: 0.1s; background: $playerDefaultIconColor !important; } @@ -406,6 +406,7 @@ md-toolbar { #beatSpeakerContainer { position: relative; height: $playerBeatAreaHeight; + padding: 0; } #beatSpeaker { @@ -421,7 +422,7 @@ md-toolbar { background-image: url('images/speaker-inner.png'); position: absolute; top: 21%; - left: 22%; + left: 18%; } .pop { diff --git a/app/templates/components/bridge-finder.hbs b/app/templates/components/bridge-finder.hbs index 788a6cf..88eadd7 100644 --- a/app/templates/components/bridge-finder.hbs +++ b/app/templates/components/bridge-finder.hbs @@ -23,9 +23,15 @@ Enter one manually?

- {{paper-input label="Hue Bridge IP Address" value=manualBridgeIp}} + {{paper-input label="Hue bridge IP address" value=manualBridgeIp}} {{#paper-button action="findBridgeByIp" primary=true}}Find{{/paper-button}} + + {{#liquid-if manualBridgeIpNotFound}} +

+ Could not find a bridge with that IP address. +

+ {{/liquid-if}} {{/if}} {{/if}} {{/if}} diff --git a/app/templates/components/controls/music-control.hbs b/app/templates/components/controls/music-control.hbs index 4b7d7e0..a405739 100644 --- a/app/templates/components/controls/music-control.hbs +++ b/app/templates/components/controls/music-control.hbs @@ -2,7 +2,7 @@
- {{range-slider start=0 min=0 max=100 id="seekSlider" slide="seekChanged" }} + {{range-slider start=seekPosition min=0 max=100 id="seekSlider" slide="seekChanged"}} {{#if nextPrevEnabled}}