305 lines
10 KiB
JavaScript
305 lines
10 KiB
JavaScript
import Ember from 'ember';
|
|
|
|
const { A, Component, computed, isEmpty, isNone, run: { later, scheduleOnce }, inject, $ } = Ember;
|
|
|
|
export default Component.extend({
|
|
classNames: ['container-fluid'],
|
|
elementId: 'hue-controls',
|
|
lightsData: null,
|
|
|
|
firstVisitApp: true,
|
|
activeLights: A(),
|
|
tabList: ['Lights', 'Music'],
|
|
selectedTab: 1,
|
|
pauseLightUpdates: false,
|
|
|
|
displayNextFailure: true,
|
|
|
|
notify: inject.service(),
|
|
|
|
dimmerOnClass: computed('dimmerOn', function() {
|
|
return this.get('dimmerOn') ? 'dimmerOn md-menu-origin' : 'md-menu-origin';
|
|
}),
|
|
|
|
ready: computed('lightsData', 'trial', function() {
|
|
return this.get('trial') || !isNone(this.get('lightsData'));
|
|
}),
|
|
|
|
apiURL: computed('bridgeIp', 'bridgeUsername', function() {
|
|
return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername');
|
|
}),
|
|
|
|
tabData: computed('tabList', 'selectedTab', function() {
|
|
let tabData = [],
|
|
selectedTab = this.get('selectedTab');
|
|
|
|
this.get('tabList').forEach(function(tab, i) {
|
|
let selected = false;
|
|
|
|
if (i === selectedTab) {
|
|
selected = true;
|
|
}
|
|
|
|
tabData.push({ name: tab, selected: selected });
|
|
});
|
|
|
|
return tabData;
|
|
}),
|
|
|
|
didInsertElement() {
|
|
if (!window.matchMedia || window.matchMedia('(min-width: 768px)').matches) {
|
|
// here's a weird way to automatically initialize bootstrap tooltips
|
|
let observer = new MutationObserver(function(mutations) {
|
|
let haveTooltip = !mutations.every(function(mutation) {
|
|
return (
|
|
isEmpty(mutation.addedNodes) || isNone(mutation.addedNodes[0].classList) || mutation.addedNodes[0].classList.contains('tooltip')
|
|
);
|
|
});
|
|
|
|
if (haveTooltip) {
|
|
scheduleOnce('afterRender', function() {
|
|
$('.bootstrap-tooltip').tooltip();
|
|
});
|
|
}
|
|
});
|
|
|
|
observer.observe($('#hue-controls')[0], { childList: true, subtree: true });
|
|
}
|
|
},
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
|
|
let storage = this.get('storage'),
|
|
firstVisitApp = storage.get('huegasm.firstVisitApp');
|
|
|
|
this.set('canTryChrome', /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor));
|
|
|
|
if (!isEmpty(firstVisitApp)) {
|
|
this.set('firstVisitApp', false);
|
|
}
|
|
|
|
if (!this.get('trial')) {
|
|
this.updateLightData();
|
|
setInterval(this.updateLightData.bind(this), 3000);
|
|
}
|
|
|
|
if (!isNone(storage.get('huegasm.selectedTab'))) {
|
|
this.set('selectedTab', this.get('storage').get('huegasm.selectedTab'));
|
|
}
|
|
},
|
|
|
|
updateLightData() {
|
|
let fail = () => {
|
|
if (isNone(this.get('lightsData'))) {
|
|
this.send('clearBridge');
|
|
} 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.set('displayNextFailure', false);
|
|
|
|
later(
|
|
this,
|
|
() => {
|
|
this.set('displayNextFailure', true);
|
|
},
|
|
30000
|
|
);
|
|
}
|
|
};
|
|
|
|
if (!this.get('pauseLightUpdates')) {
|
|
$.get(this.get('apiURL') + '/lights', (result, status) => {
|
|
if (!isNone(result[0]) && !isNone(result[0].error)) {
|
|
fail();
|
|
} else if (status === 'success' && JSON.stringify(this.get('lightsData')) !== JSON.stringify(result)) {
|
|
this.set('lightsData', result);
|
|
}
|
|
}).fail(fail);
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
tryAndroid() {
|
|
window.open('https://play.google.com/store/apps/details?id=com.hoboman313.huegasm', '_blank');
|
|
},
|
|
tryExtension() {
|
|
chrome.webstore.install('https://chrome.google.com/webstore/detail/mbjanbdhcpohhfecjgbdpcfhnnbofooj');
|
|
},
|
|
changeTab(tabName) {
|
|
let index = this.get('tabList').indexOf(tabName);
|
|
this.set('selectedTab', index);
|
|
this.get('storage').set('huegasm.selectedTab', index);
|
|
},
|
|
clearBridge() {
|
|
let storage = this.get('storage');
|
|
storage.remove('huegasm.bridgeUsername');
|
|
storage.remove('huegasm.bridgeIp');
|
|
location.reload();
|
|
},
|
|
toggleDimmer() {
|
|
this.sendAction('toggleDimmer');
|
|
},
|
|
toggleLightsIcons() {
|
|
this.sendAction('toggleLightsIcons');
|
|
},
|
|
clearAllSettings() {
|
|
this.get('storage').clear();
|
|
location.reload();
|
|
},
|
|
email() {
|
|
window.open('mailto:huegasm.app@gmail.com', '_blank');
|
|
},
|
|
startIntro() {
|
|
let intro = introJs(),
|
|
playerBottom = $('#player-bottom');
|
|
|
|
if (this.get('dimmerOn')) {
|
|
this.send('toggleDimmer');
|
|
}
|
|
|
|
intro.setOptions({
|
|
steps: [
|
|
{
|
|
intro: 'Welcome! This short tutorial will introduce you to Huegasm.'
|
|
},
|
|
{
|
|
element: '#music-tab',
|
|
intro:
|
|
"This is the music player. You'll use this to play music and synchronize it with your active lights.<br><br>" +
|
|
'<i><b>TIP</b>: Control which lights are active through the <b>Lights</b> tab.</i>'
|
|
},
|
|
{
|
|
element: '#playlist',
|
|
intro:
|
|
'You can add and select music to play from your playlist here. You may listen to local audio files or stream music from Soundcloud.<br><br>' +
|
|
'<i><b>TIP</b>: Songs added through Soundcloud will be saved for when you visit this page again.</i>'
|
|
},
|
|
{
|
|
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'
|
|
},
|
|
{
|
|
element: '#player-area',
|
|
intro:
|
|
'The audio playback may be controlled with the controls here. Basic music visualization effects may be shown here by selecting them from the menu (eyeball icon in the bottom right).'
|
|
},
|
|
{
|
|
element: '#beat-option-row',
|
|
intro:
|
|
'<b>Sensitivity</b> - The sensitivity of the beat detector (higher sensitivity results in more registered beats)<br>' +
|
|
'<b>Color Range</b> - The color range that the lights may change to on beat.<br>' +
|
|
'<b>Brightness Range</b> - The minimum (off-beat) and maximum (on-beat) brightness of the lights.<br>' +
|
|
'<b>Flashing Transitions</b> - Quickly flash the lights on beat<br>' +
|
|
'<b>Colorloop</b> - Slowly cycle the lights through all the colors while the music is playing<br>' +
|
|
'<b>Ambience</b> - When turned on, your lights will sporadically change color.<br>' +
|
|
'<b>Blackout</b> - When turned on, your lghts will turn off after flashing on a detected beat.<br><br>' +
|
|
'<i><b>TIP</b>: Your sensitivity settings are saved per song as indicated by the red star icon in the top left corner.</i>',
|
|
position: 'top'
|
|
},
|
|
{
|
|
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>',
|
|
position: 'top'
|
|
},
|
|
{
|
|
element: '#lights-tab',
|
|
intro:
|
|
"This is the lights tab. Here you'll be able to change various light properties:<br>" +
|
|
'<b>Power</b> - Turn the selected lights on/off<br>' +
|
|
'<b>Brightness</b> - The brightness level of the selected lights<br>' +
|
|
'<b>Color</b> - The color of the selected lights<br>' +
|
|
'<b>Strobe</b> - Selected lights will flash in sequential order<br>' +
|
|
'<b>Colorloop</b> - Selected lights will slowly cycle through all the colors<br>' +
|
|
'<b>Randomize Hues</b> - Randomize the hues (colors) of your selected lights<br>'
|
|
},
|
|
{
|
|
element: '#active-lights',
|
|
intro:
|
|
'These icons represent the hue lights in your system. Active lights will be controlled by the application while the inactive lights will have a red X over them and will not be controlled.<br>' +
|
|
"You may toggle a light's state by clicking on it."
|
|
},
|
|
{
|
|
element: $('#navigation .ember-basic-dropdown-trigger')[0],
|
|
intro:
|
|
'A few miscellaneous settings can be found here.<br><br>' +
|
|
'<b>WARNING</b>: clearing application settings will restore the application to its original state. This will even delete your playlist and any saved song beat preferences.'
|
|
},
|
|
{
|
|
intro: "And that's it...Hope you enjoy the application. ;)"
|
|
}
|
|
]
|
|
});
|
|
|
|
intro.onexit(() => {
|
|
$('body').velocity('scroll', { duration: 200 });
|
|
});
|
|
|
|
intro.onchange(element => {
|
|
if (
|
|
element.id === '' ||
|
|
element.id === 'music-tab' ||
|
|
element.id === 'playlist' ||
|
|
element.id === 'player-area' ||
|
|
element.id === 'beat-option-row' ||
|
|
element.id === 'beat-option-button-group' ||
|
|
element.id === 'beat-container' ||
|
|
element.id === 'using-mic-audio-tooltip' ||
|
|
element.nodeName === 'MD-MENU'
|
|
) {
|
|
$('.navigation-item')
|
|
.eq(1)
|
|
.click();
|
|
} else {
|
|
$('.navigation-item')
|
|
.eq(0)
|
|
.click();
|
|
}
|
|
|
|
if (element.id === 'music-tab' || element.id === 'playlist' || element.id === 'player-area') {
|
|
playerBottom.hide();
|
|
} else if (element.id === 'beat-option-row' || element.id === 'beat-option-button-group' || element.id === 'beat-container') {
|
|
playerBottom.show();
|
|
} else if (element.id === 'dimmer') {
|
|
$(document).click();
|
|
}
|
|
});
|
|
|
|
// skip hidden/missing elements
|
|
intro
|
|
.onafterchange(element => {
|
|
let elem = $(element);
|
|
if (elem.html() === '<!---->') {
|
|
$('.introjs-nextbutton').click();
|
|
}
|
|
|
|
if (element.id === '') {
|
|
later(
|
|
this,
|
|
() => {
|
|
$('body').velocity('scroll');
|
|
},
|
|
500
|
|
);
|
|
} else {
|
|
later(
|
|
this,
|
|
() => {
|
|
$('.introjs-tooltip').velocity('scroll', { offset: -100 });
|
|
},
|
|
500
|
|
);
|
|
}
|
|
})
|
|
.start();
|
|
},
|
|
closeNotificationModal() {
|
|
this.set('firstVisitApp', false);
|
|
this.get('storage').set('huegasm.firstVisitApp', false);
|
|
}
|
|
}
|
|
});
|