This repository has been archived on 2026-04-30. You can view files and clone it, but cannot push or open issues or pull requests.
huegasm/web/app/pods/components/hue-controls/component.js

263 lines
10 KiB
JavaScript

/*global chrome introJs*/
import Ember from 'ember';
const { A, Component, computed, isEmpty, isNone, run: { later, scheduleOnce }, inject, $, set } = Ember;
export default Component.extend({
classNames: ['container-fluid'],
elementId: 'hue-controls',
lightsData: null,
firstVisitApp: true,
activeLights: A(),
tabList: ["Lights", "Music"],
selectedTab: 1,
pauseLightUpdates: false,
displayFailure: 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 isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor),
storage = this.get('storage'),
firstVisitApp = storage.get('huegasm.firstVisitApp');
if (!isEmpty(firstVisitApp)) {
this.set('firstVisitApp', false);
}
if (!this.get('trial')) {
this.updateLightData();
setInterval(this.updateLightData.bind(this), 2000);
}
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('displayFailure')) {
this.get('notify').warning({ html: '<div class="alert alert-warning" role="alert">Error retrieving data from your lights. Yikes.</div>' });
this.set('displayFailure', false);
later(this, function () {
this.set('displayFailure', 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);
}
}
});