working on the music controls

This commit is contained in:
lone-cloud 2015-08-27 01:16:18 -07:00
parent eb518c4898
commit b2eb2ede21
22 changed files with 534 additions and 305 deletions

View file

@ -2,7 +2,8 @@
"predef": [
"document",
"window",
"-Promise"
"-Promise",
"Dancer"
],
"browser": true,
"boss": true,

View file

@ -8,7 +8,8 @@ export default Em.Component.extend({
updateGroupsData: true,
groupsData: null,
lightsData: null,
activeLights: Em.A(),
activeLights: [],
apiURL: function(){
return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername');
@ -41,7 +42,7 @@ export default Em.Component.extend({
},
tabList: ["Lights", "Scenes", "Music"],
selectedTab: 0,
selectedTab: 2,
tabData: function(){
var tabData = [], selectedTab = this.get('selectedTab');
@ -73,16 +74,6 @@ export default Em.Component.extend({
Em.$.get(this.get('apiURL') + '/lights', function (result, status) {
if (status === 'success' && JSON.stringify(self.get('lightsData')) !== JSON.stringify(result) ) {
if(self.get('activeLights').length === 0){
var ids = [];
for (let key in result) {
if(result.hasOwnProperty(key) && result[key].state.reachable){
ids.push(key);
}
}
self.set('activeLights', ids);
}
self.set('lightsData', result);
} else if(status !== 'success') {
// something went terribly wrong ( user got unauthenticated? ) and we'll need to start all over

View file

@ -5,7 +5,7 @@ export default Em.Component.extend({
tagName: null,
groupIdSelection: '0',
groupIdSelection: null,
actions: {
selectGroup: function(selection){
@ -58,8 +58,20 @@ export default Em.Component.extend({
}
});
if(!Em.isNone(groupIdSelection)){
localStorage.setItem('huegasm.selectedGroup', groupIdSelection);
if(!Em.isNone(groupIdSelection) && !Em.isEmpty(lights)){
this.set('activeLights', lights);
}
}.observes('groupIdSelection')
}.observes('groupIdSelection', 'groupsArrData'),
didInsertElement: function(){
var selectGroup = '0', storageItem = localStorage.getItem('huegasm.selectedGroup');
if(storageItem){
selectGroup = storageItem;
}
this.set('groupIdSelection', selectGroup);
}
});

View file

@ -4,13 +4,16 @@ export default Em.Component.extend({
classNames: ['innerControlFrame'],
activeLights: [],
lightsData: null,
lightsDataIntervalHandle: null,
modalData: null,
isShowingLightsModal: false,
isShowingAddGroupsModal: false,
actions: {
selectLight: function(id, data){
clickLight: function(id, data){
if(this.get('isShowingLightsModal')){
this.set('modalData', {data:data, id:id});
}

View file

@ -1,13 +1,54 @@
import Em from 'ember';
export default Em.Component.extend({
apiURL: null,
lightsData: null,
activeLights: null,
didInsertElement: function () {
var dancer = new Dancer(),
self = this,
briOff = function(i){
Em.$.ajax(self.get('apiURL') + '/lights/' + i + '/state', {
data: JSON.stringify({'on': 1, 'transitiontime': 0}),
contentType: 'application/json',
type: 'PUT'
});
},
kick = dancer.createKick({
threshold : 0.45,
frequency: [0, 3],
onKick: function ( mag ) {
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',
type: 'PUT'
});
setTimeout(briOff, 50, i);
}
self.set('paused', true);
setTimeout(function(){ self.set('paused', false); }, 150);
console.log('Kick at ' + mag);
}
}
}),
a = new Audio();
kick.on();
audio_file.onchange = function(){
var files = this.files;
var file = URL.createObjectURL(files[0]);
a.src = file;
dancer.load(a);
dancer.play();
};
},
paused: false
});

View file

@ -0,0 +1,27 @@
import Em from 'ember';
export default Em.Component.extend({
classNames: ['container-fluid'],
actions: {
play: function(){
},
next : function(){
},
previous: function(){
}
},
status: null,
playButton: function(){
if(this.get('status') === 'paused'){
return 'pause';
} else {
return 'play-arrow';
}
}.property('status')
});

View file

@ -7,6 +7,7 @@ export default Em.Component.extend({
init: function(){
this._super();
if(localStorage.getItem('huegasm.bridgeIp')){
this.set('bridgeIp', localStorage.getItem('huegasm.bridgeIp'));
}

View file

@ -40,7 +40,13 @@ export default Em.Component.extend({
selectedLights: [],
onIsShowingAddGroupsModalChange: function(){
this.set('selectedLights', []);
if(this.get('isShowingAddGroupsModal')){
}
this.setProperties({
selectedLights: [],
groupName: null
});
}.observes('isShowingAddGroupsModal'),
saveDisabled: function(){

View file

@ -6,7 +6,9 @@ export default Em.Component.extend({
this.sendAction();
},
delete: function(){
Em.$.ajax(this.get('apiURL') + '/groups/' + this.get('groupId'), {
var groupId = this.get('groupId');
Em.$.ajax(this.get('apiURL') + '/groups/' + groupId, {
contentType: 'application/json',
type: 'DELETE'
});
@ -18,6 +20,10 @@ export default Em.Component.extend({
}
}
if(groupId === this.get('groupIdSelection')){
this.set('groupIdSelection', '0');
}
this.setProperties({
updateGroupsData: true,
groupsData: newGroupsData

View file

@ -9,6 +9,9 @@
{{content-for 'head'}}
<link href='http://fonts.googleapis.com/css?family=Slabo+27px' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link rel="shortcut icon" href="assets/images/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="assets/vendor.css">

View file

@ -6,6 +6,7 @@ var Router = Ember.Router.extend({
});
Router.map(function() {
this.route('404', {path:'/*path'});
});
export default Router;

View file

@ -3,10 +3,7 @@
@import 'ember-modal-dialog/ember-modal-structure';
@import 'ember-modal-dialog/ember-modal-appearance';
body, html {
height: 100%;
}
// BRIDGE FINDER
#pressButtonBridgeImg {
width: 200px;
margin: 0 auto 0 auto;
@ -17,10 +14,43 @@ body, html {
text-decoration: none;
}
md-list {
md-content {
max-width: 800px;
}
// BRIDGE CONTROLS
.navigation {
margin: 0 auto 0 auto;
padding: 30px 0 30px 0;
}
.navigationItem {
text-transform: uppercase;
cursor: pointer;
font-family: 'Slabo 27px', serif;
font-size: 18px;
padding: 0 10px 0 10px;
}
.navigationItem:hover{
text-decoration: underline;
}
.navigationItem.active {
font-weight: bold;
cursor: default;
}
.navigationItem.active:hover {
color: #000;
text-decoration: none;
}
// LIGHT GROUP
.lightGroup {
margin: 0 auto 0 auto;
}
.hueLight {
margin-right: 10px;
border-radius: 20px;
@ -54,7 +84,7 @@ md-icon {
}
md-icon.menu {
margin: 10px 16px 0 0;
margin: 30px 0 0 16px;
}
.addButton {
@ -70,6 +100,7 @@ md-icon.menu {
.sideNavTitle {
margin-left: 16px;
font-family: 'Slabo 27px', serif;
}
md-toolbar {
@ -77,20 +108,85 @@ md-toolbar {
}
.innerControlFrame {
background-color: mintcream;
height: 100vh;
}
// GROUP CONTROL
.groupRow.selectedRow {
background-color: lightgrey !important;
background-color: #7F7F7F !important;
color: white;
}
.groupRow:hover {
background-color: #E6E6E6;
background-color: #c3c3c3;
}
.groupRow.selectedRow .groupSelect {
cursor: default;
}
.groupSelect {
padding: 10px 0 10px 0;
cursor: pointer;
width: 70%;
font-family: 'Open Sans', sans-serif;
}
.groupRow:hover * .close {
display: block;
}
.groupRow:hover * .close {
display: block;
}
.selectedRow * .close {
color: white !important;
}
.selectedRow.groupRow * .close:hover {
color: darken(white, 20%) !important;
}
.groupRow * .close:hover {
color: darken(#333333, 20%) !important;
}
.close:hover {
opacity: 1;
}
.close {
color: rgb(51, 51, 51);
display: none;
opacity: 1;
text-shadow: none;
}
// MUSIC CONTROL
#playListContainer {
height: 600px;
width: 200px;
color: red;
}
.playerControllIcon {
color: white !important;
cursor: pointer;
}
.playerControllIcon:hover {
color: darken(white, 20%) !important;
}
#playerArea {
height: 200px;
background-color: black;
display: inline-block;
}
#playlist {
height: 200px;
background-color: grey;
display: inline-block;
}

View file

@ -1,11 +1,22 @@
{{#liquid-if lightsData}}
{{#paper-nav-container open=drawerOpen class="ember-app"}}
{{#paper-sidenav class="md-sidenav-left md-whiteframe-z2" flex-layout="column" flex=true}}
{{controls/group-control lightsData=lightsData groupsData=groupsData activeLights=activeLights apiURL=apiURL updateGroupsData=updateGroupsData}}
{{/paper-sidenav}}
{{#paper-sidenav-toggle class="menu-sidenav-toggle"}}
{{paper-icon icon="menu" size="lg"}}
{{/paper-sidenav-toggle}}
{{#paper-content flex-layout="column" flex=true}}
<ul class="nav nav-tabs">
<div class="navigation">
{{#each tabData as |tab|}}
<li role="presentation" class="{{if tab.selected "active" ""}}"><a
href="#" {{action "changeTab" tab.name}}>{{tab.name}}</a></li>
<span class="navigationItem {{if tab.selected "active" ""}}" {{action "changeTab" tab.name}}>{{tab.name}}</span>
{{/each}}
</ul>
</div>
{{#liquid-if lightsTabSelected class="tabSwitch"}}
{{controls/light-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}}
@ -18,13 +29,9 @@
{{#liquid-if musicTabSelected class="tabSwitch"}}
{{controls/music-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}}
{{/liquid-if}}
{{/paper-content}}
{{#paper-sidenav-toggle class="menu-sidenav-toggle"}}
{{paper-icon icon="menu" size="lg"}}
{{/paper-sidenav-toggle}}
{{#paper-sidenav class="md-sidenav-right md-whiteframe-z2" flex-layout="column" flex=true}}
{{controls/group-control lightsData=lightsData groupsData=groupsData activeLights=activeLights apiURL=apiURL updateGroupsData=updateGroupsData}}
{{/paper-sidenav}}
{{/paper-nav-container}}
{{/liquid-if}}

View file

@ -4,7 +4,7 @@
{{#paper-list}}
{{#each groupsArrData as |group|}}
{{#paper-item class=group.rowClass}}
<div class="groupSelect" {{action "selectGroup" group.data.key}}>{{group.name}}</div> {{#if group.deletable}}<span title="Remove Group" class="removeButton" {{action "toggleConfirmDeleteGroupsModal" group.name group.data.key}}>{{paper-icon icon="remove"}}</span>{{/if}}
<div class="groupSelect" {{action "selectGroup" group.data.key}}>{{group.name}}</div> {{#if group.deletable}}<span title="Remove Group" class="removeButton" {{action "toggleConfirmDeleteGroupsModal" group.name group.data.key}}>{{paper-icon icon="close"}}</span>{{/if}}
{{/paper-item}}
{{/each}}
{{/paper-list}}
@ -13,4 +13,4 @@
{{modals/add-group-modal lightsData=lightsData groupsData=groupsData isShowingAddGroupsModal=isShowingAddGroupsModal apiURL=apiURL updateGroupsData=updateGroupsData
action="toggleAddGroupsModal"}}
{{modals/confirm-delete-modal groupName=deleteGroupName groupId=deleteGroupId groupsData=groupsData isShowingConfirmDeleteModal=isShowingConfirmDeleteModal apiURL=apiURL updateGroupsData=updateGroupsData action="toggleConfirmDeleteGroupsModal"}}
{{modals/confirm-delete-modal groupName=deleteGroupName groupId=deleteGroupId groupsData=groupsData isShowingConfirmDeleteModal=isShowingConfirmDeleteModal apiURL=apiURL updateGroupsData=updateGroupsData groupIdSelection=groupIdSelection action="toggleConfirmDeleteGroupsModal"}}

View file

@ -22,6 +22,6 @@
{{#paper-switch checked=strobeOn}} {{strobeOnTxt}} {{/paper-switch}}
{{/paper-item}}
{{modals/light-control-modal modalData=modalData apiURL=apiURL action="selectLight" isShowingLightsModal=isShowingLightsModal}}
{{modals/light-control-modal modalData=modalData apiURL=apiURL action="clickLight" isShowingLightsModal=isShowingLightsModal}}
{{/paper-list}}

View file

@ -1,9 +1 @@
{{#paper-list}}
{{#paper-item class="item"}}
{{paper-icon icon="music-note"}}
<p>Music</p>
{{#paper-button raised=true primary=true}}UPLOAD{{/paper-button}}
{{/paper-item}}
{{/paper-list}}
{{controls/music-control/music-player}}

View file

@ -0,0 +1,14 @@
<div class="row">
<div id="playerArea" class="col-lg-8 col-xs-12">
<div id="playerControls">
{{paper-icon icon="skip-previous" action="previous" class="playerControllIcon"}}
{{paper-icon icon=playButton action="play" class="playerControllIcon"}}
{{paper-icon icon="skip-next" action="pause" class="playerControllIcon"}}
</div>
</div>
<div id="playlist" class="col-lg-4 col-xs-12">
<input id="audio_file" type="file" accept="audio/*" />
</div>
</div>

View file

@ -1,6 +1,5 @@
export default function(){
this.transition(
this.hasClass('tabSwitch'),
this.use('crossFade')
);
}

View file

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

View file

@ -6,8 +6,7 @@ module.exports = function(defaults) {
// Add options here
});
app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/collapse.js');
app.import('vendor/dancer.js');
// Use `app.import` to add additional libraries to the generated
// output files.
//

View file

@ -0,0 +1,26 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('controls/music-control/music-player', 'Integration | Component | controls/music control/music player', {
integration: true
});
test('it renders', function(assert) {
assert.expect(2);
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });
this.render(hbs`{{controls/music-control/music-player}}`);
assert.equal(this.$().text().trim(), '');
// Template block usage:
this.render(hbs`
{{#controls/music-control/music-player}}
template block text
{{/controls/music-control/music-player}}
`);
assert.equal(this.$().text().trim(), 'template block text');
});

18
vendor/dancer.js vendored
View file

@ -189,7 +189,7 @@
function update () {
for (var i in this.sections) {
if ( this.sections[ i ].condition() )
if (this.sections[i].condition && this.sections[i].condition() )
this.sections[i].callback.call(this);
}
}
@ -342,9 +342,7 @@
}
},
maxAmplitude : function ( frequency ) {
var
max = 0,
fft = this.dancer.getSpectrum();
var max = 0, fft = this.dancer.getSpectrum();
// Sloppy array check
if ( !frequency.length ) {
@ -369,11 +367,15 @@
SAMPLE_RATE = 44100;
var adapter = function ( dancer ) {
var context = new AudioContext(), filter = context.createBiquadFilter();
filter.type = "lowpass";
filter.frequency.value = 440;
this.dancer = dancer;
this.audio = new Audio();
this.context = window.AudioContext ?
new window.AudioContext() :
new window.webkitAudioContext();
this.context = context;
this.filter = filter;
};
adapter.prototype = {
@ -477,8 +479,10 @@
this.source = this.context.createMediaElementSource( this.audio );
this.source.connect( this.proc );
this.source.connect( this.gain );
//this.source.connect( this.filter );
this.gain.connect( this.context.destination );
this.proc.connect( this.context.destination );
//this.filter.connect( this.context.destination );
this.isLoaded = true;
this.progress = 1;