From d6da125df7927dec535c9c8c7c3dea5e145d88c8 Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 16 Feb 2022 17:54:12 +0100 Subject: [PATCH 01/13] Added optinoal fullscreen mode. --- apps/neonx/ChangeLog | 1 + apps/neonx/README.md | 8 +++++-- apps/neonx/metadata.json | 2 +- apps/neonx/neonx.app.js | 45 ++++++++++++++++++++++++------------ apps/neonx/neonx.settings.js | 13 +++++++++-- 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/apps/neonx/ChangeLog b/apps/neonx/ChangeLog index af7f83942..7ac033fe8 100644 --- a/apps/neonx/ChangeLog +++ b/apps/neonx/ChangeLog @@ -1 +1,2 @@ 0.01: Initial release +0.02: Optional fullscreen mode \ No newline at end of file diff --git a/apps/neonx/README.md b/apps/neonx/README.md index d836dfab3..c3926c4b6 100644 --- a/apps/neonx/README.md +++ b/apps/neonx/README.md @@ -4,8 +4,8 @@ |---------------------------------|--------------------------------------| |
Neon X
|
Neon IO X
| -This is a clock based on Pebble's Neon X and Neon IO X watchfaces by Sam Jerichow. -Can be switched between in the Settings menu, which can be accessed through +This is a clock based on Pebble's Neon X and Neon IO X watchfaces by Sam Jerichow. +Can be switched between in the Settings menu, which can be accessed through the app/widget settings menu of the Bangle.js ## Settings @@ -18,3 +18,7 @@ The thickness of watch lines, from 1 to 5. ### Date on touch Shows the current date as DD MM on touch and reverts back to time after 5 seconds or with another touch. + +### Fullscreen +Shows the watchface in fullscreen mode. +Note: In fullscreen mode, widgets are hidden, but still loaded. \ No newline at end of file diff --git a/apps/neonx/metadata.json b/apps/neonx/metadata.json index 41b16d11b..ffa4d1b8e 100644 --- a/apps/neonx/metadata.json +++ b/apps/neonx/metadata.json @@ -2,7 +2,7 @@ "id": "neonx", "name": "Neon X & IO X Clock", "shortName": "Neon X Clock", - "version": "0.01", + "version": "0.02", "description": "Pebble Neon X & Neon IO X for Bangle.js", "icon": "neonx.png", "type": "clock", diff --git a/apps/neonx/neonx.app.js b/apps/neonx/neonx.app.js index 967fc8582..d3521b1db 100644 --- a/apps/neonx/neonx.app.js +++ b/apps/neonx/neonx.app.js @@ -34,6 +34,7 @@ const colors = { const is12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false; const screenWidth = g.getWidth(); +const screenHeight = g.getHeight(); const halfWidth = screenWidth / 2; const scale = screenWidth / 240; const REFRESH_RATE = 10E3; @@ -58,16 +59,19 @@ function drawLine(poly, thickness){ } } -let settings = require('Storage').readJSON('neonx.json', 1); - -if (!settings) { - settings = { - thickness: 4, - io: 0, - showDate: 1 - }; +let settings = { + thickness: 4, + io: 0, + showDate: 1, + fullscreen: false, +}; +let saved_settings = require('Storage').readJSON('neonx.json', 1) || settings; +for (const key in saved_settings) { + settings[key] = saved_settings[key] } + + function drawClock(num){ let tx, ty; @@ -79,13 +83,15 @@ function drawClock(num){ g.setColor(colors[settings.io ? 'io' : 'x'][y][x]); if (!settings.io) { - tx = (x * 100 + 18) * newScale; - ty = (y * 100 + 32) * newScale; + newScale *= settings.fullscreen ? 1.18 : 1.0; + let dx = settings.fullscreen ? 0 : 18 + tx = (x * 100 + dx) * newScale; + ty = (y * 100 + dx*2) * newScale; } else { - newScale = 0.33 + current * 0.4; + newScale = 0.33 + current * (settings.fullscreen ? 0.48 : 0.4); - tx = (halfWidth - 139) * newScale + halfWidth; - ty = (halfWidth - 139) * newScale + halfWidth + 12; + tx = (halfWidth - 139) * newScale + halfWidth + (settings.fullscreen ? 2 : 0); + ty = (halfWidth - 139) * newScale + halfWidth + (settings.fullscreen ? 1 : 12); } for (let i = 0; i < digits[num[y][x]].length; i++) { @@ -116,7 +122,11 @@ function draw(date){ l2 = ('0' + d.getMinutes()).substr(-2); } - g.clearRect(0,24,240,240); + if(settings.fullscreen){ + g.clearRect(0,0,screenWidth,screenHeight); + } else { + g.clearRect(0,24,240,240); + } drawClock([l1, l2]); } @@ -150,4 +160,9 @@ Bangle.on('lcdPower', function(on){ }); Bangle.loadWidgets(); -Bangle.drawWidgets(); + +if(settings.fullscreen){ + for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} +} else { + Bangle.drawWidgets(); +} \ No newline at end of file diff --git a/apps/neonx/neonx.settings.js b/apps/neonx/neonx.settings.js index 0e205e03b..b4b481baf 100644 --- a/apps/neonx/neonx.settings.js +++ b/apps/neonx/neonx.settings.js @@ -7,7 +7,8 @@ neonXSettings = { thickness: 4, io: 0, - showDate: 1 + showDate: 1, + fullscreen: false, }; updateSettings(); @@ -48,7 +49,15 @@ neonXSettings.showDate = v; updateSettings(); } - } + }, + 'Fullscreen': { + value: false | neonXSettings.fullscreen, + format: () => (neonXSettings.fullscreen ? 'Yes' : 'No'), + onchange: () => { + neonXSettings.fullscreen = !neonXSettings.fullscreen; + updateSettings(); + }, + }, }; E.showMenu(menu); }) From 08af40ff9aeed52acebbfe523659dd5a641f9bb2 Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 16 Feb 2022 18:05:22 +0100 Subject: [PATCH 02/13] Allow a thickness of 6 - looks nice in fullscreen mode. --- apps/neonx/README.md | 2 +- apps/neonx/neonx.settings.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/neonx/README.md b/apps/neonx/README.md index c3926c4b6..f205b702f 100644 --- a/apps/neonx/README.md +++ b/apps/neonx/README.md @@ -14,7 +14,7 @@ the app/widget settings menu of the Bangle.js Activate the Neon IO X clock look, a bit hard to read until one gets used to it. ### Thickness -The thickness of watch lines, from 1 to 5. +The thickness of watch lines, from 1 to 6. ### Date on touch Shows the current date as DD MM on touch and reverts back to time after 5 seconds or with another touch. diff --git a/apps/neonx/neonx.settings.js b/apps/neonx/neonx.settings.js index b4b481baf..3af2e0fa5 100644 --- a/apps/neonx/neonx.settings.js +++ b/apps/neonx/neonx.settings.js @@ -18,7 +18,7 @@ if (!neonXSettings) resetSettings(); - let thicknesses = [1, 2, 3, 4, 5]; + let thicknesses = [1, 2, 3, 4, 5, 6]; const menu = { "" : { "title":"Neon X & IO"}, From 307527386e7f75959514fec2ee99d1b6f790a6ab Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 16 Feb 2022 18:07:15 +0100 Subject: [PATCH 03/13] Minor position fix --- apps/neonx/neonx.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/neonx/neonx.app.js b/apps/neonx/neonx.app.js index d3521b1db..4ef0986fe 100644 --- a/apps/neonx/neonx.app.js +++ b/apps/neonx/neonx.app.js @@ -91,7 +91,7 @@ function drawClock(num){ newScale = 0.33 + current * (settings.fullscreen ? 0.48 : 0.4); tx = (halfWidth - 139) * newScale + halfWidth + (settings.fullscreen ? 2 : 0); - ty = (halfWidth - 139) * newScale + halfWidth + (settings.fullscreen ? 1 : 12); + ty = (halfWidth - 139) * newScale + halfWidth + (settings.fullscreen ? 2 : 12); } for (let i = 0; i < digits[num[y][x]].length; i++) { From 88e9fca8e46e265b3c855de9ae80b50de1c6e06d Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 16 Feb 2022 19:57:22 +0100 Subject: [PATCH 04/13] Add simple info app --- apps/info/ChangeLog | 1 + apps/info/README.md | 17 +++++++ apps/info/info.app.js | 106 ++++++++++++++++++++++++++++++++++++++++ apps/info/info.icon.js | 1 + apps/info/info.png | Bin 0 -> 1548 bytes apps/info/metadata.json | 18 +++++++ 6 files changed, 143 insertions(+) create mode 100644 apps/info/ChangeLog create mode 100644 apps/info/README.md create mode 100644 apps/info/info.app.js create mode 100644 apps/info/info.icon.js create mode 100644 apps/info/info.png create mode 100644 apps/info/metadata.json diff --git a/apps/info/ChangeLog b/apps/info/ChangeLog new file mode 100644 index 000000000..07afedd21 --- /dev/null +++ b/apps/info/ChangeLog @@ -0,0 +1 @@ +0.01: Release \ No newline at end of file diff --git a/apps/info/README.md b/apps/info/README.md new file mode 100644 index 000000000..007a9794e --- /dev/null +++ b/apps/info/README.md @@ -0,0 +1,17 @@ +# Info + +A very simple app that shows information on 3 different screens. +Go to the next screen via tab right, go to the previous screen +via tab left and reload the data via tab in the middle of the +screen. Very useful if combined with pattern launcher ;) + +![](screenshot_1.png) +![](screenshot_2.png) +![](screenshot_2.png) + + +## Contributors +- [David Peer](https://github.com/peerdavid). + +## Thanks To +Info icons created by Freepik - Flaticon diff --git a/apps/info/info.app.js b/apps/info/info.app.js new file mode 100644 index 000000000..b241907f3 --- /dev/null +++ b/apps/info/info.app.js @@ -0,0 +1,106 @@ +var s = require("Storage"); +const locale = require('locale'); +var ENV = process.env; +var W = g.getWidth(), H = g.getHeight(); +var screen = 0; + +function getVersion(file) { + var j = s.readJSON(file,1); + var v = ("object"==typeof j)?j.version:false; + return v?((v?"v"+v:"Unknown")):"NO "; +} + + +function drawData(name, value, y){ + g.drawString(name, 5, y); + g.drawString(value, 100, y); +} + +function getSteps(){ + try{ + return Bangle.getHealthStatus("day").steps; + } catch(e) { + return ">= 2v12"; + } +} + +function getBpm(){ + try{ + return Math.round(Bangle.getHealthStatus("day").bpm) + " bpm"; + } catch(e) { + return ">= 2v12"; + } +} + +function drawInfo() { + g.reset().clearRect(Bangle.appRect); + var h=18, y = h;//-h; + + // Header + g.setFont("Vector", h+2).setFontAlign(0,-1); + g.drawString("--==|| INFO ||==--", W/2, 0); + g.setFont("Vector",h).setFontAlign(-1,-1); + + // Dynamic data + if(screen == 0){ + drawData("Steps", getSteps(), y+=h); + drawData("HRM", getBpm(), y+=h); + drawData("Battery", E.getBattery() + "%", y+=h); + drawData("Voltage", E.getAnalogVRef().toFixed(2) + "V", y+=h); + drawData("IntTemp.", locale.temp(parseInt(E.getTemperature())), y+=h); + } + + if(screen == 1){ + drawData("Charging?", Bangle.isCharging() ? "Yes" : "No", y+=h); + drawData("Bluetooth", NRF.getSecurityStatus().connected ? "Conn." : "Disconn.", y+=h); + drawData("GPS", Bangle.isGPSOn() ? "On" : "Off", y+=h); + drawData("Compass", Bangle.isCompassOn() ? "On" : "Off", y+=h); + drawData("HRM", Bangle.isHRMOn() ? "On" : "Off", y+=h); + } + + // Static data + if(screen == 2){ + drawData("Firmw.", ENV.VERSION, y+=h); + drawData("Boot.", getVersion("boot.info"), y+=h); + drawData("Settings", getVersion("setting.info"), y+=h); + drawData("Storage", "", y+=h); + drawData(" Total", ENV.STORAGE>>10, y+=h); + drawData(" Free", require("Storage").getFree()>>10, y+=h); + } + + if(Bangle.isLocked()){ + g.setFont("Vector",h-2).setFontAlign(-1,-1); + g.drawString("Locked", 0, H-h+2); + } + + g.setFont("Vector",h-2).setFontAlign(1,-1); + g.drawString((screen+1) + "/3", W, H-h+2); +} + +drawInfo(); +setWatch(_=>load(), BTN1); + +Bangle.on('touch', function(btn, e){ + var left = parseInt(g.getWidth() * 0.3); + var right = g.getWidth() - left; + var isLeft = e.x < left; + var isRight = e.x > right; + + if(isRight){ + screen = (screen + 1) % 3; + } + + if(isLeft){ + screen = Math.max(0, (screen - 1)); + } + + drawInfo(); +}); + +Bangle.on('lock', function(isLocked) { + drawInfo(); +}); + +Bangle.loadWidgets(); +for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} +// Bangle.drawWidgets(); \ No newline at end of file diff --git a/apps/info/info.icon.js b/apps/info/info.icon.js new file mode 100644 index 000000000..8dbab8357 --- /dev/null +++ b/apps/info/info.icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwcBkmSpICDBwcJBYwCDpAhFggRJGg8SCI+ABgU//gSDCI4JBj//AAX4JRAIBg4QDAAPgBIJWGgIQFAAI+BLglAgEPCI/wEgJoEgYQHAAPANwhWFAApcBCIWQgAQJAAMAgSMDCJiSCwB6GQA6eCn5TFL4q5BUgIRF/wuBv4RGkCeGO4IREUgMBCJCVGCISwIWw0BYRLIICLBHHCJRrGCIQIFR44I5LIoRaPpARcdIwRJfYMBCJuACKUkgE/a5f8gEJCJD7FCIeAg78FAAvggFJCIMACJZOBCIOQCJsCCIOSgEfCBP4gESCIZTFOIwRDoDIGaguSCIVIgCkFTwcAggRDpIYBQAx6BgAOCAQYIBLghWBTwQRFFgIABXIIFDBwgCDBYQAENAYCFLgIAEKwpKIIhA=")) diff --git a/apps/info/info.png b/apps/info/info.png new file mode 100644 index 0000000000000000000000000000000000000000..c73813025950aaccc31b7476b67ceb6326b5f915 GIT binary patch literal 1548 zcmV+n2J`ueP)&f>~B9rWa~T zO&bJa&{8T~N=wOnsPP9`P{G7MVAx;4pjMrUnq>u3O-u&aq>I5{OcTJi(H~mE+Gfk` zhf%z{UZL%^)V-5S?s@KcKA+d;p68x>?s-lCJcJM`j>qHsVzJmqkw`=t2n3XO?%er& zqdID}dak;<`dMXVI(xU#bHT_6xR>G%8PGcz;NZ0s~N zG%U$vvRR2l;wmpMzr`nzv}L#3NMqE?>U9sV}3^`177Udj^Y&ihNF|^Y3){HkHX_ z>Vgz^uDQ9Hx_I#-m8nKXMyO-Qj-_l7v)OE$oSZD;4S)Ld>7i6kawUyM!)d>>vvV|S zaD>nY27_UO%kb3HRL)j5ALy~a-T<{$o9eDw#%WO6$1)vYg-1N(D?XxQV}@xNctk%xpOD4x1`Z%WTd51>G=A70zybg5X4iUO_JPhH?K*TTrQtZ z*gACR5bxP2olT`u`I44a);1UZ7t1PreSKQaX432RZhAqp*<5ILiX=$}yjH9Aq+IBA zI2@m`qdkBAe8J$kmKLp6>o;^}##Cb4wr%rg&YbC|=bbxu4z6Fn&KYn%b^G>huvjdN zyzcJqA4*C}o^DtXA%v|hWiukba^*@v?|fTZ+fN&=OtW?3#EB`kkyEEmJs? z`0?YvWVFEn05C8xP@~i79fFvXm(BVxnoIvU-OZ#@ss601s~g(Ad-pw(B>zgcUe-T*L?RK@^73+r z-|zp@>-A=}prlkPU&~~&=TfP3yrQCFGMk@0c+C*ky4LTko@l5yPs}U y=jhR+zwg?$YqqMY>dE%)+keAx+{foHm45-pmUCXlaFiAR0000 Date: Wed, 16 Feb 2022 20:00:33 +0100 Subject: [PATCH 05/13] Added screenshots --- apps/info/screenshot_1.png | Bin 0 -> 3552 bytes apps/info/screenshot_2.png | Bin 0 -> 3334 bytes apps/info/screenshot_3.png | Bin 0 -> 3455 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/info/screenshot_1.png create mode 100644 apps/info/screenshot_2.png create mode 100644 apps/info/screenshot_3.png diff --git a/apps/info/screenshot_1.png b/apps/info/screenshot_1.png new file mode 100644 index 0000000000000000000000000000000000000000..97d42a89636e01437a6397075db1dc453ca22fe8 GIT binary patch literal 3552 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 literal 0 HcmV?d00001 diff --git a/apps/info/screenshot_2.png b/apps/info/screenshot_2.png new file mode 100644 index 0000000000000000000000000000000000000000..2d25dd4e6ce4166d5a6b48ad7f50231bf643cc95 GIT binary patch literal 3334 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 literal 0 HcmV?d00001 diff --git a/apps/info/screenshot_3.png b/apps/info/screenshot_3.png new file mode 100644 index 0000000000000000000000000000000000000000..782e4a1952f1dc3205f20852edf88e9493edd6d8 GIT binary patch literal 3455 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 Xk+%_!CsMW>72tTx)$W-M?(+Wt^h|>m literal 0 HcmV?d00001 From 88ea3bd0b11f3f946939647a7647cecca94663f4 Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 16 Feb 2022 20:02:20 +0100 Subject: [PATCH 06/13] Added README to metadata --- apps/info/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/info/metadata.json b/apps/info/metadata.json index 9b82acb4e..f05f0e134 100644 --- a/apps/info/metadata.json +++ b/apps/info/metadata.json @@ -6,6 +6,7 @@ "icon": "info.png", "type": "app", "tags": "tool", + "readme": "README.md", "supports": ["BANGLEJS2"], "screenshots": [ {"url":"screenshot_1.png"}, From 50f973b3d3779ef883aab748bbbf3fca39ca2184 Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 16 Feb 2022 20:44:35 +0100 Subject: [PATCH 07/13] Pagination bugfix. --- apps/info/info.app.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/info/info.app.js b/apps/info/info.app.js index b241907f3..bce9d4cff 100644 --- a/apps/info/info.app.js +++ b/apps/info/info.app.js @@ -3,6 +3,7 @@ const locale = require('locale'); var ENV = process.env; var W = g.getWidth(), H = g.getHeight(); var screen = 0; +const maxScreen = 2; function getVersion(file) { var j = s.readJSON(file,1); @@ -87,11 +88,12 @@ Bangle.on('touch', function(btn, e){ var isRight = e.x > right; if(isRight){ - screen = (screen + 1) % 3; + screen = (screen + 1) % (maxScreen+1); } if(isLeft){ - screen = Math.max(0, (screen - 1)); + screen -= 1; + screen = screen < 0 ? maxScreen : screen; } drawInfo(); From 9dd3e9b06925b848d89eadd9ec46d7ada4085a0a Mon Sep 17 00:00:00 2001 From: hughbarney Date: Wed, 16 Feb 2022 20:02:56 +0000 Subject: [PATCH 08/13] Pastel: make new boolean setting work --- apps/pastel/ChangeLog | 1 + apps/pastel/metadata.json | 2 +- apps/pastel/pastel.settings.js | 32 +++++++++++--------------------- 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/apps/pastel/ChangeLog b/apps/pastel/ChangeLog index d133697b3..a77fa758f 100644 --- a/apps/pastel/ChangeLog +++ b/apps/pastel/ChangeLog @@ -16,3 +16,4 @@ 0.14: incorporated lazybones idle timer, configuration settings to come 0.15: fixed tendancy for mylocation to default to London added setting to enable/disable idle timer warning +0.16: make check_idle boolean setting work properly with new B2 menu diff --git a/apps/pastel/metadata.json b/apps/pastel/metadata.json index da3c18eae..f04a7ae54 100644 --- a/apps/pastel/metadata.json +++ b/apps/pastel/metadata.json @@ -2,7 +2,7 @@ "id": "pastel", "name": "Pastel Clock", "shortName": "Pastel", - "version": "0.15", + "version": "0.16", "description": "A Configurable clock with custom fonts, background and weather display. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", "icon": "pastel.png", "dependencies": {"mylocation":"app","weather":"app"}, diff --git a/apps/pastel/pastel.settings.js b/apps/pastel/pastel.settings.js index 26dafd271..afe461f15 100644 --- a/apps/pastel/pastel.settings.js +++ b/apps/pastel/pastel.settings.js @@ -38,38 +38,28 @@ }, }, 'Show Grid': { - value: s.grid, - format: () => (s.grid ? 'Yes' : 'No'), - onchange: () => { - s.grid = !s.grid; + value: !!s.grid, + format: v => v ? /*LANG*/"Yes":/*LANG*/"No", + onchange: v => { + s.grid = v; save(); }, }, 'Show Weather': { - value: s.weather, - format: () => (s.weather ? 'Yes' : 'No'), - onchange: () => { - s.weather = !s.weather; + value: !!s.weather, + format: v => v ? /*LANG*/"Yes":/*LANG*/"No", + onchange: v => { + s.weather = v; save(); }, }, - // for use when the new menu system goes live - /* 'Idle Warning': { - value: s.idle_check, - onchange : v => { + value: !!s.idle_check, + format: v => v ? /*LANG*/"Yes":/*LANG*/"No", + onchange: v => { s.idle_check = v; save(); }, - }, - */ - 'Idle Warning': { - value: s.idle_check, - format: () => (s.idle_check ? 'Yes' : 'No'), - onchange: () => { - s.idle_check = !s.idle_check; - save(); - }, } }) }) From ece775bb8ea0e38d38123116fa49865923b6cc1f Mon Sep 17 00:00:00 2001 From: David Peer Date: Wed, 16 Feb 2022 21:31:46 +0100 Subject: [PATCH 09/13] Minor change --- apps/info/info.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/info/info.app.js b/apps/info/info.app.js index bce9d4cff..c61a88045 100644 --- a/apps/info/info.app.js +++ b/apps/info/info.app.js @@ -27,7 +27,7 @@ function getSteps(){ function getBpm(){ try{ - return Math.round(Bangle.getHealthStatus("day").bpm) + " bpm"; + return Math.round(Bangle.getHealthStatus("day").bpm) + "bpm"; } catch(e) { return ">= 2v12"; } From 864faef9617c2e551093abff341aa8f3d2a62d57 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Wed, 16 Feb 2022 21:59:28 +0100 Subject: [PATCH 10/13] widbars - Yellow battery bar on charge and prevent GC on every draw --- apps/widbars/ChangeLog | 2 ++ apps/widbars/metadata.json | 2 +- apps/widbars/widget.js | 10 ++++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/widbars/ChangeLog b/apps/widbars/ChangeLog index 4c21f3ace..61e28e6e4 100644 --- a/apps/widbars/ChangeLog +++ b/apps/widbars/ChangeLog @@ -1 +1,3 @@ 0.01: New Widget! +0.02: Battery bar turns yellow on charge + Memory status bar does not trigger garbage collect diff --git a/apps/widbars/metadata.json b/apps/widbars/metadata.json index e8d52c90a..a9981305c 100644 --- a/apps/widbars/metadata.json +++ b/apps/widbars/metadata.json @@ -1,7 +1,7 @@ { "id": "widbars", "name": "Bars Widget", - "version": "0.01", + "version": "0.02", "description": "Display several measurements as vertical bars.", "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], diff --git a/apps/widbars/widget.js b/apps/widbars/widget.js index a1134f31f..cceeb0897 100644 --- a/apps/widbars/widget.js +++ b/apps/widbars/widget.js @@ -42,19 +42,25 @@ if (top) g .clearRect(x,y, x+w-1,y+top-1); // erase above bar if (f) g.setColor(col).fillRect(x,y+top, x+w-1,y+h-1); // even for f=0.001 this is still 1 pixel high } + let batColor='#0f0'; function draw() { g.reset(); const x = this.x, y = this.y, - m = process.memory(); + m = process.memory(false); let b=0; // ==HRM== bar(x+(w*b++),y,'#f00'/*red */,bpm/200); // >200 seems very unhealthy; if we have no valid bpm this will just be empty space // ==Temperature== bar(x+(w*b++),y,'#ff0'/*yellow */,E.getTemperature()/50); // you really don't want to wear a watch that's hotter than 50°C bar(x+(w*b++),y,g.theme.dark?'#0ff':'#00f'/*cyan/blue*/,1-(require('Storage').getFree() / process.env.STORAGE)); bar(x+(w*b++),y,'#f0f'/*magenta*/,m.usage/m.total); - bar(x+(w*b++),y,'#0f0'/*green */,E.getBattery()/100); + bar(x+(w*b++),y,batColor,E.getBattery()/100); } let redraw; + Bangle.on('charging', function(charging) { + batColor=charging?'#ff0':'#0f0'; + WIDGETS["bars"].draw(); + }); + Bangle.on('lcdPower', on => { if (redraw) clearInterval(redraw) redraw = undefined; From 63156bcca81875e7b61f6f64a69492e513f9e246 Mon Sep 17 00:00:00 2001 From: Danny <31635744+DDDanny@users.noreply.github.com> Date: Thu, 17 Feb 2022 02:42:21 +0100 Subject: [PATCH 11/13] v 0.04 fixes #1154 --- apps/timecal/ChangeLog | 9 + apps/timecal/README.md | 22 + apps/timecal/metadata.json | 11 +- apps/timecal/testing/timecal.app.test.js | 798 +++++++++++++++++++++++ apps/timecal/timecal.app.js | 352 +++++++--- apps/timecal/timecal.settings.js | 109 ++++ 6 files changed, 1211 insertions(+), 90 deletions(-) create mode 100644 apps/timecal/ChangeLog create mode 100644 apps/timecal/README.md create mode 100644 apps/timecal/testing/timecal.app.test.js create mode 100644 apps/timecal/timecal.settings.js diff --git a/apps/timecal/ChangeLog b/apps/timecal/ChangeLog new file mode 100644 index 000000000..43bff461d --- /dev/null +++ b/apps/timecal/ChangeLog @@ -0,0 +1,9 @@ +0.01: Initial creation of the clock face time and calendar +0.02: Feature Request #1154 and some findings... + -> get rendered time from optimisations + -> *BATT SAFE* only update once a minute instead of once a second + -> *RAM optimized* clean code, corrected minute update (timout, no intervall) + -> locale: weekday name (first two characters) from locale + -> added settings to render cal view begin day (-1: today, 0:sunday, 1:monday [default]) +0.03: a lot of more settings for outline, colors and highlights +0.04: finalized README, fixed settings cancel, fixed border-setting \ No newline at end of file diff --git a/apps/timecal/README.md b/apps/timecal/README.md new file mode 100644 index 000000000..d26f9ba4d --- /dev/null +++ b/apps/timecal/README.md @@ -0,0 +1,22 @@ +# Calendar Clock + +## Features +Shows the +* Date +* Time (hh:mm) - respecting 12/24 (uses locale string) +* 3 weeks calendar view (last,current and next week) + +### The settings menu +Calendar View can be customized +* < Save: Exist and save the current settings +* Show date: Choose if and how the date is displayed: none, locale (default), monthfull or monthshort.yearshort #weeknum with 0 prefixed +* Start wday: Set day of week start. Values: 0=Sunday, 1=Monday,...,6=Saturday or -1=Relative to today (default 0: Sunday) +* Su color: Set Sundays color. Values: none (default), red, green or blue +* Border: show or none (default) +* Submenu Today settings - choose how today is highlighted + * < Back: + * Color: none, red (default), green or blue + * Marker: Outline today graphically. Values: none (default), circle, rect(angle) + * Mrk.Color: Circle/rectangle color: red (default), green or blue + * Mrk.Size: Circle/rectangle thickness in pixel: min:1, max: 10, default:3 +* < Cancel: Exit and no change. Nevertheless missing default settings and superflous settings will be removed and saved. diff --git a/apps/timecal/metadata.json b/apps/timecal/metadata.json index 3237dd08a..4dd8a8ca0 100644 --- a/apps/timecal/metadata.json +++ b/apps/timecal/metadata.json @@ -1,13 +1,16 @@ { "id": "timecal", "name": "TimeCal", "shortName":"TimeCal", + "version":"0.04", + "description": "TimeCal shows the date/time along with a 3 week calendar", "icon": "icon.png", - "version":"0.01", - "description": "TimeCal shows the Time along with a 3 week calendar", - "tags": "clock", "type": "clock", + "tags": "clock,calendar", "supports":["BANGLEJS2"], + "readme": "README.md", + "allow_emulator":true, "storage": [ - {"name":"timecal.app.js","url":"timecal.app.js"} + {"name":"timecal.app.js","url":"timecal.app.js"}, + {"name":"timecal.settings.js","url":"timecal.settings.js"} ] } diff --git a/apps/timecal/testing/timecal.app.test.js b/apps/timecal/testing/timecal.app.test.js new file mode 100644 index 000000000..e41f3d848 --- /dev/null +++ b/apps/timecal/testing/timecal.app.test.js @@ -0,0 +1,798 @@ +//Clock renders date, time and pre,current,next week calender view +class TimeCalClock{ + DATE_FONT_SIZE(){ return 20; } + TIME_FONT_SIZE(){ return 40; } + + /** + * @param{Date} date optional the date (e.g. for testing) + * @param{Settings} settings optional settings to use e.g. for testing + */ + constructor(date, settings){ + if (date) + this.date=date; + + if (settings) + this._settings = settings; + else + this._settings = require("Storage").readJSON("timecal.settings.json", 1) || {}; + + const defaults = { + shwDate:1, //0:none, 1:locale, 2:month, 3:monthshort.year #week + + wdStrt:0, //identical to getDay() 0->Su, 1->Mo, ... //Issue #1154: weekstart So/Mo, -1 for use today + + tdyNumClr:3, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E + tdyMrkr:0, //0:none, 1:circle, 2:rectangle, 3:filled + tdyMrkClr:2, //1:red=#E00, 2:green=#0E0, 3:blue=#00E + tdyMrkPxl:3, //px + + suClr:1, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E + //phColor:"#E00", //public holiday + + calBrdr:false + }; + for (const k in this._settings) if (!defaults.hasOwnProperty(k)) delete this._settings[k]; //remove invalid settings + for (const k in defaults) if(!this._settings.hasOwnProperty(k)) this._settings[k] = defaults[k]; //assign missing defaults + + g.clear(); + Bangle.setUI("clock"); + Bangle.loadWidgets(); + Bangle.drawWidgets(); + + this.centerX = Bangle.appRect.w/2; + this.nrgb = [g.theme.fg, "#E00", "#0E0", "#00E"]; //fg, r ,g , b + + this.ABR_DAY=[]; + if (require("locale") && require("locale").dow) + for (let d=0; d<=6; d++) { + var refDay=new Date(); + refDay.setFullYear(1972); + refDay.setMonth(0); + refDay.setDate(2+d); + this.ABR_DAY.push(require("locale").dow(refDay)); + + } + else + this.ABR_DAY=["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + } + + /** + * @returns {Object} current settings object + */ + settings(){ + return this._settings; + } + + + /* + * Run forest run + **/ + draw(){ + this.drawTime(); + + if (this.TZOffset===undefined || this.TZOffset!==d.getTimezoneOffset()) + this.drawDateAndCal(); + } + + /** + * draw given or current time from date + * overwatch timezone changes + * schedules itself to update + */ + drawTime(){ + d=this.date ? this.date : new Date(); + const Y=Bangle.appRect.y+this.DATE_FONT_SIZE()+10; + + d=d?d :new Date(); + + g.setFontAlign(0, -1).setFont("Vector", this.TIME_FONT_SIZE()).setColor(g.theme.fg) + .clearRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+this.TIME_FONT_SIZE()-7) + .drawString(("0" + require("locale").time(d, 1)).slice(-5), this.centerX, Y, true); + //.drawRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+this.TIME_FONT_SIZE()-7); //DEV-Option + + setTimeout(this.draw.bind(this), 60000-(d.getSeconds()*1000)-d.getMilliseconds()); + } + + /** + * draws given date and cal + * @param{Date} d provide date or uses today + */ + drawDateAndCal(){ + d=this.date ? this.date : new Date(); + + this.TZOffset=d.getTimezoneOffset(); + this.drawDate(); + this.drawCal(); + + if (this.tOutD) //abort exisiting + clearTimeout(this.tOutD); + this.tOutD=setTimeout(this.drawDateAndCal.bind(this), 86400000-(d.getHours()*24*60*1000)-(d.getMinutes()*60*1000)-d.getSeconds()-d.getMilliseconds()); + } + + /** + * draws given date as defiend in settings + */ + drawDate(){ + d=this.date ? this.date : new Date(); + + const FONT_SIZE=20; + const Y=Bangle.appRect.y; + var render=false; + var dateStr = ""; + if (this.settings().shwDate>0) { //skip if exactly -none + const dateSttngs = ["","l","M","m.Y #W"]; + for (let c of dateSttngs[this.settings().shwDate]) { //add part as configured + switch (c){ + case "l":{ //locale + render=true; + dateStr+=require("locale").date(d,1); + break; + } + case "m":{ //month e.g. Jan. + render=true; + dateStr+=require("locale").month(d,1); + break; + } + case "M":{ //month e.g. January + render=true; + dateStr+=require("locale").month(d,0); + break; + } + case "y":{ //year e.g. 22 + render=true; + dateStr+=d.getFullYear().slice(-2); + break; + } + case "Y":{ //year e.g. 2022 + render=true; + dateStr+=d.getFullYear(); + break; + } + case "w":{ //week e.g. #2 + dateStr+=(this.ISO8601calWeek(d)); + break; + } + case "W":{ //week e.g. #02 + dateStr+=("0"+this.ISO8601calWeek(d)).slice(-2); + break; + } + default: //append c + dateStr+=c; + render=dateStr.length>0; + break; //noop + } + } + } + if (render){ + g.setFont("Vector", FONT_SIZE).setColor(g.theme.fg).setFontAlign(0, -1).clearRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+FONT_SIZE-3).drawString(dateStr,this.centerX,Y); + } + //g.drawRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+FONT_SIZE-3); //DEV-Option + } + + /** + * draws calender week view (-1,0,1) for given date + */ + drawCal(){ + d=this.date ? this.date : new Date(); + + const DAY_NAME_FONT_SIZE=10; + const CAL_Y=Bangle.appRect.y+this.DATE_FONT_SIZE()+10+this.TIME_FONT_SIZE()+3; + const CAL_AREA_H=Bangle.appRect.h-CAL_Y+24; //+24: top widegtes only + const CELL_W=Bangle.appRect.w/7; //cell width + const CELL_H=(CAL_AREA_H-DAY_NAME_FONT_SIZE)/3; //cell heigth + const DAY_NUM_FONT_SIZE=Math.min(CELL_H-1,15); //size down, max 15 + + g.setFont("Vector", DAY_NAME_FONT_SIZE).setColor(g.theme.fg).setFontAlign(-1, -1).clearRect(Bangle.appRect.x, CAL_Y, Bangle.appRect.x2, CAL_Y+CAL_AREA_H); + + //draw grid & Headline + const dNames = this.ABR_DAY.map((a) => a.length<=2 ? a : a.substr(0, 2)); //force shrt 2 + for(var dNo=0; dNo=0 ? (dNo+this.settings().wdStrt)%7 : (dNo+d.getDay()+4)%7; + const dName=dNames[dIdx]; + if(dNo>0) + g.drawLine(dNo*CELL_W, CAL_Y, dNo*CELL_W, CAL_Y+CAL_AREA_H-1); + + if (dIdx==0) g.setColor(this.nrgb[this.settings().suClr]); //sunday maybe colorize txt + g.drawString(dName, dNo*CELL_W+(CELL_W-g.stringWidth(dName))/2+2, CAL_Y+1).setColor(g.theme.fg); + } + + var nextY=CAL_Y+DAY_NAME_FONT_SIZE; + + for(i=0; i<3; i++){ + const y=nextY+i*CELL_H; + g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); + } + + g.setFont("Vector", DAY_NUM_FONT_SIZE); + + //write days + const tdyDate=d.getDate(); + const days=this.settings().wdStrt>=0 ? 7+((7+d.getDay()-this.settings().wdStrt)%7) : 10;//start day (week before=7 days + days in this week realtive to week start) or fixed 7+3 days + var rD=new Date(d.getTime()); + rD.setDate(rD.getDate()-days); + var rDate=rD.getDate(); + for(var y=0; y<3; y++){ + for(var x=0; x", + cases: [ + { + value: "required,", + beforeTxt: "optional,", + beforeExpression: "optional,", + afterText: "optional,", + afterExpression: "optional," + } + ], + constructorParams: ["optional: ","|TEST_SETTINGS|","..."], //TEST_SETTINGS will be replcaed with each current {setting: case} + functionNames: ["required, ", "..."], + functionParams: ["optional: ","|TEST_SETTINGS|","..."] + }; + } + + constructor(data){ + + this._validate(data); + + this.setting = data.setting; + this.cases = data.cases.map((entry) => { + return { + value: entry.value, + beforeTxt: entry.beforeTxt||"", + beforeExpression: entry.beforeExpression||true, + afterTxt: entry.afterTxt||"", + afterExpression: entry.afterExpression||true + }; + }); + this.constructorParams = data.constructorParams; + this.functionNames = data.functionNames; + this.functionParams = data.functionParams; + } + + /** + * validates the given data config + */ + _validate(data){ + //validate given config + if (!data.setting) throw new EmptyMandatoryError("setting", data, this.TEST_SETTING_SAMPLE()); + if (!(data.cases instanceof Array) || data.cases.length==0) throw new EmptyMandatoryError("cases", data, this.TEST_SETTING_SAMPLE()); + if (!(data.functionNames instanceof Array) || data.functionNames==0) throw new EmptyMandatoryError("functionNames", data, this.TEST_SETTING_SAMPLE()); + + data.cases.forEach((entry,idx) => { + if (entry.value === undefined) throw new EmptyMandatoryError("cases["+idx+"].value", entry, this.TEST_SETTING_SAMPLE()); + }); + } +} + +/*************************************************************************/ + +/** + * Testing a Bangle object + */ +class BangleTestRunner{ + /** + * create for ObjClass + * @param {Class} objClass + * @param {LogSeverity} minSeverity to Log + */ + constructor(objClass, minSeverity){ + this.TESTCASE_MSG_BEFORE_TIMEOUT = 1000; //5s + this.TESTCASE_RUN_TIMEOUT = 1000; //5s + this.TESTCASE_MSG_AFTER_TIMEOUT = 1000; //5s + + this.oClass = objClass; + this.minSvrty = minSeverity; + this.tests = []; + + this.currentCaseNum = this.currentTestNum = this.currentTest = this.currentCase = undefined; + } + + /** + * add a Setting Test, return instance for chaining + * @param {TestSetting} + */ + addTestSettings(sttngs) { + this.tests.push(new TestSetting(sttngs)); + return this; + } + + /** + * Test execution of all tests + */ + execute() { + this._init(); + while (this._nextTest()) { + this._beforeTest(); + while (this._nextCase()) { + this._beforeCase(); + this._runCase(); + this._afterCase(); + } + this._afterTest(); + this._firstCase(); + } + this._exit(); + } + + /** + * global prepare - before all test + */ + _init() { + console.log(this._nowTime(), ">>init"); + this.currentTestNum=-1; + this.currentCaseNum=-1; + } + + /** + * before each test + */ + _beforeTest() { + console.log(this._nowTime(), ">>test #" + this.currentTestNum); + } + + /** + * befor each testcase + */ + _beforeCase() { + console.log(this.currentTest); + console.log(this._nowTime(), ">>case #" + this.currentTestNum + "." + this.currentCaseNum + "/" + (this.currentTest.cases.length-1)); + if (this.currentTest instanceof TestSetting) + console.log(this.currentTest.setting+"="+this.currentCase.value+"/n"+(this.currentCase.beforeTxt ? "#"+this.currentCase.beforeTxt : "")); + } + + /** + * testcase runner + */ + _runCase() { + console.log(this._nowTime(), ">>running..."); + var returns = []; + this.currentTest.functionNames.forEach((fName) => { + var settings={}; settings[this.currentTest.setting] = this.currentCase.value; + var cParams = this.currentTest.constructorParams||[]; + cParams = cParams.map((v) => (v && v instanceof String && v==="|TEST_SETTINGS|") ? settings : v);//replace settings in call params + var fParams = this.currentTest.functionParams||[]; + fParams = fParams.map((v) => (v && v instanceof String && v==="|TEST_SETTINGS|") ? settings : v);//replace settings in call params + + var creatorFunc = new Function("console.log('Constructor params:', arguments); return new " + this.oClass + "(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8],arguments[9])"); //prepare spwan arguments[0],arguments[1] + let instance = creatorFunc.call(this.oClass, cParams[0], cParams[1], cParams[2], cParams[3], cParams[4], cParams[5], cParams[6], cParams[7], cParams[8], cParams[9]); //spwan + + console.log(">>"+this.oClass+"["+fName+"]()"); + + console.log('Instance:', instance); + console.log('Function params:', fParams); + returns.push(instance[fName](fParams[0], fParams[1], fParams[2], fParams[3], fParams[4], fParams[5], fParams[6], fParams[7], fParams[8], fParams[9])); //run method and store result + g.dump(); + console.log("<<"+this.oClass+"["+fName+"]()"); + }); + console.log(this._nowTime(), "<<...running"); + } + + /** + * after each testcase + */ + _afterCase() { + if (this.currentTest instanceof TestSetting) + if (this.currentCase.afterTxt.length>0) + console.log("++EXPECTED:" + this.currentCase.afterTxt + "EXPECTED++"); + console.log(this._nowTime(), "< setTimeout(resolve, sec)); + } + + _waits(sec) { + this._delay(1).then(); + } + + _log() { + + } + + _nextTest() { + if (this.currentTestNum>=-1 && (this.currentTestNum+1)=-1 && (this.currentCaseNum+1)Su, 1->Mo, ... //Issue #1154: weekstart So/Mo, -1 for use today + + tdyNumClr:3, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E + tdyMrkr:0, //0:none, 1:circle, 2:rectangle, 3:filled + tdyMrkClr:2, //1:red=#E00, 2:green=#0E0, 3:blue=#00E + tdyMrkPxl:3, //px + + suClr:1, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E + //phColor:"#E00", //public holiday + + calBrdr:false + }; + for (const k in this._settings) if (!defaults.hasOwnProperty(k)) delete this._settings[k]; //remove invalid settings + for (const k in defaults) if(!this._settings.hasOwnProperty(k)) this._settings[k] = defaults[k]; //assign missing defaults + + g.clear(); + Bangle.setUI("clock"); + Bangle.loadWidgets(); + Bangle.drawWidgets(); + + this.centerX = Bangle.appRect.w/2; + this.nrgb = [g.theme.fg, "#E00", "#0E0", "#00E"]; //fg, r ,g , b + + this.ABR_DAY=[]; + if (require("locale") && require("locale").dow) + for (let d=0; d<=6; d++) { + var refDay=new Date(); + refDay.setFullYear(1972); + refDay.setMonth(0); + refDay.setDate(2+d); + this.ABR_DAY.push(require("locale").dow(refDay)); -function drawCal(d){ - var calStart = 101; - var cellSize = g.getWidth() / 7; - var halfSize = cellSize / 2; - g.clearRect(0,calStart,g.getWidth(),g.getHeight()); - g.drawLine(0,calStart,g.getWidth(),calStart); - var days = ["Mo","Tu","We","Th","Fr","Sa","Su"]; - g.setFont("Vector",10); - g.setColor(fontColor); - g.setFontAlign(-1,-1,0); - for(var i = 0; i < days.length;i++){ - g.drawString(days[i],i*cellSize+5,calStart -11); - if(i!=0){ - g.drawLine(i*cellSize,calStart,i*cellSize,g.getHeight()); - } - } - var cellHeight = (g.getHeight() -calStart ) / 3; - for(var i = 0;i < 3;i++){ - var starty = calStart + i * cellHeight; - g.drawLine(0,starty,g.getWidth(),starty); - } - - g.setFont("Vector",15); - - var dayOfWeek = d.getDay(); - var dayRem = d.getDay() - 1; - if(dayRem <0){ - dayRem = 0; - } - - var start = new Date(); - start.setDate(start.getDate()-(7+dayRem)); - g.setFontAlign(0,-1,0); - for (var y = 0;y < 3; y++){ - for(var x = 0;x < 7; x++){ - if(start.getDate() === d.getDate()){ - g.setColor(accentColor); - }else{ - g.setColor(fontColor); } - g.drawString(start.getDate(),x*cellSize +(cellSize / 2) + 2,calStart+(cellHeight*y) + 5); - start.setDate(start.getDate()+1); + else + this.ABR_DAY=["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + } + + /** + * @returns {Object} current settings object + */ + settings(){ + return this._settings; + } + + + /* + * Run forest run + **/ + draw(){ + this.drawTime(); + + if (this.TZOffset===undefined || this.TZOffset!==d.getTimezoneOffset()) + this.drawDateAndCal(); } + + /** + * draw given or current time from date + * overwatch timezone changes + * schedules itself to update + */ + drawTime(){ + d=this.date ? this.date : new Date(); + const Y=Bangle.appRect.y+this.DATE_FONT_SIZE()+10; + + d=d?d :new Date(); + + g.setFontAlign(0, -1).setFont("Vector", this.TIME_FONT_SIZE()).setColor(g.theme.fg) + .clearRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+this.TIME_FONT_SIZE()-7) + .drawString(("0" + require("locale").time(d, 1)).slice(-5), this.centerX, Y, true); + //.drawRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+this.TIME_FONT_SIZE()-7); //DEV-Option + + setTimeout(this.draw.bind(this), 60000-(d.getSeconds()*1000)-d.getMilliseconds()); + } + + /** + * draws given date and cal + * @param{Date} d provide date or uses today + */ + drawDateAndCal(){ + d=this.date ? this.date : new Date(); + + this.TZOffset=d.getTimezoneOffset(); + this.drawDate(); + this.drawCal(); + + if (this.tOutD) //abort exisiting + clearTimeout(this.tOutD); + this.tOutD=setTimeout(this.drawDateAndCal.bind(this), 86400000-(d.getHours()*24*60*1000)-(d.getMinutes()*60*1000)-d.getSeconds()-d.getMilliseconds()); + } + + /** + * draws given date as defiend in settings + */ + drawDate(){ + d=this.date ? this.date : new Date(); + + const FONT_SIZE=20; + const Y=Bangle.appRect.y; + var render=false; + var dateStr = ""; + if (this.settings().shwDate>0) { //skip if exactly -none + const dateSttngs = ["","l","M","m.Y #W"]; + for (let c of dateSttngs[this.settings().shwDate]) { //add part as configured + switch (c){ + case "l":{ //locale + render=true; + dateStr+=require("locale").date(d,1); + break; + } + case "m":{ //month e.g. Jan. + render=true; + dateStr+=require("locale").month(d,1); + break; + } + case "M":{ //month e.g. January + render=true; + dateStr+=require("locale").month(d,0); + break; + } + case "y":{ //year e.g. 22 + render=true; + dateStr+=d.getFullYear().slice(-2); + break; + } + case "Y":{ //year e.g. 2022 + render=true; + dateStr+=d.getFullYear(); + break; + } + case "w":{ //week e.g. #2 + dateStr+=(this.ISO8601calWeek(d)); + break; + } + case "W":{ //week e.g. #02 + dateStr+=("0"+this.ISO8601calWeek(d)).slice(-2); + break; + } + default: //append c + dateStr+=c; + render=dateStr.length>0; + break; //noop + } + } + } + if (render){ + g.setFont("Vector", FONT_SIZE).setColor(g.theme.fg).setFontAlign(0, -1).clearRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+FONT_SIZE-3).drawString(dateStr,this.centerX,Y); + } + //g.drawRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+FONT_SIZE-3); //DEV-Option + } + + /** + * draws calender week view (-1,0,1) for given date + */ + drawCal(){ + d=this.date ? this.date : new Date(); + + const DAY_NAME_FONT_SIZE=10; + const CAL_Y=Bangle.appRect.y+this.DATE_FONT_SIZE()+10+this.TIME_FONT_SIZE()+3; + const CAL_AREA_H=Bangle.appRect.h-CAL_Y+24; //+24: top widegtes only + const CELL_W=Bangle.appRect.w/7; //cell width + const CELL_H=(CAL_AREA_H-DAY_NAME_FONT_SIZE)/3; //cell heigth + const DAY_NUM_FONT_SIZE=Math.min(CELL_H-1,15); //size down, max 15 + + g.setFont("Vector", DAY_NAME_FONT_SIZE).setColor(g.theme.fg).setFontAlign(-1, -1).clearRect(Bangle.appRect.x, CAL_Y, Bangle.appRect.x2, CAL_Y+CAL_AREA_H); + + //draw grid & Headline + const dNames = this.ABR_DAY.map((a) => a.length<=2 ? a : a.substr(0, 2)); //force shrt 2 + for(var dNo=0; dNo=0 ? (dNo+this.settings().wdStrt)%7 : (dNo+d.getDay()+4)%7; + const dName=dNames[dIdx]; + if(dNo>0) + g.drawLine(dNo*CELL_W, CAL_Y, dNo*CELL_W, CAL_Y+CAL_AREA_H-1); + + if (dIdx==0) g.setColor(this.nrgb[this.settings().suClr]); //sunday maybe colorize txt + g.drawString(dName, dNo*CELL_W+(CELL_W-g.stringWidth(dName))/2+2, CAL_Y+1).setColor(g.theme.fg); + } + + var nextY=CAL_Y+DAY_NAME_FONT_SIZE; + + for(i=0; i<3; i++){ + const y=nextY+i*CELL_H; + g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); + } + + g.setFont("Vector", DAY_NUM_FONT_SIZE); + + //write days + const tdyDate=d.getDate(); + const days=this.settings().wdStrt>=0 ? 7+((7+d.getDay()-this.settings().wdStrt)%7) : 10;//start day (week before=7 days + days in this week realtive to week start) or fixed 7+3 days + var rD=new Date(d.getTime()); + rD.setDate(rD.getDate()-days); + var rDate=rD.getDate(); + for(var y=0; y<3; y++){ + for(var x=0; xSu, 1->Mo, ... //Issue #1154: weekstart So/Mo, -1 for use today + + tdyNumClr:3, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E + tdyMrkr:0, //0:none, 1:circle, 2:rectangle, 3:filled + tdyMrkClr:2, //1:red=#E00, 2:green=#0E0, 3:blue=#00E + tdyMrkPxl:3, //px + + suClr:1, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E + //phColor:"#E00", //public holiday + + calBrdr:false + }; + validSttngs = require("Storage").readJSON("timecal.validSttngs.json", 1) || {}; + for (const k in validSttngs) if (!DEFAULTS.hasOwnProperty(k)) delete this.validSttngs[k]; //remove invalid settings + for (const k in DEFAULTS) if(!validSttngs.hasOwnProperty(k)) validSttngs[k] = validSttngs[k]; //assign missing defaults + + var changedSttngs = Object.assign({}, validSttngs); + + var saveExitSettings = () => { + require('Storage').writeJSON(FILE, changedSttngs); + exit(); + }; + + var cancelExitSettings = () => { + require('Storage').writeJSON(FILE, validSttngs); + exit(); + }; + + var showMainMenu = () => { + E.showMenu({ + "": { + "title": "TimeCal "+ /*LANG*/"settings" + }, + /*LANG*/"< Save": () => saveExitSettings(), + /*LANG*/"Show date": { + value: validSttngs.shwDate, + min: 0, max: 3, + format: v => [/*LANG*/"none", /*LANG*/"locale", /*LANG*/"M", /*LANG*/"m.Y #W"][v], + onchange: v => validSttngs.shwDate = v + }, + /*LANG*/"Start wday": { + value: validSttngs.wdStrt, + min: -1, max: 6, + format: v => v>=0 ? ABR_DAY[v] : /*LANG*/"today", + onchange: v => validSttngs.wdStrt = v + }, + /*LANG*/"Su color": { + value: validSttngs.suClr, + min: 0, max: 3, + format: v => [/*LANG*/"none", /*LANG*/"red", /*LANG*/"green", /*LANG*/"blue"][v], + onchange: v => validSttngs.suClr = v + }, + /*LANG*/"Border": { + value: validSttngs.calBrdr, + format: v => v ? /*LANG*/"show" : /*LANG*/"none", + onchange: v => validSttngs.calBrdr = v + }, + /*LANG*/"Today settings": () => { + showTodayMenu(); + }, + /*LANG*/"< Cancel": () => cancelExitSettings() + }); + }; + + var showTodayMenu = () => { + E.showMenu({ + "": { + "title": /*LANG*/"Today settings" + }, + "< Back": () => showMainMenu(), + /*LANG*/"Color": { + value: validSttngs.tdyNumClr, + min: 0, max: 3, + format: v => [/*LANG*/"none", /*LANG*/"red", /*LANG*/"green", /*LANG*/"blue"][v], + onchange: v => validSttngs.tdyNumClr = v + }, + /*LANG*/"Marker": { + value: validSttngs.tdyMrkr, + min: 0, max: 3, + format: v => [/*LANG*/"none", /*LANG*/"circle", /*LANG*/"rectangle", /*LANG*/"filled"][v], + onchange: v => validSttngs.tdyMrkr = v + }, + /*LANG*/"Mrk.Color": { + value: validSttngs.tdyMrkClr, + min: 0, max: 2, + format: v => [/*LANG*/"red", /*LANG*/"green", /*LANG*/"blue"][v], + onchange: v => validSttngs.tdyMrkClr = v + }, + /*LANG*/"Mrk.Size": { + value: validSttngs.tdyMrkPxl, + min: 1, max: 10, + format: v => v+"px", + onchange: v => validSttngs.tdyMrkPxl = v + }, + /*LANG*/"< Cancel": () => cancelExitSettings() + }); + }; + + showMainMenu(); +}); From 8ddbc90c33b3e9565bf37b21df7e54cbc8bdc99a Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 17 Feb 2022 13:39:35 +0000 Subject: [PATCH 12/13] > specificlly check for Jekyll markup > Add ability to scan the server for metadata.json files if no apps.json is present > Tidying up search box/chip handling to avoid global vars - just work out what to filter from window location each time > Under device info, show installed apps > Allow left-click and copy link for links > Merge pull request #18 from myxor/chips_quickfix --- core | 2 +- loader.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core b/core index bf29f5697..a7a80a13f 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit bf29f5697445686255a785476e6b1ed6a13ff697 +Subproject commit a7a80a13fa187a4ff5f89669992babca2d95812c diff --git a/loader.js b/loader.js index 6b27736ae..82d6172cb 100644 --- a/loader.js +++ b/loader.js @@ -202,7 +202,6 @@ window.addEventListener('load', (event) => { } var selectLang = document.getElementById("settings-lang"); - console.log(languages); languages.forEach(lang => { selectLang.innerHTML += ``; }); From eb64a7a43653b0975e0d7dd5adb6aada3a542ad5 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 17 Feb 2022 16:45:24 +0000 Subject: [PATCH 13/13] Fix build issues created with #1465 --- .eslintignore | 1 + apps/timecal/timecal.settings.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index e657b6260..7bbe41136 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,3 +2,4 @@ apps/animclk/V29.LBM.js apps/banglerun/rollup.config.js apps/schoolCalendar/fullcalendar/main.js apps/authentiwatch/qr_packed.js +*.test.js diff --git a/apps/timecal/timecal.settings.js b/apps/timecal/timecal.settings.js index 38c87903b..f3b46384d 100644 --- a/apps/timecal/timecal.settings.js +++ b/apps/timecal/timecal.settings.js @@ -21,7 +21,7 @@ }; validSttngs = require("Storage").readJSON("timecal.validSttngs.json", 1) || {}; for (const k in validSttngs) if (!DEFAULTS.hasOwnProperty(k)) delete this.validSttngs[k]; //remove invalid settings - for (const k in DEFAULTS) if(!validSttngs.hasOwnProperty(k)) validSttngs[k] = validSttngs[k]; //assign missing defaults + for (const k in DEFAULTS) if(!validSttngs.hasOwnProperty(k)) validSttngs[k] = DEFAULTS[k]; //assign missing defaults var changedSttngs = Object.assign({}, validSttngs);