self advertising other huegasm projects on web, no jquery for background chrome, adding missing features and fixing bugs for chrome

This commit is contained in:
Egor 2017-02-27 01:12:33 -08:00
parent 3230831d72
commit c7a786b0ca
22 changed files with 162 additions and 207 deletions

View file

@ -3,11 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Huegasm</title> <title>Huegasm</title>
<meta name="description" content="Huegasm is a free web application for managing and synchronizing your Philips Hue lights with the beat of your music.">
<meta name="keywords" content="huegasm,hue,philips hue,lights,ambience,music player">
<meta name="author" content="Egor Philippov">
<meta name="viewport" content="width=device-width, initial-scale=1"> {{content-for 'head'}} <meta name="viewport" content="width=device-width, initial-scale=1"> {{content-for 'head'}}
<link href='https://fonts.googleapis.com/css?family=Open+Sans|Raleway' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Open+Sans|Raleway' rel='stylesheet' type='text/css'>

View file

@ -31,12 +31,13 @@
</div> </div>
</div> </div>
{{light-group lightsData=lightsData activeLights=activeLights syncLight=syncLight apiURL=apiURL dimmerOn=dimmerOn lightsIconsOn=lightsIconsOn}} {{light-group lightsData=lightsData activeLights=activeLights syncLight=syncLight apiURL=apiURL dimmerOn=dimmerOn lightsIconsOn=lightsIconsOn pauseLightUpdates=pauseLightUpdates}}
<div id="huegasm-content" class="row"> <div class="row">
{{lights-tab active=(eq selectedTab 0) apiURL=apiURL lightsData=lightsData activeLights=activeLights syncLight=syncLight {{lights-tab active=(eq selectedTab 0) apiURL=apiURL lightsData=lightsData activeLights=activeLights syncLight=syncLight
trial=trial colorLoopOn=colorLoopOn dimmerOn=dimmerOn playing=playing pauseLightUpdates=pauseLightUpdates}} {{music-tab trial=trial colorLoopOn=colorLoopOn dimmerOn=dimmerOn playing=playing pauseLightUpdates=pauseLightUpdates}}
active=(eq selectedTab 1) apiURL=apiURL lightsData=lightsData activeLights=activeLights pauseLightUpdates=pauseLightUpdates
{{music-tab active=(eq selectedTab 1) apiURL=apiURL lightsData=lightsData activeLights=activeLights pauseLightUpdates=pauseLightUpdates
dimmerOn=dimmerOn colorLoopOn=colorLoopOn playing=playing action="startIntro"}} dimmerOn=dimmerOn colorLoopOn=colorLoopOn playing=playing action="startIntro"}}
</div> </div>
{{else}} {{else}}

View file

@ -125,38 +125,40 @@ export default Component.extend({
} }
}, },
lightStartHover(id) { lightStartHover(id) {
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) {
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
data: JSON.stringify({ "alert": "lselect" }),
contentType: 'application/json',
type: 'PUT'
}); });
if (!isEmpty(hoveredLight) && this.get('noHover') !== true) {
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
data: JSON.stringify({ "alert": "lselect" }),
contentType: 'application/json',
type: 'PUT'
});
}
this.set('isHovering', true);
} }
this.setProperties({
pauseLightUpdates: true,
isHovering: true
});
}, },
lightStopHover(id) { lightStopHover(id) {
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) {
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
data: JSON.stringify({ "alert": "none" }),
contentType: 'application/json',
type: 'PUT'
}); });
if (!isEmpty(hoveredLight) && this.get('noHover') !== true) {
$.ajax(this.get('apiURL') + '/lights/' + id + '/state', {
data: JSON.stringify({ "alert": "none" }),
contentType: 'application/json',
type: 'PUT'
});
}
this.set('isHovering', false);
} }
this.setProperties({
pauseLightUpdates: false,
isHovering: false
});
} }
} }
}); });

View file

@ -95,7 +95,7 @@ export default Component.extend({
} }
}, },
threshold: 0.3, threshold: 0.2,
hueRange: [0, 65535], hueRange: [0, 65535],
brightnessRange: [1, 254], brightnessRange: [1, 254],
@ -126,10 +126,9 @@ export default Component.extend({
} }
}), }),
onConfigItemChanged: observer('threshold', 'hueRange', 'brightnessRange', 'isListenining', function (wtf, name) { onConfigItemChanged: observer('threshold', 'hueRange', 'brightnessRange', 'isListenining', function (_class, name) {
once(this, () => { once(this, () => {
let value = this.get(name), let value = this.get(name);
self = this;
this.set(name, value); this.set(name, value);
@ -137,11 +136,11 @@ export default Component.extend({
if (value) { if (value) {
chrome.storage.local.get('currentlyListenining', ({currentlyListenining}) => { chrome.storage.local.get('currentlyListenining', ({currentlyListenining}) => {
if (!currentlyListenining) { if (!currentlyListenining) {
chrome.runtime.sendMessage({ action: 'start-listening' }, function (response) { chrome.runtime.sendMessage({ action: 'start-listening' }, (response) => {
if (response && response.error) { if (response && response.error) {
self.get('notify').warning({ html: '<div class="alert alert-warning" role="alert">' + response.error + '</div>' }); this.get('notify').warning({ html: '<div class="alert alert-warning" role="alert">' + response.error + '</div>' });
self.set('isListenining', false); this.set('isListenining', false);
chrome.storage.local.set({ isListenining: false }); chrome.storage.local.set({ isListenining: false });
} }
}); });

View file

@ -1,6 +1,11 @@
<div id="fancy-button-wrapper"> <div id="fancy-button-wrapper">
<div id="start-listening" data-toggle="tooltip" data-placement="top" data-title="Toggle to have Huegasm start/stop listening on your active Chrome tab" class="bootstrap-tooltip">
{{if isListenining "Stop" "Start"}} Listening
</div>
<a href="#" data-content="Click here for Huegasm to start listening to your current tab" class="fancy-button note {{if isListenining "active"}}" <a href="#" data-content="Click here for Huegasm to start listening to your current tab" class="fancy-button note {{if isListenining "active"}}"
{{action "toggleListening"}}></a> {{action "toggleListening"}}>
</a>
</div> </div>
<div class="row {{if dimmerOn "dimmerOn"}}"> <div class="row {{if dimmerOn "dimmerOn"}}">

View file

@ -58,28 +58,3 @@ div.ember-modal-dialog {
.display-flex { .display-flex {
display: flex !important; display: flex !important;
} }
// fancy webkit scrollbars
::-webkit-scrollbar {
-webkit-appearance: none;
}
::-webkit-scrollbar:vertical {
width: 12px;
}
::-webkit-scrollbar:horizontal {
height: 12px;
}
::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, .5);
border-radius: 10px;
border: 2px solid #ffffff;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
}
::-webkit-scrollbar-track {
background-color: #ffffff;
}

View file

@ -15,13 +15,10 @@
margin: 30px auto 20px; margin: 30px auto 20px;
} }
#bridge-finder, .ready-block {
text-align: center;
padding: 10px 15px 0;
font-size: 16px;
}
#bridge-finder { #bridge-finder {
text-align: center;
padding: 20px;
font-size: 16px;
flex-direction: column; flex-direction: column;
display: flex; display: flex;
justify-content: center; justify-content: center;

View file

@ -33,7 +33,7 @@
} }
#navigation { #navigation {
padding: 5px 0 2vh; padding: 5px 0 1vh;
text-align: center; text-align: center;
margin: auto; margin: auto;
position: relative; position: relative;
@ -95,10 +95,6 @@
font-size: 16px !important; font-size: 16px !important;
} }
#huegasm-content {
height: 80%;
max-height: 500px;
}
@media(min-width:767px) { @media(min-width:767px) {
#lights-tab { #lights-tab {

View file

@ -1,6 +1,6 @@
.light-group { .light-group {
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 5px auto;
display: flex; display: flex;
justify-content: center; justify-content: center;
.tooltip.top { .tooltip.top {

View file

@ -4,12 +4,11 @@
#music-tab { #music-tab {
padding: 0; padding: 0;
margin-top: 20px; margin-top: 5px;
} }
#beat-area { #beat-area {
position: relative; position: relative;
padding: 0 0 10px;
} }
#beat-option-button-group { #beat-option-button-group {
@ -17,7 +16,7 @@
} }
.beat-option { .beat-option {
padding: 5px 0; padding: 10px 0;
text-align: center; text-align: center;
md-checkbox { md-checkbox {
padding: 10px 0; padding: 10px 0;
@ -30,49 +29,27 @@
font-size: 16px; font-size: 16px;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
padding: 10px 0; padding: 5px 0;
} }
button { button {
margin-top: 0; margin-top: 0;
} }
.tooltip { .tooltip {
margin: 0; margin: 0;
display: inline-block !important;
} }
} }
#player-bottom { #start-listening {
color: $blackish; margin-bottom: 5px;
border: 1px solid black; font-size: 18px;
width: 100%;
background: white;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
display: flex;
align-items: center;
}
#beat-area .light-group {
margin: 10px 20px 0 40px;
float: right;
div {
display: block;
padding: 10px;
}
}
.close {
font-size: 18px !important;
color: rgb(51, 51, 51);
display: none;
text-shadow: none;
&:hover {
color: darken(#333333, 5%) !important;
}
} }
#fancy-button-wrapper { #fancy-button-wrapper {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
flex-direction: column;
} }
.fancy-button { .fancy-button {
@ -132,12 +109,6 @@
} }
} }
@media(max-width: 500px) {
.option-description {
height: 55px;
}
}
// mobile overrides // mobile overrides
@media(max-width:767px) { @media(max-width:767px) {
div#player-bottom { div#player-bottom {

View file

@ -63,7 +63,7 @@ md-switch.md-default-theme.md-checked .md-thumb {
} }
md-list-item { md-list-item {
margin-bottom: 1vh; margin-bottom: 2vh;
} }
@media(max-width:500px) { @media(max-width:500px) {

View file

@ -9,7 +9,7 @@ let isNone = function (obj) {
// the main ember app controls may change these // the main ember app controls may change these
let state = { let state = {
activeLights: [], activeLights: [],
threshold: 0.3, threshold: 0.2,
hueRange: [0, 65535], hueRange: [0, 65535],
brightnessRange: [1, 254], brightnessRange: [1, 254],
bridgeIp: null, bridgeIp: null,
@ -113,6 +113,33 @@ chrome.storage.onChanged.addListener(function ({activeLights, threshold, hueRang
chrome.storage.local.set({ currentlyListenining: false }); chrome.storage.local.set({ currentlyListenining: false });
chrome.browserAction.setBadgeBackgroundColor({ color: [80, 80, 80, 255] }); chrome.browserAction.setBadgeBackgroundColor({ color: [80, 80, 80, 255] });
let stopListening = function () {
chrome.browserAction.setBadgeText({ text: "" });
chrome.storage.local.set({ currentlyListenining: false });
if (state.preMusicLightsDataCache) {
let updateLight = function (lightIndex) {
let xhr = new XMLHttpRequest();
xhr.open('PUT', 'http://' + state.bridgeIp + '/api/' + state.bridgeUsername + '/lights/' + lightIndex + '/state', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
'on': state.preMusicLightsDataCache[lightIndex].state.on,
'hue': state.preMusicLightsDataCache[lightIndex].state.hue,
'bri': state.preMusicLightsDataCache[lightIndex].state.bri
}));
};
for (let key in state.lightsData) {
if (state.lightsData.hasOwnProperty(key)) {
setTimeout(function () {
updateLight(key);
}, 1000);
}
}
}
};
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action === 'start-listening') { if (request.action === 'start-listening') {
chrome.tabCapture.capture({ chrome.tabCapture.capture({
@ -129,6 +156,12 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
chrome.storage.local.set({ currentlyListenining: true }); chrome.storage.local.set({ currentlyListenining: true });
chrome.browserAction.setBadgeText({ text: "♪" }); chrome.browserAction.setBadgeText({ text: "♪" });
state.preMusicLightsDataCache = state.lightsData; state.preMusicLightsDataCache = state.lightsData;
stream.getTracks()[0].onended = function () {
chrome.storage.local.set({ isListenining: false });
stopListening();
};
} }
sendResponse({ error }); sendResponse({ error });
@ -138,28 +171,8 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
} else if (request.action === 'stop-listening' && stream !== null) { } else if (request.action === 'stop-listening' && stream !== null) {
stream.getTracks()[0].stop(); stream.getTracks()[0].stop();
stream = null; stream = null;
chrome.browserAction.setBadgeText({ text: "" });
chrome.storage.local.set({ currentlyListenining: false });
let updateLight = function (lightIndex) { stopListening();
$.ajax('http://' + state.bridgeIp + '/api/' + state.bridgeUsername + '/lights/' + lightIndex + '/state', {
data: JSON.stringify({
'on': state.preMusicLightsDataCache[lightIndex].state.on,
'hue': state.preMusicLightsDataCache[lightIndex].state.hue,
'bri': state.preMusicLightsDataCache[lightIndex].state.bri
}),
contentType: 'application/json',
type: 'PUT'
});
};
for (let key in state.lightsData) {
if (state.lightsData.hasOwnProperty(key)) {
setTimeout(function () {
updateLight(key);
}, 1000);
}
}
} }
return true; return true;
@ -170,7 +183,7 @@ let simulateKick = (/*mag, ratioKickMag*/) => {
chrome.runtime.sendMessage({ action: 'button-bump' }); chrome.runtime.sendMessage({ action: 'button-bump' });
let color = null, let color = null,
_stimulateLight = (light, brightness, hue) => { _stimulateLight = (lightIndex, brightness, hue) => {
let options = { bri: brightness, transitiontime: 1 }, let options = { bri: brightness, transitiontime: 1 },
xhr = new XMLHttpRequest(); xhr = new XMLHttpRequest();
@ -178,15 +191,13 @@ let simulateKick = (/*mag, ratioKickMag*/) => {
options.hue = hue; options.hue = hue;
} }
if (state.lightsData[light].state.on === false) { if (state.lightsData[lightIndex].state.on === false) {
options.on = true; options.on = true;
} }
$.ajax('http://' + state.bridgeIp + '/api/' + state.bridgeUsername + '/lights/' + light + '/state', { xhr.open('PUT', 'http://' + state.bridgeIp + '/api/' + state.bridgeUsername + '/lights/' + lightIndex + '/state', true);
data: JSON.stringify(options), xhr.setRequestHeader('Content-Type', 'application/json');
contentType: 'application/json', xhr.send(JSON.stringify(options));
type: 'PUT'
});
}, },
timeToBriOff = 80; timeToBriOff = 80;

File diff suppressed because one or more lines are too long

View file

@ -3,7 +3,7 @@
"name": "Huegasm for Philips Hue Lights", "name": "Huegasm for Philips Hue Lights",
"short_name": "Huegasm", "short_name": "Huegasm",
"description": "Manage and synchronize your Philips Hue lights with the beat of your music.", "description": "Manage and synchronize your Philips Hue lights with the beat of your music.",
"version": "1.0.1", "version": "1.0.2",
"icons": { "icons": {
"16": "16x16.png", "16": "16x16.png",
"48": "48x48.png", "48": "48x48.png",
@ -12,7 +12,6 @@
"background": { "background": {
"scripts": [ "scripts": [
"dancer.js", "dancer.js",
"jquery-3.1.1.min.js",
"background.js" "background.js"
] ]
}, },

View file

@ -111,6 +111,12 @@ export default Component.extend({
}, },
actions: { actions: {
tryAndroid() {
window.open("https://play.google.com/store/apps/details?id=com.hoboman313.huegasm", '_blank');
},
tryExtension() {
window.open("https://chrome.google.com/webstore/detail/huegasm-for-philips-hue-l/mbjanbdhcpohhfecjgbdpcfhnnbofooj", '_blank');
},
changeTab(tabName){ changeTab(tabName){
let index = this.get('tabList').indexOf(tabName); let index = this.get('tabList').indexOf(tabName);
this.set('selectedTab', index); this.set('selectedTab', index);

View file

@ -4,13 +4,23 @@
{{#each tabData as |tab|}} {{#each tabData as |tab|}}
<span class="navigation-item pointer text-uppercase {{if tab.selected "active"}}" {{action "changeTab" tab.name}}>{{tab.name}}</span> <span class="navigation-item pointer text-uppercase {{if tab.selected "active"}}" {{action "changeTab" tab.name}}>{{tab.name}}</span>
{{/each}} {{/each}}
{{#paper-menu as |menu|}} {{#paper-menu as |menu|}}
{{#menu.trigger}} {{#menu.trigger}}
{{#paper-button iconButton=true}} {{#paper-button iconButton=true}}
{{paper-icon "settings-icon" class=dimmerOnClass size=28}} {{paper-icon "settings-icon" class=dimmerOnClass size=28}}
{{/paper-button}} {{/paper-button}}
{{/menu.trigger}} {{/menu.trigger}}
{{#menu.content width=3 as |content|}} {{#menu.content width=3 as |content|}}
{{#content.menu-item class="hidden-xs" onClick="tryExtension"}}
{{paper-icon "extension" class=dimmerOnClass}} Try the Chrome Extension
{{/content.menu-item}}
{{#content.menu-item class="visible-xs" onClick="tryAndroid"}}
{{paper-icon "extension" class=dimmerOnClass}} Try the Android Extension
{{/content.menu-item}}
{{#content.menu-item onClick="toggleDimmer"}} {{#content.menu-item onClick="toggleDimmer"}}
{{paper-icon "highlight" class=dimmerOnClass}} Dark Mode: <strong>{{if dimmerOn "On" "Off"}}</strong> {{paper-icon "highlight" class=dimmerOnClass}} Dark Mode: <strong>{{if dimmerOn "On" "Off"}}</strong>
{{/content.menu-item}} {{/content.menu-item}}
@ -35,7 +45,7 @@
</div> </div>
</div> </div>
{{light-group lightsData=lightsData activeLights=activeLights syncLight=syncLight apiURL=apiURL dimmerOn=dimmerOn lightsIconsOn=lightsIconsOn storage=storage}} {{light-group lightsData=lightsData activeLights=activeLights syncLight=syncLight apiURL=apiURL dimmerOn=dimmerOn lightsIconsOn=lightsIconsOn storage=storage pauseLightUpdates=pauseLightUpdates}}
<div id="huegasm-content" class="row"> <div id="huegasm-content" class="row">
{{lights-tab active=(eq selectedTab 0) apiURL=apiURL lightsData=lightsData activeLights=activeLights syncLight=syncLight trial=trial colorLoopOn=colorLoopOn dimmerOn=dimmerOn playing=playing pauseLightUpdates=pauseLightUpdates}} {{lights-tab active=(eq selectedTab 0) apiURL=apiURL lightsData=lightsData activeLights=activeLights syncLight=syncLight trial=trial colorLoopOn=colorLoopOn dimmerOn=dimmerOn playing=playing pauseLightUpdates=pauseLightUpdates}}

View file

@ -1,3 +1,7 @@
<a href="https://chrome.google.com/webstore/detail/huegasm-for-philips-hue-l/mbjanbdhcpohhfecjgbdpcfhnnbofooj" target="_blank" rel="noopener noreferrer" class="hidden-xs">
<img src="assets/images/chrome-store-badge.png" alt="Available in the Chrome Web Store">
</a>
<div id="footer-text"> <div id="footer-text">
© {{year}} © {{year}}
@ -6,11 +10,6 @@
</a> </a>
</div> </div>
<div id="footer-links"> <a href="https://play.google.com/store/apps/details?id=com.hoboman313.huegasm" target="_blank" rel="noopener noreferrer">
<a href="https://play.google.com/store/apps/details?id=com.hoboman313.huegasm" target="_blank" rel="noopener noreferrer"> <img src="assets/images/google-play-badge.png" alt="Get it on the Google Play Store">
<img src="assets/images/google-play-badge.png" alt="Get it on the Google Play Store"> </a>
</a>
<a href="https://chrome.google.com/webstore/detail/huegasm-for-philips-hue-l/mbjanbdhcpohhfecjgbdpcfhnnbofooj" target="_blank" rel="noopener noreferrer">
<img src="assets/images/chrome-store-badge.png" alt="Available in the Chrome Web Store">
</a>
</div>

View file

@ -17,7 +17,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'),
@ -29,7 +29,7 @@ export default Component.extend({
activeClass = 'light-active'; activeClass = 'light-active';
if (lightsData.hasOwnProperty(key) && lightsData[key].state.reachable) { if (lightsData.hasOwnProperty(key) && lightsData[key].state.reachable) {
switch(lightsData[key].modelid){ switch (lightsData[key].modelid) {
case 'LCT001': case 'LCT001':
type = 'a19'; type = 'a19';
break; break;
@ -61,7 +61,7 @@ export default Component.extend({
type = 'storylight'; type = 'storylight';
break; break;
case 'LWB004': case 'LWB004':
type ='a19'; type = 'a19';
break; break;
case 'LLC020': case 'LLC020':
type = 'huego'; type = 'huego';
@ -70,34 +70,34 @@ export default Component.extend({
type = 'a19'; type = 'a19';
} }
if(dimmerOn){ if (dimmerOn) {
type += 'w'; type += 'w';
} }
if(!activeLights.includes(key)){ if (!activeLights.includes(key)) {
activeClass = 'light-inactive'; activeClass = 'light-inactive';
} }
lightsList.push({type: type, name: lightsData[key].name, id: key, data: lightsData[key], activeClass: activeClass}); lightsList.push({ type: type, name: lightsData[key].name, id: key, data: lightsData[key], activeClass: activeClass });
} }
} }
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'));
}), }),
init(){ init() {
this._super(...arguments); this._super(...arguments);
let lightsData = this.get('lightsData'), let lightsData = this.get('lightsData'),
activeLights = this.get('activeLights'), activeLights = this.get('activeLights'),
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);
} }
@ -112,49 +112,55 @@ export default Component.extend({
}, },
actions: { actions: {
clickLight(id){ clickLight(id) {
let activeLights = this.get('activeLights'), let activeLights = this.get('activeLights'),
lightId = activeLights.indexOf(id); lightId = activeLights.indexOf(id);
if(lightId !== -1){ if (lightId !== -1) {
activeLights.removeObject(id); activeLights.removeObject(id);
} else { } else {
activeLights.pushObject(id); activeLights.pushObject(id);
this.set('syncLight', id); this.set('syncLight', id);
} }
}, },
lightStartHover(id){ lightStartHover(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": "lselect"}), data: JSON.stringify({ "alert": "lselect" }),
contentType: 'application/json', contentType: 'application/json',
type: 'PUT' type: 'PUT'
}); });
} }
this.set('isHovering', true); this.setProperties({
pauseLightUpdates: true,
isHovering: true
});
} }
}, },
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'
}); });
} }
this.set('isHovering', false); this.setProperties({
pauseLightUpdates: false,
isHovering: false
});
} }
} }
} }

View file

@ -56,7 +56,7 @@ body, button {
#footer-text { #footer-text {
display: inline-block; display: inline-block;
font-size: 18px; font-size: 18px;
padding-left: 39%; padding-right: 30px;
a { a {
margin-left: 5px; margin-left: 5px;
} }
@ -119,20 +119,6 @@ div.ember-modal-dialog {
} }
@media(max-width:768px) { @media(max-width:768px) {
#footer {
display: block;
}
#footer-links {
margin-top: 10px;
display: flex;
justify-content: space-around;
}
#footer-text {
padding-left: 0 !important;
}
#intro-logo { #intro-logo {
margin-bottom: 10px; margin-bottom: 10px;
} }

View file

@ -1,6 +1,5 @@
#lights-tab { #lights-tab {
padding: 0; padding: 0;
margin-top: 5vh;
.paper-icon { .paper-icon {
line-height: 0.8 !important; line-height: 0.8 !important;
} }
@ -35,7 +34,7 @@
} }
#navigation { #navigation {
padding: 15px 0 4vh; padding: 15px 0 0;
text-align: center; text-align: center;
margin: auto; margin: auto;
position: relative; position: relative;

View file

@ -1,6 +1,7 @@
.light-group { #active-lights {
margin: 2vh auto;
padding-top: 10px;
max-width: 800px; max-width: 800px;
margin: 0 auto;
display: flex; display: flex;
justify-content: center; justify-content: center;
.tooltip.top { .tooltip.top {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB