diff --git a/apps/93dub/ChangeLog b/apps/93dub/ChangeLog index 712a52a37..9a07b38ad 100644 --- a/apps/93dub/ChangeLog +++ b/apps/93dub/ChangeLog @@ -5,3 +5,4 @@ 0.05: Display time, even on Thursday 0.06: Fix light theme issue, where widgets would end up on a light strip 0.07: Minor code improvements +0.08: Support Fast Loading diff --git a/apps/93dub/app.js b/apps/93dub/app.js index c9f670993..dbf8ec907 100644 --- a/apps/93dub/app.js +++ b/apps/93dub/app.js @@ -1,146 +1,162 @@ -// get 12 hour status, code from barclock -const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; +{ + // get 12 hour status, code from barclock + const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; -// define background -var imgBg = require("heatshrink").decompress(atob("2GwgJC/AH4A/AH4A/AH4A/AH4A/ACcGAhAV/Cp3gvdug+Gj0AgeABYMBAQMIggVEg/w/9/h/Gn8As3ACpk559zznmseAs0B13nq/Rie+uodCIIUZw9hzFmv+AgcCmco7MRilow1ACpN8gFhwMilFRCoMowgVEIIVhIINhwFg4GiCpfw/dhx/mn4uBCoXRhWktAVFTIVhw9mj8YseDkUnqPEoeuugVEAAlgSgICBACAVC8AUQCQQVSAEsD/4ASeYgA/ACkHNiK5Cj4VR/AVBng+RCQVwCqMOAQPhIKOHgEB44VR8YVBx4VR+eAgOfCqPxwEDCqX5CoKvS/PAgc/YqQVU/gV/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/CsMfCqP4CoOfCqP54EBx4VR+OAgPPCqPzwEA44VR4cAgHhCqMHCoNwAQIAPjwCBngVRvgCBV6XwCoMHCqPAHyIA/AEigEf4IAOkAEDoAPJWAtA+PHv+Al6uPCofAGAgALoHz51/8AVT+IVS+4VPpMR73woH27n/8Eh8+ZmadIqsoyGICofAkMUktJFZAVBzgVBv34YgMhi8RkIVJnGQIIN8/H34FB8kJiIVIkVEyGQkF8/Pj4GBkhBKCoOexEQvHx8fBgMXzMxTJkICoXCVx8AggDGABsD/4AB/AVQAH4APA")); + // define background + const imgBg = require("heatshrink").decompress(atob("2GwgJC/AH4A/AH4A/AH4A/AH4A/ACcGAhAV/Cp3gvdug+Gj0AgeABYMBAQMIggVEg/w/9/h/Gn8As3ACpk559zznmseAs0B13nq/Rie+uodCIIUZw9hzFmv+AgcCmco7MRilow1ACpN8gFhwMilFRCoMowgVEIIVhIINhwFg4GiCpfw/dhx/mn4uBCoXRhWktAVFTIVhw9mj8YseDkUnqPEoeuugVEAAlgSgICBACAVC8AUQCQQVSAEsD/4ASeYgA/ACkHNiK5Cj4VR/AVBng+RCQVwCqMOAQPhIKOHgEB44VR8YVBx4VR+eAgOfCqPxwEDCqX5CoKvS/PAgc/YqQVU/gV/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/CsMfCqP4CoOfCqP54EBx4VR+OAgPPCqPzwEA44VR4cAgHhCqMHCoNwAQIAPjwCBngVRvgCBV6XwCoMHCqPAHyIA/AEigEf4IAOkAEDoAPJWAtA+PHv+Al6uPCofAGAgALoHz51/8AVT+IVS+4VPpMR73woH27n/8Eh8+ZmadIqsoyGICofAkMUktJFZAVBzgVBv34YgMhi8RkIVJnGQIIN8/H34FB8kJiIVIkVEyGQkF8/Pj4GBkhBKCoOexEQvHx8fBgMXzMxTJkICoXCVx8AggDGABsD/4AB/AVQAH4APA")); -// define fonts -// reg number first char 48 28 by 41 -var fontNum = atob("AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//w//j4//A/+P4/8A/4/4AAAAD/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/wAAAAH/H/gH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wB/4AP/4H/4A//4f/4D//5//4P//h//4//+B//4AAAAAAAAAAAAAAAAAf/+AAAB//4gAAD//jgAAD/+PgABj/4/gAHj/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f88AAfx/8wAAfH/8AAAcf/8AAAR//4AAAH//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA4AAAAAD4AAYAAP4AD8AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAHgAH/H/GH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAP//AAAAP//AAAAP//AAAAP/8AAAAP/2AAAAP/eAAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAB/7x/4AH/7H/4Af/4f/4B//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wAAAD//wAAAj//gAADj/+AAAPj/5gAA/j/ngAD/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8AA8f8fwAAx/8fAAAH/8cAAAf/8QAAA//8AAAA//8AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//0//j4//Y/+P4/94/4/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/AAPH/H8AAMf/HwAAB//HAAAH//EAAAH//AAAAH//AAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAGAAAAAAOAAAAAAeAAAAAA+AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB8AAAAADx/4B/4HH/4H/4Mf/4f/4R//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wP/+D//w//4j//z//jj//T/+Pj/9j/4/j/3j/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f+8f8fx/+x/8fH/+H/8cf/+f/8R//4f/8H//gf/8AAAAAAAAAAAAAA//8AAAA//8AAAI//8AAA4//0AAD4//YAAP4/94AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/H/vH/H8f/sf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); -// tiny font for percentage first char 48 6 by 8 -//var fontTiny = atob("AH6BgYF+ACFB/wEBAGGDhYlxAEKBkZFuAAx0hP8EAPqRkZGOAH6RkZFOAICHmKDAAG6RkZFuAHKJiYl+AAAAAAAAAAAAAAAA"); -// date font first char 48 12 by 15 -var fontDate = atob("AAAAAfv149wAeADwAeADwAeADvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAPHn9/AAAAAAP0A9wweGDwweGDwweGDvAL8AAAAAAAAAAAgwOGDwweGDwweGDvHp98AAAAA/gB6AAwAGAAwAGAAwAGAPHj9/AAAAAfgF6BwweGDwweGDwweGDgHoB+AAAAAfv169wweGDwweGDwweGDgHoB+AAAAAAAAAAgAGAAwAGAAwAGAAvHh9/AAAAAfv169wweGDwweGDwweGDvHr9+AAAAAfgF6BwweGDwweGDwweGDvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + // define fonts + // reg number first char 48 28 by 41 + const fontNum = atob("AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//w//j4//A/+P4/8A/4/4AAAAD/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/wAAAAH/H/gH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wB/4AP/4H/4A//4f/4D//5//4P//h//4//+B//4AAAAAAAAAAAAAAAAAf/+AAAB//4gAAD//jgAAD/+PgABj/4/gAHj/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f88AAfx/8wAAfH/8AAAcf/8AAAR//4AAAH//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA4AAAAAD4AAYAAP4AD8AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAHgAH/H/GH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAP//AAAAP//AAAAP//AAAAP/8AAAAP/2AAAAP/eAAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAB/7x/4AH/7H/4Af/4f/4B//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wAAAD//wAAAj//gAADj/+AAAPj/5gAA/j/ngAD/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8AA8f8fwAAx/8fAAAH/8cAAAf/8QAAA//8AAAA//8AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//0//j4//Y/+P4/94/4/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/AAPH/H8AAMf/HwAAB//HAAAH//EAAAH//AAAAH//AAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAGAAAAAAOAAAAAAeAAAAAA+AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB8AAAAADx/4B/4HH/4H/4Mf/4f/4R//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wP/+D//w//4j//z//jj//T/+Pj/9j/4/j/3j/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f+8f8fx/+x/8fH/+H/8cf/+f/8R//4f/8H//gf/8AAAAAAAAAAAAAA//8AAAA//8AAAI//8AAA4//0AAD4//YAAP4/94AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/H/vH/H8f/sf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + // tiny font for percentage first char 48 6 by 8 + //var fontTiny = atob("AH6BgYF+ACFB/wEBAGGDhYlxAEKBkZFuAAx0hP8EAPqRkZGOAH6RkZFOAICHmKDAAG6RkZFuAHKJiYl+AAAAAAAAAAAAAAAA"); + // date font first char 48 12 by 15 + const fontDate = atob("AAAAAfv149wAeADwAeADwAeADvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAPHn9/AAAAAAP0A9wweGDwweGDwweGDvAL8AAAAAAAAAAAgwOGDwweGDwweGDvHp98AAAAA/gB6AAwAGAAwAGAAwAGAPHj9/AAAAAfgF6BwweGDwweGDwweGDgHoB+AAAAAfv169wweGDwweGDwweGDgHoB+AAAAAAAAAAgAGAAwAGAAwAGAAvHh9/AAAAAfv169wweGDwweGDwweGDvHr9+AAAAAfgF6BwweGDwweGDwweGDvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); -// define days of the week images -var imgMon = E.toArrayBuffer(atob("Ig8BgHwfD5AvB8HD8z8wMPzPzMQzM/M/DMz8z8c7f7f7z////3Oz+3+PzPzPw/M/M/D8z8z8PzPzPw/vB8/n/8H3/A==")); -var imgTue = E.toArrayBuffer(atob("Ig8BwDv9wDAOfmgf/5+Z///n5n/5+fmf/n5+Z//fv9oH////Af37/b/+fn5n/5+fmf/n5+Z/+fn5n/5/g+gfn+D8AA==")); -var imgWed = E.toArrayBuffer(atob("Ig8Bf7gHgM/NA9Az8z/z8PzP/Pw/M/8/D8z/z8c7QPf7z+A//3O3/3+MzP/PwzM/8/D8z/z8PzP/PxAtA9A4B4B4DA==")); -var imgThu = E.toArrayBuffer(atob("Ig8BgHf7f6Ac/M/P/z8z8//PzPzz8/M/PPz8z8+/QLf7/+A///v3+3+8/PzPzz8/M/PPz8z88/PzPzz8/vB/P3/8HA==")); -var imgFri = E.toArrayBuffer(atob("Ig8B/wDwP7+geg/P5/5+c/n/n5z+f+fnP5/5+c/oHoF7/AfAf/7/7/+/n/k/z+f+R/P5/5j8/n/nHz+/++PP7//8+A==")); -var imgSat = E.toArrayBuffer(atob("Ig8B4DwDwDgOgXAJ/5+f/n/n5/+f+fn55/5+fnoHoF/fAfAf//+b/f3/5n5+f/mfn5/+Z+fn//n5+eAef358B7//nA==")); -var imgSun = E.toArrayBuffer(atob("Ig8BwHf7D7Ac/MHD/z8wMP/PzMQ/8/M/D/z8z8QPf7f6A/////83+3+/zPzPz/M/M/P8z8z8//PzPwA/B8/oD8H3/A==")); + // define days of the week images + const imgMon = E.toArrayBuffer(atob("Ig8BgHwfD5AvB8HD8z8wMPzPzMQzM/M/DMz8z8c7f7f7z////3Oz+3+PzPzPw/M/M/D8z8z8PzPzPw/vB8/n/8H3/A==")); + const imgTue = E.toArrayBuffer(atob("Ig8BwDv9wDAOfmgf/5+Z///n5n/5+fmf/n5+Z//fv9oH////Af37/b/+fn5n/5+fmf/n5+Z/+fn5n/5/g+gfn+D8AA==")); + const imgWed = E.toArrayBuffer(atob("Ig8Bf7gHgM/NA9Az8z/z8PzP/Pw/M/8/D8z/z8c7QPf7z+A//3O3/3+MzP/PwzM/8/D8z/z8PzP/PxAtA9A4B4B4DA==")); + const imgThu = E.toArrayBuffer(atob("Ig8BgHf7f6Ac/M/P/z8z8//PzPzz8/M/PPz8z8+/QLf7/+A///v3+3+8/PzPzz8/M/PPz8z88/PzPzz8/vB/P3/8HA==")); + const imgFri = E.toArrayBuffer(atob("Ig8B/wDwP7+geg/P5/5+c/n/n5z+f+fnP5/5+c/oHoF7/AfAf/7/7/+/n/k/z+f+R/P5/5j8/n/nHz+/++PP7//8+A==")); + const imgSat = E.toArrayBuffer(atob("Ig8B4DwDwDgOgXAJ/5+f/n/n5/+f+fn55/5+fnoHoF/fAfAf//+b/f3/5n5+f/mfn5/+Z+fn//n5+eAef358B7//nA==")); + const imgSun = E.toArrayBuffer(atob("Ig8BwHf7D7Ac/MHD/z8wMP/PzMQ/8/M/D/z8z8QPf7f6A/////83+3+/zPzPz/M/M/P8z8z8//PzPwA/B8/oD8H3/A==")); -// define icons -var imgSep = E.toArrayBuffer(atob("BhsBAAAAAA///////////////AAAAAAA")); -//var imgPercent = E.toArrayBuffer(atob("BwcBuq7ffbqugA==")); -var img24hr = E.toArrayBuffer(atob("EwgBj7vO53na73tcDtu9uDev7vA93g==")); -var imgPM = E.toArrayBuffer(atob("EwgB+HOfdnPu1X3ar4dV9+q+/bfftg==")); + // define icons + const imgSep = E.toArrayBuffer(atob("BhsBAAAAAA///////////////AAAAAAA")); + //var imgPercent = E.toArrayBuffer(atob("BwcBuq7ffbqugA==")); + const img24hr = E.toArrayBuffer(atob("EwgBj7vO53na73tcDtu9uDev7vA93g==")); + const imgPM = E.toArrayBuffer(atob("EwgB+HOfdnPu1X3ar4dV9+q+/bfftg==")); -//vars -var separator = true; -var is24hr = !is12Hour; -var leadingZero = true; + //vars + let separator = true; + let is24hr = !is12Hour; + let leadingZero = true; -//the following 2 sections are used from waveclk to schedule minutely updates -// timeout used to update every minute -var drawTimeout; + //the following 2 sections are used from waveclk to schedule minutely updates + // timeout used to update every minute + let drawTimeout; -// schedule a draw for the next minute -function queueDraw() { - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = setTimeout(function() { - drawTimeout = undefined; - draw(); - }, 60000 - (Date.now() % 60000)); -} - -function drawBackground() { - g.setBgColor(0,0,0); - g.setColor(1,1,1); - g.clear(); - g.drawImage(imgBg,0,0); - g.reset(); -} - -function draw(){ - drawBackground(); - var date = new Date(); - var h = date.getHours(), m = date.getMinutes(); - var d = date.getDate(), w = date.getDay(); - g.reset(); - g.setBgColor(0,0,0); - g.setColor(1,1,1); - - //draw 24 hr indicator and 12 hr specific behavior - if (is24hr){ - g.drawImage(img24hr,32, 65); - if (leadingZero){ - h = ("0"+h).substr(-2); - } - } else if (h > 12) { - g.drawImage(imgPM,40, 70); - h = h - 12; - if (leadingZero){ - h = ("0"+h).substr(-2); - } else { - h = " " + h; - } - } else if (h === 0) { - // display 12:00 instead of 00:00 for 12 hr mode - h = "12"; - } - - //draw separator - if (separator){ - g.drawImage(imgSep, 85,98);} - - //draw day of week - var imgW = null; - if (w == 0) {imgW = imgSun;} - if (w == 1) {imgW = imgMon;} - if (w == 2) {imgW = imgTue;} - if (w == 3) {imgW = imgWed;} - if (w == 4) {imgW = imgThu;} - if (w == 5) {imgW = imgFri;} - if (w == 6) {imgW = imgSat;} - g.drawImage(imgW, 85, 63); - - - // draw nums - // draw time - g.setColor(0,0,0); - g.setBgColor(1,1,1); - g.setFontCustom(fontNum, 48, 28, 41); - if (h<10) { - if (leadingZero) { - h = ("0"+h).substr(-2); - } else { - h = " " + h; - } - } - g.drawString(h, 25, 90, true); - g.drawString(("0"+m).substr(-2), 92, 90, true); - // draw date - g.setFontCustom(fontDate, 48, 12, 15); - g.drawString(("0"+d).substr(-2), 123,63, true); - - // widget redraw - Bangle.drawWidgets(); - queueDraw(); -} - -/** - * This watch is mostly dark, it does not make sense to respect the - * light theme as you end up with a white strip at the top for the - * widgets and black watch. So set the colours to the dark theme. - * - */ -g.setTheme({bg:"#000",fg:"#fff",dark:true}).clear(); -draw(); - -//the following section is also from waveclk -Bangle.on('lcdPower',on=>{ - if (on) { - draw(); // draw immediately, queue redraw - } else { // stop draw timer + // schedule a draw for the next minute + let queueDraw = function() { if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = undefined; - } -}); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); + }; -Bangle.setUI("clock"); -Bangle.loadWidgets(); -Bangle.drawWidgets(); + let drawBackground = function() { + g.setBgColor(0, 0, 0); + g.setColor(1, 1, 1); + g.clear(); + g.drawImage(imgBg, 0, 0); + g.reset(); + }; + + let draw = function() { + drawBackground(); + let date = new Date(); + let h = date.getHours(), + m = date.getMinutes(); + let d = date.getDate(), + w = date.getDay(); + g.reset(); + g.setBgColor(0, 0, 0); + g.setColor(1, 1, 1); + + //draw 24 hr indicator and 12 hr specific behavior + if (is24hr){ + g.drawImage(img24hr,32, 65); + if (leadingZero){ + h = ("0"+h).substr(-2); + } + } else if (h > 12) { + g.drawImage(imgPM,40, 70); + h = h - 12; + if (leadingZero){ + h = ("0"+h).substr(-2); + } else { + h = " " + h; + } + } else if (h === 0) { + // display 12:00 instead of 00:00 for 12 hr mode + h = "12"; + } + + //draw separator + if (separator) { + g.drawImage(imgSep, 85, 98); + } + + //draw day of week + let imgW = null; + if (w == 0) {imgW = imgSun;} + if (w == 1) {imgW = imgMon;} + if (w == 2) {imgW = imgTue;} + if (w == 3) {imgW = imgWed;} + if (w == 4) {imgW = imgThu;} + if (w == 5) {imgW = imgFri;} + if (w == 6) {imgW = imgSat;} + g.drawImage(imgW, 85, 63); + + + // draw nums + // draw time + g.setColor(0, 0, 0); + g.setBgColor(1, 1, 1); + g.setFontCustom(fontNum, 48, 28, 41); + if (h < 10) { + if (leadingZero) { + h = ("0" + h).substr(-2); + } else { + h = " " + h; + } + } + g.drawString(h, 25, 90, true); + g.drawString(("0" + m).substr(-2), 92, 90, true); + // draw date + g.setFontCustom(fontDate, 48, 12, 15); + g.drawString(("0" + d).substr(-2), 123, 63, true); + + // widget redraw + Bangle.drawWidgets(); + queueDraw(); + }; + + /** + * This watch is mostly dark, it does not make sense to respect the + * light theme as you end up with a white strip at the top for the + * widgets and black watch. So set the colours to the dark theme. + * + */ + g.setTheme({ + bg: "#000", + fg: "#fff", + dark: true + }).clear(); + draw(); + + //the following section is also from waveclk + let onLCDPower = on => { + if (on) { + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } + }; + Bangle.on('lcdPower', onLCDPower); + + Bangle.setUI({ + mode: "clock", + remove: function() { + if (drawTimeout) clearTimeout(drawTimeout); + Bangle.removeListener('lcdPower', onLCDPower); + } + }); + Bangle.loadWidgets(); + Bangle.drawWidgets(); +} diff --git a/apps/93dub/metadata.json b/apps/93dub/metadata.json index 4b0b7bd21..97b771902 100644 --- a/apps/93dub/metadata.json +++ b/apps/93dub/metadata.json @@ -3,7 +3,7 @@ "shortName":"93 Dub", "icon": "93dub.png", "screenshots": [{"url":"screenshot.png"}], - "version": "0.07", + "version": "0.08", "description": "Fan recreation of orviwan's 91 Dub app for the Pebble smartwatch. Uses assets from his 91-Dub-v2.0 repo", "tags": "clock", "type": "clock", diff --git a/apps/cc_clock24/ChangeLog b/apps/cc_clock24/ChangeLog new file mode 100644 index 000000000..c807c40a0 --- /dev/null +++ b/apps/cc_clock24/ChangeLog @@ -0,0 +1,3 @@ +0.01: copied from andark (V0.08) + refactored + add 24 hour mode diff --git a/apps/cc_clock24/README.md b/apps/cc_clock24/README.md new file mode 100644 index 000000000..84b1fa874 --- /dev/null +++ b/apps/cc_clock24/README.md @@ -0,0 +1,16 @@ +# Analog Clock With 24 hour hands + +## Features + +* second hand (only on unlocked screen) +* date +* battery percentage (showing charge status with color) +* turned off or swipeable widgets (choose in settings) + +![logo](cc_clock24_screen.png) + +## Settings + +* whether to load widgets, or not; if widgets are loaded, they are swipeable from the top; if not, NO ACTIONS of widgets are available +* date and battery can be printed both below hands (as if hands were physical) and above (more readable) +* hour hand can be made slighly shorter to improve readability when minute hand is behind a number diff --git a/apps/cc_clock24/app.js b/apps/cc_clock24/app.js new file mode 100644 index 000000000..82487a5dd --- /dev/null +++ b/apps/cc_clock24/app.js @@ -0,0 +1,277 @@ +// ----- const ----- + +const defaultSettings = { + loadWidgets : false, + textAboveHands : false, + shortHrHand : false, + show24HourMode : false +}; + +const settings = Object.assign(defaultSettings, require('Storage').readJSON('cc_clock24.json', 1) || {}); + +const center = { + "x": g.getWidth()/2, + "y": g.getHeight()/2 +}; + +const hourNumberPositions = (function() { + let positions = []; + + for (let hour = 1; hour <= 12; hour += 1) { + let phi = 30 * (hour - 3) * (Math.PI / 180); + let x = center.x + 2 + Math.cos(phi) * (center.x - 10); + let y = center.y + 2 + Math.sin(phi) * (center.x - 10); + + // fix positions, which are not on a circle + if (hour == 3){ x -= 10; } + else if (hour == 6){ y -= 10; } + else if (hour == 9){ x += 10; } + else if (hour == 12){ y += 10; } + else if (hour == 10){ x += 3; } + + positions.push([hour, x, y]); + } + return positions; +})(); + + +// ----- global vars ----- + +let drawTimeout; +let queueMillis = 1000; +let unlock = true; +let lastBatteryStates = [E.getBattery()]; + + +// ----- functions ----- + +function updateState() { + updateBatteryStates(); + + if (Bangle.isLCDOn()) { + if (!Bangle.isLocked()) { + queueMillis = 1000; + unlock = true; + } + else { + queueMillis = 60000; + unlock = false; + } + draw(); + } + else { + if (drawTimeout) + clearTimeout(drawTimeout); + drawTimeout = undefined; + } +} + + +function updateBatteryStates() { + lastBatteryStates.push(E.getBattery()); + if (lastBatteryStates.length > 5) + lastBatteryStates.shift(); // remove 1st item +} + +function drawTicks() { // draws the scale once the app is startet + // clear screen + g.setBgColor(0, 0, 0); + g.clear(); + + // draw ticks + for (let i = 1; i <= 60; i++){ + const phi = 6 * i * (Math.PI / 180); + let thickness = 2; + if (i % 5 == 0) + thickness = 5; + + g.fillPoly(calcHandPolygon(300, thickness, phi), true); + g.setColor(0, 0, 0); + g.fillRect(10, 10, 2 * center.x - 10, 2 * center.x - 10); + g.setColor(1, 1, 1); + } +} + +function calcHandPolygon(len, thickness, phi) { + const x = center.x + Math.cos(phi) * len/2, + y = center.y + Math.sin(phi) * len/2, + d = { + "d": 3, + "x": thickness/2 * Math.cos(phi + Math.PI/2), + "y": thickness/2 * Math.sin(phi + Math.PI/2) + }, + polygon = [ + center.x - d.x, + center.y - d.y, + center.x + d.x, + center.y + d.y, + x + d.x, + y + d.y, + x - d.x, + y - d.y + ]; + return polygon; +} + + +// ----- draw ---- + +function draw() { + // draw black rectangle in the middle to clear screen from scale and hands + g.setColor(0, 0, 0); + g.fillRect(10, 10, 2 * center.x - 10, 2 * center.x - 10); + + g.setFontAlign(0, 0); + drawNumbers(); + + const date = new Date(); + if (settings.textAboveHands) { + drawHands(date); + drawText(date); + } + else { + drawText(date); + drawHands(date); + } + queueDraw(); +} + + +function drawNumbers() { + g.setFont("Vector", 20); + + const batteryState = calcAvgBatteryState(); + if (batteryState < 20) + g.setColor(1, 0, 0); // draw in red, if battery is low + else if (batteryState < 40) + g.setColor(1, 1, 0); + else + g.setColor(1, 1, 1); + + g.setBgColor(0, 0, 0); + for(let i = 0; i < 12; i++) { + let hour = hourNumberPositions[i][0]; + if (settings.show24HourMode) + hour *= 2; + + g.drawString(hour, hourNumberPositions[i][1], hourNumberPositions[i][2], true); + } +} + +function calcAvgBatteryState() { + const n = lastBatteryStates.length; + if (n == 0) + return 100; + + let sum = lastBatteryStates.reduce((acc, value) => acc + value, 0); + return Math.round(sum / n); +} + +function drawHands(date) { + let m = date.getMinutes(), + h = date.getHours(), + s = date.getSeconds(); + + g.setColor(1, 1, 1); + + let numHoursForHourHand = settings.show24HourMode? 24 : 12; + + if (h > numHoursForHourHand) + h = h - numHoursForHourHand; + + + const hour_angle = 2 * Math.PI / numHoursForHourHand * (h + m/60) - Math.PI/2, + minute_angle = 2 * Math.PI / 60 * m - Math.PI/2, + second_angle = 2 * Math.PI / 60 * s - Math.PI/2; + + const hourPolygon = calcHandPolygon(settings.shortHrHand ? 88 : 100, 5, hour_angle); + g.fillPoly(hourPolygon, true); + + const minutePolygon = calcHandPolygon(150, 5, minute_angle); + g.fillPoly(minutePolygon, true); + + if (unlock) { + const secondPolygon = calcHandPolygon(150, 2, second_angle); + g.fillPoly(secondPolygon, true); + } + g.fillCircle(center.x, center.y, 4); +} + +function drawText(date) { + if (!unlock) + return; + + g.setBgColor(0, 0, 0); + g.setColor(1, 1, 1); + + const today = new Date(); + const dateStr = formatDate(today); + g.setFont("Vector", 16); + g.drawString(dateStr, center.x + 5, center.y - 30, true); + + const batteryStr = calcAvgBatteryState() + "%"; + + if (Bangle.isCharging()) + g.setBgColor(1, 0, 0); + + g.setFont("Vector", 24); + g.drawString(batteryStr, center.x, center.y + 30, true); +} + +function formatDate(date) { + const weekdays = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"]; + const month_names = ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]; + const day = date.getDate(); + const month_name = month_names[date.getMonth()]; + const weekday = weekdays[date.getDay()]; + + return weekday + " " + day + ". " + month_name; +} + +function queueDraw() { + if (drawTimeout) + clearTimeout(drawTimeout); + + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, queueMillis - (Date.now() % queueMillis)); +} + + +//// main running sequence //// + +// Show launcher when middle button pressed, and widgets that we're clock +Bangle.setUI({ + mode: "clock", + remove: function() { + Bangle.removeListener('lcdPower', updateState); + Bangle.removeListener('lock', updateState); + Bangle.removeListener('charging', draw); + + // We clear drawTimout after removing all listeners, because they can add one again + if (drawTimeout) + clearTimeout(drawTimeout); + + drawTimeout = undefined; + require("widget_utils").show(); + } +}); + +// Load widgets if needed, and make them show swipeable +if (settings.loadWidgets) { + Bangle.loadWidgets(); + require("widget_utils").swipeOn(); +} +else if (global.WIDGETS) { + require("widget_utils").hide(); +} + +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower', updateState); +Bangle.on('lock', updateState); +Bangle.on('charging', draw); // Immediately redraw when charger (dis)connected + +updateState(); +drawTicks(); +draw(); diff --git a/apps/cc_clock24/app_icon.js b/apps/cc_clock24/app_icon.js new file mode 100644 index 000000000..b213fe5c8 --- /dev/null +++ b/apps/cc_clock24/app_icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgIEBoUAiAKCgUCBQUEColEAYUQhAmKCwgeCAAcCgEDjwEBkEAg8TBocNgYFDh8GAYMDxkPjEA8EAwkHJgIcBAoPfAoYWCBYYFIgfvAoX4FYRJEAp9gAomYNAOAArPwAogAC4AFiRoIFJLgIFJuADCg//Q4U//4FDj4FEAAV4Aoi0CSxBsCA==")) \ No newline at end of file diff --git a/apps/cc_clock24/cc_clock24_icon.png b/apps/cc_clock24/cc_clock24_icon.png new file mode 100644 index 000000000..cded02071 Binary files /dev/null and b/apps/cc_clock24/cc_clock24_icon.png differ diff --git a/apps/cc_clock24/cc_clock24_screen.png b/apps/cc_clock24/cc_clock24_screen.png new file mode 100644 index 000000000..1f0e5b089 Binary files /dev/null and b/apps/cc_clock24/cc_clock24_screen.png differ diff --git a/apps/cc_clock24/metadata.json b/apps/cc_clock24/metadata.json new file mode 100644 index 000000000..e450893b7 --- /dev/null +++ b/apps/cc_clock24/metadata.json @@ -0,0 +1,18 @@ +{ "id": "cc_clock24", + "name": "CC Clock 24", + "shortName":"CC-Clock24", + "version":"0.01", + "description": "analog clock face with 24 hour pointer", + "icon": "cc_clock24_icon.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "screenshots": [{"url":"cc_clock24_screen.png"}], + "readme": "README.md", + "storage": [ + {"name":"cc_clock24.app.js","url":"app.js"}, + {"name":"cc_clock24.settings.js","url":"settings.js"}, + {"name":"cc_clock24.img","url":"app_icon.js","evaluate":true} + ], + "data": [{"name":"cc_clock24.json"}] +} diff --git a/apps/cc_clock24/settings.js b/apps/cc_clock24/settings.js new file mode 100644 index 000000000..4aa19215d --- /dev/null +++ b/apps/cc_clock24/settings.js @@ -0,0 +1,33 @@ +(function(back) { + const defaultSettings = { + loadWidgets : false, + textAboveHands : false, + shortHrHand : false, + show24HourMode : false + } + let settings = Object.assign(defaultSettings, require('Storage').readJSON('cc_clock24.json',1) || {}); + + const save = () => require('Storage').write('cc_clock24.json', settings); + + const appMenu = { + '': {title: 'cc_clock24'}, '< Back': back, + /*LANG*/'Load widgets': { + value : !!settings.loadWidgets, + onchange : v => { settings.loadWidgets=v; save();} + }, + /*LANG*/'Text above hands': { + value : !!settings.textAboveHands, + onchange : v => { settings.textAboveHands=v; save();} + }, + /*LANG*/'Short hour hand': { + value : !!settings.shortHrHand, + onchange : v => { settings.shortHrHand=v; save();} + }, + /*LANG*/'Show 24 hour mode': { + value : !!settings.show24HourMode, + onchange : v => { settings.show24HourMode=v; save();} + }, + }; + + E.showMenu(appMenu); +}) diff --git a/apps/slomoclock/ChangeLog b/apps/slomoclock/ChangeLog index 28fd26391..cfec61ae0 100644 --- a/apps/slomoclock/ChangeLog +++ b/apps/slomoclock/ChangeLog @@ -1,3 +1,4 @@ 0.01: Created app 0.10: Different colour schemes selectable in SloMo Clock settings. 0.11: Minor code improvements +0.20: Add day of week to display diff --git a/apps/slomoclock/app.js b/apps/slomoclock/app.js index 6ffc08bdb..b7a270d45 100644 --- a/apps/slomoclock/app.js +++ b/apps/slomoclock/app.js @@ -3,6 +3,7 @@ Simple watch [slomoclock] Mike Bennett mike[at]kereru.com 0.01 : Initial 0.03 : Use Layout library +0.20 : Add day of week display */ //var v='0.10'; @@ -54,7 +55,8 @@ var layout = new Layout( { {type:"txt", font:"40%", label:"", id:"hour", valign:1}, {type:"txt", font:"40%", label:"", id:"min", valign:-1}, ]}, - {type:"v", c: [ + {type:"v", c: [ + {type:"txt", font:"10%", label:"", id:"dow", col:0xEFE0, halign:1}, {type:"txt", font:"10%", label:"", id:"day", col:0xEFE0, halign:1}, {type:"txt", font:"10%", label:"", id:"mon", col:0xEFE0, halign:1}, ]} @@ -82,6 +84,8 @@ function draw() { layout.min.col = cfg.colour==0 ? colH[hh] : cfg.colour==1 ? colH[colNum] :col[cfg.colour]; // Update date + var dayOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + layout.dow.label = dayOfWeek[date.getDay()]; layout.day.label = date.getDate(); layout.mon.label = require("locale").month(date,1); diff --git a/apps/slomoclock/metadata.json b/apps/slomoclock/metadata.json index a59d82c3b..95fdc723b 100644 --- a/apps/slomoclock/metadata.json +++ b/apps/slomoclock/metadata.json @@ -2,7 +2,7 @@ "id": "slomoclock", "name": "SloMo Clock", "shortName": "SloMo Clock", - "version": "0.11", + "version": "0.20", "description": "Simple 24h clock face with large digits, hour above minute. Uses Layout library.", "icon": "watch.png", "type": "clock",