squashing bugs, tooltip stuff, better drag and dropping

This commit is contained in:
Egor Philippov 2015-09-16 15:29:26 -07:00
parent 2aeb666226
commit beab6069f8
9 changed files with 135 additions and 119 deletions

View file

@ -1,53 +1,24 @@
# Huegasm
This README outlines the details of collaborating on this Ember application.
A short introduction of this app could easily go here.
Music awesomeness for hue lights.
## Prerequisites
# TODO
## FEATURES
- finish beat detection light effects
- more granular light controls on the lights tab
- handle multiple bridge IPs for bridge-finder
- save beat detection settings per song
- app intro with intro.js
- music visualizations with three.js
- new favicon
You will need the following things properly installed on your computer.
* [Git](http://git-scm.com/)
* [Node.js](http://nodejs.org/) (with NPM)
* [Bower](http://bower.io/)
* [Ember CLI](http://www.ember-cli.com/)
* [PhantomJS](http://phantomjs.org/)
## Installation
* `git clone <repository-url>` this repository
* change into the new directory
* `npm install`
* `bower install`
## Running / Development
* `ember server`
* Visit your app at [http://localhost:4200](http://localhost:4200).
### Code Generators
Make use of the many generators for code, try `ember help generate` for more details
### Running Tests
* `ember test`
* `ember test --server`
### Building
* `ember build` (development)
* `ember build --environment production` (production)
### Deploying
Specify what it takes to deploy your app.
## Further Reading / Useful Links
* [ember.js](http://emberjs.com/)
* [ember-cli](http://www.ember-cli.com/)
* Development Browser Extensions
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
* [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
## POSSIBLE FEATURES
- clear localstorage
- help, contact, about, youtube video ???
- beat settings by interval
- integration with youtube, soundcloud, spotify ???
## BUGS
- fuckery when listening to music and switching tabs
- can't create groups anymore
- BUGS BUGS BUGS

View file

@ -27,16 +27,29 @@ export default Em.Component.extend({
}
},
// automatically close the group menu when the user clicks somewhere else
click: function() {
if(this.get('groupControlDisplayed') && !event.target.classList.contains('menu') && !$(event.target).closest('#groupControls').length) {
this.toggleProperty('groupControlDisplayed');
}
},
apiURL: function(){
return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername');
}.property('bridgeIp', 'bridgeUsername'),
didInsertElement: function(){
//TODO: make less shitty
// here's a weird way to automatically initialize bootstrap tooltips
var observer = new MutationObserver(function(mutations) {
Em.run.once(this, function(){
Em.$('.bootstrapTooltip').tooltip();
var haveTooltip = !mutations.every(function(mutation) {
return Em.isEmpty(mutation.addedNodes) || Em.isNone(mutation.addedNodes[0].classList) || mutation.addedNodes[0].classList.contains('tooltip');
});
if(haveTooltip) {
Em.run.once(this, function(){
Em.$('.bootstrapTooltip').tooltip();
});
}
});
observer.observe(Em.$('#bridgeControls')[0], {childList: true, subtree: true});
},

View file

@ -46,7 +46,6 @@ export default Em.Component.extend({
self.set('manualBridgeIpNotFound', true);
setTimeout(function(){ self.set('manualBridgeIpNotFound', false); }, 5000);
}).then(function () {
debugger;
self.set('bridgeIp', manualBridgeIp);
});
}

View file

@ -2,7 +2,8 @@ import Em from 'ember';
export default Em.Component.extend({
classNameBindings: ['groupControlDisplayed:on'],
classNames: ['innerControlFrame', 'groupControls'],
classNames: ['innerControlFrame'],
elementId: 'groupControls',
tagName: null,

View file

@ -64,8 +64,7 @@ export default Em.Component.extend(musicControlMixin, {
}
},
play: function () {
var dancer = this.get('dancer'),
playQueue = this.get('playQueue');
var dancer = this.get('dancer');
if(this.get('playQueuePointer') !== -1 ) {
if (this.get('playing')) {
@ -120,7 +119,6 @@ export default Em.Component.extend(musicControlMixin, {
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;
@ -196,20 +194,31 @@ export default Em.Component.extend(musicControlMixin, {
if (files.hasOwnProperty(key)) {
var file = files[key];
ID3.loadTags("local", updatePlayQueue.bind(file),{
dataReader: new FileAPIReader(file)
});
if(file.type.startsWith('audio')) {
ID3.loadTags("local", updatePlayQueue.bind(file),{
dataReader: new FileAPIReader(file)
});
}
}
}
}
},
dragOver: function(){
dragLeaveTimeoutHandle: null,
dragOver: function() {
var dragLeaveTimeoutHandle = this.get('dragLeaveTimeoutHandle');
this.set('dragging', true);
if (dragLeaveTimeoutHandle) {
clearTimeout(dragLeaveTimeoutHandle);
}
},
dragLeave: function(){
this.set('dragging', false);
// need to delay the dragLeave notification to avoid flickering ( hovering over some page elements causes this event to be sent )
var self = this;
this.set('dragLeaveTimeoutHandle', setTimeout(function(){ self.set('dragging', false); }, 500));
},
changePlayerControl: function(name, value, isOption){
@ -318,15 +327,17 @@ export default Em.Component.extend(musicControlMixin, {
});
// control the volume by scrolling up/down
Em.$('#playerArea').on('mousewheel', function(event) {
var scrollSize = 5;
if(self.get('playQueueNotEmpty')) {
var scrollSize = 5;
if(event.deltaY < 0) {
scrollSize *= -1;
if(event.deltaY < 0) {
scrollSize *= -1;
}
var newVolume = self.get('volume') + scrollSize;
self.send('volumeChanged', newVolume < 0 ? 0 : newVolume);
event.preventDefault();
}
var newVolume = self.get('volume') + scrollSize;
self.send('volumeChanged', newVolume < 0 ? 0 : newVolume);
event.preventDefault();
});
},

View file

@ -118,7 +118,7 @@ export default Em.Mixin.create({
}.property('playing'),
playListAreaClass: function(){
var classes = 'cursorPointer dragArea';
var classes = 'cursorPointer';
if(this.get('dragging')){
classes += ' dragHereHighlight';
@ -199,6 +199,18 @@ export default Em.Mixin.create({
this.changeTooltipText(type, tooltipTxt);
}.observes('volumeMuted').on('init'),
onPrevChange: function() {
if(this.get('playQueueMultiple')){
var tooltipTxt = 'Previous', type = 'prev';
if(this.get('timeElapsed') > 5) {
tooltipTxt = 'Replay';
}
this.changeTooltipText(type, tooltipTxt);
}
}.observes('timeElapsed', 'playQueueMultiple'),
onPlayingChange: function () {
var tooltipTxt = 'Play', type = 'playing';
@ -213,8 +225,11 @@ export default Em.Mixin.create({
// 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);
Em.$('#' + type + 'Tooltip').attr('data-original-title', text);
if(Em.isNone(this.get(type + 'TooltipTxt'))) {
this.set(type + 'TooltipTxt', text);
}
},
timeElapsedTxt: function(){

View file

@ -131,7 +131,7 @@ md-progress-circular {
overflow: visible;
}
.groupControls {
#groupControls {
display: none;
border-left: 1px solid #C5C5C5;
border-bottom: 1px solid #C5C5C5;
@ -140,7 +140,7 @@ md-progress-circular {
border-radius: 0 0 5px 5px;
}
.groupControls.on {
#groupControls.on {
width: 300px;
top: 48px;
left: -5px;
@ -210,7 +210,7 @@ md-icon.menu {
}
.addButton .group-add:hover {
color: darken(#333333, 20%) !important;
color: darken(#333333, 5%) !important;
}
.removeButton {
@ -267,7 +267,7 @@ md-toolbar {
}
.close:hover {
color: darken(#333333, 20%) !important;
color: darken(#333333, 5%) !important;
}
.close:hover {
@ -442,6 +442,7 @@ md-toolbar {
height: 333px;
margin: 10px auto 0 auto;
border-radius: 5px;
transition: 0.1s all ease-in-out;
#dragHere {
position: absolute;
top: 41%;
@ -457,6 +458,15 @@ md-toolbar {
}
}
#playListArea.dragHereHighlight {
background-color: white;
border: 5px dotted #5383ff;
}
#playListArea.draggingOver {
background-color: darken(white, 5%);
box-shadow: inset 0 0 20px 0 rgba(0,0,0,1);
}
#fileInput {
width: 1px;
height: 1px;
@ -509,7 +519,7 @@ md-toolbar {
.beatOption {
display: inline-block;
margin-left: 0.714em;
margin-right: 2em;
}
#playerBottom {
@ -534,15 +544,23 @@ md-toolbar {
background-image: url('images/speaker-outer.png');
width: 284px;
height: 283px;
}
#beatSpeakerCenter {
width: 188px;
height: 186px;
background-image: url('images/speaker-inner.png');
position: absolute;
top: 16%;
left: 18%;
#beatSpeakerCenter {
width: 188px;
height: 186px;
background-image: url('images/speaker-inner.png');
position: absolute;
top: 16%;
left: 18%;
}
#beatSpeakerCenterBackground {
width: 188px;
height: 186px;
background-color: black;
position: absolute;
top: 16%;
left: 18%;
z-index: -1;
}
}
.pop {
@ -585,13 +603,3 @@ md-toolbar {
padding: 10px;
box-shadow: 5px 10px 15px 5px rgba(0, 0, 0, 0.1);
}
#playListArea.dragArea.dragHereHighlight {
background-color: white;
border: 5px dotted #5383ff;
}
#playListArea.dragArea.draggingOver {
background-color: darken(white, 5%);
box-shadow: inset 0 0 20px 0 rgba(0,0,0,1);
}

View file

@ -5,17 +5,13 @@
{{range-slider start=seekPosition min=0 max=100 id="seekSlider" slide="seekChanged"}}
{{#if playQueueMultiple}}
<span data-toggle="tooltip" data-placement="top" title="Previous" class="bootstrapTooltip"
id="prevTooltip" {{action "previous"}}>{{paper-icon icon="skip-previous" class="playerControllIcon"}}</span><!--
<span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" id="prevTooltip" title={{prevTooltipTxt}} {{action "previous"}}>{{paper-icon icon="skip-previous" class="playerControllIcon"}}</span><!--
-->{{/if}}<!--
--><span data-toggle="tooltip" data-placement="top"
id="playingTooltip" class="bootstrapTooltip" title={{playingTooltipTxt}} {{action "play"}}>{{paper-icon icon=playingIcon class="playerControllIcon"}}</span><!--
--><span data-toggle="tooltip" data-placement="top" id="playingTooltip" class="bootstrapTooltip" title={{playingTooltipTxt}} {{action "play"}}>{{paper-icon icon=playingIcon class="playerControllIcon"}}</span><!--
-->{{#if playQueueMultiple}}<!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip"
title="Next song" {{action "next"}}>{{paper-icon icon="skip-next" action="" class="playerControllIcon"}}</span><!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" title="Next" {{action "next"}}>{{paper-icon icon="skip-next" action="" class="playerControllIcon"}}</span><!--
-->{{/if}}<!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" id="volumeMutedTooltip"
title={{volumeMutedTooltipTxt}} {{action "volumeMutedChanged"}}>{{paper-icon icon=volumeClass class="playerControllIcon volumeButton"}}</span><!--
--><span data-toggle="tooltip" data-placement="top" class="bootstrapTooltip" id="volumeMutedTooltip" title={{volumeMutedTooltipTxt}} {{action "volumeMutedChanged"}}>{{paper-icon icon=volumeClass class="playerControllIcon volumeButton"}}</span><!--
-->{{range-slider start=volume min=0 max=100 slide="volumeChanged" id="volumeBar"}}
<span id="playerTimeControls">{{timeElapsedTxt}} / {{timeTotalTxt}}</span>
@ -43,13 +39,13 @@
</div>
<div id="playListArea" class={{playListAreaClass}} {{action "playListAreaAddAudio"}} {{action "playListAreaDragOver" on="dragOver"}} {{action "playListAreaDragLeave" on="dragLeave"}} {{action "dropFiles" on="drop"}}>
{{#if playQueueEmpty}}
{{#if (or playQueueEmpty dragging)}}
<div id="dragHere">Drag your music files here</div>
{{paper-icon icon="library-music"}}
{{/if}}
{{#each playQueue as |item index|}}
<div class="playlistItem cursorPointer {{if (eq index playQueuePointer) "active"}}" {{action "goToSong" index bubbles=false}}>
<div class="playlistItem cursorPointer {{if (eq index playQueuePointer) "active"}} {{if dragging "hidden"}}" {{action "goToSong" index bubbles=false}}>
{{#if item.title}}
{{item.title}}
<div class="songArtist">{{item.artist}}</div>
@ -68,21 +64,22 @@
<div id="vertDivider"></div>
{{light-group lightsData=lightsData activeLights=activeLights action='clickLight' apiURL=apiURL noHover=true}}
<span id="beatOptionGroup">
<span class="beatOption">
{{range-slider start=threshold orientation="vertical" range=beatOptions.threshold.range slide="thresholdChanged" pips=beatOptions.threshold.pips}}
Beat Threshold
Beat Threshold
</span>
<span class="beatOption">
{{range-slider start=decay orientation="vertical" step=beatOptions.decay.step range=beatOptions.decay.range slide="decayChanged" pips=beatOptions.decay.pips}}
Beat Decay
Beat Decay
</span>
<span class="beatOption">
{{range-slider start=frequency orientation="vertical" step=beatOptions.frequency.step range=beatOptions.frequency.range connect=true slide="frequencyChanged" pips=beatOptions.frequency.pips}}
Beat Frequency Range
Beat Frequency Range
</span>
</span>
<div id="playerButtonGroup">
{{#paper-button raised=true warn=true action="defaultControls"}}Default{{/paper-button}}
@ -90,17 +87,18 @@
</span>
<span id="beatSpeakerContainer" class="col-xs-5">
{{#paper-switch checked=speakerViewed noink=true}} {{speakerLabel}} {{/paper-switch}}
{{#liquid-if speakerViewed}}
{{#paper-switch checked=speakerViewed noink=true}} {{speakerLabel}} {{/paper-switch}}
{{#liquid-if speakerViewed}}
<div id="beatSpeaker">
<span id="beatSpeakerCenter" class="beatSpeakerCenter cursorPointer" {{action "clickSpeaker"}}></span>
</div>
<span id="beatSpeakerCenterBackground"></span>
<span id="beatSpeakerCenter" class="beatSpeakerCenter cursorPointer" {{action "clickSpeaker"}}></span>
</div>
{{else}}
<div id ="beatHistory">
{{#each beatHistory as |item|}}
<p>{{{item}}}</p>
{{/each}}
{{#each beatHistory as |item|}}
<p>{{{item}}}</p>
{{/each}}
</div>
{{/liquid-if}}
</span>
</div>
</span>
</div>

View file

@ -24,7 +24,7 @@ module.exports = function(environment) {
'font-src': "'self' fonts.gstatic.com",
'connect-src': "'self' *",
'img-src': "'self' data:",
'media-src': "'self'",
'media-src': "'self' blob:",
'style-src': "'self' 'unsafe-inline' fonts.googleapis.com",
'object-src': "'self'",
'frame-src': "'self'"