From 2ee7c6468acc5f6bbc6a4b282842906298a63689 Mon Sep 17 00:00:00 2001 From: paul-arg <18153423+paul-arg@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:27:46 +0200 Subject: [PATCH 1/6] elapsed_t: use the new pickers for target date and time --- apps/elapsed_t/ChangeLog | 1 + apps/elapsed_t/app.js | 254 ++++++++++++++++++++--------------- apps/elapsed_t/metadata.json | 2 +- 3 files changed, 150 insertions(+), 107 deletions(-) diff --git a/apps/elapsed_t/ChangeLog b/apps/elapsed_t/ChangeLog index 6a72c2590e..193bb2413d 100644 --- a/apps/elapsed_t/ChangeLog +++ b/apps/elapsed_t/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Handle AM/PM time in the "set target" menu. Add yesterday/today/tomorrow when showing target date to improve readability. 0.03: Add option to set clock as default, handle DST in day/month/year mode +0.04: Use new pickers from more_pickers library diff --git a/apps/elapsed_t/app.js b/apps/elapsed_t/app.js index 13fbca2cda..bda8d2ef1a 100644 --- a/apps/elapsed_t/app.js +++ b/apps/elapsed_t/app.js @@ -49,17 +49,12 @@ function writeData() { require('Storage').writeJSON(APP_NAME + ".data.json", data); } -function writeSettings() { - require('Storage').writeJSON(APP_NAME + ".settings.json", settings); - temp_displaySeconds = settings.temp_displaySeconds; -} - let inMenu = false; Bangle.on('touch', function (zone, e) { if (!inMenu && e.y > 24) { if (drawTimeout) clearTimeout(drawTimeout); - E.showMenu(menu); + showMainMenu(); inMenu = true; } }); @@ -112,11 +107,11 @@ function formatDateTime(date, dateFormat, time24, showSeconds) { return formattedDateTime; } -function formatHourToAMPM(h){ +function formatHourToAMPM(h) { var ampm = (h >= 12 ? 'PM' : 'AM'); var h_ampm = h % 12; h_ampm = (h_ampm == 0 ? 12 : h_ampm); - return `${h_ampm} ${ampm}` + return `${h_ampm}\n${ampm}`; } function howManyDaysInMonth(month, year) { @@ -132,95 +127,145 @@ function handleExceedingDay() { } } -var menu = { - "": { - "title": "Set target", - back: function () { - E.showMenu(); - Bangle.setUI("clock"); - inMenu = false; - draw(); - } - }, - 'Day': { - value: data.target.D, - min: 1, max: 31, wrap: true, - onchange: v => { - data.target.D = v; - } - }, - 'Month': { - value: data.target.M, - min: 1, max: 12, noList: true, wrap: true, - onchange: v => { - data.target.M = v; - handleExceedingDay(); - } - }, - 'Year': { - value: data.target.Y, - min: 1900, max: 2100, - onchange: v => { - data.target.Y = v; - handleExceedingDay(); - } - }, - 'Hours': { - value: data.target.h, - min: 0, max: 23, wrap: true, - onchange: v => { - data.target.h = v; +function getDatePickerObject() { + switch (settings.dateFormat) { + case 0: + return { + back: showMainMenu, + title: "Date", + separator_1: "/", + separator_2: "/", + + value_1: data.target.D, + min_1: 1, max_1: 31, step_1: 1, wrap_1: true, + + value_2: data.target.M, + min_2: 1, max_2: 12, step_2: 1, wrap_2: true, + + value_3: data.target.Y, + min_3: 1900, max_3: 2100, step_3: 1, wrap_3: true, + + format_1: function (v_1) { return (pad2(v_1)); }, + format_2: function (v_2) { return (pad2(v_2)); }, + onchange: function (v_1, v_2, v_3) { data.target.D = v_1; data.target.M = v_2; data.target.Y = v_3; setTarget(true); } + }; + + case 1: + return { + back: showMainMenu, + title: "Date", + separator_1: "/", + separator_2: "/", + + value_1: data.target.M, + min_1: 1, max_1: 12, step_1: 1, wrap_1: true, + + value_2: data.target.D, + min_2: 1, max_2: 31, step_2: 1, wrap_2: true, + + value_3: data.target.Y, + min_3: 1900, max_3: 2100, step_3: 1, wrap_3: true, + + format_1: function (v_1) { return (pad2(v_1)); }, + format_2: function (v_2) { return (pad2(v_2)); }, + onchange: function (v_1, v_2, v_3) { data.target.M = v_1; data.target.D = v_2; data.target.Y = v_3; setTarget(true); } + }; + + case 2: + return { + back: showMainMenu, + title: "Date", + separator_1: "-", + separator_2: "-", + + value_1: data.target.Y, + min_1: 1900, max_1: 2100, step_1: 1, wrap_1: true, + + value_2: data.target.M, + min_2: 1, max_2: 12, step_2: 1, wrap_2: true, + + value_3: data.target.D, + min_3: 1, max_3: 31, step_3: 1, wrap_3: true, + + format_1: function (v_1) { return (pad2(v_1)); }, + format_2: function (v_2) { return (pad2(v_2)); }, + onchange: function (v_1, v_2, v_3) { data.target.Y = v_1; data.target.M = v_2; data.target.D = v_3; setTarget(true); } + }; + } +} + +function getTimePickerObject() { + var timePickerObject = { + back: showMainMenu, + title: "Time", + separator_1: ":", + separator_2: ":", + + value_1: data.target.h, + min_1: 0, max_1: 23, step_1: 1, wrap_1: true, + + value_2: data.target.m, + min_2: 0, max_2: 59, step_2: 1, wrap_2: true, + + value_3: data.target.s, + min_3: 0, max_3: 59, step_3: 1, wrap_3: true, + + format_2: function (v_2) { return (pad2(v_2)); }, + format_3: function (v_3) { return (pad2(v_3)); }, + onchange: function (v_1, v_2, v_3) { data.target.h = v_1; data.target.m = v_2; data.target.s = v_3; setTarget(true); }, + }; + + if (settings.time24) { + timePickerObject.format_1 = function (v_1) { return (pad2(v_1)); }; + } else { + timePickerObject.format_1 = function (v_1) { return (formatHourToAMPM(v_1)); }; + } + + return timePickerObject; +} + +function showMainMenu() { + E.showMenu({ + "": { + "title": "Set target", + back: function () { + E.showMenu(); + Bangle.setUI("clock"); + inMenu = false; + draw(); + } }, - format: function (v) {return(settings.time24 ? pad2(v) : formatHourToAMPM(v))} - }, - 'Minutes': { - value: data.target.m, - min: 0, max: 59, wrap: true, - onchange: v => { - data.target.m = v; + 'Date': { + value: formatDateTime(target, settings.dateFormat, settings.time24, true).date, + onchange: function () { require("more_pickers").triplePicker(getDatePickerObject()); } }, - format: function (v) { return pad2(v); } - }, - 'Seconds': { - value: data.target.s, - min: 0, max: 59, wrap: true, - onchange: v => { - data.target.s = v; + 'Time': { + value: formatDateTime(target, settings.dateFormat, settings.time24, true).time, + onchange: function () { require("more_pickers").triplePicker(getTimePickerObject()); } }, - format: function (v) { return pad2(v); } - }, - 'Save': function () { - E.showMenu(); - inMenu = false; - Bangle.setUI("clock"); - setTarget(true); - writeSettings(); - temp_displaySeconds = settings.displaySeconds; - updateQueueMillis(settings.displaySeconds); - draw(); - }, - 'Reset': function () { - E.showMenu(); - inMenu = false; - Bangle.setUI("clock"); - setTarget(false); - updateQueueMillis(settings.displaySeconds); - draw(); - }, - 'Set clock as default': function () { - setClockAsDefault(); - E.showAlert("Elapsed Time was set as default").then(function() { + 'Reset': function () { E.showMenu(); inMenu = false; Bangle.setUI("clock"); + setTarget(false); + updateQueueMillis(settings.displaySeconds); draw(); - }); - } -}; + }, + 'Set clock as default': function () { + setClockAsDefault(); + E.showAlert("Elapsed Time was set as default").then(function () { + E.showMenu(); + inMenu = false; + Bangle.setUI("clock"); + draw(); + }); + } + }); +} -function setClockAsDefault(){ +function setClockAsDefault() { let storage = require('Storage'); - let settings = storage.readJSON('setting.json',true)||{clock:null}; + let settings = storage.readJSON('setting.json', true) || { clock: null }; settings.clock = "elapsed_t.app.js"; storage.writeJSON('setting.json', settings); } @@ -238,26 +283,21 @@ function setTarget(set) { data.target.isSet = true; } else { target = new Date(); + target.setSeconds(0); Object.assign( data, { target: { isSet: false, - Y: now.getFullYear(), - M: now.getMonth() + 1, // Month is zero-based, so add 1 - D: now.getDate(), - h: now.getHours(), - m: now.getMinutes(), + Y: target.getFullYear(), + M: target.getMonth() + 1, // Month is zero-based, so add 1 + D: target.getDate(), + h: target.getHours(), + m: target.getMinutes(), s: 0 } } ); - menu.Day.value = data.target.D; - menu.Month.value = data.target.M; - menu.Year.value = data.target.Y; - menu.Hours.value = data.target.h; - menu.Minutes.value = data.target.m; - menu.Seconds.value = 0; } writeData(); @@ -269,7 +309,6 @@ setTarget(data.target.isSet); var drawTimeout; var queueMillis = 1000; - function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); var delay = queueMillis - (Date.now() % queueMillis); @@ -335,18 +374,21 @@ function diffToTarget() { var end; if (now > target) { - start = target; - end = now; + start = new Date(target.getTime()); + end = new Date(now.getTime()); } else { - start = now; - end = target; + start = new Date(now.getTime()); + end = new Date(target.getTime()); } + // Adjust for DST + end.setMinutes(end.getMinutes() + end.getTimezoneOffset() - start.getTimezoneOffset()); + diff.Y = end.getFullYear() - start.getFullYear(); diff.M = end.getMonth() - start.getMonth(); diff.D = end.getDate() - start.getDate(); diff.hh = end.getHours() - start.getHours(); - diff.mm = end.getMinutes() - start.getMinutes() + end.getTimezoneOffset() - start.getTimezoneOffset(); + diff.mm = end.getMinutes() - start.getMinutes(); diff.ss = end.getSeconds() - start.getSeconds(); // Adjust negative differences @@ -372,7 +414,6 @@ function diffToTarget() { diff.Y--; } - } else { var timeDifference = target - now; timeDifference = Math.abs(timeDifference); @@ -492,3 +533,4 @@ Bangle.drawWidgets(); Bangle.setUI("clock"); draw(); + diff --git a/apps/elapsed_t/metadata.json b/apps/elapsed_t/metadata.json index fa0674e0ba..2515e0e799 100644 --- a/apps/elapsed_t/metadata.json +++ b/apps/elapsed_t/metadata.json @@ -3,7 +3,7 @@ "name": "Elapsed Time Clock", "shortName": "Elapsed Time", "type": "clock", - "version":"0.03", + "version":"0.04", "description": "A clock that calculates the time difference between now and any given target date.", "tags": "clock,tool", "supports": ["BANGLEJS2"], From 81fd82926f94211be7a7b669dbdcaa5d3dc70a8e Mon Sep 17 00:00:00 2001 From: paul-arg <18153423+paul-arg@users.noreply.github.com> Date: Sun, 23 Jun 2024 22:16:55 +0200 Subject: [PATCH 2/6] fix bug preventing to not show seconds when locked --- apps/elapsed_t/app.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/elapsed_t/app.js b/apps/elapsed_t/app.js index bda8d2ef1a..246ae44659 100644 --- a/apps/elapsed_t/app.js +++ b/apps/elapsed_t/app.js @@ -532,5 +532,11 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); Bangle.setUI("clock"); +if (Bangle.isBacklightOn()) { + temp_displaySeconds = settings.displaySeconds; + updateQueueMillis(temp_displaySeconds); +} else { + temp_displaySeconds = false; + updateQueueMillis(false); +} draw(); - From 03f1f8cda0e67c561bc8102ff8cda90734a3b3a8 Mon Sep 17 00:00:00 2001 From: paul-arg <18153423+paul-arg@users.noreply.github.com> Date: Sun, 23 Jun 2024 22:54:16 +0200 Subject: [PATCH 3/6] elapsed_t: add setting to show seconds never/unlocked/always --- apps/elapsed_t/ChangeLog | 2 +- apps/elapsed_t/app.js | 48 +++++++++++++++----------------------- apps/elapsed_t/settings.js | 9 ++++--- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/apps/elapsed_t/ChangeLog b/apps/elapsed_t/ChangeLog index 193bb2413d..26fbf5ff02 100644 --- a/apps/elapsed_t/ChangeLog +++ b/apps/elapsed_t/ChangeLog @@ -1,4 +1,4 @@ 0.01: New App! 0.02: Handle AM/PM time in the "set target" menu. Add yesterday/today/tomorrow when showing target date to improve readability. 0.03: Add option to set clock as default, handle DST in day/month/year mode -0.04: Use new pickers from more_pickers library +0.04: Use new pickers from the more_pickers library, add settings to display seconds never/unlocked/always diff --git a/apps/elapsed_t/app.js b/apps/elapsed_t/app.js index 246ae44659..08e2e145f7 100644 --- a/apps/elapsed_t/app.js +++ b/apps/elapsed_t/app.js @@ -24,14 +24,12 @@ var now = new Date(); var settings = Object.assign({ // default values - displaySeconds: true, + displaySeconds: 1, displayMonthsYears: true, dateFormat: 0, time24: true }, require('Storage').readJSON(APP_NAME + ".settings.json", true) || {}); -var temp_displaySeconds = settings.displaySeconds; - var data = Object.assign({ // default values target: { @@ -118,15 +116,6 @@ function howManyDaysInMonth(month, year) { return new Date(year, month, 0).getDate(); } -function handleExceedingDay() { - var maxDays = howManyDaysInMonth(data.target.M, data.target.Y); - menu.Day.max = maxDays; - if (data.target.D > maxDays) { - menu.Day.value = maxDays; - data.target.D = maxDays; - } -} - function getDatePickerObject() { switch (settings.dateFormat) { case 0: @@ -248,7 +237,6 @@ function showMainMenu() { inMenu = false; Bangle.setUI("clock"); setTarget(false); - updateQueueMillis(settings.displaySeconds); draw(); }, 'Set clock as default': function () { @@ -307,7 +295,8 @@ var target; setTarget(data.target.isSet); var drawTimeout; -var queueMillis = 1000; +var temp_displaySeconds; +var queueMillis; function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); @@ -322,27 +311,25 @@ function queueDraw() { }, delay); } -function updateQueueMillis(displaySeconds) { +function updateQueueMillisAndDraw(displaySeconds) { + temp_displaySeconds = displaySeconds; if (displaySeconds) { queueMillis = 1000; } else { queueMillis = 60000; } + draw(); } Bangle.on('lock', function (on, reason) { - if (inMenu) { // if already in a menu, nothing to do + if (inMenu || settings.displaySeconds == 0 || settings.displaySeconds == 2) { // if already in a menu, or always/never show seconds, nothing to do return; } if (on) { // screen is locked - temp_displaySeconds = false; - updateQueueMillis(false); - draw(); + updateQueueMillisAndDraw(false); } else { // screen is unlocked - temp_displaySeconds = settings.displaySeconds; - updateQueueMillis(temp_displaySeconds); - draw(); + updateQueueMillisAndDraw(true); } }); @@ -532,11 +519,14 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); Bangle.setUI("clock"); -if (Bangle.isBacklightOn()) { - temp_displaySeconds = settings.displaySeconds; - updateQueueMillis(temp_displaySeconds); -} else { - temp_displaySeconds = false; - updateQueueMillis(false); +switch (settings.displaySeconds) { + case 0: // never + updateQueueMillisAndDraw(false); + break; + case 1: // unlocked + updateQueueMillisAndDraw(Bangle.isBacklightOn()); + break; + case 2: // always + updateQueueMillisAndDraw(true); + break; } -draw(); diff --git a/apps/elapsed_t/settings.js b/apps/elapsed_t/settings.js index d3a7cb3572..9b405986f0 100644 --- a/apps/elapsed_t/settings.js +++ b/apps/elapsed_t/settings.js @@ -4,7 +4,7 @@ // Load settings var settings = Object.assign({ // default values - displaySeconds: true, + displaySeconds: 1, displayMonthsYears: true, dateFormat: 0, time24: true @@ -15,17 +15,20 @@ } var dateFormats = ["DD/MM/YYYY", "MM/DD/YYYY", "YYYY-MM-DD"]; + var displaySecondsFormats = ["Never", "Unlocked", "Always"]; // Show the menu E.showMenu({ "" : { "title" : "Elapsed Time" }, "< Back" : () => back(), 'Show\nseconds': { - value: !!settings.displaySeconds, + value: settings.displaySeconds, + min: 0, max: 2, wrap: true, onchange: v => { settings.displaySeconds = v; writeSettings(); - } + }, + format: function (v) {return displaySecondsFormats[v];} }, 'Show months/\nyears': { value: !!settings.displayMonthsYears, From e5c82c43415a826c0a3fbbbebdd434778a09f06a Mon Sep 17 00:00:00 2001 From: paul-arg <18153423+paul-arg@users.noreply.github.com> Date: Sun, 23 Jun 2024 23:03:59 +0200 Subject: [PATCH 4/6] elapsed_t: ensure retro compatibility with the previous displaySeconds setting --- apps/elapsed_t/app.js | 9 +++++++++ apps/elapsed_t/settings.js | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/apps/elapsed_t/app.js b/apps/elapsed_t/app.js index 08e2e145f7..29bea4fef1 100644 --- a/apps/elapsed_t/app.js +++ b/apps/elapsed_t/app.js @@ -30,6 +30,15 @@ var settings = Object.assign({ time24: true }, require('Storage').readJSON(APP_NAME + ".settings.json", true) || {}); +function writeSettings() { + require('Storage').writeJSON(APP_NAME + ".settings.json", settings); +} + +if (typeof settings.displaySeconds === 'boolean') { + settings.displaySeconds = 1; + writeSettings(); +} + var data = Object.assign({ // default values target: { diff --git a/apps/elapsed_t/settings.js b/apps/elapsed_t/settings.js index 9b405986f0..4726516d50 100644 --- a/apps/elapsed_t/settings.js +++ b/apps/elapsed_t/settings.js @@ -14,6 +14,11 @@ require('Storage').writeJSON(FILE, settings); } + if (typeof settings.displaySeconds === 'boolean') { + settings.displaySeconds = 1; + writeSettings(); + } + var dateFormats = ["DD/MM/YYYY", "MM/DD/YYYY", "YYYY-MM-DD"]; var displaySecondsFormats = ["Never", "Unlocked", "Always"]; From e984cb18c0ce0553d9528e9b38cf6860eb319ac4 Mon Sep 17 00:00:00 2001 From: paul-arg <18153423+paul-arg@users.noreply.github.com> Date: Sun, 23 Jun 2024 23:05:44 +0200 Subject: [PATCH 5/6] elapsed_t: update readme --- apps/elapsed_t/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/elapsed_t/README.md b/apps/elapsed_t/README.md index dc2173409b..9e361be59b 100644 --- a/apps/elapsed_t/README.md +++ b/apps/elapsed_t/README.md @@ -1,7 +1,10 @@ # Elapsed Time Clock A clock that calculates the time difference between now (in blue/cyan) and any given target date (in red/orange). -The results is show in years, months, days, hours, minutes, seconds. To save battery life, the seconds are shown only when the watch is unlocked, or can be disabled entirely. +The results is show in years, months, days, hours, minutes, seconds. The seconds can be shown: +- always +- when the watch is unlocked +- never. The time difference is positive if the target date is in the past and negative if it is in the future. From 4b1e4d01ce1cb5924d09e3de31b30b674c0414b8 Mon Sep 17 00:00:00 2001 From: paul-arg <18153423+paul-arg@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:55:23 +0200 Subject: [PATCH 6/6] elapsed_t: remove unused function --- apps/elapsed_t/app.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/elapsed_t/app.js b/apps/elapsed_t/app.js index 29bea4fef1..910ff85f3c 100644 --- a/apps/elapsed_t/app.js +++ b/apps/elapsed_t/app.js @@ -121,10 +121,6 @@ function formatHourToAMPM(h) { return `${h_ampm}\n${ampm}`; } -function howManyDaysInMonth(month, year) { - return new Date(year, month, 0).getDate(); -} - function getDatePickerObject() { switch (settings.dateFormat) { case 0: