diff --git a/app/index.js b/app/index.js index be8b063..b699be9 100644 --- a/app/index.js +++ b/app/index.js @@ -13,6 +13,8 @@ import * as util from "../common/utils"; import * as weather from 'fitbit-weather/app'; import * as simpleSettings from "./device-settings"; +// ***** Settings ***** + const settings; function settingsCallback(data) { @@ -28,33 +30,129 @@ messaging.peerSocket.addEventListener("message", (evt) => { } }); -// Update the clock every minute -clock.granularity = "seconds"; +// ***** Initialize Body & Heart Rate ***** + +const body = null; +if (BodyPresenceSensor) { + body = new BodyPresenceSensor(); + body.start(); +} + +const hrm; +if (HeartRateSensor) { + hrm = new HeartRateSensor({ frequency: 1 }); + hrm.addEventListener("reading", () => { + document.getElementById("bpm").text = hrm.heartRate; + }); +} + +// ***** Display ***** + +if (display.aodAvailable && me.permissions.granted("access_aod")) { + // tell the system we support AOD + display.aodAllowed = true; + + // respond to display change events + display.addEventListener("change", () => { + // Is AOD inactive and the display is on? + if (!display.aodActive && display.on) { + body.start(); + hrm.start(); + clock.granularity = "seconds"; + // Show elements & start sensors + document.getElementsByClassName("tertiary").forEach(showMinutes); + document.getElementById("numbers").style.visibility = "visible"; + document.getElementById("seconds").style.visibility = "visible"; + if(!settings.hideDate) document.getElementById("dateBox").style.visibility = "visible"; + else document.getElementById("iii").style.visibility = "visible"; + if(!settings.hideHeartRate) { + document.getElementById("heartrateBox").style.visibility = "visible"; + document.getElementById("bpm").style.visibility = "visible"; + } + else document.getElementById("vi").style.visibility = "visible"; + if(!settings.hideWeather) document.getElementById("weatherBox").style.visibility = "visible"; + else document.getElementById("ix").style.visibility = "visible"; + if(!settings.hideGoals) { + document.getElementById("icons").style.visibility = "visible"; + } + document.getElementById("steps").style.visibility = "visible"; + document.getElementById("distance").style.visibility = "visible"; + document.getElementById("zone").style.visibility = "visible"; + } + else { + body.stop(); + hrm.stop(); + clock.granularity = "minutes"; + // Hide elements & stop sensors + document.getElementById("seconds").style.visibility = "hidden"; + document.getElementById("numbers").style.visibility = "hidden"; + document.getElementById("icons").style.visibility = "hidden"; + if(settings.hideGoals) { + document.getElementById("steps").style.visibility = "hidden"; + document.getElementById("distance").style.visibility = "hidden"; + document.getElementById("zone").style.visibility = "hidden"; + } + document.getElementById("heartrateBox").style.visibility = "hidden"; + if(settings.hideDate) document.getElementById("dateBox").style.visibility = "hidden"; + document.getElementById("weatherBox").style.visibility = "hidden"; + document.getElementById("bpm").style.visibility = "hidden"; + document.getElementById("iii").style.visibility = "hidden"; + document.getElementById("vi").style.visibility = "hidden"; + document.getElementById("ix").style.visibility = "hidden"; + document.getElementsByClassName("tertiary").forEach(hideMinutes); + } + }); +} + +function hideMinutes(item, index) { + item.style.visibility = "hidden"; +} + +function showMinutes(item, index) { + item.style.visibility = "visible"; +} + +// ***** Clock ***** -// Get a handle on the element const dateBox = document.getElementById("dateBox") const hourHand = document.getElementById("hours"); const minuteHand = document.getElementById("minutes"); const secondsHand = document.getElementById("seconds"); const heartRate = document.getElementById("heartRate"); -const body = null; -if (BodyPresenceSensor) { - body = new BodyPresenceSensor(); - body.start(); -} +clock.granularity = "seconds"; -// Update the element every tick with the current time clock.ontick = (evt) => { let now = evt.date; - let dateText = now.toLocaleString('default', { month: 'short' }).substring(4, 10); + processDate(now); let hours = now.getHours(); hours = hours % 12 || 12; let minutes = now.getMinutes(); let seconds = now.getSeconds(); - if (!settings.hideDate && !display.aodActive && display.on) { + hourHand.groupTransform.rotate.angle = ((360 / 12) * hours) + ((360 / 12 / 60) * minutes); + minuteHand.groupTransform.rotate.angle = (360 / 60) * minutes + ((360 / 60 / 60) * seconds); + secondsHand.groupTransform.rotate.angle = seconds * 6; + + processHeartRate(); + processGoals(); + processBattery(); + + if (!settings.hideWeather && !display.aodActive && display.on) { + weather.fetch(30 * 60 * 1000) // return the cached value if it is less than 30 minutes old + .then(weather => processWeather(weather)) + .catch(error => console.log(JSON.stringify(error))); + } + else processWeather(weather); +} + +// ***** Date ***** + +function processDate(date) { + let dateText = date.toLocaleString('default', { month: 'short' }).substring(4, 10); + + if (!settings.hideDate) { dateBox.text = dateText; dateBox.style.visibility = "visible"; document.getElementById("iii").style.visibility = "hidden"; @@ -67,74 +165,24 @@ clock.ontick = (evt) => { dateBox.style.visibility = "hidden"; document.getElementById("iii").style.visibility = "hidden"; } +} - hourHand.groupTransform.rotate.angle = ((360 / 12) * hours) + ((360 / 12 / 60) * minutes); - minuteHand.groupTransform.rotate.angle = (360 / 60) * minutes + ((360 / 60 / 60) * seconds); - secondsHand.groupTransform.rotate.angle = seconds * 6; - heartRate.animate("enable"); - - if (!settings.hideGoals && !display.aodActive && display.on) - document.getElementById("icons").style.visibility = "visible"; - else - document.getElementById("icons").style.visibility = "hidden"; - var stepPercent = 0; - var distancePercent = 0; - var zonePercent = 0; - if (me.permissions.granted("access_activity")) { - var stepCount = today.adjusted.steps; - var stepGoal = goals.steps; - stepPercent = stepCount / stepGoal * 100; - - var distanceCount = today.adjusted.distance; - var distanceGoal = goals.distance; - distancePercent = distanceCount / distanceGoal * 100; - - var zoneCount = today.adjusted.activeZoneMinutes.total; - var zoneGoal = goals.activeZoneMinutes.total; - zonePercent = zoneCount / zoneGoal * 100; - } - if (stepPercent >= 20 && !settings.hideGoals) document.getElementById("steps1").style.opacity = 1; - else document.getElementById("steps1").style.opacity = 0.5; - if (stepPercent >= 40 && !settings.hideGoals) document.getElementById("steps2").style.opacity = 1; - else document.getElementById("steps2").style.opacity = 0.5; - if (stepPercent >= 60 && !settings.hideGoals) document.getElementById("steps3").style.opacity = 1; - else document.getElementById("steps3").style.opacity = 0.5; - if (stepPercent >= 80 && !settings.hideGoals) document.getElementById("steps4").style.opacity = 1; - else document.getElementById("steps4").style.opacity = 0.5; - - if (distancePercent >= 20 && !settings.hideGoals) document.getElementById("distance1").style.opacity = 1; - else document.getElementById("distance1").style.opacity = 0.5; - if (distancePercent >= 40 && !settings.hideGoals) document.getElementById("distance2").style.opacity = 1; - else document.getElementById("distance2").style.opacity = 0.5; - if (distancePercent >= 60 && !settings.hideGoals) document.getElementById("distance3").style.opacity = 1; - else document.getElementById("distance3").style.opacity = 0.5; - if (distancePercent >= 80 && !settings.hideGoals) document.getElementById("distance4").style.opacity = 1; - else document.getElementById("distance4").style.opacity = 0.5; - - if (zonePercent >= 20 && !settings.hideGoals) document.getElementById("zone1").style.opacity = 1; - else document.getElementById("zone1").style.opacity = 0.5; - if (zonePercent >= 40 && !settings.hideGoals) document.getElementById("zone2").style.opacity = 1; - else document.getElementById("zone2").style.opacity = 0.5; - if (zonePercent >= 60 && !settings.hideGoals) document.getElementById("zone3").style.opacity = 1; - else document.getElementById("zone3").style.opacity = 0.5; - if (zonePercent >= 80 && !settings.hideGoals) document.getElementById("zone4").style.opacity = 1; - else document.getElementById("zone4").style.opacity = 0.5; - - if (battery.chargeLevel >= 20) document.getElementById("battery1").style.opacity = 1; - else document.getElementById("battery1").style.opacity = 0.5; - if (battery.chargeLevel >= 40) document.getElementById("battery2").style.opacity = 1; - else document.getElementById("battery2").style.opacity = 0.5; - if (battery.chargeLevel >= 60) document.getElementById("battery3").style.opacity = 1; - else document.getElementById("battery3").style.opacity = 0.5; - if (battery.chargeLevel >= 80) document.getElementById("battery4").style.opacity = 1; - else document.getElementById("battery4").style.opacity = 0.5; +// ***** Weather ***** +function processWeather(weather) { if (!settings.hideWeather && !display.aodActive && display.on) { document.getElementById("weatherBox").style.visibility = "visible"; document.getElementById("ix").style.visibility = "hidden"; - weather.fetch(30 * 60 * 1000) // return the cached value if it is less than 30 minutes old - .then(weather => processWeather(weather)) - .catch(error => console.log(JSON.stringify(error))); + if (settings.tempUnit.selected == "1") + document.getElementById("temperature").text = `${Math.round(weather.temperatureF)}°`; + else + document.getElementById("temperature").text = `${Math.round(weather.temperatureC)}°`; + var weatherIcon = document.getElementById("weatherIcon"); + var weatherCode = weather.conditionCode; + var dayNight; + if (weather.timestamp > weather.sunrise && weather.timestamp < weather.sunset) dayNight = "d"; + else dayNight = "n"; + weatherIcon.href = `weather/${weatherCode}${dayNight}.png`; } else if(settings.hideWeather && !display.aodActive && display.on) { document.getElementById("weatherBox").style.visibility = "hidden"; @@ -144,10 +192,15 @@ clock.ontick = (evt) => { document.getElementById("weatherBox").style.visibility = "hidden"; document.getElementById("ix").style.visibility = "hidden"; } +} +// ***** Heart Rate ***** + +function processHeartRate() { if (!settings.hideHeartRate && !display.aodActive && display.on) { document.getElementById("heartrateBox").style.visibility = "visible"; document.getElementById("vi").style.visibility = "hidden"; + heartRate.animate("enable"); } else if (settings.hideHeartRate && !display.aodActive && display.on) { document.getElementById("heartrateBox").style.visibility = "hidden"; @@ -167,75 +220,102 @@ clock.ontick = (evt) => { } } -function processWeather(weather) { - if (settings.tempUnit.selected == "1") - document.getElementById("temperature").text = `${Math.round(weather.temperatureF)}°`; - else - document.getElementById("temperature").text = `${Math.round(weather.temperatureC)}°`; - var weatherIcon = document.getElementById("weatherIcon"); - var weatherCode = weather.conditionCode; - var dayNight; - if (weather.timestamp > weather.sunrise && weather.timestamp < weather.sunset) dayNight = "d"; - else dayNight = "n"; - weatherIcon.href = `weather/${weatherCode}${dayNight}.png`; -} +// ***** Goals ***** -if (display.aodAvailable && me.permissions.granted("access_aod")) { - // tell the system we support AOD - display.aodAllowed = true; +function processGoals() { + var stepPercent = 0; + var distancePercent = 0; + var zonePercent = 0; - // respond to display change events - display.addEventListener("change", () => { - // Is AOD inactive and the display is on? - if (!display.aodActive && display.on) { - body.start(); - hrm.start(); - clock.granularity = "seconds"; - // Show elements & start sensors - document.getElementById("seconds").style.visibility = "visible"; - document.getElementById("numbers").style.visibility = "visible"; - document.getElementById("icons").style.visibility = "visible"; - document.getElementById("heartrateBox").style.visibility = "visible"; - document.getElementById("dateBox").style.visibility = "visible"; - document.getElementById("weatherBox").style.visibility = "visible"; - document.getElementById("bpm").style.visibility = "visible"; - document.getElementById("iii").style.visibility = "visible"; - document.getElementById("vi").style.visibility = "visible"; - document.getElementById("ix").style.visibility = "visible"; - document.getElementsByClassName("tertiary").forEach(showMinutes); - } else { - body.stop(); - hrm.stop(); - clock.granularity = "minutes"; - // Hide elements & stop sensors - document.getElementById("seconds").style.visibility = "hidden"; - document.getElementById("numbers").style.visibility = "hidden"; - document.getElementById("icons").style.visibility = "hidden"; - document.getElementById("heartrateBox").style.visibility = "hidden"; - document.getElementById("dateBox").style.visibility = "hidden"; - document.getElementById("weatherBox").style.visibility = "hidden"; - document.getElementById("bpm").style.visibility = "hidden"; - document.getElementById("iii").style.visibility = "hidden"; - document.getElementById("vi").style.visibility = "hidden"; - document.getElementById("ix").style.visibility = "hidden"; - document.getElementsByClassName("tertiary").forEach(hideMinutes); + if (me.permissions.granted("access_activity")) { + var stepCount = today.adjusted.steps; + var stepGoal = goals.steps; + stepPercent = stepCount / stepGoal * 100; + + var distanceCount = today.adjusted.distance; + var distanceGoal = goals.distance; + distancePercent = distanceCount / distanceGoal * 100; + + var zoneCount = today.adjusted.activeZoneMinutes.total; + var zoneGoal = goals.activeZoneMinutes.total; + zonePercent = zoneCount / zoneGoal * 100; + } + + if (!settings.hideGoals && !display.aodActive && display.on) { + document.getElementById("icons").style.visibility = "visible"; + } + else + document.getElementById("icons").style.visibility = "hidden"; + + if (settings.hideGoals) { + document.getElementById("steps").style.fill = "#FFFFFF"; + document.getElementById("steps1").style.opacity = 0.33; + document.getElementById("steps2").style.opacity = 0.33; + document.getElementById("steps3").style.opacity = 0.33; + document.getElementById("steps4").style.opacity = 0.33; + document.getElementById("distance").style.fill = "#FFFFFF"; + document.getElementById("distance1").style.opacity = 0.33; + document.getElementById("distance2").style.opacity = 0.33; + document.getElementById("distance3").style.opacity = 0.33; + document.getElementById("distance4").style.opacity = 0.33; + document.getElementById("zone").style.fill = "#FFFFFF"; + document.getElementById("zone1").style.opacity = 0.33; + document.getElementById("zone2").style.opacity = 0.33; + document.getElementById("zone3").style.opacity = 0.33; + document.getElementById("zone4").style.opacity = 0.33; + + if(display.aodActive) { + document.getElementById("steps").style.visibility = "hidden"; + document.getElementById("distance").style.visibility = "hidden"; + document.getElementById("zone").style.visibility = "hidden"; } - }); -} + } + else { + document.getElementById("steps").style.visibility = "visible"; + document.getElementById("distance").style.visibility = "visible"; + document.getElementById("zone").style.visibility = "visible"; + + document.getElementById("steps").style.fill = "#EFC12B"; + if (stepPercent >= 20) document.getElementById("steps1").style.opacity = 1; + else document.getElementById("steps1").style.opacity = 0.5; + if (stepPercent >= 40) document.getElementById("steps2").style.opacity = 1; + else document.getElementById("steps2").style.opacity = 0.5; + if (stepPercent >= 60) document.getElementById("steps3").style.opacity = 1; + else document.getElementById("steps3").style.opacity = 0.5; + if (stepPercent >= 80) document.getElementById("steps4").style.opacity = 1; + else document.getElementById("steps4").style.opacity = 0.5; -const hrm; + document.getElementById("distance").style.fill = "#376EEF"; + if (distancePercent >= 20) document.getElementById("distance1").style.opacity = 1; + else document.getElementById("distance1").style.opacity = 0.5; + if (distancePercent >= 40) document.getElementById("distance2").style.opacity = 1; + else document.getElementById("distance2").style.opacity = 0.5; + if (distancePercent >= 60) document.getElementById("distance3").style.opacity = 1; + else document.getElementById("distance3").style.opacity = 0.5; + if (distancePercent >= 80) document.getElementById("distance4").style.opacity = 1; + else document.getElementById("distance4").style.opacity = 0.5; -if (HeartRateSensor) { - hrm = new HeartRateSensor({ frequency: 1 }); - hrm.addEventListener("reading", () => { - document.getElementById("bpm").text = hrm.heartRate; - }); + document.getElementById("zone").style.fill = "#EA7D1E"; + if (zonePercent >= 20) document.getElementById("zone1").style.opacity = 1; + else document.getElementById("zone1").style.opacity = 0.5; + if (zonePercent >= 40) document.getElementById("zone2").style.opacity = 1; + else document.getElementById("zone2").style.opacity = 0.5; + if (zonePercent >= 60) document.getElementById("zone3").style.opacity = 1; + else document.getElementById("zone3").style.opacity = 0.5; + if (zonePercent >= 80) document.getElementById("zone4").style.opacity = 1; + else document.getElementById("zone4").style.opacity = 0.5; + } } -function hideMinutes(item, index) { - item.style.visibility = "hidden"; -} +// ***** Battery ***** -function showMinutes(item, index) { - item.style.visibility = "visible"; +function processBattery() { + if (battery.chargeLevel >= 20) document.getElementById("battery1").style.opacity = 1; + else document.getElementById("battery1").style.opacity = 0.5; + if (battery.chargeLevel >= 40) document.getElementById("battery2").style.opacity = 1; + else document.getElementById("battery2").style.opacity = 0.5; + if (battery.chargeLevel >= 60) document.getElementById("battery3").style.opacity = 1; + else document.getElementById("battery3").style.opacity = 0.5; + if (battery.chargeLevel >= 80) document.getElementById("battery4").style.opacity = 1; + else document.getElementById("battery4").style.opacity = 0.5; } \ No newline at end of file diff --git a/build/app.fba b/build/app.fba index b1dd958..75a686f 100644 Binary files a/build/app.fba and b/build/app.fba differ diff --git a/package-lock.json b/package-lock.json index ae8e329..053cba9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1775,6 +1775,22 @@ "path-exists": "^4.0.0" } }, + "fitbit": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/fitbit/-/fitbit-0.0.7.tgz", + "integrity": "sha1-XRRJm6Mb+CdWwWrHFlWkAsXdB+A=", + "requires": { + "lodash": "~1.3.1", + "oauth": "github:p-m-p/node-oauth" + }, + "dependencies": { + "lodash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.3.1.tgz", + "integrity": "sha1-pGY7U2hriV/wdOK6UE37dqjit3A=" + } + } + }, "fitbit-weather": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/fitbit-weather/-/fitbit-weather-0.2.3.tgz", @@ -3016,6 +3032,10 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "oauth": { + "version": "github:p-m-p/node-oauth#334afb5478240c4676410c3db9811129f436fc96", + "from": "github:p-m-p/node-oauth" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",