prettier formatting
This commit is contained in:
parent
ea6eb4f968
commit
b64e19c3fe
13 changed files with 279 additions and 214 deletions
4
.prettierrc
Normal file
4
.prettierrc
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 140
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ module.exports = {
|
||||||
browser: true
|
browser: true
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
|
'no-debugger': 'off'
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
chrome: false,
|
chrome: false,
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,6 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
const {
|
const { Component, observer, computed, on, isNone, run: { later }, $, String: { htmlSafe } } = Ember;
|
||||||
Component,
|
|
||||||
observer,
|
|
||||||
computed,
|
|
||||||
on,
|
|
||||||
isNone,
|
|
||||||
run: { later },
|
|
||||||
$,
|
|
||||||
String: { htmlSafe }
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
elementId: 'bridge-finder',
|
elementId: 'bridge-finder',
|
||||||
|
|
@ -31,17 +22,20 @@ export default Component.extend({
|
||||||
isAuthenticating: computed.notEmpty('bridgePingIntervalHandle'),
|
isAuthenticating: computed.notEmpty('bridgePingIntervalHandle'),
|
||||||
|
|
||||||
// try to authenticate against the bridge here
|
// try to authenticate against the bridge here
|
||||||
onBridgeIpChange: on('init', observer('bridgeIp', function () {
|
onBridgeIpChange: on(
|
||||||
if (!this.get('trial') && !this.get('isAuthenticating')) {
|
'init',
|
||||||
this.setProperties({
|
observer('bridgeIp', function() {
|
||||||
bridgePingIntervalHandle: setInterval(this.pingBridgeUser.bind(this), this.get('bridgeUsernamePingIntervalTime')),
|
if (!this.get('trial') && !this.get('isAuthenticating')) {
|
||||||
bridgeUserNamePingIntervalProgress: 0
|
this.setProperties({
|
||||||
});
|
bridgePingIntervalHandle: setInterval(this.pingBridgeUser.bind(this), this.get('bridgeUsernamePingIntervalTime')),
|
||||||
}
|
bridgeUserNamePingIntervalProgress: 0
|
||||||
})),
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
),
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
$(document).keypress((event) => {
|
$(document).keypress(event => {
|
||||||
if (!isNone(this.get('manualBridgeIp')) && event.which === 13) {
|
if (!isNone(this.get('manualBridgeIp')) && event.which === 13) {
|
||||||
this.send('findBridgeByIp');
|
this.send('findBridgeByIp');
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +60,7 @@ export default Component.extend({
|
||||||
} else if (result.length > 1) {
|
} else if (result.length > 1) {
|
||||||
let multipleBridgeIps = this.get('multipleBridgeIps');
|
let multipleBridgeIps = this.get('multipleBridgeIps');
|
||||||
|
|
||||||
result.forEach(function (item) {
|
result.forEach(function(item) {
|
||||||
multipleBridgeIps.pushObject(item.internalipaddress);
|
multipleBridgeIps.pushObject(item.internalipaddress);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -90,27 +84,34 @@ export default Component.extend({
|
||||||
|
|
||||||
if (bridgeIp !== null && bridgeUserNamePingIntervalProgress < 100) {
|
if (bridgeIp !== null && bridgeUserNamePingIntervalProgress < 100) {
|
||||||
$.ajax('http://' + bridgeIp + '/api', {
|
$.ajax('http://' + bridgeIp + '/api', {
|
||||||
data: JSON.stringify({ "devicetype": "huegasm" }),
|
data: JSON.stringify({ devicetype: 'huegasm' }),
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
type: 'POST'
|
type: 'POST'
|
||||||
}).done((result, status) => {
|
})
|
||||||
if (!this.isDestroyed) {
|
.done((result, status) => {
|
||||||
if (status === 'success' && !result[0].error) {
|
if (!this.isDestroyed) {
|
||||||
this.clearBridgePingIntervalHandle();
|
if (status === 'success' && !result[0].error) {
|
||||||
this.get('storage').set('huegasm.bridgeUsername', result[0].success.username);
|
this.clearBridgePingIntervalHandle();
|
||||||
this.set('bridgeUsername', result[0].success.username);
|
this.get('storage').set('huegasm.bridgeUsername', result[0].success.username);
|
||||||
|
this.set('bridgeUsername', result[0].success.username);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}).fail(() => {
|
|
||||||
this.clearBridgePingIntervalHandle();
|
|
||||||
this.setProperties({
|
|
||||||
bridgeConnectError: true,
|
|
||||||
bridgeConnectMessage: htmlSafe('Your network and/or computer security settings are preventing Huegasm from connecting to your Hue bridge.' +
|
|
||||||
'<br><span>Feel free to contact us at <a href="mailto:huegasm.app@gmail.com">huegasm.app@gmail.com</a> if this is unexpected and you need help debugging the problem.</span>')
|
|
||||||
})
|
})
|
||||||
});
|
.fail(() => {
|
||||||
|
this.clearBridgePingIntervalHandle();
|
||||||
|
this.setProperties({
|
||||||
|
bridgeConnectError: true,
|
||||||
|
bridgeConnectMessage: htmlSafe(
|
||||||
|
'Your network and/or computer security settings are preventing Huegasm from connecting to your Hue bridge.' +
|
||||||
|
'<br><span>Feel free to contact us at <a href="mailto:huegasm.app@gmail.com">huegasm.app@gmail.com</a> if this is unexpected and you need help debugging the problem.</span>'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.incrementProperty('bridgeUserNamePingIntervalProgress', this.get('bridgeUsernamePingIntervalTime') / bridgeUsernamePingMaxTime * 100);
|
this.incrementProperty(
|
||||||
|
'bridgeUserNamePingIntervalProgress',
|
||||||
|
this.get('bridgeUsernamePingIntervalTime') / bridgeUsernamePingMaxTime * 100
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.clearBridgePingIntervalHandle();
|
this.clearBridgePingIntervalHandle();
|
||||||
}
|
}
|
||||||
|
|
@ -140,18 +141,24 @@ export default Component.extend({
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$.ajax('http://' + manualBridgeIp + '/api', {
|
$.ajax('http://' + manualBridgeIp + '/api', {
|
||||||
data: JSON.stringify({ "devicetype": "huegasm" }),
|
data: JSON.stringify({ devicetype: 'huegasm' }),
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
type: 'POST'
|
type: 'POST'
|
||||||
}).fail(() => {
|
})
|
||||||
this.set('manualBridgeIpNotFound', true);
|
.fail(() => {
|
||||||
later(this, function () {
|
this.set('manualBridgeIpNotFound', true);
|
||||||
this.set('manualBridgeIpNotFound', false);
|
later(
|
||||||
}, 5000);
|
this,
|
||||||
}).then(() => {
|
function() {
|
||||||
this.send('chooseBridge', manualBridgeIp);
|
this.set('manualBridgeIpNotFound', false);
|
||||||
});
|
},
|
||||||
|
5000
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.send('chooseBridge', manualBridgeIp);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
||||||
{{#if bridgeFindMultiple}}
|
{{#if bridgeFindMultiple}}
|
||||||
<p>Huegasm found multiple hue bridges. <br> Please select the one you want to use for Huegasm.</p>
|
<p>Multiple Hue bridge were found on your network. <br> Please select the one you want to use for Huegasm.</p>
|
||||||
|
|
||||||
<div id="bridge-button-group">
|
<div id="bridge-button-group">
|
||||||
{{#each multipleBridgeIps as |bridge|}}
|
{{#each multipleBridgeIps as |bridge|}}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ export default Component.extend({
|
||||||
// here's a weird way to automatically initialize bootstrap tooltips
|
// here's a weird way to automatically initialize bootstrap tooltips
|
||||||
let observer = new MutationObserver(function(mutations) {
|
let observer = new MutationObserver(function(mutations) {
|
||||||
let haveTooltip = !mutations.every(function(mutation) {
|
let haveTooltip = !mutations.every(function(mutation) {
|
||||||
return isEmpty(mutation.addedNodes) || isNone(mutation.addedNodes[0].classList) || mutation.addedNodes[0].classList.contains('tooltip');
|
return (
|
||||||
|
isEmpty(mutation.addedNodes) || isNone(mutation.addedNodes[0].classList) || mutation.addedNodes[0].classList.contains('tooltip')
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (haveTooltip) {
|
if (haveTooltip) {
|
||||||
|
|
@ -92,7 +94,9 @@ export default Component.extend({
|
||||||
if (isNone(this.get('lightsData'))) {
|
if (isNone(this.get('lightsData'))) {
|
||||||
this.send('clearBridge');
|
this.send('clearBridge');
|
||||||
} else if (this.get('displayNextFailure')) {
|
} else if (this.get('displayNextFailure')) {
|
||||||
this.get('notify').warning({ html: '<div class="alert alert-warning" role="alert">Error retrieving data from your lights. Yikes.</div>' });
|
this.get('notify').warning({
|
||||||
|
html: '<div class="alert alert-warning" role="alert">Error retrieving data from your lights. Yikes.</div>'
|
||||||
|
});
|
||||||
this.set('displayNextFailure', false);
|
this.set('displayNextFailure', false);
|
||||||
|
|
||||||
later(
|
later(
|
||||||
|
|
@ -174,7 +178,8 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
element: $('#playlist md-menu')[0],
|
element: $('#playlist md-menu')[0],
|
||||||
intro: '<img src="/assets/images/soundcloudUrl.png" id="soundcloud-tutorial">You can add songs from SoundCloud by copy and pasting the URL shown here'
|
intro:
|
||||||
|
'<img src="/assets/images/soundcloudUrl.png" id="soundcloud-tutorial">You can add songs from SoundCloud by copy and pasting the URL shown here'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
element: '#player-area',
|
element: '#player-area',
|
||||||
|
|
@ -196,7 +201,9 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
element: '#beat-container',
|
element: '#beat-container',
|
||||||
intro: 'An interactive speaker that will bump when a beat is registered. <br><br>' + '<i><b>TIP</b>: Click on the center of the speaker to simulate a beat.</i>',
|
intro:
|
||||||
|
'An interactive speaker that will bump when a beat is registered. <br><br>' +
|
||||||
|
'<i><b>TIP</b>: Click on the center of the speaker to simulate a beat.</i>',
|
||||||
position: 'top'
|
position: 'top'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
const {
|
const { Component, isEmpty, $ } = Ember;
|
||||||
Component,
|
|
||||||
isEmpty,
|
|
||||||
$
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
bridgeIp: null,
|
bridgeIp: null,
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
const {
|
const { Component, computed } = Ember;
|
||||||
Component,
|
|
||||||
computed
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: 'footer',
|
tagName: 'footer',
|
||||||
elementId: 'footer',
|
elementId: 'footer',
|
||||||
|
|
||||||
year: computed(function () {
|
year: computed(function() {
|
||||||
return new Date().getFullYear();
|
return new Date().getFullYear();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,6 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
const {
|
const { A, Component, computed, isEmpty, isNone, observer, $ } = Ember;
|
||||||
A,
|
|
||||||
Component,
|
|
||||||
computed,
|
|
||||||
isEmpty,
|
|
||||||
isNone,
|
|
||||||
observer,
|
|
||||||
$
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
elementId: 'active-lights',
|
elementId: 'active-lights',
|
||||||
|
|
@ -17,7 +9,7 @@ export default Component.extend({
|
||||||
activeLights: A(),
|
activeLights: A(),
|
||||||
|
|
||||||
// list of all the lights in the hue system
|
// list of all the lights in the hue system
|
||||||
lightsList: computed('lightsData', 'activeLights.[]', 'dimmerOn', function () {
|
lightsList: computed('lightsData', 'activeLights.[]', 'dimmerOn', function() {
|
||||||
let lightsData = this.get('lightsData'),
|
let lightsData = this.get('lightsData'),
|
||||||
activeLights = this.get('activeLights'),
|
activeLights = this.get('activeLights'),
|
||||||
dimmerOn = this.get('dimmerOn'),
|
dimmerOn = this.get('dimmerOn'),
|
||||||
|
|
@ -172,7 +164,7 @@ export default Component.extend({
|
||||||
return lightsList;
|
return lightsList;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onActiveLightsChange: observer('activeLights.[]', function () {
|
onActiveLightsChange: observer('activeLights.[]', function() {
|
||||||
this.get('storage').set('huegasm.activeLights', this.get('activeLights'));
|
this.get('storage').set('huegasm.activeLights', this.get('activeLights'));
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -184,7 +176,7 @@ export default Component.extend({
|
||||||
activeLightsCache = this.get('storage').get('huegasm.activeLights');
|
activeLightsCache = this.get('storage').get('huegasm.activeLights');
|
||||||
|
|
||||||
if (!isNone(activeLightsCache)) {
|
if (!isNone(activeLightsCache)) {
|
||||||
activeLightsCache.forEach(function (i) {
|
activeLightsCache.forEach(function(i) {
|
||||||
if (!isNone(lightsData) && lightsData.hasOwnProperty(i) && lightsData[i].state.reachable) {
|
if (!isNone(lightsData) && lightsData.hasOwnProperty(i) && lightsData[i].state.reachable) {
|
||||||
activeLights.pushObject(i);
|
activeLights.pushObject(i);
|
||||||
}
|
}
|
||||||
|
|
@ -211,15 +203,15 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lightStartHover(id) {
|
lightStartHover(id) {
|
||||||
if (!window.matchMedia || (window.matchMedia("(min-width: 768px)").matches)) {
|
if (!window.matchMedia || window.matchMedia('(min-width: 768px)').matches) {
|
||||||
let activeLights = this.get('activeLights'),
|
let activeLights = this.get('activeLights'),
|
||||||
hoveredLight = this.get('lightsList').filter(function (light) {
|
hoveredLight = this.get('lightsList').filter(function(light) {
|
||||||
return light.activeClass !== 'unreachable' && light.id === id[0] && activeLights.indexOf(id) !== -1;
|
return light.activeClass !== 'unreachable' && light.id === id[0] && activeLights.indexOf(id) !== -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isEmpty(hoveredLight) && this.get('noHover') !== true) {
|
if (!isEmpty(hoveredLight) && this.get('noHover') !== true) {
|
||||||
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
|
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
|
||||||
data: JSON.stringify({ "alert": "lselect" }),
|
data: JSON.stringify({ alert: 'lselect' }),
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
type: 'PUT'
|
type: 'PUT'
|
||||||
});
|
});
|
||||||
|
|
@ -232,14 +224,14 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lightStopHover(id) {
|
lightStopHover(id) {
|
||||||
if (!window.matchMedia || (window.matchMedia("(min-width: 768px)").matches)) {
|
if (!window.matchMedia || window.matchMedia('(min-width: 768px)').matches) {
|
||||||
let hoveredLight = this.get('lightsList').filter(function (light) {
|
let hoveredLight = this.get('lightsList').filter(function(light) {
|
||||||
return light.activeClass !== 'unreachable' && light.id === id[0];
|
return light.activeClass !== 'unreachable' && light.id === id[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isEmpty(hoveredLight) && this.get('noHover') !== true) {
|
if (!isEmpty(hoveredLight) && this.get('noHover') !== true) {
|
||||||
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
|
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
|
||||||
data: JSON.stringify({ "alert": "none" }),
|
data: JSON.stringify({ alert: 'none' }),
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
type: 'PUT'
|
type: 'PUT'
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
const {
|
const { Component, $ } = Ember;
|
||||||
Component,
|
|
||||||
$
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
elementId: 'color-picker',
|
elementId: 'color-picker',
|
||||||
|
|
@ -12,17 +9,17 @@ export default Component.extend({
|
||||||
canvasContext: null,
|
canvasContext: null,
|
||||||
pressingDown: false,
|
pressingDown: false,
|
||||||
|
|
||||||
mouseUp(){
|
mouseUp() {
|
||||||
this.set('pressingDown', false);
|
this.set('pressingDown', false);
|
||||||
},
|
},
|
||||||
|
|
||||||
mouseMove(event){
|
mouseMove(event) {
|
||||||
if (this.get('pressingDown')) {
|
if (this.get('pressingDown')) {
|
||||||
this.mouseDown(event);
|
this.mouseDown(event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mouseDown(event){
|
mouseDown(event) {
|
||||||
let canvasOffset = $(this.get('canvas')).offset(),
|
let canvasOffset = $(this.get('canvas')).offset(),
|
||||||
canvasX = Math.floor(event.pageX - canvasOffset.left),
|
canvasX = Math.floor(event.pageX - canvasOffset.left),
|
||||||
canvasY = Math.floor(event.pageY - canvasOffset.top);
|
canvasY = Math.floor(event.pageY - canvasOffset.top);
|
||||||
|
|
@ -39,14 +36,14 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://dzone.com/articles/creating-your-own-html5
|
// https://dzone.com/articles/creating-your-own-html5
|
||||||
didInsertElement(){
|
didInsertElement() {
|
||||||
// handle color changes
|
// handle color changes
|
||||||
let canvas = $('#picker')[0],
|
let canvas = $('#picker')[0],
|
||||||
canvasContext = canvas.getContext('2d'),
|
canvasContext = canvas.getContext('2d'),
|
||||||
image = new Image();
|
image = new Image();
|
||||||
|
|
||||||
image.src = 'assets/images/colormap.png';
|
image.src = 'assets/images/colormap.png';
|
||||||
image.onload = function () {
|
image.onload = function() {
|
||||||
canvasContext.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
|
canvasContext.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,25 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
const {
|
const { Component, observer, computed, isEmpty, isNone, run: { later }, $ } = Ember;
|
||||||
Component,
|
|
||||||
observer,
|
|
||||||
computed,
|
|
||||||
isEmpty,
|
|
||||||
isNone,
|
|
||||||
run: { later },
|
|
||||||
$
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
url: null,
|
url: null,
|
||||||
|
|
||||||
onIsShowingModalChange: observer('isShowingModal', function () {
|
onIsShowingModalChange: observer('isShowingModal', function() {
|
||||||
if (this.get('isShowingModal')) {
|
if (this.get('isShowingModal')) {
|
||||||
this.set('url', null);
|
this.set('url', null);
|
||||||
later(function () {
|
later(function() {
|
||||||
$('md-input-container input').focus();
|
$('md-input-container input').focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
saveDisabled: computed('url', function () {
|
saveDisabled: computed('url', function() {
|
||||||
return isNone(this.get('url')) || isEmpty(this.get('url').trim());
|
return isNone(this.get('url')) || isEmpty(this.get('url').trim());
|
||||||
}),
|
}),
|
||||||
|
|
||||||
didInsertElement: function () {
|
didInsertElement: function() {
|
||||||
$(document).keypress((event) => {
|
$(document).keypress(event => {
|
||||||
if (!this.get('saveDisabled') && event.which === 13) {
|
if (!this.get('saveDisabled') && event.which === 13) {
|
||||||
this.send('add');
|
this.send('add');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import visualizerMixin from './mixins/visualizer';
|
||||||
const { Component, observer, isEmpty, isNone, $, run: { later, next } } = Ember;
|
const { Component, observer, isEmpty, isNone, $, run: { later, next } } = Ember;
|
||||||
|
|
||||||
export default Component.extend(helperMixin, visualizerMixin, {
|
export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
updatePageTitle: observer('playQueuePointer', function () {
|
updatePageTitle: observer('playQueuePointer', function() {
|
||||||
let title = 'Huegasm',
|
let title = 'Huegasm',
|
||||||
playQueuePointer = this.get('playQueuePointer'),
|
playQueuePointer = this.get('playQueuePointer'),
|
||||||
playQueue = this.get('playQueue');
|
playQueue = this.get('playQueue');
|
||||||
|
|
@ -17,7 +17,7 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
title = song.title;
|
title = song.title;
|
||||||
|
|
||||||
if (song.artist) {
|
if (song.artist) {
|
||||||
title += (' - ' + song.artist);
|
title += ' - ' + song.artist;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
title = song.fileName;
|
title = song.fileName;
|
||||||
|
|
@ -64,12 +64,14 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
oldBeatPrefCache = this.get('oldBeatPrefCache'),
|
oldBeatPrefCache = this.get('oldBeatPrefCache'),
|
||||||
newOldBeatPrefCache = null;
|
newOldBeatPrefCache = null;
|
||||||
|
|
||||||
if (!isNone(preference)) { // load existing beat prefs
|
if (!isNone(preference)) {
|
||||||
|
// load existing beat prefs
|
||||||
newOldBeatPrefCache = { threshold: this.get('threshold') };
|
newOldBeatPrefCache = { threshold: this.get('threshold') };
|
||||||
|
|
||||||
this.changePlayerControl('threshold', preference.threshold);
|
this.changePlayerControl('threshold', preference.threshold);
|
||||||
this.set('usingBeatPreferences', true);
|
this.set('usingBeatPreferences', true);
|
||||||
} else if (!isNone(oldBeatPrefCache)) { // revert to using beat prefs before the remembered song
|
} else if (!isNone(oldBeatPrefCache)) {
|
||||||
|
// revert to using beat prefs before the remembered song
|
||||||
this.changePlayerControl('threshold', oldBeatPrefCache.threshold);
|
this.changePlayerControl('threshold', oldBeatPrefCache.threshold);
|
||||||
this.set('usingBeatPreferences', false);
|
this.set('usingBeatPreferences', false);
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +108,12 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
|
|
||||||
dragLeave() {
|
dragLeave() {
|
||||||
// need to delay the dragLeave notification to avoid flickering (hovering over some page elements causes this event to be sent)
|
// need to delay the dragLeave notification to avoid flickering (hovering over some page elements causes this event to be sent)
|
||||||
this.set('dragLeaveTimeoutHandle', setTimeout(() => { this.set('dragging', false); }, 500));
|
this.set(
|
||||||
|
'dragLeaveTimeoutHandle',
|
||||||
|
setTimeout(() => {
|
||||||
|
this.set('dragging', false);
|
||||||
|
}, 500)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
simulateKick() {
|
simulateKick() {
|
||||||
|
|
@ -118,7 +125,7 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
let options = { bri, transitiontime: 0 };
|
let options = { bri, transitiontime: 0 };
|
||||||
|
|
||||||
if (!transitiontime) {
|
if (!transitiontime) {
|
||||||
options.transitiontime = 1;
|
options.transitiontime = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNone(hue)) {
|
if (!isNone(hue)) {
|
||||||
|
|
@ -168,20 +175,32 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
timeToBriOff = 80;
|
timeToBriOff = 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
later(this, () => {
|
later(
|
||||||
stimulateLight(light, brightnessRange[1], true);
|
this,
|
||||||
later(this, stimulateLight, light, brightnessRange[0], false, color, timeToBriOff);
|
() => {
|
||||||
}, this.get('beatDelay'));
|
stimulateLight(light, brightnessRange[1], true);
|
||||||
|
later(this, stimulateLight, light, brightnessRange[0], false, color, timeToBriOff);
|
||||||
|
},
|
||||||
|
this.get('beatDelay')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('paused', true);
|
this.set('paused', true);
|
||||||
later(this, function () {
|
later(
|
||||||
this.set('paused', false);
|
this,
|
||||||
}, 200);
|
function() {
|
||||||
|
this.set('paused', false);
|
||||||
|
},
|
||||||
|
200
|
||||||
|
);
|
||||||
|
|
||||||
//work the music beat area - simulate the speaker vibration by running a CSS animation on it
|
//work the music beat area - simulate the speaker vibration by running a CSS animation on it
|
||||||
$('#beat-speaker-center-outer').velocity({ blur: 3 }, 100).velocity({ blur: 0 }, 100);
|
$('#beat-speaker-center-outer')
|
||||||
$('#beat-speaker-center-inner').velocity({ scale: 1.05 }, 100).velocity({ scale: 1 }, 100);
|
.velocity({ blur: 3 }, 100)
|
||||||
|
.velocity({ blur: 0 }, 100);
|
||||||
|
$('#beat-speaker-center-inner')
|
||||||
|
.velocity({ scale: 1.05 }, 100)
|
||||||
|
.velocity({ scale: 1 }, 100);
|
||||||
},
|
},
|
||||||
|
|
||||||
doAmbience(mag) {
|
doAmbience(mag) {
|
||||||
|
|
@ -189,12 +208,13 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
|
|
||||||
if (mag > 0.01 && !this.pauseAmbience && activeLights.length > 0) {
|
if (mag > 0.01 && !this.pauseAmbience && activeLights.length > 0) {
|
||||||
let _stimulateLight = (lightIndex, options) => {
|
let _stimulateLight = (lightIndex, options) => {
|
||||||
$.ajax(this.get('apiURL') + '/lights/' + lightIndex + '/state', {
|
$.ajax(this.get('apiURL') + '/lights/' + lightIndex + '/state', {
|
||||||
data: JSON.stringify(options),
|
data: JSON.stringify(options),
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
type: 'PUT'
|
type: 'PUT'
|
||||||
});
|
});
|
||||||
}, lightIndex = Math.floor(Math.random() * activeLights.length);
|
},
|
||||||
|
lightIndex = Math.floor(Math.random() * activeLights.length);
|
||||||
|
|
||||||
// let's try not to select the same light twice in a row
|
// let's try not to select the same light twice in a row
|
||||||
if (activeLights.length > 1) {
|
if (activeLights.length > 1) {
|
||||||
|
|
@ -210,14 +230,14 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
this.lastAmbienceLightIndex = lightIndex;
|
this.lastAmbienceLightIndex = lightIndex;
|
||||||
|
|
||||||
_stimulateLight(light, { bri: Math.floor(brightnessRange[1] / 1.4), hue, transitiontime: Math.floor(Math.random() * 4) + 4 });
|
_stimulateLight(light, { bri: Math.floor(brightnessRange[1] / 1.4), hue, transitiontime: Math.floor(Math.random() * 4) + 4 });
|
||||||
setTimeout(function () {
|
setTimeout(function() {
|
||||||
hue = Math.floor(Math.random() * (hueRange[1] - hueRange[0] + 1) + hueRange[0]);
|
hue = Math.floor(Math.random() * (hueRange[1] - hueRange[0] + 1) + hueRange[0]);
|
||||||
|
|
||||||
_stimulateLight(light, { bri: brightnessRange[0], hue, transitiontime: Math.floor(Math.random() * 4) + 4 });
|
_stimulateLight(light, { bri: brightnessRange[0], hue, transitiontime: Math.floor(Math.random() * 4) + 4 });
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
this.pauseAmbience = true;
|
this.pauseAmbience = true;
|
||||||
let pauseTime = Math.floor(1000 + (2000 / activeLights.length));
|
let pauseTime = Math.floor(1000 + 2000 / activeLights.length);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.pauseAmbience = false;
|
this.pauseAmbience = false;
|
||||||
|
|
@ -228,9 +248,15 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
|
window.requestAnimationFrame =
|
||||||
window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame;
|
window.requestAnimationFrame ||
|
||||||
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
window.webkitRequestAnimationFrame ||
|
||||||
|
window.mozRequestAnimationFrame ||
|
||||||
|
window.msRequestAnimationFrame;
|
||||||
|
window.cancelAnimationFrame =
|
||||||
|
window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame;
|
||||||
|
navigator.getUserMedia =
|
||||||
|
navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
||||||
|
|
||||||
let dancer = new Dancer(),
|
let dancer = new Dancer(),
|
||||||
storage = this.get('storage'),
|
storage = this.get('storage'),
|
||||||
|
|
@ -241,7 +267,7 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
this.simulateKick(mag, ratioKickMag);
|
this.simulateKick(mag, ratioKickMag);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
offKick: (mag) => {
|
offKick: mag => {
|
||||||
if (this.get('ambienceMode')) {
|
if (this.get('ambienceMode')) {
|
||||||
this.doAmbience(mag);
|
this.doAmbience(mag);
|
||||||
}
|
}
|
||||||
|
|
@ -255,7 +281,25 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
kick: kick
|
kick: kick
|
||||||
});
|
});
|
||||||
|
|
||||||
['volume', 'shuffle', 'repeat', 'volumeMuted', 'threshold', 'ambienceMode', 'blackoutMode', 'playerBottomDisplayed', 'songBeatPreferences', 'firstVisit', 'currentVisName', 'playQueue', 'playQueuePointer', 'flashingTransitions', 'hueRange', 'brightnessRange', 'beatDelay'].forEach((item) => {
|
[
|
||||||
|
'volume',
|
||||||
|
'shuffle',
|
||||||
|
'repeat',
|
||||||
|
'volumeMuted',
|
||||||
|
'threshold',
|
||||||
|
'ambienceMode',
|
||||||
|
'blackoutMode',
|
||||||
|
'playerBottomDisplayed',
|
||||||
|
'songBeatPreferences',
|
||||||
|
'firstVisit',
|
||||||
|
'currentVisName',
|
||||||
|
'playQueue',
|
||||||
|
'playQueuePointer',
|
||||||
|
'flashingTransitions',
|
||||||
|
'hueRange',
|
||||||
|
'brightnessRange',
|
||||||
|
'beatDelay'
|
||||||
|
].forEach(item => {
|
||||||
if (!isNone(storage.get('huegasm.' + item))) {
|
if (!isNone(storage.get('huegasm.' + item))) {
|
||||||
let itemVal = storage.get('huegasm.' + item);
|
let itemVal = storage.get('huegasm.' + item);
|
||||||
|
|
||||||
|
|
@ -280,33 +324,33 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
// file input code
|
// file input code
|
||||||
$('#file-input').on('change', function () {
|
$('#file-input').on('change', function() {
|
||||||
let files = this.files;
|
let files = this.files;
|
||||||
self.send('handleNewFiles', files);
|
self.send('handleNewFiles', files);
|
||||||
this.value = null; // reset in case upload the second file again
|
this.value = null; // reset in case upload the second file again
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('click', '.alert', (event) => {
|
$(document).on('click', '.alert', event => {
|
||||||
$(event.target).addClass('removed');
|
$(event.target).addClass('removed');
|
||||||
});
|
});
|
||||||
|
|
||||||
// prevent space/text selection when the user repeatedly clicks on the center
|
// prevent space/text selection when the user repeatedly clicks on the center
|
||||||
$('#beat-container').on('mousedown', '#beat-speaker-center-inner', function (event) {
|
$('#beat-container').on('mousedown', '#beat-speaker-center-inner', function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).keypress((event) => {
|
$(document).keypress(event => {
|
||||||
if (event.which === 32 && event.target.type !== 'text') {
|
if (event.which === 32 && event.target.type !== 'text') {
|
||||||
this.send('play');
|
this.send('play');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$().on('drop', '#play-list-area', (event) => {
|
this.$().on('drop', '#play-list-area', event => {
|
||||||
this.send('dropFiles', event.dataTransfer.files);
|
this.send('dropFiles', event.dataTransfer.files);
|
||||||
});
|
});
|
||||||
|
|
||||||
// control the volume by scrolling up/down
|
// control the volume by scrolling up/down
|
||||||
$('#player-area').on('mousewheel', (event) => {
|
$('#player-area').on('mousewheel', event => {
|
||||||
if (this.get('playQueueNotEmpty')) {
|
if (this.get('playQueueNotEmpty')) {
|
||||||
let scrollSize = 5;
|
let scrollSize = 5;
|
||||||
|
|
||||||
|
|
@ -368,59 +412,77 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
},
|
},
|
||||||
handleNewSoundCloudURL(URL) {
|
handleNewSoundCloudURL(URL) {
|
||||||
if (URL) {
|
if (URL) {
|
||||||
SC.resolve(URL).then((resultObj) => {
|
SC.resolve(URL).then(
|
||||||
let processResult = (result) => {
|
resultObj => {
|
||||||
if (result.kind === 'user') {
|
let processResult = result => {
|
||||||
this.get('notify').alert({ html: this.get('scUserNotSupportedHtml') });
|
if (result.kind === 'user') {
|
||||||
} else if (result.kind === 'track') {
|
this.get('notify').alert({ html: this.get('scUserNotSupportedHtml') });
|
||||||
if (result.streamable === true) {
|
} else if (result.kind === 'track') {
|
||||||
let picture = null;
|
if (result.streamable === true) {
|
||||||
|
let picture = null;
|
||||||
|
|
||||||
if (result.artwork_url) {
|
if (result.artwork_url) {
|
||||||
picture = result.artwork_url.replace('large', 't67x67');
|
picture = result.artwork_url.replace('large', 't67x67');
|
||||||
} else if (result.user.avatar_url) {
|
} else if (result.user.avatar_url) {
|
||||||
picture = result.user.avatar_url;
|
picture = result.user.avatar_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.get(picture)
|
||||||
|
.done(() => {
|
||||||
|
this.get('playQueue').pushObject({
|
||||||
|
url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'),
|
||||||
|
fileName: result.title + ' - ' + result.user.username,
|
||||||
|
artist: result.user.username,
|
||||||
|
scUrl: result.permalink_url,
|
||||||
|
title: result.title,
|
||||||
|
picture: picture
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.fail(() => {
|
||||||
|
// no picture
|
||||||
|
this.get('playQueue').pushObject({
|
||||||
|
url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'),
|
||||||
|
fileName: result.title + ' - ' + result.user.username,
|
||||||
|
artist: result.user.username,
|
||||||
|
scUrl: result.permalink_url,
|
||||||
|
title: result.title
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
failedSongs.push(result.title);
|
||||||
|
}
|
||||||
|
} else if (result.kind === 'playlist') {
|
||||||
|
if (result.streamable === true) {
|
||||||
|
result.tracks.forEach(processResult);
|
||||||
|
} else {
|
||||||
|
failedSongs.push(result.title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
failedSongs = [];
|
||||||
|
|
||||||
$.get(picture)
|
if (resultObj instanceof Array) {
|
||||||
.done(() => {
|
resultObj.forEach(processResult);
|
||||||
this.get('playQueue').pushObject({ url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), fileName: result.title + ' - ' + result.user.username, artist: result.user.username, scUrl: result.permalink_url, title: result.title, picture: picture });
|
} else {
|
||||||
}).fail(() => { // no picture
|
processResult(resultObj);
|
||||||
this.get('playQueue').pushObject({ url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), fileName: result.title + ' - ' + result.user.username, artist: result.user.username, scUrl: result.permalink_url, title: result.title });
|
}
|
||||||
});
|
|
||||||
|
if (failedSongs.length > 0) {
|
||||||
|
this.get('notify').alert({ html: this.get('notStreamableHtml')(failedSongs) });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.get('playQueuePointer') === -1) {
|
||||||
|
if (this.get('firstVisit')) {
|
||||||
|
this.send('goToSong', 0);
|
||||||
} else {
|
} else {
|
||||||
failedSongs.push(result.title);
|
this.send('next');
|
||||||
}
|
|
||||||
} else if (result.kind === 'playlist') {
|
|
||||||
if (result.streamable === true) {
|
|
||||||
result.tracks.forEach(processResult);
|
|
||||||
} else {
|
|
||||||
failedSongs.push(result.title);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
failedSongs = [];
|
() => {
|
||||||
|
this.get('notify').alert({ html: this.get('urlNotFoundHtml')(URL) });
|
||||||
if (resultObj instanceof Array) {
|
|
||||||
resultObj.forEach(processResult);
|
|
||||||
} else {
|
|
||||||
processResult(resultObj);
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
if (failedSongs.length > 0) {
|
|
||||||
this.get('notify').alert({ html: this.get('notStreamableHtml')(failedSongs) });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.get('playQueuePointer') === -1) {
|
|
||||||
if (this.get('firstVisit')) {
|
|
||||||
this.send('goToSong', 0);
|
|
||||||
} else {
|
|
||||||
this.send('next');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, () => {
|
|
||||||
this.get('notify').alert({ html: this.get('urlNotFoundHtml')(URL) });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('isShowingAddSoundCloudModal', false);
|
this.set('isShowingAddSoundCloudModal', false);
|
||||||
|
|
@ -435,7 +497,8 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
this.changePlayerControl('playerBottomDisplayed', !this.get('playerBottomDisplayed'));
|
this.changePlayerControl('playerBottomDisplayed', !this.get('playerBottomDisplayed'));
|
||||||
},
|
},
|
||||||
goToSong(index, playSong, scrollToSong) {
|
goToSong(index, playSong, scrollToSong) {
|
||||||
let dancer = this.get('dancer'), playQueue = this.get('playQueue');
|
let dancer = this.get('dancer'),
|
||||||
|
playQueue = this.get('playQueue');
|
||||||
|
|
||||||
if (dancer.audio) {
|
if (dancer.audio) {
|
||||||
this.clearCurrentAudio(true);
|
this.clearCurrentAudio(true);
|
||||||
|
|
@ -445,12 +508,12 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
let audio = new Audio();
|
let audio = new Audio();
|
||||||
audio.src = this.get('playQueue')[index].url;
|
audio.src = this.get('playQueue')[index].url;
|
||||||
|
|
||||||
audio.crossOrigin = "anonymous";
|
audio.crossOrigin = 'anonymous';
|
||||||
audio.oncanplay = () => {
|
audio.oncanplay = () => {
|
||||||
this.set('timeTotal', Math.floor(audio.duration));
|
this.set('timeTotal', Math.floor(audio.duration));
|
||||||
this.set('soundCloudFuckUps', 0);
|
this.set('soundCloudFuckUps', 0);
|
||||||
};
|
};
|
||||||
audio.onerror = (event) => {
|
audio.onerror = event => {
|
||||||
let playQueuePointer = this.get('playQueuePointer'),
|
let playQueuePointer = this.get('playQueuePointer'),
|
||||||
song = this.get('playQueue')[playQueuePointer];
|
song = this.get('playQueue')[playQueuePointer];
|
||||||
|
|
||||||
|
|
@ -514,7 +577,9 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
if (isEmpty($('#player-controls:hover')) && this.get('playQueuePointer') !== -1) {
|
if (isEmpty($('#player-controls:hover')) && this.get('playQueuePointer') !== -1) {
|
||||||
this.send('play');
|
this.send('play');
|
||||||
|
|
||||||
$('#play-notification').velocity({ opacity: 0.8, scale: 1 }, 0).velocity({ opacity: 0, scale: 3 }, 500);
|
$('#play-notification')
|
||||||
|
.velocity({ opacity: 0.8, scale: 1 }, 0)
|
||||||
|
.velocity({ opacity: 0, scale: 3 }, 500);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
play(replayPause) {
|
play(replayPause) {
|
||||||
|
|
@ -528,12 +593,12 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
dancer.pause();
|
dancer.pause();
|
||||||
|
|
||||||
let preMusicLightsDataCache = this.get('preMusicLightsDataCache'),
|
let preMusicLightsDataCache = this.get('preMusicLightsDataCache'),
|
||||||
updateLight = (lightIndex) => {
|
updateLight = lightIndex => {
|
||||||
$.ajax(this.get('apiURL') + '/lights/' + lightIndex + '/state', {
|
$.ajax(this.get('apiURL') + '/lights/' + lightIndex + '/state', {
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
'on': preMusicLightsDataCache[lightIndex].state.on,
|
on: preMusicLightsDataCache[lightIndex].state.on,
|
||||||
'hue': preMusicLightsDataCache[lightIndex].state.hue,
|
hue: preMusicLightsDataCache[lightIndex].state.hue,
|
||||||
'bri': preMusicLightsDataCache[lightIndex].state.bri
|
bri: preMusicLightsDataCache[lightIndex].state.bri
|
||||||
}),
|
}),
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
type: 'PUT'
|
type: 'PUT'
|
||||||
|
|
@ -587,17 +652,19 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
next(repeatAll) {
|
next(repeatAll) {
|
||||||
let playQueuePointer = this.get('playQueuePointer'),
|
let playQueuePointer = this.get('playQueuePointer'),
|
||||||
playQueue = this.get('playQueue'),
|
playQueue = this.get('playQueue'),
|
||||||
nextSong = (playQueuePointer + 1),
|
nextSong = playQueuePointer + 1,
|
||||||
repeat = this.get('repeat'),
|
repeat = this.get('repeat'),
|
||||||
shuffle = this.get('shuffle');
|
shuffle = this.get('shuffle');
|
||||||
|
|
||||||
if (repeat === 2) { // repeating one song takes precedence over shuffling
|
if (repeat === 2) {
|
||||||
|
// repeating one song takes precedence over shuffling
|
||||||
if (playQueuePointer === -1 && playQueue.length > 0) {
|
if (playQueuePointer === -1 && playQueue.length > 0) {
|
||||||
nextSong = 0;
|
nextSong = 0;
|
||||||
} else {
|
} else {
|
||||||
nextSong = playQueuePointer;
|
nextSong = playQueuePointer;
|
||||||
}
|
}
|
||||||
} else if (shuffle) { // next shuffle song
|
} else if (shuffle) {
|
||||||
|
// next shuffle song
|
||||||
let shufflePlayed = this.get('shufflePlayed');
|
let shufflePlayed = this.get('shufflePlayed');
|
||||||
|
|
||||||
// played all the song in shuffle mode
|
// played all the song in shuffle mode
|
||||||
|
|
@ -631,19 +698,22 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
let nextSong = this.get('playQueuePointer'),
|
let nextSong = this.get('playQueuePointer'),
|
||||||
playQueue = this.get('playQueue');
|
playQueue = this.get('playQueue');
|
||||||
|
|
||||||
if (this.get('shuffle') && !isNone(playQueue[nextSong])) { // go to the previously shuffled song
|
if (this.get('shuffle') && !isNone(playQueue[nextSong])) {
|
||||||
|
// go to the previously shuffled song
|
||||||
let shufflePlayed = this.get('shufflePlayed'),
|
let shufflePlayed = this.get('shufflePlayed'),
|
||||||
shuffledSongIndx = this.get('shufflePlayed').indexOf(playQueue[nextSong].url),
|
shuffledSongIndx = this.get('shufflePlayed').indexOf(playQueue[nextSong].url),
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (shufflePlayed.length > 0 && shuffledSongIndx !== -1) { // only if there was one
|
if (shufflePlayed.length > 0 && shuffledSongIndx !== -1) {
|
||||||
|
// only if there was one
|
||||||
nextSong = shuffledSongIndx - 1;
|
nextSong = shuffledSongIndx - 1;
|
||||||
|
|
||||||
if (nextSong < 0) {
|
if (nextSong < 0) {
|
||||||
nextSong = shufflePlayed.length - 1;
|
nextSong = shufflePlayed.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
playQueue.some(function (item) { // try to find the previous song id
|
playQueue.some(function(item) {
|
||||||
|
// try to find the previous song id
|
||||||
if (item.url === shufflePlayed[nextSong]) {
|
if (item.url === shufflePlayed[nextSong]) {
|
||||||
nextSong = i;
|
nextSong = i;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -685,7 +755,7 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addLocalAudio: function () {
|
addLocalAudio: function() {
|
||||||
$('#file-input').click();
|
$('#file-input').click();
|
||||||
},
|
},
|
||||||
shuffleChanged(value) {
|
shuffleChanged(value) {
|
||||||
|
|
@ -728,21 +798,21 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
handleNewFiles(files) {
|
handleNewFiles(files) {
|
||||||
let self = this,
|
let self = this,
|
||||||
playQueue = this.get('playQueue'),
|
playQueue = this.get('playQueue'),
|
||||||
updatePlayQueue = function () {
|
updatePlayQueue = function() {
|
||||||
let tags = ID3.getAllTags("local"),
|
let tags = ID3.getAllTags('local'),
|
||||||
picture = null;
|
picture = null;
|
||||||
|
|
||||||
if (tags.picture) {
|
if (tags.picture) {
|
||||||
let base64String = "";
|
let base64String = '';
|
||||||
for (let i = 0; i < tags.picture.data.length; i++) {
|
for (let i = 0; i < tags.picture.data.length; i++) {
|
||||||
base64String += String.fromCharCode(tags.picture.data[i]);
|
base64String += String.fromCharCode(tags.picture.data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
picture = "data:" + tags.picture.format + ";base64," + window.btoa(base64String);
|
picture = 'data:' + tags.picture.format + ';base64,' + window.btoa(base64String);
|
||||||
}
|
}
|
||||||
|
|
||||||
playQueue.pushObject({
|
playQueue.pushObject({
|
||||||
fileName: this.name.replace(/\.[^/.]+$/, ""),
|
fileName: this.name.replace(/\.[^/.]+$/, ''),
|
||||||
url: URL.createObjectURL(this),
|
url: URL.createObjectURL(this),
|
||||||
artist: tags.artist,
|
artist: tags.artist,
|
||||||
title: tags.title,
|
title: tags.title,
|
||||||
|
|
@ -762,7 +832,7 @@ export default Component.extend(helperMixin, visualizerMixin, {
|
||||||
let file = files[key];
|
let file = files[key];
|
||||||
|
|
||||||
if (file.type.startsWith('audio') || file.type.startsWith('video')) {
|
if (file.type.startsWith('audio') || file.type.startsWith('video')) {
|
||||||
ID3.loadTags("local", updatePlayQueue.bind(file), {
|
ID3.loadTags('local', updatePlayQueue.bind(file), {
|
||||||
dataReader: new FileAPIReader(file),
|
dataReader: new FileAPIReader(file),
|
||||||
tags: ['title', 'artist', 'album', 'track', 'picture']
|
tags: ['title', 'artist', 'album', 'track', 'picture']
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,9 @@ export default Mixin.create({
|
||||||
'<div class="alert alert-danger" role="alert">The SoundCloud API is not seving the audio properly. More details <a href="https://www.soundcloudcommunity.com/soundcloud/topics/some-soundcloud-cdn-hosted-tracks-dont-have-access-control-allow-origin-header" target="_blank" rel="noopener noreferrer">HERE</a>.</div>',
|
'<div class="alert alert-danger" role="alert">The SoundCloud API is not seving the audio properly. More details <a href="https://www.soundcloudcommunity.com/soundcloud/topics/some-soundcloud-cdn-hosted-tracks-dont-have-access-control-allow-origin-header" target="_blank" rel="noopener noreferrer">HERE</a>.</div>',
|
||||||
notStreamableHtml(fileNames) {
|
notStreamableHtml(fileNames) {
|
||||||
let html =
|
let html =
|
||||||
'<div class="alert alert-danger" role="alert">The following file(s) could not be added because they are not allowed to be streamed:<br>' + fileNames.toString().replace(/,/g, '<br>') + '</div>';
|
'<div class="alert alert-danger" role="alert">The following file(s) could not be added because they are not allowed to be streamed:<br>' +
|
||||||
|
fileNames.toString().replace(/,/g, '<br>') +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
|
|
@ -319,7 +321,10 @@ export default Mixin.create({
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
onOptionChange: observer('flashingTransitions', 'playQueue.[]', 'playQueuePointer', 'ambienceMode', 'blackoutMode', function(self, option) {
|
onOptionChange: observer('flashingTransitions', 'playQueue.[]', 'playQueuePointer', 'ambienceMode', 'blackoutMode', function(
|
||||||
|
self,
|
||||||
|
option
|
||||||
|
) {
|
||||||
option = option.replace('.[]', '');
|
option = option.replace('.[]', '');
|
||||||
let value = this.get(option);
|
let value = this.get(option);
|
||||||
|
|
||||||
|
|
@ -350,7 +355,7 @@ export default Mixin.create({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNone(value)) {
|
if (!isNone(value)) {
|
||||||
this.get('storage').set('huegasm.' + option, value);
|
this.get('storage').set('huegasm.' + option, value);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,16 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
const {
|
const { Mixin, observer, $ } = Ember;
|
||||||
Mixin,
|
|
||||||
observer,
|
|
||||||
$
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Mixin.create({
|
export default Mixin.create({
|
||||||
currentVisName: 'None',
|
currentVisName: 'None',
|
||||||
|
|
||||||
visNames: ['None', 'Bars', 'Wave'],
|
visNames: ['None', 'Bars', 'Wave'],
|
||||||
|
|
||||||
onCurrentVisNameChange: observer('currentVisName', function () {
|
onCurrentVisNameChange: observer('currentVisName', function() {
|
||||||
let currentVisName = this.get('currentVisName');
|
let currentVisName = this.get('currentVisName');
|
||||||
|
|
||||||
if(currentVisName === 'None'){
|
if (currentVisName === 'None') {
|
||||||
let canvasEl = $('#visualization')[0],
|
let canvasEl = $('#visualization')[0],
|
||||||
ctx = canvasEl.getContext('2d');
|
ctx = canvasEl.getContext('2d');
|
||||||
|
|
||||||
|
|
@ -24,19 +20,20 @@ export default Mixin.create({
|
||||||
this.get('storage').set('huegasm.currentVisName', currentVisName);
|
this.get('storage').set('huegasm.currentVisName', currentVisName);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
didInsertElement(){
|
didInsertElement() {
|
||||||
let dancer = this.get('dancer'),
|
let dancer = this.get('dancer'),
|
||||||
canvas = $('#visualization')[0],
|
canvas = $('#visualization')[0],
|
||||||
playerArea = $('#player-area'),
|
playerArea = $('#player-area'),
|
||||||
ctx = canvas.getContext('2d'),
|
ctx = canvas.getContext('2d'),
|
||||||
spacing = 2,
|
spacing = 2,
|
||||||
h = playerArea.height(), w;
|
h = playerArea.height(),
|
||||||
|
w;
|
||||||
|
|
||||||
canvas.height = h;
|
canvas.height = h;
|
||||||
|
|
||||||
// must be done to preserver resolution so that things don't appear blurry
|
// must be done to preserver resolution so that things don't appear blurry
|
||||||
// note that the height is set to 400px via css so it doesn't need to be recalculated
|
// note that the height is set to 400px via css so it doesn't need to be recalculated
|
||||||
let syncCanvasHeight = ()=>{
|
let syncCanvasHeight = () => {
|
||||||
w = playerArea.width();
|
w = playerArea.width();
|
||||||
canvas.width = w;
|
canvas.width = w;
|
||||||
};
|
};
|
||||||
|
|
@ -51,7 +48,7 @@ export default Mixin.create({
|
||||||
pageHidden = document.hidden || document.msHidden || document.webkitHidden || document.mozHidden;
|
pageHidden = document.hidden || document.msHidden || document.webkitHidden || document.mozHidden;
|
||||||
|
|
||||||
// dont do anything if the page is hidden or no visualization
|
// dont do anything if the page is hidden or no visualization
|
||||||
if(currentVisName === 'None' || pageHidden || !this.get('active')){
|
if (currentVisName === 'None' || pageHidden || !this.get('active')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +68,7 @@ export default Mixin.create({
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(0, h / 2);
|
ctx.moveTo(0, h / 2);
|
||||||
for (let i = 0, l = waveform.length; i < l && i < count; i++) {
|
for (let i = 0, l = waveform.length; i < l && i < count; i++) {
|
||||||
ctx.lineTo(i * ( spacing + width ), ( h / 2 ) + waveform[i] * ( h / 2 ));
|
ctx.lineTo(i * (spacing + width), h / 2 + waveform[i] * (h / 2));
|
||||||
}
|
}
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
|
|
@ -86,7 +83,7 @@ export default Mixin.create({
|
||||||
ctx.fillStyle = gradient;
|
ctx.fillStyle = gradient;
|
||||||
let spectrum = dancer.getSpectrum();
|
let spectrum = dancer.getSpectrum();
|
||||||
for (let i = 0, l = spectrum.length; i < l && i < count; i++) {
|
for (let i = 0, l = spectrum.length; i < l && i < count; i++) {
|
||||||
ctx.fillRect(i * ( spacing + width ), h, width, -spectrum[i] * h - 60);
|
ctx.fillRect(i * (spacing + width), h, width, -spectrum[i] * h - 60);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Reference in a new issue