From 1251f261da4ff7a6eb0d7ecab8124303f7fdbb57 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Tue, 2 Jul 2024 00:43:29 +0200 Subject: [PATCH 01/96] spotrem: refactor to handle ui all inside setUI and fix lint warnings --- apps/spotrem/ChangeLog | 1 + apps/spotrem/app.js | 15 ++++----------- apps/spotrem/metadata.json | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/apps/spotrem/ChangeLog b/apps/spotrem/ChangeLog index 723fbd2d7..f21454551 100644 --- a/apps/spotrem/ChangeLog +++ b/apps/spotrem/ChangeLog @@ -11,3 +11,4 @@ when fastloading. 0.10: Some refactoring to shorten the code. 0.11: Further refactoring to shorten the code. Fixed search and play that was broken in v0.10. 0.12: Fix some warnings from the linter. +0.13: Move ui-handlers inside setUI-call. diff --git a/apps/spotrem/app.js b/apps/spotrem/app.js index 4abc5392c..bbe706b93 100644 --- a/apps/spotrem/app.js +++ b/apps/spotrem/app.js @@ -14,7 +14,6 @@ let gfx = function() { widgetUtils.hide(); R = Bangle.appRect; const MARIGIN = 8; - // g.drawString(str, x, y, solid) g.clearRect(R); g.reset(); @@ -100,23 +99,17 @@ let swipeHandler = function(LR, _) { // Navigation input on the main layout let setUI = function() { -// Bangle.setUI code from rigrig's smessages app for volume control: https://git.tubul.net/rigrig/BangleApps/src/branch/personal/apps/smessages/app.js Bangle.setUI( {mode : "updown", - remove : ()=>{ - Bangle.removeListener("touch", touchHandler); - Bangle.removeListener("swipe", swipeHandler); - clearWatch(buttonHandler); - widgetUtils.show(); - } + touch: touchHandler, + swipe: swipeHandler, + btn: ()=>load(), + remove : ()=>widgetUtils.show(), }, ud => { if (ud) Bangle.musicControl(ud>0 ? "volumedown" : "volumeup"); } ); - Bangle.on("touch", touchHandler); - Bangle.on("swipe", swipeHandler); - let buttonHandler = setWatch(()=>{load();}, BTN, {edge:'falling'}); }; // Get back to the main layout diff --git a/apps/spotrem/metadata.json b/apps/spotrem/metadata.json index f25b0e42b..8ecc0d867 100644 --- a/apps/spotrem/metadata.json +++ b/apps/spotrem/metadata.json @@ -1,7 +1,7 @@ { "id": "spotrem", "name": "Remote for Spotify", - "version": "0.12", + "version": "0.13", "description": "Control spotify on your android device.", "readme": "README.md", "type": "app", From 9ab4ed8a129686becbef21ba4bf4e9ffefeb196f Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 18:21:45 +1100 Subject: [PATCH 02/96] Add Dense Clock app --- apps/denseclock/app-icon.js | 1 + apps/denseclock/app.js | 157 ++++++++++++++++++++++++++++++++++ apps/denseclock/app.png | Bin 0 -> 1569 bytes apps/denseclock/metadata.json | 14 +++ 4 files changed, 172 insertions(+) create mode 100644 apps/denseclock/app-icon.js create mode 100644 apps/denseclock/app.js create mode 100644 apps/denseclock/app.png create mode 100644 apps/denseclock/metadata.json diff --git a/apps/denseclock/app-icon.js b/apps/denseclock/app-icon.js new file mode 100644 index 000000000..380a7b4ff --- /dev/null +++ b/apps/denseclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mElwMBwf/AAeAAomYAomcAov4/E/w/jzngnEPg+AzninGOn+IznnnPOn+cCIIFBh4RBAoPPC4Xn/PP8efAo3jAoWPwAdCC4OB+AjC4BGEAEnH/ADBx/BGoN//0PwPx8E/AoOP/HnAoPPAoPmn0/ApHkn//5+DDoQFBEYPhAoX48YFE4/jAogvBAoWP8QFBFAKDBn0+geBwHwvwFBwYA=")) diff --git a/apps/denseclock/app.js b/apps/denseclock/app.js new file mode 100644 index 000000000..62a40154e --- /dev/null +++ b/apps/denseclock/app.js @@ -0,0 +1,157 @@ +// FONTS + +/* + Share Tech Mono: https://fonts.google.com/specimen/Share+Tech+Mono + Converted with: https://www.espruino.com/Font+Converter +*/ + +Graphics.prototype.setFontShareTechMonoBig = function(scale) { + // Actual height 56 (55 - 0) + this.setFontCustom( + atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAHwAAAAAAAA/wAAAAAAAD/wAAAAAAAf/wAAAAAAB//gAAAAAAP/8AAAAAAA//wAAAAAAH/+AAAAAAA//4AAAAAAD//AAAAAAAf/8AAAAAAB//gAAAAAAP/8AAAAAAB//wAAAAAAH/+AAAAAAA//4AAAAAAD//AAAAAAAf/4AAAAAAB//gAAAAAAP/8AAAAAAA//wAAAAAAA/+AAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf///4AAAAD/////AAAAP/////wAAAf/////4AAA//////8AAA//////8AAB/AAB/j+AAB+AAH/B+AAB8AAP8A+AAB8AA/4A+AAB8AB/gA+AAB8AH/AA+AAB8AP8AA+AAB8A/4AA+AAB8B/gAA+AAB+D/AAB+AAA//+AAP8AAA//////8AAAf/////4AAAP/////wAAAH/////gAAAB////+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAAAeAAAfgAAAA+AAAfAAAAA+AAA/AAAAA+AAA+AAAAA+AAA+AAAAA+AAB+AAAAA+AAB8AAAAA+AAB//////+AAB//////+AAB//////+AAB//////+AAB//////+AAB//////+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAB8AAAAD+AAB8AAAAP+AAB8AAAAf+AAB8AAAB/+AAB8AAAD/+AAB8AAAH/+AAB8AAAf8+AAB8AAA/4+AAB8AAD/w+AAB8AAH/A+AAB+AAf+A+AAB+AA/4A+AAA////wA+AAA////gA+AAAf//+AA+AAAP//8AA+AAAH//wAA+AAAB/+AAA+AAAAAAAAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAAAA+AAB8AAAAA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AD8AA+AAB+AH+AB+AAA////gD+AAA//////8AAAf/////8AAAP//P//4AAAH/+H//wAAAA/4D//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAP/wAAAAAAD//wAAAAAB///wAAAAAf///wAAAAH////wAAAB///+HwAAAB///gHwAAAB//wAHwAAAB/4AAHwAAAB+AAAHwAAABAAAAHwAAAAAAP///+AAAAAf///+AAAAAf///+AAAAAf///+AAAAAf///+AAAAAf///+AAAAAAAHwAAAAAAAAHwAAAAAAAAHwAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB///wAA+AAB///wAA+AAB///wAA+AAB///wAA+AAB///wAA+AAB///wAA+AAB8AHwAA+AAB8AHwAA+AAB8AHwAA+AAB8AD4AA+AAB8AD4AA+AAB8AD4AB+AAB8AD+AD+AAB8AD///8AAB8AB///8AAB8AA///4AAB8AAf//wAAB4AAP//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////AAAAP/////gAAAf/////4AAAf/////4AAA//////8AAA/APgAD+AAB+APgAB+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8AHwAA+AAB8AHwAB+AAB8AH+AP8AAB8AH///8AAB8AD///4AAAAAB///wAAAAAA///gAAAAAAP/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAAAAAAAB8AAAAAAAAB8AAAAAAAAB8AAAAAAAAB8AAAAAOAAB8AAAAD+AAB8AAAAf+AAB8AAAD/+AAB8AAA//+AAB8AAH//+AAB8AB///gAAB8AP//8AAAB8D///AAAAB8f//4AAAAB////AAAAAB///wAAAAAB//+AAAAAAB//gAAAAAAB/8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//AAAAD/8H//wAAAP//P//4AAAf/////8AAA//////8AAA//////+AAB/AP+AB+AAB8AD8AA+AAB8AD8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AD8AA+AAB+AH+AA+AAA////AD+AAA//////8AAAf/////8AAAP//P//4AAAH/+H//wAAAA/4D//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AAAAAAP//+AAAAAAf///AAAAAAf///AA+AAA////gA+AAB/AAfgA+AAB+AAPgA+AAB8AAPwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwB+AAB+AAHwB+AAA//////8AAA//////8AAAf/////4AAAP/////wAAAH/////gAAAB////+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'), + 46, + 32, + 60+(scale<<8)+(1<<16) + ); + return this; +}; + +Graphics.prototype.setFontShareTechMono = function(scale) { + // Actual height 38 (37 - 0) + this.setFontCustom( + atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAAAeAAAAAB4AAAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAfAAAAAP8AAAAD/gAAAB/4AAAAf+AAAAP/AAAAH/gAAAB/4AAAA/8AAAAP/AAAAH/gAAAD/wAAAA/8AAAAP+AAAAA/gAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//4AAA///8AAP///8AA////wAHwAfvgAeAH4eABwA/A4AHAHwDgAcB+AOAB4PgB4AHj8AHgAf///+AA////wAB///+AAD///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAOAA8AAA4ADwAADgAeAAAOAB4AAA4AH////gAf///+AB////4AH////gAAAAAOAAAAAA4AAAAADgAAAAAOAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AHAAAfgAcAAD+ABwAA/4AHAAH/gAcAA/OABwAP44AHgB+DgAfAfwOAA//8A4AD//gDgAH/4AOAAH+AA4AAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAOABwBwA4AHAHADgAcAcAOABwBwA4AHAHADgAeA+AOAB8H4B4AD////gAP///8AAf+f/gAAPgf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAAAP+AAAAP/4AAAf//gAAf//OAAB//A4AAH+ADgAAcAAOAAAAH//4AAA///gAAD//+AAAP//4AAAAHgAAAAAOAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/+ADgAf/4AOAB//gA4AH/+ADgAcA4AOABwDgA4AHAPADgAcA8AeABwD//4AHAH//AAcAP/4AAAAf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///8AAH///4AA////wAH////gAeB4AeABwHgA4AHAeADgAcB4AOABwHgA4AHAeAHgAcA//+ABwD//wAAAH/+AAAAP/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAABwAAAAAHAAAAgAcAAAeABwAAf4AHAAP/gAcAH/+ABwH/+AAHD//AAAf//AAAB//gAAAH/gAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/gAAP+f/gAD////AAP///+AB//8B4AHgPgDgAcAcAOABwBwA4AHAHADgAcAcAOAB4D4B4AH////gAP///8AAf/f/wAAfw/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAH/+AAAA//8A4AH4HwDgAeAHgOABwAeA4AHAB4DgAcAHgOABwAeB4AHgB4HgAf///+AA////wAB///+AAB///gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AHgAAHgAeAAAeAB4AAB4AHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='), + 46, + 22, + 40+(scale<<8)+(1<<16) + ); + return this; +}; + +Graphics.prototype.setFontShareTechMonoSmall = function(scale) { + // Actual height 23 (22 - 0) + this.setFontCustom( + atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zgP/zgP/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAPwAAPwAAAAAAPwAAPwAAPAAAAAAAAAAAAAAAAAAAAAAAAwYAP//gP//gP//gAwYAP//gP//gP//gAwYAAAAAAAAAAAAAAAAAB4AAD+BgH/Bg+HB8+DB8+DB8GD/gGB/AAAcAAAAAAAAAABAAH7AAP7AAMLAAMbAAP7AAHzfAAG/gAGxgAGxgAG/gAGfAAGAAAAAAAAAADz/AH//gP+DgMOBgMMBgMMBgMP/gAP/gAMAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAPwAAPwAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wP//8/AA+4AAGgAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAC4AAG/AB+P//8D//wAAAAAAAAAAAAAAAAAAAAAAAADAAADuAAB+AAP4AAfwAAP8AAB+AADsAADAAAAAAAAAAAAAAAAAAAADgAADgAADgAAf8AAf8AAf8AADgAADgAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAD+AAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAADgAADgAADgAADgAADgAADgAADgAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAADgAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAeAAD8AAfwAB+AAP4AA/AAH8AAfgAA8AAAwAAAAAAAAAAAAAAAD/+AH//APB/gMDxgMHBgMeBgP//gH//AD/+AAAAAAAAAAAAAAAAAGAAgGABgOABgOABgP//gP//gAABgAABgAABgAAAAAAAAAAAAAAAAAABgMAHgMAPgMA9gMB5gOHxgH/BgD+BgAABgAAAAAAAAAAAAAAAAAAAAMCBgMGBgMGBgMHBgP/DgH//gD5/AAAAAAAAAAAAAAAAAAAAAAD4AA/4AP/4APwYAMAYAAP/gAP/gAAcAAAYAAAAAAAAAAAAAAAAAAAAAP+BgP+BgMGBgMGBgMHDgMH/gMD/AAAAAAAAAAAAAAAAAAAAAD/+AH//AP//gMMBgMMBgMOBgMP/gMH/AAD+AAAAAAAAAAAAAAAAAMAAAMAAAMADgMAfgMH/AM/4AP/AAPwAAGAAAAAAAAAAAAAAAAAAAD5/AH//gP/DgMHBgMGBgMHBgP/jgH//gD5/AAAAAAAAAAAAAAAAAD+AAH/AgP/hgMBhgMBhgMBhgP//gH//AD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcDgAcDgAcDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAcD+AcD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAHgAAPwAAMwAAc4AAY4AA4cAA4cABwMAAAAAAAAAAAAAAAAAAMYAAMYAAMYAAMYAAMYAAMYAAMYAAMYAAMYAAAAAAAAAAAAAAAAABwMAA4cAA4cAAY4AAc4AAMwAAPwAAHgAAHgAAAAAAAAAAAAAAAAAAAAAMAAAMABgMDzgMHzgOeAAH8AAD4AAAAAAAAAAAAAAB/8AH//AP//gMHhgMf5gM/9gMwNgM/5gM/8gMAMAP/8AH/8AA/wAAAAAAADgAA/gAP/gD/4AP8YAPAYAP8YAD/4AAP/gAA/gAADgAAAAAAAAAAAAP//gP//gMGBgMGBgMGBgMGBgP/DgH//gD5/AAAAAAAAAAAAAAAAAB/8AH//AP//gOABgMABgMABgMABgMABgMABgAAAAAAAAAAAAAAAAP//gP//gMABgMABgMABgMABgOADgH//gH//AAAAAAAAAAAAAAAAAP//gP//gP//gMGBgMGBgMGBgMGBgMGBgMABgAAAAAAAAAAAAAAAAP//gP//gP//gMHAAMHAAMHAAMHAAMHAAMAAAAAAAAAAAAAAAAAAAD/+AH//AP//gMABgMDBgMDBgMD/gMD/gAD/gAAAAAAAAAAAAAAAAP//gP//gAHAAAHAAAHAAAHAAAHAAP//gP//gAAAAAAAAAAAAAAAAAAAAMABgMABgP//gP//gP//gMABgMABgAAAAAAAAAAAAAAAAAAAAAAAAAABgMABgMABgMABgMAHgP//AP/+AAAAAAAAAAAAAAAAAAAAAP//gP//gAPAAAfgAB/4ADw+APAfgOAHgIABgAAAAAAAAAAAAAAAAAAAAP//gP//gAABgAABgAABgAABgAABgAAAAAAAAAAAAAAAAP//gP//gPgAAP+AAB/gAAHwAB/gAP8AAPgAAP//gP//gAAAAAAAAAAAAP//gP//gPwAAP/AAA/8AAD/gAAPgP//gP//gAAAAAAAAAAAAA/8AH//AH//gOADgMABgMABgMABgOADgH//gH//AA/4AAAAAAAAAAAAAP//gP//gMDgAMDgAMDgAMDgAP/AAH/AAD+AAAAAAAAAAAAAAA/8AH//AH//gOADgMABgMABgMABgOADgH//gH//wA/4wAAAAAAAAH//gP//gP//gMDAAMDAAMDgAOD8AP//AH+PgB4DgAAAgAAAAAAAAAAAAD4AAH+BgP+BgOGBgMHBgMHBgMH/gMD/AAA+AAAAAAAAAAAAAMAAAMAAAMAAAMAAAP//gP//gP//gMAAAMAAAMAAAMAAAAAAAAAAAAAAAP//AP//gAADgAABgAABgAABgAADgP//gP//AAAAAAAAAAAAAMAAAP4AAP/wAA//AAB/gAAHgAD/gB/+AP/AAPwAAIAAAAAAAAAAAP/gAP//gAP/gAAfgAH+AAHwAAD/gAAfgAf/gP//gP8AAAAAAAAAAAAAgOADgPgPgH4+AB/4AAfwAB/4AH4/APgPgOADgAAAgAAAAAAAAMAAAPAAAPwAAD8AAA//gAP/gAf/gD8AAPwAAPAAAIAAAAAAAAAAAAAAAMADgMAPgMA/gMD5gMPhgM+BgP4BgPgBgOABgAAAAAAAAAAAAAAAAAAAAAAAA///+///+wAAGwAAGwAAGAAAAAAAAAAAAAAAAAAAAwAAA+AAAfgAAH8AAA/AAAP4AAB+AAAPwAAD8AAAeAAAGAAAAAAAAAAAAAAAAAAAAwAAGwAAGwAAG///+///+AAAAAAAAAAAAAAAAAAAAAAAAA4AAD4AAPwAAeAAAYAAAeAAAPwAAD4AAAYAAAAAAAAAAAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAAAAAAAAAAAAAAIAAAMAAAOAAAGAAACAAAAAAAAAAAAAAAAAAAAAAAAAOAAY/gAY/gAZxgAZxgAZxgAZxgAf/gAP/gAABgAAAgAAAAAAAAAAAAP//gP//gAcBgAYBgAYBgAYBgAcDgAf/gAP/AAAAAAAAAAAAAAAAAAAAAAP/AAf/gAYBgAYBgAYBgAYBgAYBgAAAAAAAAAAAAAAAAAAAAAP/AAf/gAcDgAYBgAYBgAYBgAYDgP//gP//gAAAAAAAAAAAAAAAAAP+AAf/gAf/gAYxgAYxgAYxgAfxgAPxgAHwAAAAAAAAAAAAAAAAAAYBgAYBgD//gP//gP//gMYBgMYBgMYBgMQAAAAAAAAAAAAAAAAAAAPwGAf/GAYfGAYfGAYfGAYfGAY7mAf7+Afx8AAAAAAAAAAAAAAAAP//gP//gAcAAAYAAAYAAAYAAAcAAAf/gAP/gAAAAAAAAAAAAAAAAAYAAAYAAAYAAMf/gOf/gMf/gAABgAABgAABgAAAAAAAAAAAAAAAAAAAAAAAGAYAGAYAGAYAGMf/+Of/+Mf/8AAAAAAAAAAAAAAAAAAAAP//gP//gP//gADwAAH8AAefAAcHgAYDgAQAgAAAAAAAAAAAAEAAAMAAAMAAAMAAAP//AP//gAADgAABgAABgAABgAAAgAAAAAAAAAf/gAf/gAYAAAYAAAf/gAf/gAf/gAYAAAYAAAf/gAP/gAAAAAAAAAAAAAf/gAf/gAcAAAYAAAYAAAYAAAcAAAf/gAP/gAAAAAAAAAAAAAAAAAP/AAf/gAcDgAYBgAYBgAYBgAcDgAf/gAP/AAAAAAAAAAAAAAAAAAf/+Af/+AcBgAYBgAYBgAYBgAcDgAf/gAP/AAAAAAAAAAAAAAAAAAP/AAf/gAcDgAYBgAYBgAYBgAYDgAf/+Af/+AAAAAAAAAAAAAAAAAYBgAYBgAf/gAf/gAcBgAYBgAYBgAYAAAYAAAAAAAAAAAAAAAAAAAAAAAPhgAfxgAZxgAYxgAYxgAY/gAYfAAAAAAAAAAAAAAAAAAAAAAYAAAYAAAYAAD//AD//gAYBgAYBgAYBgAYBgAAAAAAAAAAAAAAAAAf+AAf/gAf/gAABgAABgAABgAf/gAf/gAf/gAAAAAAAAAAAAAQAAAeAAAf4AAH/AAAfgAADgAAfgAH/AAf4AAeAAAQAAAAAAAAAAAfAAAf/AAD/gAAPgAD/gAH4AAH/gAAPgAD/gAf+AAfAAAAAAAAAAAAAAAYBgAcHgAfPAAH+AAD4AAH+AAfPgAcDgAQBgAAAAAAAAAAAAAQAAAeAAAfwGAH+GAA/uAAD+AAf8AH/AAf4AAeAAAQAAAAAAAAAAAAAAAABgAYHgAYPgAY/gAZ5gAfxgAfBgAeBgAYAAAAAAAAAAAAAAAAAAAAAAADgAADgAf//8/+/+4AAGwAAGwAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//+///+f//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAGwAAG4AAG/+/+f//8ADgAADgAAAAAAAAAAAAAAAAAAAAAADgAADAAADAAADAAADAAADgAABgAADgAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'), + 32, + atob("DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0H"), + 24+(scale<<8)+(1<<16) + ); + return this; +}; + +{ + + // VARS + + let FONT_NAME = "ShareTechMono"; + let BIG_FONT_HEIGHT = 60; + //let NORMAL_FONT_HEIGHT = 40; + let SMALL_FONT_HEIGHT = 24; + + let timeDrawTimeout; + let infoDrawTimeout; + let lockState = Bangle.isLocked(); + let pressure; + + + + // LISTENERS + + Bangle.on('lock', function(isLocked) { + lockState = isLocked; + timeDraw(); + infoDraw(); + }); + + + + // DRAW FUNCTIONS + + let timeDraw = function() { + g.reset(); + g.clearRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y + BIG_FONT_HEIGHT); + + var date = new Date(); + var timeArray = [date.getHours().toString().padStart(2, "0"), + date.getMinutes().toString().padStart(2, "0")]; + if (!lockState) timeArray.push(date.getSeconds().toString().padStart(2, "0")); + var timeString = timeArray.join(":"); + g.setFontAlign(0, 0).setColor(g.theme.fg).setFont(FONT_NAME + (lockState ? "Big" : "")); + g.drawString(timeString, Bangle.appRect.x2/2, Bangle.appRect.y + BIG_FONT_HEIGHT/2); + + if (timeDrawTimeout) clearTimeout(timeDrawTimeout); + timeDrawTimeout = setTimeout(function() { + timeDrawTimeout = undefined; + timeDraw(); + }, (lockState ? 10000 - (Date.now() % 10000) : 1000 - (Date.now() % 1000))); // if locked, every clock's 10s, otherwise every 1s + }; + + let infoDraw = function() { + g.reset(); + + var date = new Date(); + var dateString = [date.getFullYear().toString().padStart(4,"0"), + (date.getMonth()+1).toString().padStart(2,"0"), + date.getDate().toString().padStart(2,"0")].join("-"); + + var tzOffset = -(date.getTimezoneOffset())/60; + var tzOffsetString = (tzOffset >= 0 ? "+" + tzOffset : tzOffset); + + var batteryString = (Bangle.isCharging() ? "+" : "") + E.getBattery() + "%"; + + var pressureString = (pressure ? pressure + "hPa" : "(hPa)"); + + var powerString = (E.getPowerUsage().total / 1000) + "mA"; + + var stepsString = Bangle.getHealthStatus("day").steps + "ST"; + + var bluetoothStatus = NRF.getSecurityStatus(); + var bluetoothString = (bluetoothStatus.connected ? bluetoothStatus.connected_addr.split(" ")[0].substr(-5) : "N/C"); + + var infoMatrix = [ + [dateString + tzOffsetString ], + [batteryString, pressureString], + [powerString ], + [stepsString, bluetoothString ] + ]; + + g.clearRect(Bangle.appRect.x, Bangle.appRect.y + BIG_FONT_HEIGHT, Bangle.appRect.x2, Bangle.appRect.y2); + g.setFontAlign(0, -1).setColor(g.theme.fg2).setFont(FONT_NAME+"Small"); + + infoMatrix.forEach((lineArray, lineNumber) => { + g.drawString(lineArray.join(" "), Bangle.appRect.x2/2, Bangle.appRect.y + BIG_FONT_HEIGHT + SMALL_FONT_HEIGHT*lineNumber); + }); + + Bangle.getPressure().then(baroValue => { pressure=Math.round(baroValue.pressure); }); + + if (infoDrawTimeout) clearTimeout(infoDrawTimeout); + infoDrawTimeout = setTimeout(function() { + infoDrawTimeout = undefined; + infoDraw(); + }, (lockState ? 60000 : 10000)); // if locked, a minute from now, otherwise in 10s + }; + + + + // DRAW CALLS + + g.clear(); + + Bangle.setUI({ + mode: "clock", + remove: function() { + if (timeDrawTimeout) clearTimeout(timeDrawTimeout); + timeDrawTimeout = undefined; + if (infoDrawTimeout) clearTimeout(infoDrawTimeout); + infoDrawTimeout = undefined; + + delete Graphics.prototype.setFontShareTechMono; + delete Graphics.prototype.setFontShareTechMonoBig; + delete Graphics.prototype.setFontShareTechMonoSmall; + }}); + + Bangle.loadWidgets(); + Bangle.drawWidgets(); + + timeDraw(); + infoDraw(); +} diff --git a/apps/denseclock/app.png b/apps/denseclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..e395fcf8dab8c375e49b2d5a3ee61ab18999aa49 GIT binary patch literal 1569 zcmV++2HyFJP)EX>4Tx04R}tkv&MmP!xqv8>J!@K|828WT;MdQ4z;lg(6f4wL+^7CNKSiCJjl7 zi=*ILaPVib>fqw6tAnc`2>yV$3r>nIQsR9{p+$@r9`ED4dk*j22Lu}xrdeHaK+|nA zolJli&xt2Yx*+i**A;ArbawX991=)@`G8A zRnA+SwMvb(?#W*m&g(17T&FdPBo?s*2_h8KP(}qdVzld|SV+@(!pA@2`XzEHZ+(5ySo_p#$NPXOT=xYFDHY6F=4B)#6& zqDMggHgIv>)|5Tqat9cCGGtSBC4pA3PypV~=$mrD;4RR*=FP2jj?)JqL$gZV00)P_ zc#*Q#ecs*EIk$g%TJ!q>9cprf@^f1Q00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>Zu7DgtiJ!V&-g02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00a3+L_t(&-tC!hXx3E}$3H!7uG!L26BCU{39&Xqos1B{ z#_UD2@GlPbLIOpiB1QZM>I*57FvQ3|IHTn&YnAq*cj_of){Ew!LM6n;h*h*~vN`{4 z&wSzc%JK5Mzdg^hIVb+U@bJ68bI6j*I&y+9jq0@w>& z9qvl30{Q~KUx5+BdGaameY1XF>b(@0_aIroZmnygtsBmh&kNA|fF7X0+d?CNw}IKf zIG_VK4txw;7f%)NzRpf3Fa~G`nt&ZZw3_X%8h|svRPoFKW&ppaf03T8 zz-K^O?@d|A&Da7n4Bs@-o-?$H2n&o7ZKR>q7#WSCHN-4jtlU%<7RWd4AGHrp2l^e{ zirz4^BGdj|&&9z1a@*@Y?-(mLmE++r0!9N*4A6;e16tHBmfPM2EYDPKUXFs-8o>_d zav0|iU@}k+JPm9BW&&>j`!bQ6*H4(?LJRu@I0~E`Bv*bzVGF>kQednX+63kL3RLMi zNe2($A3fU)-%8IL-fd@hNZY-!qHRl?=M)w&%1 z27U&11}YNsbXh$szuW*E9)SG0zzX0Q(Pnw!1G?C1Bfh_LU(`q3a%Unc5~~9@;>H{% zKN7eQF;-N3wml$sgR{Wvz)NaR1m0BpE!Bnq9#f3+IB*L1PF5>dK0Fq{#5SqAapwA5rb~1Czkw>R{MV~0 zT3QEb5x2|lOAX)o2tgGpLUo(ciN!3S5SU_Um6G!VaMLWXa~6d; zd=XfwQ|iAE=x>RUYwwOD0iM^gRiFUastMf$E~*q*ID`sxYTRW>GLaxbg8PqKe2H?b Tdy8}$00000NkvXXu0mjfaLv*} literal 0 HcmV?d00001 diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json new file mode 100644 index 000000000..fa8c620a2 --- /dev/null +++ b/apps/denseclock/metadata.json @@ -0,0 +1,14 @@ +{ "id": "denseclock", + "name": "Dense Clock", + "shortName":"Dense Clock", + "version":"0.01", + "description": "A clockface dense with text-only information. Switches between showing seconds and minutes when unlocked/locked, in the interest of saving power.", + "icon": "app.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "storage": [ + {"name":"denseclock.app.js","url":"app.js"}, + {"name":"denseclock.img","url":"app-icon.js","evaluate":true} + ] +} From d6c08245ee7256f0caee2c2991ca8d1f0249e596 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 18:32:11 +1100 Subject: [PATCH 03/96] denseclock: add screenshots --- apps/denseclock/metadata.json | 4 ++++ apps/denseclock/screenshot_locked.png | Bin 0 -> 3535 bytes apps/denseclock/screenshot_unlocked.png | Bin 0 -> 3590 bytes 3 files changed, 4 insertions(+) create mode 100644 apps/denseclock/screenshot_locked.png create mode 100644 apps/denseclock/screenshot_unlocked.png diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json index fa8c620a2..d5bcd3cd5 100644 --- a/apps/denseclock/metadata.json +++ b/apps/denseclock/metadata.json @@ -10,5 +10,9 @@ "storage": [ {"name":"denseclock.app.js","url":"app.js"}, {"name":"denseclock.img","url":"app-icon.js","evaluate":true} + ], + "screenshots": [ + {"url":"screenshot_locked.png"}, + {"url":"screenshot_unlocked.png"} ] } diff --git a/apps/denseclock/screenshot_locked.png b/apps/denseclock/screenshot_locked.png new file mode 100644 index 0000000000000000000000000000000000000000..61a05ca446c9a44b1d72c6c66739fa70e1149029 GIT binary patch literal 3535 zcmaKvc{G%d_s5^-VJw3PBeJHVnq&>dM2zh#MAj%{Nn$LOWf+t3AzQYoM3QWkJxm#U z4^0SJD*MtD;ge;?zVr3{`*+Uoo^$U#??3K6_m9`T=iIof=0<$TqeuV%_)LtkRtLHK zf6m2m5Z}=zZyqG}`+6qUTn84$kcAtu<%)`Xk$FGv2FJaq_L zx4)m~trgty!5n!t>Rd{d+qg%9E>e>IxhvzNb9iIp-i-8Ve@nz3lJUr6Vaj)ZcX{0| zYTtf$^(Q;)>*Z=I0>;y5Pg;qGfxfjd)%XU$2Yy3OXbjl=Qm|s+{95csrb;14megIY z-v(l&L8UuDGGM?#NS{J#Sb|ZC1rQH|UQ&Rz2SHxb*U_&E$iN=Gq)pyFLI9ot%{eb< zN_!cfVSQrEjj`6Z6KO=8$j!@FJPf}cLs)^n{P$*xF>Tk*KZYa`?B(Uv?;&X8+rLki z3xSW5J42^}8+kA4q^(%V=!0NpPVUy=8!|91*TB(rRYnrmahmkQ?R5Th0_00}jw}yu z`X|jKaaa}^1sHN%6+eBokPMVr+mX`H@Eo-ABzGym6R-ur&NFY;((H6~{?>;fUrCaI z2SIy^(hWf4|5dtY;QsT*e@3*t=Z=3(y;OqbPNd2D2H{Q9jLn+?)h4WjWE`9jzL3{^ z1a0}eJGfp}y2)+g!7YOhXqStyqNO1iiqJ29*BAc5*{0lZ z>t&P2zbLV^p(TSIV^DOH`+>*nN8~|jB3Js$$)Y{kj9Z)5zx26qv&n$RLSPrkK&C`M z8Qqk+8>Tl(sps>{*}I&+rxQ{rf|kX8@Jkgi+!~h*?%OCs;<+9E%qf=vRVu9QkU;aZ z$we(k;GgY3NzzV;6vRTwjC(y=lX2LXjhL#^HT$&UC4ifkY<6+S9OMi>UN5x)}H~YCXL&>%sHv5i)&tleaE)4jWa{F z5=LN|xy)aqz&e!7s;m9M++}ZW-`_8;GKbQytejQ8Vi)|b8C@iEf0!bL%WkkW?B`$`LLU180CRFbwXyaL;Ko71uLr?q% z9u9}qVnt(-F zqcOzaAMuVV?~j`-uixD?9L}S zwG1VnW8>Goi5;K z5g`$KN``#=@0XxD2qF-Xle$~4q0J4m z%g!gO!@R3Yi?)BdCpvd{PBhQo_Nz<`a3~$QaH^XQEj?lj%UVqZ94BPDKdGsW2n#cM z-Pr{xzm~f5N4Wi?Iq299&T15YVFA7eOZHVVbW>U^VJ%B!pU+wyRp_VpsLHuq{V!uY=97ad=SB^Q%U0-L}r^2n7WbHIBy9icV=n3 z*rGscR3OuC+iNUkFS2i?HM58B9c&9sUna5|>x(%E>Md<=DQ1S+p0f5oJ+iGmm0sMi zHMiu;967{`;~BTK2}8sTN_DCF5J5*Jl{nE-nS^BHB@dR=UT#XZ0o14UT>~AhLhg-9 zJftZ_lp9nR>qlAfyUt!`@p2sP4zY4v#GX-_;IE_e;Bp~5xn^opg1IpVE;-y2^*_I{L&?PjVL!JwCIvnk{+%xqolS)pyzjQ zk{g;69>;CO0~3j@&$;NYY3jv+%SkjzoG_PPGX}J^mVIv_M-i(qKu_a6lqz~u=SJW> z(B=C(c>JptQPknQxpmkIV_*R#rq$Alo?VLA2oLS)^%@ zc7jgZ372DEetcD}(N_PN;j#{wz+Q?7k<&8dBiyAfUcv(K`P!lZg98E$^t{uL9&npj z_BW7n04k;D=o>>2bjm9Zy^*hb3C`2POxYDW_^4tfNIz6(>)u8L4rI7Q&UkFzO?pI9 zPR-F6GCBw2;j?piqE!NIYP`apujGi3gW|o|0jkbLdqvUoF9Kga)7ANL-NZnV$Lic! z`Pq7vjUQyPo@jk`jLYjD(38nc}8YM;!nL8BMF!5TqaKP?q73KN1OPd`>hGa-K- zZmS3}ad0OO4n+I6M7caed*6GBW_fP2yi}poia0RwU2{7+(oOMmre^iNKEwn3S%KXz{E$(I~$B5Eh zK{nP|nW}G*zpK~bm|qke2aev7H^RHrs~Uj1u8L`bF>Jenfg^;opRQBRjO|6icpH3BT{FX z5jGL~`<%iQ{nTlJ7!fx2++0$G<}^5JE3>j9Hl}K`5P@k7@indV8TNY6Wp)x4VVnOY z5*5&Y_6Wlg$aA<2elx`?X2d(j#`@*WzITul6;Jk~IC8!5l5NZhK>*#HqN3Jj`MS>z zE|#guD%Ai4>kWeVGG3E`E-R~D{J~-Kquhw}IG~UE)LO^!fIdg}foun)(-GX%xLWSB zX#7?J;FVUhG9IPnYktXCDN&4iT@}CLuB{Czc`y4b z1}NK0=fqf-0-9SDonqHPUh^lN9+=)@(06w|>_%%?@uRQ{(VkwVR^!|;2@M5bSJD1` zIrO3cD$~p83l%ncVDqhcEYe>M9Ik>0y=q$g-yNY|tDXwWMcZE54s6eUI#4e|-67X7LD?FMLD#13^cOOa>E80?9mgtfY%4i}Mx zeuYnG$e6_wuS+Ul%-S&=PR5^_HX;1r7}6rH!~I#8y#K^|E|fQ@!ws*M(1$HWEq~gV zv$MpfAcESg9XKj3J#?E%k~YG4Lgx1V`34JIt4>VS+AM=rF-YzT_Py?c|NG2UlQ zJgzJhZPJeqp)CXuFJ+^W3ZJzd>xmx<%>u6592sCIuq#7cFG{57{hCrQ?nfh(I=2JC zXnpHXT4)(EGjoiSE=QJ5nbe9o_5Y~qLyTTK_ZiceyqD95)^2HS9~x*cKmXlW(@qEmF4d(Dl*aFn}T`xs46RA|2 zOXxa^`P$_fVyi3P4%q|Uy@fmYAKddJPMcfHpEFx0^m9Ajyj8)P&wGB3N3%XkX-_Dt zUl|#C4nqW&5A!vf&r#K8{*M>phzt$}tlmc>9mTs4w5H1Hr-z4J$b3DD1GE z{Aae@*64_|8x1|FPZyhd*HqCgV+jjEOY!$F^(Qrix;3T5e^_|46(UDZ#dVH4h|~A9 zPh^C>mqfM{yu2-u%=h;#V3@k)8v_vR$QYSWe9zO)t*Rw=j1h^es;*z;cUZOldf_R+ zQ|lcgYY(HI5DukVc34I@%gs1f$DJE0#$A@rx?Nf6C=c>NoeR{GHHE?XK8tPzp3MIo zFh#)Ile?d|KWiV7wqNw*bB$Ch{;5Y0Ql?VPTYM%(>V0G>Yq7O$^ozrUM!T%dICJ9@ qI{2oxe!tv6416WG&lZ`2+~EvO7DT#hLKX)f8DL^yjxE!}{qtYb1(%Tk literal 0 HcmV?d00001 diff --git a/apps/denseclock/screenshot_unlocked.png b/apps/denseclock/screenshot_unlocked.png new file mode 100644 index 0000000000000000000000000000000000000000..f1af09cbacbe67306b90ec6c26ff191aa57ff786 GIT binary patch literal 3590 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 H{O$h(BRQD5 literal 0 HcmV?d00001 From f47af9fe0fb422ab432f3b914aadb0a01611f5aa Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 18:51:37 +1100 Subject: [PATCH 04/96] denseclock: bump version --- apps/denseclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json index d5bcd3cd5..515e4661c 100644 --- a/apps/denseclock/metadata.json +++ b/apps/denseclock/metadata.json @@ -1,7 +1,7 @@ { "id": "denseclock", "name": "Dense Clock", "shortName":"Dense Clock", - "version":"0.01", + "version":"0.02", "description": "A clockface dense with text-only information. Switches between showing seconds and minutes when unlocked/locked, in the interest of saving power.", "icon": "app.png", "type": "clock", From 5a8f9328d1e7b0936d0ef184a14d8b5dbef67845 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 19:22:29 +1100 Subject: [PATCH 05/96] denseclock: (retroactive) changelog --- apps/denseclock/ChangeLog | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 apps/denseclock/ChangeLog diff --git a/apps/denseclock/ChangeLog b/apps/denseclock/ChangeLog new file mode 100644 index 000000000..2e09e5bb2 --- /dev/null +++ b/apps/denseclock/ChangeLog @@ -0,0 +1,2 @@ +0.01: Begin rewrite from old code. +0.02: Changed visuals: uA > mA, info order, battery state indication From 9b473e185ee6fc5ed0bb4d62f757b4e46224a5a9 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 21:19:16 +1100 Subject: [PATCH 06/96] denseclock: app icon update blurred inverted background to improve readability note in changelog --- apps/denseclock/ChangeLog | 1 + apps/denseclock/app-icon.js | 2 +- apps/denseclock/app.png | Bin 1569 -> 4198 bytes apps/denseclock/metadata.json | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/denseclock/ChangeLog b/apps/denseclock/ChangeLog index 2e09e5bb2..7ae520fa5 100644 --- a/apps/denseclock/ChangeLog +++ b/apps/denseclock/ChangeLog @@ -1,2 +1,3 @@ 0.01: Begin rewrite from old code. 0.02: Changed visuals: uA > mA, info order, battery state indication +0.03: Update app icon diff --git a/apps/denseclock/app-icon.js b/apps/denseclock/app-icon.js index 380a7b4ff..b8a0761f8 100644 --- a/apps/denseclock/app-icon.js +++ b/apps/denseclock/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mElwMBwf/AAeAAomYAomcAov4/E/w/jzngnEPg+AzninGOn+IznnnPOn+cCIIFBh4RBAoPPC4Xn/PP8efAo3jAoWPwAdCC4OB+AjC4BGEAEnH/ADBx/BGoN//0PwPx8E/AoOP/HnAoPPAoPmn0/ApHkn//5+DDoQFBEYPhAoX48YFE4/jAogvBAoWP8QFBFAKDBn0+geBwHwvwFBwYA=")) +require("heatshrink").decompress(atob("mEwwcBkmSpIC/AS0nwEHCh5yBggROgP4jgROh1ICKWT4Hkz0AC4NPgFypPgAQIRDyBLBCIMAiVAgECpAGBCInwn4RBg4dBoH/yV4j+ACI0Dz05kARB8gRJgARFgYRBgEB5IRKBwICCI4/8CIdJ/kCGoP+CIMPUIIRBkgRIYop9DgJHCPowDBTwUAyAREiSkBCITCOAX4CuwE5kmT4D1BBYSMByShBhwRCgEkWYQRDUIIRCUIWfEALXBCIsDCIMf+QICvEECIILBBAV5CIUcBAYRFpEEBYIRKnARIgFyHwfk+PAGogREgQIBPQMk+EACI9J/hrCyUHCIMHCJEnwAIByEBCIJrFCI/wWYIROwP5CIShECI7FBgjFDPoTFBgTXGBYICCCI6PDAX4C/ARoA=")) diff --git a/apps/denseclock/app.png b/apps/denseclock/app.png index e395fcf8dab8c375e49b2d5a3ee61ab18999aa49..4f27b473ca189d0d1457b960d08599b436dfa66d 100644 GIT binary patch delta 4103 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 IM6N<$f^!zRApigX diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json index 515e4661c..c361313ff 100644 --- a/apps/denseclock/metadata.json +++ b/apps/denseclock/metadata.json @@ -1,7 +1,7 @@ { "id": "denseclock", "name": "Dense Clock", "shortName":"Dense Clock", - "version":"0.02", + "version":"0.03", "description": "A clockface dense with text-only information. Switches between showing seconds and minutes when unlocked/locked, in the interest of saving power.", "icon": "app.png", "type": "clock", From e007d05e978dc03d7ec72771894c80c7e4f04f65 Mon Sep 17 00:00:00 2001 From: Randy Heydon Date: Tue, 28 Jan 2025 20:37:58 -0500 Subject: [PATCH 07/96] calendar: read events synchronized from Gadgetbridge This is a partial fix for feature request #3707. This allows synchronized events (stored in android.calendar.json) to be shown in the app, alongside the manually entered events and alarm events that are already shown. Note only date/time and event title are currently used; other information available in the synchronized events (e.g. duration, description) are ignored. --- apps/calendar/ChangeLog | 1 + apps/calendar/calendar.js | 6 ++++++ apps/calendar/metadata.json | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/calendar/ChangeLog b/apps/calendar/ChangeLog index 9a4f81491..d737ec6d4 100644 --- a/apps/calendar/ChangeLog +++ b/apps/calendar/ChangeLog @@ -19,3 +19,4 @@ Display Widgets in menus 0.17: Load holidays before events so the latter is not overpainted 0.18: Minor code improvements +0.19: Read events synchronized from Gadgetbridge diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js index e140ff576..da5a00a6e 100644 --- a/apps/calendar/calendar.js +++ b/apps/calendar/calendar.js @@ -60,6 +60,12 @@ const loadEvents = () => { date.setSeconds(time.s); return {date: date, msg: a.msg, type: "e"}; })); + // all events synchronized from Gadgetbridge + events = events.concat((require("Storage").readJSON("android.calendar.json",1) || []).map(a => { + // timestamp is in seconds, Date requires milliseconds + const date = new Date(a.timestamp * 1000); + return {date: date, msg: a.title, type: "e"}; + })); }; const loadSettings = () => { diff --git a/apps/calendar/metadata.json b/apps/calendar/metadata.json index 468bceabb..5f5f21b27 100644 --- a/apps/calendar/metadata.json +++ b/apps/calendar/metadata.json @@ -1,7 +1,7 @@ { "id": "calendar", "name": "Calendar", - "version": "0.18", + "version": "0.19", "description": "Monthly calendar, displays holidays uploaded from the web interface and scheduled events.", "icon": "calendar.png", "screenshots": [{"url":"screenshot_calendar.png"}], From 00cd02bcb80a6e474bbe0927a08d67c5b766592b Mon Sep 17 00:00:00 2001 From: Randy Heydon Date: Wed, 29 Jan 2025 19:30:43 -0500 Subject: [PATCH 08/96] Fix lint warnings. Loop variables had warnings for being undefinied. Added the "let" keyword where they are initialized. --- apps/calendar/calendar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js index da5a00a6e..ea06b70e8 100644 --- a/apps/calendar/calendar.js +++ b/apps/calendar/calendar.js @@ -227,8 +227,8 @@ const drawCalendar = function(date) { }, []); let i = 0; g.setFont("8x12", fontSize); - for (y = 0; y < rowN - 1; y++) { - for (x = 0; x < colN; x++) { + for (let y = 0; y < rowN - 1; y++) { + for (let x = 0; x < colN; x++) { i++; const day = days[i]; const curMonth = day < 15 ? month+1 : day < 50 ? month-1 : month; From 195dd618f18a7e2c6294a28afc4687024673c847 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 14:43:18 +1100 Subject: [PATCH 09/96] grandfather-clock: add initial metadata --- apps/grandfather-clock/ChangeLog | 1 + apps/grandfather-clock/README.md | 15 +++++++++++++++ apps/grandfather-clock/icon.png | Bin 0 -> 1620 bytes apps/grandfather-clock/metadata.json | 14 ++++++++++++++ apps/grandfather-clock/widget.js | 5 +++++ 5 files changed, 35 insertions(+) create mode 100644 apps/grandfather-clock/ChangeLog create mode 100644 apps/grandfather-clock/README.md create mode 100644 apps/grandfather-clock/icon.png create mode 100644 apps/grandfather-clock/metadata.json create mode 100644 apps/grandfather-clock/widget.js diff --git a/apps/grandfather-clock/ChangeLog b/apps/grandfather-clock/ChangeLog new file mode 100644 index 000000000..4c21f3ace --- /dev/null +++ b/apps/grandfather-clock/ChangeLog @@ -0,0 +1 @@ +0.01: New Widget! diff --git a/apps/grandfather-clock/README.md b/apps/grandfather-clock/README.md new file mode 100644 index 000000000..12ce92f9e --- /dev/null +++ b/apps/grandfather-clock/README.md @@ -0,0 +1,15 @@ +# Grandfather Clock + +A widget that runs in the background and chimes every 15mins (similar to Chimer), and counts out the fractions of an hour and the o'clock hour. + +## Usage + +Once installed, see the App Settings page for options. + +## Requests + +Drop me a message at @yogsoy on Discord if you need help / discover a bug that I can squash for you. + +## Creator + +Written by June B (yogsoy), inspired by aaronrolls' Chimer. diff --git a/apps/grandfather-clock/icon.png b/apps/grandfather-clock/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0 GIT binary patch literal 1620 zcmV-a2CMmrP)1gXjloC|3_d8m;N2OpV(|i0q4YwBna<2! zK9thw%-*|urnNbV{Gax^?eD+#{x0kLJ~)lj_;W+1>qV*k8akT^^dvctZccUyj4}H~#M%Wwee_v` zHMv7o%BM8@dBrLshn{wGD9BDl?^eV5vSM3T96;NnHvtc6La=(qzq)xrX1d8bK-TN- zrd_f$_O`9nEmS+_S7HTXK<&u;LDIW|qlN&KJvM}tt6TVVqL-AvNv`B*{NzNpBfSQwQP5~Sf(Dp@Vq1+3Q`N9wBQN2`J_?M^u0FIMlt?p^8 z%U3%80kIwg!T{E9<8J18S&$k1`eO)@HP+=TZKo(z3_A3VFYJB=sn`2^Q$mRE>02(+W)np;)L1!GUvU2{O{<&F_nE6Qe#D~Xf|dD z+?d3-D1(IUiL`C2;PPv4CKw8H)v7h8^obJ&Z6D0CjVUe8Xq_NAymxUyPAMU^CCrIu z%1M71EC`5o2if_~7E&h??0jeQ1Y3N6p?}G72FmS*)xQD)%wBE=2tW6@(+MTi!fk9H1pWKew2(jTXVu4%vk26QvSQCbGmk`Z)Y! zBIhh)6vG2)h6mF8wC^|l$M(Eo9D?JiW}=_T2jUA>LC80foTera{^p)Wi`>}Gf;(|ZwEZQ zS^k|*9wyt=f4ZOo!xty7{%}HKD9tBZ50g$=%v&&vMa!#@Nsf>EkEEDA*ST6fiC+An zsNK1#>!x0obq@j$QqYU-ad3ZvbjqUU+%iw(0WahgmHV6yeLWqoYkSl4pzFQ(_Vp&I ztO{WI-48rGLwQb?#vgVvduyd9_6W)rFRoQJq3I(J?{Xmin45#=3l9BmL6Bp<*MZej zrsWN7oRPUr7IvrHoIHOjS=gPTCw>d)^LQK+B|=f2qbGjrWaOd5D<<9Dv>MTW0X3z> zyPy}9`<>1~?NCx@m8G$_@rRTy5zH12YM&P)=tU+L^fgY z^0Z&_6^qdVuwgN3wt_Ze(10?J@%{C2grBk42hsu74qEo^nd&v`X`IHN9lrxzS~GeF S(*#!l0000 { + + + +})() From 6bf6b2c14b8c9c5834b26ba1485c895239385fdf Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 16:30:54 +1100 Subject: [PATCH 10/96] grandfather-clock: initial code commit --- apps/grandfather-clock/widget.js | 62 ++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/apps/grandfather-clock/widget.js b/apps/grandfather-clock/widget.js index 4a3b50f45..33fb3059f 100644 --- a/apps/grandfather-clock/widget.js +++ b/apps/grandfather-clock/widget.js @@ -1,5 +1,67 @@ (() => { + // todo: all of these configurable through app settings menu. + const twelve_hour = true; + const swap_meridian = false; + const hour_attention_buzz_ms = 1000; + const hour_count_buzz_ms = 250; + const fraction_count_buzz_ms = 250; + const fractions_of_hour = 4; // 4 = 15min intervals + const wait_ms = 500; + const meridian_buzz_ms = 100; + const meridian_buzz_wait_ms = 50; + let date; + let fractionMs = 3600000 / fractions_of_hour + let chime = function () { + date = new Date(); + let hourFrac = Math.floor(date.getMinutes() / (60 / fractions_of_hour)); + + if (hourFrac == 0) { // if it's an o'clock hour + let chimeHour = (twelve_hour ? date.getHours() % 12 : date.getHours()); + if (chimeHour == 0) (twelve_hour ? chimeHour += 12 : chimeHour += 24); + + Bangle.buzz(hour_attention_buzz_ms).then(() => { // initial buzz + setTimeout(hourChime, wait_ms, chimeHour); // wait a period before doing the first chime + }); + } else { // if it's a fraction of an hour + fractionChime(hourFrac); + } + + queueNextChime(); + }; + + let hourChime = function (hoursLeftToChime) { + hoursLeftToChime--; + Bangle.buzz(hour_count_buzz_ms).then(() => { // recursive. buzz and wait to do the next buzz. + if (hoursLeftToChime > 0) { + setTimeout(hourChime, wait_ms, hoursLeftToChime); + } else if (twelve_hour) { // once finished with the hour count + setTimeout(meridianChime, wait_ms, (date.getHours() >= 12)); // if in twelve hour mode, queue up the meridian chime. + } + }); + }; + + let fractionChime = function (fractionsLeftToChime) { + fractionsLeftToChime--; + Bangle.buzz(fraction_count_buzz_ms).then(() => { // recursive. buzz and wait to do the next buzz. + if (fractionsLeftToChime > 0) setTimeout(fractionChime, wait_ms, fractionsLeftToChime); + }); + }; + + let meridianChime = function (meridian) { + if ((swap_meridian ? !meridian : meridian)) { // default: if PM + Bangle.buzz(meridian_buzz_ms).then(setTimeout(Bangle.buzz, meridian_buzz_wait_ms, meridian_buzz_ms)); // buzz once, wait, buzz again. + } else { // default: if AM + Bangle.buzz(meridian_buzz_ms); // buzz once. + } + }; + + let queueNextChime = function () { + let msUntilNextFraction = fractionMs - (Date.now() % fractionMs); + setTimeout(chime, msUntilNextFraction); + }; + + queueNextChime(); })() From 6fc0be482ca6f72a36c0f8760ff5b34b50c1406e Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 16:38:06 +1100 Subject: [PATCH 11/96] grandfather-clock: metadata & documentation updates --- apps/grandfather-clock/README.md | 15 +++++++++++++-- apps/grandfather-clock/metadata.json | 2 +- apps/grandfather-clock/widget.js | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/grandfather-clock/README.md b/apps/grandfather-clock/README.md index 12ce92f9e..34b0d2892 100644 --- a/apps/grandfather-clock/README.md +++ b/apps/grandfather-clock/README.md @@ -1,10 +1,21 @@ # Grandfather Clock -A widget that runs in the background and chimes every 15mins (similar to Chimer), and counts out the fractions of an hour and the o'clock hour. +A widget that runs in the background and chimes on every (configurable) fraction of an hour, similar to Chimer, and counts out the fractions and the o'clock hour. ## Usage -Once installed, see the App Settings page for options. +Once installed, see the App Settings page for options. ** This is not implemented yet. Await v0.02 + +Defaults: +- Twelve hour mode is ENABLED. +- Swap meridian is DISABLED. (in the AM, there will be a single buzz after counting the hours. in the PM, there will be two buzzes after counting the hours) +- The attention buzz for the hour chime is 1000ms long. +- The buzz for each hour count is 250ms long. +- The buzz for each fraction count is 250ms long. +- The widget will count out 4 fractions of an hour (15 min interval). +- The time between count buzzes is 500ms. +- The meridian buzzes are 100ms long. +- The time between meridian buzzes is 50ms long. ## Requests diff --git a/apps/grandfather-clock/metadata.json b/apps/grandfather-clock/metadata.json index f8fa52489..133ba3859 100644 --- a/apps/grandfather-clock/metadata.json +++ b/apps/grandfather-clock/metadata.json @@ -2,7 +2,7 @@ "name": "Grandfather Clock Bell Widget", "shortName":"Grandfather Clock", "version":"0.01", - "description": "A widget that chimes every 15mins (similar to Chimer), and counts out the fractions of an hour and the o'clock hour.", + "description": "A widget that chimes every fraction of an hour (similar to Chimer), and counts out the fractions and the o'clock hour.", "icon": "icon.png", "type": "widget", "tags": "widget", diff --git a/apps/grandfather-clock/widget.js b/apps/grandfather-clock/widget.js index 33fb3059f..3cdf66af3 100644 --- a/apps/grandfather-clock/widget.js +++ b/apps/grandfather-clock/widget.js @@ -6,7 +6,7 @@ const hour_attention_buzz_ms = 1000; const hour_count_buzz_ms = 250; const fraction_count_buzz_ms = 250; - const fractions_of_hour = 4; // 4 = 15min intervals + const fractions_of_hour = 4; // 4 = 15min intervals, 6 = 10min intervals const wait_ms = 500; const meridian_buzz_ms = 100; const meridian_buzz_wait_ms = 50; From 762219dca262da3c92a72b3981a5403498ccc87e Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 16:38:42 +1100 Subject: [PATCH 12/96] =?UTF-8?q?grandfather-clock:=20missing=20semi=20?= =?UTF-8?q?=F0=9F=98=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/grandfather-clock/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/grandfather-clock/widget.js b/apps/grandfather-clock/widget.js index 3cdf66af3..4b07104da 100644 --- a/apps/grandfather-clock/widget.js +++ b/apps/grandfather-clock/widget.js @@ -12,7 +12,7 @@ const meridian_buzz_wait_ms = 50; let date; - let fractionMs = 3600000 / fractions_of_hour + let fractionMs = 3600000 / fractions_of_hour; let chime = function () { date = new Date(); From 434b7848b2985d0b2c5cc65bb74482e66e646a4a Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 22:08:37 +1100 Subject: [PATCH 13/96] grandfather-clock: adjust default meridian timings --- apps/grandfather-clock/README.md | 6 +++--- apps/grandfather-clock/widget.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/grandfather-clock/README.md b/apps/grandfather-clock/README.md index 34b0d2892..f0e628cda 100644 --- a/apps/grandfather-clock/README.md +++ b/apps/grandfather-clock/README.md @@ -12,10 +12,10 @@ Defaults: - The attention buzz for the hour chime is 1000ms long. - The buzz for each hour count is 250ms long. - The buzz for each fraction count is 250ms long. -- The widget will count out 4 fractions of an hour (15 min interval). +- The widget will count out 4 fractions of an hour (a 15 min interval). - The time between count buzzes is 500ms. -- The meridian buzzes are 100ms long. -- The time between meridian buzzes is 50ms long. +- The meridian buzzes are 50ms long. +- The time between meridian buzzes is 300ms. ## Requests diff --git a/apps/grandfather-clock/widget.js b/apps/grandfather-clock/widget.js index 4b07104da..86b134c15 100644 --- a/apps/grandfather-clock/widget.js +++ b/apps/grandfather-clock/widget.js @@ -8,8 +8,8 @@ const fraction_count_buzz_ms = 250; const fractions_of_hour = 4; // 4 = 15min intervals, 6 = 10min intervals const wait_ms = 500; - const meridian_buzz_ms = 100; - const meridian_buzz_wait_ms = 50; + const meridian_buzz_ms = 50; + const meridian_buzz_wait_ms = 300; let date; let fractionMs = 3600000 / fractions_of_hour; From 7b0cc119ceb7dc5f006a57864b31701c6992c2db Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 22:08:55 +1100 Subject: [PATCH 14/96] grandfather-clock: remove "bell" from app name --- apps/grandfather-clock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/grandfather-clock/metadata.json b/apps/grandfather-clock/metadata.json index 133ba3859..2bd092e23 100644 --- a/apps/grandfather-clock/metadata.json +++ b/apps/grandfather-clock/metadata.json @@ -1,5 +1,5 @@ { "id": "grandfather-clock", - "name": "Grandfather Clock Bell Widget", + "name": "Grandfather Clock Widget", "shortName":"Grandfather Clock", "version":"0.01", "description": "A widget that chimes every fraction of an hour (similar to Chimer), and counts out the fractions and the o'clock hour.", From dc575281a091f3068014e5ae9ef16a0d6d307fc9 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 22:19:55 +1100 Subject: [PATCH 15/96] grandfather-clock: add icon --- apps/grandfather-clock/icon.png | Bin 1620 -> 4971 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/grandfather-clock/icon.png b/apps/grandfather-clock/icon.png index 582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0..b7ca0872f2cafac763afc700a2e1916ae524b2f1 100644 GIT binary patch literal 4971 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 delta 1590 zcmV-62FdyBCe#d&B$E^n5q|~=NklVsi@II zDWLJF<-tS+MbQVNMvWngMiMVMF($}~PbV60iJqKGq6sl-z#5IgNDvG@D81m_8L(pU z0#u>&LWh~o%w9f}(&^0JyL+a!If?wA_PXuwzxMtv>-#=9jnnvZLw~00MXDHdHZ-F~ zE6@xyAk0IFoNQ?rJ z?=L3MHi1NI%W6w_1%Iftvl|hOhaVrR!sN{2xw@hkSSKy zk8akT^^R7(Pu73-SLjz9%wK^oEKM9^v2d+uZBzb_ElWR@^923y?MQ5Sh3y}H359v|8 zR9g6#r~d$slVYvzX{^gvI{yK&9t6Sw)^Fo(=6P9=8U6ZW2$40`DO|&}2{l-??t>KM^xP{PQp9J>sMDt1wG0P7(^*|FxpxgxUNu=e>XY z@94oXm34@@sD<7z%UMsx_zdi4z8GAI!3iDJ{-u zogg{9cYkp~PAMU^CCrIu%1M71EC`5o2if_~7E&h??0jeQ1Y3N6p?}G72FSn>E+sATQ)Q)70!M+WViTAl9FdlI z^_bw)g$_FC{~s`6^Y4_v-WecL8bso`qEiB0GeD&@Sajx!_6dmf;f#FXiqAg!jge#)(`PVmVSj|$`UsHZGo<5&Mq0i(4E(oP@&iXk=-U1(Bgrgt{}SSg8|!FVQpN1*ApW3% zX$qBd0$g%sHPPlXP=%gv2Ryu4{+&-ACfn41x}XBX7bma&a6)1z%_mzAlTKO8TYoT% zMa!#@Nsf>EkEEDA*ST6fiC+AnsNK1#>!x0obq@j$QqYU-ad3ZvbjqUU+%iw(0Wahg zmHV6yeLWqoYkSl4pzFQ(_Vp&ItO{WI-48rGLwQb?#vgVvduyd9_6W)rFRoQJq3I(J z?{Xmin45#=3l9BmL6Bp<*MZejrhnxPZJd$0O%`^i+?+grDp}Z_q9=X}=<|3S6D2}X zo}(vz>ty7i#49G<-Lx9fe*rb6#JivumHVB}LG4gdXO*R~xABLfz>ADt4^0(GkQeZW zqQ#Jh>AK{zSO Date: Thu, 30 Jan 2025 22:20:29 +1100 Subject: [PATCH 16/96] grandfather-clock: update readme --- apps/grandfather-clock/README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/grandfather-clock/README.md b/apps/grandfather-clock/README.md index f0e628cda..637ab50c4 100644 --- a/apps/grandfather-clock/README.md +++ b/apps/grandfather-clock/README.md @@ -1,10 +1,10 @@ # Grandfather Clock -A widget that runs in the background and chimes on every (configurable) fraction of an hour, similar to Chimer, and counts out the fractions and the o'clock hour. +A widget that runs in the background and chimes on every (configurable*) fraction of an hour, similar to Chimer, and counts out the fractions and the o'clock hour. ## Usage -Once installed, see the App Settings page for options. ** This is not implemented yet. Await v0.02 +Once installed, see the App Settings page for options. Defaults: - Twelve hour mode is ENABLED. @@ -24,3 +24,7 @@ Drop me a message at @yogsoy on Discord if you need help / discover a bug that I ## Creator Written by June B (yogsoy), inspired by aaronrolls' Chimer. + +## Notes + +\* This is not implemented yet, sorry! Await v0.02. From 15f820f3123ab567314400b27a6a4b69819cb2d5 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 22:41:09 +1100 Subject: [PATCH 17/96] grandfather-clock: show icon for widget once settings are implemented, this will be disabled by default --- apps/grandfather-clock/widget.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apps/grandfather-clock/widget.js b/apps/grandfather-clock/widget.js index 86b134c15..86294e087 100644 --- a/apps/grandfather-clock/widget.js +++ b/apps/grandfather-clock/widget.js @@ -1,5 +1,14 @@ (() => { + WIDGETS["grandfather-clock"] = { + area: "tr", + width: 24, + draw: function() { + g.reset(); + g.drawImage(atob("GBiBAAAYAAA8AAA8AAD/AAH/gAP/wAf/4Afn4Afn4Afn4Afn4Afn4Af/4Af/4Afn4Afn4A/n8A//8B//+D///AAAAAAAAAA8AAAYAA=="), this.x, this.y); + } + }; + // todo: all of these configurable through app settings menu. const twelve_hour = true; const swap_meridian = false; From 31c3725b93478b737427d78780dca8181e954f83 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Thu, 30 Jan 2025 23:06:11 +1100 Subject: [PATCH 18/96] grandfather-clock: more edits to readme, todo --- apps/grandfather-clock/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/grandfather-clock/README.md b/apps/grandfather-clock/README.md index 637ab50c4..fdf98dd86 100644 --- a/apps/grandfather-clock/README.md +++ b/apps/grandfather-clock/README.md @@ -4,7 +4,7 @@ A widget that runs in the background and chimes on every (configurable*) fractio ## Usage -Once installed, see the App Settings page for options. +Once installed, see the App Settings page for options. * Defaults: - Twelve hour mode is ENABLED. @@ -25,6 +25,8 @@ Drop me a message at @yogsoy on Discord if you need help / discover a bug that I Written by June B (yogsoy), inspired by aaronrolls' Chimer. -## Notes +## Todo -\* This is not implemented yet, sorry! Await v0.02. +\* App settings are not implemented yet, sorry! Await v0.02. + +A better icon would be nice. A 1-bit simplified grandfather clock. From a4eab7383ad079591c2218e09701dca7b09fa9b7 Mon Sep 17 00:00:00 2001 From: Le~Kat Date: Fri, 31 Jan 2025 18:25:02 -0500 Subject: [PATCH 19/96] added a settings page to multidice --- apps/multidice/ChangeLog | 5 ++++ apps/multidice/app.js | 57 ++++++++++++++++++++++++++--------- apps/multidice/metadata.json | 6 ++-- apps/multidice/settings.js | 58 ++++++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 apps/multidice/settings.js diff --git a/apps/multidice/ChangeLog b/apps/multidice/ChangeLog index cb0cce2aa..ca17e1833 100644 --- a/apps/multidice/ChangeLog +++ b/apps/multidice/ChangeLog @@ -30,3 +30,8 @@ 1.28: increased vibration strength, added some comments, & some QOL 1.29: changed image 1.30: changed image, again +1.40: added various settings for controlling when & how to throw dice +1.41: fixed dumb mistake +1.42: okay maby I should've read the *whole* error log +1.43: playing whackamole with ESLint +1.44: fixed (?) settings app diff --git a/apps/multidice/app.js b/apps/multidice/app.js index 53f67e21e..fe869626a 100644 --- a/apps/multidice/app.js +++ b/apps/multidice/app.js @@ -1,12 +1,20 @@ -var menu = true; // default to have the selection menu open +var settings = Object.assign({ + vibrate: true, + shake: true, + screen: false, + shake_timeout: 200, + shake_duration: 100, +}, require('Storage').readJSON("multidice.json", true) || {}); + +var menu = true; // defaults to having the menu open const DICE_ARRAY = [0, 4, 6, 8, 10, 12, 20, 100]; // 0 means nothing selected const SELECTION_ARRAY = [6, 0, 0, 0, 0, 0, 0, 0]; // default to selecting a single d20 // function to draw the selection menu function drawMenu() { - stringArr = new Array ("", "", "", "", "", "", "", ""); - for (i = 0; i < 8; i++) { + var stringArr = new Array ("", "", "", "", "", "", "", ""); + for (var i = 0; i < 8; i++) { if (SELECTION_ARRAY [i] != 0) { @@ -41,6 +49,7 @@ function touchHandler (button, xy) { return; } + var selection; if (xy.x <= 87) { // left if (xy.y <= 43) { // first @@ -84,15 +93,30 @@ function touchHandler (button, xy) { drawMenu(); } +var shaken = false; +var last_shaken = null; function accelHandler (xyz) { + // if the screen should be on *and* it isn't, return + if (settings.screen && ! Bangle.isBacklightOn()) { + + return; + } + if (xyz.diff >= 0.3) { - menu = false; - mutex (rollDice).catch (() => { + shaken = true; + last_shaken = Date.now(); + } else if (shaken && last_shaken !== null) { + + if (Date.now() - last_shaken > settings.shake_timeout) { - return; // not necessary, but prevents spamming the logs - }); + last_shaken = null; + shaken = false; + menu = false; + + mutex (rollDice).catch (() => { return; }); + } } } @@ -123,8 +147,8 @@ function mutex (functionRef) { // function to roll all selected dice, and display them function rollDice() { - resultsArr = new Uint8Array (8); - for (i = 0; i < 8; i++) { + var resultsArr = new Uint8Array (8); + for (var i = 0; i < 8; i++) { if (SELECTION_ARRAY [i] != 0) { @@ -135,7 +159,7 @@ function rollDice() { g.clear(); g.setFont ("Vector", 40); - for (i = 0; i < 4; i++) { + for (var i = 0; i < 4; i++) { if (SELECTION_ARRAY [i] != 0) { @@ -143,7 +167,7 @@ function rollDice() { } } - for (i = 4; i < 8; i++) { + for (var i = 4; i < 8; i++) { if (SELECTION_ARRAY [i] != 0) { @@ -157,14 +181,19 @@ function rollDice() { // triggers the vibration, then pauses before returning function vibrate() { + if (! settings.vibrate) { + + return (Promise.resolve (0)); + } + return new Promise ((resolve, reject) => { - return Bangle.buzz (50, 1).then ((value) => { + return Bangle.buzz (settings.shake_duration, 1).then ((value) => { setTimeout (() => { resolve (value); - }, 200); + }, 2 * settings.shake_duration + settings.shake_timeout); }); }); } @@ -177,7 +206,7 @@ function random (max) { drawMenu(); Bangle.on ('touch', touchHandler); -Bangle.on ('accel', accelHandler); +if (settings.shake) { Bangle.on ('accel', accelHandler); } setWatch (function() { menu = false; diff --git a/apps/multidice/metadata.json b/apps/multidice/metadata.json index 304c789e4..dd6941060 100644 --- a/apps/multidice/metadata.json +++ b/apps/multidice/metadata.json @@ -1,7 +1,7 @@ { "id": "multidice", "name": "multiple dice roller", "shortName":"multidice", - "version":"1.30", + "version":"1.44", "description": "roll anywhere from 1-8 dice at the same time", "icon": "app.png", "tags": "tool,game", @@ -10,6 +10,8 @@ "allow_emulator": true, "storage": [ {"name":"multidice.app.js","url":"app.js"}, + {"name":"multidice.settings.js","url":"settings.js"}, {"name":"multidice.img","url":"app-icon.js","evaluate":true} - ] + ], + "data": [{"name": "multidice.json"}] } diff --git a/apps/multidice/settings.js b/apps/multidice/settings.js new file mode 100644 index 000000000..446a785e1 --- /dev/null +++ b/apps/multidice/settings.js @@ -0,0 +1,58 @@ +(function(back) { + var settings = Object.assign({ + vibrate: true, + shake: true, + screen: false, + shake_timeout: 200, + shake_duration: 100, + }, require('Storage').readJSON("multidice.json", true) || {}); + + function writeSettings() { + require('Storage').writeJSON("multidice.json", settings); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "multi dice roll" }, + "< Back" : () => back(), + 'vibrate on roll?': { + value: !!settings.vibrate, + onchange: v => { + settings.vibrate = v; + writeSettings(); + } + }, + 'allow shaking?': { + value: !!settings.shake, + onchange: v => { + settings.shake = v; + writeSettings(); + } + }, + 'screen on to shake?': { + value: !!settings.screen, + onchange: v => { + settings.screen = v; + writeSettings(); + } + }, + 'shake timeout': { + value: settings.shake_timeout / 5, + min: 10, max: 40, + format: v => v * 5, + onchange: v => { + settings.shake_timeout = v * 5; + writeSettings(); + } + }, + 'shake duration': { + value: settings.shake_duration / 5, + min: 10, max: 40, + format: v => v * 5, + onchange: v => { + settings.shake_duration = v * 5; + writeSettings(); + } + }, + }); +}) From fe2ccfb1087fb150de812f8060c2aa0ac4ae8eee Mon Sep 17 00:00:00 2001 From: Randy Heydon Date: Fri, 31 Jan 2025 21:28:30 -0500 Subject: [PATCH 20/96] bwclk & bwclklite: Support 12-hour time format. This modifies how the time string is generated so it respects the system's locale settings, specifically for 12-hour time. This is done with the locale package, which also simplifies some of the string handling since the package creates a complete time string. Note this does not add any display of AM/PM, but neither do any other clock faces. --- apps/bwclk/ChangeLog | 3 ++- apps/bwclk/app.js | 8 +++----- apps/bwclk/metadata.json | 2 +- apps/bwclklite/ChangeLog | 3 ++- apps/bwclklite/app.js | 8 +++----- apps/bwclklite/metadata.json | 2 +- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/bwclk/ChangeLog b/apps/bwclk/ChangeLog index 191bb51e5..74b80b73b 100644 --- a/apps/bwclk/ChangeLog +++ b/apps/bwclk/ChangeLog @@ -32,4 +32,5 @@ clkinfo.addInteractive that would cause ReferenceError. 0.30: Use widget_utils 0.31: Use clock_info module as an app 0.32: Make the border of the clock_info box extend all the way to the right of the screen. -0.33: Fix issue rendering ClockInfos with for fg+bg color set to the same (#2749) \ No newline at end of file +0.33: Fix issue rendering ClockInfos with for fg+bg color set to the same (#2749) +0.34: Support 12-hour time format diff --git a/apps/bwclk/app.js b/apps/bwclk/app.js index fdb82df73..5053dafbb 100644 --- a/apps/bwclk/app.js +++ b/apps/bwclk/app.js @@ -239,11 +239,9 @@ let drawTime = function() { var y = y1; var date = new Date(); - var hours = String(date.getHours()); - var minutes = date.getMinutes(); - minutes = minutes < 10 ? String("0") + minutes : minutes; - var colon = settings.hideColon ? "" : ":"; - var timeStr = hours + colon + minutes; + var timeStr = locale.time(date, 1); + if (settings.hideColon) + timeStr = timeStr.replace(":", ""); // Set y coordinates correctly y += parseInt((H - y)/2) + 5; diff --git a/apps/bwclk/metadata.json b/apps/bwclk/metadata.json index d4091c2fe..de84ba947 100644 --- a/apps/bwclk/metadata.json +++ b/apps/bwclk/metadata.json @@ -1,7 +1,7 @@ { "id": "bwclk", "name": "BW Clock", - "version": "0.33", + "version": "0.34", "description": "A very minimalistic clock.", "readme": "README.md", "icon": "app.png", diff --git a/apps/bwclklite/ChangeLog b/apps/bwclklite/ChangeLog index c68c62edc..bba66928b 100644 --- a/apps/bwclklite/ChangeLog +++ b/apps/bwclklite/ChangeLog @@ -35,4 +35,5 @@ clkinfo.addInteractive that would cause ReferenceError. Remove invertion of theme as this doesn'twork very well with fastloading. Do an quick inital fillRect on theclock info area. 0.33: Make the border of the clock_info box extend all the way to the right of the screen. -0.34: Fix issue rendering ClockInfos with for fg+bg color set to the same (#2749) \ No newline at end of file +0.34: Fix issue rendering ClockInfos with for fg+bg color set to the same (#2749) +0.35: Support 12-hour time format diff --git a/apps/bwclklite/app.js b/apps/bwclklite/app.js index 05f61ec58..794b39aa9 100644 --- a/apps/bwclklite/app.js +++ b/apps/bwclklite/app.js @@ -199,11 +199,9 @@ let drawTime = function() { let y = y1; let date = new Date(); - let hours = String(date.getHours()); - let minutes = date.getMinutes(); - minutes = minutes < 10 ? String("0") + minutes : minutes; - let colon = settings.hideColon ? "" : ":"; - let timeStr = hours + colon + minutes; + var timeStr = locale.time(date, 1); + if (settings.hideColon) + timeStr = timeStr.replace(":", ""); // Set y coordinates correctly y += parseInt((H - y)/2) + 5; diff --git a/apps/bwclklite/metadata.json b/apps/bwclklite/metadata.json index f8dffdca9..14af7131c 100644 --- a/apps/bwclklite/metadata.json +++ b/apps/bwclklite/metadata.json @@ -1,7 +1,7 @@ { "id": "bwclklite", "name": "BW Clock Lite", - "version": "0.34", + "version": "0.35", "description": "A very minimalistic clock. This version of BW Clock is quicker at the cost of the custom font.", "readme": "README.md", "icon": "app.png", From 5323f83146625caa6cc43a9cfd4549801a106913 Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Sun, 2 Feb 2025 09:35:49 -0500 Subject: [PATCH 21/96] Added fixed on not reading defaults in counter2 settings --- apps/counter2/ChangeLog | 1 + apps/counter2/metadata.json | 2 +- apps/counter2/settings.js | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/counter2/ChangeLog b/apps/counter2/ChangeLog index 58eacf613..d952c505b 100644 --- a/apps/counter2/ChangeLog +++ b/apps/counter2/ChangeLog @@ -2,3 +2,4 @@ 0.02: Added Settings & readme 0.03: Fix lint warnings 0.04: Fix lint warnings +0.05: Fix on not reading counter defaults in Settings diff --git a/apps/counter2/metadata.json b/apps/counter2/metadata.json index 400abf267..04b00487f 100644 --- a/apps/counter2/metadata.json +++ b/apps/counter2/metadata.json @@ -1,7 +1,7 @@ { "id": "counter2", "name": "Counter2", - "version": "0.04", + "version": "0.05", "description": "Dual Counter", "readme":"README.md", "icon": "counter2-icon.png", diff --git a/apps/counter2/settings.js b/apps/counter2/settings.js index f97d49ad3..d74d9269f 100644 --- a/apps/counter2/settings.js +++ b/apps/counter2/settings.js @@ -18,7 +18,7 @@ "": { "title": "Counter2" }, "< Back": () => back(), 'Default C1': { - value: settings[0], + value: settings.max0, min: -99, max: 99, onchange: v => { settings.max0 = v; @@ -26,7 +26,7 @@ } }, 'Default C2': { - value: settings[2], + value: settings.max1, min: -99, max: 99, onchange: v => { settings.max1 = v; From 7664036fa7677033bbd23da9f061b78c4cd445ab Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 13 May 2024 22:42:21 +0200 Subject: [PATCH 22/96] mysetup: set up watch to my preference --- apps/mysetup/ChangeLog | 2 + apps/mysetup/README.md | 29 ++++++++++++ apps/mysetup/app-icon.js | 1 + apps/mysetup/app.png | Bin 0 -> 1620 bytes apps/mysetup/autoreset.json | 1 + apps/mysetup/backswipe.json | 1 + apps/mysetup/dtlaunch.json | 1 + apps/mysetup/fastload.json | 1 + apps/mysetup/lightswitch.json | 1 + apps/mysetup/messages.settings.json | 1 + apps/mysetup/metadata.json | 68 ++++++++++++++++++++++++++++ apps/mysetup/quicklaunch.json | 1 + apps/mysetup/recorder.json | 1 + apps/mysetup/setting.json | 1 + apps/mysetup/widbt_notify.json | 1 + 15 files changed, 110 insertions(+) create mode 100644 apps/mysetup/ChangeLog create mode 100644 apps/mysetup/README.md create mode 100644 apps/mysetup/app-icon.js create mode 100644 apps/mysetup/app.png create mode 100644 apps/mysetup/autoreset.json create mode 100644 apps/mysetup/backswipe.json create mode 100644 apps/mysetup/dtlaunch.json create mode 100644 apps/mysetup/fastload.json create mode 100644 apps/mysetup/lightswitch.json create mode 100644 apps/mysetup/messages.settings.json create mode 100644 apps/mysetup/metadata.json create mode 100644 apps/mysetup/quicklaunch.json create mode 100644 apps/mysetup/recorder.json create mode 100644 apps/mysetup/setting.json create mode 100644 apps/mysetup/widbt_notify.json diff --git a/apps/mysetup/ChangeLog b/apps/mysetup/ChangeLog new file mode 100644 index 000000000..b783a7917 --- /dev/null +++ b/apps/mysetup/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App! +0.02: update to my current preferences. diff --git a/apps/mysetup/README.md b/apps/mysetup/README.md new file mode 100644 index 000000000..278665743 --- /dev/null +++ b/apps/mysetup/README.md @@ -0,0 +1,29 @@ +# App Name + +Describe the app... + +Add screen shots (if possible) to the app folder and link then into this file with ![](.png) + +## Usage + +Before installing this do: + +1. Factory reset the watch. +2. Remove all apps via the "More..." tab in the App Loader. +3. Make sure minification is turned off on the App Loader. + +## Features + +Name the function + +## Controls + +Name the buttons and what they are used for + +## Requests + +Name who should be contacted for support/update requests + +## Creator + +thyttan diff --git a/apps/mysetup/app-icon.js b/apps/mysetup/app-icon.js new file mode 100644 index 000000000..49232b838 --- /dev/null +++ b/apps/mysetup/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA==")) diff --git a/apps/mysetup/app.png b/apps/mysetup/app.png new file mode 100644 index 0000000000000000000000000000000000000000..582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0 GIT binary patch literal 1620 zcmV-a2CMmrP)1gXjloC|3_d8m;N2OpV(|i0q4YwBna<2! zK9thw%-*|urnNbV{Gax^?eD+#{x0kLJ~)lj_;W+1>qV*k8akT^^dvctZccUyj4}H~#M%Wwee_v` zHMv7o%BM8@dBrLshn{wGD9BDl?^eV5vSM3T96;NnHvtc6La=(qzq)xrX1d8bK-TN- zrd_f$_O`9nEmS+_S7HTXK<&u;LDIW|qlN&KJvM}tt6TVVqL-AvNv`B*{NzNpBfSQwQP5~Sf(Dp@Vq1+3Q`N9wBQN2`J_?M^u0FIMlt?p^8 z%U3%80kIwg!T{E9<8J18S&$k1`eO)@HP+=TZKo(z3_A3VFYJB=sn`2^Q$mRE>02(+W)np;)L1!GUvU2{O{<&F_nE6Qe#D~Xf|dD z+?d3-D1(IUiL`C2;PPv4CKw8H)v7h8^obJ&Z6D0CjVUe8Xq_NAymxUyPAMU^CCrIu z%1M71EC`5o2if_~7E&h??0jeQ1Y3N6p?}G72FmS*)xQD)%wBE=2tW6@(+MTi!fk9H1pWKew2(jTXVu4%vk26QvSQCbGmk`Z)Y! zBIhh)6vG2)h6mF8wC^|l$M(Eo9D?JiW}=_T2jUA>LC80foTera{^p)Wi`>}Gf;(|ZwEZQ zS^k|*9wyt=f4ZOo!xty7{%}HKD9tBZ50g$=%v&&vMa!#@Nsf>EkEEDA*ST6fiC+An zsNK1#>!x0obq@j$QqYU-ad3ZvbjqUU+%iw(0WahgmHV6yeLWqoYkSl4pzFQ(_Vp&I ztO{WI-48rGLwQb?#vgVvduyd9_6W)rFRoQJq3I(J?{Xmin45#=3l9BmL6Bp<*MZej zrsWN7oRPUr7IvrHoIHOjS=gPTCw>d)^LQK+B|=f2qbGjrWaOd5D<<9Dv>MTW0X3z> zyPy}9`<>1~?NCx@m8G$_@rRTy5zH12YM&P)=tU+L^fgY z^0Z&_6^qdVuwgN3wt_Ze(10?J@%{C2grBk42hsu74qEo^nd&v`X`IHN9lrxzS~GeF S(*#!l0000 Date: Sat, 6 Jul 2024 13:39:22 +0200 Subject: [PATCH 23/96] mysetup: update app list --- apps/mysetup/ChangeLog | 1 + apps/mysetup/metadata.json | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/mysetup/ChangeLog b/apps/mysetup/ChangeLog index b783a7917..e2cf1d249 100644 --- a/apps/mysetup/ChangeLog +++ b/apps/mysetup/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! 0.02: update to my current preferences. +0.03: update app list diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index 3a5af4b54..2d1258192 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -1,6 +1,6 @@ { "id": "mysetup", "name": "My Setup", - "version":"0.02", + "version":"0.03", "description": "Setup the Bangle.js watch as I want it.", "icon": "app.png", "type": "settings", @@ -34,15 +34,14 @@ "recorder":"app", "bthrm":"app", "fastload":"app", - "fastreset":"app", "agenda":"app", "edgeclk":"app", - "activityreminder":"app", "twenties":"app", "autoreset":"app", "chargent":"app", "setting":"app", - "boot":"app" + "boot":"app", + "setuichange":"app" }, "readme": "README.md", "storage": [ From 64abe11db913e1f3670cc36e946ea0e8eeebb6aa Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sat, 6 Jul 2024 15:10:05 +0200 Subject: [PATCH 24/96] mysetup: add edgeclk settings --- apps/mysetup/edgeclk.settings.json | 1 + apps/mysetup/metadata.json | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 apps/mysetup/edgeclk.settings.json diff --git a/apps/mysetup/edgeclk.settings.json b/apps/mysetup/edgeclk.settings.json new file mode 100644 index 000000000..6ff3cbe84 --- /dev/null +++ b/apps/mysetup/edgeclk.settings.json @@ -0,0 +1 @@ +{"buzzOnCharge":true,"monthFirst":true,"twentyFourH":true,"showAmPm":false,"showSeconds":false,"showWeather":false,"stepGoal":10000,"stepBar":true,"weekBar":true,"mondayFirst":true,"dayBar":true} diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index 2d1258192..fbe3ff802 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -61,6 +61,8 @@ "url":"widbt_notify.json"}, {"name":"recorder.json", "url":"recorder.json"}, + {"name":"edgeclk.settings.json", + "url":"edgeclk.settings.json"}, {"name":"setting.json", "url":"setting.json"} ] From ad1efa2cbf1274117b8dd7e6888aac85718a75e3 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 10 Jul 2024 23:44:01 +0200 Subject: [PATCH 25/96] mysetup: add delaylock app --- apps/mysetup/backswipe.json | 2 +- apps/mysetup/metadata.json | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/mysetup/backswipe.json b/apps/mysetup/backswipe.json index b43cb1cf4..aa66bd534 100644 --- a/apps/mysetup/backswipe.json +++ b/apps/mysetup/backswipe.json @@ -1 +1 @@ -{"mode":0,"apps":[{"name":"Calculator","src":"calculator.app.js"},{"name":"SleepLog","src":"sleeplog.app.js"},{"name":"Messages","sortorder":-9,"src":"messagegui.app.js"},{"name":"Messages","sortorder":-9,"src":"messagegui.app.js","files":"messagegui.info,messagegui,messagegui.app.js,messagegui.new.js,messagegui.boot.js,messagegui.img"}],"standardNumSwipeHandlers":4,"standardNumDragHandlers":1} \ No newline at end of file +{"mode":0,"apps":[{"name":"Calculator","src":"calculator.app.js"},{"name":"SleepLog","src":"sleeplog.app.js"},{"name":"Messages","sortorder":-9,"src":"messagegui.app.js"},{"name":"Messages","sortorder":-9,"src":"messagegui.app.js","files":"messagegui.info,messagegui,messagegui.app.js,messagegui.new.js,messagegui.boot.js,messagegui.img"}],"standardNumSwipeHandlers":5,"standardNumDragHandlers":1} diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index fbe3ff802..206aba80e 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -6,6 +6,7 @@ "type": "settings", "tags": "system,clkinfo", "supports" : ["BANGLEJS2"], + "readme": "README.md", "dependencies" : { "sched":"app", "kbmulti":"app", @@ -33,17 +34,17 @@ "alarm":"app", "recorder":"app", "bthrm":"app", - "fastload":"app", "agenda":"app", "edgeclk":"app", "twenties":"app", "autoreset":"app", "chargent":"app", "setting":"app", + "fastload":"app", "boot":"app", + "delaylock":"app", "setuichange":"app" }, - "readme": "README.md", "storage": [ {"name":"backswipe.json", "url":"backswipe.json"}, From 112e90c7d7d7d148f516938c255c88bf2ea2230a Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 10 Jul 2024 23:45:50 +0200 Subject: [PATCH 26/96] =?UTF-8?q?mysetup:=20add=20app=20=C2=B4forge=C2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mysetup/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index 206aba80e..82c01159d 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -30,6 +30,7 @@ "runplus":"app", "dtlaunch":"app", "quicklaunch":"app", + "forge":"app", "kineticscroll":"app", "alarm":"app", "recorder":"app", From c3fc33b278550f8941658f7373a2078075861161 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sun, 10 Nov 2024 09:58:27 +0100 Subject: [PATCH 27/96] mysetup: remove traces of mysetup installation --- apps/mysetup/boot.js | 5 +++++ apps/mysetup/metadata.json | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 apps/mysetup/boot.js diff --git a/apps/mysetup/boot.js b/apps/mysetup/boot.js new file mode 100644 index 000000000..85f2c4ff0 --- /dev/null +++ b/apps/mysetup/boot.js @@ -0,0 +1,5 @@ +{ +require("Storage").erase("mysetup.info"); +require("Storage").erase("mysetup.boot.js"); +load(); +} diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index 82c01159d..a1ed941b9 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -66,6 +66,8 @@ {"name":"edgeclk.settings.json", "url":"edgeclk.settings.json"}, {"name":"setting.json", - "url":"setting.json"} + "url":"setting.json"}, + {"name":"mysetup.boot.js", + "url":"boot.js"} ] } From 08b730915a2b1547841d87457a4c7b268401390c Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Sun, 10 Nov 2024 10:09:07 +0100 Subject: [PATCH 28/96] mysetup: rm setuichange, use kbedgewrite --- apps/mysetup/metadata.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index a1ed941b9..4ed008b19 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -9,7 +9,7 @@ "readme": "README.md", "dependencies" : { "sched":"app", - "kbmulti":"app", + "kbedgewrite":"app", "messageicons":"app", "widmsggrid":"app", "msgwakefup":"app", @@ -43,8 +43,7 @@ "setting":"app", "fastload":"app", "boot":"app", - "delaylock":"app", - "setuichange":"app" + "delaylock":"app" }, "storage": [ {"name":"backswipe.json", From 8091e3c3b42517545806ededfd082dc95a339810 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 22 Jan 2025 21:12:48 +0100 Subject: [PATCH 29/96] mysetup: add apps, tweak edgeclk settings json --- apps/mysetup/edgeclk.settings.json | 2 +- apps/mysetup/metadata.json | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/mysetup/edgeclk.settings.json b/apps/mysetup/edgeclk.settings.json index 6ff3cbe84..bdf875621 100644 --- a/apps/mysetup/edgeclk.settings.json +++ b/apps/mysetup/edgeclk.settings.json @@ -1 +1 @@ -{"buzzOnCharge":true,"monthFirst":true,"twentyFourH":true,"showAmPm":false,"showSeconds":false,"showWeather":false,"stepGoal":10000,"stepBar":true,"weekBar":true,"mondayFirst":true,"dayBar":true} +{"buzzOnCharge":true,"monthFirst":true,"twentyFourH":true,"showAmPm":false,"showSeconds":true,"showWeather":false,"stepGoal":10000,"stepBar":true,"weekBar":true,"mondayFirst":true,"dayBar":true,"redrawOnStep":false} diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index 4ed008b19..3fdf93476 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -43,6 +43,8 @@ "setting":"app", "fastload":"app", "boot":"app", + "gbdiscon":"app", + "ateatimer":"app", "delaylock":"app" }, "storage": [ From 0f79a767ed10f75b6aa585866d800dd483ce8f92 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 21:09:46 +0100 Subject: [PATCH 30/96] mysetup: add msgtwscr app --- apps/mysetup/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/mysetup/metadata.json b/apps/mysetup/metadata.json index 3fdf93476..acf75cdd4 100644 --- a/apps/mysetup/metadata.json +++ b/apps/mysetup/metadata.json @@ -13,6 +13,7 @@ "messageicons":"app", "widmsggrid":"app", "msgwakefup":"app", + "msgtwscr":"app", "notify":"app", "health":"app", "widminbate":"app", From f0b1fb2c2311b5c98816e3e1da663b3b62f008f1 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 21:19:26 +0100 Subject: [PATCH 31/96] mysetup: add icon --- apps/mysetup/app-icon.js | 1 - apps/mysetup/app.png | Bin 1620 -> 1789 bytes 2 files changed, 1 deletion(-) delete mode 100644 apps/mysetup/app-icon.js diff --git a/apps/mysetup/app-icon.js b/apps/mysetup/app-icon.js deleted file mode 100644 index 49232b838..000000000 --- a/apps/mysetup/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA==")) diff --git a/apps/mysetup/app.png b/apps/mysetup/app.png index 582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0..24ff01b8a4a6588bbfde982ce24cdb50735e51f5 100644 GIT binary patch delta 1773 zcmV8Q}8HClU z^Y4B?*T3^S=h~7qfg#e`-6GAWP2@HIA8XQU8dmRL{i6cz#H0)EZY9&ny4G~-v1B^A zukDkz?~awHC<9cZj8_OgNG1y0_RmSWzkh zbrs#C0gOO!{O56ji0?jhNwGB$QWjOW%*c%eFzyg`f`7^~WIB0FmF4M@BwdVTxt4kG zm+@DYjA`C+J0TYeVyrzxslLUoFxJ``W0za&5m`ozlP~72iyGzCzHZ9Yfr=X6*DcSt zoYTA`2!h#Hv(~g5HFrKN?8-AE(vK9Sakv%$Kw%soYu@(XQR!6k3mvfp({GwzIUt-U z^y7Gs>VE<^m~|9I`M!DQOJP2FO3`(7d8XsHCj`LUs3^yMiJgg(m`|pYqH%MBVIDaq z1mIK))oE_rTMCF99&0uzQ@gP&>)#Hb((H`o_vB;G?6nOr?I*4Mgz(+a1*^}3cr{V9 zdDZ1|ONER)jA=Xf26|&p@3952aC@hibMIE6d4DT=F=oq#YpMX;QWXnjodRfXk|O}v zdlJQ`jyl5 zz{^8fb0M3xn1>v``K_BBw@~vVO@e#q%eDYi2$u(A@jfT!8(;W?`3>ZJQ>I+@?{C0M zJAWECH#i2UT~%|OVsw9Dt%LDo2w@Xtde4GwyKI|Z@OVm;*VgBV=G!t{69C}XbdqiQ z)k3j+*K*PLV1rQ=ySitzg>5d_X$ykc=50-4=^IPMwdHImF!bMRP|lxOIx!2VzTe)_veyp{gLtPHlGPlNn{W2bCdD!Db5uXxjdf z@XeYxgaI^E00eXU2Cv)vTG0SzAf(J^8qN_~;GA~?;He4^g)kl3UsEG8k-1`}*MD~s zL)B<_?sr844DUU3D!oD~MW|5C*FEr*7*^z`j|&w*;PnoHg&`ExM@kz~5hR00X~vi|Ey`w?cz2nd8yVz?0W_LEq=k zy2bwlfT{crk9cW4GujrB+*7yGq1^V<-xp^9EbGX4;vHQH+vd#;gDc>;6Mypu=gbvB zqz;V+P>4RZ03_c&IC;hHBetf}BtL{N29Vl&m%k!s*ZjtcfPn!pDj6JnubmeSU_0Eh zx^@wF_Z^vAXZz0Y4bK*)`QL2N92pm-00 zgg6}B`}6Tx#GzWuS%JhwOCgXkBCmUzhD5fg+4C=V3R|DkABHTl^1+)8h=2iwo#;ck4W=a z!2o^;e>)wMo-iiec0~ags?jRS zcuqW(NtNRNw+WAyU5BS8QknM?sZ2i6(Y5k?`*9S@UjOIi@s7-DJ0JQNYblu(N>Kj^ P00000NkvXXu0mjf)Z}v3 delta 1603 zcmV-J2E6(G4b%*fB!32COGiWi{{a60|De66lK=n)2}wjjRA_4iBBgQZ;76qOQH!eYQP$e z!AKAcJ}AB5-5IcA@d8w#^g@T3&dgpul+x+U-n)CIwK<9WpMUnc?eD+#{x0kLJ~)lj z_;W+1>qV*0;V;<>t_7g#4P@iwmk z1qmdsUbfUStd9Y|TVP;i68~i*#Z&Y~>jipZkI1cLC-XG&6_#ObWSo3TMb<VnloLT~EMt9))wb_t9z`$fds1weiDS%fvYLsiPBH2ZnQDk6uTc5^7mPDSrl!}_vf zTUQ)F+oLxD4{1WMdd9!Hc|m5n$vQyR>+YsqvNZO#t<^15JLgwo1!6$$$ooOkyMm*J z0F*s8gnyK)TljRMmz2LruK4O$zQL{wjY9)Z0kt|Lq(2FsQU|U{&Lnw&nv-iz0UQ(1 z_C;r*+zXKT!Vl?Dy;NHGm#6;#j+0`o?rE&cS33Uzu^t4%0M>8gZsvJekQx2@V+fHo z*5xa0rzlknI`ob)Spqpmmr>I{XwtT=f>`%xcYlkXpJLUDL8`0V*CWqymfo()hTHYJB=sn`2^Q$mRE>02( z+W)np;)L1!GUvU2{O{<&F_nE6Qe#D~Xf|dD+?d3-D1(IUiL`C2;PPv4CKw8H)v7h8 z^nZyH25leAvW+P%&S;$=IlOmqK~5megP0ekG0q%cjYX8Luf59F*IsobYlouaRHM0~ z(;q09t|si8%+WECi^loRmFYCwYI6mr1b@o&75=}a@Lib3Y|Ie4CxKK>Okic}5Rq_U zeN+~H!uVe{{lz}^`kQW`|!xuR17T{A$XG+1=zihuSA zi1p!&kSPh)j$Fxp5Gw{9(I0?wrrO+K-v|fy4|DX;36jHEtgI3$_c6CFMEwO7gd?t7 z-aKL)pd~&(x0thy7QxaE*@Ws7r4mmjvcx<3IQ(NG=PY9s!vkrC2h#ks?>HAOpF`dJ zh_{!DY|1~1bS#dwebHHv-OtHAL4Pqg_G^mIKKhN3WERtBFmGXm+WH8Q3O|NVINqP; zhpz`Xd?0}cEM8H=+`36mP?GrceEI9%2{WYQhDKVxISl-_Sn>l$M(Eo9D?J ziW}=_T2jUA>LC80foTera{^p)Wi`>}Gf;(|ZwEZQS^k|*9wyt=f4ZOo!+#eiul{gC zVkpfgTMv^?S+&Oz-^QfHN=vA6Mu zqQHxcUJp$bNst%thoZ%hhv~ZHvseduC&kuI$^k?+Ves;_U-A`;(L4gMVKHj9f;MB& zfHIHq{q=E#pRw2n(gD^ETK4Xl>NV?WoW`FWzXM%bGkOQp1Xln6002ovPDHLkV1m{L B8@m7i From 9ff0718aba339a5004442f16b59c66da3d5acba0 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 21:53:35 +0100 Subject: [PATCH 32/96] mysetup: becomes "anotherconf" --- apps/{mysetup => anotherconf}/ChangeLog | 1 + apps/anotherconf/README.md | 26 ++++++++++++++++ apps/{mysetup => anotherconf}/app.png | Bin apps/{mysetup => anotherconf}/autoreset.json | 0 apps/{mysetup => anotherconf}/backswipe.json | 0 apps/anotherconf/boot.js | 5 +++ apps/{mysetup => anotherconf}/dtlaunch.json | 0 .../edgeclk.settings.json | 0 apps/{mysetup => anotherconf}/fastload.json | 0 .../{mysetup => anotherconf}/lightswitch.json | 0 .../messages.settings.json | 0 apps/{mysetup => anotherconf}/metadata.json | 25 +++++++-------- .../{mysetup => anotherconf}/quicklaunch.json | 0 apps/{mysetup => anotherconf}/recorder.json | 0 apps/{mysetup => anotherconf}/setting.json | 0 .../widbt_notify.json | 0 apps/mysetup/README.md | 29 ------------------ apps/mysetup/boot.js | 5 --- 18 files changed, 45 insertions(+), 46 deletions(-) rename apps/{mysetup => anotherconf}/ChangeLog (61%) create mode 100644 apps/anotherconf/README.md rename apps/{mysetup => anotherconf}/app.png (100%) rename apps/{mysetup => anotherconf}/autoreset.json (100%) rename apps/{mysetup => anotherconf}/backswipe.json (100%) create mode 100644 apps/anotherconf/boot.js rename apps/{mysetup => anotherconf}/dtlaunch.json (100%) rename apps/{mysetup => anotherconf}/edgeclk.settings.json (100%) rename apps/{mysetup => anotherconf}/fastload.json (100%) rename apps/{mysetup => anotherconf}/lightswitch.json (100%) rename apps/{mysetup => anotherconf}/messages.settings.json (100%) rename apps/{mysetup => anotherconf}/metadata.json (78%) rename apps/{mysetup => anotherconf}/quicklaunch.json (100%) rename apps/{mysetup => anotherconf}/recorder.json (100%) rename apps/{mysetup => anotherconf}/setting.json (100%) rename apps/{mysetup => anotherconf}/widbt_notify.json (100%) delete mode 100644 apps/mysetup/README.md delete mode 100644 apps/mysetup/boot.js diff --git a/apps/mysetup/ChangeLog b/apps/anotherconf/ChangeLog similarity index 61% rename from apps/mysetup/ChangeLog rename to apps/anotherconf/ChangeLog index e2cf1d249..6237f5b04 100644 --- a/apps/mysetup/ChangeLog +++ b/apps/anotherconf/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: update to my current preferences. 0.03: update app list +0.04: change app name "mysetup" -> "anotherconf" diff --git a/apps/anotherconf/README.md b/apps/anotherconf/README.md new file mode 100644 index 000000000..4fac2feb4 --- /dev/null +++ b/apps/anotherconf/README.md @@ -0,0 +1,26 @@ +# Another Default Config + +A different default set of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing. + +## Usage + +Before installing do this: + +1. Backup your current setup (via the "More..." tab of the App Loader) so you can restore it later if you want. +2. Factory reset the watch. +3. Remove all apps via the "More..." tab in the App Loader. +4. Make sure minification is turned off on the App Loader. +5. Then install. +6. Try it out, switch out apps to your favorites and tweak to your liking! + +## Features + +There will not be a trace of a "Another Default Config" app on your watch after installation. Only the apps it installed and the configurations. + +## Requests + +Add to the espruino/BangleApps issue tracker and mention @thyttan for bug reports and suggestions. Or do a pull request! + +## Creator + +thyttan diff --git a/apps/mysetup/app.png b/apps/anotherconf/app.png similarity index 100% rename from apps/mysetup/app.png rename to apps/anotherconf/app.png diff --git a/apps/mysetup/autoreset.json b/apps/anotherconf/autoreset.json similarity index 100% rename from apps/mysetup/autoreset.json rename to apps/anotherconf/autoreset.json diff --git a/apps/mysetup/backswipe.json b/apps/anotherconf/backswipe.json similarity index 100% rename from apps/mysetup/backswipe.json rename to apps/anotherconf/backswipe.json diff --git a/apps/anotherconf/boot.js b/apps/anotherconf/boot.js new file mode 100644 index 000000000..a04465039 --- /dev/null +++ b/apps/anotherconf/boot.js @@ -0,0 +1,5 @@ +{ +require("Storage").erase("anotherconf.info"); +require("Storage").erase("anotherconf.boot.js"); +load(); +} diff --git a/apps/mysetup/dtlaunch.json b/apps/anotherconf/dtlaunch.json similarity index 100% rename from apps/mysetup/dtlaunch.json rename to apps/anotherconf/dtlaunch.json diff --git a/apps/mysetup/edgeclk.settings.json b/apps/anotherconf/edgeclk.settings.json similarity index 100% rename from apps/mysetup/edgeclk.settings.json rename to apps/anotherconf/edgeclk.settings.json diff --git a/apps/mysetup/fastload.json b/apps/anotherconf/fastload.json similarity index 100% rename from apps/mysetup/fastload.json rename to apps/anotherconf/fastload.json diff --git a/apps/mysetup/lightswitch.json b/apps/anotherconf/lightswitch.json similarity index 100% rename from apps/mysetup/lightswitch.json rename to apps/anotherconf/lightswitch.json diff --git a/apps/mysetup/messages.settings.json b/apps/anotherconf/messages.settings.json similarity index 100% rename from apps/mysetup/messages.settings.json rename to apps/anotherconf/messages.settings.json diff --git a/apps/mysetup/metadata.json b/apps/anotherconf/metadata.json similarity index 78% rename from apps/mysetup/metadata.json rename to apps/anotherconf/metadata.json index acf75cdd4..cbbf97278 100644 --- a/apps/mysetup/metadata.json +++ b/apps/anotherconf/metadata.json @@ -1,19 +1,20 @@ -{ "id": "mysetup", - "name": "My Setup", - "version":"0.03", - "description": "Setup the Bangle.js watch as I want it.", +{ "id": "anotherconf", + "name": "Another Default Config", + "version":"0.04", + "description": "A different default loadout of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.", "icon": "app.png", "type": "settings", - "tags": "system,clkinfo", + "tags": "system, configuration, config", "supports" : ["BANGLEJS2"], "readme": "README.md", "dependencies" : { "sched":"app", - "kbedgewrite":"app", + "kbmulti":"app", "messageicons":"app", "widmsggrid":"app", "msgwakefup":"app", "msgtwscr":"app", + "delaylock":"app", "notify":"app", "health":"app", "widminbate":"app", @@ -31,22 +32,22 @@ "runplus":"app", "dtlaunch":"app", "quicklaunch":"app", - "forge":"app", "kineticscroll":"app", "alarm":"app", "recorder":"app", - "bthrm":"app", "agenda":"app", "edgeclk":"app", - "twenties":"app", "autoreset":"app", "chargent":"app", "setting":"app", "fastload":"app", "boot":"app", - "gbdiscon":"app", "ateatimer":"app", - "delaylock":"app" + "drained":"app", + "forge":"app", + "bthrm":"app", + "twenties":"app", + "gbdiscon":"app" }, "storage": [ {"name":"backswipe.json", @@ -69,7 +70,7 @@ "url":"edgeclk.settings.json"}, {"name":"setting.json", "url":"setting.json"}, - {"name":"mysetup.boot.js", + {"name":"anotherconf.boot.js", "url":"boot.js"} ] } diff --git a/apps/mysetup/quicklaunch.json b/apps/anotherconf/quicklaunch.json similarity index 100% rename from apps/mysetup/quicklaunch.json rename to apps/anotherconf/quicklaunch.json diff --git a/apps/mysetup/recorder.json b/apps/anotherconf/recorder.json similarity index 100% rename from apps/mysetup/recorder.json rename to apps/anotherconf/recorder.json diff --git a/apps/mysetup/setting.json b/apps/anotherconf/setting.json similarity index 100% rename from apps/mysetup/setting.json rename to apps/anotherconf/setting.json diff --git a/apps/mysetup/widbt_notify.json b/apps/anotherconf/widbt_notify.json similarity index 100% rename from apps/mysetup/widbt_notify.json rename to apps/anotherconf/widbt_notify.json diff --git a/apps/mysetup/README.md b/apps/mysetup/README.md deleted file mode 100644 index 278665743..000000000 --- a/apps/mysetup/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# App Name - -Describe the app... - -Add screen shots (if possible) to the app folder and link then into this file with ![](.png) - -## Usage - -Before installing this do: - -1. Factory reset the watch. -2. Remove all apps via the "More..." tab in the App Loader. -3. Make sure minification is turned off on the App Loader. - -## Features - -Name the function - -## Controls - -Name the buttons and what they are used for - -## Requests - -Name who should be contacted for support/update requests - -## Creator - -thyttan diff --git a/apps/mysetup/boot.js b/apps/mysetup/boot.js deleted file mode 100644 index 85f2c4ff0..000000000 --- a/apps/mysetup/boot.js +++ /dev/null @@ -1,5 +0,0 @@ -{ -require("Storage").erase("mysetup.info"); -require("Storage").erase("mysetup.boot.js"); -load(); -} From feda047a417b4fbfd4e5119d45e7b5fa5e36570f Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 22:07:26 +0100 Subject: [PATCH 33/96] anotherconf: remove some apps not as important as the others --- apps/anotherconf/ChangeLog | 1 + apps/anotherconf/metadata.json | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/apps/anotherconf/ChangeLog b/apps/anotherconf/ChangeLog index 6237f5b04..6c717cad7 100644 --- a/apps/anotherconf/ChangeLog +++ b/apps/anotherconf/ChangeLog @@ -2,3 +2,4 @@ 0.02: update to my current preferences. 0.03: update app list 0.04: change app name "mysetup" -> "anotherconf" +0.05: remove apps that are not "core" to the experience. diff --git a/apps/anotherconf/metadata.json b/apps/anotherconf/metadata.json index cbbf97278..2a65584db 100644 --- a/apps/anotherconf/metadata.json +++ b/apps/anotherconf/metadata.json @@ -1,6 +1,6 @@ { "id": "anotherconf", "name": "Another Default Config", - "version":"0.04", + "version":"0.05", "description": "A different default loadout of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.", "icon": "app.png", "type": "settings", @@ -43,11 +43,7 @@ "fastload":"app", "boot":"app", "ateatimer":"app", - "drained":"app", - "forge":"app", - "bthrm":"app", - "twenties":"app", - "gbdiscon":"app" + "drained":"app" }, "storage": [ {"name":"backswipe.json", From 6af32d4c71ba920f129e49670fdc1563746aaed2 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 22:24:39 +0100 Subject: [PATCH 34/96] anotherconf: add to readme --- apps/anotherconf/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/anotherconf/README.md b/apps/anotherconf/README.md index 4fac2feb4..c292bb0a6 100644 --- a/apps/anotherconf/README.md +++ b/apps/anotherconf/README.md @@ -17,6 +17,14 @@ Before installing do this: There will not be a trace of a "Another Default Config" app on your watch after installation. Only the apps it installed and the configurations. +On the clock face: +- Swipe right on the screen to open the launcher (Desktop Launcher) - or press the hardware button. +- Swipe left to open a flashlight app. +- Swipe up to open the messages. +- Swipe down for quick access to music and podcast controls. + - (Do a subsequent left or right swipe to enter the listed apps) +- (Check out the "Quick Launch" app readme for more info) + ## Requests Add to the espruino/BangleApps issue tracker and mention @thyttan for bug reports and suggestions. Or do a pull request! From 991492c04706b7b46a9492808a30aecd9be7601f Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Wed, 29 Jan 2025 22:32:00 +0100 Subject: [PATCH 35/96] anotherconf: left swipe on clock fires up the torch --- apps/anotherconf/quicklaunch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/anotherconf/quicklaunch.json b/apps/anotherconf/quicklaunch.json index 56df7d3d2..4edbb083b 100644 --- a/apps/anotherconf/quicklaunch.json +++ b/apps/anotherconf/quicklaunch.json @@ -1 +1 @@ -{lapp:{name:"Show Launcher",sortorder:-12,src:"no source"},rapp:{name:"Extension",type:"app",sortorder:-11,src:"quicklaunch.app.js"},uapp:{name:"Messages",sortorder:-9,src:"messagegui.app.js"},dapp:{name:"Extension",type:"app",sortorder:-11,src:"quicklaunch.app.js"},tapp:{name:""},dlapp:{name:"PA Remote",src:"podadrem.app.js"},drapp:{name:"Remote for Spotify",src:"spotrem.app.js"},duapp:{name:""},ddapp:{name:"Extension",type:"app",sortorder:-11,src:"quicklaunch.app.js"},dtapp:{name:""},ddlapp:{name:"Alarms",src:"alarm.app.js"},ddrapp:{name:"Run+",src:"runplus.app.js"},dduapp:{name:""},dddapp:{name:"Agenda",src:"agenda.app.js"},ddtapp:{name:""},rlapp:{name:""},rrapp:{name:""},ruapp:{name:""},rdapp:{name:""},rtapp:{name:""},trace:"dr"} \ No newline at end of file +{lapp:{name:"Show Launcher",sortorder:-12,src:"no source"},rapp:{name:"torch",type:"app",sortorder:-11,src:"torch.app.js"},uapp:{name:"Messages",sortorder:-9,src:"messagegui.app.js"},dapp:{name:"Extension",type:"app",sortorder:-11,src:"quicklaunch.app.js"},tapp:{name:""},dlapp:{name:"PA Remote",src:"podadrem.app.js"},drapp:{name:"Remote for Spotify",src:"spotrem.app.js"},duapp:{name:""},ddapp:{name:"Extension",type:"app",sortorder:-11,src:"quicklaunch.app.js"},dtapp:{name:""},ddlapp:{name:"Alarms",src:"alarm.app.js"},ddrapp:{name:"Run+",src:"runplus.app.js"},dduapp:{name:""},dddapp:{name:"Agenda",src:"agenda.app.js"},ddtapp:{name:""},rlapp:{name:""},rrapp:{name:""},ruapp:{name:""},rdapp:{name:""},rtapp:{name:""},trace:"dr"} From 4154e24bb3ed0beb366933ed318e5a240c320bfb Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Mon, 3 Feb 2025 09:59:02 +0100 Subject: [PATCH 36/96] anotherconf: becomes "confthyttan" + some suggested changes --- apps/anotherconf/boot.js | 5 ----- apps/{anotherconf => confthyttan}/ChangeLog | 1 + apps/{anotherconf => confthyttan}/README.md | 6 +++--- apps/{anotherconf => confthyttan}/app.png | Bin .../autoreset.json | 0 .../backswipe.json | 0 .../{anotherconf => confthyttan}/dtlaunch.json | 0 .../edgeclk.settings.json | 0 .../{anotherconf => confthyttan}/fastload.json | 0 .../lightswitch.json | 0 .../messages.settings.json | 0 .../{anotherconf => confthyttan}/metadata.json | 17 +++++++---------- .../quicklaunch.json | 0 .../{anotherconf => confthyttan}/recorder.json | 0 apps/{anotherconf => confthyttan}/setting.json | 0 .../widbt_notify.json | 0 16 files changed, 11 insertions(+), 18 deletions(-) delete mode 100644 apps/anotherconf/boot.js rename apps/{anotherconf => confthyttan}/ChangeLog (78%) rename apps/{anotherconf => confthyttan}/README.md (82%) rename apps/{anotherconf => confthyttan}/app.png (100%) rename apps/{anotherconf => confthyttan}/autoreset.json (100%) rename apps/{anotherconf => confthyttan}/backswipe.json (100%) rename apps/{anotherconf => confthyttan}/dtlaunch.json (100%) rename apps/{anotherconf => confthyttan}/edgeclk.settings.json (100%) rename apps/{anotherconf => confthyttan}/fastload.json (100%) rename apps/{anotherconf => confthyttan}/lightswitch.json (100%) rename apps/{anotherconf => confthyttan}/messages.settings.json (100%) rename apps/{anotherconf => confthyttan}/metadata.json (77%) rename apps/{anotherconf => confthyttan}/quicklaunch.json (100%) rename apps/{anotherconf => confthyttan}/recorder.json (100%) rename apps/{anotherconf => confthyttan}/setting.json (100%) rename apps/{anotherconf => confthyttan}/widbt_notify.json (100%) diff --git a/apps/anotherconf/boot.js b/apps/anotherconf/boot.js deleted file mode 100644 index a04465039..000000000 --- a/apps/anotherconf/boot.js +++ /dev/null @@ -1,5 +0,0 @@ -{ -require("Storage").erase("anotherconf.info"); -require("Storage").erase("anotherconf.boot.js"); -load(); -} diff --git a/apps/anotherconf/ChangeLog b/apps/confthyttan/ChangeLog similarity index 78% rename from apps/anotherconf/ChangeLog rename to apps/confthyttan/ChangeLog index 6c717cad7..77d527619 100644 --- a/apps/anotherconf/ChangeLog +++ b/apps/confthyttan/ChangeLog @@ -3,3 +3,4 @@ 0.03: update app list 0.04: change app name "mysetup" -> "anotherconf" 0.05: remove apps that are not "core" to the experience. +0.06: change name "anotherconf" -> "confthyttan" diff --git a/apps/anotherconf/README.md b/apps/confthyttan/README.md similarity index 82% rename from apps/anotherconf/README.md rename to apps/confthyttan/README.md index c292bb0a6..5f7819171 100644 --- a/apps/anotherconf/README.md +++ b/apps/confthyttan/README.md @@ -1,4 +1,4 @@ -# Another Default Config +# Thyttan's Default Config A different default set of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing. @@ -15,7 +15,7 @@ Before installing do this: ## Features -There will not be a trace of a "Another Default Config" app on your watch after installation. Only the apps it installed and the configurations. +There will not be a trace of a "Thyttan's Default Config" app on your watch after installation. Only the apps it installed and the configurations. On the clock face: - Swipe right on the screen to open the launcher (Desktop Launcher) - or press the hardware button. @@ -27,7 +27,7 @@ On the clock face: ## Requests -Add to the espruino/BangleApps issue tracker and mention @thyttan for bug reports and suggestions. Or do a pull request! +Add to the espruino/BangleApps issue tracker and mention @thyttan for bug reports and suggestions. ## Creator diff --git a/apps/anotherconf/app.png b/apps/confthyttan/app.png similarity index 100% rename from apps/anotherconf/app.png rename to apps/confthyttan/app.png diff --git a/apps/anotherconf/autoreset.json b/apps/confthyttan/autoreset.json similarity index 100% rename from apps/anotherconf/autoreset.json rename to apps/confthyttan/autoreset.json diff --git a/apps/anotherconf/backswipe.json b/apps/confthyttan/backswipe.json similarity index 100% rename from apps/anotherconf/backswipe.json rename to apps/confthyttan/backswipe.json diff --git a/apps/anotherconf/dtlaunch.json b/apps/confthyttan/dtlaunch.json similarity index 100% rename from apps/anotherconf/dtlaunch.json rename to apps/confthyttan/dtlaunch.json diff --git a/apps/anotherconf/edgeclk.settings.json b/apps/confthyttan/edgeclk.settings.json similarity index 100% rename from apps/anotherconf/edgeclk.settings.json rename to apps/confthyttan/edgeclk.settings.json diff --git a/apps/anotherconf/fastload.json b/apps/confthyttan/fastload.json similarity index 100% rename from apps/anotherconf/fastload.json rename to apps/confthyttan/fastload.json diff --git a/apps/anotherconf/lightswitch.json b/apps/confthyttan/lightswitch.json similarity index 100% rename from apps/anotherconf/lightswitch.json rename to apps/confthyttan/lightswitch.json diff --git a/apps/anotherconf/messages.settings.json b/apps/confthyttan/messages.settings.json similarity index 100% rename from apps/anotherconf/messages.settings.json rename to apps/confthyttan/messages.settings.json diff --git a/apps/anotherconf/metadata.json b/apps/confthyttan/metadata.json similarity index 77% rename from apps/anotherconf/metadata.json rename to apps/confthyttan/metadata.json index 2a65584db..c706d45f5 100644 --- a/apps/anotherconf/metadata.json +++ b/apps/confthyttan/metadata.json @@ -1,10 +1,10 @@ -{ "id": "anotherconf", - "name": "Another Default Config", - "version":"0.05", - "description": "A different default loadout of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.", +{ "id": "confthyttan", + "name": "Thyttan's Default Config", + "version":"0.06", + "description": "A different default set of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.", "icon": "app.png", - "type": "settings", - "tags": "system, configuration, config", + "type": "RAM", + "tags": "system, configuration, config, anotherconfig, thyttan", "supports" : ["BANGLEJS2"], "readme": "README.md", "dependencies" : { @@ -26,7 +26,6 @@ "torch":"app", "calculator":"app", "widbt_notify":"app", - "clock_info":"app", "smpltmr":"app", "clkinfostopw":"app", "runplus":"app", @@ -65,8 +64,6 @@ {"name":"edgeclk.settings.json", "url":"edgeclk.settings.json"}, {"name":"setting.json", - "url":"setting.json"}, - {"name":"anotherconf.boot.js", - "url":"boot.js"} + "url":"setting.json"} ] } diff --git a/apps/anotherconf/quicklaunch.json b/apps/confthyttan/quicklaunch.json similarity index 100% rename from apps/anotherconf/quicklaunch.json rename to apps/confthyttan/quicklaunch.json diff --git a/apps/anotherconf/recorder.json b/apps/confthyttan/recorder.json similarity index 100% rename from apps/anotherconf/recorder.json rename to apps/confthyttan/recorder.json diff --git a/apps/anotherconf/setting.json b/apps/confthyttan/setting.json similarity index 100% rename from apps/anotherconf/setting.json rename to apps/confthyttan/setting.json diff --git a/apps/anotherconf/widbt_notify.json b/apps/confthyttan/widbt_notify.json similarity index 100% rename from apps/anotherconf/widbt_notify.json rename to apps/confthyttan/widbt_notify.json From 0d3cad3dec6e45cd214dd6fdcf8a23af7439806e Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 3 Feb 2025 12:17:23 +0000 Subject: [PATCH 37/96] 0.15: Fix error when displaying a category with only one clockinfo (fix #3728) --- apps/clock_info/ChangeLog | 3 ++- apps/clock_info/lib.js | 2 +- apps/clock_info/metadata.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/clock_info/ChangeLog b/apps/clock_info/ChangeLog index 7d2043899..cf7da2fa1 100644 --- a/apps/clock_info/ChangeLog +++ b/apps/clock_info/ChangeLog @@ -12,4 +12,5 @@ 0.11: Prepend swipe listener if possible 0.12: Add drawFilledImage to allow drawing icons with a separately coloured middle 0.13: Cache loaded ClockInfos so if we have clockInfoWidget and a clock, we don't load them twice (saves ~300ms) -0.14: Check for .clkinfocache and use that if exists (from boot 0.64) \ No newline at end of file +0.14: Check for .clkinfocache and use that if exists (from boot 0.64) +0.15: Fix error when displaying a category with only one clockinfo (fix #3728) diff --git a/apps/clock_info/lib.js b/apps/clock_info/lib.js index 0e20ab855..cb6a19abb 100644 --- a/apps/clock_info/lib.js +++ b/apps/clock_info/lib.js @@ -283,7 +283,7 @@ exports.addInteractive = function(menu, options) { //in the worst case we come back to 0 } while(menu[options.menuA].items.length==0); // When we change, ensure we don't display the same thing as another clockinfo if we can avoid it - while ((options.menuB < menu[options.menuA].items.length) && + while ((options.menuB < menu[options.menuA].items.length-1) && exports.clockInfos.some(m => (m!=options) && m.menuA==options.menuA && m.menuB==options.menuB)) options.menuB++; } diff --git a/apps/clock_info/metadata.json b/apps/clock_info/metadata.json index 1d9a73ce3..9e9079c28 100644 --- a/apps/clock_info/metadata.json +++ b/apps/clock_info/metadata.json @@ -1,7 +1,7 @@ { "id": "clock_info", "name": "Clock Info Module", "shortName": "Clock Info", - "version":"0.14", + "version":"0.15", "description": "A library used by clocks to provide extra information on the clock face (Altitude, BPM, etc)", "icon": "app.png", "type": "module", From 9de824a8b255942c61ab64e119c95b2fd92ca734 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 3 Feb 2025 12:17:39 +0000 Subject: [PATCH 38/96] fix generator script --- apps/icons/gen/generate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/icons/gen/generate.js b/apps/icons/gen/generate.js index b91eedcdc..fd97a1ce9 100755 --- a/apps/icons/gen/generate.js +++ b/apps/icons/gen/generate.js @@ -7,7 +7,7 @@ /* eslint-env node */ -var imageconverter = require("../../../webtools/imageconverter.js").imageconverter; +var imageconverter = require("../../../webtools/imageconverter.js"); var icons = JSON.parse(require("fs").readFileSync(__dirname+"/icon_names.json")); const imgOptions = { mode : "1bit", From 62d3f803dad8cbef7503d0664d69d083c1595b42 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 3 Feb 2025 12:17:23 +0000 Subject: [PATCH 39/96] 0.15: Fix error when displaying a category with only one clockinfo (fix #3728) --- apps/clock_info/ChangeLog | 3 ++- apps/clock_info/lib.js | 2 +- apps/clock_info/metadata.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/clock_info/ChangeLog b/apps/clock_info/ChangeLog index 7d2043899..cf7da2fa1 100644 --- a/apps/clock_info/ChangeLog +++ b/apps/clock_info/ChangeLog @@ -12,4 +12,5 @@ 0.11: Prepend swipe listener if possible 0.12: Add drawFilledImage to allow drawing icons with a separately coloured middle 0.13: Cache loaded ClockInfos so if we have clockInfoWidget and a clock, we don't load them twice (saves ~300ms) -0.14: Check for .clkinfocache and use that if exists (from boot 0.64) \ No newline at end of file +0.14: Check for .clkinfocache and use that if exists (from boot 0.64) +0.15: Fix error when displaying a category with only one clockinfo (fix #3728) diff --git a/apps/clock_info/lib.js b/apps/clock_info/lib.js index 0e20ab855..cb6a19abb 100644 --- a/apps/clock_info/lib.js +++ b/apps/clock_info/lib.js @@ -283,7 +283,7 @@ exports.addInteractive = function(menu, options) { //in the worst case we come back to 0 } while(menu[options.menuA].items.length==0); // When we change, ensure we don't display the same thing as another clockinfo if we can avoid it - while ((options.menuB < menu[options.menuA].items.length) && + while ((options.menuB < menu[options.menuA].items.length-1) && exports.clockInfos.some(m => (m!=options) && m.menuA==options.menuA && m.menuB==options.menuB)) options.menuB++; } diff --git a/apps/clock_info/metadata.json b/apps/clock_info/metadata.json index 1d9a73ce3..9e9079c28 100644 --- a/apps/clock_info/metadata.json +++ b/apps/clock_info/metadata.json @@ -1,7 +1,7 @@ { "id": "clock_info", "name": "Clock Info Module", "shortName": "Clock Info", - "version":"0.14", + "version":"0.15", "description": "A library used by clocks to provide extra information on the clock face (Altitude, BPM, etc)", "icon": "app.png", "type": "module", From b4f405f1c95887a3b17c77e1cd259fa3f5199592 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 3 Feb 2025 12:17:39 +0000 Subject: [PATCH 40/96] fix generator script --- apps/icons/gen/generate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/icons/gen/generate.js b/apps/icons/gen/generate.js index b91eedcdc..fd97a1ce9 100755 --- a/apps/icons/gen/generate.js +++ b/apps/icons/gen/generate.js @@ -7,7 +7,7 @@ /* eslint-env node */ -var imageconverter = require("../../../webtools/imageconverter.js").imageconverter; +var imageconverter = require("../../../webtools/imageconverter.js"); var icons = JSON.parse(require("fs").readFileSync(__dirname+"/icon_names.json")); const imgOptions = { mode : "1bit", From dbbc9886c9b918e8930f004c8ec95f99eb26a41b Mon Sep 17 00:00:00 2001 From: Randy Heydon Date: Tue, 28 Jan 2025 20:37:58 -0500 Subject: [PATCH 41/96] calendar: read events synchronized from Gadgetbridge This is a partial fix for feature request #3707. This allows synchronized events (stored in android.calendar.json) to be shown in the app, alongside the manually entered events and alarm events that are already shown. Note only date/time and event title are currently used; other information available in the synchronized events (e.g. duration, description) are ignored. --- apps/calendar/ChangeLog | 1 + apps/calendar/calendar.js | 6 ++++++ apps/calendar/metadata.json | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/calendar/ChangeLog b/apps/calendar/ChangeLog index 9a4f81491..d737ec6d4 100644 --- a/apps/calendar/ChangeLog +++ b/apps/calendar/ChangeLog @@ -19,3 +19,4 @@ Display Widgets in menus 0.17: Load holidays before events so the latter is not overpainted 0.18: Minor code improvements +0.19: Read events synchronized from Gadgetbridge diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js index e140ff576..da5a00a6e 100644 --- a/apps/calendar/calendar.js +++ b/apps/calendar/calendar.js @@ -60,6 +60,12 @@ const loadEvents = () => { date.setSeconds(time.s); return {date: date, msg: a.msg, type: "e"}; })); + // all events synchronized from Gadgetbridge + events = events.concat((require("Storage").readJSON("android.calendar.json",1) || []).map(a => { + // timestamp is in seconds, Date requires milliseconds + const date = new Date(a.timestamp * 1000); + return {date: date, msg: a.title, type: "e"}; + })); }; const loadSettings = () => { diff --git a/apps/calendar/metadata.json b/apps/calendar/metadata.json index 468bceabb..5f5f21b27 100644 --- a/apps/calendar/metadata.json +++ b/apps/calendar/metadata.json @@ -1,7 +1,7 @@ { "id": "calendar", "name": "Calendar", - "version": "0.18", + "version": "0.19", "description": "Monthly calendar, displays holidays uploaded from the web interface and scheduled events.", "icon": "calendar.png", "screenshots": [{"url":"screenshot_calendar.png"}], From 77cebe31780a6a03467e95847c220dd46632755d Mon Sep 17 00:00:00 2001 From: Randy Heydon Date: Wed, 29 Jan 2025 19:30:43 -0500 Subject: [PATCH 42/96] Fix lint warnings. Loop variables had warnings for being undefinied. Added the "let" keyword where they are initialized. --- apps/calendar/calendar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js index da5a00a6e..ea06b70e8 100644 --- a/apps/calendar/calendar.js +++ b/apps/calendar/calendar.js @@ -227,8 +227,8 @@ const drawCalendar = function(date) { }, []); let i = 0; g.setFont("8x12", fontSize); - for (y = 0; y < rowN - 1; y++) { - for (x = 0; x < colN; x++) { + for (let y = 0; y < rowN - 1; y++) { + for (let x = 0; x < colN; x++) { i++; const day = days[i]; const curMonth = day < 15 ? month+1 : day < 50 ? month-1 : month; From c307f1f76044bfb8ef8b798836172b83e6228510 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 4 Feb 2025 11:44:41 +0000 Subject: [PATCH 43/96] fix broken messagesoverlay metadata file --- apps/messagesoverlay/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/messagesoverlay/metadata.json b/apps/messagesoverlay/metadata.json index 26095eb33..ba5f005c3 100644 --- a/apps/messagesoverlay/metadata.json +++ b/apps/messagesoverlay/metadata.json @@ -15,6 +15,6 @@ {"name":"messagesoverlay.settings.js","url":"settings.js"}, {"name":"messagesoverlay.default.json","url":"default.json"} ], - "data": [{"name":"bthrm.json"}], + "data":[{"name":"messagesoverlay.json"}], "screenshots": [{"url":"screen_call.png"} ,{"url":"screen_message.png"} ] } From 0c0498886cc8c23d025faef4cecd409f7fbea493 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 4 Feb 2025 12:23:03 +0000 Subject: [PATCH 44/96] handle 'defaultconfig' app type for default configurations --- README.md | 1 + apps/confthyttan/README.md | 7 ++----- apps/confthyttan/metadata.json | 5 ++--- bin/sanitycheck.js | 11 ++++++++--- core | 2 +- typescript/types/info.d.ts | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ddcf23f25..13da10b0a 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,7 @@ and which gives information about the app for the Launcher. // 'notify' - provides 'notify' library for showing notifications // 'locale' - provides 'locale' library for language-specific date/distance/etc // (a version of 'locale' is included in the firmware) + // 'defaultconfig' - a set of apps that will can be installed and will wipe out all previously installed apps "tags": "", // comma separated tag list for searching // common types are: // 'clock' - it's a clock diff --git a/apps/confthyttan/README.md b/apps/confthyttan/README.md index 5f7819171..e9b952c82 100644 --- a/apps/confthyttan/README.md +++ b/apps/confthyttan/README.md @@ -7,11 +7,8 @@ A different default set of apps and configurations. Brings many quality of life Before installing do this: 1. Backup your current setup (via the "More..." tab of the App Loader) so you can restore it later if you want. -2. Factory reset the watch. -3. Remove all apps via the "More..." tab in the App Loader. -4. Make sure minification is turned off on the App Loader. -5. Then install. -6. Try it out, switch out apps to your favorites and tweak to your liking! +2. Install this app (you'll be prompted about all data being removed from your Bangle) +3. Try it out, switch out apps to your favorites and tweak to your liking! ## Features diff --git a/apps/confthyttan/metadata.json b/apps/confthyttan/metadata.json index c706d45f5..5fd18c7e9 100644 --- a/apps/confthyttan/metadata.json +++ b/apps/confthyttan/metadata.json @@ -3,8 +3,8 @@ "version":"0.06", "description": "A different default set of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.", "icon": "app.png", - "type": "RAM", - "tags": "system, configuration, config, anotherconfig, thyttan", + "type": "defaultconfig", + "tags": "system,configuration,config,anotherconfig,thyttan", "supports" : ["BANGLEJS2"], "readme": "README.md", "dependencies" : { @@ -13,7 +13,6 @@ "messageicons":"app", "widmsggrid":"app", "msgwakefup":"app", - "msgtwscr":"app", "delaylock":"app", "notify":"app", "health":"app", diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index 086c2e551..80f8abe24 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -169,7 +169,7 @@ const APP_KEYS = [ const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'supports', 'noOverwrite']; const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate']; const SUPPORTS_DEVICES = ["BANGLEJS","BANGLEJS2"]; // device IDs allowed for 'supports' -const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","scheduler","notify","locale","settings","textinput","module","clkinfo"]; // values allowed for "type" field +const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","scheduler","notify","locale","settings","textinput","module","clkinfo","defaultconfig"]; // values allowed for "type" field - listed in README.md const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info const VALID_DUPLICATES = [ '.tfmodel', '.tfnames' ]; const GRANDFATHERED_ICONS = ["s7clk", "snek", "astral", "alpinenav", "slomoclock", "arrow", "pebble", "rebble"]; @@ -207,6 +207,10 @@ apps.forEach((app,appIdx) => { if (!app.name) ERROR(`App ${app.id} has no name`, {file:metadataFile}); var isApp = !app.type || app.type=="app"; var appTags = app.tags ? app.tags.split(",") : []; + /*if (appTags.some(tag => tag!=tag.trim())) + WARN(`App ${app.id} 'tag' list contains whitespace ("${app.tags}")`, {file:metadataFile}); + if (appTags.some(tag => tag!=tag.toLowerCase())) + WARN(`App ${app.id} 'tag' list contains uppercase ("${app.tags}")`, {file:metadataFile});*/ if (app.name.length>20 && !app.shortName && isApp) ERROR(`App ${app.id} has a long name, but no shortName`, {file:metadataFile}); if (app.type && !METADATA_TYPES.includes(app.type)) ERROR(`App ${app.id} 'type' is one one of `+METADATA_TYPES, {file:metadataFile}); @@ -296,7 +300,8 @@ apps.forEach((app,appIdx) => { if (INTERNAL_FILES_IN_APP_TYPE[app.type].includes(file.name)) fileInternal = true; } - allFiles.push({app: app.id, file: file.name, internal:fileInternal}); + if (!app.type=="defaultconfig") + allFiles.push({app: app.id, file: file.name, internal:fileInternal}); if (file.url) if (!fs.existsSync(appDir+file.url)) ERROR(`App ${app.id} file ${file.url} doesn't exist`, {file:metadataFile}); if (!file.url && !file.content && !app.custom) ERROR(`App ${app.id} file ${file.name} has no contents`, {file:metadataFile}); var fileContents = ""; @@ -494,7 +499,7 @@ while(fileA=allFiles.pop()) { if (isGlob(nameA)||isGlob(nameB)) ERROR(`App ${fileB.app} ${typeB} file ${nameB} matches app ${fileA.app} ${typeB} file ${nameA}`); else if (fileA.app != fileB.app && (!fileA.internal) && (!fileB.internal)) - WARN(`App ${fileB.app} ${typeB} file ${nameB} is also listed as ${typeA} file for app ${fileA.app}`); + WARN(`App ${fileB.app} ${typeB} file ${nameB} is also listed as ${typeA} file for app ${fileA.app}`, {file:APPSDIR_RELATIVE+fileB.app+"/metadata.json"}); } }) } diff --git a/core b/core index bf08b4848..3ec8e289a 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit bf08b484830ef4e811faf67ec663ebf839b5d09b +Subproject commit 3ec8e289a26a545d0d0c50f6945978584fb3d7f8 diff --git a/typescript/types/info.d.ts b/typescript/types/info.d.ts index c305b0261..21014ff8f 100644 --- a/typescript/types/info.d.ts +++ b/typescript/types/info.d.ts @@ -14,4 +14,4 @@ type AppInfo = { type AppType = "app" | "clock" | "widget" | "module" | "bootloader" | "settings" | "clkinfo" | "RAM" | "launch" | "textinput" | "scheduler" | - "notify" | "locale"; + "notify" | "locale" | "defaultconfig"; From 9b224171e175084f515585266a748a40d6154d85 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 4 Feb 2025 12:38:56 +0000 Subject: [PATCH 45/96] Fix up app metadata - spaces/uppercase in tags meant these apps wouldn't have appeared in some searches --- README.md | 2 +- apps/UI4swatch/metadata.json | 2 +- apps/Uke/metadata.json | 4 ++-- apps/bblobface/metadata.json | 2 +- apps/beeptest/metadata.json | 2 +- apps/bordle/metadata.json | 2 +- apps/calclock/metadata.json | 2 +- apps/cassioWatch/metadata.json | 2 +- apps/chronlog/metadata.json | 2 +- apps/color_catalog/metadata.json | 2 +- apps/delaylock/metadata.json | 2 +- apps/dinoClock/metadata.json | 2 +- apps/followtherecipe/metadata.json | 2 +- apps/gassist/metadata.json | 2 +- apps/gbdiscon/metadata.json | 2 +- apps/golfview/metadata.json | 4 ++-- apps/guitar/metadata.json | 4 ++-- apps/guitarsongs/metadata.json | 2 +- apps/intervalTimer/metadata.json | 2 +- apps/kanagsec/metadata.json | 12 ++++++------ apps/ohmcalc/metadata.json | 2 +- apps/pastel/metadata.json | 2 +- apps/poweroff/metadata.json | 2 +- apps/quicklaunch/metadata.json | 2 +- apps/rescalc/metadata.json | 2 +- apps/scribble/metadata.json | 2 +- apps/sevenmin/metadata.json | 2 +- apps/spaceclock/metadata.json | 4 ++-- apps/swiperclocklaunch/metadata.json | 2 +- apps/tabanchi/metadata.json | 2 +- apps/testuserinput/metadata.json | 2 +- apps/timestamplog/metadata.json | 2 +- apps/tinydraw/metadata.json | 2 +- apps/weatherClock/metadata.json | 2 +- apps/widscrlock/metadata.json | 4 ++-- bin/sanitycheck.js | 4 ++-- 36 files changed, 47 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 13da10b0a..b9b770b37 100644 --- a/README.md +++ b/README.md @@ -271,7 +271,7 @@ and which gives information about the app for the Launcher. // 'locale' - provides 'locale' library for language-specific date/distance/etc // (a version of 'locale' is included in the firmware) // 'defaultconfig' - a set of apps that will can be installed and will wipe out all previously installed apps - "tags": "", // comma separated tag list for searching + "tags": "", // comma separated tag list for searching (don't include uppercase or spaces) // common types are: // 'clock' - it's a clock // 'widget' - it is (or provides) a widget diff --git a/apps/UI4swatch/metadata.json b/apps/UI4swatch/metadata.json index bcb0e6c51..5b4abf406 100644 --- a/apps/UI4swatch/metadata.json +++ b/apps/UI4swatch/metadata.json @@ -5,7 +5,7 @@ "version": "0.02", "description": "A UI/UX for espruino smartwatches, displays dinamically calc. x,y coordinates.", "icon": "app.png", - "tags": "Color,input,buttons,touch,UI", + "tags": "color,input,buttons,touch,ui", "supports": ["BANGLEJS"], "readme": "README.md", "screenshots": [{"url":"UI4swatch_icon.png"},{"url":"UI4swatch_s1.png"}], diff --git a/apps/Uke/metadata.json b/apps/Uke/metadata.json index 5a3f17639..1185c7202 100644 --- a/apps/Uke/metadata.json +++ b/apps/Uke/metadata.json @@ -4,8 +4,8 @@ "version": "0.04", "description": "Wrist mounted ukulele chords", "icon": "app.png", - "tags": "uke, chords", - "supports" : ["BANGLEJS2"], + "tags": "uke,chords", + "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ {"name":"Uke.app.js","url":"app.js"}, diff --git a/apps/bblobface/metadata.json b/apps/bblobface/metadata.json index 6af247c91..8393755b0 100644 --- a/apps/bblobface/metadata.json +++ b/apps/bblobface/metadata.json @@ -6,7 +6,7 @@ "description": "A fully featured watch face with a playable game on the side.", "readme":"README.md", "type": "clock", - "tags": "clock, game", + "tags": "clock,game", "supports" : ["BANGLEJS2"], "storage": [ {"name":"bblobface.app.js","url":"app.js"}, diff --git a/apps/beeptest/metadata.json b/apps/beeptest/metadata.json index a9856bc93..7c25a3848 100644 --- a/apps/beeptest/metadata.json +++ b/apps/beeptest/metadata.json @@ -5,7 +5,7 @@ "version": "0.01", "description": "Aerobic fitness test created by LĆ©ger & Lambert", "icon": "beeptest.png", - "tags": "Health", + "tags": "health", "supports": ["BANGLEJS2"], "readme": "README.md", "storage": [ diff --git a/apps/bordle/metadata.json b/apps/bordle/metadata.json index f6011f798..0dbcf09f9 100644 --- a/apps/bordle/metadata.json +++ b/apps/bordle/metadata.json @@ -6,7 +6,7 @@ "description": "Bangle version of a popular word search game", "supports" : ["BANGLEJS2"], "readme": "README.md", - "tags": "game, text", + "tags": "game,text", "storage": [ {"name":"bordle.app.js","url":"bordle.app.js"}, {"name":"wordlencr.txt","url":"wordlencr.txt"}, diff --git a/apps/calclock/metadata.json b/apps/calclock/metadata.json index c339e8ce0..31dcb88d0 100644 --- a/apps/calclock/metadata.json +++ b/apps/calclock/metadata.json @@ -6,7 +6,7 @@ "description": "Show the current and upcoming events synchronized from Gadgetbridge", "icon": "calclock.png", "type": "clock", - "tags": "clock agenda", + "tags": "clock,agenda", "supports": ["BANGLEJS2"], "readme": "README.md", "storage": [ diff --git a/apps/cassioWatch/metadata.json b/apps/cassioWatch/metadata.json index fb7dfd401..5ec12e751 100644 --- a/apps/cassioWatch/metadata.json +++ b/apps/cassioWatch/metadata.json @@ -6,7 +6,7 @@ "icon": "app.png", "version": "0.13", "type": "clock", - "tags": "clock, weather, cassio, retro", + "tags": "clock,weather,cassio,retro", "supports": ["BANGLEJS2"], "allow_emulator": true, "readme": "README.md", diff --git a/apps/chronlog/metadata.json b/apps/chronlog/metadata.json index 8ed618b27..50a9166bf 100644 --- a/apps/chronlog/metadata.json +++ b/apps/chronlog/metadata.json @@ -3,7 +3,7 @@ "version":"0.01", "description": "Record time active on a task, course, work or anything really.", "icon": "app.png", - "tags": "logging, record, work, tasks", + "tags": "logging,record,work,tasks", "supports" : ["BANGLEJS2"], "readme": "README.md", "screenshots" : [ { "url":"dump.png"}, { "url":"dump1.png" }, { "url":"dump2.png" }, { "url":"dump3.png" }, { "url":"dump4.png" }, { "url":"dump5.png" }, { "url":"dump6.png" } ], diff --git a/apps/color_catalog/metadata.json b/apps/color_catalog/metadata.json index 4d49308ef..e445e3175 100644 --- a/apps/color_catalog/metadata.json +++ b/apps/color_catalog/metadata.json @@ -5,7 +5,7 @@ "version": "0.03", "description": "Displays RGB565 and RGB888 colors, its name and code in screen.", "icon": "app.png", - "tags": "Color,input,buttons,touch,UI", + "tags": "color,input,buttons,touch,ui", "supports": ["BANGLEJS"], "readme": "README.md", "storage": [ diff --git a/apps/delaylock/metadata.json b/apps/delaylock/metadata.json index dff4d9219..7441d822b 100644 --- a/apps/delaylock/metadata.json +++ b/apps/delaylock/metadata.json @@ -3,7 +3,7 @@ "version":"0.01", "description": "Delay the locking of the screen to 5 seconds after the backlight turns off.", "icon": "app.png", - "tags": "settings, configuration, backlight, touchscreen, screen", + "tags": "settings,configuration,backlight,touchscreen,screen", "type": "bootloader", "supports" : ["BANGLEJS2"], "readme": "README.md", diff --git a/apps/dinoClock/metadata.json b/apps/dinoClock/metadata.json index a61ce122b..1455e84a6 100644 --- a/apps/dinoClock/metadata.json +++ b/apps/dinoClock/metadata.json @@ -6,7 +6,7 @@ "icon": "app.png", "version": "0.01", "type": "clock", - "tags": "clock, weather, dino, trex, chrome", + "tags": "clock,weather,dino,trex,chrome", "supports": ["BANGLEJS2"], "allow_emulator": true, "readme": "README.md", diff --git a/apps/followtherecipe/metadata.json b/apps/followtherecipe/metadata.json index 0c1de0817..59fabc8c5 100644 --- a/apps/followtherecipe/metadata.json +++ b/apps/followtherecipe/metadata.json @@ -6,7 +6,7 @@ "version": "0.02", "description": "Follow The Recipe (FTR) is a bangle.js app to follow a recipe step by step", "type": "app", - "tags": "tool, tools, cook", + "tags": "tool,tools,cook", "supports": [ "BANGLEJS2" ], diff --git a/apps/gassist/metadata.json b/apps/gassist/metadata.json index 995c44adb..bd38cdfb8 100644 --- a/apps/gassist/metadata.json +++ b/apps/gassist/metadata.json @@ -5,7 +5,7 @@ "description": "A simple way to initiate Google Assistant on Android. Intents must be enabled in Gadgetbridge.", "icon": "app.png", "type": "app", - "tags": "tool, voice, tasker", + "tags": "tool,voice,tasker", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": false, "storage": [ diff --git a/apps/gbdiscon/metadata.json b/apps/gbdiscon/metadata.json index ecc92d01c..904b4c6a2 100644 --- a/apps/gbdiscon/metadata.json +++ b/apps/gbdiscon/metadata.json @@ -4,7 +4,7 @@ "version":"0.01", "description": "Disconnect from your android device by running this app. The app will forward you to your clock face immediately after triggering the command. (Gadgetbridge nightly required until version 82 is released)", "icon": "app.png", - "tags": "android, gadgetbridge, bluetooth, bt", + "tags": "android,gadgetbridge,bluetooth,bt", "supports" : ["BANGLEJS", "BANGLEJS2"], "storage": [ {"name":"gbdiscon.app.js","url":"app.js"}, diff --git a/apps/golfview/metadata.json b/apps/golfview/metadata.json index bc3a00f90..cf77f3a26 100644 --- a/apps/golfview/metadata.json +++ b/apps/golfview/metadata.json @@ -3,9 +3,9 @@ "version": "0.03", "description": "This app will provide you with on course data to support your golf game!", "icon": "golfview.png", - "tags": "outdoors, gps", + "tags": "outdoors,gps", "allow_emulator": true, - "supports" : ["BANGLEJS2"], + "supports" : ["BANGLEJS2"], "readme": "README.md", "custom": "custom.html", "storage": [ diff --git a/apps/guitar/metadata.json b/apps/guitar/metadata.json index 0dc6893d6..7b4683c47 100644 --- a/apps/guitar/metadata.json +++ b/apps/guitar/metadata.json @@ -4,8 +4,8 @@ "version": "0.03", "description": "Wrist mounted guitar chords", "icon": "app.png", - "tags": "guitar, chords", - "supports" : ["BANGLEJS2"], + "tags": "guitar,chords", + "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ {"name":"guitar.app.js","url":"app.js"}, diff --git a/apps/guitarsongs/metadata.json b/apps/guitarsongs/metadata.json index 242850a70..18e1f7146 100644 --- a/apps/guitarsongs/metadata.json +++ b/apps/guitarsongs/metadata.json @@ -5,7 +5,7 @@ "description": "Songs lyrics and guitar chords", "icon": "app.png", "screenshots": [{"url": "screenshot.png"}], - "tags": "guitar, song, lyrics, chords", + "tags": "guitar,song,lyrics,chords", "supports" : ["BANGLEJS2"], "interface": "manage_songs.html", "readme": "README.md", diff --git a/apps/intervalTimer/metadata.json b/apps/intervalTimer/metadata.json index 2722473c1..a0489833c 100644 --- a/apps/intervalTimer/metadata.json +++ b/apps/intervalTimer/metadata.json @@ -5,7 +5,7 @@ "icon": "app.png", "version":"0.01", "description": "Interval Timer for workouts, HIIT, or whatever else.", - "tags": "timer, interval, hiit, workout", + "tags": "timer,interval,hiit,workout", "readme":"README.md", "supports":["BANGLEJS2"], "storage": [ diff --git a/apps/kanagsec/metadata.json b/apps/kanagsec/metadata.json index c00ec9d7a..2e3376c5b 100644 --- a/apps/kanagsec/metadata.json +++ b/apps/kanagsec/metadata.json @@ -1,23 +1,23 @@ -{ +{ "id": "kanagsec", "name": "Kanagawa clock", "shortName":"kanagawa", "version": "0.04", "description": "A clock that displays the great wave of kanagawa (image from wikipedia) with seconds in active mode.", "icon": "app.png", - "tags": "clock, kanagawa, wave", + "tags": "clock,kanagawa,wave", "type": "clock", - "supports" : ["BANGLEJS2"], + "supports" : ["BANGLEJS2"], "readme": "README.md", "allow_emulator":true, - "storage": + "storage": [ {"name":"kanagsec.app.js","url":"app.js"}, {"name":"kanagsec.img","url":"app-icon.js","evaluate":true} ], - "screenshots" : + "screenshots" : [ { "url":"screenshot.png" }, - { "url":"screenshot2.png" } + { "url":"screenshot2.png" } ] } \ No newline at end of file diff --git a/apps/ohmcalc/metadata.json b/apps/ohmcalc/metadata.json index c72727a4c..2ab25947f 100644 --- a/apps/ohmcalc/metadata.json +++ b/apps/ohmcalc/metadata.json @@ -6,7 +6,7 @@ "description": "A smart and simple calculator for Ohm's Law calculations, designed specifically for Bangle.js 2 smartwatches. Handles voltage, current, resistance, and power calculations with smart logic to prevent invalid inputs.", "icon": "app.png", "type": "app", - "tags": "calculator, utilities, electric", + "tags": "calculator,utilities,electric", "supports": ["BANGLEJS2"], "readme": "README.md", "allow_emulator": true, diff --git a/apps/pastel/metadata.json b/apps/pastel/metadata.json index 532aa8ccc..5d1f925fe 100644 --- a/apps/pastel/metadata.json +++ b/apps/pastel/metadata.json @@ -8,7 +8,7 @@ "dependencies": {"mylocation":"app","weather":"app"}, "screenshots": [{"url":"screenshot_pastel.png"}, {"url":"weather_icons.png"}], "type": "clock", - "tags": "clock, weather, tool", + "tags": "clock,weather,tool", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "storage": [ diff --git a/apps/poweroff/metadata.json b/apps/poweroff/metadata.json index 218e4b441..b9a7d60ea 100644 --- a/apps/poweroff/metadata.json +++ b/apps/poweroff/metadata.json @@ -4,7 +4,7 @@ "version": "0.05", "description": "Simple app to power off your Bangle.js", "icon": "app.png", -"tags": "tool, poweroff, shutdown", +"tags": "tool,poweroff,shutdown", "supports" : ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "allow_emulator": true, diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index 15c40dfdc..95ae0b014 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -5,7 +5,7 @@ "version": "0.16", "description": "Tap or swipe left/right/up/down on your clock face to launch up to five apps of your choice. Configurations can be accessed through Settings->Apps.", "type": "bootloader", - "tags": "tools, system", + "tags": "tools,system", "readme": "README.md", "supports": ["BANGLEJS2"], "storage": [ diff --git a/apps/rescalc/metadata.json b/apps/rescalc/metadata.json index cd2b7ea31..f7f7c5e29 100644 --- a/apps/rescalc/metadata.json +++ b/apps/rescalc/metadata.json @@ -10,7 +10,7 @@ {"url": "screenshot-2.png"} ], "description": "An intuitive, easy-to-use app that aids in the interpretation of resistor color codes and calculation of resistance values.", - "tags": "app, tool, electricity, ohms, converter", + "tags": "app,tool,electricity,ohms,converter", "supports": ["BANGLEJS2"], "readme": "README.md", "allow_emulator": true, diff --git a/apps/scribble/metadata.json b/apps/scribble/metadata.json index 2c31be931..19c6c707c 100644 --- a/apps/scribble/metadata.json +++ b/apps/scribble/metadata.json @@ -6,7 +6,7 @@ "description": "A keyboard on your wrist! Swipe right for space, left for delete.", "icon": "app.png", "allow_emulator": true, - "tags": "tools, keyboard, text, scribble", + "tags": "tools,keyboard,text,scribble", "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ diff --git a/apps/sevenmin/metadata.json b/apps/sevenmin/metadata.json index 5103a5f97..8a1867e4a 100644 --- a/apps/sevenmin/metadata.json +++ b/apps/sevenmin/metadata.json @@ -5,7 +5,7 @@ "description": "A basic implementation of the famous consice workout", "icon": "icon.png", "type":"app", - "tags": "Training, Workout", + "tags": "training,workout", "supports": ["BANGLEJS2"], "readme": "README.md", "allow_emulator":true, diff --git a/apps/spaceclock/metadata.json b/apps/spaceclock/metadata.json index 1e8bc266f..cff458d08 100644 --- a/apps/spaceclock/metadata.json +++ b/apps/spaceclock/metadata.json @@ -5,8 +5,8 @@ "description": "Watch face in the style of Casio Prototype Space Resist", "icon": "app-icon.png", "type": "clock", - "tags": "clock, casio, retro", - "supports" : ["BANGLEJS2"], + "tags": "clock,casio,retro", + "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ {"name":"spaceclock.app.js","url":"app.js"}, diff --git a/apps/swiperclocklaunch/metadata.json b/apps/swiperclocklaunch/metadata.json index d474b38e3..6bb24987e 100644 --- a/apps/swiperclocklaunch/metadata.json +++ b/apps/swiperclocklaunch/metadata.json @@ -5,7 +5,7 @@ "description": "Navigate between clock and launcher with Swipe action", "icon": "swiperclocklaunch.png", "type": "bootloader", - "tags": "tools, system", + "tags": "tools,system", "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ {"name":"swiperclocklaunch.boot.js","url":"boot.js"}, diff --git a/apps/tabanchi/metadata.json b/apps/tabanchi/metadata.json index db81707b5..43ebc62ac 100644 --- a/apps/tabanchi/metadata.json +++ b/apps/tabanchi/metadata.json @@ -7,7 +7,7 @@ "description": "Tamagotchi WatchApp", "icon": "app.png", "allow_emulator": true, - "tags": "clock, watch, virtual pet", + "tags": "clock,watch,virtualpet", "supports": [ "BANGLEJS2" ], diff --git a/apps/testuserinput/metadata.json b/apps/testuserinput/metadata.json index 409843198..39fab86af 100644 --- a/apps/testuserinput/metadata.json +++ b/apps/testuserinput/metadata.json @@ -5,7 +5,7 @@ "version": "0.08", "description": "App to test the bangle.js input interface. It displays the user action in text, circle buttons or on/off switch UI elements.", "icon": "app.png", - "tags": "input,interface,buttons,touch,UI", + "tags": "input,interface,buttons,touch,ui", "supports": ["BANGLEJS"], "readme": "README.md", "storage": [ diff --git a/apps/timestamplog/metadata.json b/apps/timestamplog/metadata.json index e1aa0eb23..6f0126c4a 100644 --- a/apps/timestamplog/metadata.json +++ b/apps/timestamplog/metadata.json @@ -7,7 +7,7 @@ "description": "Conveniently record a series of date/time stamps", "screenshots": [ {"url": "screenshot.png" } ], "readme": "README.md", - "tags": "timestamp, log", + "tags": "timestamp,log", "supports": ["BANGLEJS2"], "interface": "interface.html", "storage": [ diff --git a/apps/tinydraw/metadata.json b/apps/tinydraw/metadata.json index 21ea1eb89..61f4129e8 100644 --- a/apps/tinydraw/metadata.json +++ b/apps/tinydraw/metadata.json @@ -6,7 +6,7 @@ "description": "Draw stuff in your wrist", "icon": "app.png", "allow_emulator": true, - "tags": "tools, keyboard, text, scribble", + "tags": "tools,keyboard,text,scribble", "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ diff --git a/apps/weatherClock/metadata.json b/apps/weatherClock/metadata.json index 88057c8dd..b1b586a21 100644 --- a/apps/weatherClock/metadata.json +++ b/apps/weatherClock/metadata.json @@ -8,7 +8,7 @@ "dependencies": {"weather":"app"}, "screenshots": [{"url":"screens/screen1.png"}], "type": "clock", - "tags": "clock, weather", + "tags": "clock,weather", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, "readme": "README.md", diff --git a/apps/widscrlock/metadata.json b/apps/widscrlock/metadata.json index 5110d76c1..568c61b93 100644 --- a/apps/widscrlock/metadata.json +++ b/apps/widscrlock/metadata.json @@ -3,9 +3,9 @@ "shortName":"Screenlock", "version":"0.03", "description": "Lock a Bangle 2 screen by tapping a widget.", - "icon": "widget.png", + "icon": "widget.png", "type": "widget", - "tags": "widget, screenlock", + "tags": "widget,screenlock", "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index 80f8abe24..5432999eb 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -207,10 +207,10 @@ apps.forEach((app,appIdx) => { if (!app.name) ERROR(`App ${app.id} has no name`, {file:metadataFile}); var isApp = !app.type || app.type=="app"; var appTags = app.tags ? app.tags.split(",") : []; - /*if (appTags.some(tag => tag!=tag.trim())) + if (appTags.some(tag => tag!=tag.trim())) WARN(`App ${app.id} 'tag' list contains whitespace ("${app.tags}")`, {file:metadataFile}); if (appTags.some(tag => tag!=tag.toLowerCase())) - WARN(`App ${app.id} 'tag' list contains uppercase ("${app.tags}")`, {file:metadataFile});*/ + WARN(`App ${app.id} 'tag' list contains uppercase ("${app.tags}")`, {file:metadataFile}); if (app.name.length>20 && !app.shortName && isApp) ERROR(`App ${app.id} has a long name, but no shortName`, {file:metadataFile}); if (app.type && !METADATA_TYPES.includes(app.type)) ERROR(`App ${app.id} 'type' is one one of `+METADATA_TYPES, {file:metadataFile}); From f5e6842019a22cf3b14234921bb752984a01379d Mon Sep 17 00:00:00 2001 From: tonykakuuu Date: Tue, 4 Feb 2025 18:56:20 +0100 Subject: [PATCH 46/96] New app! --- apps/txtreader/ChangeLog | 1 + apps/txtreader/README.md | 20 ++++++ apps/txtreader/app-icon.js | 1 + apps/txtreader/app.js | 88 +++++++++++++++++++++++ apps/txtreader/metadata.json | 16 +++++ apps/txtreader/screenshot_txtreader.png | Bin 0 -> 7168 bytes apps/txtreader/txtreader.png | Bin 0 -> 1549 bytes apps/txtreader/txtreader_transparent.png | Bin 0 -> 1549 bytes 8 files changed, 126 insertions(+) create mode 100644 apps/txtreader/ChangeLog create mode 100644 apps/txtreader/README.md create mode 100644 apps/txtreader/app-icon.js create mode 100644 apps/txtreader/app.js create mode 100644 apps/txtreader/metadata.json create mode 100644 apps/txtreader/screenshot_txtreader.png create mode 100644 apps/txtreader/txtreader.png create mode 100644 apps/txtreader/txtreader_transparent.png diff --git a/apps/txtreader/ChangeLog b/apps/txtreader/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/txtreader/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/txtreader/README.md b/apps/txtreader/README.md new file mode 100644 index 000000000..1cede764c --- /dev/null +++ b/apps/txtreader/README.md @@ -0,0 +1,20 @@ +# txtreader + +Very basic text reader with an integrated file selector. + +## Features + +- select files from storage (.txt) +- display their contents +- browse pages + +## Controls + +Bangle.js 2 +- tap the right side of the screen to flip to the next page +- tap the left side of the screen to flip to the previous page +- exit by pressing the physical button + +## Creator + + diff --git a/apps/txtreader/app-icon.js b/apps/txtreader/app-icon.js new file mode 100644 index 000000000..a8c210baf --- /dev/null +++ b/apps/txtreader/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkCkQA/AH4A/AAcosd2m9jw04AQlyC5WL1e63YCG3lUC5WPj/x/8f+H/h4CBj/3jYXLv/3/4CCt4FC/IXM/4AI/YXk/WZzOfCgWfAoIXN/F3u9/C4V/AoIvUI6H3F4p3oC6/73e734XTR4wXQ/vd7vfC6f85gAG55HQAAppBC5n5xAAGz4vmzIAGF/33F49/C5v6F4+vC5rrFd6JHCv4XTI4WfF6lms1vF6mq1WvC6Z3WxfdABHVugXKlFUogAHoVCC5QA/AH4A6A")) \ No newline at end of file diff --git a/apps/txtreader/app.js b/apps/txtreader/app.js new file mode 100644 index 000000000..890b4254c --- /dev/null +++ b/apps/txtreader/app.js @@ -0,0 +1,88 @@ +function showFileSelector() { + let files = require("Storage").list().filter(f => f.endsWith('.txt')); + + let menuItems = {}; + files.forEach(file => { + menuItems[file] = () => { + E.showPrompt(`Select ${file}?`).then(confirm => { + if (confirm) { + onFileSelected(file); + } else { + showFileSelector(); + } + }); + }; + }); + + menuItems['< Back'] = () => { load(); }; // Go back to the launcher or previous screen + E.showMenu(menuItems); +} + +function onFileSelected(file) { + + var text = require("Storage").read(file); + + function displayText(text, startLine, pageNumber) { + g.clear(); + g.setFont("6x8", 1); + g.setColor(1); + g.drawString("Page " + pageNumber, 10, 2); + g.drawString(file, g.getWidth()-file.length*6, 2); + + var lines = text.split("\n"); + var y = 15; // Text start, top row reserved for page number + var currentLine = startLine || 0; + var linesDisplayed = 0; //Per page + + for (var i = currentLine; i < lines.length; i++) { + var wrappedLines = g.wrapString(lines[i], g.getWidth() - 20); + for (var j = 0; j < wrappedLines.length; j++) { + g.drawString(wrappedLines[j], 10, y); + y += 10; // Move down for the next line + linesDisplayed++; + if (y >= g.getHeight() - 10) { + // If we run out of space, stop drawing + return { nextStartLine: i , linesDisplayed: linesDisplayed }; + } + } + } + return null; // No more lines to display + } + + var currentStartLine = 0; + var currentPage = 1; + var history = []; // Track the start line and lines displayed for each page + + // Initial display + var result = displayText(text, currentStartLine, currentPage); + history.push({ startLine: currentStartLine, linesDisplayed: result.linesDisplayed }); + + // Handle touch events + Bangle.on('touch', function(button) { + if (button === 2) { // Right side of the screen (next page) + var nextStartLine = displayText(text, currentStartLine, currentPage + 1); + if (nextStartLine !== null) { + currentStartLine = nextStartLine.nextStartLine; + currentPage++; + history.push({ startLine: currentStartLine, linesDisplayed: nextStartLine.linesDisplayed }); + displayText(text, currentStartLine, currentPage); + } else { + currentStartLine = 0; + currentPage = 1; + history = [{ startLine: currentStartLine, linesDisplayed: result.linesDisplayed }]; + displayText(text, currentStartLine, currentPage); + } + } else if (button === 1) { // Left side of the screen (previous page) + if (currentPage > 1) { + // Go back to the previous page + history.pop(); // Remove the current page from history + var previousPage = history[history.length - 1]; + currentStartLine = previousPage.startLine; + currentPage--; + displayText(text, currentStartLine, currentPage); + } + } + }); +} + +showFileSelector(); \ No newline at end of file diff --git a/apps/txtreader/metadata.json b/apps/txtreader/metadata.json new file mode 100644 index 000000000..985b8e5ea --- /dev/null +++ b/apps/txtreader/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "txtreader", + "name": "txtreader", + "shortName": "txtreader", + "version": "0.01", + "description": "Basic text reader with pages and a file selector.", + "icon": "txtreader.png", + "screenshots": [{"url":"screenshot_txtreader.png"}], + "tags": "app,tool", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"txtreader.app.js","url":"app.js"}, + {"name":"txtreader.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/txtreader/screenshot_txtreader.png b/apps/txtreader/screenshot_txtreader.png new file mode 100644 index 0000000000000000000000000000000000000000..1b565024aa69b1dde87b3fe1fb703fdb8c007583 GIT binary patch literal 7168 zcmeHKcTiJ#*G2@vpr~|EF$SecNJt2TNJI=(2_Q`ZD-eUt)i&{xY~7s2w`*=dO+*j zGMmFQQ#(RloXV;)yb*7L4^qV}w{pq^y8WUWF2;6;bR4_oGuoK2^@&1q-GD->77XBI-j*VD~K%F+Jbo3rkU~Hp)4-2s=f* zg__urYEirWiPzLp1FvJV-)-`Ds{rq202QuhR8#cW<# z8VQOn*j~_&h|-)?;{Q~Y=B$`-I3FdWBV`#TT0IxC@@$$hS^4UAx`ZiT40Kp^IRRn4^~a1}JA3inPruE3?JzGa)3HH4|Mm4JLcdJ$5iIVws-#KWQIUXD ze3T8g7L_R#T;_i2b@+%4=0m-*9ovA#3e-gW`c(eiRBub~7yQeyX`z}F-@4OIR}XFb8j(9zLBAW;Yu3JzMpSwRdoIS|fZDXc<##V`O^6kobGo6clFS24-1Og}ar1_Slb zzw-0)CKA8HGg#kP0Qo=!lD!cc>PUo_7vg6R7TeGt1o@WGfAnD4fD?+a0$5BxUkYI8 z4=~sYKSNL{-~GM)d_C97p;8clC*TE|vcRYse+y}BO0@j$u}Xm(-OGE;3ncq*mTWrh z2U&m1ZB?^Y&d-T}?%#3$X8l*~YsR1zk%%*3Qv6oaGc~}&R^#KSObVTfTl=e{sg1;< zumGHjrfI`9DQF5D3m~=NNLLJ5TbqW$(x}v*piCJoHkm;IR-r&}bvlTHa;2du6r=_m zN!0)$kTear4h;lDX#uWS9SsbiL3RBJ!orshb|u;K=d4zts34S<78RkQ1FBMs|QN3+%*IObw(u zT5Cwn031cp zp}{rDWDHyfg+;@)H89$m7)`Ve#TC28!gq8Qlg17p`vUrIAdetdV0*4{1yx=PrvMTLN21_A2-EsT7~)&Oh}E6(SH-%B|HX;!n!!&?2K4(X1D6-L3lZO!;Wy5} zeE*xTZ)fq}3;~7y8{{AH`!8Mp()EuR_(#V7cGtgj{UZkck@3IX_5Vf}Fo*Olaj8_@K4H^@yJJqKb@`?S`Zj@GlgHb{USowlaZ4-CEqLJi4C%b#<V9jy)j7r^kwpME&BLS-^l`Yn_jxb zlUclJ%cj!2uqE5<>2ya3*NS7X`^+?JaYQw~^ZJV4RNu-MCu8p7$3>oxr3m-RMGWGI z)HE)z_Kb1ghm!5RL^<2KaeiAHr`Ase+_wE&j@)zH(u+2?NSg>MKD~1C^WyZ=!E$3b zF@DQvu%)fu;L)%Jx#&pD;ncdTgGeW^HY2A=S&L`i>mYtk``-tlR;^vf4v(pSTCZU>&f zwYA717E0AOxBwND5>P3Gnw%3m2bpDWKbGs<_s)F>t2 z6jwCfome&$?&cN-gET37cE8TONuf%IPSvMX|FO{&(ruM^v?j`nP7=I%()p6v1#|oU zLk1EquV99W8Kh@tmTHCec{f@CQRS5}ZgmQ=l8Jy0-fsh^IySF6UpCT0i=edW)MT0o zwGM$7irIs@T?!6C$B}c5uhv0_uH{|dQt1-0PE9QA?uRAkKaJ`Z(@Mh$zFbauakk1W z-cxvP?r7~OHqDPxBu5w-+PO0I*j^_lZsZyr+27?Jmy%nuV(gfFx^~gddcMfCczAm~ zhN6*(mO1!q){bUdwX5P6m&tG=&&=)|_<_vZBb85>oheugA&VmW9gPL2en+`|?>d`f&B;M<^x}9PPiLmP6HTJi+)~=m+c*8@@Qm*kzCfYXr%Ta%zvu43C97I1 z^OQpL^XD6_`bR~JtT1&EN6#lwXnB(R0Ya+D;7&W+kW%Xw;rkaHcCta8Ja92+`|9{b_~pVLIkax8fjo{zTB1M3ZA?}vyhxrwIk@M` zRvyffyDcH}-kGF%({~`$M({ybTC}py{Dc53Q*Aax@=^7{o}oBH-y64@dTjr+-8|db z5fT29Mm+n=r4z9)AjiPgO3A6h(z_-&L&qac_4-}RJTedzO)YRXB(ZkW6D>OtY~_U3Sc=waI?dvmve(z5ZUlOiJrO;anmTg8=9 z@+vag1@oM|I=2aEYCTy$-r*`nGLxN4@js%-#ha-vmFU;K)1-MlC@OIdF`3@vAaS0A zzw*pJNc)6T#`7zg4t<*3xd@wUYW2^H6BA6Fkw)pocLfhFKf5_gMPG;qN<@63?8+ml zU7oeifki<|HTu|xHgru}=>|#c>xWsxms=8fo{hHmREH%5<=;+oIhW+`)O&k{o@8kQ5KKo35R5e9gT)@{34a65M8uT!=Q0tYXq^UQNg-&h$IcOfyn=v3j z7E+E>1b6zM?t<^%984_|Z>0RPQH~l);=!V~uCKI`-$w`<-guwOnMXzg2w z8f?%zg^_-{q7p5ccy0d!)))Js6Y&<|o}rS7GxV;{b9W}IIHgaS_lm2^{9~AgN~LWO zL`Y4xSU4)Um-wNkfIqfQf((%N}?@_@7hRL&K8$?9d8>83$R0U2~Bb~PqIeHRa0+v+3MDu zO6Sw?sZT%Mekzt<wvAQy8^GR!d0;gZgDZSX$Oxbv=Y3CDBE~(!n`sQL2rm_gdOJAxEJ$&SNf%C2xJqso+ z(pG!LCf!Dgacu_zMsYXhA`T!tKIi#xCPv-$o@oj?y=~N}IXac>+}Rd*VE=e&5r090 zK4E&?Pm;rBD3xDX2y@VJPT11KSUjQOk@kfV?|12a^4#h8qved-D?7((Po_yX6umzk zldG4kArZIEULvMiN>NW+rSRK!%vRSQQa%@LeE6K;x&m`qa&Bzu;^=VW)y4~`!?NQP zuMNgI!5kR^`%|98BOy(mXM0kI=dcGmSQpW6Qf%>NZ}&p3@8f~fy)A|c2qVmjcwTAe)M4aQ+CQGUWRLa5-e#WWCFP1P@eu)5t{W$IYU}jXbGPafxA8)U{lAQ{-B%N9wQN7MhBG5b=A}wIJAM9xT#+d|4SC z*89-SmgC_vB<|pA7$O^< zO$?rDP%bpS2mkZrJ=@f}h`iuEy{Avqp=|o)7UFcJj4sK>X4byw+ZHx&f1wvMJ}tu) z$}tKrcN*2=s$x06+A4}!>Wz}J=TGxwwj+%=6T=6pPYEH9V(XhSd zqH34)!177W+>2#(YC3TrIo!Mi)`)ER;-(zi`?piW4qo4m0%tqvQQT<5rIbiNchVOV z+op-J)V-223#qw^XYUWqs0uo^IJFbmJ?8J|2`YuW>BiCN_(>(&@I1-R@e7J9J`()0 z?ZVjrJF0E|jxpZJn)=ZK9?LlP3kSW-B`!Tdhi@{3hvo&lsN^BHgOimvv+LR-kTR^5 SR1MzD^O+i&8{{8yIsZS{p3)Tn literal 0 HcmV?d00001 diff --git a/apps/txtreader/txtreader.png b/apps/txtreader/txtreader.png new file mode 100644 index 0000000000000000000000000000000000000000..a60ee864722a913e9f359abe54bdce504f32634e GIT binary patch literal 1549 zcmYLJdpMM76o0>Q8RRl9VOx!H7d@I}_mPbmX2eL->?D+F4ZEx)j8r0Kh^=?RMA{;jen*bkbv}O14oGWy0-e^4&Ip+wR%5bohJMtD;B1+D2h zmxuL=UghRr8nQZgJgR_wsL%d2;Y`BILr<34t(~3M$T!O?XlAw()nVyV_oh zDa&$-YmfQHzm|VlS&_?qHrM@@*|iI?5o2N{mv3iGlRitUcL_>o^8cijt#oj_9%f2h zB=H_k7HUTtcJPKbB}OGH8%>EzwA6Z`Z!Yi6f#HAd2&>XsNA-y_K_P)1XS3XLA`MeW zR}vnn<%O{mdnT&ubNjG_ZF?&dc*iO1a_Wl-uPOWonQUlN$#MoL98YR+WsRnwQ_)WJ z-+d5(RmSij;DW#$jw+e9-4{ECQ8RI0yT}rc1E9W^M)eL#c`3WlBNT<1h>MTVjuyL` zP?nLezAsExAe~_|W^C&pt!@0|B*(2D;?AHFzF|4FD{aQ8Zff|8=YmK{f1lJW=46PM zAD2coHT}%J)cE{$+5w=edHeyJXs)X{8zYJD=eVsoz4eNg9y9_;+_x8d?0G6T_^l(d zHWaAb2pcM!)|4&yTydckMn&_U#-K(pK9}0^1GeS`YSSwlnp#*==E~mQ4i@&uHZtc` z3amFpQz7R1C)(cN$o2(YKe_U#)_MN6F%2X-FBE!le~l%3l<2cXESKVK;4;I}LP}D<7V7L@_kIu+)J|`p3Cs5E^{h=W#TLs9QOVP@b#5V4!4lXPakD%|e zZ@rQoZmyhEfwzKKt{O)<*z;4pEYL;}E7(n<X=M2fqV`2qLCf%8U88EU^vm;LLUoYSy7=By;v>)Qdz&QSydARLNLt3mtfP^HWal( zI+wY3B^wN8QI>BO*A*y5Xo*+Kdo4bYB@&@Z@evs+fq?ObPLO9gHWj=Zipc0ELrlGD zxQz=*OR8}XohZ*G6im)S*+eGbwA3-+Jgmr&b@Kg|mx-89un3lH+cx3wX;0@o+H&6* zqZbyG-7_10vxQvAM2U_)dW4g%2&-!`-^R7;gTz-lra^xC+||7y1FxE9fk4d#2PvAK zGfq1&DaNq0YwxxROPjSBFy08%?ra%c9)qI&-@2`DU3n){$)W`re?0>6(pKd{PSy*$ zW!%Mft_ZY0RR^_m_XqExV-oiFu2@#oK*R$iK0uQ)t5}v<@fw_fMIMGPEK8fBS{`-? zG>!f!Lkyh3ZjQB%%R*X2dCe^9ZhSqJuZE`sRYNyPzqjG1yZB9pHP}HKfJ-2(#SU%< zb$_1`6##TojZUGd^U=jUugD0Wv~=d7dl=(3Fp#~n-&c24A~NGdxN%ZS0}xhhLWuE0 z467AxG+mH>Yy6C-`>o}aCPSAM}`!ssj7DX9r`gZE(z&eROhhh oS5&jfmUOGcM&0}W@3vo|vF~W8IN-EfJo@hdG+#RPh7UXIU&u?`tN;K2 literal 0 HcmV?d00001 diff --git a/apps/txtreader/txtreader_transparent.png b/apps/txtreader/txtreader_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..a60ee864722a913e9f359abe54bdce504f32634e GIT binary patch literal 1549 zcmYLJdpMM76o0>Q8RRl9VOx!H7d@I}_mPbmX2eL->?D+F4ZEx)j8r0Kh^=?RMA{;jen*bkbv}O14oGWy0-e^4&Ip+wR%5bohJMtD;B1+D2h zmxuL=UghRr8nQZgJgR_wsL%d2;Y`BILr<34t(~3M$T!O?XlAw()nVyV_oh zDa&$-YmfQHzm|VlS&_?qHrM@@*|iI?5o2N{mv3iGlRitUcL_>o^8cijt#oj_9%f2h zB=H_k7HUTtcJPKbB}OGH8%>EzwA6Z`Z!Yi6f#HAd2&>XsNA-y_K_P)1XS3XLA`MeW zR}vnn<%O{mdnT&ubNjG_ZF?&dc*iO1a_Wl-uPOWonQUlN$#MoL98YR+WsRnwQ_)WJ z-+d5(RmSij;DW#$jw+e9-4{ECQ8RI0yT}rc1E9W^M)eL#c`3WlBNT<1h>MTVjuyL` zP?nLezAsExAe~_|W^C&pt!@0|B*(2D;?AHFzF|4FD{aQ8Zff|8=YmK{f1lJW=46PM zAD2coHT}%J)cE{$+5w=edHeyJXs)X{8zYJD=eVsoz4eNg9y9_;+_x8d?0G6T_^l(d zHWaAb2pcM!)|4&yTydckMn&_U#-K(pK9}0^1GeS`YSSwlnp#*==E~mQ4i@&uHZtc` z3amFpQz7R1C)(cN$o2(YKe_U#)_MN6F%2X-FBE!le~l%3l<2cXESKVK;4;I}LP}D<7V7L@_kIu+)J|`p3Cs5E^{h=W#TLs9QOVP@b#5V4!4lXPakD%|e zZ@rQoZmyhEfwzKKt{O)<*z;4pEYL;}E7(n<X=M2fqV`2qLCf%8U88EU^vm;LLUoYSy7=By;v>)Qdz&QSydARLNLt3mtfP^HWal( zI+wY3B^wN8QI>BO*A*y5Xo*+Kdo4bYB@&@Z@evs+fq?ObPLO9gHWj=Zipc0ELrlGD zxQz=*OR8}XohZ*G6im)S*+eGbwA3-+Jgmr&b@Kg|mx-89un3lH+cx3wX;0@o+H&6* zqZbyG-7_10vxQvAM2U_)dW4g%2&-!`-^R7;gTz-lra^xC+||7y1FxE9fk4d#2PvAK zGfq1&DaNq0YwxxROPjSBFy08%?ra%c9)qI&-@2`DU3n){$)W`re?0>6(pKd{PSy*$ zW!%Mft_ZY0RR^_m_XqExV-oiFu2@#oK*R$iK0uQ)t5}v<@fw_fMIMGPEK8fBS{`-? zG>!f!Lkyh3ZjQB%%R*X2dCe^9ZhSqJuZE`sRYNyPzqjG1yZB9pHP}HKfJ-2(#SU%< zb$_1`6##TojZUGd^U=jUugD0Wv~=d7dl=(3Fp#~n-&c24A~NGdxN%ZS0}xhhLWuE0 z467AxG+mH>Yy6C-`>o}aCPSAM}`!ssj7DX9r`gZE(z&eROhhh oS5&jfmUOGcM&0}W@3vo|vF~W8IN-EfJo@hdG+#RPh7UXIU&u?`tN;K2 literal 0 HcmV?d00001 From 27bb244d1e7e765c917a901bbf3174507cd52524 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 5 Feb 2025 09:45:07 +0000 Subject: [PATCH 47/96] remove known warnings from list by default so we can see new errors more clearly (fix #3733) --- bin/sanitycheck.js | 48 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index 5432999eb..5366ab294 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -2,6 +2,31 @@ /* Checks for any obvious problems in apps.json */ +var BASEDIR = __dirname+"/../"; +var APPSDIR_RELATIVE = "apps/"; +var APPSDIR = BASEDIR + APPSDIR_RELATIVE; +var showAllErrors = process.argv.includes("--show-all"); + +if (process.argv.includes("--help")) { + console.log(`BangleApps Sanity Check +------------------------ + +Checks apps in this repository for common issues that might +cause problems. + +USAGE: + +bin/sanitycheck.js + - default, runs all tests (hides known errors) +bin/sanitycheck.js --show-all + - show all warnings/errors (including known ones) +bin/sanitycheck.js --help + - show this message +`); + process.exit(0); +} + + var fs = require("fs"); var vm = require("vm"); var heatshrink = require("../webtools/heatshrink"); @@ -27,9 +52,7 @@ var jsparse = (() => { return str => acorn.parse(str, { ecmaVersion: 2020 }); })(); -var BASEDIR = __dirname+"/../"; -var APPSDIR_RELATIVE = "apps/"; -var APPSDIR = BASEDIR + APPSDIR_RELATIVE; + var knownWarningCount = 0; var knownErrorCount = 0; var warningCount = 0; @@ -38,23 +61,23 @@ function ERROR(msg, opt) { // file=app.js,line=1,col=5,endColumn=7 opt = opt||{}; if (KNOWN_ERRORS.includes(msg)) { - console.log(`Known error : ${msg}`); knownErrorCount++; - } else { - console.log(`::error${Object.keys(opt).length?" ":""}${Object.keys(opt).map(k=>k+"="+opt[k]).join(",")}::${msg}`); - errorCount++; + if (!showAllErrors) return; + msg += " (KNOWN)" } + console.log(`::error${Object.keys(opt).length?" ":""}${Object.keys(opt).map(k=>k+"="+opt[k]).join(",")}::${msg}`); + errorCount++; } function WARN(msg, opt) { // file=app.js,line=1,col=5,endColumn=7 opt = opt||{}; if (KNOWN_WARNINGS.includes(msg)) { - console.log(`Known warning : ${msg}`); knownWarningCount++; - } else { - console.log(`::warning${Object.keys(opt).length?" ":""}${Object.keys(opt).map(k=>k+"="+opt[k]).join(",")}::${msg}`); - warningCount++; + if (!showAllErrors) return; + msg += " (KNOWN)" } + console.log(`::warning${Object.keys(opt).length?" ":""}${Object.keys(opt).map(k=>k+"="+opt[k]).join(",")}::${msg}`); + warningCount++; } /* These are errors that we temporarily allow */ var KNOWN_ERRORS = [ @@ -526,7 +549,8 @@ function sanityCheckLocales(){ promise.then(function() { console.log("=================================="); - console.log(`${errorCount} errors, ${warningCount} warnings (and ${knownErrorCount} known errors, ${knownWarningCount} known warnings)`); + console.log(`${errorCount} errors, ${warningCount} warnings`); + console.log(`${knownErrorCount} known errors, ${knownWarningCount} known warnings${(knownErrorCount||knownWarningCount)?", run with --show-all to see them":""}`); console.log("=================================="); if (errorCount) { process.exit(1); From d7ee6e0fb248115a4e741e50669e512bfa585c25 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 5 Feb 2025 10:11:55 +0000 Subject: [PATCH 48/96] now check for outdated known warnings/errors --- bin/sanitycheck.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index 5366ab294..e4532b41b 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -57,9 +57,13 @@ var knownWarningCount = 0; var knownErrorCount = 0; var warningCount = 0; var errorCount = 0; +var warningList = []; +var errorList = []; + function ERROR(msg, opt) { // file=app.js,line=1,col=5,endColumn=7 opt = opt||{}; + errorList.push(msg); if (KNOWN_ERRORS.includes(msg)) { knownErrorCount++; if (!showAllErrors) return; @@ -71,6 +75,7 @@ function ERROR(msg, opt) { function WARN(msg, opt) { // file=app.js,line=1,col=5,endColumn=7 opt = opt||{}; + warningList.push(msg); if (KNOWN_WARNINGS.includes(msg)) { knownWarningCount++; if (!showAllErrors) return; @@ -136,7 +141,6 @@ var KNOWN_ERRORS = [ var KNOWN_WARNINGS = [ "App gpsrec data file wildcard .gpsrc? does not include app ID", "App owmweather data file weather.json is also listed as data file for app weather", - "App messagegui storage file messagegui is also listed as storage file for app messagelist", "App carcrazy has a setting file but no corresponding data entry (add `\"data\":[{\"name\":\"carcrazy.settings.json\"}]`)", "App loadingscreen has a setting file but no corresponding data entry (add `\"data\":[{\"name\":\"loadingscreen.settings.json\"}]`)", "App trex has a setting file but no corresponding data entry (add `\"data\":[{\"name\":\"trex.settings.json\"}]`)", @@ -548,6 +552,14 @@ function sanityCheckLocales(){ } promise.then(function() { + KNOWN_ERRORS.forEach(msg => { + if (!errorList.includes(msg)) + WARN(`Known error '${msg}' no longer occurs`); + }); + KNOWN_WARNINGS.forEach(msg => { + if (!warningList.includes(msg)) + WARN(`Known warning '${msg}' no longer occurs`); + }); console.log("=================================="); console.log(`${errorCount} errors, ${warningCount} warnings`); console.log(`${knownErrorCount} known errors, ${knownWarningCount} known warnings${(knownErrorCount||knownWarningCount)?", run with --show-all to see them":""}`); From 52f084778f82de76cab16f035faab0af63da755c Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 5 Feb 2025 10:16:04 +0000 Subject: [PATCH 49/96] Update locales to avoid some sanity check errors based on month/etc length --- apps/locale/locales.js | 18 +++++++++--------- bin/sanitycheck.js | 28 ---------------------------- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/apps/locale/locales.js b/apps/locale/locales.js index c704e0f90..1e3081227 100644 --- a/apps/locale/locales.js +++ b/apps/locale/locales.js @@ -261,7 +261,7 @@ var locales = { ampm: { 0: "am", 1: "pm" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%d %B %Y", "1": "%d/%m/%Y" }, // 1 mars 2020 // 01/03/2020 - abmonth: "janv,fĆ©vr,mars,avril,mai,juin,juil,aoĆ»t,sept,oct,nov,dĆ©c", + abmonth: "janv,fĆ©vr,mars,avr,mai,juin,juil,aoĆ»t,sept,oct,nov,dĆ©c", month: "janvier,fĆ©vrier,mars,avril,mai,juin,juillet,aoĆ»t,septembre,octobre,novembre,dĆ©cembre", abday: "dim,lun,mar,mer,jeu,ven,sam", day: "dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi", @@ -423,7 +423,7 @@ var locales = { ampm: { 0: "am", 1: "pm" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%A %B %d %Y", "1": "%d/%m/%y" }, // dimanche 1 mars 2020 // 01/03/20 - abmonth: "janv.,fĆ©vr.,mars,avril,mai,juin,juil.,aoĆ»t,sept.,oct.,nov.,dĆ©c.", + abmonth: "janv,fĆ©vr,mars,avr,mai,juin,juil,aoĆ»t,sept,oct,nov,dĆ©c", month: "janvier,fĆ©vrier,mars,avril,mai,juin,juillet,aoĆ»t,septembre,octobre,novembre,dĆ©cembre", abday: "dim,lun,mar,mer,jeu,ven,sam", day: "dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi", @@ -452,7 +452,7 @@ var locales = { speed: "kmh", distance: { 0: "m", 1: "km" }, temperature: "°C", - ampm: { 0: "vorm", 1: " nachm" }, + ampm: { 0: "vorm", 1: "nachm" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%A, %d. %B %Y", "1": "%d.%m.%Y" }, // Sonntag, 1. MƤrz 2020 // 1.3.2020 abmonth: "Jan,Feb,MƤrz,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez", @@ -471,7 +471,7 @@ var locales = { ampm: { 0: "AM", 1: "PM" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%A %d %B %Y", "1": "%d/%m/%y" }, // dimanche 1 mars 2020 // 01/03/20 - abmonth: "janv.,fĆ©vr.,mars,avril,mai,juin,juil.,aoĆ»t,sept.,oct.,nov.,dĆ©c.", + abmonth: "janv,fĆ©vr,mars,avr,mai,juin,juil,aoĆ»t,sept,oct,nov,dĆ©c", month: "janvier,fĆ©vrier,mars,avril,mai,juin,juillet,aoĆ»t,septembre,octobre,novembre,dĆ©cembre", abday: "dim,lun,mar,mer,jeu,ven,sam", day: "dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi", @@ -567,7 +567,7 @@ var locales = { ampm: { 0: "am", 1: "pm" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%A %d %B de %Y", "1": "%d/%m/%Y" }, // dimenge 1 de marƧ de 2020 // 01/03/2020 - abmonth: "gen.,febr.,marƧ,abril,mai,junh,julh,ago.,set.,oct.,nov.,dec.", + abmonth: "gen,febr,marƧ,abril,mai,junh,julh,ago,set,oct,nov,dec", month: "geniĆØr,febriĆØr,marƧ,abril,mai,junh,julhet,agost,setembre,octòbre,novembre,decembre", abday: "dg,dl,dm,dc,dj,dv,ds", day: "dimenge,diluns,dimars,dimĆØcres,dijòus,divendres,dissabte", @@ -612,10 +612,10 @@ var locales = { speed: "km/h", distance: { 0: "m", 1: "km" }, temperature: "°C", - ampm: { 0: "dop.", 1: "pop." }, + ampm: { 0: "dop", 1: "pop" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%-d. %b %Y", 1: "%-d.%-m.%Y" }, // "3. jan. 2020" // "3.1.2020"(short) - abmonth: "sij.,velj.,ožu.,tra.,svi,lip.,srp.,kol.,ruj.,lis.,stu.,pro.", + abmonth: "sij,velj,ožu,tra,svi,lip,srp,kol,ruj,lis,stu,pro", month: "siječanj,veljača,ožujak,travanj,svibanj,lipanj,srpanj,kolovoz,rujan,listopad,studeni,prosinac", abday: "ned.,pon.,uto.,sri.,čet.,pet.,sub.", day: "nedjelja,ponedjeljak,utorak,srijeda,četvrtak,petak,subota", @@ -628,7 +628,7 @@ var locales = { speed: "km/h", distance: { 0: "m", 1: "km" }, temperature: "°C", - ampm: { 0: "dop.", 1: "pop." }, + ampm: { 0: "dop", 1: "pop" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%-d. %b %Y", 1: "%-d.%-m.%Y" }, // "3. jan. 2020" // "3.1.2020"(short) abmonth: "jan.,feb.,mar.,apr.,maj,jun.,jul.,avg.,sep.,okt.,nov.,dec.", @@ -728,7 +728,7 @@ var locales = { ampm: { 0: "am", 1: "pm" }, timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, datePattern: { 0: "%d %B %Y", "1": "%d/%m/%y" }, - abmonth: "gen.,febr.,marƧ,abr.,maig,juny,jul.,ag.,set.,oct.,nov.,des.", + abmonth: "gen,febr,marƧ,abr,maig,juny,jul,ag,set,oct,nov,des", month: "gener,febrer,marƧ,abril,maig,juny,juliol,agost,setembre,octubre,novembre,desembre", abday: "dg.,dl.,dt.,dc.,dj.,dv.,ds.", day: "diumenge,dilluns,dimarts,dimecres,dijous,divendres,dissabte", diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index e4532b41b..75f740d4f 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -88,7 +88,6 @@ function WARN(msg, opt) { var KNOWN_ERRORS = [ "In locale en_CA, long date output must be shorter than 15 characters (Wednesday, September 10, 2024 -> 29)", "In locale fr_FR, long date output must be shorter than 15 characters (10 septembre 2024 -> 17)", - "In locale fr_FR, short month must be shorter than 5 characters", "In locale sv_SE, speed must be shorter than 5 characters", "In locale en_SE, long date output must be shorter than 15 characters (September 10 2024 -> 17)", "In locale en_NZ, long date output must be shorter than 15 characters (Wednesday, September 10, 2024 -> 29)", @@ -97,45 +96,18 @@ var KNOWN_ERRORS = [ "In locale en_IL, long date output must be shorter than 15 characters (Wednesday, September 10, 2024 -> 29)", "In locale es_ES, long date output must be shorter than 15 characters (miĆ©rcoles, 10 de septiembre de 2024 -> 35)", "In locale fr_BE, long date output must be shorter than 15 characters (dimanche septembre 10 2024 -> 26)", - "In locale fr_BE, short month must be shorter than 5 characters", - "In locale fr_BE, short month must be shorter than 5 characters", - "In locale fr_BE, short month must be shorter than 5 characters", - "In locale fr_BE, short month must be shorter than 5 characters", - "In locale fr_BE, short month must be shorter than 5 characters", "In locale fi_FI, long date output must be shorter than 15 characters (keskiviikkona 10. maaliskuuta 2024 -> 34)", "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", - "In locale fi_FI, short month must be shorter than 5 characters", "In locale de_CH, meridian must be shorter than 4 characters", "In locale de_CH, meridian must be shorter than 4 characters", "In locale de_CH, long date output must be shorter than 15 characters (Donnerstag, 10. September 2024 -> 30)", "In locale fr_CH, long date output must be shorter than 15 characters (dimanche 10 septembre 2024 -> 26)", - "In locale fr_CH, short month must be shorter than 5 characters", - "In locale fr_CH, short month must be shorter than 5 characters", - "In locale fr_CH, short month must be shorter than 5 characters", - "In locale fr_CH, short month must be shorter than 5 characters", - "In locale fr_CH, short month must be shorter than 5 characters", "In locale wae_CH, long date output must be shorter than 15 characters (Sunntag, 10. HerbÅ”tmĆ”net 2024 -> 29)", "In locale tr_TR, long date output must be shorter than 15 characters (10 Haziran 2024 Pazartesi -> 25)", "In locale hu_HU, long date output must be shorter than 15 characters (2024 Szep 10, Csütƶrtƶk -> 23)", "In locale oc_FR, long date output must be shorter than 15 characters (divendres 10 setembre de 2024 -> 29)", "In locale oc_FR, short month must be shorter than 5 characters", - "In locale oc_FR, short month must be shorter than 5 characters", - "In locale hr_HR, meridian must be shorter than 4 characters", - "In locale hr_HR, meridian must be shorter than 4 characters", - "In locale hr_HR, short month must be shorter than 5 characters", - "In locale sl_SI, meridian must be shorter than 4 characters", - "In locale sl_SI, meridian must be shorter than 4 characters", "In locale ca_ES, long date output must be shorter than 15 characters (10 setembre 2024 -> 16)", - "In locale ca_ES, short month must be shorter than 5 characters", ]; /* These are warnings we know about but don't want in our output */ var KNOWN_WARNINGS = [ From c51785467c006b5521def8985b0602e013719653 Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Wed, 5 Feb 2025 23:11:02 +0100 Subject: [PATCH 50/96] sched: fix type re hidden set to false hiding widget --- apps/sched/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sched/README.md b/apps/sched/README.md index 1216a1a11..0fa780405 100644 --- a/apps/sched/README.md +++ b/apps/sched/README.md @@ -49,7 +49,7 @@ Alarms are stored in an array in `sched.json`, and take the form: // e.g. repeat every 2 months: { interval: "month", num: 2 }. // Supported intervals: day, week, month, year vibrate : "...", // OPTIONAL pattern of '.', '-' and ' ' to use for when buzzing out this alarm (defaults to '..' if not set) - hidden : false, // OPTIONAL if false, the widget should not show an icon for this alarm + hidden : false, // OPTIONAL if true, the widget should not show an icon for this alarm as : false, // auto snooze timer : 5*60*1000, // OPTIONAL - if set, this is a timer and it's the time in ms del : false, // OPTIONAL - if true, delete the timer after expiration From 45844692917d8000ce196574a0a7a9e2b6d00636 Mon Sep 17 00:00:00 2001 From: tonykakuuu Date: Thu, 6 Feb 2025 22:28:36 +0100 Subject: [PATCH 51/96] Implemented offsets, support larger files & general performance increase --- apps/txtreader/app.js | 55 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/apps/txtreader/app.js b/apps/txtreader/app.js index 890b4254c..bc6bec708 100644 --- a/apps/txtreader/app.js +++ b/apps/txtreader/app.js @@ -14,72 +14,73 @@ function showFileSelector() { }; }); - menuItems['< Back'] = () => { load(); }; // Go back to the launcher or previous screen + menuItems['< Back'] = () => { load(); }; E.showMenu(menuItems); } function onFileSelected(file) { + const fileSize = require("Storage").read(file, 0, 0).length; + const chunkSize = 1024; + let currentOffset = 0; + let currentPage = 1; + let history = []; - var text = require("Storage").read(file); - - function displayText(text, startLine, pageNumber) { + function displayText(offset, pageNumber) { g.clear(); g.setFont("6x8", 1); g.setColor(1); g.drawString("Page " + pageNumber, 10, 2); - g.drawString(file, g.getWidth()-file.length*6, 2); + //g.drawString("Offset " + offset, 60, 2); + g.drawString(file, g.getWidth() - file.length * 6, 2); + var text = require("Storage").read(file, offset, chunkSize); var lines = text.split("\n"); var y = 15; // Text start, top row reserved for page number - var currentLine = startLine || 0; - var linesDisplayed = 0; //Per page + var linesDisplayed = 0; // Lines per page + var totalCharsDisplayed = 0; // Total characters per page - for (var i = currentLine; i < lines.length; i++) { + for (var i = 0; i < lines.length; i++) { var wrappedLines = g.wrapString(lines[i], g.getWidth() - 20); for (var j = 0; j < wrappedLines.length; j++) { g.drawString(wrappedLines[j], 10, y); y += 10; // Move down for the next line linesDisplayed++; + totalCharsDisplayed += wrappedLines[j].length + (j < wrappedLines.length - 1 ? 0 : 1); // Add newline character for the last wrapped line if (y >= g.getHeight() - 10) { // If we run out of space, stop drawing - return { nextStartLine: i , linesDisplayed: linesDisplayed }; + return { nextOffset: offset + totalCharsDisplayed, linesDisplayed: linesDisplayed }; } } } return null; // No more lines to display } - var currentStartLine = 0; - var currentPage = 1; - var history = []; // Track the start line and lines displayed for each page - // Initial display - var result = displayText(text, currentStartLine, currentPage); - history.push({ startLine: currentStartLine, linesDisplayed: result.linesDisplayed }); + var result = displayText(currentOffset, currentPage); + history.push({ offset: currentOffset, linesDisplayed: result.linesDisplayed }); // Handle touch events Bangle.on('touch', function(button) { if (button === 2) { // Right side of the screen (next page) - var nextStartLine = displayText(text, currentStartLine, currentPage + 1); - if (nextStartLine !== null) { - currentStartLine = nextStartLine.nextStartLine; + var nextOffset = displayText(currentOffset, currentPage + 1); + if (nextOffset !== null) { + currentOffset = nextOffset.nextOffset; currentPage++; - history.push({ startLine: currentStartLine, linesDisplayed: nextStartLine.linesDisplayed }); - displayText(text, currentStartLine, currentPage); + history.push({ offset: currentOffset, linesDisplayed: nextOffset.linesDisplayed }); + displayText(currentOffset, currentPage); } else { - currentStartLine = 0; + currentOffset = 0; currentPage = 1; - history = [{ startLine: currentStartLine, linesDisplayed: result.linesDisplayed }]; - displayText(text, currentStartLine, currentPage); + history = [{ offset: currentOffset, linesDisplayed: result.linesDisplayed }]; + displayText(currentOffset, currentPage); } } else if (button === 1) { // Left side of the screen (previous page) if (currentPage > 1) { - // Go back to the previous page - history.pop(); // Remove the current page from history + history.pop(); // Remove current page from history var previousPage = history[history.length - 1]; - currentStartLine = previousPage.startLine; + currentOffset = previousPage.offset; currentPage--; - displayText(text, currentStartLine, currentPage); + displayText(currentOffset, currentPage); } } }); From a339c9fb634452f55ac65fb0b1ed169ab4357cf0 Mon Sep 17 00:00:00 2001 From: tonykakuuu Date: Thu, 6 Feb 2025 22:31:09 +0100 Subject: [PATCH 52/96] Unused variable --- apps/txtreader/app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/txtreader/app.js b/apps/txtreader/app.js index bc6bec708..df61a2783 100644 --- a/apps/txtreader/app.js +++ b/apps/txtreader/app.js @@ -19,7 +19,6 @@ function showFileSelector() { } function onFileSelected(file) { - const fileSize = require("Storage").read(file, 0, 0).length; const chunkSize = 1024; let currentOffset = 0; let currentPage = 1; From 2ae961ee567e57361b3f8c7141429c0597bd6e9e Mon Sep 17 00:00:00 2001 From: Randy Heydon Date: Thu, 6 Feb 2025 06:55:38 -0500 Subject: [PATCH 53/96] calendar: properly display synced all-day events. Discovered that, in the events synchronized from Gadgetbridge, all-day events have timestamps that disregard local timezones. Specifically, all-day events always start at midnight UTC, which caused calendar to display them starting at a different time depending on time zone offset (e.g. for my offset of -5, I see all-day events start at 19:00 the day before). Borrowed logic from the agenda app to correct this. This logic shifts an all-day event's start time to start at midnight in the current time zone. Also specify all-day events as type "o" (other) so the full day is highlighted and the start time is not displayed. Note that this does nothing to handle all-day events that span more than one day (only the first day is highlighted in the calendar). Also note that I'm not sure how this will handle time zone changes, like shifting to/from daylight savings time. --- apps/calendar/ChangeLog | 1 + apps/calendar/calendar.js | 8 +++++--- apps/calendar/metadata.json | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/calendar/ChangeLog b/apps/calendar/ChangeLog index d737ec6d4..b5a5fbe2f 100644 --- a/apps/calendar/ChangeLog +++ b/apps/calendar/ChangeLog @@ -20,3 +20,4 @@ 0.17: Load holidays before events so the latter is not overpainted 0.18: Minor code improvements 0.19: Read events synchronized from Gadgetbridge +0.20: Correct start time of all-day events synchronized from Gadgetbridge diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js index ea06b70e8..d6eefce39 100644 --- a/apps/calendar/calendar.js +++ b/apps/calendar/calendar.js @@ -62,9 +62,11 @@ const loadEvents = () => { })); // all events synchronized from Gadgetbridge events = events.concat((require("Storage").readJSON("android.calendar.json",1) || []).map(a => { - // timestamp is in seconds, Date requires milliseconds - const date = new Date(a.timestamp * 1000); - return {date: date, msg: a.title, type: "e"}; + // All-day events always start at 00:00:00 UTC, so we need to "undo" the + // timezone offsetting to make sure that the day is correct. + const offset = a.allDay ? new Date().getTimezoneOffset() * 60 : 0 + const date = new Date((a.timestamp+offset) * 1000); + return {date: date, msg: a.title, type: a.allDay ? "o" : "e"}; })); }; diff --git a/apps/calendar/metadata.json b/apps/calendar/metadata.json index 5f5f21b27..36713a487 100644 --- a/apps/calendar/metadata.json +++ b/apps/calendar/metadata.json @@ -1,7 +1,7 @@ { "id": "calendar", "name": "Calendar", - "version": "0.19", + "version": "0.20", "description": "Monthly calendar, displays holidays uploaded from the web interface and scheduled events.", "icon": "calendar.png", "screenshots": [{"url":"screenshot_calendar.png"}], From e21979bd0815a4863e1ef1f57f22316d2252723d Mon Sep 17 00:00:00 2001 From: Brian Whelan Date: Fri, 7 Feb 2025 21:52:01 +0000 Subject: [PATCH 54/96] New app "Shortcuts" Adds a new app that allows you to pin apps to clockfaces that support clock_info --- apps/clkshortcuts/ChangeLog | 1 + apps/clkshortcuts/README.md | 10 + .../clkshortcuts/add_shortcuts_screenshot.png | Bin 0 -> 471 bytes apps/clkshortcuts/app-icon.js | 1 + apps/clkshortcuts/app.js | 224 ++++++++++++++++++ apps/clkshortcuts/app.png | Bin 0 -> 1131 bytes apps/clkshortcuts/clkinfo.js | 45 ++++ .../example_shortcuts_screenshot.png | Bin 0 -> 622 bytes apps/clkshortcuts/metadata.json | 17 ++ 9 files changed, 298 insertions(+) create mode 100644 apps/clkshortcuts/ChangeLog create mode 100644 apps/clkshortcuts/README.md create mode 100644 apps/clkshortcuts/add_shortcuts_screenshot.png create mode 100644 apps/clkshortcuts/app-icon.js create mode 100644 apps/clkshortcuts/app.js create mode 100644 apps/clkshortcuts/app.png create mode 100644 apps/clkshortcuts/clkinfo.js create mode 100644 apps/clkshortcuts/example_shortcuts_screenshot.png create mode 100644 apps/clkshortcuts/metadata.json diff --git a/apps/clkshortcuts/ChangeLog b/apps/clkshortcuts/ChangeLog new file mode 100644 index 000000000..759f68777 --- /dev/null +++ b/apps/clkshortcuts/ChangeLog @@ -0,0 +1 @@ +0.01: New app! \ No newline at end of file diff --git a/apps/clkshortcuts/README.md b/apps/clkshortcuts/README.md new file mode 100644 index 000000000..0d4b72318 --- /dev/null +++ b/apps/clkshortcuts/README.md @@ -0,0 +1,10 @@ +# Shortcuts + +An app that allows you to create custom ClockInfos that act as shortcuts to your favourite apps. + +## Create a Shortcut +After installing the app, you can open the app to add and manage existing shortcuts. If no shortcuts exist, the app will display a ``[+] Shortcuts`` button as a ClockInfo on your Clock (see screenshots), which when clicked will quickly launch into the app so you can add new shortcuts. + +When adding a shortcut, first select the app you wish to use, then select the icon you wish to register to the shortcut. If a keyboard is installed, you'll get the option to rename the shortcut before saving. + +Once created, your shortcut will appear on any Clocks with ClockInfo support, and tapping the shortcut will launch the chosen app \ No newline at end of file diff --git a/apps/clkshortcuts/add_shortcuts_screenshot.png b/apps/clkshortcuts/add_shortcuts_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..ea7c6273b9f3d4ab4ad05105873455f8224660f8 GIT binary patch literal 471 zcmeAS@N?(olHy`uVBq!ia0vp^8$g(a8A!&?{Fw`+7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h2Ka=yGW=)w|NlRb7uwr89VA%b5n0T@z;_sg8IR|$NCBD>?&;zfl5y|t zbk0f53L>m0dH>vFcvpXdaf-_UR?YuCX}caX{dl7#GF5`1;j+h3(@4{e9ojei=AYE+ zifxUV7%KXFdvg4pIj(zz;@+%3q2%`G^`ocNA3W~NaE)n^%M{{$2&S+btzkmMCh?l3r5-k<)on|_~=Er%&U#wfGL-2oN zg%5M}I`PA`m8WLNZ+h+9A$Z>}C-`#Z$KO4zH@w`^EOVTCeyBZS-6ZGS^FzKn_iC5K zN7Y9;rxaH|ws>ou?)15lccW|1k8_VsJNEq0J_0tFnZd#O*dK=X$!@D#>el%K!=1s? L)z4*}Q$iB}H6zec literal 0 HcmV?d00001 diff --git a/apps/clkshortcuts/app-icon.js b/apps/clkshortcuts/app-icon.js new file mode 100644 index 000000000..99f51a2e8 --- /dev/null +++ b/apps/clkshortcuts/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4UB/4ACBIM889VAHmqAAwKCrQLH0oLCuBoFhoLCtJ1HtILBtYLH9ILBtALHlILQlRFCwALSnWwgECBY8O1gLJgeoBaojLHZfqAQILIFwMDBY8CFwMO2QLGhwuBlWuBY0K4ED1aDHBYJUBlQLGnRUChQLIKgJHHBYJUBZY8KgZUBBZHCKgILHh2CBZMC0fABZC+CBZBSBC5JUB14MDcY2q1YLIDAILGtY4EAAXpBYNpBY9pBYNauAKFhulBYWqAAwLCqoLHBQQA6A=")) \ No newline at end of file diff --git a/apps/clkshortcuts/app.js b/apps/clkshortcuts/app.js new file mode 100644 index 000000000..197ca70cf --- /dev/null +++ b/apps/clkshortcuts/app.js @@ -0,0 +1,224 @@ +var storage = require("Storage"); +var keyboard = "textinput"; +try { + keyboard = require(keyboard); +} catch (e) { + keyboard = null; +} + +var icons = [ + {name:"agenda", img :"GBiBAAAAAAA8AAB+AA/n8B/n+BgAGBgAGBn/mBn/mBgAGBgAGBn/mBn/+BgD/BgHDhn+Bhn8MxgMIxgMIx/8Ew/+BgAHDgAD/AAA8A=="}, + {name:"alarm", img:"GBiBAAAAAAAAAAYAYA4AcBx+ODn/nAOBwAcA4A4YcAwYMBgYGBgYGBgYGBgYGBgeGBgHGAwBMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="}, + {name:"mail", img:"GBiBAAAAAAAAAAAAAAAAAB//+D///DAADDgAHDwAPDcA7DPDzDDnDDA8DDAYDDAADDAADDAADDAADD///B//+AAAAAAAAAAAAAAAAA=="}, + {name:"android", img: "GBiBAAAAAAEAgAD/AAD/AAHDgAGBgAMkwAMAwAP/wBv/2BsA2BsA2BsA2BsA2BsA2BsA2Bv/2AP/wADnAADnAADnAADnAADnAAAAAA=="}, + {name:"add", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgYGBgYGBgYGBgYGBn/mBn/mBgYGBgYGBgYGBgYGBgAGBgAGB//+A//8AAAAAAAAAAAAA=="}, + {name:"bangle", img:"GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA=="}, + {name:"bike", img:"GBiBAAAAAAAAAAAAAAAD+AAD/AADjAABjAfhnAfjyAMDwAcGwB4O+H8M/GGZ5sD7c8fzM8fjM8DDA2GBhn8B/h4AeAAAAAAAAAAAAA=="}, + {name:"map", img:"GBiBAAAAAAAAAAAAAADgGAf8+B//+BjHGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjjGB//+B8/4BgHAAAAAAAAAAAAAA=="}, + {name:"play", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBjAGBjwGBj8GBjeGBjHmBjB2BjB2BjHmBjeGBj8GBjwGBjAGBgAGB//+A//8AAAAAAAAAAAAA=="}, + {name:"fast forward", img:"GBiBAAAAAAAAAAAAAH///v///8AAA8YYA8eeA8f/g8b7w8Y488YYO8YYO8Y488b7w8f/g8eeA8YYA8AAA////3///gAAAAAAAAAAAA=="}, + {name:"rewind", img:"GBiBAAAAAAAAAAAAAH///v///8AAA8AYY8B548H/48PfY88cY9wYY9wYY88cY8PfY8H/48B548AYY8AAA////3///gAAAAAAAAAAAA=="}, + {name:"timer", img:"GBiBAAAAAAB+AAB+AAAAMAB+OAH/nAOByAcA4A4YcAwYMBgYGBgYGBgYGBgYGBgAGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="}, + {name:"connected", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBngGBn4GBgcGBgOGBnHGBnzGBgxmBgZmBmZmBmZmBgAGBgAGB//+A//8AAAAAAAAAAAAA=="}, + {name:"lock", img:"GBiBAAAAAAA8AAD/AAHDgAGBgAMAwAMAwAMAwAf/4A//8AwAMAwAMAwAMAwYMAw8MAw8MAwYMAwAMAwAMAwAMA//8Af/4AAAAAAAAA=="}, + {name:"battery", img:"GBiBAAAAAAAAAAB+AAB+AAHngAPnwAMAwAMAwAMIwAMIwAMYwAM4wAM+wAN8wAMcwAMYwAMQwAMQwAMAwAMAwAP/wAH/gAAAAAAAAA=="}, + {name:"game", img:"GBiBAAAAAAAAAAAAAAA8AAB+AABmAABmAAB+AAA8AAAYAAAYAAAYAAMYAA//8B//+BgAGBgAGBgAGBgAGB//+A//8AAAAAAAAAAAAA=="}, + {name:"dice", img:"GBiBAAAAAB//8D//+HAAPGMDHmeHnmeHnmMDHmAAHmMDHmeHnmeHnmMDHmAAHmMDHmeHnmeHnmMDHnAAPn///j///h///g///AAAAA=="}, + {name:"gear", img:"GBiBAAAAAAAAAAA8AAB+AABmAA3nsA/D8B8A+Dg8HBx+OAznMAzDMAzDMAznMBx+ODg8HB8A+A/D8A3nsABmAAB+AAA8AAAAAAAAAA=="}, + {name:"wrench", img:"GBiBAAAAAAAAAAAAAAAHgAAfwAA7gAAzEABjOABj+ABh+ABgGADgMAHAcAOP4AcfgA44AB9wADHgADHAADGAAB8AAA4AAAAAAAAAAA=="}, + {name:"calendar", img:"FhgBDADAMAMP/////////////////////8AADwAAPAAA8AADwAAPAAA8AADwAAPAAA8AADwAAPAAA8AADwAAP///////"}, + {name:"power", img:"GBiBAAAAAAAAAAB+AAH/gAeBwA4YcAwYMBjbGBnbmDGZjDMYzDMYzDMAzDMAzDGBjBnDmBj/GAw8MA4AcAeB4AH/gAB+AAAAAAAAAA=="}, + {name:"terminal", img:"GBiBAAAAAAAAAAAAAA//8B//+B//+B//+B//+BgAGBgAGBgAGBmAGBjAGBhgGBhgGBjAGBmPmBgAGBgAGB//+A//8AAAAAAAAAAAAA=="}, + {name:"camera", img:"GBiBAAAAAAAAAAD/AAH/gAMAwD8A/H8A/mA8BmD/BmHDhmGBhmMAxmMAxmMAxmMAxmGBhmHDhmD/BmA8BmAABn///j///AAAAAAAAA=="}, + {name:"phone", img:"GBiBAAAAAAAAAAOAAA/AABzgADBgADBgADBgABjgABjAABzAAAxgAA5wAAc58AMf+AGHHADgDABwDAA8GAAfGAAH8AAA4AAAAAAAAA=="}, + {name:"two prong plug", img:"GBiBAAABgAADwAAHwAAPgACfAAHOAAPkBgHwDwP4Hwf8Pg/+fB//OD//kD//wD//4D//8D//4B//QB/+AD/8AH/4APnwAHAAACAAAA=="}, + {name:"steps", img:"GBiBAAcAAA+AAA/AAA/AAB/AAB/gAA/g4A/h8A/j8A/D8A/D+AfH+AAH8AHn8APj8APj8AHj4AHg4AADAAAHwAAHwAAHgAAHgAADAA=="}, + {name:"graph", img:"GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA=="}, + {name:"hills", img:"GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA=="}, + {name:"sun", img:"GBiBAAAYAAAYAAAYAAgAEBwAOAx+MAD/AAHDgAMAwAcA4AYAYOYAZ+YAZwYAYAcA4AMAwAHDgAD/AAx+MBwAOAgAEAAYAAAYAAAYAA=="}, + {name:"home", img:"GBiBAAAAAAAAAAAAAAH/gAP/wAdg4A5wYA44MBwf+DgP/BgAGBgAGBgAGBnnmBnnmBnnmBnnmBngGBngGB//+B//+AAAAAAAAAAAAA=="}, + {name:"bell", img:"GBiBAAAAAAAAAAAfgAB/2ADw+AHAMAOAGAcAGD4ADHgADDgADBwADA4AHAcAGAOAOAHAcAPg4ANxwAM5gAP/AAHvAAAHAAACAAAAAA=="}, + {name:"bin", img:"GBiBAAAAAAAAAAB+AB//+B//+AwAMAwAMAxmMAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYANmwAMAwAMAwAP/wAH/gAAAAAAAAA=="}, +]; + +let storedApps; +var showMainMenu = () => { + storedApps = storage.readJSON("clkshortcuts.json", 1) || {}; + + var mainMenu = { + "": { + title: "Shortcuts", + }, + "< Back": () => { + load(); + }, + "New": () => { + // Select the app + getSelectedApp().then((app) => { + getSelectedIcon().then((icon) => { + promptForRename(app.name).then((name) => { + E.showMessage("Saving..."); + storedApps[app.src] = { + name: name, src: app.src, icon: icon + }; + storage.writeJSON("clkshortcuts.json", storedApps); + showMainMenu(); + }).catch(() => { + E.showMessage("Saving..."); + storedApps[app.src] = { + name: app.name, src: app.src, icon: icon + }; + storage.writeJSON("clkshortcuts.json", storedApps); + showMainMenu(); + } ); + }).catch(() => {showMainMenu();}); + }).catch(() => {showMainMenu();}); + }, + }; + getStoredAppsArray(storedApps).forEach((app) => { + mainMenu[app.name] = { + onchange: () => { + showEditMenu(app).then((dirty) => { + if (dirty) { + E.showMessage("Saving..."); + storage.writeJSON("clkshortcuts.json", storedApps); + } + showMainMenu(); + }); + }, + format: v=>"\0" + atob(app.icon) + }; + }); + E.showMenu(mainMenu); +}; + +var showEditMenu = (app) => { + return new Promise((resolve, reject) => { + var editMenu = { + "": { + title: "Edit " + app.name, + }, + "< Back": () => { + resolve(false); + }, + "Name":{ + onchange: () => { + promptForRename(app.name).then((name) => { + storedApps[app.src].name = name; + resolve(true); + }).catch(); + }, + format: v=>app.name.substring(0, 7) + }, + "Icon": { + onchange: () => { + getSelectedIcon().then((icon) => { + storedApps[app.src].icon = icon; + resolve(true); + }).catch(() => resolve(false)); + }, + format: v=>"\0" + atob(app.icon) + }, + "Delete": { + onchange: () => { + delete storedApps[app.src] + resolve(true); + }, + format: v=>"\0" + atob("GBiBAAAAAAAAAAB+AB//+B//+AwAMAwAMAxmMAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYANmwAMAwAMAwAP/wAH/gAAAAAAAAA==") + } + }; + E.showMenu(editMenu); + }); +}; + +var promptForRename = (name) => { + return new Promise((resolve, reject) => { + if (!keyboard) { reject("No textinput is available"); } + else { + return require("textinput").input({text:name}).then((result) => resolve(result)); + } + }); +}; + +var getStoredAppsArray = (apps) => { + var appList = Object.keys(apps); + var storedAppArray = []; + for (var i = 0; i < appList.length; i++) { + var app = "" + appList[i]; + storedAppArray.push( + apps[app] + ); + } + return storedAppArray; +}; + +var getSelectedIcon = () => { + return new Promise((resolve, reject) => { + var iconMenu = { + "": { + title: "Select Icon", + }, + "< Back": () => { + reject("The user cancelled the operation"); + }, + }; + + icons.forEach((icon) => { + iconMenu["\0" + atob(icon.img) + " " + icon.name] = () => { + resolve(icon.img); + }; + }); + + E.showMenu(iconMenu); + }); +}; + +var getAppList = () => { + var appList = storage + .list(/\.info$/) + .map((appInfoFileName) => { + var appInfo = storage.readJSON(appInfoFileName, 1); + return ( + appInfo && { + name: appInfo.name, + sortorder: appInfo.sortorder, + src: appInfo.src, + } + ); + }) + .filter((app) => app && !!app.src); + appList.sort((a, b) => { + var n = (0 | a.sortorder) - (0 | b.sortorder); + if (n) return n; + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + return 0; + }); + + return appList; +}; + +var getSelectedApp = () => { + return new Promise((resolve, reject) => { + E.showMessage("Loading apps..."); + var selectAppMenu = { + "": { + title: "Select App", + }, + "< Back": () => { + reject("The user cancelled the operation"); + }, + }; + + var appList = getAppList(); + appList.forEach((app) => { + selectAppMenu[app.name] = () => { + resolve(app); + }; + }); + + E.showMenu(selectAppMenu); + }); +}; + +showMainMenu(); \ No newline at end of file diff --git a/apps/clkshortcuts/app.png b/apps/clkshortcuts/app.png new file mode 100644 index 0000000000000000000000000000000000000000..66e28fde79af1045cfc8f2a1ea3ebbd8b2a7c204 GIT binary patch literal 1131 zcmV-x1eE)UP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA1OQ1yK~!i%?U_9+ zWKk5yuSoLP7`%QAk95G{ml+M4}=jqFd8Q6tgO|LZwuRPPZFE6lla(XoUER zkHqW_cH-mgIcM*keTV#aGm8f#V?$Dk5m)$?+HJ%gMM-$xa-dvLKPa)6BpT&_5w6wJFC`F@&h6Wua zIvnZ1?d`4Ji=3sUCB5e?eBnqrKR<`6sw(y=D=XtAP=d4_V}}wW3T%ZsQC(fle$hbZB_v3+R zWUTD(??Y*6Df^X_l)&EJo~{Xvv>juI5+e$1*xA{EoSYo?sjI7li;D|g6CPFkY`0Iy*b9 zNkCp+9_;S!29E8p_=>R&+||{^Hg30DmjpvMGjm^{(Vv)@fTpG35iSF)h=C(4h z@Z~ z%nWY_1_o3?K>_c-H&H*0_Vo1dc5G}+;i|;@xNP#awY8PE@g(dNB4{Z!Z()OjgIq>; z*r};0czSx`W2Z3rpv2gAfLL8!#{r$bJaTb#gN{pxj#N6B*q^72_eN9ab zEH5wX8s{+ipu~tfKrAjULUD0%pdorP9UmWum6a7ZJ39k>Gt-vQVdA31utOx!(mFCS z61W4ul*{FU(a}+D9T}E5K{)nKOiQcB<57o)hiZCyTJ`q!DtwSr+1c3&lh;|puCir6#A4+PQyA*+`t^7`n*m*6Ud2va12X6QaKH^iEUHzQT^Z`=(i3z xegsAQi^)K}rc=j1JYuXj|Kv-MAi;-6soz#qUFcx}E6o4^002ovPDHLkV1iM-87BY$ literal 0 HcmV?d00001 diff --git a/apps/clkshortcuts/clkinfo.js b/apps/clkshortcuts/clkinfo.js new file mode 100644 index 000000000..842ae2747 --- /dev/null +++ b/apps/clkshortcuts/clkinfo.js @@ -0,0 +1,45 @@ +(function() { + var storage = require("Storage"); + var storedApps = storage.readJSON("clkshortcuts.json", 1) || {}; + var items = []; + if (Object.keys(storedApps).length !== 0) { + for (var key in storedApps) { + var source = { + name: storedApps[key].name, + img: storedApps[key].icon, + src: storedApps[key].src, + get : function() { + return { + text : this.name, + img : atob(this.img) + } + }, + run: function() { load(this.src);}, + show : function() {}, + hide : function() {}, + } + items.push(source); + } + } + else { + var source = { + name: "Shortcuts", + img: "GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgYGBgYGBgYGBgYGBn/mBn/mBgYGBgYGBgYGBgYGBgAGBgAGB//+A//8AAAAAAAAAAAAA==", + src: "clkshortcuts.app.js", + get : function() { + return { + text : this.name, + img : atob(this.img) + } + }, + run: function() { load(this.src);}, + show : function() {}, + hide : function() {}, + }; + items = [source]; + } + return { + name: "Shortcuts", + items: items + }; +}) \ No newline at end of file diff --git a/apps/clkshortcuts/example_shortcuts_screenshot.png b/apps/clkshortcuts/example_shortcuts_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..b60a57f5743622691d2ac5c937c4d36887896d39 GIT binary patch literal 622 zcmV-!0+IcRP)Px#1ZP1_K>z@;j|==^1poj52~bQ_MF9T*|Ns900032ug_i&T010qNS#tmY4#NNd z4#NS*Z>VGd00HhvL_t(&-tCtSmV+P+gy9B;8-)8Ga`|+f}a^bTVkCEW*qifr9 z+@k9sY6HP`%WZ)ZO&B}mp+@U@C8q`k@fdjSfOF4ootIj?yjRva_GZ z!@$zq11quq^e2cKQ&p9jC^ExpsbE1?Sc z-PPuN75x{=Q+gioeE&=#2!d`9Ew1^6YSDhFs&`iRI+9;9dU1P&y8!EJV5)-2@4!O1N{5h|ohVD5ok z+eE;G4%b6L?i7m_V6zW}kJmM@t%IXCrc1n|6pGOCnPhko>6XmD;27l;qyo$%!9|ua z9i|%zu&Jk8+-?Ue(k^#4Gr5@k^(n2K$v3}N==xd_xBI~m1T|y_3E-K*G)Mpg`~cYG z#7@6A=`Ig3 Date: Sat, 8 Feb 2025 14:27:01 -0600 Subject: [PATCH 55/96] [gbmusic] fix #3737; fix autostart saved state; pass playpause to gb instead of play; allow widget clicks --- apps/gbmusic/ChangeLog | 1 + apps/gbmusic/app.js | 16 +++++++++++----- apps/gbmusic/boot.js | 4 ++-- apps/gbmusic/metadata.json | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/apps/gbmusic/ChangeLog b/apps/gbmusic/ChangeLog index 0275542fb..433c58368 100644 --- a/apps/gbmusic/ChangeLog +++ b/apps/gbmusic/ChangeLog @@ -12,3 +12,4 @@ 0.11: Use default Bangle formatter for booleans 0.12: Issue newline before GB commands (solves issue with console.log and ignored commands) 0.13: Upgrade to new translation system +0.14: Fix auto-start saved state; fix clearing track number; allow widget clicks diff --git a/apps/gbmusic/app.js b/apps/gbmusic/app.js index 7f5aad8f3..8cf813fb9 100644 --- a/apps/gbmusic/app.js +++ b/apps/gbmusic/app.js @@ -91,8 +91,8 @@ function rScroller(l) { const w = g.stringWidth(l.label)+40, y = l.y+l.h/2; l.offset = l.offset%w; - g.setClipRect(l.x, l.y, l.x+l.w-1, l.y+l.h-1) - .setColor(l.col).setBgColor(l.bgCol) // need to set colors: iScroll calls this function outside Layout + //g.setClipRect(l.x, l.y, l.x+l.w-1, l.y+l.h-1) + g.setColor(l.col).setBgColor(l.bgCol) // need to set colors: iScroll calls this function outside Layout .setFontAlign(-1, 0) // left center .clearRect(l.x, l.y, l.x+l.w-1, l.y+l.h-1) .drawString(l.label, l.x-l.offset+40, y) @@ -433,15 +433,21 @@ function sendCommand(command) { drawControls(); } +function handleTouch(btn, pos) { + if (pos === undefined || pos.y >= Bangle.appRect.y) { + togglePlay(); + } +} + function togglePlay() { - sendCommand(stat==="play" ? "pause" : "play"); + sendCommand(stat==="play" ? "pause" : "playpause"); } /** * Setup touch+swipe for Bangle.js 1 */ function touch1() { - Bangle.on("touch", togglePlay); + Bangle.on("touch", handleTouch); Bangle.on("swipe", dir => { sendCommand(dir===1 ? "previous" : "next"); }); @@ -450,7 +456,7 @@ function touch1() { * Setup touch+swipe for Bangle.js 2 */ function touch2() { - Bangle.on("touch", togglePlay); + Bangle.on("touch", handleTouch); // swiping let drag; Bangle.on("drag", e => { diff --git a/apps/gbmusic/boot.js b/apps/gbmusic/boot.js index 154f85c2b..6cd544a21 100644 --- a/apps/gbmusic/boot.js +++ b/apps/gbmusic/boot.js @@ -10,7 +10,7 @@ setTimeout( // make other boot code run first, so we override e.g. android.boot. * Only runs while other apps are loaded */ function check() { - if (s!=="play" || !i || !a || !Bangle.CLOCK) return; // only launch app if we know which song we are playing, and autoLoad is enabled + if ((!s || s.state!=="play") || !i || !a || !Bangle.CLOCK) return; // only launch app if we know which song we are playing, and autoLoad is enabled delete (i.t); // store info and launch music app require("Storage").writeJSON("gbmusic.load.json", { @@ -27,7 +27,7 @@ setTimeout( // make other boot code run first, so we override e.g. android.boot. i = e; return APP ? info(e) : check(); case "musicstate": - s = e.state; + s = e; return APP ? state(e) : check(); default: // pass on other events diff --git a/apps/gbmusic/metadata.json b/apps/gbmusic/metadata.json index 0024a1708..a463e6ea0 100644 --- a/apps/gbmusic/metadata.json +++ b/apps/gbmusic/metadata.json @@ -2,7 +2,7 @@ "id": "gbmusic", "name": "Gadgetbridge Music Controls", "shortName": "Music Controls", - "version": "0.13", + "version": "0.14", "description": "Control the music on your Gadgetbridge-connected phone", "icon": "icon.png", "screenshots": [{"url":"screenshot_v1_d.png"},{"url":"screenshot_v1_l.png"}, From 63797c402abde3f827f30e9e9d1e8b1ab1789be8 Mon Sep 17 00:00:00 2001 From: Logan B <3870583+thinkpoop@users.noreply.github.com> Date: Sat, 8 Feb 2025 16:01:18 -0600 Subject: [PATCH 56/96] [gbmusic] fix lint warnings --- apps/gbmusic/app.js | 109 ++++++++++++++++++++++--------------------- apps/gbmusic/boot.js | 11 +++-- 2 files changed, 62 insertions(+), 58 deletions(-) diff --git a/apps/gbmusic/app.js b/apps/gbmusic/app.js index 8cf813fb9..1f6f6c620 100644 --- a/apps/gbmusic/app.js +++ b/apps/gbmusic/app.js @@ -128,57 +128,60 @@ function rInfo(l) { .setFontAlign(0, -1) // center top .drawString(l.label, l.x+l.w/2, l.y); } -/** - * Render icon - * @param l - */ -function rIcon(l) { - const x2 = l.x+l.w-1, - y2 = l.y+l.h-1; - switch(l.icon) { - case "pause": { - const w13 = l.w/3; - g.drawRect(l.x, l.y, l.x+w13, y2); - g.drawRect(l.x+l.w-w13, l.y, x2, y2); - break; - } - case "play": { - g.drawPoly([ - l.x, l.y, - x2, l.y+l.h/2, - l.x, y2, - ], true); - break; - } - case "previous": { - const w15 = l.w*1/5; - g.drawPoly([ - x2, l.y, - l.x+w15, l.y+l.h/2, - x2, y2, - ], true); - g.drawRect(l.x, l.y, l.x+w15, y2); - break; - } - case "next": { - const w45 = l.w*4/5; - g.drawPoly([ - l.x, l.y, - l.x+w45, l.y+l.h/2, - l.x, y2, - ], true); - g.drawRect(l.x+w45, l.y, x2, y2); - break; - } - default: { // red X - console.log(`Unknown icon: ${l.icon}`); - g.setColor("#f00") - .drawRect(l.x, l.y, x2, y2) - .drawLine(l.x, l.y, x2, y2) - .drawLine(l.x, y2, x2, l.y); - } - } -} + +// *** Unused Function *** +// // /** +// // * Render icon +// // * @param l +// // */ +// // function rIcon(l) { +// // const x2 = l.x+l.w-1, +// // y2 = l.y+l.h-1; +// // switch(l.icon) { +// // case "pause": { +// // const w13 = l.w/3; +// // g.drawRect(l.x, l.y, l.x+w13, y2); +// // g.drawRect(l.x+l.w-w13, l.y, x2, y2); +// // break; +// // } +// // case "play": { +// // g.drawPoly([ +// // l.x, l.y, +// // x2, l.y+l.h/2, +// // l.x, y2, +// // ], true); +// // break; +// // } +// // case "previous": { +// // const w15 = l.w*1/5; +// // g.drawPoly([ +// // x2, l.y, +// // l.x+w15, l.y+l.h/2, +// // x2, y2, +// // ], true); +// // g.drawRect(l.x, l.y, l.x+w15, y2); +// // break; +// // } +// // case "next": { +// // const w45 = l.w*4/5; +// // g.drawPoly([ +// // l.x, l.y, +// // l.x+w45, l.y+l.h/2, +// // l.x, y2, +// // ], true); +// // g.drawRect(l.x+w45, l.y, x2, y2); +// // break; +// // } +// // default: { // red X +// // console.log(`Unknown icon: ${l.icon}`); +// // g.setColor("#f00") +// // .drawRect(l.x, l.y, x2, y2) +// // .drawLine(l.x, l.y, x2, y2) +// // .drawLine(l.x, y2, x2, l.y); +// // } +// // } +// // } + let layout; function makeUI() { Bangle.loadWidgets(); @@ -489,10 +492,10 @@ function startLCDWatch() { Bangle.on("lcdPower", (on) => { if (on) { // redraw and resume scrolling - tick(); + //tick(); // Not sure what this function was; currently undefined layout.render(); fadeOut(); - if (offset.offset!==null) { + if (layout.title.offset!==null) { // Making an assumption about what offset.offset was supposed to be if (!iScroll) { iScroll = setInterval(scroll, 200); } diff --git a/apps/gbmusic/boot.js b/apps/gbmusic/boot.js index 6cd544a21..2f1c09d8a 100644 --- a/apps/gbmusic/boot.js +++ b/apps/gbmusic/boot.js @@ -1,6 +1,6 @@ setTimeout( // make other boot code run first, so we override e.g. android.boot.js GB () => { - const APP = global.__FILE__==="gbmusic.app.js", + const APP = globalThis.__FILE__==="gbmusic.app.js", a = !!(require("Storage").readJSON("gbmusic.json", 1) || {}).autoStart; let s, i; // state, info @@ -20,18 +20,19 @@ setTimeout( // make other boot code run first, so we override e.g. android.boot. load("gbmusic.app.js"); } - global.GB = (_GB => e => { + + globalThis.GB = (_GB => e => { // we eat music events! switch(e.t) { case "musicinfo": i = e; - return APP ? info(e) : check(); + return APP ? globalThis.info(e) : check(); case "musicstate": s = e; - return APP ? state(e) : check(); + return APP ? globalThis.state(e) : check(); default: // pass on other events if (_GB) setTimeout(_GB, 0, e); } - })(global.GB); + })(globalThis.GB); }, 1); From 13505ad7548f7e529ba081eb0563715907f2d3aa Mon Sep 17 00:00:00 2001 From: tonykakuuu Date: Sun, 9 Feb 2025 11:05:20 +0100 Subject: [PATCH 57/96] Set font color to g.theme.fg --- apps/txtreader/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/txtreader/app.js b/apps/txtreader/app.js index df61a2783..1e4fd30e9 100644 --- a/apps/txtreader/app.js +++ b/apps/txtreader/app.js @@ -27,7 +27,7 @@ function onFileSelected(file) { function displayText(offset, pageNumber) { g.clear(); g.setFont("6x8", 1); - g.setColor(1); + g.setColor(g.theme.fg); g.drawString("Page " + pageNumber, 10, 2); //g.drawString("Offset " + offset, 60, 2); g.drawString(file, g.getWidth() - file.length * 6, 2); From 5c98ab8f5ad253e685cfd687c973c5f5f2655a11 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sun, 9 Feb 2025 23:47:36 +1100 Subject: [PATCH 58/96] grandfatherclock: rename app to grandfatherclock --- .../ChangeLog | 0 .../README.md | 0 .../icon.png | Bin .../metadata.json | 4 ++-- .../widget.js | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) rename apps/{grandfather-clock => grandfatherclock}/ChangeLog (100%) rename apps/{grandfather-clock => grandfatherclock}/README.md (100%) rename apps/{grandfather-clock => grandfatherclock}/icon.png (100%) rename apps/{grandfather-clock => grandfatherclock}/metadata.json (80%) rename apps/{grandfather-clock => grandfatherclock}/widget.js (98%) diff --git a/apps/grandfather-clock/ChangeLog b/apps/grandfatherclock/ChangeLog similarity index 100% rename from apps/grandfather-clock/ChangeLog rename to apps/grandfatherclock/ChangeLog diff --git a/apps/grandfather-clock/README.md b/apps/grandfatherclock/README.md similarity index 100% rename from apps/grandfather-clock/README.md rename to apps/grandfatherclock/README.md diff --git a/apps/grandfather-clock/icon.png b/apps/grandfatherclock/icon.png similarity index 100% rename from apps/grandfather-clock/icon.png rename to apps/grandfatherclock/icon.png diff --git a/apps/grandfather-clock/metadata.json b/apps/grandfatherclock/metadata.json similarity index 80% rename from apps/grandfather-clock/metadata.json rename to apps/grandfatherclock/metadata.json index 2bd092e23..4d388d0b7 100644 --- a/apps/grandfather-clock/metadata.json +++ b/apps/grandfatherclock/metadata.json @@ -1,4 +1,4 @@ -{ "id": "grandfather-clock", +{ "id": "grandfatherclock", "name": "Grandfather Clock Widget", "shortName":"Grandfather Clock", "version":"0.01", @@ -9,6 +9,6 @@ "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ - {"name":"grandfather-clock.wid.js","url":"widget.js"} + {"name":"grandfatherclock.wid.js","url":"widget.js"} ] } diff --git a/apps/grandfather-clock/widget.js b/apps/grandfatherclock/widget.js similarity index 98% rename from apps/grandfather-clock/widget.js rename to apps/grandfatherclock/widget.js index 86294e087..fbbc260dc 100644 --- a/apps/grandfather-clock/widget.js +++ b/apps/grandfatherclock/widget.js @@ -1,6 +1,6 @@ (() => { - WIDGETS["grandfather-clock"] = { + WIDGETS["grandfatherclock"] = { area: "tr", width: 24, draw: function() { From 45cf7e3974f4611d75cfbee7371a15b1100f605c Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sun, 9 Feb 2025 23:57:07 +1100 Subject: [PATCH 59/96] grandfatherclock: update icon from https://icons8.com/icon/D2sDn8Iefcjx/old-fashioned-clock --- apps/grandfatherclock/icon.png | Bin 4971 -> 979 bytes apps/grandfatherclock/widget.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/grandfatherclock/icon.png b/apps/grandfatherclock/icon.png index b7ca0872f2cafac763afc700a2e1916ae524b2f1..8dc851c0432813ed8664031aa7433ce6fbc76eb2 100644 GIT binary patch delta 957 zcmV;u148`kCesIyB!3BTNLh0L01FcU01FcV0GgZ_000ApNkl=VpAk2NelW= zFATfTDNfMZyf{Txh!jseFYci8oU@&|ot=R%{NZrU!~6b!=YKrU`#wjd%D`ak_0?@o zde!Z$hg8(&tpDqF(pOYU7*fqE3W7<~ydof&Et=0M1S4SH>$(8}Unh(W4?!e61xv9g z5nkgxzpsS*4h7`<5<+PsmM+NvSeAvpu67;>dNtz!dKfw6NP{sg8-@K9^U@kl*YAP5EasZ)FNPKGzPstCk6pf0S z(&=;@fL^Z`ja`aHl?|ZLXkcMsK`=J9R;vZIT1_CVRx2znF7n3C zP3Itmu(wH8oT$mkNhmEXB@h;ih4)L0=AwwPF-rviH8C;4rBq8x3(q#{l^>wpbsZuz z(~=-uE*HdNv4n#xEYCs4*Gk}MFv=WS+HnlnFmBhuct4!DYaL~_d-tDZj zWE_BlaDUJn7Q~i#BovTtJ`~v8PLsK_WIjIb)tJ^6O6W|x+Ec0tjNwfi2MzZxn=+sK ziNj$o2O$V7Y;4SMTg1H`4?7fI<2|eyj1e;LFqg{%5Qk{B*KIN*Rm?i`vH;w*p63=b z>Wa4n!8m9*ZP0S_;oMmVVC*zBT{=e=#Dghah<~_wilWF|P1R?CvD>l_Ko)Pb!5vE_ z*Q`l}SZ|)9C~#RSp|#PLodb*y0M*)H;|%c0@7fFSR0Yj72Snp2ih_p?wb?s?g#b`u zrXrqQ1i)-KoD{&F%@!gZfa2pvi22`-cY^v@LH+^Uyl{{JyldW*)I6m`0N?d}1fZjC ze}8@gj6c{-0BX-1%0B>&x&T&scfh|VDmYPeG=BgLC5159V}w8BW`NHoSbnXCin5~o z05Fsk!uJm*fG-y}=*LGhd8T-P!5-r#^KlLMjLHZ2HC81Eusm9o-vB>9nUxRlvR62T z`nyjlAE2VFh!kw1dG@^tP8R1u5mReB5jGYq<~$1Dd@ANCr2uS2?ri`GL+Y=iRH?E( fwgH@({R001pqzAz%SiXX00000NkvXXu0mjf@$}xj2hwsqDeZPy(KCTkSGC0kY&^vI_XZ*Ko*h!LB|nL6vt&8 zcMy?5c_J=|3kr;i%eXuR(Ryz6ltD&)jtf|h;)eKchefQJs#jLM`DeOr?z!il^WAg5 zd+tekSyaR{SLb2Q5Cpl(!lW}n4^z$29(>2yyj}{rMj~FOlF9rbM=$`EG&_h!*?>mt zBiqnyAzPqZ0@@%TQ#Mo^M(bzoR{(ie%&@UK<3bFAXm^Af`$Ou6ZGYvkxRSQ zItFCw<7j=tfJ7np^wVVWC_2L8z$~r^_`?Vvg*hk}rXvW-;h}sEu%;D%h=@Wmyr}|# z(iW4!!BMi{V7kGmSCJ_M1X&6f{3r=K73G;5IlHukIUqgC{e0Ax$0dwahnz#o+>&x* zM}&X<#z8)8ji>jt6Nj3cFDb5`_$49EAuiCZgO=)D=s9=$>9=cwmJeYEG@Z?S`9)Lh zz^6k0aDHt|R(V1wn(wy1dX~>C=TV`Tm%>ZNs2-Y1Hsz=n+>RDrox4Jv`SM)?Hdc?+ z`MRCW*TtV6eww>^Lqq0P(aGs+g1(Iiz#9848&%D!?Ko5YVBc1C=!)=pMWUdIo|EER z6JwE>7P6(RBxzmSrJCJ_rk35YNxRb`J5NS^Jv-q(y2pJ?W!~64H~O|Ei2pvfZF5Ke zA}wg}7}<%PWv`hrE^g?GFI>uka__!6@xJ+GO8v=yZQtxU9lFh~ddIQ1%g9#Ut~&mM zwl>qot|)uLo+lN8tecTn9%-5L?4Ijwy{~KKO}4CztP{R-kulSp8=rYQ*S#IOAbP-% zBmL%Gzg2yxA@vP}Yhrf}Z*F!Q!k*b)bGCLq`k!`vWb$`YG*V;9d+|mWkb@R7Cf*z` z4@Z@HEepf-3W88wom( z#bd$D5DS@(FeW?G1B|!|ohc3Nh5#c8Lt{1@P&PXwBZHN}W$BG-Hb*QLvtfjdAWUGv zG-c|{n1!h`jiw;FFr;^n3zJJW|lA*V4mI+pVlCk_rmK;-7Ek;*cQyd z=CEM4R?F_|VKRrL1CZ{3{?fw~lW8E>GYOME&8Q?o(g~e;bYBQu+3RmeGp1O#gDcrY z3ZVt2Ca@~!qa~>u*Xu!1peD5js}~^qBTF->`asr4u~9SD?eq-tlS&xW`Y5hfk~nG=d3-Kk$l)VQ6_*e&c}gM96yqEfQ>ox96aoPs<_U#; zpkz9e8Ph2V3JQR;NPxrRDKV9jCt?y@F~Z~t5S*#t!9pg+6W}}%4)XwfABadJ39=GP z=^GUVg###DEEHm}K+IGqI9w(V;{y~GEMOuShH*JcF^8)VTcL0z8mc#HF>suu7E=>! zgHCOopa@3;qht~W!h%0&qEaxk3OGm@;iN9j@?j!|)DqEVjAD}`P0gr$yke=3GD7v5ZpvHe3ONNG^P5}_c zggHzu+(Q_*n=p3whS^lj=-F`q`%jz%SPl9V8Q|BY1H}u}LUwO4?B)!_`*(i2&*JY~ zf=>Uu$S3jpnXb=teG&toWc)e1KGXF{41ALD=j{5w(dGQ%b&Ak|e?b}GW$AtPf=uwD zWv`eqO$xoIp5miB)&h-_AuPcJK`tItqd^6QLx9r3ER%;g{7xI`GJt<@PFoEG**eOk zfiaqOV!D@?Kcg(q@o>h?qh&tDoWqwGaSu|9=BK6~_^|^kxOqGOb^S46Tm1^R z?C*$HN z%BRrqD2cje%5RY4{P)kp?j$~=Jv=ym-#N3IjCQR))ii8Yy6ucdKVNJ0>R229<_4+F z6h4WVv`qsyWjv^ke%B-f1%tjQW1y~VcK zo@9xK&Swaq!|_QrM{No@c=mOh^~;}BUyQ#CweH&(S~^ffz^nWkld&}Qf%<#rVt?ug z8=q?&D$I2fTcTV0ooH%0)RPJBaZu7^oh~=}YM=l$9 zB&1Cgw(y+3$adhahwaep;5Vmye3O3_c%8e2v2*`<**agGZ*nZ4@OHDdn>0h2NdF=IW{j9Xj>Opk{)0fTR zHZ4}sI^(ivu5AQH!kD<9!c)U$p+I4L>k0JL(%+QmD$#={pwmL+oNB*XI5lcQ0&q!*`eAsmGctJnjr=rjy$T4a|yk>SwvId(gOT!WX*B6S8ikU9qPH_$E(ss?WXazPkKX z?4C6?t-gYMkGuX)k2XyBReEGYJmgwXNW*@$;SAi^g7afI^S2+g+I|$us7h opOlNhcF&_5`ir#+-kwgUO>Xz<#^+Su0oMeQg+xgA1|{bF7f!JEQUCw| diff --git a/apps/grandfatherclock/widget.js b/apps/grandfatherclock/widget.js index fbbc260dc..af2d910f9 100644 --- a/apps/grandfatherclock/widget.js +++ b/apps/grandfatherclock/widget.js @@ -5,7 +5,7 @@ width: 24, draw: function() { g.reset(); - g.drawImage(atob("GBiBAAAYAAA8AAA8AAD/AAH/gAP/wAf/4Afn4Afn4Afn4Afn4Afn4Af/4Af/4Afn4Afn4A/n8A//8B//+D///AAAAAAAAAA8AAAYAA=="), this.x, this.y); + g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); } }; From 717d263159e208d0310476bddb39a4a21827a972 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Mon, 10 Feb 2025 00:47:16 +1100 Subject: [PATCH 60/96] grandfatherclock: remove unused widget icon space --- apps/grandfatherclock/widget.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/grandfatherclock/widget.js b/apps/grandfatherclock/widget.js index af2d910f9..66e63830b 100644 --- a/apps/grandfatherclock/widget.js +++ b/apps/grandfatherclock/widget.js @@ -2,7 +2,6 @@ WIDGETS["grandfatherclock"] = { area: "tr", - width: 24, draw: function() { g.reset(); g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); From 53f441567523a59b598f683231936c65b73faaeb Mon Sep 17 00:00:00 2001 From: June Bennison Date: Mon, 10 Feb 2025 00:47:37 +1100 Subject: [PATCH 61/96] grandfatherclock: implement settings menu --- apps/grandfatherclock/settings.js | 83 +++++++++++++++++++++++++++++++ apps/grandfatherclock/widget.js | 53 ++++++++++---------- 2 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 apps/grandfatherclock/settings.js diff --git a/apps/grandfatherclock/settings.js b/apps/grandfatherclock/settings.js new file mode 100644 index 000000000..6ab3b43b3 --- /dev/null +++ b/apps/grandfatherclock/settings.js @@ -0,0 +1,83 @@ +(function(back) { + + const configFile = "grandfatherclock.json"; + + let config = Object.assign({ + twelve_hour: true, + swap_meridian: false, + hour_attention_buzz_ms: 1000, + hour_count_buzz_ms: 250, + fraction_count_buzz_ms: 250, + fractions_of_hour: 4, // 4 = 15min intervals, 6 = 10min intervals + wait_ms: 500, + meridian_buzz_ms: 50, + meridian_buzz_wait_ms: 300 + }, require('Storage').readJSON("grandfatherclock.json", true) || {}); + + let writeConfig = function() { + require('Storage').writeJSON(configFile, config); + }; + + E.showMenu({ + "": {"title" : "Grandfather Clock"}, + "< Back": () => back(), + "12 / 24 hour": { + value: config.twelve_hour, + format: v => v ? "12" : "24", + onchange: v => { + config.twelve_hour = v; + writeConfig(); + } + },"Swap meridian": { + value: config.swap_meridian, + format: v => v ? "Yes" : "No", + onchange: v => { + config.swap_meridian = v; + writeConfig(); + } + },"Hr attn. buzz length (ms)": { + value: config.hour_attention_buzz_ms, + onchange: v => { + config.hour_attention_buzz_ms = v; + writeConfig(); + } + },"Hr count buzz (ms)": { + value: config.hour_count_buzz_ms, + onchange: v => { + config.hour_count_buzz_ms = v; + writeConfig(); + } + },"Frac. count buzz (ms)": { + value: config.fraction_count_buzz_ms, + onchange: v => { + config.fraction_count_buzz_ms = v; + writeConfig(); + } + },"Fracs. of hour": { + value: config.fractions_of_hour, + onchange: v => { + config.fractions_of_hour = v; + writeConfig(); + } + },"Count wait (ms)": { + value: config.wait_ms, + onchange: v => { + config.wait_ms = v; + writeConfig(); + } + },"Meridian buzz (ms)": { + value: config.meridian_buzz_ms, + onchange: v => { + config.meridian_buzz_ms = v; + writeConfig(); + } + },"Meridian wait (ms)": { + value: config.meridian_buzz_wait_ms, + onchange: v => { + config.meridian_buzz_wait_ms = v; + writeConfig(); + } + } + }); + +}) diff --git a/apps/grandfatherclock/widget.js b/apps/grandfatherclock/widget.js index 66e63830b..32162186a 100644 --- a/apps/grandfatherclock/widget.js +++ b/apps/grandfatherclock/widget.js @@ -2,36 +2,39 @@ WIDGETS["grandfatherclock"] = { area: "tr", + width: 16, draw: function() { g.reset(); g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); } }; - // todo: all of these configurable through app settings menu. - const twelve_hour = true; - const swap_meridian = false; - const hour_attention_buzz_ms = 1000; - const hour_count_buzz_ms = 250; - const fraction_count_buzz_ms = 250; - const fractions_of_hour = 4; // 4 = 15min intervals, 6 = 10min intervals - const wait_ms = 500; - const meridian_buzz_ms = 50; - const meridian_buzz_wait_ms = 300; + // sensible defaults + let config = Object.assign({ + twelve_hour: true, + swap_meridian: false, + hour_attention_buzz_ms: 1000, + hour_count_buzz_ms: 250, + fraction_count_buzz_ms: 250, + fractions_of_hour: 4, // 4 = 15min intervals, 6 = 10min intervals + wait_ms: 500, + meridian_buzz_ms: 50, + meridian_buzz_wait_ms: 300 + }, require('Storage').readJSON("grandfatherclock.json", true) || {}); // or, load the app settings file. let date; - let fractionMs = 3600000 / fractions_of_hour; + let fractionMs = 3600000 / config.fractions_of_hour; let chime = function () { date = new Date(); - let hourFrac = Math.floor(date.getMinutes() / (60 / fractions_of_hour)); + let hourFrac = Math.floor(date.getMinutes() / (60 / config.fractions_of_hour)); if (hourFrac == 0) { // if it's an o'clock hour - let chimeHour = (twelve_hour ? date.getHours() % 12 : date.getHours()); - if (chimeHour == 0) (twelve_hour ? chimeHour += 12 : chimeHour += 24); + let chimeHour = (config.twelve_hour ? date.getHours() % 12 : date.getHours()); + if (chimeHour == 0) (config.twelve_hour ? chimeHour += 12 : chimeHour += 24); - Bangle.buzz(hour_attention_buzz_ms).then(() => { // initial buzz - setTimeout(hourChime, wait_ms, chimeHour); // wait a period before doing the first chime + Bangle.buzz(config.hour_attention_buzz_ms).then(() => { // initial buzz + setTimeout(hourChime, config.wait_ms, chimeHour); // wait a period before doing the first chime }); } else { // if it's a fraction of an hour fractionChime(hourFrac); @@ -42,27 +45,27 @@ let hourChime = function (hoursLeftToChime) { hoursLeftToChime--; - Bangle.buzz(hour_count_buzz_ms).then(() => { // recursive. buzz and wait to do the next buzz. + Bangle.buzz(config.hour_count_buzz_ms).then(() => { // recursive. buzz and wait to do the next buzz. if (hoursLeftToChime > 0) { - setTimeout(hourChime, wait_ms, hoursLeftToChime); - } else if (twelve_hour) { // once finished with the hour count - setTimeout(meridianChime, wait_ms, (date.getHours() >= 12)); // if in twelve hour mode, queue up the meridian chime. + setTimeout(hourChime, config.wait_ms, hoursLeftToChime); + } else if (config.twelve_hour) { // once finished with the hour count + setTimeout(meridianChime, config.wait_ms, (date.getHours() >= 12)); // if in twelve hour mode, queue up the meridian chime. } }); }; let fractionChime = function (fractionsLeftToChime) { fractionsLeftToChime--; - Bangle.buzz(fraction_count_buzz_ms).then(() => { // recursive. buzz and wait to do the next buzz. - if (fractionsLeftToChime > 0) setTimeout(fractionChime, wait_ms, fractionsLeftToChime); + Bangle.buzz(config.fraction_count_buzz_ms).then(() => { // recursive. buzz and wait to do the next buzz. + if (fractionsLeftToChime > 0) setTimeout(fractionChime, config.wait_ms, fractionsLeftToChime); }); }; let meridianChime = function (meridian) { - if ((swap_meridian ? !meridian : meridian)) { // default: if PM - Bangle.buzz(meridian_buzz_ms).then(setTimeout(Bangle.buzz, meridian_buzz_wait_ms, meridian_buzz_ms)); // buzz once, wait, buzz again. + if ((config.swap_meridian ? !meridian : meridian)) { // default: if PM + Bangle.buzz(config.meridian_buzz_ms).then(setTimeout(Bangle.buzz, config.meridian_buzz_wait_ms, config.meridian_buzz_ms)); // buzz once, wait, buzz again. } else { // default: if AM - Bangle.buzz(meridian_buzz_ms); // buzz once. + Bangle.buzz(config.meridian_buzz_ms); // buzz once. } }; From 1b5b5392b6d0d55959c4acf37e9ac48cd8536575 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Mon, 10 Feb 2025 00:52:36 +1100 Subject: [PATCH 62/96] grandfatherclock: update metadata for settings --- apps/grandfatherclock/metadata.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/grandfatherclock/metadata.json b/apps/grandfatherclock/metadata.json index 4d388d0b7..bd1166b3d 100644 --- a/apps/grandfatherclock/metadata.json +++ b/apps/grandfatherclock/metadata.json @@ -9,6 +9,10 @@ "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ - {"name":"grandfatherclock.wid.js","url":"widget.js"} + {"name":"grandfatherclock.wid.js","url":"widget.js"}, + {"name":"grandfatherclock.settings.js","url":"settings.js"} + ], + "data": [ + {"name":"grandfatherclock.json"} ] } From 0e06e82a25d60adb8c2b8aaea52127d1a010d480 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Mon, 10 Feb 2025 01:00:05 +1100 Subject: [PATCH 63/96] grandfatherclock: clean settings --- apps/grandfatherclock/settings.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/grandfatherclock/settings.js b/apps/grandfatherclock/settings.js index 6ab3b43b3..e59e969bf 100644 --- a/apps/grandfatherclock/settings.js +++ b/apps/grandfatherclock/settings.js @@ -21,16 +21,14 @@ E.showMenu({ "": {"title" : "Grandfather Clock"}, "< Back": () => back(), - "12 / 24 hour": { + "12 hour": { value: config.twelve_hour, - format: v => v ? "12" : "24", onchange: v => { config.twelve_hour = v; writeConfig(); } },"Swap meridian": { value: config.swap_meridian, - format: v => v ? "Yes" : "No", onchange: v => { config.swap_meridian = v; writeConfig(); From 24d4a9284dc963b6809a60ec6cad2b68f37ad347 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Mon, 10 Feb 2025 01:06:21 +1100 Subject: [PATCH 64/96] grandfatherclock: draw widget option --- apps/grandfatherclock/settings.js | 8 ++++++++ apps/grandfatherclock/widget.js | 21 ++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/apps/grandfatherclock/settings.js b/apps/grandfatherclock/settings.js index e59e969bf..6401dffa5 100644 --- a/apps/grandfatherclock/settings.js +++ b/apps/grandfatherclock/settings.js @@ -3,6 +3,7 @@ const configFile = "grandfatherclock.json"; let config = Object.assign({ + draw_widget: true, twelve_hour: true, swap_meridian: false, hour_attention_buzz_ms: 1000, @@ -21,6 +22,13 @@ E.showMenu({ "": {"title" : "Grandfather Clock"}, "< Back": () => back(), + "Draw widget": { + value: config.draw_widget, + onchange: v => { + config.draw_widget = v; + writeConfig(); + } + }, "12 hour": { value: config.twelve_hour, onchange: v => { diff --git a/apps/grandfatherclock/widget.js b/apps/grandfatherclock/widget.js index 32162186a..b7014d595 100644 --- a/apps/grandfatherclock/widget.js +++ b/apps/grandfatherclock/widget.js @@ -1,16 +1,8 @@ (() => { - WIDGETS["grandfatherclock"] = { - area: "tr", - width: 16, - draw: function() { - g.reset(); - g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); - } - }; - // sensible defaults let config = Object.assign({ + draw_widget: true, twelve_hour: true, swap_meridian: false, hour_attention_buzz_ms: 1000, @@ -22,6 +14,17 @@ meridian_buzz_wait_ms: 300 }, require('Storage').readJSON("grandfatherclock.json", true) || {}); // or, load the app settings file. + WIDGETS["grandfatherclock"] = { + area: "tr", + width: config.draw_widget ? 16, + draw: function() { + if (config.draw_widget) { + g.reset(); + g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); + } + } + }; + let date; let fractionMs = 3600000 / config.fractions_of_hour; From 4630ff1d855878fd5d602ce2e1a4c456b37b4242 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Mon, 10 Feb 2025 01:11:07 +1100 Subject: [PATCH 65/96] grandfatherclock: undefine widget width & draw ifn't --- apps/grandfatherclock/widget.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/grandfatherclock/widget.js b/apps/grandfatherclock/widget.js index b7014d595..bb9d9406f 100644 --- a/apps/grandfatherclock/widget.js +++ b/apps/grandfatherclock/widget.js @@ -16,13 +16,11 @@ WIDGETS["grandfatherclock"] = { area: "tr", - width: config.draw_widget ? 16, - draw: function() { - if (config.draw_widget) { - g.reset(); - g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); - } - } + width: config.draw_widget ? 16 : undefined, + draw: config.draw_widget ? function() { + g.reset(); + g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); + } : undefined }; let date; From cf0c293e60fffcb28c3f7b5e6c026a70ecfa37bc Mon Sep 17 00:00:00 2001 From: June Bennison Date: Mon, 10 Feb 2025 01:59:42 +1100 Subject: [PATCH 66/96] grandfatherclock: metadata & changelog --- apps/grandfatherclock/ChangeLog | 1 + apps/grandfatherclock/README.md | 10 ++-------- apps/grandfatherclock/metadata.json | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/apps/grandfatherclock/ChangeLog b/apps/grandfatherclock/ChangeLog index 4c21f3ace..a21dc397d 100644 --- a/apps/grandfatherclock/ChangeLog +++ b/apps/grandfatherclock/ChangeLog @@ -1 +1,2 @@ 0.01: New Widget! +0.02: rename, new icon, settings menu! diff --git a/apps/grandfatherclock/README.md b/apps/grandfatherclock/README.md index fdf98dd86..b701164cc 100644 --- a/apps/grandfatherclock/README.md +++ b/apps/grandfatherclock/README.md @@ -1,10 +1,10 @@ # Grandfather Clock -A widget that runs in the background and chimes on every (configurable*) fraction of an hour, similar to Chimer, and counts out the fractions and the o'clock hour. +A widget that runs in the background and chimes on every (configurable) fraction of an hour, similar to Chimer, and counts out the fractions and the o'clock hour. ## Usage -Once installed, see the App Settings page for options. * +Once installed, see the App Settings page for options. Defaults: - Twelve hour mode is ENABLED. @@ -24,9 +24,3 @@ Drop me a message at @yogsoy on Discord if you need help / discover a bug that I ## Creator Written by June B (yogsoy), inspired by aaronrolls' Chimer. - -## Todo - -\* App settings are not implemented yet, sorry! Await v0.02. - -A better icon would be nice. A 1-bit simplified grandfather clock. diff --git a/apps/grandfatherclock/metadata.json b/apps/grandfatherclock/metadata.json index bd1166b3d..053e384d6 100644 --- a/apps/grandfatherclock/metadata.json +++ b/apps/grandfatherclock/metadata.json @@ -1,7 +1,7 @@ { "id": "grandfatherclock", "name": "Grandfather Clock Widget", "shortName":"Grandfather Clock", - "version":"0.01", + "version":"0.02", "description": "A widget that chimes every fraction of an hour (similar to Chimer), and counts out the fractions and the o'clock hour.", "icon": "icon.png", "type": "widget", From ea9f71031f76fb02314c0016376caef80c99b6d9 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Sun, 9 Feb 2025 22:30:13 -0500 Subject: [PATCH 67/96] Add v0.1 of daymoon clock --- apps/daymoon/ChangeLog | 0 apps/daymoon/README.md | 3 + apps/daymoon/app-icon.js | Bin 0 -> 1027 bytes apps/daymoon/app.js | 162 ++++++++++++++++++++++++++++++++++++ apps/daymoon/icon.png | Bin 0 -> 1660 bytes apps/daymoon/metadata.json | 18 ++++ apps/daymoon/screenshot.png | Bin 0 -> 4446 bytes 7 files changed, 183 insertions(+) create mode 100644 apps/daymoon/ChangeLog create mode 100644 apps/daymoon/README.md create mode 100644 apps/daymoon/app-icon.js create mode 100644 apps/daymoon/app.js create mode 100644 apps/daymoon/icon.png create mode 100644 apps/daymoon/metadata.json create mode 100644 apps/daymoon/screenshot.png diff --git a/apps/daymoon/ChangeLog b/apps/daymoon/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/apps/daymoon/README.md b/apps/daymoon/README.md new file mode 100644 index 000000000..ffb33ef69 --- /dev/null +++ b/apps/daymoon/README.md @@ -0,0 +1,3 @@ +# FairBangle +This started out with a goal to recreate the Fair Circadian watchface from Pebble for the Bangle.js2. +It ended up with me making a mostly new watchface that has the moon phase more prominent, but keeps the single dial 24 hour clock with daylight and sunset highlighted. diff --git a/apps/daymoon/app-icon.js b/apps/daymoon/app-icon.js new file mode 100644 index 0000000000000000000000000000000000000000..47663be0c38d52ffb95e7be2445bcac124bfab0b GIT binary patch literal 1027 zcmV+e1pNDnP)Px&y-7qtRA@u(S?zM{AP7y~|Dkh75rqQ??(Us!XWBoVRHFjt1JnDuuICaz&!Zl% z`@ZGy_2b6>0{C`?etiWV0QDy@-@Aq;qxascYh)PJ}e)sqiSeD`{j*;R?L`A z6ZlpDX{N_1DF|B$`Th$2O!Zz2;2H2>n80r(yzTVCJotNi?YIIbB&Lk*Gdah{!sYpr zGn|02-CQm1}qIZo)?cLG@e zgv){9$ux^;-s+^)SW?@beN1w|S@<}B%u!d6q)t?FsaC979o+;Bp)TruyT11Tqd=;Z211?>c)BlDz*8HoKCf{=`$X*63PKpbkmAXDe5NXRsFr_R z+K~A`#E+==D)_)63^grF!iJCuoktFw`2cc&pOqS!u2u_&@qwOkqm^C|>+s75IP+_T zQx4$a)lvGg5CD?6zW_HWx*z)Hr6I)*{5l7aYaKG;JWg))hpjnbS)Y1G5?E(r!ACmt zDF>uX%Ve^grAEeDOB;_qG3s5M-shwj@;Jch^!K+Ns%a%6Rgl=Ub0qdq=n1pZS6!=B5`~K7f_CNSIuyTxh%l=uBAk;SWP69EdJFQ3ARq#ZK&TAXB5) zeZW;8;Gh>^`dw&;S;V6^w^D)V3X1Ew0p#7NtwfCj!?#PAr@0vic#aHgbD`Py`t~a6 z*J@XR4D;TKsSjWi#kU|&m+=5zW!Aky-v=s~#}44A0&;`Qon@v>hEDzg61e|%{hEws zy1X3n+8R#B2jt+I+#o!Lc1>1,32); + //this gives r/2 pts on the way down and up, capped at 64 total for polyfill + let a=[],b=[],s1=1,s2=0; + // scale s1 is 1 or -1 for fixed edge of the shadow; defined via case switches below + // scale s2 factor for the moving edge of the shadow + // need to do some computation to simplify for new/full moon if k 'close enough' to 0 or 1/-1 + // + let isWaxing=(mp.phase<0.5); + s1 = isWaxing ? -1 : 1; + s2 = isWaxing ? 1-2*k : 2*k-1; + let tr =(pos.r+0.5); + for (var i=0;i{ + if (secondInterval) clearInterval(secondInterval); + secondInterval = undefined; + if (on) { + secondInterval = setInterval(draw, 10000); //was 1000 + draw(); // draw immediately + } +}); +/* Show launcher when middle button pressed +This should be done *before* Bangle.loadWidgets so that +widgets know if they're being loaded into a clock app or not */ +Bangle.setUI("clock"); +// Load widgets +Bangle.loadWidgets(); +Bangle.drawWidgets(); \ No newline at end of file diff --git a/apps/daymoon/icon.png b/apps/daymoon/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f9cd8417826f35b096abdcbfbab4e22b622d163f GIT binary patch literal 1660 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 literal 0 HcmV?d00001 From f317d9c8ad7415b23ab58a5ce6a31dec69460f0c Mon Sep 17 00:00:00 2001 From: MomentumV Date: Sun, 9 Feb 2025 23:00:50 -0500 Subject: [PATCH 68/96] Fix missing comma, update name in storage --- apps/daymoon/metadata.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/daymoon/metadata.json b/apps/daymoon/metadata.json index f7ebdb8f0..813de8d93 100644 --- a/apps/daymoon/metadata.json +++ b/apps/daymoon/metadata.json @@ -1,8 +1,7 @@ -{ - "id": "daymoon", +{ "id": "daymoon", "name": "Circadian Moon Clock", "version": "0.1", - "dependencies": {"mylocation":"app"}, + "dependencies": {"mylocation":"app"}, "description": "A 24 hour clockface showing the Moon Phase and portion of the day that the Sun is up", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], @@ -10,9 +9,9 @@ "tags": "clock,moon,lunar", "supports": ["BANGLEJS2"], "allow_emulator": true, - "readme":"README.md" + "readme":"README.md", "storage": [ - {"name":"fairbangle.app.js","url":"app.js"}, - {"name":"fairbangle.img","url":"app-icon.js","evaluate":true} + {"name":"daymoon.app.js","url":"app.js"}, + {"name":"daymoon.img","url":"app-icon.js","evaluate":true} ] } \ No newline at end of file From 1ea2fbd72befb2458b4755dcaca1eddade5f0de6 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Sun, 9 Feb 2025 23:08:59 -0500 Subject: [PATCH 69/96] Fix icon url --- apps/daymoon/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daymoon/metadata.json b/apps/daymoon/metadata.json index 813de8d93..04214ab4d 100644 --- a/apps/daymoon/metadata.json +++ b/apps/daymoon/metadata.json @@ -3,7 +3,7 @@ "version": "0.1", "dependencies": {"mylocation":"app"}, "description": "A 24 hour clockface showing the Moon Phase and portion of the day that the Sun is up", - "icon": "app.png", + "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], "type": "clock", "tags": "clock,moon,lunar", From 26819f0dfceb0ac9205106cf0e97585696f64597 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Mon, 10 Feb 2025 00:11:27 -0500 Subject: [PATCH 70/96] Fix app icon to be image string, not PNG binary --- apps/daymoon/app-icon.js | Bin 1027 -> 1094 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/daymoon/app-icon.js b/apps/daymoon/app-icon.js index 47663be0c38d52ffb95e7be2445bcac124bfab0b..a87dd3ee2b1281ba88913a91aeeddf07a39eb5ac 100644 GIT binary patch literal 1094 zcmWlXO_QoR7=-`Jtmc$e7lEL#xQiqZ%s6~G7sc6)h~Y~z5J=Qte{sR9M+ zLn?rY1U&6o4jQSXU;IKWZ11-h25Az)JLTrEz#<@u?$D}|_j7@!yX(ow8(>Wa&LsI} zF{^XKaE<$I;|;>qq79kJC6obFNtiP#kl{GU>r1b{I?n_8TfZuNU5#Lce*o#msR8or zXv;FhpINZ1n}ga%s8EIB{F=xcqDj+p8wm?v++~s!+s%Mu^ z7#vKrz8MKfBganc4vrctE&R4@wmQS=+eYSU#3~gd*V75zuIMr7j@yS83K)Dk=Eul|-`wT6xS>f(z<_r!`yD_^{Gv8&fdZUd z#nBoA9YZuMs2sa)?Sm~ZO;k1W<;M1Fgdv4K%P^|v(n_{t@^D479Rx_@QR-+}5%~HU z&t6(nTQt3_T`7LfH1i4Q7-Y$66o>ZurMb4>dwuV53v?kfNDofew0-5UOgBod)1yKd NF=%MNf8YN6`5#tnWGw&y literal 1027 zcmV+e1pNDnP)Px&y-7qtRA@u(S?zM{AP7y~|Dkh75rqQ??(Us!XWBoVRHFjt1JnDuuICaz&!Zl% z`@ZGy_2b6>0{C`?etiWV0QDy@-@Aq;qxascYh)PJ}e)sqiSeD`{j*;R?L`A z6ZlpDX{N_1DF|B$`Th$2O!Zz2;2H2>n80r(yzTVCJotNi?YIIbB&Lk*Gdah{!sYpr zGn|02-CQm1}qIZo)?cLG@e zgv){9$ux^;-s+^)SW?@beN1w|S@<}B%u!d6q)t?FsaC979o+;Bp)TruyT11Tqd=;Z211?>c)BlDz*8HoKCf{=`$X*63PKpbkmAXDe5NXRsFr_R z+K~A`#E+==D)_)63^grF!iJCuoktFw`2cc&pOqS!u2u_&@qwOkqm^C|>+s75IP+_T zQx4$a)lvGg5CD?6zW_HWx*z)Hr6I)*{5l7aYaKG;JWg))hpjnbS)Y1G5?E(r!ACmt zDF>uX%Ve^grAEeDOB;_qG3s5M-shwj@;Jch^!K+Ns%a%6Rgl=Ub0qdq=n1pZS6!=B5`~K7f_CNSIuyTxh%l=uBAk;SWP69EdJFQ3ARq#ZK&TAXB5) zeZW;8;Gh>^`dw&;S;V6^w^D)V3X1Ew0p#7NtwfCj!?#PAr@0vic#aHgbD`Py`t~a6 z*J@XR4D;TKsSjWi#kU|&m+=5zW!Aky-v=s~#}44A0&;`Qon@v>hEDzg61e|%{hEws zy1X3n+8R#B2jt+I+#o!Lc1 Date: Mon, 10 Feb 2025 13:37:30 -0500 Subject: [PATCH 71/96] 0.1 Release Add changelog, update app icon, lay out development path. --- apps/daymoon/ChangeLog | 1 + apps/daymoon/README.md | 16 ++++++++++++++-- apps/daymoon/{icon.png => daymoon.png} | Bin apps/daymoon/metadata.json | 6 +++--- 4 files changed, 18 insertions(+), 5 deletions(-) rename apps/daymoon/{icon.png => daymoon.png} (100%) diff --git a/apps/daymoon/ChangeLog b/apps/daymoon/ChangeLog index e69de29bb..1e5e620fe 100644 --- a/apps/daymoon/ChangeLog +++ b/apps/daymoon/ChangeLog @@ -0,0 +1 @@ +0.1 First functional release \ No newline at end of file diff --git a/apps/daymoon/README.md b/apps/daymoon/README.md index ffb33ef69..cef843569 100644 --- a/apps/daymoon/README.md +++ b/apps/daymoon/README.md @@ -1,3 +1,15 @@ -# FairBangle -This started out with a goal to recreate the Fair Circadian watchface from Pebble for the Bangle.js2. +# DayMoon Circadian +This started out with a goal to recreate the Pebble [Fair Circadian watchface](https://setpebble.com/app/fair-circadian) by Matthew Clark for the Bangle.js2. It ended up with me making a mostly new watchface that has the moon phase more prominent, but keeps the single dial 24 hour clock with daylight and sunset highlighted. + +## Future Development +Feature roadmap: +0.1.1 fix the layout so that the widget bar is clear; + put sunrise/sunset at angle on sides +0.2 add Day of week and month display +1.0 Seconds display +1.1 Color Themes (and settings/options) +1.2 Moon display angle represents how it looks in the sky +1.3 custom/bigger/fitted time digits + +2.0 clockinfo support? diff --git a/apps/daymoon/icon.png b/apps/daymoon/daymoon.png similarity index 100% rename from apps/daymoon/icon.png rename to apps/daymoon/daymoon.png diff --git a/apps/daymoon/metadata.json b/apps/daymoon/metadata.json index 04214ab4d..2d9430043 100644 --- a/apps/daymoon/metadata.json +++ b/apps/daymoon/metadata.json @@ -1,9 +1,9 @@ { "id": "daymoon", - "name": "Circadian Moon Clock", + "name": "DayMoon Circadian Clock", "version": "0.1", - "dependencies": {"mylocation":"app"}, + "dependencies": {"mylocation":"app"}, "description": "A 24 hour clockface showing the Moon Phase and portion of the day that the Sun is up", - "icon": "icon.png", + "icon": "daymoon.png", "screenshots": [{"url":"screenshot.png"}], "type": "clock", "tags": "clock,moon,lunar", From 0fb7bf42ec9bec2ad890ce28f792afe172cf49f8 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 11 Feb 2025 07:15:45 +0000 Subject: [PATCH 72/96] drained: redisplay immediately when charge status changes --- apps/drained/ChangeLog | 1 + apps/drained/app.js | 1 + apps/drained/app.ts | 1 + apps/drained/metadata.json | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/drained/ChangeLog b/apps/drained/ChangeLog index 0667d8ff6..af1ee299b 100644 --- a/apps/drained/ChangeLog +++ b/apps/drained/ChangeLog @@ -6,3 +6,4 @@ 0.05: Enhance menu: permit toggling bluetooth 0.06: Display clock in green when charging, with "charging" text 0.07: Correctly restore full power when the charged threshold is reached +0.08: Redisplay immediately on changes to charging status diff --git a/apps/drained/app.js b/apps/drained/app.js index cefddbcc7..9f8f6988f 100644 --- a/apps/drained/app.js +++ b/apps/drained/app.js @@ -118,6 +118,7 @@ Bangle.on("charging", function (charging) { drainedInterval = clearInterval(drainedInterval); if (charging) drainedInterval = setInterval(checkCharge, interval * 60 * 1000); + draw(); }); if (!keepStartup) { var storage = require("Storage"); diff --git a/apps/drained/app.ts b/apps/drained/app.ts index bd79ebcab..57c71e727 100644 --- a/apps/drained/app.ts +++ b/apps/drained/app.ts @@ -151,6 +151,7 @@ Bangle.on("charging", charging => { drainedInterval = clearInterval(drainedInterval) as undefined; if(charging) drainedInterval = setInterval(checkCharge, interval * 60 * 1000); + draw(); // redraw to update charging status on screen }); if(!keepStartup){ diff --git a/apps/drained/metadata.json b/apps/drained/metadata.json index eff9a331b..84addc803 100644 --- a/apps/drained/metadata.json +++ b/apps/drained/metadata.json @@ -1,7 +1,7 @@ { "id": "drained", "name": "Drained", - "version": "0.07", + "version": "0.08", "description": "Switches to displaying a simple clock when the battery percentage is low, and disables some peripherals", "readme": "README.md", "icon": "icon.png", From 7001b31897a17d7fb71edee2f1b30fc1b9521978 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Tue, 11 Feb 2025 13:44:30 -0500 Subject: [PATCH 73/96] Release DayMoon clock v 0.1.2 --- apps/daymoon/ChangeLog | 3 +- apps/daymoon/README.md | 19 ++--- apps/daymoon/app.js | 143 +++++++++++++++++++++++------------- apps/daymoon/metadata.json | 4 +- apps/daymoon/screenshot.png | Bin 4446 -> 4538 bytes 5 files changed, 104 insertions(+), 65 deletions(-) diff --git a/apps/daymoon/ChangeLog b/apps/daymoon/ChangeLog index 1e5e620fe..d3b376af0 100644 --- a/apps/daymoon/ChangeLog +++ b/apps/daymoon/ChangeLog @@ -1 +1,2 @@ -0.1 First functional release \ No newline at end of file +0.1 First functional release +0.1.1 move moon down, rotate sunrise/sunset, shift Hours/minutes to corners \ No newline at end of file diff --git a/apps/daymoon/README.md b/apps/daymoon/README.md index cef843569..803eb1696 100644 --- a/apps/daymoon/README.md +++ b/apps/daymoon/README.md @@ -2,14 +2,15 @@ This started out with a goal to recreate the Pebble [Fair Circadian watchface](https://setpebble.com/app/fair-circadian) by Matthew Clark for the Bangle.js2. It ended up with me making a mostly new watchface that has the moon phase more prominent, but keeps the single dial 24 hour clock with daylight and sunset highlighted. +This uses the myLocation app to get your latitude and longitude for proper daylight calculations. If your location isn't set in that app, it will default to Nashua, NH. If your sunrise/sunset times aren't making sense, check that first! + ## Future Development Feature roadmap: -0.1.1 fix the layout so that the widget bar is clear; - put sunrise/sunset at angle on sides -0.2 add Day of week and month display -1.0 Seconds display -1.1 Color Themes (and settings/options) -1.2 Moon display angle represents how it looks in the sky -1.3 custom/bigger/fitted time digits - -2.0 clockinfo support? + - [x]0.1.1 Fix blocking widgets + - [x]0.1.2 Day and Night different color markers + - [ ]0.2 add Day of week and month display + - [ ]1.0 Seconds display + - [ ]1.1 Color Themes (and settings/options) + - [ ]1.2 Moon display angle represents how it looks in the sky + - [ ]1.3 custom/bigger/fitted time digits + - [ ]2.0 clockinfo support? diff --git a/apps/daymoon/app.js b/apps/daymoon/app.js index b3f16ec27..1f770869f 100644 --- a/apps/daymoon/app.js +++ b/apps/daymoon/app.js @@ -3,19 +3,36 @@ let location; var Utils = require("graphics_utils"); var SunCalc = require("suncalc"); - -const TAU = 2.0*Math.PI,MX=g.getWidth()/2,MY=g.getHeight()/2-20,R=40,X=MX+55,Y=MY+98; -const DAY_MILLIS = 86400000, DIAL=0.05; -const dR1=R+2,dR2=R+23,dR3=R+26; -var shadeCol=8196; -const M_POS = {x:MX,y:MY,r:R}; -const moon_texture = { - width : 80, height : 80, bpp : 1,transparent:0, - buffer : require("heatshrink").decompress(atob("ABsRqAJHkEiBA0VqtVqgIEgIIBqNVBIkCkQACDg4ABGYku1Wu1GICYgSDqsVBIf71U73WigQ6FAAdABIMD/2K1YpBwATCgoTFHgUf/e7/ej1eiJw5vEn/+///9WqxAoCutVq4UEBIP//YTB3Uj0UgJw5QCgYRBE4Uq1BOCE4N3CZWq3e6UIJiGMgUPJwX/9wpBE4MXutXJ4oTBCQW71f/8R2C6onGqgTD/3v//oE4RNFKoNQl//3+//4nB/UikBOHE4ZQB/2vCYOq9FXEIImDAoNUE4O61e73e/ZQP6E5FVO4O+xxQDCYInDPAIFDE4IlCKQWj+QnJCYJPC1wTB/BPBO4TyCAoUrd4JMB1U/MgM6J5SeBJgOoPAPu1QkCAARPBKYMjE4LGB0UrFgJ3JqkLEwPv1WIwXqeIIjCd4tUkW7HgOqkUj0W/1EVE5EA1Z3B1WAwXo/+ICZWv/YnCgE6ncgCZFQgEv9wnCwGu12gCZMCUAP/0UikE63eggoTHoEAwYnB9GAgEq1GAgITJPAM70ECkEiKQITIgEAhRNBAgMAhADCBwRTDioJBlRMBAgMCCQUACANURIaKBBwImDAAhkBqMRCYNRRQITBJIInGKAxiBAAMoJ448BE4Y6CEYgCBKYQ8DYogAMHggMHKQYUGJoYAJA=")) +var RADII = { + moon: 40, + arcMin: 48, + arcMax: 63, + dots: 55, + needle: 54, }; -const dial = { width: 23, height: 9, bpp:1, transparent:0, - buffer: atob("///B///gAADgAADgAADgAAOAAA5///j//8A=") +var COL ={ + moon: 65535, // + txture:33792, // 0.5 ,0.5,0 + shadow: 8196, // .125,0, .125 + day: 40159, //0.6, 0.6,1 + night: 6, // 0, 0, 0.2 + ndots: 2047, // 0, 1, 1 cyan + ddots: 0, + needle:63488, // 1, 0, 0 red + stime: 2047 +}; +const TAU = 2.0*Math.PI; +const MX=g.getWidth()/2,MY=24+3+RADII.arcMax; +const DAY_MILLIS = 86400000; +const M_POS = {x:MX,y:MY,r:RADII.moon}; +// images +const moon_texture = { width : 80, height : 80, bpp : 1,transparent:0, + buffer : require("heatshrink").decompress(atob("ABsRqAJHkEiBA0N0uq1AIEgNVqtRqoJEgUiAAQJEioTBAAIzEl2q12oxATECQdVioJD/eqne60UCHQoADoAJBgf+xWrFIOACYUFCYo8Cj/73f70er0ROHAANUBIM//3///q1WIFAV1qtXCggJB//7CYO6keikBOHKAUDCIInClSgCgonBu4TK1W73ShBMQxkCh5OC//uFIInBi91q5PFCYISC3er//iOwXVE41UCYf+9//9AnCJopVBqEv/+/3//E4P6kUgJw4nDKAP+14TB1Xoq4hBEwYFBqgnB3Wr3e737KB/QnIqp3B32OKAYTBE4Z4BAoYnBEoRSC0fyE5ITBJ4WuCYP4J4J3CeQQFClbvBJgOqn5kBnRPKTwJMB1B4B92qEgQACJ4JTBkYnBYwOilYsBO5NUhYmB9+qxGC9TxBEYTvFqki3Y8B1Uikei3+oionIgGrO4OqwGC9H/xATK1/7E4UAnU7kATIqEAl/uE4WA12u0ATJgSgB/+ikUgnW70EFCY9AgGDE4PowEAlWowEBCZJ4BneggUgkRSBCZEAgEKJoIEBgEIAYQOCKYcVBIMqJgIEBgQSCgAQBqiJDRQIOBEwYAEMgNRiITBqKKBCYJJBE4xQGMQIABlBPHHgInDHQQjEAQJTCHgbFEABg8EBg5SDCgxNDABI=")) +}; +const needle = { width: 23, height: 11, bpp:1, transparent:0, + buffer: atob("///B///D///AAAPAAAHAAAHAAAcAADz///H//8P//wA=") }; + /* now use SunCalc.getMoonIllumination() previously used these: @@ -26,58 +43,78 @@ const dial = { width: 23, height: 9, bpp:1, transparent:0, // requires the myLocation app function loadLocation() { - location = require("Storage").readJSON(LOCATION_FILE,1)||{"lat":51.5072,"lon":0.1276,"location":"London"}; + location = require("Storage").readJSON(LOCATION_FILE,1)||{"lat":45,"lon":-71.3,"location":"Nashua"};//{"lat":51.5072,"lon":0.1276,"location":"London"}; } -function drawMoon(shape){ - g.setColor(0,0,0).fillCircle(MX,MY,R+30); - g.setColor(1,1,1).fillCircle(MX,MY,R-1); - g.setColor(1,1,0).drawImage(moon_texture,MX,MY,{rotate:0}); +function drawMoon(shadowShape){ + g.setColor(0,0,0).fillCircle(MX,MY,RADII.arcMax+3); + g.setColor(COL.moon).fillCircle(MX,MY,RADII.moon); + g.setColor(COL.txture).drawImage(moon_texture,MX,MY,{rotate:0}); //later can set the rotation here to the parallacticAngle from getMoonPosition - g.setColor(shadeCol).fillPoly(shape); - //later set rotation of the fillPoly? parallactic-mp.angle I think. use g.transformVertices + g.setColor(COL.shadow).fillPoly(shadowShape); + //later set rotation of the fillPoly? parallactic-mp.angle I think. + //Use g.transformVertices to do the rotation } -function drawSunTime(times){ +function drawDayRing(times){ + let r_ = RADII.arcMin; + let rm = RADII.arcMax; + let rd = RADII.dots; radT=[tToRad(times[0]),tToRad(times[1])]; hhmm=[require("locale").time(times[0],1),require("locale").time(times[1],1)]; - g.setColor(0.6,0.6,1); - Utils.fillArc(g,MX,MY,R+9,R+26,radT[0],radT[1]); - g.setColor(0,0,0.2); - Utils.fillArc(g,MX,MY,R+9,R+26,radT[1]-TAU,radT[0]); - g.setFont('6x8').setColor(0,1,1); - g.setFontAlign(-1,1,0).drawString(hhmm[0],MX-(R+26),MY+R+26); - g.setFontAlign(1,1,0).drawString(hhmm[1],MX+(R+26),MY+R+26); -} - -function drawDial() { - let r=56; - let labels=['6P','12A','6A','12P']; - let offx=[-11,2,12,2]; - let offy=[1,-11,1,14]; - g.setFont('4x6').setFontAlign(0,0,0).setColor(0,1,1); - //draw dots & labels - let j =0; + g.setColor(COL.day); + Utils.fillArc(g,MX,MY,r_,rm,radT[0],radT[1]); + g.setColor(COL.night); + Utils.fillArc(g,MX,MY,r_,rm,radT[1]-TAU,radT[0]); + //write sunrise/sunset times + g.setFont('6x8').setColor(COL.stime); + g.setFontAlign(0,1,3).drawString(hhmm[0],MX-rm-2,MY); + g.setFontAlign(0,1,1).drawString(hhmm[1],MX+rm+2,MY); + //draw dots + let edges=[]; + var isday=true; + let flag = false; + if (radT[1]>TAU){ + edges=[radT[1]-TAU,radT[0]]; + g.setColor(COL.ddots); + isDay=true; + } else { + edges=[radT[0],radT[1]]; + g.setColor(COL.ndots); + isDay=false; + } for (var i=0;i<24;i++) { let a=i*TAU/24; - let ds = (i%3 == 0) ? 2 : 1; - let pX = MX+Math.cos(a)*r; - let pY = MY+Math.sin(a)*r; - g.fillCircle(pX,pY,ds); - if (i%6==0) { - //console.log(i,j); - g.drawString(labels[j],pX+offx[j],pY+offy[j]); - j++; - } + if (!flag && a>edges[0]){ + //first cross + if (isDay){g.setColor(COL.ndots);}else{g.setColor(COL.ddots);} + flag = true; + } else if (flag && a>edges[1]){ + //second cross + if (isDay){g.setColor(COL.ddots);}else{g.setColor(COL.ndots);} + flag = false; + } + let dotSize = (i%3 == 0) ? 2 : 1; + let pX = MX+Math.cos(a)*rd; + let pY = MY+Math.sin(a)*rd; + g.fillCircle(pX,pY,dotSize); + } + let labels=['6P','12A','6A','12P']; + let qX=[rd-9,2,11-rd,2]; + let qY=[1,rd-10,1,12-rd]; + g.setFont('4x6').setFontAlign(0,0,0).setColor(COL.ndots); + for (var j=0;j<4;j++){ + g.drawString(labels[j],MX+qX[j],MY+qY[j]); } } + function drawHHMM(d) { var HM=require("locale").time(d, 1 /*omit seconds*/).split(":"); //write digital time - g.setBgColor(0,0,0).setColor(1,1,1).setFontVector(46); - g.setFontAlign(1,1,0).drawString(" "+HM[0],MX,g.getHeight()+7,true); - g.setFontAlign(-1,1,0).drawString(HM[1]+" ",MX+10,g.getHeight()+7,true); + g.setBgColor(0,0,0).setColor(1,1,1).setFontVector(45); + g.setFontAlign(1,1,0).drawString(" "+HM[0],MX-20,g.getHeight()+3); + g.setFontAlign(-1,1,0).drawString(HM[1]+" ",MX+30,g.getHeight()+3); var meridian = require("locale").meridian(d); } @@ -99,7 +136,6 @@ function moonShade(pos,mp) { s2 = isWaxing ? 1-2*k : 2*k-1; let tr =(pos.r+0.5); for (var i=0;i?_7a2)b*&`QOH>KhV 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 B&Nu)7 delta 4438 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 cVrm5b13TQ}T9ZA~Gynhq07*qoM6N<$g4 Date: Tue, 11 Feb 2025 15:18:25 -0500 Subject: [PATCH 74/96] Update ChangeLog --- apps/daymoon/ChangeLog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/daymoon/ChangeLog b/apps/daymoon/ChangeLog index d3b376af0..c0502fc82 100644 --- a/apps/daymoon/ChangeLog +++ b/apps/daymoon/ChangeLog @@ -1,2 +1,3 @@ -0.1 First functional release -0.1.1 move moon down, rotate sunrise/sunset, shift Hours/minutes to corners \ No newline at end of file +0.1 : First functional release +0.1.1 : move moon down, rotate sunrise/sunset, shift Hours/minutes to corners +0.1.2 : Change day and night to have different dots \ No newline at end of file From 3fdc3328ec7691c5cd8e75e256f9754632802629 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Tue, 11 Feb 2025 15:52:33 -0500 Subject: [PATCH 75/96] Version 0.04 Fix theme and versioning --- apps/daymoon/ChangeLog | 7 ++++--- apps/daymoon/README.md | 16 ++++++++-------- apps/daymoon/app.js | 1 + apps/daymoon/metadata.json | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/apps/daymoon/ChangeLog b/apps/daymoon/ChangeLog index c0502fc82..8e650db84 100644 --- a/apps/daymoon/ChangeLog +++ b/apps/daymoon/ChangeLog @@ -1,3 +1,4 @@ -0.1 : First functional release -0.1.1 : move moon down, rotate sunrise/sunset, shift Hours/minutes to corners -0.1.2 : Change day and night to have different dots \ No newline at end of file +0.01: First functional release +0.02: move moon down, rotate sunrise/sunset, shift Hours/minutes to corners +0.03: Change day and night to have different dots +0.04: Update ChangeLog, coerce dark theme \ No newline at end of file diff --git a/apps/daymoon/README.md b/apps/daymoon/README.md index 803eb1696..2c7e0e6ad 100644 --- a/apps/daymoon/README.md +++ b/apps/daymoon/README.md @@ -6,11 +6,11 @@ This uses the myLocation app to get your latitude and longitude for proper dayli ## Future Development Feature roadmap: - - [x]0.1.1 Fix blocking widgets - - [x]0.1.2 Day and Night different color markers - - [ ]0.2 add Day of week and month display - - [ ]1.0 Seconds display - - [ ]1.1 Color Themes (and settings/options) - - [ ]1.2 Moon display angle represents how it looks in the sky - - [ ]1.3 custom/bigger/fitted time digits - - [ ]2.0 clockinfo support? + - [x]0.01 Fix blocking widgets + - [x]0.03 Day and Night different color markers + - [ ]0.05 add Day of week and month display + - [ ]0.06 Seconds display + - [ ]0.07 Color Themes (and settings/options) + - [ ]0.08 Moon display angle represents how it looks in the sky + - [ ]0.10 custom/bigger/fitted time digits + - [ ]0.20 clockinfo support? diff --git a/apps/daymoon/app.js b/apps/daymoon/app.js index 1f770869f..53d6fd640 100644 --- a/apps/daymoon/app.js +++ b/apps/daymoon/app.js @@ -196,4 +196,5 @@ widgets know if they're being loaded into a clock app or not */ Bangle.setUI("clock"); // Load widgets Bangle.loadWidgets(); +g.setTheme({bg:"#000"}); Bangle.drawWidgets(); \ No newline at end of file diff --git a/apps/daymoon/metadata.json b/apps/daymoon/metadata.json index 900985de2..fd2c2c4d0 100644 --- a/apps/daymoon/metadata.json +++ b/apps/daymoon/metadata.json @@ -1,6 +1,6 @@ { "id": "daymoon", "name": "DayMoon Circadian Clock", - "version": "0.1.2", + "version": "0.4", "dependencies": {"mylocation":"app"}, "description": "A 24 hour clockface showing the Moon Phase and portion of the day that the Sun is up inspired by Matthew Clark's *Fair Circadian* Pebble watchface", "icon": "daymoon.png", From ab48ad12bfad03b47e614ade87e455991af8c889 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Tue, 11 Feb 2025 16:10:36 -0500 Subject: [PATCH 76/96] Fix metadata to agree with ChangeLog Last time had it as 0.4 when it should have been 0.04 --- apps/daymoon/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daymoon/metadata.json b/apps/daymoon/metadata.json index fd2c2c4d0..e2cbf2a8f 100644 --- a/apps/daymoon/metadata.json +++ b/apps/daymoon/metadata.json @@ -1,6 +1,6 @@ { "id": "daymoon", "name": "DayMoon Circadian Clock", - "version": "0.4", + "version": "0.04", "dependencies": {"mylocation":"app"}, "description": "A 24 hour clockface showing the Moon Phase and portion of the day that the Sun is up inspired by Matthew Clark's *Fair Circadian* Pebble watchface", "icon": "daymoon.png", From 3e6683a0adea391ba781d3154319790892c3d6cd Mon Sep 17 00:00:00 2001 From: smulrine Date: Tue, 11 Feb 2025 21:42:10 +0000 Subject: [PATCH 77/96] Create app.js --- apps/pacer/app.js | 845 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 845 insertions(+) create mode 100644 apps/pacer/app.js diff --git a/apps/pacer/app.js b/apps/pacer/app.js new file mode 100644 index 000000000..1422f7810 --- /dev/null +++ b/apps/pacer/app.js @@ -0,0 +1,845 @@ +Bangle.loadWidgets(); +g.clear(); +Bangle.drawWidgets(); + +var cfg; +try { + cfg = require("Storage").readJSON("pacer.json",true)||{}; +} +catch(err) { + cfg = {}; +} +if (process.env.BOARD == 'BANGLEJS2') + var bangle2 = true; +else + var bangle2 = false; + +var laps = ["Off","0.25","0.5","1","2","5","10"]; +var fg = 1; +var fixed = false; +var started = false; +var startHidden = false; +var recording = false; +var invID = 0; +var intID = 0; +var startID = 0; +var cadID = 0; +var finID = 0; +var lapID = 0; +var steps = 0; +var sats = 0; +var ctr = 0; +var elapsed_ms = 0; +var finish_ms = 0; +var lap_start_ms = 0; +var lap_ms; +var gps = {fix:0,satellites:0}; +var fp; +var start_time; +var current_time; +var paused_time = 0; +var last_time = 0; +var begin_pause; +var next_lap = 0.0; +var skip_ctr = 0; +var skip_max = 0; +var force_write = true; +var show_lap = false; +var lcd_on = true; +var dist = 0.0; +var pdist = 0.0; +var oldDist = 0.0; +var oldLat = -1; +var oldLon = -1; +var oldTime = -1; +var cadence = 0; +var pace = 0; +var ppace = 0; +var R = 6371; +var stepTimes = []; +var dists = []; + +function pace_str(pval) { + var psecs = 295 + 5 * pval; + return ''+Math.floor(psecs/60)+':'+('0'+psecs%60).substr(-2); +} + +function defaults() { + if (typeof(cfg.record) != 'boolean') + cfg.record = true; + if (typeof(cfg.metric) != 'boolean') + cfg.metric = false; + if (typeof(cfg.lap_idx) != 'number') + cfg.lap_idx = 3; + if (typeof(cfg.dark) != 'boolean') + cfg.dark = true; + if (typeof(cfg.eco) != 'boolean') + cfg.eco = false; + if (typeof(cfg.storage) != 'boolean') + cfg.storage = false; + if (typeof(cfg.show_steps) != 'boolean') + cfg.show_steps = false; + if (typeof(cfg.pacer) != 'number') + cfg.pacer = 0; + fg = cfg.dark?1:0; +} + +function genFilename() { + var today=new Date(); + return ('.pacer'+today.getFullYear()+('0'+(today.getMonth()+1)).substr(-2)+('0'+today.getDate()).substr(-2)+('0'+today.getHours()).substr(-2)+('0'+today.getMinutes()).substr(-2)+('0'+today.getSeconds()).substr(-2)+'.csv'); +} + +function doCadence() { + if (steps > 0) + clearInterval(cadID); + cadID = setTimeout(function() { + cadence = 0; + }, 2000); + if (recording) { + steps++; + stepTimes.push(Date.now()); + stepTimes = stepTimes.slice(-20); + const elapsed = stepTimes[stepTimes.length - 1] - stepTimes[0]; + cadence = elapsed ? Math.round(60000 * (stepTimes.length - 1) / elapsed) : 0; + } else + stepTimes = []; +} + +function doPace(thistime,thisdist) { + dists.push([thistime,thisdist]); + dists = dists.slice(-30); + const thiselapsed = dists[dists.length - 1][0] - dists[0][0]; + const thisdistance = dists[dists.length - 1][1] - dists[0][1]; + pace = thisdistance ? ((thiselapsed) / thisdistance) / 1000 : 0; +} + +function countStep() { + if (recording) + steps++; +} + +function calcCrow(lat1, lon1, lat2, lon2) +{ + var dLat = toRad(lat2-lat1); + var dLon = toRad(lon2-lon1); + var lat1r = toRad(lat1); + var lat2r = toRad(lat2); + + var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1r) * Math.cos(lat2r); + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + var d = R * c; + if (isNaN(d)) + return 0; + else + return d; +} + +function toRad(Value) +{ + return Value * Math.PI / 180; +} + +function saveGPS(fix) { + var newLat, newLon, newTime, newDist; + + try { + newTime = fix.time.getTime(); + } + catch(err) { + newTime = NaN; + } + newLat = fix.lat; + newLon = fix.lon; + gps = fix; + if (!cfg.storage) { + if (gps.satellites >= 8) + skip_max = 0; + else if (gps.satellites < 4) + skip_max = 5; + else + skip_max = 8 - gps.satellites; + } + if (recording && cfg.pacer > 0 && skip_ctr >= (cfg.storage ? 9 : skip_max)) + pdist = (elapsed_ms / 1000) / ppace; + if (isNaN(newLat) || isNaN(newLon) || isNaN(newTime)) { + skip_ctr = 0; + skip_max = 0; + force_write = true; + } else { + if (oldLat != -1 && recording) { + skip_ctr++; + if (skip_ctr > (cfg.storage ? 9 : skip_max)) { + skip_ctr = 0; + oldDist = dist; + newDist = calcCrow(oldLat, oldLon, newLat, newLon); + dist += newDist; + doPace(newTime,dist); + oldLat = newLat; + oldLon = newLon; + oldTime = newTime; + } + } else { + oldLat = newLat; + oldLon = newLon; + oldTime = newTime; + } + if (recording && cfg.record && (force_write || skip_ctr == 0)) { + fp.write([gps.time.getTime(),gps.lat.toFixed(5),gps.lon.toFixed(5),gps.alt].join(",")+"\n"); + last_time = gps.time; + if (force_write) { + skip_ctr = 0; + force_write = false; + } + } + } +} + +function drawInvert() { + // not applicable to bangle2 + g.drawImage(atob("DQ0BD4HjHwT4L8D+B/A/gfwL4J8EeMD4AA=="),225,26); +} + +function drawSatIcon() { + if (bangle2) + g.drawImage(atob("CQkBIDo7i+Pj6O4uAgA="),3,53); + else + g.drawImage(atob("DAwBEAOAcQ84T8D4HwPyHPCOAcAI"),4,66); +} + +function drawStepsIcon() { + if (bangle2) + g.drawimage(atob("CQkBBhudzudzgBzsMAA="),3,139); + else + g.drawImage(atob("DAwBAMAcMeOeeeeeeAecAcOYOAGA"),4,197); +} + +function drawCadenceIcon() { + if (bangle2) + g.drawImage(atob("CQkBCB4SEBgMBCQ8CAA="),3,139); + else + g.drawImage(atob("DAwBBAAwP4YxxDwDwDwjjGH8DAAg"),4,197); +} + +function hideStart() { + g.clearRect(bangle2?162:226,bangle2?81:113,bangle2?174:238,bangle2?93:125); +} + +function drawStart() { + hideStart(); + g.fillPoly([bangle2?162:226,bangle2?81:113,bangle2?162:226,bangle2?93:125,bangle2?174:238,bangle2?87:119,bangle2?162:226,bangle2?81:113]); +} + +function drawPause() { + hideStart(); + g.fillRect(bangle2?165:227,bangle2?82:113,bangle2?167:230,bangle2?92:125); + g.fillRect(bangle2?171:234,bangle2?82:113,bangle2?173:237,bangle2?92:125); +} + +function drawStop() { + // not applicable to bangle2 + g.fillRect(226,202,237,213); +} + +function drawExit() { + if (bangle2) + g.drawImage(atob("CQkBwfHdx8HB8d3HwQg="),165,82); + else + g.drawImage(atob("DAwBwD4HcOOcH4DwDwH4OccO4HwD"),226,202); +} + +function setColours() { + g.setBgColor(1-fg,1-fg,1-fg); + g.setColor(fg,fg,fg); +} + +function setScreenMode() { + g.reset(); + setColours(); + g.clearRect(0,24,bangle2?175:239,bangle2?151:215); +} + +function doLayout() { + setColours(); + if (!bangle2) + drawInvert(); + drawSatIcon(); + drawDist(); + drawTime(); + if (cfg.pacer == 0) + drawPace(); + else { + drawPacer(); + drawSmallPace(); + } + g.setFont("6x8",bangle2?2:3); + if (cfg.show_steps) { + drawStepsIcon(); + g.drawString(steps.toString(),bangle2?15:20,bangle2?134:190,true); + } else { + drawCadenceIcon(); + g.drawString(cadence.toString()+" ",bangle2?15:20,bangle2?134:190,true); + } + drawStart(); + if (!bangle2) + drawStop(); +} + +function drawDist() { + g.setFont("6x8",bangle2?4:5); // 3:5? + var dStr = dist.toString(); + if (dStr.indexOf('.') == -1) + dStr += '.0'; + g.drawString(((' '+(dStr.split('.'))[0])).substr(-2),bangle2?33:53,bangle2?26:35,true); + g.fillRect(bangle2?80:112,bangle2?51:66,bangle2?82:115,bangle2?53:69); + g.drawString(((dStr.split('.'))[1]+'0').substr(0,2),bangle2?86:120,bangle2?26:35,true); + g.setFont("6x8",2); + g.drawString(cfg.metric?"K":"M",bangle2?134:180,bangle2?40:56,true); +} + +function drawPacer() { + g.setFont("6x8",bangle2?3:5); + var pstr=(pdist>dist?'-':'+')+(Math.floor(Math.abs(dist-pdist)))%100; + g.drawString(pstr,bangle2?(49-(pstr.length>2?18:0)):(53-(pstr.length>2?30:0)),bangle2?107:145,true); + g.fillRect(bangle2?84:112,bangle2?126:176,bangle2?85:115,bangle2?127:179); + g.drawString(('0'+Math.floor(Math.abs(((dist-pdist)*100)%100))).substr(-2),bangle2?89:120,bangle2?107:145,true); + g.setFont("6x8",bangle2?1:2); + g.drawString(cfg.metric?"K":"M",bangle2?125:180,bangle2?121:166,true); +} + +function drawPace() { + g.setFont("6x8",bangle2?3:5); + if (pace > 0 && pace < 6000) + g.drawString((' '+Math.floor(pace/60)).substr(-2),bangle2?49:53,bangle2?107:145,true); + else + g.drawString("--",bangle2?49:53,bangle2?107:145,true); + g.fillRect(bangle2?84:112,bangle2?117:160,bangle2?85:115,bangle2?118:163); + g.fillRect(bangle2?84:112,bangle2?120:166,bangle2?85:115,bangle2?121:169); + if (pace > 0 && pace < 6000) + g.drawString(('0'+Math.floor(pace%60)).substr(-2),bangle2?89:120,bangle2?107:145,true); + else + g.drawString("--",bangle2?89:120,bangle2?107:145,true); + g.setFont("6x8",bangle2?1:2); + g.drawString(cfg.metric?"/K":"/M",bangle2?124:178,bangle2?121:166,true); +} + +function drawSmallPace() { + g.setFont("6x8",bangle2?2:3); + if (pace > 0 && pace < 6000) + g.drawString((' '+Math.floor(pace/60)).substr(-2),bangle2?113:136,bangle2?134:190,true); + else + g.drawString("--",bangle2?113:136,bangle2?134:190,true); + if (bangle2) { + g.setPixel(136,140); + g.setPixel(136,142); + } else { + g.fillRect(172,199,173,200); + g.fillRect(172,203,173,204); + } + if (pace > 0 && pace < 6000) + g.drawString(('0'+Math.floor(pace%60)).substr(-2),bangle2?138:176,bangle2?134:190,true); + else + g.drawString("--",bangle2?138:176,bangle2?134:190,true); + g.setFont("6x8",1); + g.drawString(cfg.metric?"/K":"/M",bangle2?164:212,bangle2?141:204,true); +} + +function drawTime() { + var seconds; + var minutes; + var hours; + + setColours(); + g.setFont("6x8",bangle2?5:7); + seconds = parseInt(elapsed_ms/1000) % 60; + minutes = parseInt(elapsed_ms/60000) % 60; + hours = parseInt(elapsed_ms/3600000) % 10; + g.drawString(hours.toString(),bangle2?6:5,bangle2?63:82,true); + g.fillRect(bangle2?34:44,bangle2?79:103,bangle2?36:48,bangle2?81:107); + g.fillRect(bangle2?34:44,bangle2?84:112,bangle2?36:48,bangle2?86:116); + g.drawString(('0'+minutes).substr(-2),bangle2?40:53,bangle2?63:82,true); + g.fillRect(bangle2?98:134,bangle2?79:103,bangle2?100:138,bangle2?81:107); + g.fillRect(bangle2?98:134,bangle2?84:112,bangle2?100:138,bangle2?86:116); + g.drawString(('0'+seconds).substr(-2),bangle2?104:143,bangle2?63:82,true); +} + +function drawGPSBox() { + g.drawRect(2,26,bangle2?12:17,bangle2?51:63); +} + +function drawGPS() { + g.clearRect(3,27,bangle2?11:16,bangle2?50:62); + if (gps.satellites > 0) { + if (!gps.fix) + g.setColor("#FF0000"); + else if (gps.satellites < 4) + g.setColor("#FF5500"); + else if (gps.satellites < 6) + g.setColor("#FF8800"); + else if (gps.satellites < 8) + g.setColor("#FFCC00"); + else + g.setColor("#00FF00"); + g.fillRect(3,bangle2?50:62,bangle2?11:16,(bangle2?50:62)-(gps.satellites>12?12:gps.satellites)*(bangle2?2:3)+1); + g.setColor(fg,fg,fg); + } +} + +function hideLap() { + show_lap = false; + g.reset(); + setColours(); + g.clearRect(bangle2?6:5,bangle2?63:82,bangle2?162:224,bangle2?129:182); + if (recording) { + current_time = Date.now(); + elapsed_ms = current_time - (start_time + paused_time); + } else + elapsed_ms = begin_pause - (start_time + paused_time); + drawTime(); + if (cfg.pacer == 0) + drawPace(); + else { + drawPacer(); + drawSmallPace(); + } +} + +function showLap() { + g.clearRect(bangle2?6:5,bangle2?63:82,bangle2?162:224,bangle2?129:182); + g.drawRect(bangle2?21:28,bangle2?68:90,bangle2?147:201,bangle2?124:174); + g.drawRect(bangle2?23:30,bangle2?70:92,bangle2?145:199,bangle2?122:172); + g.setFont("6x8",bangle2?1:2); + g.drawString("Last lap",bangle2?61:68,bangle2?77:102,true); + g.setFont("6x8",bangle2?3:5); + if (lap_ms < 600000) { + g.drawString((''+Math.floor(lap_ms/60000)),bangle2?57:69,bangle2?89:122,true); + g.fillRect(bangle2?74:98,bangle2?99:137,bangle2?75:101,bangle2?100:140); + g.fillRect(bangle2?74:98,bangle2?102:143,bangle2?75:101,bangle2?103:146); + g.drawString(('0'+Math.floor((lap_ms%60000)/1000)).substr(-2),bangle2?78:106,bangle2?89:122,true); + } else if (lap_ms < 3600000) { + g.drawString((''+Math.floor(lap_ms/60000)),bangle2?48:54,bangle2?89:122,true); + g.fillRect(bangle2?83:113,bangle2?99:137,bangle2?84:116,bangle2?100:140); + g.fillRect(bangle2?83:113,bangle2?102:143,bangle2?84:116,bangle2?103:146); + g.drawString(('0'+Math.floor((lap_ms%60000)/1000)).substr(-2),bangle2?87:121,bangle2?89:122,true); + } else { + g.drawString((''+Math.floor(lap_ms/3600000)).substr(-1),bangle2?37:35,bangle2?89:122,true); + g.fillRect(bangle2?54:64,bangle2?99:137,bangle2?55:67,bangle2?100:140); + g.fillRect(bangle2?54:64,bangle2?102:143,bangle2?55:67,bangle2?103:146); + g.drawString(('0'+Math.floor((lap_ms%3600000)/60000)).substr(-2),bangle2?58:72,bangle2?89:122,true); + g.fillRect(bangle2?93:131,bangle2?99:137,bangle2?94:134,bangle2?100:140); + g.fillRect(bangle2?93:131,bangle2?102:143,bangle2?94:134,bangle2?103:146); + g.drawString(('0'+Math.floor((lap_ms%60000)/1000)).substr(-2),bangle2?97:139,bangle2?89:122,true); + } + Bangle.setLCDPower(true); +} + +function mainLoop() { + g.reset(); + setColours(); + current_time = Date.now(); + if (started) { + elapsed_ms = current_time - (start_time + paused_time); + if (oldDist != dist) { + drawDist(); + if (cfg.lap_idx > 0 && dist >= next_lap ) { + show_lap = true; + next_lap += parseFloat(laps[cfg.lap_idx]); + lap_ms = elapsed_ms - lap_start_ms; + lap_start_ms = elapsed_ms; + Bangle.buzz(); + lapID = setTimeout(hideLap,5000); + showLap(); + } + } + } else + elapsed_ms = 0; + drawSats = false; + if (recording) { + if (!show_lap) + drawTime(); + g.setFont("6x8",bangle2?2:3); + if (cfg.show_steps) + g.drawString(steps.toString(),bangle2?15:20,bangle2?134:190,true); + else + g.drawString(cadence.toString()+" ",bangle2?15:20,bangle2?134:190,true); + } /* else + g.setFont("6x8",3); */ + if (!show_lap) + if (cfg.pacer == 0) + drawPace(); + else { + drawPacer(); + drawSmallPace(); + } + if (gps.fix) { + if (!started && startHidden) { + startHidden = false; + if (!bangle2) + startID = setWatch(start, BTN2); + else + startID = setWatch(start, BTN1, {edge: 'falling'}); + drawStart(); + } + if (!fixed) { + fixed = true; + drawSats = true; + } + } else { + if (!started && !startHidden) { + startHidden = true; + clearWatch(startID); + hideStart(); + } + if (fixed) { + fixed = false; + drawSats = true; + } + } + if (gps.satellites != sats) { + sats = gps.satellites; + drawSats = true; + } + if (drawSats) + drawGPS(); + if (ctr++%10 == 0) { + g.reset(); + Bangle.drawWidgets(); + } +} + +function restart(e) { + if (bangle2 && (e.time - e.lastTime > 0.5)) { + finish(); + } + g.reset(); + setColours(); + paused_time += (Date.now() - begin_pause); + pace = 0; + drawPause(); + oldDist = dist; + skip_ctr = 0; + force_write = true; + recording = true; + Bangle.buzz(); + if (!bangle2) + setWatch(pause, BTN2); + else + setWatch(pause, BTN1, { edge: 'falling' }); +} + +function pause(e) { + if (bangle2 && (e.time - e.lastTime > 0.5)) { + finish(); + } + g.reset(); + setColours(); + begin_pause = Date.now(); + elapsed_ms = begin_pause - (start_time + paused_time); + finish_ms = elapsed_ms; + drawDist(); + recording = false; + if (!show_lap) + drawTime(); + drawStart(); + oldTime = -1; + if (!isNaN(gps.time) && !isNaN(gps.lat) && !isNaN(gps.lon) && !isNaN(gps.alt) && cfg.record && (last_time != gps.time)) + fp.write([gps.time.getTime(),gps.lat.toFixed(5),gps.lon.toFixed(5),gps.alt].join(",")+"\n"); + Bangle.buzz(); + dists = []; + if (!bangle2) + setWatch(restart, BTN2); + else + setWatch(restart, BTN1, { edge: 'falling' }); +} + +function start() { + g.reset(); + setColours(); + if (cfg.eco){ + Bangle.setLCDPower(true); + Bangle.setLCDTimeout(10); + } + if (cfg.record) + fp = require("Storage").open(genFilename(),"w"); + start_time = Date.now(); + drawPause(); + Bangle.buzz(); + started = true; + recording = true; + if (!bangle2) + setWatch(pause, BTN2); + else + setWatch(pause, BTN1, { edge: 'falling' }); + if (cfg.show_steps) + Bangle.on('step',countStep); + else + Bangle.on('step',doCadence); + clearInterval(intID); + intID = setInterval(mainLoop,200); + if (cfg.lap_idx > 0) + next_lap = parseFloat(laps[cfg.lap_idx]); +} + +function endScreen() { + fg = 1-fg; + setScreenMode(); + if (!bangle2) + drawInvert(); + drawExit(); + g.setFont("6x8",bangle2?1:2); + var dStr = dist.toString(); + if (dStr.indexOf('.') == -1) + dStr += '.00'; + dStr = dStr.slice(0, (dStr.indexOf('.'))+3); + if (bangle2) + g.drawString('Distance: '+dStr+(cfg.metric?'K':'M'),38,43); + else { + //g.drawString('Distance: '+dist.toFixed(2),19,53); + g.drawString('Distance: '+dStr,19,53); + g.setFont("6x8",1); + //g.drawString(cfg.metric?'K':'M',139+12*(dist.toFixed(2).length),60); + g.drawString(cfg.metric?'K':'M',139+12*(dStr.length),60); + g.setFont("6x8",2); + } + g.drawString('Time: '+parseInt(finish_ms/3600000)%10+':'+('0'+parseInt(finish_ms/60000)%60).substr(-2)+':'+('0'+parseInt(finish_ms/1000)%60).substr(-2),bangle2?62:67,bangle2?63:83); + var avgPace = dist?((finish_ms/dist)/1000):0; + var paceStr = 'Avg Pace: '+parseInt(avgPace/60)+':'+('0'+parseInt(avgPace%60)).substr(-2); + if (bangle2) + g.drawString(paceStr+(cfg.metric?'/K':'/M'),38,83); + else { + g.drawString(paceStr,19,113); + g.setFont("6x8",1); + g.drawString(cfg.metric?'/K':'/M',19+12*(paceStr.length),120); + g.setFont("6x8",2); + } + g.drawString("Steps: "+steps,bangle2?56:55,bangle2?103:143); + var avgCadence = steps?(60*steps/(finish_ms/1000)):0; + g.drawString("Cadence: "+parseInt(avgCadence),bangle2?44:31,bangle2?123:173); + g.reset(); + Bangle.drawWidgets(); +} + +function finish() { + if (recording) { + finish_ms = elapsed_ms; + if (!isNaN(gps.time) && !isNaN(gps.lat) && !isNaN(gps.lon) && !isNaN(gps.alt) && cfg.record && (last_time != gps.time)) + fp.write([gps.time.getTime(),gps.lat.toFixed(5),gps.lon.toFixed(5),gps.alt].join(",")+"\n"); + } + recording = false; + Bangle.setGPSPower(0); + Bangle.on('step',function(){}); + Bangle.on('GPS',function(){}); + clearInterval(lapID); + clearInterval(intID); + if (!bangle2) { + clearWatch(finID); + clearWatch(invID); + } + if (!bangle2) { + setWatch(function() {if (lcd_on) endScreen();}, BTN1, {repeat:true}); + setWatch(function() {load();},BTN3); + } else + setWatch(function() {load();},BTN1); + fg = 1-fg; + endScreen(); +} + +function startScreen() { + clearInterval(intID); + if (!bangle2) { + clearWatch(invID); + } + clearWatch(finID); + setScreenMode(); + doLayout(); + drawGPSBox(); + Bangle.buzz(); + if (!bangle2) { + invID = setWatch(invertRunning, BTN1, {repeat:true}); + startID = setWatch(start, BTN2); + finID = setWatch(finish, BTN3); + } else + startID = setWatch(start, BTN1, {edge: 'falling'}); + fixed = false; + intID = setInterval(mainLoop,1000); +} + +function invertRunning() { + // not applicable to bangle2 + if (!lcd_on) + return; + fg = 1-fg; + setScreenMode(); + if (started) + if (recording) { + current_time = Date.now(); + elapsed_ms = current_time - (start_time + paused_time); + } else + elapsed_ms = begin_pause - (start_time + paused_time); + else + elapsed_ms = 0; + drawInvert(); + drawSatIcon(); + drawGPSBox(); + drawGPS(); + drawDist(); + if (show_lap) + showLap(); + else { + drawTime(); + if (cfg.pacer == 0) + drawPace(); + else { + drawPacer(); + drawSmallPace(); + } + } + g.setFont("6x8",3); + if (cfg.show_steps) { + drawStepsIcon(); + g.drawString(steps.toString(),20,190,true); + } else { + drawCadenceIcon(); + g.drawString(cadence.toString()+" ",20,190,true); + } + if (recording) + drawPause(); + else if (started || gps.fix) + drawStart(); + drawStop(); + g.reset(); + Bangle.drawWidgets(); +} + +function drawDots() { + if (ctr % 4 == 0) + g.drawString(" ",bangle2?116:176,bangle2?90:108,true); + else if (ctr % 4 == 1) + g.drawString(".",bangle2?116:176,bangle2?90:108); + else if (ctr % 4 == 2) + g.drawString("..",bangle2?116:176,bangle2?90:108); + else + g.drawString("...",bangle2?116:176,bangle2?90:108); +} + +function invertWaiting() { + /* not applicable to bangle2 */ + fg = 1-fg; + setScreenMode(); + drawInvert(); + drawExit(); + g.setFont("6x8",2); + g.drawString("Locating",68,88); + g.drawString("Satellites",56,108); + ctr--; + drawDots(); + g.reset(); + Bangle.drawWidgets(); + ctr++; +} + +function awaitGPSLoop() { + g.reset(); + setColours(); + g.setFont("6x8",bangle2?1:2); + drawDots(); + if (gps.fix) + startScreen(); + if (ctr % 10 == 0) { + g.reset(); + Bangle.drawWidgets(); + } + ctr++; +} + +function awaitGPS() { + Bangle.setOptions({wakeOnTwist:false}); + Bangle.setGPSPower(1); + Bangle.on('GPS', saveGPS); + Bangle.setLCDPower(true); + Bangle.setLCDTimeout(0); + g.reset(); + setColours(); + if (!bangle2) { + drawInvert(); + invID = setWatch(invertWaiting, BTN1, {repeat:true}); + } + drawExit(); + g.setFont("6x8",bangle2?1:2); + // g.drawString("Locating",bangle2?36:68,bangle2?72:88); + // g.drawString("Satellites",bangle2?24:56,bangle2?92:108); + g.drawString("Locating",bangle2?62:68,bangle2?78:88); + g.drawString("Satellites",56,bangle2?90:108); + intID = setInterval(awaitGPSLoop,1000); + if (bangle2) + finID = setWatch(function(){load();},BTN1); + else + finID = setWatch(function(){load();},BTN3); +} + +function main() { + require("Storage").write("pacer.json", cfg); + E.showMenu(); + if (cfg.eco) + Bangle.on('lcdPower', function(on) {setTimeout(function(){lcd_on = on;}, 500);}); + fg = cfg.dark?1:0; + R = cfg.metric?6371:3959; + ppace = 295 + 5 * cfg.pacer; + setScreenMode(); + awaitGPS(); +} + +defaults(); + +var main_menu = { + "" : { "title" : "Pacer"}, + "Start": function() { main(); }, + "Recording" : { + value : cfg.record, + format : v => v?"On":"Off", + onchange : v => { cfg.record = v; }, + }, + "Units" : { + value : cfg.metric, + format : v => v?"Metric":"Imperial", + onchange : v => { cfg.metric = v; }, + }, + "Lap" : { + value : cfg.lap_idx, + format : v => laps[v], + min : 0, max : 6, + onchange : v => { cfg.lap_idx = v; } + }, + "Dark mode" : { + value : cfg.dark, + format : v => v?"On":"Off", + onchange : v => { cfg.dark = v; }, + }, + "Eco battery" : { + value : cfg.eco, + format : v => v?"On":"Off", + onchange : v => { cfg.eco = v; }, + }, + "Eco storage" : { + value : cfg.storage, + format : v => v?"On":"Off", + onchange : v => { cfg.storage = v; }, + }, + "Steps" : { + value : cfg.show_steps, + format : v => v?"Count":"Cadence", + onchange : v => { cfg.show_steps = v; }, + }, + "Pacer" : { + value : cfg.pacer, + format : v => v==0?"Off":pace_str(v), + min : 0, max : 121, + onchange : v => { cfg.pacer = v; } + }, +}; + +if (!bangle2) { + Bangle.setLCDMode(); +} +Bangle.setLCDBrightness(1); +setScreenMode(); +E.showMenu(main_menu); From 9425a3eef4c7e0f8ca8e618d9db5b2331cb4f3b7 Mon Sep 17 00:00:00 2001 From: smulrine Date: Tue, 11 Feb 2025 21:44:04 +0000 Subject: [PATCH 78/96] Add files via upload --- apps/pacer/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/pacer/app-icon.js diff --git a/apps/pacer/app-icon.js b/apps/pacer/app-icon.js new file mode 100644 index 000000000..33eeed26b --- /dev/null +++ b/apps/pacer/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4cA///un/+2Eqee1nV+X26NjtfNGLsf+AQOg+kzAROnskyfACJs5CINACJshCKAjMgfJBoPwgpHLiGSpMk3kHyneO5OECIMl23Aj+AO5QRD7ZSJgPpknZkmNCIJFJhFJk1wgFtCIN4CJFCpMwAgIRCt5HIoVN8B/BCIVmEZFyt6RCCIb7Ih5SCmYRCkjoM7YRB78k6ARO++kzwQKhgRC4GEzARKswRD8mT///Lg8DtmbCILvEEw8DkmzCIUcCIWTN40bkmWUoUCCIWbCJGSrIpC5YoB5x7HCINLRZcAg3bsgwBsARNtgRBlgRLmyNBCIMlwAQJgLkBtuyMwIRHvJUBpP2GoMGCIOwCI1SBQOSr3bA4PJSQKtGSoWSpXYBAMZAwKcGoQRCpoLCZAOSoARFh5HCk4IDtmpnikMAAMOpO8CJ0KpKQKAAlyfoQANqVMCByGBt4ROgWSfhgACjmTvAROimTCB0A8mbYgwAIwmYEZ/07wRPj/wCJ4AI")) From d1b344dbf70ef725ec738a79c055eb09fd65a852 Mon Sep 17 00:00:00 2001 From: smulrine Date: Tue, 11 Feb 2025 21:45:29 +0000 Subject: [PATCH 79/96] Add files via upload --- apps/pacer/README.md | 56 +++++++++++ apps/pacer/interface.html | 198 ++++++++++++++++++++++++++++++++++++++ apps/pacer/metadata.json | 19 ++++ 3 files changed, 273 insertions(+) create mode 100644 apps/pacer/README.md create mode 100644 apps/pacer/interface.html create mode 100644 apps/pacer/metadata.json diff --git a/apps/pacer/README.md b/apps/pacer/README.md new file mode 100644 index 000000000..0824bc7f4 --- /dev/null +++ b/apps/pacer/README.md @@ -0,0 +1,56 @@ +## Pacer + +![icon](app.png) + +Run with a virtual partner at your chosen pace, and export the GPX data +from the Bangle.js App Store. + +## Usage + +Pacer starts up with a menu. + +* **Recording** - whether to record the run +* **Units** - imperial or metric +* **Lap** - the multiple of a mile or kilometer to use for splits +* **Dark mode** - use black or white background +* **Eco battery** - display will turn off after 10 seconds +* **Eco storage** - only record GPS position every 10 seconds +* **Steps** - display step count or cadence +* **Pacer** - pace of virtual partner + +On selecting **Start**, GPS position will be detected. A run cannot be +started without a GPS fix. The watch touchscreen is disabled while the +app is running. + +The app will run on Bangle.js 1 and 2, although use on Bangle.js 2 is not +recommended due to poor GPS accuracy. + +On a Bangle.js 1, the top button reverses the screen colours, the middle +button starts, pauses or resumes a run, and the bottom button ends the run. + +On a Bangle.js 2, a short press of the button starts, pauses or resumes a +run, and a long press (over 0.5 seconds, but under 2!) ends the run. Note +that holding the button for 2 seconds will exit back to the default clock +app. + +## Downloading + +GPX tracks can be downloaded using the +[App Loader](https://banglejs.com/apps/?id=pacer). Connect the +Bangle.js and click on the Pacer app's disk icon to see the tracks +available for downloading. + +## Tips + +For best results, only start a run when the satellite signal strength bar is +green. + +Use the [Assisted GPS Updater](https://banglejs.com/apps/#AGPS) to improve +the time taken to get a GPS fix. + +## Bugs + +The eco settings are unlikely to be useful. + +GPS track smoothing is accomplished simply by reducing the frequency with +which readings are taken, depending on signal strength. diff --git a/apps/pacer/interface.html b/apps/pacer/interface.html new file mode 100644 index 000000000..71e8842d4 --- /dev/null +++ b/apps/pacer/interface.html @@ -0,0 +1,198 @@ + + + + + +
+
+ + + + + + + diff --git a/apps/pacer/metadata.json b/apps/pacer/metadata.json new file mode 100644 index 000000000..1fb5fcdcd --- /dev/null +++ b/apps/pacer/metadata.json @@ -0,0 +1,19 @@ +{ + "id": "pacer", + "name": "Pacer", + "version": "0.01", + "description": "Run with a virtual partner", + "icon": "app.png", + "tags": "run,running,fitness,outdoors,gps", + "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", + "interface": "interface.html", + "storage": [ + {"name":"pacer.app.js","url":"app.js"}, + {"name":"pacer.img","url":"app-icon.js","evaluate":true} + ], + "data": [ + {"name":"pacer.json"}, + {"wildcard":".pacer*.csv","storageFile":true} + ] +} From 0f766ab1b6706685418f1fe242ea6785bbfd0035 Mon Sep 17 00:00:00 2001 From: smulrine Date: Tue, 11 Feb 2025 22:22:09 +0000 Subject: [PATCH 80/96] Add files via upload --- apps/pacer/app.png | Bin 0 -> 2263 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/pacer/app.png diff --git a/apps/pacer/app.png b/apps/pacer/app.png new file mode 100644 index 0000000000000000000000000000000000000000..92148056878e20aa72bc542fb374db0203226a15 GIT binary patch literal 2263 zcmV;|2q^c7P)+aIooC0iiNvOPJ!q`T*Q=ljmRXYbt$@Etd7Fq2nSmQebjP)3rX1sG0Xp&)N& zJg%~*R-H1(i!o>dPVAW{RV(Q;Lr0Gvt<`5q0007hAKdu&g(kPh_1w&5pPr5f2k&2+ zu}!TM?-)7$$#G%w003fI3ge1qapTRId@#IhVHHr{mwUvwBOwZ2wW&RVRbdQ5NS>Fy{GdM_T30PX1f@%Kt z4I6&3YiISod6Q*Q*($(LN-z|xX4-uF=DzfKAYL8`3HWU9PZb(DeQfBc@kN@9OzGqN zU49 zhoxh)K%r7ks`_Y-w%-J#L3=}+)zTK^c>n-tZ8CeVT|8ffETJchSAW?Q?Z55g)f-5q zHd88&x#0ri^T8Mm4Jt7S#$h82Dq6m!w*q?A1E>EqH&?1s?#6La&2jAEX^W4&+mqj( zJteBUiUM2SkODD=#YlkwtgS8Z%2XqeM5oVx&Yix6J-9wyqtQqklnTn=>hgxv;tIg)OSQ44lAYFCBk?1I+7a+PHl0rvL!8 ze_3>u^ZShyO#=XcA%B>rwXxyoh04WuqGJ(4Z7k>AK5O}jD@hmd){YIYH@9V{id+Qn zIYH1CkkC^LSX(VYCEHOP{_pj9UTbQ&Ra7uyj1~YuL{U&Q`)5V~Fhh$1ilfmtp00g{3grA#XK+biX+x)`bht(}!S#{lR zwcJI5&O8>N zZTACwgZt^|c+SsNv^JaLIt#I0MgRdlytU}_5_;#&-%h{n)Xm25PLknegX1`)YBIpj z_@M5r0~AA8qzSpUmYMeZqcNs0J9f0Tk|_1KoKvK7r7HS)*tme7d2qk^j>FAvO^N`M z$%MBBiQ_>5$1oHGmhpm2sfh5QrBV>n5^$NVn2Jz#BM$)3`SDV@uzlsh?P>`N z*tzwk@%7%^OI#?DEhQF%CPNPd*?lVr1w#;Y)VoQ}mu51Vf{EttY6&;7J*26QCJz9> z1p@HEVgW9|c8eiM0tlr+NlD>CqItVvCK6O$UUsO-t(n-$hz(nM^n#CF*!dUV%uWj1Ykk0Bbk%TI}}Nb(`M5nG^vvpDcWF*ywTF zbeRS^p1?z=7^u1S?Mp=};)4d2b>;f?6$iWeZ7qNO5+ll)K+97jLhy7u2LLFYB?E)5bD~tV-=9OZ7DbZ>0N7mi+C&9!KJ9baBJO!`k_23p ztE6ODpZejUfKY%x(tM}R8E>G7z+mANE|96{Xd9}s8rQx0_N7?9o63G)oQlkcSy!uo z5C9So@T>>OkOvepYQz^G&7YL0fQV_WIa0DlOi{}TLKOQj|9?Y*z;T@atOY|`N=uK1 z;z?Ff@yd2vApPYmt(cfLhJw*~B=7-0TseQ{@RUVImLwt|qFJZ^{OE1~*qsPaJmz*& zzneee((K7IXO9RUIRXI|2`JQ(DCU6PPR}T~zC5pRxUuUo+gx|E(d+Eko+##k2|x%i zT0(C~HyCB%F`vf`UbpM)Q)^B=NECO#1k@aQc12G9@Vu_oufKWi9^-Uv>I?3G2 Date: Wed, 12 Feb 2025 00:11:22 +0000 Subject: [PATCH 81/96] minor code fixes --- apps/pacer/app.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/pacer/app.js b/apps/pacer/app.js index 1422f7810..d12a13b01 100644 --- a/apps/pacer/app.js +++ b/apps/pacer/app.js @@ -46,12 +46,12 @@ var skip_max = 0; var force_write = true; var show_lap = false; var lcd_on = true; +var drawSats = false; var dist = 0.0; var pdist = 0.0; var oldDist = 0.0; var oldLat = -1; var oldLon = -1; -var oldTime = -1; var cadence = 0; var pace = 0; var ppace = 0; @@ -176,12 +176,10 @@ function saveGPS(fix) { doPace(newTime,dist); oldLat = newLat; oldLon = newLon; - oldTime = newTime; } } else { oldLat = newLat; oldLon = newLon; - oldTime = newTime; } if (recording && cfg.record && (force_write || skip_ctr == 0)) { fp.write([gps.time.getTime(),gps.lat.toFixed(5),gps.lon.toFixed(5),gps.alt].join(",")+"\n"); @@ -540,7 +538,6 @@ function pause(e) { if (!show_lap) drawTime(); drawStart(); - oldTime = -1; if (!isNaN(gps.time) && !isNaN(gps.lat) && !isNaN(gps.lon) && !isNaN(gps.alt) && cfg.record && (last_time != gps.time)) fp.write([gps.time.getTime(),gps.lat.toFixed(5),gps.lon.toFixed(5),gps.alt].join(",")+"\n"); Bangle.buzz(); From bc88bf08e3be6c086c5e68651c0834f6fad70047 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Tue, 11 Feb 2025 20:10:16 -0500 Subject: [PATCH 82/96] Fix sanity check tabs, defines --- apps/daymoon/app.js | 69 +++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/apps/daymoon/app.js b/apps/daymoon/app.js index 53d6fd640..352395ba8 100644 --- a/apps/daymoon/app.js +++ b/apps/daymoon/app.js @@ -4,22 +4,22 @@ let location; var Utils = require("graphics_utils"); var SunCalc = require("suncalc"); var RADII = { - moon: 40, - arcMin: 48, - arcMax: 63, - dots: 55, - needle: 54, + moon: 40, + arcMin: 48, + arcMax: 63, + dots: 55, + needle: 54, }; var COL ={ - moon: 65535, // - txture:33792, // 0.5 ,0.5,0 - shadow: 8196, // .125,0, .125 - day: 40159, //0.6, 0.6,1 - night: 6, // 0, 0, 0.2 - ndots: 2047, // 0, 1, 1 cyan - ddots: 0, - needle:63488, // 1, 0, 0 red - stime: 2047 + moon: 65535, // + txture:33792, // 0.5 ,0.5,0 + shadow: 8196, // .125,0, .125 + day: 40159, //0.6, 0.6,1 + night: 6, // 0, 0, 0.2 + ndots: 2047, // 0, 1, 1 cyan + ddots: 0, + needle:63488, // 1, 0, 0 red + stime: 2047 }; const TAU = 2.0*Math.PI; const MX=g.getWidth()/2,MY=24+3+RADII.arcMax; @@ -60,8 +60,8 @@ function drawDayRing(times){ let r_ = RADII.arcMin; let rm = RADII.arcMax; let rd = RADII.dots; - radT=[tToRad(times[0]),tToRad(times[1])]; - hhmm=[require("locale").time(times[0],1),require("locale").time(times[1],1)]; + let radT=[tToRad(times[0]),tToRad(times[1])]; + let hhmm=[require("locale").time(times[0],1),require("locale").time(times[1],1)]; g.setColor(COL.day); Utils.fillArc(g,MX,MY,r_,rm,radT[0],radT[1]); g.setColor(COL.night); @@ -72,28 +72,28 @@ function drawDayRing(times){ g.setFontAlign(0,1,1).drawString(hhmm[1],MX+rm+2,MY); //draw dots let edges=[]; - var isday=true; + boolean isDay; let flag = false; if (radT[1]>TAU){ - edges=[radT[1]-TAU,radT[0]]; - g.setColor(COL.ddots); - isDay=true; + edges=[radT[1]-TAU,radT[0]]; + g.setColor(COL.ddots); + isDay=true; } else { - edges=[radT[0],radT[1]]; - g.setColor(COL.ndots); - isDay=false; + edges=[radT[0],radT[1]]; + g.setColor(COL.ndots); + isDay=false; } for (var i=0;i<24;i++) { let a=i*TAU/24; - if (!flag && a>edges[0]){ - //first cross - if (isDay){g.setColor(COL.ndots);}else{g.setColor(COL.ddots);} - flag = true; - } else if (flag && a>edges[1]){ - //second cross - if (isDay){g.setColor(COL.ddots);}else{g.setColor(COL.ndots);} - flag = false; - } + if (!flag && a>edges[0]){ + //first cross + if (isDay){g.setColor(COL.ndots);}else{g.setColor(COL.ddots);} + flag = true; + } else if (flag && a>edges[1]){ + //second cross + if (isDay){g.setColor(COL.ddots);}else{g.setColor(COL.ndots);} + flag = false; + } let dotSize = (i%3 == 0) ? 2 : 1; let pX = MX+Math.cos(a)*rd; let pY = MY+Math.sin(a)*rd; @@ -104,7 +104,7 @@ function drawDayRing(times){ let qY=[1,rd-10,1,12-rd]; g.setFont('4x6').setFontAlign(0,0,0).setColor(COL.ndots); for (var j=0;j<4;j++){ - g.drawString(labels[j],MX+qX[j],MY+qY[j]); + g.drawString(labels[j],MX+qX[j],MY+qY[j]); } } @@ -115,7 +115,8 @@ function drawHHMM(d) { g.setBgColor(0,0,0).setColor(1,1,1).setFontVector(45); g.setFontAlign(1,1,0).drawString(" "+HM[0],MX-20,g.getHeight()+3); g.setFontAlign(-1,1,0).drawString(HM[1]+" ",MX+30,g.getHeight()+3); - var meridian = require("locale").meridian(d); + // TODO: use the meridian text AM/PM or blank for 24 hr. + // var meridian = require("locale").meridian(d); } function moonShade(pos,mp) { From e4644727338441dc9d5697bbceea48907c83ab54 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Wed, 12 Feb 2025 19:43:04 +1100 Subject: [PATCH 83/96] grandfatherclock: show/hide functionality change sets width to 0 and checks inside the draw function rather than leaving them undefined --- apps/grandfatherclock/widget.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/grandfatherclock/widget.js b/apps/grandfatherclock/widget.js index bb9d9406f..96e121e63 100644 --- a/apps/grandfatherclock/widget.js +++ b/apps/grandfatherclock/widget.js @@ -16,11 +16,13 @@ WIDGETS["grandfatherclock"] = { area: "tr", - width: config.draw_widget ? 16 : undefined, - draw: config.draw_widget ? function() { - g.reset(); - g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); - } : undefined + width: config.draw_widget ? 16 : 0, + draw: function() { + if (config.draw_widget) { + g.reset(); + g.drawImage(atob("EBiDASSTJJISSSSZJJJCSSTJ///ISSZP///5CTJ/////ITJ/////ITJ/+B//ITJ/+B//ITJ//+P/ITJ/////ISZP///5CSRJ///ICSQJJJJACSYBJJIBCSYABgABCSYABgABCSYAJAABCSYANgABCSYBtgABCSYNtsABCSYBtgABCSYAMAABCSYAAAABCSZJJJJJCQ=="), this.x, this.y); + } + } }; let date; From 1c02277bac2057223cfada1010c574d415181d43 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Wed, 12 Feb 2025 09:38:25 -0500 Subject: [PATCH 84/96] Prettify and validate JS --- apps/daymoon/app.js | 285 +++++++++++++++++++++++--------------------- 1 file changed, 149 insertions(+), 136 deletions(-) diff --git a/apps/daymoon/app.js b/apps/daymoon/app.js index 352395ba8..25664ecea 100644 --- a/apps/daymoon/app.js +++ b/apps/daymoon/app.js @@ -10,28 +10,37 @@ var RADII = { dots: 55, needle: 54, }; -var COL ={ - moon: 65535, // - txture:33792, // 0.5 ,0.5,0 - shadow: 8196, // .125,0, .125 - day: 40159, //0.6, 0.6,1 - night: 6, // 0, 0, 0.2 - ndots: 2047, // 0, 1, 1 cyan - ddots: 0, - needle:63488, // 1, 0, 0 red - stime: 2047 +var COL = { + moon: 65535, // + txture: 33792, // 0.5 ,0.5,0 + shadow: 8196, // .125,0, .125 + day: 40159, //0.6, 0.6,1 + night: 6, // 0, 0, 0.2 + ndots: 2047, // 0, 1, 1 cyan + ddots: 0, + needle: 63488, // 1, 0, 0 red + stime: 2047 }; -const TAU = 2.0*Math.PI; -const MX=g.getWidth()/2,MY=24+3+RADII.arcMax; +const TAU = 2.0 * Math.PI; +const MX = g.getWidth() / 2, + MY = 24 + 3 + RADII.arcMax; const DAY_MILLIS = 86400000; -const M_POS = {x:MX,y:MY,r:RADII.moon}; +const M_POS = { x: MX, y: MY, r: RADII.moon }; // images -const moon_texture = { width : 80, height : 80, bpp : 1,transparent:0, - buffer : require("heatshrink").decompress(atob("ABsRqAJHkEiBA0N0uq1AIEgNVqtRqoJEgUiAAQJEioTBAAIzEl2q12oxATECQdVioJD/eqne60UCHQoADoAJBgf+xWrFIOACYUFCYo8Cj/73f70er0ROHAANUBIM//3///q1WIFAV1qtXCggJB//7CYO6keikBOHKAUDCIInClSgCgonBu4TK1W73ShBMQxkCh5OC//uFIInBi91q5PFCYISC3er//iOwXVE41UCYf+9//9AnCJopVBqEv/+/3//E4P6kUgJw4nDKAP+14TB1Xoq4hBEwYFBqgnB3Wr3e737KB/QnIqp3B32OKAYTBE4Z4BAoYnBEoRSC0fyE5ITBJ4WuCYP4J4J3CeQQFClbvBJgOqn5kBnRPKTwJMB1B4B92qEgQACJ4JTBkYnBYwOilYsBO5NUhYmB9+qxGC9TxBEYTvFqki3Y8B1Uikei3+oionIgGrO4OqwGC9H/xATK1/7E4UAnU7kATIqEAl/uE4WA12u0ATJgSgB/+ikUgnW70EFCY9AgGDE4PowEAlWowEBCZJ4BneggUgkRSBCZEAgEKJoIEBgEIAYQOCKYcVBIMqJgIEBgQSCgAQBqiJDRQIOBEwYAEMgNRiITBqKKBCYJJBE4xQGMQIABlBPHHgInDHQQjEAQJTCHgbFEABg8EBg5SDCgxNDABI=")) +const moon_texture = { + width: 80, + height: 80, + bpp: 1, + transparent: 0, + buffer: require("heatshrink").decompress(atob("ABsRqAJHkEiBA0N0uq1AIEgNVqtRqoJEgUiAAQJEioTBAAIzEl2q12oxATECQdVioJD/eqne60UCHQoADoAJBgf+xWrFIOACYUFCYo8Cj/73f70er0ROHAANUBIM//3///q1WIFAV1qtXCggJB//7CYO6keikBOHKAUDCIInClSgCgonBu4TK1W73ShBMQxkCh5OC//uFIInBi91q5PFCYISC3er//iOwXVE41UCYf+9//9AnCJopVBqEv/+/3//E4P6kUgJw4nDKAP+14TB1Xoq4hBEwYFBqgnB3Wr3e737KB/QnIqp3B32OKAYTBE4Z4BAoYnBEoRSC0fyE5ITBJ4WuCYP4J4J3CeQQFClbvBJgOqn5kBnRPKTwJMB1B4B92qEgQACJ4JTBkYnBYwOilYsBO5NUhYmB9+qxGC9TxBEYTvFqki3Y8B1Uikei3+oionIgGrO4OqwGC9H/xATK1/7E4UAnU7kATIqEAl/uE4WA12u0ATJgSgB/+ikUgnW70EFCY9AgGDE4PowEAlWowEBCZJ4BneggUgkRSBCZEAgEKJoIEBgEIAYQOCKYcVBIMqJgIEBgQSCgAQBqiJDRQIOBEwYAEMgNRiITBqKKBCYJJBE4xQGMQIABlBPHHgInDHQQjEAQJTCHgbFEABg8EBg5SDCgxNDABI=")) +}; +const needle = { + width: 23, + height: 11, + bpp: 1, + transparent: 0, + buffer: atob("///B///D///AAAPAAAHAAAHAAAcAADz///H//8P//wA=") }; -const needle = { width: 23, height: 11, bpp:1, transparent:0, - buffer: atob("///B///D///AAAPAAAHAAAHAAAcAADz///H//8P//wA=") - }; /* now use SunCalc.getMoonIllumination() @@ -43,132 +52,136 @@ const needle = { width: 23, height: 11, bpp:1, transparent:0, // requires the myLocation app function loadLocation() { - location = require("Storage").readJSON(LOCATION_FILE,1)||{"lat":45,"lon":-71.3,"location":"Nashua"};//{"lat":51.5072,"lon":0.1276,"location":"London"}; + location = require("Storage").readJSON(LOCATION_FILE, 1) || { "lat": 45, "lon": -71.3, "location": "Nashua" }; //{"lat":51.5072,"lon":0.1276,"location":"London"}; } -function drawMoon(shadowShape){ - g.setColor(0,0,0).fillCircle(MX,MY,RADII.arcMax+3); - g.setColor(COL.moon).fillCircle(MX,MY,RADII.moon); - g.setColor(COL.txture).drawImage(moon_texture,MX,MY,{rotate:0}); - //later can set the rotation here to the parallacticAngle from getMoonPosition - g.setColor(COL.shadow).fillPoly(shadowShape); - //later set rotation of the fillPoly? parallactic-mp.angle I think. - //Use g.transformVertices to do the rotation +function drawMoon(shadowShape) { + g.setColor(0, 0, 0).fillCircle(MX, MY, RADII.arcMax + 3); + g.setColor(COL.moon).fillCircle(MX, MY, RADII.moon); + g.setColor(COL.txture).drawImage(moon_texture, MX, MY, { rotate: 0 }); + // TODO: can set the rotation here to the parallacticAngle from getMoonPosition + g.setColor(COL.shadow).fillPoly(shadowShape); + // TODO: set rotation of the fillPoly? parallactic-mp.angle I think. + // Use g.transformVertices to do the rotation } -function drawDayRing(times){ - let r_ = RADII.arcMin; - let rm = RADII.arcMax; - let rd = RADII.dots; - let radT=[tToRad(times[0]),tToRad(times[1])]; - let hhmm=[require("locale").time(times[0],1),require("locale").time(times[1],1)]; - g.setColor(COL.day); - Utils.fillArc(g,MX,MY,r_,rm,radT[0],radT[1]); - g.setColor(COL.night); - Utils.fillArc(g,MX,MY,r_,rm,radT[1]-TAU,radT[0]); - //write sunrise/sunset times - g.setFont('6x8').setColor(COL.stime); - g.setFontAlign(0,1,3).drawString(hhmm[0],MX-rm-2,MY); - g.setFontAlign(0,1,1).drawString(hhmm[1],MX+rm+2,MY); - //draw dots - let edges=[]; - boolean isDay; - let flag = false; - if (radT[1]>TAU){ - edges=[radT[1]-TAU,radT[0]]; - g.setColor(COL.ddots); - isDay=true; - } else { - edges=[radT[0],radT[1]]; - g.setColor(COL.ndots); - isDay=false; - } - for (var i=0;i<24;i++) { - let a=i*TAU/24; - if (!flag && a>edges[0]){ - //first cross - if (isDay){g.setColor(COL.ndots);}else{g.setColor(COL.ddots);} - flag = true; - } else if (flag && a>edges[1]){ - //second cross - if (isDay){g.setColor(COL.ddots);}else{g.setColor(COL.ndots);} - flag = false; +function drawDayRing(times) { + let r_ = RADII.arcMin; + let rm = RADII.arcMax; + let rd = RADII.dots; + let radT = [tToRad(times[0]), tToRad(times[1])]; + let hhmm = [require("locale").time(times[0], 1), require("locale").time(times[1], 1)]; + g.setColor(COL.day); + Utils.fillArc(g, MX, MY, r_, rm, radT[0], radT[1]); + g.setColor(COL.night); + Utils.fillArc(g, MX, MY, r_, rm, radT[1] - TAU, radT[0]); + // write sunrise/sunset times + g.setFont('6x8').setColor(COL.stime); + g.setFontAlign(0, 1, 3).drawString(hhmm[0], MX - rm - 2, MY); + g.setFontAlign(0, 1, 1).drawString(hhmm[1], MX + rm + 2, MY); + // draw dots + let edges = []; + let isDay = false; + let flag = false; + if (radT[1] > TAU) { + edges = [radT[1] - TAU, radT[0]]; + g.setColor(COL.ddots); + isDay = true; + } else { + edges = [radT[0], radT[1]]; + g.setColor(COL.ndots); + isDay = false; + } + for (var i = 0; i < 24; i++) { + let a = i * TAU / 24; + if (!flag && a > edges[0]) { + //first cross + if (isDay) { g.setColor(COL.ndots); } else { g.setColor(COL.ddots); } + flag = true; + } else if (flag && a > edges[1]) { + //second cross + if (isDay) { g.setColor(COL.ddots); } else { g.setColor(COL.ndots); } + flag = false; + } + let dotSize = (i % 3 == 0) ? 2 : 1; + let pX = MX + Math.cos(a) * rd; + let pY = MY + Math.sin(a) * rd; + g.fillCircle(pX, pY, dotSize); + } + let labels = ['6P', '12A', '6A', '12P']; + let qX = [rd - 9, 2, 11 - rd, 2]; + let qY = [1, rd - 10, 1, 12 - rd]; + g.setFont('4x6').setFontAlign(0, 0, 0).setColor(COL.ndots); + for (var j = 0; j < 4; j++) { + g.drawString(labels[j], MX + qX[j], MY + qY[j]); } - let dotSize = (i%3 == 0) ? 2 : 1; - let pX = MX+Math.cos(a)*rd; - let pY = MY+Math.sin(a)*rd; - g.fillCircle(pX,pY,dotSize); - } - let labels=['6P','12A','6A','12P']; - let qX=[rd-9,2,11-rd,2]; - let qY=[1,rd-10,1,12-rd]; - g.setFont('4x6').setFontAlign(0,0,0).setColor(COL.ndots); - for (var j=0;j<4;j++){ - g.drawString(labels[j],MX+qX[j],MY+qY[j]); - } } function drawHHMM(d) { - var HM=require("locale").time(d, 1 /*omit seconds*/).split(":"); - //write digital time - g.setBgColor(0,0,0).setColor(1,1,1).setFontVector(45); - g.setFontAlign(1,1,0).drawString(" "+HM[0],MX-20,g.getHeight()+3); - g.setFontAlign(-1,1,0).drawString(HM[1]+" ",MX+30,g.getHeight()+3); - // TODO: use the meridian text AM/PM or blank for 24 hr. - // var meridian = require("locale").meridian(d); + var HM = require("locale").time(d, 1 /*omit seconds*/ ).split(":"); + // write digital time + g.setBgColor(0, 0, 0).setColor(1, 1, 1).setFontVector(45); + g.setFontAlign(1, 1, 0).drawString(" " + HM[0], MX - 20, g.getHeight() + 3); + g.setFontAlign(-1, 1, 0).drawString(HM[1] + " ", MX + 30, g.getHeight() + 3); + // TODO: use the meridian text AM/PM or blank for 24 hr. + // var meridian = require("locale").meridian(d); } -function moonShade(pos,mp) { - pos = pos !== undefined ? pos : M_POS; - mp = mp !== undefined ? mp : SunCalc.getMoonIllumination(new Date()); - //position has x,y, r for the drawing, mp is from SunCalc Moon Illumination - let k=mp.fraction; - //k is the percent along the equator of the terminator - const pts = Math.min(pos.r>>1,32); - //this gives r/2 pts on the way down and up, capped at 64 total for polyfill - let a=[],b=[],s1=1,s2=0; - // scale s1 is 1 or -1 for fixed edge of the shadow; defined via case switches below - // scale s2 factor for the moving edge of the shadow - // need to do some computation to simplify for new/full moon if k 'close enough' to 0 or 1/-1 - // - let isWaxing=(mp.phase<0.5); - s1 = isWaxing ? -1 : 1; - s2 = isWaxing ? 1-2*k : 2*k-1; - let tr =(pos.r+0.5); - for (var i=0;i> 1, 32); + // this gives r/2 pts on the way down and up, capped at 64 total for polyfill + let a = [], + b = [], + s1 = 1, + s2 = 0; + // scale s1 is 1 or -1 for fixed edge of the shadow; defined via case switches below + // scale s2 factor for the moving edge of the shadow + // need to do some computation to simplify for new/full moon if k 'close enough' to 0 or 1/-1 + // + let isWaxing = (mp.phase < 0.5); + s1 = isWaxing ? -1 : 1; + s2 = isWaxing ? 1 - 2 * k : 2 * k - 1; + let tr = (pos.r + 0.5); + for (var i = 0; i < pts; i++) { + // down stroke on the outer shadow + var t = i * Math.PI / (pts + 1); //pts+1 so we leave the last point for the starting of going up + let cirX = Math.sin(t) * tr; + let cirY = Math.cos(t) * tr; + a.push(pos.x + s1 * cirX); //x + a.push(pos.y + cirY); //y + b.push(pos.x + s2 * cirX); //x for shadow edge + b.push(pos.y - cirY); //y going up for shadow edge + } + return a.concat(b); } function tToRad(date) { - date = (date !== undefined) ? new Date(date.getTime()) : new Date(); - let milli = date - new Date(date.setHours(0,0,0,0)); - return (milli/DAY_MILLIS +0.25)*TAU; + date = (date !== undefined) ? new Date(date.getTime()) : new Date(); + let milli = date - new Date(date.setHours(0, 0, 0, 0)); + return (milli / DAY_MILLIS + 0.25) * TAU; } function draw() { - // work out how to display the current time - var d = new Date(), a=tToRad(d); - var shape = moonShade(M_POS,SunCalc.getMoonIllumination(d)); - var sTimes = SunCalc.getTimes(d,location.lat,location.lon); - var daylight = [sTimes.sunrise,sTimes.sunset]; - //clear time area - g.setColor(0).fillRect(0,176-45,176,176); - drawMoon(shape); - drawDayRing(daylight); - drawHHMM(d); - //draw pointer - //Maybe later make this an overlay that can be removed?? -avoid drawing so much every minute/second - g.setColor(COL.needle).drawImage(needle,MX+RADII.needle*Math.cos(a),MY+RADII.needle*Math.sin(a),{rotate:a}); + // work out how to display the current time + var d = new Date(), + a = tToRad(d); + var shape = moonShade(M_POS, SunCalc.getMoonIllumination(d)); + var sTimes = SunCalc.getTimes(d, location.lat, location.lon); + var daylight = [sTimes.sunrise, sTimes.sunset]; + //clear time area + g.setColor(0).fillRect(0, 176 - 45, 176, 176); + drawMoon(shape); + drawDayRing(daylight); + drawHHMM(d); + // draw pointer + // TODO: Maybe later make this an overlay that can be removed?? -avoid drawing so much every minute/second + g.setColor(COL.needle).drawImage(needle, MX + RADII.needle * Math.cos(a), MY + RADII.needle * Math.sin(a), { rotate: a }); } @@ -176,20 +189,20 @@ function draw() { g.reset(); // requires the myLocation app loadLocation(); -g.setBgColor(0,0,0).clear(); +g.setBgColor(0, 0, 0).clear(); // draw immediately at first draw(); // now draw every second // eventually maybe update the moon just every hour?? var secondInterval = setInterval(draw, 10000); //was 1000 // Stop updates when LCD is off, restart when on -Bangle.on('lcdPower',on=>{ - if (secondInterval) clearInterval(secondInterval); - secondInterval = undefined; - if (on) { - secondInterval = setInterval(draw, 10000); //was 1000 - draw(); // draw immediately - } +Bangle.on('lcdPower', on => { + if (secondInterval) clearInterval(secondInterval); + secondInterval = undefined; + if (on) { + secondInterval = setInterval(draw, 10000); //was 1000 + draw(); // draw immediately + } }); /* Show launcher when middle button pressed This should be done *before* Bangle.loadWidgets so that @@ -197,5 +210,5 @@ widgets know if they're being loaded into a clock app or not */ Bangle.setUI("clock"); // Load widgets Bangle.loadWidgets(); -g.setTheme({bg:"#000"}); +g.setTheme({ bg: "#000" }); Bangle.drawWidgets(); \ No newline at end of file From 4d86934924a0b4a4e36b565adf9b4d79d041a61d Mon Sep 17 00:00:00 2001 From: MomentumV Date: Wed, 12 Feb 2025 09:56:02 -0500 Subject: [PATCH 85/96] Update README.md --- apps/daymoon/README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/daymoon/README.md b/apps/daymoon/README.md index 2c7e0e6ad..5cd46f07e 100644 --- a/apps/daymoon/README.md +++ b/apps/daymoon/README.md @@ -6,11 +6,13 @@ This uses the myLocation app to get your latitude and longitude for proper dayli ## Future Development Feature roadmap: - - [x]0.01 Fix blocking widgets - - [x]0.03 Day and Night different color markers - - [ ]0.05 add Day of week and month display - - [ ]0.06 Seconds display - - [ ]0.07 Color Themes (and settings/options) - - [ ]0.08 Moon display angle represents how it looks in the sky - - [ ]0.10 custom/bigger/fitted time digits - - [ ]0.20 clockinfo support? + - [x] 0.01 Fix blocking widgets + - [x] 0.03 Day and Night different color markers + - [ ] 0.05 add Day of week and month display + - [ ] 0.06 Seconds display + - [ ] 0.07 Color Themes (and settings/options) + - [ ] 0.08 Moon display angle represents how it looks in the sky + - [ ] 0.10 custom/bigger/fitted time digits + - [ ] 0.20 clockinfo support? + - [ ] 0.30 Tap/swipe actions? + From 4c4831fd438bf772dd972da57a47731c65ff66cf Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Wed, 12 Feb 2025 17:18:02 +0100 Subject: [PATCH 86/96] daymoon: set all dark theme info --- apps/daymoon/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/daymoon/app.js b/apps/daymoon/app.js index 25664ecea..9ed5c5354 100644 --- a/apps/daymoon/app.js +++ b/apps/daymoon/app.js @@ -210,5 +210,5 @@ widgets know if they're being loaded into a clock app or not */ Bangle.setUI("clock"); // Load widgets Bangle.loadWidgets(); -g.setTheme({ bg: "#000" }); +g.setTheme({fg:"#fff", bg:"#000", fg2:"#fff", bg2:"#004", fgH:"#fff", bgH:"#00f", dark:true }); Bangle.drawWidgets(); \ No newline at end of file From 13b16ac87dccc022f63ace1827a84ce9ea70d83f Mon Sep 17 00:00:00 2001 From: Logan B <3870583+thinkpoop@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:17:54 -0600 Subject: [PATCH 87/96] [gbmusic] delete commented out code --- apps/gbmusic/app.js | 54 --------------------------------------------- 1 file changed, 54 deletions(-) diff --git a/apps/gbmusic/app.js b/apps/gbmusic/app.js index 1f6f6c620..50e7cf500 100644 --- a/apps/gbmusic/app.js +++ b/apps/gbmusic/app.js @@ -91,7 +91,6 @@ function rScroller(l) { const w = g.stringWidth(l.label)+40, y = l.y+l.h/2; l.offset = l.offset%w; - //g.setClipRect(l.x, l.y, l.x+l.w-1, l.y+l.h-1) g.setColor(l.col).setBgColor(l.bgCol) // need to set colors: iScroll calls this function outside Layout .setFontAlign(-1, 0) // left center .clearRect(l.x, l.y, l.x+l.w-1, l.y+l.h-1) @@ -129,58 +128,6 @@ function rInfo(l) { .drawString(l.label, l.x+l.w/2, l.y); } -// *** Unused Function *** -// // /** -// // * Render icon -// // * @param l -// // */ -// // function rIcon(l) { -// // const x2 = l.x+l.w-1, -// // y2 = l.y+l.h-1; -// // switch(l.icon) { -// // case "pause": { -// // const w13 = l.w/3; -// // g.drawRect(l.x, l.y, l.x+w13, y2); -// // g.drawRect(l.x+l.w-w13, l.y, x2, y2); -// // break; -// // } -// // case "play": { -// // g.drawPoly([ -// // l.x, l.y, -// // x2, l.y+l.h/2, -// // l.x, y2, -// // ], true); -// // break; -// // } -// // case "previous": { -// // const w15 = l.w*1/5; -// // g.drawPoly([ -// // x2, l.y, -// // l.x+w15, l.y+l.h/2, -// // x2, y2, -// // ], true); -// // g.drawRect(l.x, l.y, l.x+w15, y2); -// // break; -// // } -// // case "next": { -// // const w45 = l.w*4/5; -// // g.drawPoly([ -// // l.x, l.y, -// // l.x+w45, l.y+l.h/2, -// // l.x, y2, -// // ], true); -// // g.drawRect(l.x+w45, l.y, x2, y2); -// // break; -// // } -// // default: { // red X -// // console.log(`Unknown icon: ${l.icon}`); -// // g.setColor("#f00") -// // .drawRect(l.x, l.y, x2, y2) -// // .drawLine(l.x, l.y, x2, y2) -// // .drawLine(l.x, y2, x2, l.y); -// // } -// // } -// // } let layout; function makeUI() { @@ -492,7 +439,6 @@ function startLCDWatch() { Bangle.on("lcdPower", (on) => { if (on) { // redraw and resume scrolling - //tick(); // Not sure what this function was; currently undefined layout.render(); fadeOut(); if (layout.title.offset!==null) { // Making an assumption about what offset.offset was supposed to be From 15688b545b60fe7d8b2beb074352cea184889da9 Mon Sep 17 00:00:00 2001 From: smulrine Date: Wed, 12 Feb 2025 23:18:36 +0000 Subject: [PATCH 88/96] Add files via upload --- apps/pacer/screenshot.png | Bin 0 -> 2592 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/pacer/screenshot.png diff --git a/apps/pacer/screenshot.png b/apps/pacer/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..d97f04d7d9c7619d8b802b15905a92869e412f23 GIT binary patch literal 2592 zcmb7``8(8o7so%}8Dq>COK6yssfc7ZNLjN?m@;T`yRB0~Su(QUwjm`?gu+imA39r`$@M}S6AXsz)^|B_alH1y=VR<8_*VMs_D$EpNkg|2> zE6!UqH#M)DX2iN92jJqb1ICn9H9xhDmYxm3(O~nnRnKGLeQBX7XO%b`$WfA<9sB?lBDt<15d)@H^<_AF;DFkPylIqCz5g&11p)9XX`95k6 zuHe(1x2KU5yx9(Wt!hK6ZIdB13ch*_uY|hmSM$EI^~gg;Dg+b$ZUU;P-L&Ofrb*M@ zpHF^y3n&C_=i18HauVaKY;zE?ULwnG&uZDIGRhqT!Qb9pm*Zm!^69Ud(NsSbPknMh zm%9km;wBm_#8IS&qINOet|!OH58h4-vKLw5R;0W^*9KM0V6aL2`_d|`;cmsazG85M zFL#hD+$eL!qKm?`8a~Fo2HL{4gTbJI|7*l)|7oOZ){4{R@`or07#(R#;s++WqEe$=gGy#iY z2NeMv+z>Dop=F8wrz#8Nxe9sxM!rHDHMvSxG&IKQ0?(afYnaGvNgJ+^L%>74CX+!i| z9Nwq%Nhcn(Zxrzr)2LRP#1~7GUjAHbeSD}OjOhe*S+cd#K#J*xz54LP_4KJA91L(U zsrOwq)vkHu4+HI8``oF`KAHDyx9^%Mvyad%Zhb8SRDUTjl5$%Ko}(UXBi@OOGJ%-d z;&q$F3x3lgoi87D!v9iH!{9X;grLldP8j4lw^>e49&xFS|K5uyNHK~0>e?KSv<7!f znsi_?-k@58kcErPjh!C97^6pBM>d_|zekFzDYp@?`SAJblRn!YH+2GfC_)qK^JAPox+0aIC71Ocw2v1@-TicM|$qY2_ zbgv*2lFBFNCMY^&y}O8~H*sAFzyE!U$a*z8{d~ieAmLyKUF3JYaYeWJ7SCwRvkLSq zK=gIrS}6kX-#0raEXFL59#Z@ho}{4t zkJc)$SGC-&?y8^Df8^krB0wn72<**=2z9`LUuoDiErRac)-!nHgk?xYtZCk>h@LYF z;JSWC)kAtCa)iE9&v{d2fb#FGB1cxw5^`NIp*&KjB4UEqbFB8QsvDmrhv1JNm7<>qct7F zcK#F4f&DOSpuiBOFJRCx&_4!?)m=mr47})_N3X{d2V~EWP4%ZEat??8N29@Q{Xw0C z+}N2{p!AgB<}Y!3uKY7!dP=IUn$*43XSnu8eyl?>(&9cQ@}lv2jiSJtMnxd`Sck&D z#w(s~6ou45`F=ouMcWi=j{m;MI-uKUYRj+lNrZHqUJ5|2W#SPL6c{lL-qyMRm_5a9 zsR;^pl&`F9KGerPIJhm?I#Dc2qbg4BPz%-zhQAxZO z=d5ty#{o&}%;Rfr>)-s9 z8tp@rp|#g2xJ=+XqOGek#?&%7p4< zU4NcOs)Nn4XYL{?z@hp{!F%;hy#>czqm}YdOB?SNS!(NfBxiw@m>y>=q@OoTN#Kod zS3)O@BfxYLmhaunl(8GU!VZk74^`Bn#@XuyB+}Mh&mu!TYY`03eZzah&FP|^fsYH0_$BA872-t~ z(wu#MbIQERV|=AOKidNs%2W*#HLD1hrA%UVP%J6I@mYC0iId&Db-Zho9a}<3MM^Lg^?}sNvaF&=y06d5L}v1;Q3MAN4^iJiuFi10P$%!R^?R{eWH4ny?OVNQx4G wDG4HTkQ9HWJz%ngiM>d5-2YVe|7pw-nGNqLH6zQY@J>EpX>M&+X+n?tFVEPW{r~^~ literal 0 HcmV?d00001 From faf65dd93af47662188cb4f7fe670e71e7dbdc73 Mon Sep 17 00:00:00 2001 From: smulrine Date: Wed, 12 Feb 2025 23:20:06 +0000 Subject: [PATCH 89/96] added screenshot --- apps/pacer/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pacer/metadata.json b/apps/pacer/metadata.json index 1fb5fcdcd..87d5fb1ce 100644 --- a/apps/pacer/metadata.json +++ b/apps/pacer/metadata.json @@ -8,6 +8,7 @@ "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "interface": "interface.html", + "screenshots": [{"url":"screenshot.png"}], "storage": [ {"name":"pacer.app.js","url":"app.js"}, {"name":"pacer.img","url":"app-icon.js","evaluate":true} From 2aadfe9bc862bccac3feaea6299e4d2cbaaecec6 Mon Sep 17 00:00:00 2001 From: smulrine Date: Wed, 12 Feb 2025 23:21:51 +0000 Subject: [PATCH 90/96] fixed Bangle.js2 exit icon --- apps/pacer/app.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/apps/pacer/app.js b/apps/pacer/app.js index d12a13b01..6b2b9efce 100644 --- a/apps/pacer/app.js +++ b/apps/pacer/app.js @@ -46,7 +46,7 @@ var skip_max = 0; var force_write = true; var show_lap = false; var lcd_on = true; -var drawSats = false; +var drawSats = true; var dist = 0.0; var pdist = 0.0; var oldDist = 0.0; @@ -507,21 +507,22 @@ function mainLoop() { function restart(e) { if (bangle2 && (e.time - e.lastTime > 0.5)) { finish(); + } else { + g.reset(); + setColours(); + paused_time += (Date.now() - begin_pause); + pace = 0; + drawPause(); + oldDist = dist; + skip_ctr = 0; + force_write = true; + recording = true; + Bangle.buzz(); + if (!bangle2) + setWatch(pause, BTN2); + else + setWatch(pause, BTN1, { edge: 'falling' }); } - g.reset(); - setColours(); - paused_time += (Date.now() - begin_pause); - pace = 0; - drawPause(); - oldDist = dist; - skip_ctr = 0; - force_write = true; - recording = true; - Bangle.buzz(); - if (!bangle2) - setWatch(pause, BTN2); - else - setWatch(pause, BTN1, { edge: 'falling' }); } function pause(e) { From 879485b664dbd3ac28852653e4706211542e56fd Mon Sep 17 00:00:00 2001 From: Logan B <3870583+thinkpoop@users.noreply.github.com> Date: Wed, 12 Feb 2025 18:29:00 -0600 Subject: [PATCH 91/96] [gbmusic] update sendCommand parameter jsdoc --- apps/gbmusic/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/gbmusic/app.js b/apps/gbmusic/app.js index 50e7cf500..b09d772ff 100644 --- a/apps/gbmusic/app.js +++ b/apps/gbmusic/app.js @@ -367,7 +367,7 @@ function handleButton2Press() { let tCommand = {}; /** * Send command and highlight corresponding control - * @param {string} command - "play"/"pause"/"next"/"previous"/"volumeup"/"volumedown" + * @param {"play"|"pause"|"playpause"|"next"|"previous"|"volumeup"|"volumedown"} command */ function sendCommand(command) { Bluetooth.println(""); From 7a245cc8af83841d789ad565d01839c7cefeae5f Mon Sep 17 00:00:00 2001 From: Logan B <3870583+thinkpoop@users.noreply.github.com> Date: Wed, 12 Feb 2025 18:31:39 -0600 Subject: [PATCH 92/96] [gbmusic] always send playpause when toggling play/pause --- apps/gbmusic/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/gbmusic/app.js b/apps/gbmusic/app.js index b09d772ff..31e56ec39 100644 --- a/apps/gbmusic/app.js +++ b/apps/gbmusic/app.js @@ -390,7 +390,7 @@ function handleTouch(btn, pos) { } function togglePlay() { - sendCommand(stat==="play" ? "pause" : "playpause"); + sendCommand("playpause"); } /** From d7f6dc953cca9502c0e0703d2ef6291aa9f37e47 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Thu, 13 Feb 2025 12:51:13 -0500 Subject: [PATCH 93/96] 0.04.1 release Fixes a bug in the dot coloring and adds more screenshots --- apps/daymoon/ChangeLog | 3 +- apps/daymoon/README.md | 3 +- apps/daymoon/app.js | 333 ++++++++++++++++++++---------------- apps/daymoon/metadata.json | 4 +- apps/daymoon/s1.png | Bin 0 -> 4005 bytes apps/daymoon/s2.png | Bin 0 -> 4429 bytes apps/daymoon/s3.png | Bin 0 -> 3632 bytes apps/daymoon/s4.png | Bin 0 -> 3527 bytes apps/daymoon/screenshot.png | Bin 4538 -> 0 bytes 9 files changed, 196 insertions(+), 147 deletions(-) create mode 100644 apps/daymoon/s1.png create mode 100644 apps/daymoon/s2.png create mode 100644 apps/daymoon/s3.png create mode 100644 apps/daymoon/s4.png delete mode 100644 apps/daymoon/screenshot.png diff --git a/apps/daymoon/ChangeLog b/apps/daymoon/ChangeLog index 8e650db84..a793d2017 100644 --- a/apps/daymoon/ChangeLog +++ b/apps/daymoon/ChangeLog @@ -1,4 +1,5 @@ 0.01: First functional release 0.02: move moon down, rotate sunrise/sunset, shift Hours/minutes to corners 0.03: Change day and night to have different dots -0.04: Update ChangeLog, coerce dark theme \ No newline at end of file +0.04: Update ChangeLog, coerce dark theme +0.04.1: Add more screenshots, fix bug in dot colors diff --git a/apps/daymoon/README.md b/apps/daymoon/README.md index 5cd46f07e..2162bf808 100644 --- a/apps/daymoon/README.md +++ b/apps/daymoon/README.md @@ -8,6 +8,7 @@ This uses the myLocation app to get your latitude and longitude for proper dayli Feature roadmap: - [x] 0.01 Fix blocking widgets - [x] 0.03 Day and Night different color markers + - [x] 0.04 Add to App Loader - [ ] 0.05 add Day of week and month display - [ ] 0.06 Seconds display - [ ] 0.07 Color Themes (and settings/options) @@ -15,4 +16,4 @@ Feature roadmap: - [ ] 0.10 custom/bigger/fitted time digits - [ ] 0.20 clockinfo support? - [ ] 0.30 Tap/swipe actions? - + \ No newline at end of file diff --git a/apps/daymoon/app.js b/apps/daymoon/app.js index 9ed5c5354..cb560ae9f 100644 --- a/apps/daymoon/app.js +++ b/apps/daymoon/app.js @@ -4,42 +4,46 @@ let location; var Utils = require("graphics_utils"); var SunCalc = require("suncalc"); var RADII = { - moon: 40, - arcMin: 48, - arcMax: 63, - dots: 55, - needle: 54, + moon: 40, + arcMin: 48, + arcMax: 63, + dots: 55, + needle: 54, }; var COL = { - moon: 65535, // - txture: 33792, // 0.5 ,0.5,0 - shadow: 8196, // .125,0, .125 - day: 40159, //0.6, 0.6,1 - night: 6, // 0, 0, 0.2 - ndots: 2047, // 0, 1, 1 cyan - ddots: 0, - needle: 63488, // 1, 0, 0 red - stime: 2047 + moon: 65535, // + txture: 33792, // 0.5 ,0.5,0 + shadow: 8196, // .125,0, .125 + day: 40159, //0.6, 0.6,1 + night: 6, // 0, 0, 0.2 + ndots: 2047, // 0, 1, 1 cyan + ddots: 0, + needle: 63488, // 1, 0, 0 red + stime: 2047 }; const TAU = 2.0 * Math.PI; const MX = g.getWidth() / 2, - MY = 24 + 3 + RADII.arcMax; + MY = 24 + 3 + RADII.arcMax; const DAY_MILLIS = 86400000; -const M_POS = { x: MX, y: MY, r: RADII.moon }; +const M_POS = { + x: MX, + y: MY, + r: RADII.moon +}; // images const moon_texture = { - width: 80, - height: 80, - bpp: 1, - transparent: 0, - buffer: require("heatshrink").decompress(atob("ABsRqAJHkEiBA0N0uq1AIEgNVqtRqoJEgUiAAQJEioTBAAIzEl2q12oxATECQdVioJD/eqne60UCHQoADoAJBgf+xWrFIOACYUFCYo8Cj/73f70er0ROHAANUBIM//3///q1WIFAV1qtXCggJB//7CYO6keikBOHKAUDCIInClSgCgonBu4TK1W73ShBMQxkCh5OC//uFIInBi91q5PFCYISC3er//iOwXVE41UCYf+9//9AnCJopVBqEv/+/3//E4P6kUgJw4nDKAP+14TB1Xoq4hBEwYFBqgnB3Wr3e737KB/QnIqp3B32OKAYTBE4Z4BAoYnBEoRSC0fyE5ITBJ4WuCYP4J4J3CeQQFClbvBJgOqn5kBnRPKTwJMB1B4B92qEgQACJ4JTBkYnBYwOilYsBO5NUhYmB9+qxGC9TxBEYTvFqki3Y8B1Uikei3+oionIgGrO4OqwGC9H/xATK1/7E4UAnU7kATIqEAl/uE4WA12u0ATJgSgB/+ikUgnW70EFCY9AgGDE4PowEAlWowEBCZJ4BneggUgkRSBCZEAgEKJoIEBgEIAYQOCKYcVBIMqJgIEBgQSCgAQBqiJDRQIOBEwYAEMgNRiITBqKKBCYJJBE4xQGMQIABlBPHHgInDHQQjEAQJTCHgbFEABg8EBg5SDCgxNDABI=")) + width: 80, + height: 80, + bpp: 1, + transparent: 0, + buffer: require("heatshrink").decompress(atob("ABsRqAJHkEiBA0N0uq1AIEgNVqtRqoJEgUiAAQJEioTBAAIzEl2q12oxATECQdVioJD/eqne60UCHQoADoAJBgf+xWrFIOACYUFCYo8Cj/73f70er0ROHAANUBIM//3///q1WIFAV1qtXCggJB//7CYO6keikBOHKAUDCIInClSgCgonBu4TK1W73ShBMQxkCh5OC//uFIInBi91q5PFCYISC3er//iOwXVE41UCYf+9//9AnCJopVBqEv/+/3//E4P6kUgJw4nDKAP+14TB1Xoq4hBEwYFBqgnB3Wr3e737KB/QnIqp3B32OKAYTBE4Z4BAoYnBEoRSC0fyE5ITBJ4WuCYP4J4J3CeQQFClbvBJgOqn5kBnRPKTwJMB1B4B92qEgQACJ4JTBkYnBYwOilYsBO5NUhYmB9+qxGC9TxBEYTvFqki3Y8B1Uikei3+oionIgGrO4OqwGC9H/xATK1/7E4UAnU7kATIqEAl/uE4WA12u0ATJgSgB/+ikUgnW70EFCY9AgGDE4PowEAlWowEBCZJ4BneggUgkRSBCZEAgEKJoIEBgEIAYQOCKYcVBIMqJgIEBgQSCgAQBqiJDRQIOBEwYAEMgNRiITBqKKBCYJJBE4xQGMQIABlBPHHgInDHQQjEAQJTCHgbFEABg8EBg5SDCgxNDABI=")) }; const needle = { - width: 23, - height: 11, - bpp: 1, - transparent: 0, - buffer: atob("///B///D///AAAPAAAHAAAHAAAcAADz///H//8P//wA=") + width: 23, + height: 10, + bpp: 1, + transparent: 0, + buffer: atob("//+B///D///AAAHgAADgAAHAAA9///j//+H//gA=") }; /* @@ -52,137 +56,172 @@ const needle = { // requires the myLocation app function loadLocation() { - location = require("Storage").readJSON(LOCATION_FILE, 1) || { "lat": 45, "lon": -71.3, "location": "Nashua" }; //{"lat":51.5072,"lon":0.1276,"location":"London"}; + location = require("Storage").readJSON(LOCATION_FILE, 1) || { + "lat": 45, + "lon": -71.3, + "location": "Nashua" + }; //{"lat":51.5072,"lon":0.1276,"location":"London"}; } function drawMoon(shadowShape) { - g.setColor(0, 0, 0).fillCircle(MX, MY, RADII.arcMax + 3); - g.setColor(COL.moon).fillCircle(MX, MY, RADII.moon); - g.setColor(COL.txture).drawImage(moon_texture, MX, MY, { rotate: 0 }); - // TODO: can set the rotation here to the parallacticAngle from getMoonPosition - g.setColor(COL.shadow).fillPoly(shadowShape); - // TODO: set rotation of the fillPoly? parallactic-mp.angle I think. - // Use g.transformVertices to do the rotation + g.setColor(0, 0, 0).fillCircle(MX, MY, RADII.arcMax + 3); + g.setColor(COL.moon).fillCircle(MX, MY, RADII.moon - 1); + g.setColor(COL.txture).drawImage(moon_texture, MX, MY, { + rotate: 0 + }); + // TODO: can set the rotation here to the parallacticAngle from getMoonPosition + g.setColor(COL.shadow).fillPoly(shadowShape); + // TODO: set rotation of the fillPoly? parallactic-mp.angle I think. + // Use g.transformVertices to do the rotation } function drawDayRing(times) { - let r_ = RADII.arcMin; - let rm = RADII.arcMax; - let rd = RADII.dots; - let radT = [tToRad(times[0]), tToRad(times[1])]; - let hhmm = [require("locale").time(times[0], 1), require("locale").time(times[1], 1)]; - g.setColor(COL.day); - Utils.fillArc(g, MX, MY, r_, rm, radT[0], radT[1]); - g.setColor(COL.night); - Utils.fillArc(g, MX, MY, r_, rm, radT[1] - TAU, radT[0]); - // write sunrise/sunset times - g.setFont('6x8').setColor(COL.stime); - g.setFontAlign(0, 1, 3).drawString(hhmm[0], MX - rm - 2, MY); - g.setFontAlign(0, 1, 1).drawString(hhmm[1], MX + rm + 2, MY); - // draw dots - let edges = []; - let isDay = false; - let flag = false; - if (radT[1] > TAU) { - edges = [radT[1] - TAU, radT[0]]; - g.setColor(COL.ddots); - isDay = true; - } else { - edges = [radT[0], radT[1]]; + let r_ = RADII.arcMin; + let rm = RADII.arcMax; + let rd = RADII.dots; + let radT = [tToRad(times[0]), tToRad(times[1])]; + let hhmm = [require("locale").time(times[0], 1), require("locale").time(times[1], 1)]; + g.setColor(COL.day); + Utils.fillArc(g, MX, MY, r_, rm, radT[0], radT[1]); + g.setColor(COL.night); + Utils.fillArc(g, MX, MY, r_, rm, radT[1] - TAU, radT[0]); + // write sunrise/sunset times + g.setFont('6x8').setColor(COL.stime); + g.setFontAlign(0, 1, 3).drawString(hhmm[0], MX - rm - 2, MY); + g.setFontAlign(0, 1, 1).drawString(hhmm[1], MX + rm + 2, MY); + // draw dots + let edges = []; + let isDay = false; + let flag = false; + if (radT[1] > TAU) { + edges = [radT[1] - TAU, radT[0]]; + g.setColor(COL.ddots); + isDay = true; + } else { + edges = [radT[0], radT[1]]; + g.setColor(COL.ndots); + isDay = false; + } + for (var i = 0; i < 24; i++) { + let a = i * TAU / 24; + if (!flag && a > edges[0] && a < edges[1]) { + //first cross + if (isDay) { g.setColor(COL.ndots); - isDay = false; - } - for (var i = 0; i < 24; i++) { - let a = i * TAU / 24; - if (!flag && a > edges[0]) { - //first cross - if (isDay) { g.setColor(COL.ndots); } else { g.setColor(COL.ddots); } - flag = true; - } else if (flag && a > edges[1]) { - //second cross - if (isDay) { g.setColor(COL.ddots); } else { g.setColor(COL.ndots); } - flag = false; - } - let dotSize = (i % 3 == 0) ? 2 : 1; - let pX = MX + Math.cos(a) * rd; - let pY = MY + Math.sin(a) * rd; - g.fillCircle(pX, pY, dotSize); - } - let labels = ['6P', '12A', '6A', '12P']; - let qX = [rd - 9, 2, 11 - rd, 2]; - let qY = [1, rd - 10, 1, 12 - rd]; - g.setFont('4x6').setFontAlign(0, 0, 0).setColor(COL.ndots); - for (var j = 0; j < 4; j++) { - g.drawString(labels[j], MX + qX[j], MY + qY[j]); + } else { + g.setColor(COL.ddots); + } + flag = true; + } else if (flag && a > edges[1]) { + //second cross + if (isDay) { + g.setColor(COL.ddots); + } else { + g.setColor(COL.ndots); + } + flag = false; } + let dotSize = (i % 3 == 0) ? 2 : 1; + let pX = MX + Math.cos(a) * rd; + let pY = MY + Math.sin(a) * rd; + g.fillCircle(pX, pY, dotSize); + } + let labels = ['6P', '12A', '6A', '12P']; + let qX = [rd - 9, 2, 11 - rd, 2]; + let qY = [1, rd - 10, 1, 12 - rd]; + g.setFont('4x6').setFontAlign(0, 0, 0).setColor(COL.ndots); + for (var j = 0; j < 4; j++) { + g.drawString(labels[j], MX + qX[j], MY + qY[j]); + } } function drawHHMM(d) { - var HM = require("locale").time(d, 1 /*omit seconds*/ ).split(":"); - // write digital time - g.setBgColor(0, 0, 0).setColor(1, 1, 1).setFontVector(45); - g.setFontAlign(1, 1, 0).drawString(" " + HM[0], MX - 20, g.getHeight() + 3); - g.setFontAlign(-1, 1, 0).drawString(HM[1] + " ", MX + 30, g.getHeight() + 3); - // TODO: use the meridian text AM/PM or blank for 24 hr. - // var meridian = require("locale").meridian(d); + var HM = require("locale").time(d, 1 /*omit seconds*/ ).split(":"); + // write digital time + g.setBgColor(0, 0, 0).setColor(1, 1, 1).setFontVector(45); + g.setFontAlign(1, 1, 0).drawString(" " + HM[0], MX - 20, g.getHeight() + 3); + g.setFontAlign(-1, 1, 0).drawString(HM[1] + " ", MX + 30, g.getHeight() + 3); + // TODO: use the meridian text AM/PM or blank for 24 hr. + // var meridian = require("locale").meridian(d); } function moonShade(pos, mp) { - pos = pos !== undefined ? pos : M_POS; - mp = mp !== undefined ? mp : SunCalc.getMoonIllumination(new Date()); - // pos has x,y, r for the drawing, mp is from SunCalc Moon Illumination - let k = mp.fraction; - // k is the percent along the equator of the terminator - const pts = Math.min(pos.r >> 1, 32); - // this gives r/2 pts on the way down and up, capped at 64 total for polyfill - let a = [], - b = [], - s1 = 1, - s2 = 0; - // scale s1 is 1 or -1 for fixed edge of the shadow; defined via case switches below - // scale s2 factor for the moving edge of the shadow - // need to do some computation to simplify for new/full moon if k 'close enough' to 0 or 1/-1 - // - let isWaxing = (mp.phase < 0.5); - s1 = isWaxing ? -1 : 1; - s2 = isWaxing ? 1 - 2 * k : 2 * k - 1; - let tr = (pos.r + 0.5); - for (var i = 0; i < pts; i++) { - // down stroke on the outer shadow - var t = i * Math.PI / (pts + 1); //pts+1 so we leave the last point for the starting of going up - let cirX = Math.sin(t) * tr; - let cirY = Math.cos(t) * tr; - a.push(pos.x + s1 * cirX); //x - a.push(pos.y + cirY); //y - b.push(pos.x + s2 * cirX); //x for shadow edge - b.push(pos.y - cirY); //y going up for shadow edge - } - return a.concat(b); + pos = pos !== undefined ? pos : M_POS; + mp = mp !== undefined ? mp : SunCalc.getMoonIllumination(new Date()); + // pos has x,y, r for the drawing, mp is from SunCalc Moon Illumination + let k = mp.fraction; + // k is the percent along the equator of the terminator + const pts = Math.min(pos.r >> 1, 32); + // this gives r/2 pts on the way down and up, capped at 64 total for polyfill + let a = [], + b = [], + s1 = 1, + s2 = 0; + // scale s1 is 1 or -1 for fixed edge of the shadow; defined via case switches below + // scale s2 factor for the moving edge of the shadow + // need to do some computation to simplify for new/full moon if k 'close enough' to 0 or 1/-1 + // + let isWaxing = (mp.phase < 0.5); + s1 = isWaxing ? -1 : 1; + s2 = isWaxing ? 1 - 2 * k : 2 * k - 1; + let tr = (pos.r + 1); + for (var i = 0; i < pts; i++) { + // down stroke on the outer shadow + var t = i * Math.PI / (pts + 1); //pts+1 so we leave the last point for the starting of going up + let cirX = Math.sin(t) * tr; + let cirY = Math.cos(t) * tr; + a.push(pos.x + s1 * cirX); //x + a.push(pos.y + cirY); //y + b.push(pos.x + s2 * cirX); //x for shadow edge + b.push(pos.y - cirY); //y going up for shadow edge + } + return a.concat(b); } function tToRad(date) { - date = (date !== undefined) ? new Date(date.getTime()) : new Date(); - let milli = date - new Date(date.setHours(0, 0, 0, 0)); - return (milli / DAY_MILLIS + 0.25) * TAU; + date = (date !== undefined) ? new Date(date.getTime()) : new Date(); + let milli = date - new Date(date.setHours(0, 0, 0, 0)); + return (milli / DAY_MILLIS + 0.25) * TAU; } -function draw() { - // work out how to display the current time - var d = new Date(), - a = tToRad(d); - var shape = moonShade(M_POS, SunCalc.getMoonIllumination(d)); - var sTimes = SunCalc.getTimes(d, location.lat, location.lon); - var daylight = [sTimes.sunrise, sTimes.sunset]; - //clear time area - g.setColor(0).fillRect(0, 176 - 45, 176, 176); - drawMoon(shape); - drawDayRing(daylight); - drawHHMM(d); - // draw pointer - // TODO: Maybe later make this an overlay that can be removed?? -avoid drawing so much every minute/second - g.setColor(COL.needle).drawImage(needle, MX + RADII.needle * Math.cos(a), MY + RADII.needle * Math.sin(a), { rotate: a }); +function draw(date) { + d = date !== undefined ? date : new Date(); + //var d = new Date(), + var a = tToRad(d), + shape = moonShade(M_POS, SunCalc.getMoonIllumination(d)), + sTimes = SunCalc.getTimes(d, location.lat, location.lon), + daylight = [sTimes.sunrise, sTimes.sunset]; + //clear time area + g.clearRect(Bangle.appRect); //g.setColor(0).fillRect(0, 176 - 45, 176, 176); + drawMoon(shape); + drawDayRing(daylight); + drawHHMM(d); + // draw pointer + // TODO: Maybe later make this an overlay that can be removed?? -avoid drawing so much every minute/second + g.setColor(COL.needle).drawImage(needle, MX + RADII.needle * Math.cos(a), MY + RADII.needle * Math.sin(a), { + rotate: a + }); + +} +const shotTimes = [1720626960000, 1729184400000, 1738298880000, 1717575420000]; +/*first quarter -2 days moon at 10:20 in the summer + jun 10 2024 10:56 +full moon at 12 noon near fall equinox + Sep 17 2024 12:00 +new moon at 11pm in winter + dec 30 2024 23:48 +3rd quarter moon at 03:17 am + May 5 2024 03:17*/ + +function screenshots(times) { + let d = new Date(); + for (let t of times) { + d.setTime(t); + draw(d); + g.dump(); + } } // Clear the screen once, at startup @@ -197,12 +236,12 @@ draw(); var secondInterval = setInterval(draw, 10000); //was 1000 // Stop updates when LCD is off, restart when on Bangle.on('lcdPower', on => { - if (secondInterval) clearInterval(secondInterval); - secondInterval = undefined; - if (on) { - secondInterval = setInterval(draw, 10000); //was 1000 - draw(); // draw immediately - } + if (secondInterval) clearInterval(secondInterval); + secondInterval = undefined; + if (on) { + secondInterval = setInterval(draw, 10000); //was 1000 + draw(); // draw immediately + } }); /* Show launcher when middle button pressed This should be done *before* Bangle.loadWidgets so that @@ -210,5 +249,13 @@ widgets know if they're being loaded into a clock app or not */ Bangle.setUI("clock"); // Load widgets Bangle.loadWidgets(); -g.setTheme({fg:"#fff", bg:"#000", fg2:"#fff", bg2:"#004", fgH:"#fff", bgH:"#00f", dark:true }); +g.setTheme({ + fg: "#fff", + bg: "#000", + fg2: "#fff", + bg2: "#004", + fgH: "#fff", + bgH: "#00f", + dark: true +}); Bangle.drawWidgets(); \ No newline at end of file diff --git a/apps/daymoon/metadata.json b/apps/daymoon/metadata.json index e2cbf2a8f..49e4b9df8 100644 --- a/apps/daymoon/metadata.json +++ b/apps/daymoon/metadata.json @@ -1,10 +1,10 @@ { "id": "daymoon", "name": "DayMoon Circadian Clock", - "version": "0.04", + "version": "0.04.1", "dependencies": {"mylocation":"app"}, "description": "A 24 hour clockface showing the Moon Phase and portion of the day that the Sun is up inspired by Matthew Clark's *Fair Circadian* Pebble watchface", "icon": "daymoon.png", - "screenshots": [{"url":"screenshot.png"}], + "screenshots": [{"url":"s1.png"},{"url":"s2.png"},{"url":"s3.png"},{"url":"s4.png"}], "type": "clock", "tags": "clock,moon,lunar", "supports": ["BANGLEJS2"], diff --git a/apps/daymoon/s1.png b/apps/daymoon/s1.png new file mode 100644 index 0000000000000000000000000000000000000000..cb64c2f0128317c212e28b95182c84e63844ba98 GIT binary patch literal 4005 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 Nn|h|YRodvd{{fO=i^u=~ literal 0 HcmV?d00001 diff --git a/apps/daymoon/s3.png b/apps/daymoon/s3.png new file mode 100644 index 0000000000000000000000000000000000000000..463be5d2160eaee50a0d89ddc07a7baaea249701 GIT binary patch literal 3632 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 D?gy^@ literal 0 HcmV?d00001 diff --git a/apps/daymoon/screenshot.png b/apps/daymoon/screenshot.png deleted file mode 100644 index 937ab01a9d201702e6c08fa6a5f4beeeca408d06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4538 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 B&Nu)7 From 9a19799af6888490eff1975d944428be872cdf66 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Thu, 13 Feb 2025 13:28:09 -0500 Subject: [PATCH 94/96] Fix versioning I didn't realize it would choke on further dots in the versioning. --- apps/daymoon/ChangeLog | 2 +- apps/daymoon/README.md | 9 +++++---- apps/daymoon/metadata.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/daymoon/ChangeLog b/apps/daymoon/ChangeLog index a793d2017..a00fe7982 100644 --- a/apps/daymoon/ChangeLog +++ b/apps/daymoon/ChangeLog @@ -2,4 +2,4 @@ 0.02: move moon down, rotate sunrise/sunset, shift Hours/minutes to corners 0.03: Change day and night to have different dots 0.04: Update ChangeLog, coerce dark theme -0.04.1: Add more screenshots, fix bug in dot colors +0.05: Add more screenshots, fix bug in dot colors diff --git a/apps/daymoon/README.md b/apps/daymoon/README.md index 2162bf808..4b43b75aa 100644 --- a/apps/daymoon/README.md +++ b/apps/daymoon/README.md @@ -9,10 +9,11 @@ Feature roadmap: - [x] 0.01 Fix blocking widgets - [x] 0.03 Day and Night different color markers - [x] 0.04 Add to App Loader - - [ ] 0.05 add Day of week and month display - - [ ] 0.06 Seconds display - - [ ] 0.07 Color Themes (and settings/options) - - [ ] 0.08 Moon display angle represents how it looks in the sky + - [x] 0.05 Add more screenshots with different moon phases + - [ ] 0.06 add Day of week and month display + - [ ] 0.07 Seconds display + - [ ] 0.08 Color Themes (and settings/options) + - [ ] 0.09 Moon display angle represents how it looks in the sky - [ ] 0.10 custom/bigger/fitted time digits - [ ] 0.20 clockinfo support? - [ ] 0.30 Tap/swipe actions? diff --git a/apps/daymoon/metadata.json b/apps/daymoon/metadata.json index 49e4b9df8..f06e216bc 100644 --- a/apps/daymoon/metadata.json +++ b/apps/daymoon/metadata.json @@ -1,6 +1,6 @@ { "id": "daymoon", "name": "DayMoon Circadian Clock", - "version": "0.04.1", + "version": "0.05", "dependencies": {"mylocation":"app"}, "description": "A 24 hour clockface showing the Moon Phase and portion of the day that the Sun is up inspired by Matthew Clark's *Fair Circadian* Pebble watchface", "icon": "daymoon.png", From d9df4b5f61fb7e8b750533d679b29df73604e4f6 Mon Sep 17 00:00:00 2001 From: MomentumV Date: Thu, 13 Feb 2025 13:43:35 -0500 Subject: [PATCH 95/96] Fix linter complaints Commented out the utility functions and variables used to make documentation. Seems like there should be a better approach, maybe an extra dev.js? --- apps/daymoon/app.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/daymoon/app.js b/apps/daymoon/app.js index cb560ae9f..ce403fdfe 100644 --- a/apps/daymoon/app.js +++ b/apps/daymoon/app.js @@ -186,9 +186,7 @@ function tToRad(date) { } function draw(date) { - d = date !== undefined ? date : new Date(); - - //var d = new Date(), + var d = date !== undefined ? date : new Date(); var a = tToRad(d), shape = moonShade(M_POS, SunCalc.getMoonIllumination(d)), sTimes = SunCalc.getTimes(d, location.lat, location.lon), @@ -205,15 +203,16 @@ function draw(date) { }); } +/* const shotTimes = [1720626960000, 1729184400000, 1738298880000, 1717575420000]; -/*first quarter -2 days moon at 10:20 in the summer +let desc =`first quarter -2 days moon at 10:20 in the summer jun 10 2024 10:56 full moon at 12 noon near fall equinox Sep 17 2024 12:00 new moon at 11pm in winter dec 30 2024 23:48 3rd quarter moon at 03:17 am - May 5 2024 03:17*/ + May 5 2024 03:17` function screenshots(times) { let d = new Date(); @@ -223,7 +222,7 @@ function screenshots(times) { g.dump(); } } - +*/ // Clear the screen once, at startup g.reset(); // requires the myLocation app From f8cc620c02239f5bf6cb82d6d83730c29c89bda8 Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Sat, 15 Feb 2025 03:51:03 +0100 Subject: [PATCH 96/96] confthyttan: add "defaultconfig" tag --- apps/confthyttan/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/confthyttan/metadata.json b/apps/confthyttan/metadata.json index 5fd18c7e9..e662879a7 100644 --- a/apps/confthyttan/metadata.json +++ b/apps/confthyttan/metadata.json @@ -4,7 +4,7 @@ "description": "A different default set of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.", "icon": "app.png", "type": "defaultconfig", - "tags": "system,configuration,config,anotherconfig,thyttan", + "tags": "system,configuration,config,anotherconfig,thyttan,defaultconfig", "supports" : ["BANGLEJS2"], "readme": "README.md", "dependencies" : {