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}}