From 178b011c34c70ebcbf160fa986f7fd58324b8896 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sun, 27 Mar 2022 10:30:34 +0800 Subject: [PATCH] Fix #1583. Fix timers doubling (plus a bit) when they expire. Timer reset restores to configured time, not to the default. Added surise/sunset times (hidden by default). --- apps/timerclk/ChangeLog | 1 + apps/timerclk/README.md | 1 + apps/timerclk/alarm.info | 1 - apps/timerclk/app.js | 34 ++++++++++++++++++++++++++++++++++ apps/timerclk/boot.js | 19 +++++-------------- apps/timerclk/lib.js | 2 ++ apps/timerclk/metadata.json | 5 +---- apps/timerclk/settings.js | 28 ++++++++++++++++++++++++++++ apps/timerclk/stopwatch.info | 1 - apps/timerclk/timer.alert.js | 17 +++-------------- apps/timerclk/timer.info | 1 - apps/timerclk/timer.js | 8 +++++--- 12 files changed, 80 insertions(+), 38 deletions(-) delete mode 100644 apps/timerclk/alarm.info delete mode 100644 apps/timerclk/stopwatch.info delete mode 100644 apps/timerclk/timer.info diff --git a/apps/timerclk/ChangeLog b/apps/timerclk/ChangeLog index 5560f00bc..e17baa27c 100644 --- a/apps/timerclk/ChangeLog +++ b/apps/timerclk/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: Add sunrise/sunset. Fix timer bugs. diff --git a/apps/timerclk/README.md b/apps/timerclk/README.md index fd6d2b16b..c27a8f6f8 100644 --- a/apps/timerclk/README.md +++ b/apps/timerclk/README.md @@ -11,6 +11,7 @@ A clock based on the Anton Clock with stopwatches, timers and alarms based on th * alarms * multiple stopwatches, timers and alarms * stopwatches and timers keep running in the background +* optional time of sunrise/sunset using the My Location app - hidden by default ## Images diff --git a/apps/timerclk/alarm.info b/apps/timerclk/alarm.info deleted file mode 100644 index 1289f8cef..000000000 --- a/apps/timerclk/alarm.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"timerclk","name":"tclk Alarm","src":"timerclk.alarm.js","icon":"timerclk.img","version":"0.01","tags":"","files":"","sortorder":10} diff --git a/apps/timerclk/app.js b/apps/timerclk/app.js index eeb3ac4cd..c750fcfde 100644 --- a/apps/timerclk/app.js +++ b/apps/timerclk/app.js @@ -3,6 +3,23 @@ Graphics.prototype.setFontAnton = function(scale) { g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAA/gAAAAAAAAAAP/gAAAAAAAAAH//gAAAAAAAAB///gAAAAAAAAf///gAAAAAAAP////gAAAAAAD/////gAAAAAA//////gAAAAAP//////gAAAAH///////gAAAB////////gAAAf////////gAAP/////////gAD//////////AA//////////gAA/////////4AAA////////+AAAA////////gAAAA///////wAAAAA//////8AAAAAA//////AAAAAAA/////gAAAAAAA////4AAAAAAAA///+AAAAAAAAA///gAAAAAAAAA//wAAAAAAAAAA/8AAAAAAAAAAA/AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////AAAAAB///////8AAAAH////////AAAAf////////wAAA/////////4AAB/////////8AAD/////////+AAH//////////AAP//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wA//8AAAAAB//4A//wAAAAAAf/4A//gAAAAAAP/4A//gAAAAAAP/4A//gAAAAAAP/4A//wAAAAAAf/4A///////////4Af//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH//////////AAD/////////+AAB/////////8AAA/////////4AAAP////////gAAAD///////+AAAAAf//////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAP/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/AAAAAAAAAAA//AAAAAAAAAAA/+AAAAAAAAAAB/8AAAAAAAAAAD//////////gAH//////////gAP//////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAAB/gAAD//4AAAAf/gAAP//4AAAB//gAA///4AAAH//gAB///4AAAf//gAD///4AAA///gAH///4AAD///gAP///4AAH///gAP///4AAP///gAf///4AAf///gAf///4AB////gAf///4AD////gA////4AH////gA////4Af////gA////4A/////gA//wAAB/////gA//gAAH/////gA//gAAP/////gA//gAA///8//gA//gAD///w//gA//wA////g//gA////////A//gA///////8A//gA///////4A//gAf//////wA//gAf//////gA//gAf/////+AA//gAP/////8AA//gAP/////4AA//gAH/////gAA//gAD/////AAA//gAB////8AAA//gAA////wAAA//gAAP///AAAA//gAAD//8AAAA//gAAAP+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/+AAAAAD/wAAB//8AAAAP/wAAB///AAAA//wAAB///wAAB//wAAB///4AAD//wAAB///8AAH//wAAB///+AAP//wAAB///+AAP//wAAB////AAf//wAAB////AAf//wAAB////gAf//wAAB////gA///wAAB////gA///wAAB////gA///w//AAf//wA//4A//AAA//wA//gA//AAAf/wA//gB//gAAf/wA//gB//gAAf/wA//gD//wAA//wA//wH//8AB//wA///////////gA///////////gA///////////gA///////////gAf//////////AAf//////////AAP//////////AAP/////////+AAH/////////8AAH///+/////4AAD///+f////wAAA///8P////gAAAf//4H///+AAAAH//gB///wAAAAAP4AAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAAAAAAAAAA//wAAAAAAAAAP//wAAAAAAAAB///wAAAAAAAAf///wAAAAAAAH////wAAAAAAA/////wAAAAAAP/////wAAAAAB//////wAAAAAf//////wAAAAH///////wAAAA////////wAAAP////////wAAA///////H/wAAA//////wH/wAAA/////8AH/wAAA/////AAH/wAAA////gAAH/wAAA///4AAAH/wAAA//+AAAAH/wAAA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAH/4AAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8AAA/////+B///AAA/////+B///wAA/////+B///4AA/////+B///8AA/////+B///8AA/////+B///+AA/////+B////AA/////+B////AA/////+B////AA/////+B////gA/////+B////gA/////+B////gA/////+A////gA//gP/gAAB//wA//gf/AAAA//wA//gf/AAAAf/wA//g//AAAAf/wA//g//AAAA//wA//g//gAAA//wA//g//+AAP//wA//g////////gA//g////////gA//g////////gA//g////////gA//g////////AA//gf///////AA//gf//////+AA//gP//////+AA//gH//////8AA//gD//////4AA//gB//////wAA//gA//////AAAAAAAH////8AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////gAAAAB///////+AAAAH////////gAAAf////////4AAB/////////8AAD/////////+AAH//////////AAH//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wAf//////////4A//wAD/4AAf/4A//gAH/wAAP/4A//gAH/wAAP/4A//gAP/wAAP/4A//gAP/4AAf/4A//wAP/+AD//4A///wP//////4Af//4P//////wAf//4P//////wAf//4P//////wAf//4P//////wAP//4P//////gAP//4H//////gAH//4H//////AAH//4D/////+AAD//4D/////8AAB//4B/////4AAA//4A/////wAAAP/4AP////AAAAB/4AD///4AAAAAAAAAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAADgA//gAAAAAAP/gA//gAAAAAH//gA//gAAAAB///gA//gAAAAP///gA//gAAAD////gA//gAAAf////gA//gAAB/////gA//gAAP/////gA//gAB//////gA//gAH//////gA//gA///////gA//gD///////gA//gf///////gA//h////////gA//n////////gA//////////gAA/////////AAAA////////wAAAA///////4AAAAA///////AAAAAA//////4AAAAAA//////AAAAAAA/////4AAAAAAA/////AAAAAAAA////8AAAAAAAA////gAAAAAAAA///+AAAAAAAAA///4AAAAAAAAA///AAAAAAAAAA//4AAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//gB///wAAAAP//4H///+AAAA///8P////gAAB///+f////4AAD///+/////8AAH/////////+AAH//////////AAP//////////gAP//////////gAf//////////gAf//////////wAf//////////wAf//////////wA///////////wA//4D//wAB//4A//wB//gAA//4A//gA//gAAf/4A//gA//AAAf/4A//gA//gAAf/4A//wB//gAA//4A///P//8AH//4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////gAP//////////gAP//////////AAH//////////AAD/////////+AAD///+/////8AAB///8f////wAAAf//4P////AAAAH//wD///8AAAAA/+AAf//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAAAAAAAAB///+AA/+AAAAP////gA//wAAAf////wA//4AAB/////4A//8AAD/////8A//+AAD/////+A///AAH/////+A///AAP//////A///gAP//////A///gAf//////A///wAf//////A///wAf//////A///wAf//////A///wA///////AB//4A//4AD//AAP/4A//gAB//AAP/4A//gAA//AAP/4A//gAA/+AAP/4A//gAB/8AAP/4A//wAB/8AAf/4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH/////////+AAD/////////8AAB/////////4AAAf////////wAAAP////////AAAAB///////4AAAAAD/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAB/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("EiAnGicnJycnJycnEw=="), 78+(scale<<8)+(1<<16)); }; +var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js"); +const LOCATION_FILE = "mylocation.json"; +let location; +var sunRise = "--:--"; +var sunSet = "--:--"; +var sunIcons = "\0" + atob("DwyBAAAAAAAAAAgAOAD4A/gP+D/4//gAAAAA") + "\0" + atob("FQyDAAAAAAAAAAAAAAAABAAAAAAABAAIABAAAAABAAABAAAAAAABJAAAAABAAJJJIABAABAJJJJIBAAAAJJJJJIAAAAJJJJJJIAAJBJJJJJJBIAAJJJJJJIAAAAAAAAAAAAA") + "\0" + atob("DwyBAAAAAAAAA//j/4P+A/gD4AOAAgAAAAAA"); + +function loadLocation() { + location = require('Storage').readJSON(LOCATION_FILE, true) || {lat:51.5072,lon:0.1276,location:"London"}; +} + +function updateSunRiseSunSet(location) { + var times = SunCalc.getTimes(new Date(), location.lat, location.lon); + sunRise = require("locale").time(times.sunrise, 1); + sunSet = require("locale").time(times.sunset, 1); +} + var timerclk = require("timerclk.lib.js"); var settings = require('Storage').readJSON("timerclk.json", true) || {}; settings = Object.assign({ @@ -12,11 +29,14 @@ settings = Object.assign({ "dateFontSize":2, "dowFont":"6x8", "dowFontSize":2, + "srssFont":"6x8", + "srssFontSize":2, "specialFont":"6x8", "specialFontSize":2, "shortDate":true, "showStopwatches":true, "showTimers":true, + "showSrss":false, }, settings.clock||{}); var stopwatches = [], timers = []; @@ -77,7 +97,12 @@ function drawSpecial() { queueDraw(drawSpecialTimeout, interval, drawSpecial); } +var drawCount=0; + function draw() { + if (drawCount++ % 60 == 0) { + updateSunRiseSunSet(location); + } var x = g.getWidth()/2; var y = g.getHeight()/2; g.reset(); @@ -85,6 +110,7 @@ function draw() { var timeStr = require("locale").time(date,1); var dateStr = require("locale").date(date,settings.shortDate).toUpperCase(); var dowStr = require("locale").dow(date).toUpperCase(); + var srssStr = sunRise + sunIcons + sunSet; // draw time if (settings.timeFont == "Anton") { @@ -105,6 +131,13 @@ function draw() { g.setFontAlign(0,0).setFont(settings.dowFont, settings.dowFontSize); y += g.stringMetrics(dowStr).height/2; g.drawString(dowStr,x,y); + if (settings.showSrss) { + // draw sun rise sun set + y += g.stringMetrics(dowStr).height/2; + g.setFontAlign(0,0).setFont(settings.srssFont, settings.srssFontSize); + y += g.stringMetrics(srssStr).height/2; + g.drawString(srssStr,x,y); + } // queue draw in one minute queueDraw(drawTimeout, 60000, draw); } @@ -147,5 +180,6 @@ Bangle.setUI("clock"); // Show launcher when middle button pressed g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); +loadLocation(); draw(); if (stopwatches || timers) drawSpecial(); diff --git a/apps/timerclk/boot.js b/apps/timerclk/boot.js index 9a09f68f3..b6eb05c14 100644 --- a/apps/timerclk/boot.js +++ b/apps/timerclk/boot.js @@ -1,26 +1,17 @@ var timerclkTimerTimeout; var timerclkAlarmTimeout; function timerclkCheckTimers() { + var expiresIn=require("timerclk.lib.js").timerExpiresIn; if (timerclkTimerTimeout) clearTimeout(timerclkTimerTimeout); var timers = require('Storage').readJSON('timerclk.timer.json',1)||[]; timers = timers.filter(e=>e.start); if (timers.length) { - timers = timers.sort((a,b)=>{ - var at = a.timeAdd; - if (a.start) at += Date.now()-a.start; - at = a.period-at; - var bt = b.timeAdd; - if (b.start) bt += Date.now()-b.start; - bt = b.period-bt; - return at-bt; - }); + timers = timers.sort((a,b)=>expiresIn(a)-expiresIn(b)); if (!require('Storage').read("timerclk.timer.alert.js")) { console.log("No timer app!"); } else { - var time = timers[0].timeAdd; - if (timers[0].start) time += Date.now()-timers[0].start; - time = timers[0].time - time; - if (time<1000) t=1000; + var time = expiresIn(timers[0]); + if (time<1000) time=1000; if (timerclkTimerTimeout) clearTimeout(timerclkTimerTimeout); timerclkTimerTimeout = setTimeout(() => load("timerclk.timer.alert.js"),time); } @@ -38,7 +29,7 @@ function timerclkCheckAlarms() { } else { var time = alarms[0].time-currentTime; if (alarms[0].last == new Date().getDate() || time < 0) time += 86400000; - if (time<1000) t=1000; + if (time<1000) time=1000; if (timerclkAlarmTimeout) clearTimeout(timerclkAlarmTimeout); timerclkAlarmTimeout = setTimeout(() => load("timerclk.alarm.alert.js"),time); } diff --git a/apps/timerclk/lib.js b/apps/timerclk/lib.js index 718962fe0..dd3893fa1 100644 --- a/apps/timerclk/lib.js +++ b/apps/timerclk/lib.js @@ -125,3 +125,5 @@ exports.registerControls = function(o) { }); } }; + +exports.timerExpiresIn=t=>t.time-(Date.now()-t.start); diff --git a/apps/timerclk/metadata.json b/apps/timerclk/metadata.json index 6b415c0fc..ce8870ab0 100644 --- a/apps/timerclk/metadata.json +++ b/apps/timerclk/metadata.json @@ -2,7 +2,7 @@ "id": "timerclk", "name": "Timer Clock", "shortName":"Timer Clock", - "version":"0.01", + "version":"0.02", "description": "A clock with stopwatches, timers and alarms build in.", "icon": "app-icon.png", "type": "clock", @@ -29,9 +29,6 @@ {"name":"timerclk.timer.alert.js","url":"timer.alert.js"}, {"name":"timerclk.alarm.js","url":"alarm.js"}, {"name":"timerclk.alarm.alert.js","url":"alarm.alert.js"}, - {"name":"timerclk.stopwatch.info","url":"stopwatch.info"}, - {"name":"timerclk.timer.info","url":"timer.info"}, - {"name":"timerclk.alarm.info","url":"alarm.info"} ], "data": [{"name":"timerclk.json"},{"name":"timerclk.stopwatch.json"},{"name":"timerclk.timer.json"},{"name":"timerclk.alarm.json"}], "sortorder": 0 diff --git a/apps/timerclk/settings.js b/apps/timerclk/settings.js index 556dded98..992985f52 100644 --- a/apps/timerclk/settings.js +++ b/apps/timerclk/settings.js @@ -12,9 +12,12 @@ "dowFontSize":2, "specialFont":"6x8", "specialFontSize":2, + "srssFont":"6x8", + "srssFontSize":2, "shortDate":true, "showStopwatches":true, "showTimers":true, + "showSrss":false, }, settings.clock||{}); settings.stopwatch = Object.assign({ "font":"Vector", @@ -108,6 +111,23 @@ writeSettings(); } }, + "sun font":{ + value: 0|g.getFonts().indexOf(settings.clock.srssFont), + format: v => g.getFonts()[v], + min: 0, max: g.getFonts().length-1, + onchange: v => { + settings.clock.srssFont = g.getFonts()[v]; + writeSettings(); + } + }, + "sun size":{ + value: 0|settings.clock.srssFontSize, + min: 0, + onchange: v => { + settings.clock.srssFontSize = v; + writeSettings(); + } + }, "short date": { value: !!settings.clock.shortDate, format: BOOL_FORMAT, @@ -132,6 +152,14 @@ writeSettings(); } }, + "sun times": { + value: !!settings.clock.showSrss, + format: v=>v?/*LANG*/"Show":/*LANG*/"Hide", + onchange: v => { + settings.clock.showSrss = v; + writeSettings(); + } + }, }; var stopwatchMenu = { diff --git a/apps/timerclk/stopwatch.info b/apps/timerclk/stopwatch.info deleted file mode 100644 index 72ad418b1..000000000 --- a/apps/timerclk/stopwatch.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"timerclk","name":"tclk Stopwatch","src":"timerclk.stopwatch.js","icon":"timerclk.img","version":"0.01","tags":"","files":"","sortorder":10} diff --git a/apps/timerclk/timer.alert.js b/apps/timerclk/timer.alert.js index f51ea6767..96352097d 100644 --- a/apps/timerclk/timer.alert.js +++ b/apps/timerclk/timer.alert.js @@ -14,10 +14,7 @@ function showTimer(timer) { buttons : {/*LANG*/"Ok":true} }).then(function(ok) { buzzCount = 0; - if (ok) { - timer.time += Date.now() - timer.start; - timer.start = null; - } + timer.start = null; require("Storage").write("timerclk.timer.json",JSON.stringify(timers)); load(); }); @@ -45,16 +42,8 @@ console.log("checking for timers..."); var timers = require("Storage").readJSON("timerclk.timer.json",1)||[]; var active = timers.filter(e=>e.start); if (active.length) { - // if there's an timer, show it - active = active.sort((a,b)=>{ - var at = a.time; - if (a.start) at += Date.now()-a.start; - at = a.period-at; - var bt = b.time; - if (b.start) bt += Date.now()-b.start; - bt = b.period-bt; - return at-bt; - }); + // if there's an active timer, show it + active = active.sort((a,b)=>timerclk.timerExpiresIn(a)-timerclk.timerExpiresIn(b)); showTimer(active[0]); } else { // otherwise just go back to default app diff --git a/apps/timerclk/timer.info b/apps/timerclk/timer.info deleted file mode 100644 index 39a338693..000000000 --- a/apps/timerclk/timer.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"timerclk","name":"tclk Timer","src":"timerclk.timer.js","icon":"timerclk.img","version":"0.01","tags":"","files":"","sortorder":10} diff --git a/apps/timerclk/timer.js b/apps/timerclk/timer.js index 060c07813..25052e6ae 100644 --- a/apps/timerclk/timer.js +++ b/apps/timerclk/timer.js @@ -34,18 +34,20 @@ function update() { } function play() { if (all[current].start) { // running - all[current].timeAdd += Date.now() - all[current].start; + all[current].timeAdd = Date.now() - all[current].start; all[current].start = null; update(); } else { // paused - all[current].start = Date.now(); + all[current].start = Date.now() - all[current].timeAdd; + all[current].timeAdd = 0; update(); } require("Storage").write("timerclk.timer.json",JSON.stringify(all)); timerclkCheckTimers(); } function reset() { - all[current] = defaultElement.clone(); + all[current].start = null; + all[current].timeAdd = 0; update(); require("Storage").write("timerclk.timer.json",JSON.stringify(all)); timerclkCheckTimers();