From 4c65e216215a6791266d07d0da3b24f2ad9e401c Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 4 Sep 2015 00:47:13 -0700 Subject: [PATCH] WIP - id3 library doesnt read aac and might suck --- .jshintrc | 3 +- app/components/controls/music-control.js | 239 +++++++++++++----- app/styles/app.scss | 41 +-- .../components/controls/group-control.hbs | 2 +- .../components/controls/music-control.hbs | 46 ++-- bower.json | 5 +- ember-cli-build.js | 1 + 7 files changed, 229 insertions(+), 108 deletions(-) diff --git a/.jshintrc b/.jshintrc index 9e3599c..b81fa5c 100644 --- a/.jshintrc +++ b/.jshintrc @@ -3,7 +3,8 @@ "document", "window", "-Promise", - "Dancer" + "Dancer", + "id3" ], "browser": true, "boss": true, diff --git a/app/components/controls/music-control.js b/app/components/controls/music-control.js index 36e89c2..4832a4f 100644 --- a/app/components/controls/music-control.js +++ b/app/components/controls/music-control.js @@ -6,102 +6,189 @@ export default Em.Component.extend({ classNames: ['container-fluid'], actions: { - play: function(){ - if(this.get('status') === 'playing'){ + play: function () { + if (this.get('playing')) { this.get('dancer').pause(); - this.set('status', 'paused'); - } else if(this.get('status') === 'paused'){ + } else { this.get('dancer').play(); - this.set('status', 'playing'); } + this.toggleProperty('playing'); }, - volumeSliderChanged: function(volume){ + volumeSliderChanged: function (volume) { this.set('volume', volume); localStorage.setItem('huegasm.volume', volume); }, - next : function(){ + next: function () { }, - previous: function(){ + previous: function () { }, - fullscreen: function(){ + fullscreen: function () { }, - seekChanged: function() { + seekChanged: function () { }, - toggleMute: function() { + toggleMute: function () { this.toggleProperty('volumeMuted'); + + if(this.get('volumeMuted')){ + dancer.setVolume(0); + } else { + dancer.setVolume(this.get('volume')/100); + } + + localStorage.setItem('huegasm.volumeMuted', this.get('volumeMuted')); + }, + + toggleShuffle: function () { + this.toggleProperty('shuffle'); + localStorage.setItem('huegasm.shuffle', this.get('shuffle')); + }, + + toggleRepeat: function () { + var repeat = (this.get('repeat') + 1) % 3; + this.set('repeat', repeat); + localStorage.setItem('huegasm.repeat', repeat); + }, + + addAudio: function () { + Em.$('#fileInput').click(); } }, - volumeTooltipTxt: function() { - var tooltipTxt = 'Mute'; + // 0 - no repeat, 1 - repeat all, 2 - repeat one + repeat: 0, + shuffle: false, + volumeMuted: false, + volume: 100, + paused: false, + playing: false, - if(this.get('volumeMuted')) { - tooltipTxt = 'Unmute'; + repeatIcon: function () { + if (this.get('repeat') === 2) { + return 'repeat-one'; } - // change the tooltip text if it's already visible - Em.$('#volumeTooltip + .tooltip .tooltip-inner').html(tooltipTxt); - //change the tooltip text for hover - Em.$('#volumeTooltip').attr('data-original-title', tooltipTxt); - }.observes('volumeMuted'), - volumeMuted: false, - volumeClass: function(){ + 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')){ + if (this.get('volumeMuted')) { return "volume-off"; - } else if(volume >= 70){ + } else if (volume >= 70) { return "volume-up"; - } else if(volume > 10){ + } else if (volume > 10) { return "volume-down"; } else { return 'volume-mute'; } }.property('volumeMuted', 'volume'), - nextPrevEnabled: function(){ + 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'), + + onVolumeChange: function(){ + if(this.get('playing')){ + this.get('dancer').setVolume(this.get('volume')/100); + } + }.observes('volume').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.[]'), - status: null, - playQueue: [], timeElapsed: 0, timeReamining: 0, timeElapsedTxt: '0:00', timeRemainingTxt: '0:00', - volume: 100, - playButtonTooltipTxt: function() { - if(this.get('status') === 'playing'){ - return 'Pause'; - } else { - return 'Play'; - } - }.property('status'), - - playButton: function(){ - if(this.get('status') === 'playing'){ - return 'pause'; - } else { - return 'play-arrow'; - } - }.property('status'), - - init: function(){ + init: function () { this._super(); var dancer = new Dancer(), self = this, - briOff = function(i){ + briOff = function (i) { Em.$.ajax(self.get('apiURL') + '/lights/' + i + '/state', { data: JSON.stringify({'bri': 1, 'transitiontime': 0}), contentType: 'application/json', @@ -109,12 +196,12 @@ export default Em.Component.extend({ }); }, kick = dancer.createKick({ - threshold : 0.45, + threshold: 0.45, frequency: [0, 3], - onKick: function ( mag ) { + onKick: function (mag) { - if(self.get('paused') === false){ - for(let i=1; i <= 1; i++){ + if (self.get('paused') === false) { + for (let i = 1; i <= 1; i++) { Em.$.ajax(self.get('apiURL') + '/lights/' + i + '/state', { data: JSON.stringify({'bri': 254, 'transitiontime': 0}), contentType: 'application/json', @@ -126,7 +213,9 @@ export default Em.Component.extend({ self.set('paused', true); - setTimeout(function(){ self.set('paused', false); }, 150); + setTimeout(function () { + self.set('paused', false); + }, 150); console.log('Kick at ' + mag); } @@ -136,9 +225,17 @@ export default Em.Component.extend({ kick.on(); - if(localStorage.getItem('huegasm.volume')){ - this.set('volume', localStorage.getItem('huegasm.volume')); - } + ['volume', 'shuffle', 'repeat', 'volumeMuted'].forEach(function (item) { + if (localStorage.getItem('huegasm.' + item)) { + var itemVal = localStorage.getItem('huegasm.' + item); + if (item === 'repeat' || item === 'volume') { + itemVal = Number(itemVal); + } else { + itemVal = (itemVal === 'true'); + } + self.set(item, itemVal); + } + }); this.setProperties({ dancer: dancer, @@ -147,17 +244,27 @@ export default Em.Component.extend({ }, didInsertElement: function () { - var dancer = this.get('dancer'), self = this; - /*audio_file.onchange = function(){ - var files = this.files, a = new Audio(); - var file = URL.createObjectURL(files[0]); - a.src = file; - dancer.load(a); - self.set('status', 'paused'); - };*/ + var dancer = this.get('dancer'), self = this, playQueue = this.get('playQueue'); + + Em.$('#fileInput').on('change', function () { + var files = this.files, + updatePlayQueue = function(err, tags){ + playQueue.push({filaneme: this.name, url: URL.createObjectURL(this), artist: tags.artist, title: tags.title }); + + self.notifyPropertyChange('playQueue'); + }; + + for (var key in files) { + if (files.hasOwnProperty(key)) { + var file = files[key]; + + id3(file, updatePlayQueue.bind(file) ); + } + } + + + }); Em.$('[data-toggle="tooltip"]').tooltip(); - }, - - paused: false + } }); diff --git a/app/styles/app.scss b/app/styles/app.scss index b18c905..a1a0c87 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -6,10 +6,11 @@ $playerBackColor: #F12B24; $playerHeight: 400px; $playListBackgroundColor: #1E1E1E; +$playerDefaultIconColor: #BBBBBB; -// BRIDGE FINDER + // BRIDGE FINDER #finderContainer { - + } #pressButtonBridgeImg { @@ -55,7 +56,7 @@ md-content { // LIGHT GROUP .groupPanel { - border-right: 1px solid black; + //border-right: 1px solid black; } .lightGroup { @@ -100,7 +101,6 @@ md-icon.menu { .addButton { cursor: pointer; - float: right; margin-right: 16px; } @@ -195,14 +195,15 @@ md-toolbar { margin-left: 10px; } -#playerControlsRight { - float: right; -} - .playerControllIcon { - color: #BBBBBB !important; + color: $playerDefaultIconColor !important; cursor: pointer; transition-duration: 0.1s; + margin-right: 5px; +} + +.playerControllIcon.active { + color: lighten($playerDefaultIconColor, 20%) !important; } .playerControllIcon:hover { @@ -232,6 +233,7 @@ md-toolbar { .noUi-base { background-color: $playerBackColor; border-radius: 5px; + cursor: pointer; } #volumeBar { @@ -247,7 +249,7 @@ md-toolbar { top: -8px; cursor: pointer; transition-duration: 0.1s; - background: #BBBBBB !important; + background: $playerDefaultIconColor !important; } .noUi-horizontal .noUi-handle:hover { @@ -264,10 +266,6 @@ md-toolbar { transition-duration: 0.2s; } -#addMusicIcon { - float: right; -} - #seekSlider:hover { height: 8px; } @@ -295,10 +293,6 @@ md-toolbar { border-bottom: 1px solid #3a3a3a; } -.smallMarginRight { - margin-right:10px; -} - #playListArea { background: lighten($playListBackgroundColor, 20%); width: 100%; @@ -306,3 +300,14 @@ md-toolbar { margin: 10px auto 0 auto; border-radius: 5px; } + +#fileInput { + width: 1px; + height: 1px; + visibility: hidden; +} + +.playlistItem { + color: darken(white, 20%); + margin: 10px 5px 10px 5px; +} diff --git a/app/templates/components/controls/group-control.hbs b/app/templates/components/controls/group-control.hbs index 36aae78..06ceeec 100644 --- a/app/templates/components/controls/group-control.hbs +++ b/app/templates/components/controls/group-control.hbs @@ -1,5 +1,5 @@ {{#paper-content}} -

Light Groups{{paper-icon icon="group-add"}}

+

Light Groups{{paper-icon icon="group-add"}}

{{#paper-list}} {{#each groupsArrData as |group|}} diff --git a/app/templates/components/controls/music-control.hbs b/app/templates/components/controls/music-control.hbs index 77ffc2f..70dc334 100644 --- a/app/templates/components/controls/music-control.hbs +++ b/app/templates/components/controls/music-control.hbs @@ -4,41 +4,47 @@
{{range-slider start=0 min=0 max=100 id="seekSlider" change="seekChanged" }} + {{#if nextPrevEnabled}} - {{paper-icon icon="skip-previous" class="playerControllIcon"}} ` - {{/if}} - - {{paper-icon icon=playButton class="playerControllIcon"}} - - {{#if nextPrevEnabled}} - {{paper-icon icon="skip-next" action="" class="playerControllIcon"}} - {{/if}} - - {{paper-icon icon=volumeClass class="playerControllIcon volumeButton"}} - {{range-slider start=volume min=0 max=100 change="volumeSliderChanged" id="volumeBar"}} + {{paper-icon icon="skip-previous" class="playerControllIcon"}} {{/if}}{{paper-icon icon=playingIcon class="playerControllIcon"}}{{#if nextPrevEnabled}} + {{paper-icon icon="skip-next" action="" class="playerControllIcon"}} + {{/if}}{{paper-icon icon=volumeClass class="playerControllIcon volumeButton"}}{{range-slider start=volume min=0 max=100 change="volumeSliderChanged" id="volumeBar"}} {{timeElapsedTxt}} / {{timeRemainingTxt}} - - {{paper-icon icon="fullscreen" class="playerControllIcon"}} + + {{paper-icon icon="fullscreen" class="playerControllIcon"}}
- + -
- {{paper-icon icon="shuffle" class="playerControllIcon"}} +
+ {{paper-icon icon="shuffle" class=shuffleClass}} - {{paper-icon icon="repeat" class="playerControllIcon"}} + {{paper-icon icon=repeatIcon class=repeatClass}} - {{paper-icon icon="add" class="playerControllIcon" }} -
+ {{paper-icon icon="add" class="playerControllIcon" }} +
- + {{#each playQueue as |item|}} +
{{#if item.title}} + {{item.artist}} - {{item.title}} + {{else}} + {{item.filename}} + {{/if}}
+ {{/each}}
\ No newline at end of file diff --git a/bower.json b/bower.json index b800f3b..4b9d531 100644 --- a/bower.json +++ b/bower.json @@ -11,9 +11,10 @@ "ember-qunit-notifications": "0.0.7", "ember-resolver": "~0.1.18", "hammerjs": "~2.0.4", + "id3js": "id3#~1.0.2", "jquery": "^1.11.1", "loader.js": "ember-cli/loader.js#3.2.0", - "qunit": "~1.18.0", - "nouislider": "^8.0.1" + "nouislider": "^8.0.1", + "qunit": "~1.18.0" } } diff --git a/ember-cli-build.js b/ember-cli-build.js index 2cbcbd4..12b37f2 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -8,6 +8,7 @@ module.exports = function(defaults) { app.import('vendor/dancer.js'); app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js'); + app.import('bower_components/id3js/dist/id3.js'); // Use `app.import` to add additional libraries to the generated // output files.