From 96a6dee94c72b4a716d70808d362716ad9ef3c3d Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 16:14:40 +1300 Subject: [PATCH 0001/1839] Update app.js --- apps/speedalt2/app.js | 156 +++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 84 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 0db9629c7..951c878fb 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -1,11 +1,8 @@ /* Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com -0.01 : Initial -0.06 : Add Posn screen -0.07 : Add swipe to change screens same as BTN3 */ -var v = '1.05'; +var v = '1.06'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -173,6 +170,15 @@ var KalmanFilter = (function () { var buf = Graphics.createArrayBuffer(240,160,2,{msb:true}); +let LED = // LED as minimal and only definition (as instance / singleton) +{ isOn: false // status on / off, not needed if you don't need to ask for it +, set: function(v) { // turn on w/ no arg or truey, else off + g.setColor((this.isOn=(v===undefined||!!v))?1:0,0,0).fillCircle(10,10,10); } +, reset: function() { this.set(false); } // turn off +, write: function(v) { this.set(v); } // turn on w/ no arg or truey, else off +, toggle: function() { this.set( ! this.isOn); } // toggle the LED +}, LED1 = LED; // LED1 as 'synonym' for LED + // Load fonts //require("Font7x11Numeric7Seg").add(Graphics); @@ -183,17 +189,16 @@ var canDraw = 1; var time = ''; // Last time string displayed. Re displayed in background colour to remove before drawing new time. var tmrLP; // Timer for delay in switching to low power after screen turns off -var max = {}; -max.spd = 0; -max.alt = 0; -max.n = 0; // counter. Only start comparing for max after a certain number of fixes to allow kalman filter to have smoohed the data. +var maxSpd = 0; +var maxAlt = 0; +var maxN = 0; // counter. Only start comparing for max after a certain number of fixes to allow kalman filter to have smoohed the data. var emulator = (process.env.BOARD=="EMSCRIPTEN")?1:0; // 1 = running in emulator. Supplies test values; var wp = {}; // Waypoint to use for distance from cur position. -function nxtWp(inc){ - cfg.wp+=inc; +function nxtWp(){ + cfg.wp++; loadWp(); } @@ -252,23 +257,14 @@ function drawScrn(dat) { buf.setFontVector(35); buf.drawString(dat.unit,5,164); - if ( dat.max ) drawMax(); // MAX display indicator - if ( dat.wp ) drawWP(); // Waypoint name - - //Sats - if ( dat.sat ) { - if ( dat.age > 10 ) { - if ( dat.age > 90 ) dat.age = '>90'; - drawSats('Age:'+dat.age); - } - else drawSats('Sats:'+dat.sats); - } - + drawMax(dat.max); // MAX display indicator + drawWP(dat.wp); // Waypoint name + drawSats(dat.sats); + g.reset(); g.drawImage(img,0,40); - if ( pwrSav ) LED1.reset(); - else LED1.set(); + LED1.write(!pwrSav); } @@ -293,20 +289,12 @@ function drawPosn(dat) { buf.drawString(dat.ew,x,y+70); - //Sats - if ( dat.sat ) { - if ( dat.age > 10 ) { - if ( dat.age > 90 ) dat.age = '>90'; - drawSats('Age:'+dat.age); - } - else drawSats('Sats:'+dat.sats); - } + drawSats(dat.sats); g.reset(); g.drawImage(img,0,40); - if ( pwrSav ) LED1.reset(); - else LED1.set(); + LED1.write(!pwrSav); } @@ -329,19 +317,14 @@ function drawClock() { g.reset(); g.drawImage(img,0,40); - if ( pwrSav ) LED1.reset(); - else LED1.set(); + LED1.write(!pwrSav); } -function drawWP() { - var nm = wp.name; - if ( nm == undefined || nm == 'NONE' || cfg.modeA ==1 ) nm = ''; +function drawWP(wp) { buf.setColor(2); - buf.setFontAlign(0,1); //left, bottom buf.setFontVector(48); - buf.drawString(nm.substring(0,8),120,140); - + buf.drawString(wp,120,140); } function drawSats(sats) { @@ -351,16 +334,15 @@ function drawSats(sats) { buf.drawString(sats,240,160); } -function drawMax() { +function drawMax(max) { buf.setFontVector(30); buf.setColor(2); buf.setFontAlign(0,1); //centre, bottom - buf.drawString('MAX',120,164); + buf.drawString(max,120,164); } function onGPS(fix) { - - if ( emulator ) { +if ( emulator ) { fix.fix = 1; fix.speed = 10 + (Math.random()*5); fix.alt = 354 + (Math.random()*50); @@ -382,10 +364,12 @@ function onGPS(fix) { var ns = ''; var ew = ''; var lon = '---.--'; + var sats = '---'; + var wpName = ''; // Waypoint name if (fix.fix) lf = fix; - + if (lf.fix) { // Smooth data @@ -393,10 +377,9 @@ function onGPS(fix) { if ( cfg.spdFilt ) lf.speed = spdFilter.filter(lf.speed); if ( cfg.altFilt ) lf.alt = altFilter.filter(lf.alt); lf.smoothed = 1; - if ( max.n <= 15 ) max.n++; + if ( maxN <= 15 ) maxN++; } - // Speed if ( cfg.spd == 0 ) { m = require("locale").speed(lf.speed).match(/([0-9,\.]+)(.*)/); // regex splits numbers from units @@ -408,17 +391,22 @@ function onGPS(fix) { if ( sp < 10 ) sp = sp.toFixed(1); else sp = Math.round(sp); - if (parseFloat(sp) > parseFloat(max.spd) && max.n > 15 ) max.spd = sp; + if (parseFloat(sp) > parseFloat(maxSpd) && maxN > 15 ) maxSpd = sp; // Altitude al = lf.alt; al = Math.round(parseFloat(al)/parseFloat(cfg.alt)); - - if (parseFloat(al) > parseFloat(max.alt) && max.n > 15 ) max.alt = al; + + if (parseFloat(al) > parseFloat(maxAlt) && maxN > 15 ) maxAlt = al; // Distance to waypoint di = distance(lf,wp); - if (isNaN(di)) di = 0; + if (isNaN(di)) di = '--------'; + + // Waypoint name + wpName = wp.name; + if ( wpName == undefined || wpName == 'NONE' ) wpName = ''; + wpName = wpName.substring(0,8); // Age of last fix (secs) age = Math.max(0,Math.round(getTime())-(lf.time.getTime()/1000)); @@ -431,6 +419,13 @@ function onGPS(fix) { ew = 'E'; if ( lf.lon < 0 ) ew = 'W'; lon = Math.abs(lf.lon.toFixed(2)); + + // Sats + if ( age > 10 ) { + sats = 'Age:'+age; + if ( age > 90 ) sats = 'Age:>90'; + } + else sats = 'Sats:'+lf.satellites; } @@ -438,23 +433,21 @@ function onGPS(fix) { // Speed if ( showMax ) drawScrn({ - val:max.spd, + val:maxSpd, unit:cfg.spd_unit, - sats:lf.satellites, + sats:sats, age:age, - max:true, - wp:false, - sat:true + max:'MAX', + wp:'' }); // Speed maximums else drawScrn({ val:sp, unit:cfg.spd_unit, - sats:lf.satellites, + sats:sats, age:age, - max:false, - wp:false, - sat:true + max:'', + wp:'' }); } @@ -462,23 +455,21 @@ function onGPS(fix) { // Alt if ( showMax ) drawScrn({ - val:max.alt, + val:maxAlt, unit:cfg.alt_unit, - sats:lf.satellites, + sats:sats, age:age, - max:true, - wp:false, - sat:true + max:'MAX', + wp:'' }); // Alt maximums else drawScrn({ val:al, unit:cfg.alt_unit, - sats:lf.satellites, + sats:sats, age:age, - max:false, - wp:false, - sat:true + max:'', + wp:'' }); } @@ -487,24 +478,22 @@ function onGPS(fix) { drawScrn({ val:di, unit:cfg.dist_unit, - sats:lf.satellites, + sats:sats, age:age, - max:false, - wp:true, - sat:true + max:'', + wp:wpName }); } if ( cfg.modeA == 3 ) { // Position - drawPosn({ - sats:lf.satellites, + drawPosn({ + sats:sats, age:age, lat:lat, lon:lon, ns:ns, - ew:ew, - sat:true + ew:ew }); } @@ -534,9 +523,9 @@ function nextFunc(dur) { if ( cfg.modeA == 0 || cfg.modeA == 1 ) { // Spd+Alt mode - Switch between fix and MAX if ( dur < 2 ) showMax = !showMax; // Short press toggle fix/max display - else { max.spd = 0; max.alt = 0; } // Long press resets max values. + else { maxSpd = 0; maxAlt = 0; } // Long press resets max values. } - else if ( cfg.modeA == 2) nxtWp(1); // Dist mode - Select next waypoint + else if ( cfg.modeA == 2) nxtWp(); // Dist mode - Select next waypoint onGPS(lf); } @@ -545,7 +534,7 @@ function updateClock() { if (!canDraw) return; if ( cfg.modeA != 4 ) return; drawClock(); - if ( emulator ) {max.spd++;max.alt++;} + if ( emulator ) {maxSpd++;maxAlt++;} } function startDraw(){ @@ -585,7 +574,6 @@ function setButtons(){ setWatch(function(e){ pwrSav=!pwrSav; if ( pwrSav ) { - LED1.reset(); var s = require('Storage').readJSON('setting.json',1)||{}; var t = s.timeout||10; Bangle.setLCDTimeout(t); @@ -593,8 +581,8 @@ function setButtons(){ else { Bangle.setLCDTimeout(0); // Bangle.setLCDPower(1); - LED1.set(); } + LED1.write(!pwrSav); }, BTN2, {repeat:true,edge:"falling"}); // BTN3 - next screen From d5c827cd18c12f3c34dc1b754fe3cf0d88ef1d37 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 16:16:29 +1300 Subject: [PATCH 0002/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 0136a744a..689779b31 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"0.07", + "version":"1.06", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From 5b00b2599888f3fd062c14b826e9d3565b0fe9a1 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 16:17:24 +1300 Subject: [PATCH 0003/1839] Update ChangeLog --- apps/speedalt2/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/speedalt2/ChangeLog b/apps/speedalt2/ChangeLog index 91f01988e..bd338f8b2 100644 --- a/apps/speedalt2/ChangeLog +++ b/apps/speedalt2/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial import. 0.07: Add swipe to change screens. +1.06: Misc memory and screen optimisations. From 1f207561e6af2f59ce9806138a32e54c4ba757c6 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 16:31:23 +1300 Subject: [PATCH 0004/1839] Update app.js --- apps/speedalt2/app.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 951c878fb..b41f3054f 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -2,7 +2,7 @@ Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com */ -var v = '1.06'; +var v = '1.07'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -173,7 +173,7 @@ var buf = Graphics.createArrayBuffer(240,160,2,{msb:true}); let LED = // LED as minimal and only definition (as instance / singleton) { isOn: false // status on / off, not needed if you don't need to ask for it , set: function(v) { // turn on w/ no arg or truey, else off - g.setColor((this.isOn=(v===undefined||!!v))?1:0,0,0).fillCircle(10,10,10); } + g.setColor((this.isOn=(v===undefined||!!v))?1:0,0,0).fillCircle(20,10,10); } , reset: function() { this.set(false); } // turn off , write: function(v) { this.set(v); } // turn on w/ no arg or truey, else off , toggle: function() { this.set( ! this.isOn); } // toggle the LED @@ -390,14 +390,15 @@ if ( emulator ) { if ( sp < 10 ) sp = sp.toFixed(1); else sp = Math.round(sp); + if (isNaN(sp)) sp = '---'; if (parseFloat(sp) > parseFloat(maxSpd) && maxN > 15 ) maxSpd = sp; // Altitude al = lf.alt; al = Math.round(parseFloat(al)/parseFloat(cfg.alt)); - if (parseFloat(al) > parseFloat(maxAlt) && maxN > 15 ) maxAlt = al; + if (isNaN(al)) al = '---'; // Distance to waypoint di = distance(lf,wp); @@ -422,7 +423,7 @@ if ( emulator ) { // Sats if ( age > 10 ) { - sats = 'Age:'+age; + sats = 'Age:'+Math.round(age); if ( age > 90 ) sats = 'Age:>90'; } else sats = 'Sats:'+lf.satellites; From e39ba7778879f3eb7f31524ee2f5568f49b9ccf5 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 16:32:06 +1300 Subject: [PATCH 0005/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 689779b31..243a5b814 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.06", + "version":"1.07", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From 2d8eb136b31a3bd2602a96df3a6d2e0cf680567d Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 16:43:54 +1300 Subject: [PATCH 0006/1839] Update app.js --- apps/speedalt2/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index b41f3054f..6085ee92d 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -2,7 +2,7 @@ Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com */ -var v = '1.07'; +var v = '1.08'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -173,7 +173,7 @@ var buf = Graphics.createArrayBuffer(240,160,2,{msb:true}); let LED = // LED as minimal and only definition (as instance / singleton) { isOn: false // status on / off, not needed if you don't need to ask for it , set: function(v) { // turn on w/ no arg or truey, else off - g.setColor((this.isOn=(v===undefined||!!v))?1:0,0,0).fillCircle(20,10,10); } + g.setColor((this.isOn=(v===undefined||!!v))?1:0,0,0).fillCircle(40,10,10); } , reset: function() { this.set(false); } // turn off , write: function(v) { this.set(v); } // turn on w/ no arg or truey, else off , toggle: function() { this.set( ! this.isOn); } // toggle the LED From 13a3127bfca3d924ba994838ed7f80dcd3993de2 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 16:44:39 +1300 Subject: [PATCH 0007/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 243a5b814..39986d936 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.07", + "version":"1.08", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From 8be0bd2e34f8a86c917519c009348ae58ca7576b Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 18:51:39 +1300 Subject: [PATCH 0008/1839] Update app.js --- apps/speedalt2/app.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 6085ee92d..df101e9f1 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -2,7 +2,7 @@ Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com */ -var v = '1.08'; +var v = '1.09'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -365,8 +365,11 @@ if ( emulator ) { var ew = ''; var lon = '---.--'; var sats = '---'; - var wpName = ''; // Waypoint name + // Waypoint name + var wpName = wp.name; + if ( wpName == undefined || wpName == 'NONE' ) wpName = ''; + wpName = wpName.substring(0,8); if (fix.fix) lf = fix; @@ -403,11 +406,6 @@ if ( emulator ) { // Distance to waypoint di = distance(lf,wp); if (isNaN(di)) di = '--------'; - - // Waypoint name - wpName = wp.name; - if ( wpName == undefined || wpName == 'NONE' ) wpName = ''; - wpName = wpName.substring(0,8); // Age of last fix (secs) age = Math.max(0,Math.round(getTime())-(lf.time.getTime()/1000)); From ea28ffd65711f680e5fb08374c842d0b0d93fc26 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 18:53:58 +1300 Subject: [PATCH 0009/1839] Update app.js --- apps/speedalt2/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index df101e9f1..de94db6a3 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -321,7 +321,7 @@ function drawClock() { } function drawWP(wp) { - buf.setColor(2); + buf.setColor(3); buf.setFontAlign(0,1); //left, bottom buf.setFontVector(48); buf.drawString(wp,120,140); From a29af499e769fe9db9d6ec91e0d91040ad71fa0f Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 18:55:06 +1300 Subject: [PATCH 0010/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 39986d936..ada4c4509 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.08", + "version":"1.09", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From 7c7a0ae2cf5c8ee5bc4227517216326cd1226611 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 21:55:45 +1300 Subject: [PATCH 0011/1839] Update app.js --- apps/speedalt2/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index de94db6a3..cee725993 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -677,7 +677,7 @@ var img = { }; if ( cfg.colour == 1 ) img.palette = new Uint16Array([0,0xFFFF,0xFFF6,0xDFFF]); -if ( cfg.colour == 2 ) img.palette = new Uint16Array([0,0xFF800,0xFAE0,0xF813]); +if ( cfg.colour == 2 ) img.palette = new Uint16Array([0,0xF800,0xFAE0,0xF813]); var SCREENACCESS = { withApp:true, From 4b66b9ffa8dcae0f1552b147657bcec3c7687d4a Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 22:19:35 +1300 Subject: [PATCH 0012/1839] Update app.js --- apps/speedalt2/app.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index cee725993..2cf73dfe9 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -1,8 +1,9 @@ /* Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com +1.10 : add inverted colours */ -var v = '1.09'; +var v = '1.10'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -232,7 +233,8 @@ function drawScrn(dat) { if (!canDraw) return; buf.clear(); - + buf.setBgColor(0); + var n; n = dat.val.toString(); @@ -271,6 +273,7 @@ function drawScrn(dat) { function drawPosn(dat) { if (!canDraw) return; buf.clear(); + buf.setBgColor(0); var x, y; x=210; @@ -302,6 +305,8 @@ function drawClock() { if (!canDraw) return; buf.clear(); + buf.setBgColor(0); + var x, y; x=185; y=0; @@ -678,6 +683,7 @@ var img = { if ( cfg.colour == 1 ) img.palette = new Uint16Array([0,0xFFFF,0xFFF6,0xDFFF]); if ( cfg.colour == 2 ) img.palette = new Uint16Array([0,0xF800,0xFAE0,0xF813]); +if ( cfg.colour == 3 ) img.palette = new Uint16Array([0xFFFF,0x007F,0x0054,0x0054]); var SCREENACCESS = { withApp:true, From 7bd799accc7fb7d67784966ee11188d386cdc5a7 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 22:20:30 +1300 Subject: [PATCH 0013/1839] Update settings.js --- apps/speedalt2/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/speedalt2/settings.js b/apps/speedalt2/settings.js index 96174a89b..3ec4742ac 100644 --- a/apps/speedalt2/settings.js +++ b/apps/speedalt2/settings.js @@ -66,6 +66,7 @@ 'Default' : function() { setColour(0); }, 'Hi Contrast' : function() { setColour(1); }, 'Night' : function() { setColour(2); } + 'Inverted' : function() { setColour(3); } }; const kalMenu = { From 644db080fe0eb78d2dbc0f6f2d6929e1eb0219f9 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 22:21:13 +1300 Subject: [PATCH 0014/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index ada4c4509..5aeb95eb6 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.09", + "version":"1.10", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From 684138c36ef4829e31f3ada0193436269aa24e42 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 22:24:02 +1300 Subject: [PATCH 0015/1839] Update settings.js --- apps/speedalt2/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/speedalt2/settings.js b/apps/speedalt2/settings.js index 3ec4742ac..fe30d88df 100644 --- a/apps/speedalt2/settings.js +++ b/apps/speedalt2/settings.js @@ -65,7 +65,7 @@ '< Back': function() { E.showMenu(appMenu); }, 'Default' : function() { setColour(0); }, 'Hi Contrast' : function() { setColour(1); }, - 'Night' : function() { setColour(2); } + 'Night' : function() { setColour(2); }, 'Inverted' : function() { setColour(3); } }; From 9147108f8a18d91c36d4fa595140de2e7966bf02 Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 22:24:44 +1300 Subject: [PATCH 0016/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 5aeb95eb6..5e69ddd05 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.10", + "version":"1.11", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From a5becb249ba93e4fc18fcd9b1b8f43acb8ce931e Mon Sep 17 00:00:00 2001 From: nujw Date: Fri, 29 Oct 2021 22:32:56 +1300 Subject: [PATCH 0017/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 5e69ddd05..46826cf91 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.11", + "version":"1.12", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From adcdb50cbc15b651c94e7cc57a4cd74dc3e33ddb Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 08:51:40 +1300 Subject: [PATCH 0018/1839] Update app.js --- apps/speedalt2/app.js | 88 +++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 2cf73dfe9..d61eb4386 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -2,8 +2,9 @@ Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com 1.10 : add inverted colours +1.11 : Add VMG screen */ -var v = '1.10'; +var v = '1.11'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -194,6 +195,10 @@ var maxSpd = 0; var maxAlt = 0; var maxN = 0; // counter. Only start comparing for max after a certain number of fixes to allow kalman filter to have smoohed the data. +// Previous values for calculating VMG. +var lastDist = -1; +var lastTime = -1; + var emulator = (process.env.BOARD=="EMSCRIPTEN")?1:0; // 1 = running in emulator. Supplies test values; var wp = {}; // Waypoint to use for distance from cur position. @@ -201,6 +206,8 @@ var wp = {}; // Waypoint to use for distance from cur position. function nxtWp(){ cfg.wp++; loadWp(); + lastDist = -1; // Reset VMG calcs + lastTime = -1; } function loadWp() { @@ -219,11 +226,11 @@ function distance(a,b){ var x = radians(a.lon-b.lon) * Math.cos(radians((a.lat+b.lat)/2)); var y = radians(b.lat-a.lat); - // Distance in selected units + // Distance in metres var d = Math.sqrt(x*x + y*y) * 6371000; - d = (d/parseFloat(cfg.dist)).toFixed(2); - if ( d >= 100 ) d = parseFloat(d).toFixed(1); - if ( d >= 1000 ) d = parseFloat(d).toFixed(0); +// d = (d/parseFloat(cfg.dist)).toFixed(2); +// if ( d >= 100 ) d = parseFloat(d).toFixed(1); +// if ( d >= 1000 ) d = parseFloat(d).toFixed(0); return d; } @@ -328,8 +335,8 @@ function drawClock() { function drawWP(wp) { buf.setColor(3); buf.setFontAlign(0,1); //left, bottom - buf.setFontVector(48); - buf.drawString(wp,120,140); + buf.setFontVector(40); + buf.drawString(wp,120,132); } function drawSats(sats) { @@ -370,6 +377,7 @@ if ( emulator ) { var ew = ''; var lon = '---.--'; var sats = '---'; + var vmg = '---'; // Waypoint name var wpName = wp.name; @@ -389,17 +397,10 @@ if ( emulator ) { } // Speed - if ( cfg.spd == 0 ) { - m = require("locale").speed(lf.speed).match(/([0-9,\.]+)(.*)/); // regex splits numbers from units - sp = parseFloat(m[1]); - cfg.spd_unit = m[2]; - } - else sp = parseFloat(lf.speed)/parseFloat(cfg.spd); // Calculate for selected units - + sp = parseFloat(lf.speed)/parseFloat(cfg.spd); // Calculate for selected units if ( sp < 10 ) sp = sp.toFixed(1); else sp = Math.round(sp); if (isNaN(sp)) sp = '---'; - if (parseFloat(sp) > parseFloat(maxSpd) && maxN > 15 ) maxSpd = sp; // Altitude @@ -408,9 +409,34 @@ if ( emulator ) { if (parseFloat(al) > parseFloat(maxAlt) && maxN > 15 ) maxAlt = al; if (isNaN(al)) al = '---'; - // Distance to waypoint + // Distance to waypoint and vmg di = distance(lf,wp); - if (isNaN(di)) di = '--------'; + +//lastDist = 13640; +//lastTime = (getTime()/1000) - 10; + + if ( lastDist != -1 && ! isNaN(lastDist)) { +//console.log(' Distance : '+di); +//console.log('last.Distance : '+lastDist); +//console.log('last.Time : '+lastTime); + + // Have two WP distances and a time. Calc speed + vmg = ((lastDist-di)/1000)/((getTime()/1000-lastTime)/3600); // k/h + vmg = vmg/parseFloat(cfg.spd); // Calculate for selected units +//console.log('VMG : '+vmg); + } + lastDist = di; + lastTime = getTime()/1000; // secs + + di = (di/parseFloat(cfg.dist)).toFixed(2); + if ( di >= 100 ) di = parseFloat(di).toFixed(1); + if ( di >= 1000 ) di = parseFloat(di).toFixed(0); + + if ( Math.abs(vmg) < 10 ) vmg = vmg.toFixed(1); + else vmg = Math.round(vmg); + + if (isNaN(vmg)) vmg = '---'; + if (isNaN(di)) di = '------'; // Age of last fix (secs) age = Math.max(0,Math.round(getTime())-(lf.time.getTime()/1000)); @@ -490,6 +516,18 @@ if ( emulator ) { } if ( cfg.modeA == 3 ) { + // VMG + drawScrn({ + val:vmg, + unit:cfg.spd_unit, + sats:sats, + age:age, + max:'VMG', + wp:wpName + }); + } + + if ( cfg.modeA == 4 ) { // Position drawPosn({ sats:sats, @@ -501,7 +539,7 @@ if ( emulator ) { }); } - if ( cfg.modeA == 4 ) { + if ( cfg.modeA == 5 ) { // Large clock drawClock(); } @@ -510,14 +548,14 @@ if ( emulator ) { function prevScrn() { cfg.modeA = cfg.modeA-1; - if ( cfg.modeA < 0 ) cfg.modeA = 4; + if ( cfg.modeA < 0 ) cfg.modeA = 5; savSettings(); onGPS(lf); } function nextScrn() { cfg.modeA = cfg.modeA+1; - if ( cfg.modeA > 4 ) cfg.modeA = 0; + if ( cfg.modeA > 5 ) cfg.modeA = 0; savSettings(); onGPS(lf); } @@ -529,14 +567,14 @@ function nextFunc(dur) { if ( dur < 2 ) showMax = !showMax; // Short press toggle fix/max display else { maxSpd = 0; maxAlt = 0; } // Long press resets max values. } - else if ( cfg.modeA == 2) nxtWp(); // Dist mode - Select next waypoint + else if ( cfg.modeA == 2 || cfg.modeA == 3) nxtWp(); // Dist or VMG mode - Select next waypoint onGPS(lf); } function updateClock() { if (!canDraw) return; - if ( cfg.modeA != 4 ) return; + if ( cfg.modeA != 5 ) return; drawClock(); if ( emulator ) {maxSpd++;maxAlt++;} } @@ -646,15 +684,15 @@ console.log('MDL'); // Read settings. let cfg = require('Storage').readJSON('speedalt2.json',1)||{}; -cfg.spd = cfg.spd||0; // Multiplier for speed unit conversions. 0 = use the locale values for speed -cfg.spd_unit = cfg.spd_unit||''; // Displayed speed unit +cfg.spd = cfg.spd||1; // Multiplier for speed unit conversions. 0 = use the locale values for speed +cfg.spd_unit = cfg.spd_unit||'kph'; // Displayed speed unit cfg.alt = cfg.alt||0.3048;// Multiplier for altitude unit conversions. cfg.alt_unit = cfg.alt_unit||'feet'; // Displayed altitude units cfg.dist = cfg.dist||1000;// Multiplier for distnce unit conversions. cfg.dist_unit = cfg.dist_unit||'km'; // Displayed altitude units cfg.colour = cfg.colour||0; // Colour scheme. cfg.wp = cfg.wp||0; // Last selected waypoint for dist -cfg.modeA = cfg.modeA||0; // 0=Speed 1=Alt 2=Dist 3=Position 4=Clock +cfg.modeA = cfg.modeA||0; // 0=Speed 1=Alt 2=Dist 3 = vmg 4=Position 5=Clock cfg.primSpd = cfg.primSpd||0; // 1 = Spd in primary, 0 = Spd in secondary cfg.spdFilt = cfg.spdFilt==undefined?true:cfg.spdFilt; From c5a981d39b9639937188db1cd6cfb11df24df1a4 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 08:52:33 +1300 Subject: [PATCH 0019/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 46826cf91..2239db796 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.12", + "version":"1.14", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From c329bbe9036a7dda2e12f45648546f3b4c290219 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 08:52:51 +1300 Subject: [PATCH 0020/1839] Update app.js --- apps/speedalt2/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index d61eb4386..389beda8f 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -2,9 +2,9 @@ Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com 1.10 : add inverted colours -1.11 : Add VMG screen +1.14 : Add VMG screen */ -var v = '1.11'; +var v = '1.14'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { From d009bddf8bd451460e3a4d2f48181bb438c7204d Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 09:24:24 +1300 Subject: [PATCH 0021/1839] Update app.js --- apps/speedalt2/app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 389beda8f..e36c2efc0 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -476,7 +476,7 @@ if ( emulator ) { unit:cfg.spd_unit, sats:sats, age:age, - max:'', + max:'SPD', wp:'' }); } @@ -498,7 +498,7 @@ if ( emulator ) { unit:cfg.alt_unit, sats:sats, age:age, - max:'', + max:'ALT', wp:'' }); } @@ -510,7 +510,7 @@ if ( emulator ) { unit:cfg.dist_unit, sats:sats, age:age, - max:'', + max:'DST', wp:wpName }); } From 134ae6bf73450e2cb40638164bcf0f9317052033 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 09:26:16 +1300 Subject: [PATCH 0022/1839] Update app.js --- apps/speedalt2/app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index e36c2efc0..6d89bac81 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -188,7 +188,6 @@ var lf = {fix:0,satellites:0}; var showMax = 0; // 1 = display the max values. 0 = display the cur fix var pwrSav = 1; // 1 = default power saving with watch screen off and GPS to PMOO mode. 0 = screen kept on. var canDraw = 1; -var time = ''; // Last time string displayed. Re displayed in background colour to remove before drawing new time. var tmrLP; // Timer for delay in switching to low power after screen turns off var maxSpd = 0; From 54442044f248c665f1ca42a226f272806a4c1ae9 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 09:32:17 +1300 Subject: [PATCH 0023/1839] Update app.js --- apps/speedalt2/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 6d89bac81..34a73012d 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -4,7 +4,7 @@ Mike Bennett mike[at]kereru.com 1.10 : add inverted colours 1.14 : Add VMG screen */ -var v = '1.14'; +var v = '1.15'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { From 0bc35288eb164be14fe099423f8a92602e428241 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 09:33:13 +1300 Subject: [PATCH 0024/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 2239db796..42e54a6bd 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.14", + "version":"1.15", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From 0c6cf8f0d0313f1322c82251518de3d9ab030506 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 11:39:30 +1300 Subject: [PATCH 0025/1839] Update app.js --- apps/speedalt2/app.js | 86 ++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 34a73012d..1823b9911 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -4,7 +4,7 @@ Mike Bennett mike[at]kereru.com 1.10 : add inverted colours 1.14 : Add VMG screen */ -var v = '1.15'; +var v = '1.16'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -195,8 +195,11 @@ var maxAlt = 0; var maxN = 0; // counter. Only start comparing for max after a certain number of fixes to allow kalman filter to have smoohed the data. // Previous values for calculating VMG. -var lastDist = -1; -var lastTime = -1; +var vmgD1 = -1; // Dist start +var vmgD2 = -1; // Dist end +var vmgT1 = -1; // Time start +var vmgT2 = -1; // Time end +var vmgSpd = 0; var emulator = (process.env.BOARD=="EMSCRIPTEN")?1:0; // 1 = running in emulator. Supplies test values; @@ -205,8 +208,9 @@ var wp = {}; // Waypoint to use for distance from cur position. function nxtWp(){ cfg.wp++; loadWp(); - lastDist = -1; // Reset VMG calcs - lastTime = -1; + vmgD1 = -1; // Reset VMG calcs + vmgD2 = -1; + vmgT1 = -1; } function loadWp() { @@ -376,7 +380,6 @@ if ( emulator ) { var ew = ''; var lon = '---.--'; var sats = '---'; - var vmg = '---'; // Waypoint name var wpName = wp.name; @@ -408,33 +411,13 @@ if ( emulator ) { if (parseFloat(al) > parseFloat(maxAlt) && maxN > 15 ) maxAlt = al; if (isNaN(al)) al = '---'; - // Distance to waypoint and vmg + // Distance to waypoint di = distance(lf,wp); - -//lastDist = 13640; -//lastTime = (getTime()/1000) - 10; - - if ( lastDist != -1 && ! isNaN(lastDist)) { -//console.log(' Distance : '+di); -//console.log('last.Distance : '+lastDist); -//console.log('last.Time : '+lastTime); - - // Have two WP distances and a time. Calc speed - vmg = ((lastDist-di)/1000)/((getTime()/1000-lastTime)/3600); // k/h - vmg = vmg/parseFloat(cfg.spd); // Calculate for selected units -//console.log('VMG : '+vmg); - } - lastDist = di; - lastTime = getTime()/1000; // secs - + vmgD2 = di; + vmgT2 = Math.round(lf.time.getTime()/1000); di = (di/parseFloat(cfg.dist)).toFixed(2); if ( di >= 100 ) di = parseFloat(di).toFixed(1); if ( di >= 1000 ) di = parseFloat(di).toFixed(0); - - if ( Math.abs(vmg) < 10 ) vmg = vmg.toFixed(1); - else vmg = Math.round(vmg); - - if (isNaN(vmg)) vmg = '---'; if (isNaN(di)) di = '------'; // Age of last fix (secs) @@ -517,7 +500,7 @@ if ( emulator ) { if ( cfg.modeA == 3 ) { // VMG drawScrn({ - val:vmg, + val:vmgSpd, unit:cfg.spd_unit, sats:sats, age:age, @@ -545,6 +528,48 @@ if ( emulator ) { } +function updateVMG() { +//console.log('----------'); +//console.log('vmgT1 : '+vmgT1); +//console.log('vmgT2 : '+vmgT2); + + if (!canDraw) return; + vmgSpd = '---'; + + if ( ! lf.fix ) return; + if ( vmgT1 == vmgT2 ) return; // No new fix + + +//vmgD1 = 13640; +//vmgT1 = (getTime()/1000) - 10; + + + + + if ( vmgD1 != -1 && ! isNaN(vmgD1)) { +//console.log(' Distance : '+di); +//console.log('last.Distance : '+vmgD1); +//console.log('last.Time : '+vmgT1); + + // Have two WP distances and a time. Calc speed + vmgSpd = ((vmgD1-vmgD2)/1000)/((vmgT2-vmgT1)/3600); // k/h + + vmgSpd = vmgSpd/parseFloat(cfg.spd); // Calculate for selected units +//console.log('VMG : '+vmg); + } + vmgD1 = vmgD2; + vmgT1 = vmgT2; // secs + + + if ( Math.abs(vmgSpd) < 10 ) vmgSpd = vmgSpd.toFixed(1); + else vmgSpd = Math.round(vmgSpd); + + if (isNaN(vmgSpd)) vmgSpd = '---'; + + console.log('vmgSpd : '+vmgSpd); + +} + function prevScrn() { cfg.modeA = cfg.modeA-1; if ( cfg.modeA < 0 ) cfg.modeA = 5; @@ -753,3 +778,4 @@ Bangle.on('GPS', onGPS); setButtons(); setInterval(updateClock, 10000); +setInterval(updateVMG, 10000); From 020a2ea00598568e9a755a78969bcea08c661767 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 11:39:58 +1300 Subject: [PATCH 0026/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 42e54a6bd..6e18c3505 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.15", + "version":"1.16", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From a7b5f530c30c28f2c53c80692934135ad898a562 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 11:50:03 +1300 Subject: [PATCH 0027/1839] Update app.js --- apps/speedalt2/app.js | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 1823b9911..76dbccfc0 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -231,10 +231,6 @@ function distance(a,b){ // Distance in metres var d = Math.sqrt(x*x + y*y) * 6371000; -// d = (d/parseFloat(cfg.dist)).toFixed(2); -// if ( d >= 100 ) d = parseFloat(d).toFixed(1); -// if ( d >= 1000 ) d = parseFloat(d).toFixed(0); - return d; } @@ -529,10 +525,6 @@ if ( emulator ) { } function updateVMG() { -//console.log('----------'); -//console.log('vmgT1 : '+vmgT1); -//console.log('vmgT2 : '+vmgT2); - if (!canDraw) return; vmgSpd = '---'; @@ -542,32 +534,19 @@ function updateVMG() { //vmgD1 = 13640; //vmgT1 = (getTime()/1000) - 10; - - - if ( vmgD1 != -1 && ! isNaN(vmgD1)) { -//console.log(' Distance : '+di); -//console.log('last.Distance : '+vmgD1); -//console.log('last.Time : '+vmgT1); - // Have two WP distances and a time. Calc speed vmgSpd = ((vmgD1-vmgD2)/1000)/((vmgT2-vmgT1)/3600); // k/h - vmgSpd = vmgSpd/parseFloat(cfg.spd); // Calculate for selected units -//console.log('VMG : '+vmg); } vmgD1 = vmgD2; vmgT1 = vmgT2; // secs - if ( Math.abs(vmgSpd) < 10 ) vmgSpd = vmgSpd.toFixed(1); else vmgSpd = Math.round(vmgSpd); if (isNaN(vmgSpd)) vmgSpd = '---'; - - console.log('vmgSpd : '+vmgSpd); - } function prevScrn() { From 0bd6399d833236021f76fdb3aee298a74ae766a8 Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 11:58:16 +1300 Subject: [PATCH 0028/1839] Update app.js --- apps/speedalt2/app.js | 94 ++++++++++++------------------------------- 1 file changed, 26 insertions(+), 68 deletions(-) diff --git a/apps/speedalt2/app.js b/apps/speedalt2/app.js index 76dbccfc0..fd53cf7c3 100644 --- a/apps/speedalt2/app.js +++ b/apps/speedalt2/app.js @@ -2,9 +2,8 @@ Speed and Altitude [speedalt2] Mike Bennett mike[at]kereru.com 1.10 : add inverted colours -1.14 : Add VMG screen */ -var v = '1.16'; +var v = '1.10'; /*kalmanjs, Wouter Bulten, MIT, https://github.com/wouterbulten/kalmanjs */ var KalmanFilter = (function () { @@ -188,19 +187,13 @@ var lf = {fix:0,satellites:0}; var showMax = 0; // 1 = display the max values. 0 = display the cur fix var pwrSav = 1; // 1 = default power saving with watch screen off and GPS to PMOO mode. 0 = screen kept on. var canDraw = 1; +var time = ''; // Last time string displayed. Re displayed in background colour to remove before drawing new time. var tmrLP; // Timer for delay in switching to low power after screen turns off var maxSpd = 0; var maxAlt = 0; var maxN = 0; // counter. Only start comparing for max after a certain number of fixes to allow kalman filter to have smoohed the data. -// Previous values for calculating VMG. -var vmgD1 = -1; // Dist start -var vmgD2 = -1; // Dist end -var vmgT1 = -1; // Time start -var vmgT2 = -1; // Time end -var vmgSpd = 0; - var emulator = (process.env.BOARD=="EMSCRIPTEN")?1:0; // 1 = running in emulator. Supplies test values; var wp = {}; // Waypoint to use for distance from cur position. @@ -208,9 +201,6 @@ var wp = {}; // Waypoint to use for distance from cur position. function nxtWp(){ cfg.wp++; loadWp(); - vmgD1 = -1; // Reset VMG calcs - vmgD2 = -1; - vmgT1 = -1; } function loadWp() { @@ -229,8 +219,12 @@ function distance(a,b){ var x = radians(a.lon-b.lon) * Math.cos(radians((a.lat+b.lat)/2)); var y = radians(b.lat-a.lat); - // Distance in metres + // Distance in selected units var d = Math.sqrt(x*x + y*y) * 6371000; + d = (d/parseFloat(cfg.dist)).toFixed(2); + if ( d >= 100 ) d = parseFloat(d).toFixed(1); + if ( d >= 1000 ) d = parseFloat(d).toFixed(0); + return d; } @@ -334,8 +328,8 @@ function drawClock() { function drawWP(wp) { buf.setColor(3); buf.setFontAlign(0,1); //left, bottom - buf.setFontVector(40); - buf.drawString(wp,120,132); + buf.setFontVector(48); + buf.drawString(wp,120,140); } function drawSats(sats) { @@ -395,10 +389,17 @@ if ( emulator ) { } // Speed - sp = parseFloat(lf.speed)/parseFloat(cfg.spd); // Calculate for selected units + if ( cfg.spd == 0 ) { + m = require("locale").speed(lf.speed).match(/([0-9,\.]+)(.*)/); // regex splits numbers from units + sp = parseFloat(m[1]); + cfg.spd_unit = m[2]; + } + else sp = parseFloat(lf.speed)/parseFloat(cfg.spd); // Calculate for selected units + if ( sp < 10 ) sp = sp.toFixed(1); else sp = Math.round(sp); if (isNaN(sp)) sp = '---'; + if (parseFloat(sp) > parseFloat(maxSpd) && maxN > 15 ) maxSpd = sp; // Altitude @@ -409,12 +410,7 @@ if ( emulator ) { // Distance to waypoint di = distance(lf,wp); - vmgD2 = di; - vmgT2 = Math.round(lf.time.getTime()/1000); - di = (di/parseFloat(cfg.dist)).toFixed(2); - if ( di >= 100 ) di = parseFloat(di).toFixed(1); - if ( di >= 1000 ) di = parseFloat(di).toFixed(0); - if (isNaN(di)) di = '------'; + if (isNaN(di)) di = '--------'; // Age of last fix (secs) age = Math.max(0,Math.round(getTime())-(lf.time.getTime()/1000)); @@ -494,18 +490,6 @@ if ( emulator ) { } if ( cfg.modeA == 3 ) { - // VMG - drawScrn({ - val:vmgSpd, - unit:cfg.spd_unit, - sats:sats, - age:age, - max:'VMG', - wp:wpName - }); - } - - if ( cfg.modeA == 4 ) { // Position drawPosn({ sats:sats, @@ -517,48 +501,23 @@ if ( emulator ) { }); } - if ( cfg.modeA == 5 ) { + if ( cfg.modeA == 4 ) { // Large clock drawClock(); } } -function updateVMG() { - if (!canDraw) return; - vmgSpd = '---'; - - if ( ! lf.fix ) return; - if ( vmgT1 == vmgT2 ) return; // No new fix - - -//vmgD1 = 13640; -//vmgT1 = (getTime()/1000) - 10; - - if ( vmgD1 != -1 && ! isNaN(vmgD1)) { - // Have two WP distances and a time. Calc speed - vmgSpd = ((vmgD1-vmgD2)/1000)/((vmgT2-vmgT1)/3600); // k/h - vmgSpd = vmgSpd/parseFloat(cfg.spd); // Calculate for selected units - } - vmgD1 = vmgD2; - vmgT1 = vmgT2; // secs - - if ( Math.abs(vmgSpd) < 10 ) vmgSpd = vmgSpd.toFixed(1); - else vmgSpd = Math.round(vmgSpd); - - if (isNaN(vmgSpd)) vmgSpd = '---'; -} - function prevScrn() { cfg.modeA = cfg.modeA-1; - if ( cfg.modeA < 0 ) cfg.modeA = 5; + if ( cfg.modeA < 0 ) cfg.modeA = 4; savSettings(); onGPS(lf); } function nextScrn() { cfg.modeA = cfg.modeA+1; - if ( cfg.modeA > 5 ) cfg.modeA = 0; + if ( cfg.modeA > 4 ) cfg.modeA = 0; savSettings(); onGPS(lf); } @@ -570,14 +529,14 @@ function nextFunc(dur) { if ( dur < 2 ) showMax = !showMax; // Short press toggle fix/max display else { maxSpd = 0; maxAlt = 0; } // Long press resets max values. } - else if ( cfg.modeA == 2 || cfg.modeA == 3) nxtWp(); // Dist or VMG mode - Select next waypoint + else if ( cfg.modeA == 2) nxtWp(); // Dist mode - Select next waypoint onGPS(lf); } function updateClock() { if (!canDraw) return; - if ( cfg.modeA != 5 ) return; + if ( cfg.modeA != 4 ) return; drawClock(); if ( emulator ) {maxSpd++;maxAlt++;} } @@ -687,15 +646,15 @@ console.log('MDL'); // Read settings. let cfg = require('Storage').readJSON('speedalt2.json',1)||{}; -cfg.spd = cfg.spd||1; // Multiplier for speed unit conversions. 0 = use the locale values for speed -cfg.spd_unit = cfg.spd_unit||'kph'; // Displayed speed unit +cfg.spd = cfg.spd||0; // Multiplier for speed unit conversions. 0 = use the locale values for speed +cfg.spd_unit = cfg.spd_unit||''; // Displayed speed unit cfg.alt = cfg.alt||0.3048;// Multiplier for altitude unit conversions. cfg.alt_unit = cfg.alt_unit||'feet'; // Displayed altitude units cfg.dist = cfg.dist||1000;// Multiplier for distnce unit conversions. cfg.dist_unit = cfg.dist_unit||'km'; // Displayed altitude units cfg.colour = cfg.colour||0; // Colour scheme. cfg.wp = cfg.wp||0; // Last selected waypoint for dist -cfg.modeA = cfg.modeA||0; // 0=Speed 1=Alt 2=Dist 3 = vmg 4=Position 5=Clock +cfg.modeA = cfg.modeA||0; // 0=Speed 1=Alt 2=Dist 3=Position 4=Clock cfg.primSpd = cfg.primSpd||0; // 1 = Spd in primary, 0 = Spd in secondary cfg.spdFilt = cfg.spdFilt==undefined?true:cfg.spdFilt; @@ -757,4 +716,3 @@ Bangle.on('GPS', onGPS); setButtons(); setInterval(updateClock, 10000); -setInterval(updateVMG, 10000); From 2981aaf4af2c4c85987f460348f2169499f11e3a Mon Sep 17 00:00:00 2001 From: nujw Date: Mon, 1 Nov 2021 11:58:40 +1300 Subject: [PATCH 0029/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 6e18c3505..5aeb95eb6 100644 --- a/apps.json +++ b/apps.json @@ -3233,7 +3233,7 @@ "name": "GPS Adventure Sports II", "shortName":"GPS Adv Sport II", "icon": "app.png", - "version":"1.16", + "version":"1.10", "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.", "tags": "tool,outdoors", "supports": ["BANGLEJS"], From ac433ac7bd6d586e9b1ca11da924d64bd566ade2 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 01:57:39 +0000 Subject: [PATCH 0030/1839] Create hidmsicswipe.info --- apps/hidmsicswipe/hidmsicswipe.info | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/hidmsicswipe/hidmsicswipe.info diff --git a/apps/hidmsicswipe/hidmsicswipe.info b/apps/hidmsicswipe/hidmsicswipe.info new file mode 100644 index 000000000..207411199 --- /dev/null +++ b/apps/hidmsicswipe/hidmsicswipe.info @@ -0,0 +1 @@ +{"id":"hidmsicswipe","name":"Music Control","src":"hidmsicswipe.app.js","icon":"hidmsicswipe.img","version":"0.01","tags":"bluetooth","files":"hidmsicswipe.info,hidmsicswipe.app.js,hidmsicswipe.img"} From ad943ca5658e4f68c205996c4ad42aa1ebbeb793 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 01:58:19 +0000 Subject: [PATCH 0031/1839] Add files via upload --- apps/hidmsicswipe/hidmsicswipe.app.js | 93 ++++++++++++++++++++++++++ apps/hidmsicswipe/hidmsicswipe.img | Bin 0 -> 1156 bytes 2 files changed, 93 insertions(+) create mode 100644 apps/hidmsicswipe/hidmsicswipe.app.js create mode 100644 apps/hidmsicswipe/hidmsicswipe.img diff --git a/apps/hidmsicswipe/hidmsicswipe.app.js b/apps/hidmsicswipe/hidmsicswipe.app.js new file mode 100644 index 000000000..7f0fe39de --- /dev/null +++ b/apps/hidmsicswipe/hidmsicswipe.app.js @@ -0,0 +1,93 @@ +var storage = require('Storage'); + +const settings = storage.readJSON('setting.json',1) || { HID: false }; + +var sendHid, next, prev, toggle, up, down, profile; +var lasty = 0; +var lastx = 0; + +if (settings.HID=="kbmedia") { + profile = 'Music'; + sendHid = function (code, cb) { + try { + NRF.sendHIDReport([1,code], () => { + NRF.sendHIDReport([1,0], () => { + if (cb) cb(); + }); + }); + } catch(e) { + print(e); + } + }; + next = function (cb) { sendHid(0x01, cb); }; + prev = function (cb) { sendHid(0x02, cb); }; + toggle = function (cb) { sendHid(0x10, cb); }; + up = function (cb) {sendHid(0x40, cb); }; + down = function (cb) { sendHid(0x80, cb); }; +} else { + E.showPrompt("Enable HID?",{title:"HID disabled"}).then(function(enable) { + if (enable) { + settings.HID = "kbmedia"; + require("Storage").write('setting.json', settings); + setTimeout(load, 1000, "hidmsicswipe.app.js"); + } else setTimeout(load, 1000); + }); +} + +function drawApp() { + g.clear(); + if(Bangle.isLocked()==false) E.showMessage('Swipe', 'Music'); + else E.showMessage('Locked', 'Music'); +} + +if (next) { + setWatch(function(e) { + var len = e.time - e.lastTime; + E.showMessage('lock'); + setTimeout(drawApp, 1000); + Bangle.setLocked(true); + }, BTN1, { edge:"falling",repeat:true,debounce:50}); + Bangle.on('drag', function(e) { + if(!e.b){ + //console.log(lasty); + //console.log(lastx); + if(lasty > 40){ + E.showMessage('down'); + setTimeout(drawApp, 1000); + down(() => {}); + } + else if(lasty < -40){ + E.showMessage('up'); + setTimeout(drawApp, 1000); + up(() => {}); + } else if(lastx < -40){ + E.showMessage('prev'); + setTimeout(drawApp, 1000); + prev(() => {}); + } else if(lastx > 40){ + E.showMessage('next'); + setTimeout(drawApp, 1000); + next(() => {}); + } else if(lastx==0 && lasty==0){ + E.showMessage('play/pause'); + setTimeout(drawApp, 1000); + toggle(() => {}); + } + lastx = 0; + lasty = 0; + } + else{ + lastx = lastx + e.dx; + lasty = lasty + e.dy; + } + }); + + Bangle.on("lock", function(on) { + if(!on){ + E.showMessage('unlock'); + setTimeout(drawApp, 1000); + } + }); + + drawApp(); +} \ No newline at end of file diff --git a/apps/hidmsicswipe/hidmsicswipe.img b/apps/hidmsicswipe/hidmsicswipe.img new file mode 100644 index 0000000000000000000000000000000000000000..e4f978ba47fc10099a2805ee5258cb2612c0e079 GIT binary patch literal 1156 zcmdUtu@S%^2t_R!#}QMczzt;E0OAFLxwF+q?+Kp|TI*eoU5G2|h}1J@N|`H7+~`+F z6o|NJi~4QQlDQfD#?SO^evN*%YcXRdg`_05{i&y7V?sC&+j x-U|q(fF*8l|JziTZJ_*zca8jLPj0nb(AAv3aOJ_Bm0%sb?CduPF8s{_=Le(}b+rHh literal 0 HcmV?d00001 From b656e5973c302a39f7513364c66094132135bfc4 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 01:59:19 +0000 Subject: [PATCH 0032/1839] Create changelog --- apps/hidmsicswipe/changelog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/hidmsicswipe/changelog diff --git a/apps/hidmsicswipe/changelog b/apps/hidmsicswipe/changelog new file mode 100644 index 000000000..df3737358 --- /dev/null +++ b/apps/hidmsicswipe/changelog @@ -0,0 +1 @@ +0.01: Core functionnality based entirely on hidmsic From ffa37f2ab3b1fd2b921783e19ffb48673aad1a6e Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:22:38 +0000 Subject: [PATCH 0033/1839] Create hidmsicswipe-icon.js --- apps/hidmsicswipe/hidmsicswipe-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/hidmsicswipe/hidmsicswipe-icon.js diff --git a/apps/hidmsicswipe/hidmsicswipe-icon.js b/apps/hidmsicswipe/hidmsicswipe-icon.js new file mode 100644 index 000000000..6a0c64b9c --- /dev/null +++ b/apps/hidmsicswipe/hidmsicswipe-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwhC/AH4A5xGICquZzAVUAAIXQCogXQCoxHPCox0BxIXNxIVFBAQXPUAwXPBw4XowAvuC/4X/C9sIC6kIxGZzIXSFgIWBC6QWEC6RECAAOJwAXQFwoXLxAqBC4MICweZCxhWEC4mICxxuDA4I3BCxQ/FQxpyEK6AucC4idMI5OICyQwBQpgA/AH4Au")) From 5fce838e8ab7d2b297c05a1ae735abcd4ba76d90 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:29:36 +0000 Subject: [PATCH 0034/1839] Add files via upload --- apps/hidmsicswipe/hid-music.png | Bin 0 -> 632 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/hidmsicswipe/hid-music.png diff --git a/apps/hidmsicswipe/hid-music.png b/apps/hidmsicswipe/hid-music.png new file mode 100644 index 0000000000000000000000000000000000000000..923b5aa0e157bd3c8e32bfd5ce758da2cc8166fc GIT binary patch literal 632 zcmV-;0*C#HP)+gpH?nhpwLAjH%N$)U#%yap|A zfWjsPUE+oZSPY4wjPe5f$aW%Ok{AgJP=a@8Ttr*gd-uni;(py)_ntXtS2JUi_;!J!t=lqd)HeLH>e#l*t#m z*01afFMJdItOEo&0XiTa_+GKU`E}NXOVO>R!d0LF+L*lCnJ+k(x}}t{0kS580D1%D zInV}v##Nhp6Hg|~IQIBRTxtg!*ICe|JpI<2~(s|rg%1whe(AYIVyVt><1#N`ws z&E%u<+M=KLUjwyi=Tu}zRPUbuE$KaA`~`kgn>Anjx4@NIXM^U`z^Dg~%4>@%gfc%b zi~?xhf5ind4+a5-POGkPKTR`H2pvF_CutgqO6UM8dM8aIQ8DR(a%wJOFz-$LD``QK z0EcmlNdg){!Z$H=;}%ocjjItPd=sNvaf_+Qc3h1hM*mBO&eL}w%TWrc$WE!}-ivZ~ z8fKeVaxLIELY+}=tgQ(5W?~ee)N{Xy%41+;aBUFXQ`$v SUX6wT0000 Date: Sat, 20 Nov 2021 02:30:18 +0000 Subject: [PATCH 0035/1839] Delete hid-music.png --- apps/hidmsicswipe/hid-music.png | Bin 632 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/hidmsicswipe/hid-music.png diff --git a/apps/hidmsicswipe/hid-music.png b/apps/hidmsicswipe/hid-music.png deleted file mode 100644 index 923b5aa0e157bd3c8e32bfd5ce758da2cc8166fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 632 zcmV-;0*C#HP)+gpH?nhpwLAjH%N$)U#%yap|A zfWjsPUE+oZSPY4wjPe5f$aW%Ok{AgJP=a@8Ttr*gd-uni;(py)_ntXtS2JUi_;!J!t=lqd)HeLH>e#l*t#m z*01afFMJdItOEo&0XiTa_+GKU`E}NXOVO>R!d0LF+L*lCnJ+k(x}}t{0kS580D1%D zInV}v##Nhp6Hg|~IQIBRTxtg!*ICe|JpI<2~(s|rg%1whe(AYIVyVt><1#N`ws z&E%u<+M=KLUjwyi=Tu}zRPUbuE$KaA`~`kgn>Anjx4@NIXM^U`z^Dg~%4>@%gfc%b zi~?xhf5ind4+a5-POGkPKTR`H2pvF_CutgqO6UM8dM8aIQ8DR(a%wJOFz-$LD``QK z0EcmlNdg){!Z$H=;}%ocjjItPd=sNvaf_+Qc3h1hM*mBO&eL}w%TWrc$WE!}-ivZ~ z8fKeVaxLIELY+}=tgQ(5W?~ee)N{Xy%41+;aBUFXQ`$v SUX6wT0000 Date: Sat, 20 Nov 2021 02:30:45 +0000 Subject: [PATCH 0036/1839] Delete hidmsicswipe.img --- apps/hidmsicswipe/hidmsicswipe.img | Bin 1156 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/hidmsicswipe/hidmsicswipe.img diff --git a/apps/hidmsicswipe/hidmsicswipe.img b/apps/hidmsicswipe/hidmsicswipe.img deleted file mode 100644 index e4f978ba47fc10099a2805ee5258cb2612c0e079..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1156 zcmdUtu@S%^2t_R!#}QMczzt;E0OAFLxwF+q?+Kp|TI*eoU5G2|h}1J@N|`H7+~`+F z6o|NJi~4QQlDQfD#?SO^evN*%YcXRdg`_05{i&y7V?sC&+j x-U|q(fF*8l|JziTZJ_*zca8jLPj0nb(AAv3aOJ_Bm0%sb?CduPF8s{_=Le(}b+rHh From 21f184d6c4ad1f977c385d95c3966d95d446bf5c Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:31:10 +0000 Subject: [PATCH 0037/1839] Add files via upload --- apps/hidmsicswipe/hidmsicswipe.png | Bin 0 -> 632 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/hidmsicswipe/hidmsicswipe.png diff --git a/apps/hidmsicswipe/hidmsicswipe.png b/apps/hidmsicswipe/hidmsicswipe.png new file mode 100644 index 0000000000000000000000000000000000000000..923b5aa0e157bd3c8e32bfd5ce758da2cc8166fc GIT binary patch literal 632 zcmV-;0*C#HP)+gpH?nhpwLAjH%N$)U#%yap|A zfWjsPUE+oZSPY4wjPe5f$aW%Ok{AgJP=a@8Ttr*gd-uni;(py)_ntXtS2JUi_;!J!t=lqd)HeLH>e#l*t#m z*01afFMJdItOEo&0XiTa_+GKU`E}NXOVO>R!d0LF+L*lCnJ+k(x}}t{0kS580D1%D zInV}v##Nhp6Hg|~IQIBRTxtg!*ICe|JpI<2~(s|rg%1whe(AYIVyVt><1#N`ws z&E%u<+M=KLUjwyi=Tu}zRPUbuE$KaA`~`kgn>Anjx4@NIXM^U`z^Dg~%4>@%gfc%b zi~?xhf5ind4+a5-POGkPKTR`H2pvF_CutgqO6UM8dM8aIQ8DR(a%wJOFz-$LD``QK z0EcmlNdg){!Z$H=;}%ocjjItPd=sNvaf_+Qc3h1hM*mBO&eL}w%TWrc$WE!}-ivZ~ z8fKeVaxLIELY+}=tgQ(5W?~ee)N{Xy%41+;aBUFXQ`$v SUX6wT0000 Date: Sat, 20 Nov 2021 02:31:55 +0000 Subject: [PATCH 0038/1839] Delete hidmsicswipe.info --- apps/hidmsicswipe/hidmsicswipe.info | 1 - 1 file changed, 1 deletion(-) delete mode 100644 apps/hidmsicswipe/hidmsicswipe.info diff --git a/apps/hidmsicswipe/hidmsicswipe.info b/apps/hidmsicswipe/hidmsicswipe.info deleted file mode 100644 index 207411199..000000000 --- a/apps/hidmsicswipe/hidmsicswipe.info +++ /dev/null @@ -1 +0,0 @@ -{"id":"hidmsicswipe","name":"Music Control","src":"hidmsicswipe.app.js","icon":"hidmsicswipe.img","version":"0.01","tags":"bluetooth","files":"hidmsicswipe.info,hidmsicswipe.app.js,hidmsicswipe.img"} From b7a067234413e2cd9cb531c366371e5d88f6bb21 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:32:09 +0000 Subject: [PATCH 0039/1839] Rename hidmsicswipe.app.js to hidmsicswipe.js --- apps/hidmsicswipe/{hidmsicswipe.app.js => hidmsicswipe.js} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename apps/hidmsicswipe/{hidmsicswipe.app.js => hidmsicswipe.js} (96%) diff --git a/apps/hidmsicswipe/hidmsicswipe.app.js b/apps/hidmsicswipe/hidmsicswipe.js similarity index 96% rename from apps/hidmsicswipe/hidmsicswipe.app.js rename to apps/hidmsicswipe/hidmsicswipe.js index 7f0fe39de..e0fc760a4 100644 --- a/apps/hidmsicswipe/hidmsicswipe.app.js +++ b/apps/hidmsicswipe/hidmsicswipe.js @@ -90,4 +90,4 @@ if (next) { }); drawApp(); -} \ No newline at end of file +} From 6fda7a5f33ec6341d51529e680f5d0caa9c9fdbd Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:37:07 +0000 Subject: [PATCH 0040/1839] Update apps.json --- apps.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps.json b/apps.json index 7fe259899..325462480 100644 --- a/apps.json +++ b/apps.json @@ -4307,5 +4307,19 @@ {"name":"binwatch.app.js","url":"app.js"}, {"name":"binwatch.img","url":"app-icon.js","evaluate":true} ] + }, + { + "id": "hidmsicswipe", + "name": "Bluetooth Music Swipe Controls", + "shortName": "Music Control", + "version": "0.01", + "description": "Based on the original Bluetooth Music Controls. Swipe up/down for volume, left/right for previous and next, tap for play/pause and btn1 to lock and unlock the controls. Enable HID in settings, pair with your phone, then use this app to control music from your watch!", + "icon": "hidmsicswipe.png", + "tags": "bluetooth", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"hidmsicswipe.app.js","url":"hidmsicswipe.js"}, + {"name":"hidmsicswipe.img","url":"hidmsicswipe-icon.js","evaluate":true} + ] } ] From 51766844e6ff346119739114c28b9d638ca57cbd Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:49:56 +0000 Subject: [PATCH 0041/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 325462480..4b54e5d48 100644 --- a/apps.json +++ b/apps.json @@ -4311,7 +4311,7 @@ { "id": "hidmsicswipe", "name": "Bluetooth Music Swipe Controls", - "shortName": "Music Control", + "shortName": "Swipe Control", "version": "0.01", "description": "Based on the original Bluetooth Music Controls. Swipe up/down for volume, left/right for previous and next, tap for play/pause and btn1 to lock and unlock the controls. Enable HID in settings, pair with your phone, then use this app to control music from your watch!", "icon": "hidmsicswipe.png", From 333a646559e0a3822a1cd01654983ec57021563e Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 02:41:28 +0000 Subject: [PATCH 0042/1839] Update app-bangle2.js --- apps/launch/app-bangle2.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/launch/app-bangle2.js b/apps/launch/app-bangle2.js index 8b66247c5..161a226e5 100644 --- a/apps/launch/app-bangle2.js +++ b/apps/launch/app-bangle2.js @@ -1,4 +1,9 @@ var s = require("Storage"); +var scaleval = 1; +let settings = require('Storage').readJSON("launch.json", true) || {}; +if ("scaleval" in settings) { + scaleval = settings.scaleval; +} var apps = s.list(/\.info$/).map(app=>{var a=s.readJSON(app,1);return a&&{name:a.name,type:a.type,icon:a.icon,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="clock" || !app.type)); apps.sort((a,b)=>{ var n=(0|a.sortorder)-(0|b.sortorder); @@ -12,7 +17,8 @@ apps.forEach(app=>{ app.icon = s.read(app.icon); // should just be a link to a memory area }); // FIXME: not needed after 2v11 -var font = g.getFonts().includes("12x20") ? "12x20" : "6x8:2"; +//var font = g.getFonts().includes("12x20") ? "12x20" : "6x8:2"; +var font = "Vector"+(20*scaleval).toString(); // FIXME: check not needed after 2v11 if (g.wrapString) { g.setFont(font); @@ -22,9 +28,9 @@ if (g.wrapString) { function drawApp(i, r) { var app = apps[i]; if (!app) return; - g.clearRect(r.x,r.y,r.x+r.w-1, r.y+r.h-1); - g.setFont(font).setFontAlign(-1,0).drawString(app.name,64,r.y+32); - if (app.icon) try {g.drawImage(app.icon,8,r.y+8);} catch(e){} + g.clearRect((r.x),(r.y),(r.x+r.w-1), (r.y+r.h-1)); + g.setFont(font).setFontAlign(-1,0).drawString(app.name,64*scaleval,r.y+(32*scaleval)); + if (app.icon) try {g.drawImage(app.icon,8*scaleval, r.y+(8*scaleval), {scale: scaleval});} catch(e){} } g.clear(); @@ -32,7 +38,7 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); E.showScroller({ - h : 64, c : apps.length, + h : 64*scaleval, c : apps.length, draw : drawApp, select : i => { var app = apps[i]; From 374fa668e3a6240b76b47b83680923a994dcc600 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 02:52:13 +0000 Subject: [PATCH 0043/1839] Create settings.js --- apps/launch/settings.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 apps/launch/settings.js diff --git a/apps/launch/settings.js b/apps/launch/settings.js new file mode 100644 index 000000000..42f74e2cf --- /dev/null +++ b/apps/launch/settings.js @@ -0,0 +1,18 @@ +// make sure to enclose the function in parentheses +(function(back) { + let settings = require('Storage').readJSON('launch.json',1)||{}; + function save(key, value) { + settings[key] = value; + require('Storage').write('launch.json',settings); + } + const appMenu = { + '': {'title': 'Launcher Settings'}, + '< Back': back, + 'Scale Value': { + value: settings.scaleval, + min:0.1,max:2,step:0.05,wrap:true, + onchange: (m) => {save('scaleval', m)} + } + }; + E.showMenu(appMenu) +}) From 5b1b752dfc9660d2eba6a6268146a0a13b83abd5 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 02:55:47 +0000 Subject: [PATCH 0044/1839] Update apps.json --- apps.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 7fe259899..48b2c174b 100644 --- a/apps.json +++ b/apps.json @@ -100,7 +100,7 @@ "id": "launch", "name": "Launcher", "shortName": "Launcher", - "version": "0.08", + "version": "0.09", "description": "This is needed to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", "icon": "app.png", "type": "launch", @@ -108,8 +108,13 @@ "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"launch.app.js","url":"app-bangle1.js","supports":["BANGLEJS"]}, - {"name":"launch.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]} + {"name":"launch.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]}, + {"name":"launch.settings.js","url":"settings.js"} ], + "data": [ + {"name":"launch.json"} + ] + , "sortorder": -10 }, { From 9d1429cabc5141c0be15db43d338ba31ebb45cd7 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:02:22 +0000 Subject: [PATCH 0045/1839] Update settings.js --- apps/launch/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/launch/settings.js b/apps/launch/settings.js index 42f74e2cf..4842019fe 100644 --- a/apps/launch/settings.js +++ b/apps/launch/settings.js @@ -9,7 +9,7 @@ '': {'title': 'Launcher Settings'}, '< Back': back, 'Scale Value': { - value: settings.scaleval, + value: settings.scaleval || 1, min:0.1,max:2,step:0.05,wrap:true, onchange: (m) => {save('scaleval', m)} } From eca0ae101c74875d6a8745f294f3fdc78072e744 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:10:09 +0000 Subject: [PATCH 0046/1839] Update ChangeLog --- apps/launch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/launch/ChangeLog b/apps/launch/ChangeLog index bd8a9bd03..402953fd1 100644 --- a/apps/launch/ChangeLog +++ b/apps/launch/ChangeLog @@ -6,3 +6,4 @@ 0.06: Use Bangle.setUI for buttons 0.07: Theme colours fix 0.08: Merge Bangle.js 1 and 2 launchers +0.09: Added Scaling factor to settings and changed to vector font From 97a63993394250101bc2f70c239160671ae1b519 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:13:06 +0000 Subject: [PATCH 0047/1839] Update ChangeLog --- apps/launch/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/launch/ChangeLog b/apps/launch/ChangeLog index 402953fd1..acabd9b11 100644 --- a/apps/launch/ChangeLog +++ b/apps/launch/ChangeLog @@ -6,4 +6,4 @@ 0.06: Use Bangle.setUI for buttons 0.07: Theme colours fix 0.08: Merge Bangle.js 1 and 2 launchers -0.09: Added Scaling factor to settings and changed to vector font +0.09: Added Scaling factor to settings and changed to vector font for Bangle.js2 From 411118aa4c563bbcd85cf1ecc8a99708db28465c Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:14:15 +0000 Subject: [PATCH 0048/1839] Update apps.json --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 48b2c174b..7617a1ad7 100644 --- a/apps.json +++ b/apps.json @@ -109,10 +109,10 @@ "storage": [ {"name":"launch.app.js","url":"app-bangle1.js","supports":["BANGLEJS"]}, {"name":"launch.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]}, - {"name":"launch.settings.js","url":"settings.js"} + {"name":"launch.settings.js","url":"settings.js","supports":["BANGLEJS2"]} ], "data": [ - {"name":"launch.json"} + {"name":"launch.json","supports":["BANGLEJS2"]} ] , "sortorder": -10 From 2c25760554a8991f89403e6255a2609dfb1f6b4b Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:30:14 +0000 Subject: [PATCH 0049/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 7617a1ad7..5c67bef41 100644 --- a/apps.json +++ b/apps.json @@ -112,7 +112,7 @@ {"name":"launch.settings.js","url":"settings.js","supports":["BANGLEJS2"]} ], "data": [ - {"name":"launch.json","supports":["BANGLEJS2"]} + {"name":"launch.json"} ] , "sortorder": -10 From 181a8dd45fe144b10fdd0dbf5434d45d34fe45b8 Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Fri, 26 Nov 2021 04:37:15 +0000 Subject: [PATCH 0050/1839] Update settings.js Added font to settings Changed scalevalue to vector font size --- apps/launch/settings.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/launch/settings.js b/apps/launch/settings.js index 4842019fe..31c59faef 100644 --- a/apps/launch/settings.js +++ b/apps/launch/settings.js @@ -1,18 +1,24 @@ // make sure to enclose the function in parentheses -(function(back) { + let settings = require('Storage').readJSON('launch.json',1)||{}; + let fonts = g.getFonts(); function save(key, value) { settings[key] = value; require('Storage').write('launch.json',settings); } const appMenu = { '': {'title': 'Launcher Settings'}, - '< Back': back, - 'Scale Value': { - value: settings.scaleval || 1, - min:0.1,max:2,step:0.05,wrap:true, - onchange: (m) => {save('scaleval', m)} - } + '< Back': false, + 'Font': { + value: settings.font || 2, + min:0, max:fonts.length-1, step:1,wrap:true, + onchange: (m) => {save('font', fonts[m])}, + format: v => fonts[v] + }, + 'Vector font size': { + value: settings.vectorsize || 1, + min:10, max: 20,step:1,wrap:true, + onchange: (m) => {save('vectorsize', m)} + } }; E.showMenu(appMenu) -}) From ae6ca3b8f8344df645bee31507ac9a442a4f011b Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Fri, 26 Nov 2021 04:39:08 +0000 Subject: [PATCH 0051/1839] Update settings.js Edited default vector size --- apps/launch/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/launch/settings.js b/apps/launch/settings.js index 31c59faef..5e096c33e 100644 --- a/apps/launch/settings.js +++ b/apps/launch/settings.js @@ -16,7 +16,7 @@ format: v => fonts[v] }, 'Vector font size': { - value: settings.vectorsize || 1, + value: settings.vectorsize || 10, min:10, max: 20,step:1,wrap:true, onchange: (m) => {save('vectorsize', m)} } From ee7b7e4839ffe98c24fe6cdc95644e85f7ae6806 Mon Sep 17 00:00:00 2001 From: David Peer Date: Fri, 26 Nov 2021 19:01:12 +0100 Subject: [PATCH 0052/1839] Minor changes --- apps/lcars/bg_large.png | Bin 12390 -> 12564 bytes apps/lcars/bg_small.png | Bin 9939 -> 10161 bytes apps/lcars/lcars.app.js | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/lcars/bg_large.png b/apps/lcars/bg_large.png index dd5bda4f3207c4764d8e0dea681f05608a031cc2..7b0f1ad5f06f14889a8e0477b6f8cf7a238be586 100644 GIT binary patch delta 11741 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 delta 11502 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 diff --git a/apps/lcars/bg_small.png b/apps/lcars/bg_small.png index 8030c0ddbcee2266a654b613ecdbc108605b014b..20fe40a4e1ef66f14ac76b577a1cd6a6c8302828 100644 GIT binary patch delta 10086 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 delta 9862 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 Hm Date: Fri, 26 Nov 2021 20:42:18 +0100 Subject: [PATCH 0053/1839] Minor changes --- apps/lcars/bg_large.png | Bin 12564 -> 11049 bytes apps/lcars/bg_small.png | Bin 10161 -> 8846 bytes apps/lcars/lcars.app.js | 17 +++++++++-------- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/lcars/bg_large.png b/apps/lcars/bg_large.png index 7b0f1ad5f06f14889a8e0477b6f8cf7a238be586..5526c241fce23c9ffe492c60047549337d0566ee 100644 GIT binary patch literal 11049 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 delta 11812 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 CDbe!) diff --git a/apps/lcars/bg_small.png b/apps/lcars/bg_small.png index 20fe40a4e1ef66f14ac76b577a1cd6a6c8302828..b9f984b33cd07203e130a5cac09814588d63713b 100644 GIT binary patch literal 8846 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 Date: Fri, 26 Nov 2021 21:00:30 +0100 Subject: [PATCH 0054/1839] Minor changes --- apps/lcars/bg_large.png | Bin 11049 -> 11003 bytes apps/lcars/bg_small.png | Bin 8846 -> 8753 bytes apps/lcars/lcars.app.js | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/lcars/bg_large.png b/apps/lcars/bg_large.png index 5526c241fce23c9ffe492c60047549337d0566ee..56590e87891ec7908e31984aebc50db7ce8b3e4a 100644 GIT binary patch delta 9831 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 F{{WC60s{a5 delta 8408 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 Ws*t)6^$bDpc!j9G|NjE|93}h! diff --git a/apps/lcars/lcars.app.js b/apps/lcars/lcars.app.js index 5a7ad5f93..8ac01d90c 100644 --- a/apps/lcars/lcars.app.js +++ b/apps/lcars/lcars.app.js @@ -12,7 +12,7 @@ const locale = require('locale'); var backgroundImage = { width : 176, height : 151, bpp : 3, transparent : 2, - buffer : require("heatshrink").decompress(atob("AAdz588+YCcgEHDrRAC8+evICd8mAgIdaIANHQDyDggSAeQcNzJQ0cuPHATCDBDrUAJQ1AZwIA2jjOF+BA4T4KDFyBB5Qf4ABQAaD9QAaD/QesH8CD/g/8Qf8//+AQfsB///GQ6D2IJSD/QfEPIIP+Qfkcv5BB//HjiD5g4/CAAeAQe8B//8QYkf+PAQew+BAQQAB/EDAQKD1j//PQJBDAoKMBQesf/0APoKDDBQM/8CD1FgJBEQAUH/iDzGoZBHgH/wCDyIIcfII6PCkGChACDJQIAofYZBFBAb+rQZB6DIPk/fwZBHgZB3QYv8BIVwQfhBCQYUcuPHAQZKqg5BLj5BB8+evICDwCDqfwQ+DgIDBGoJBCnnz54CDBAKDpPQMHIIUAIIKD3II6MBQYQCCQeI1B+BBC/BKCBASGCQeK5B/xBC4BKEn/gAoKDyj//4///wIE+LLCQecAv6CBIIrLDQecAgKDBF4cHQYLLDQecAn6EBAAiJEQeZBB/jICAAMcvwMDQevggE48YyCIIiDzgP/BA1/4CD3nAHGhyD3ABqD0ABiD/Qf4ADjiD/gEHQYuQQf6D7gaDFzxB5gFzQYnz4BB5hyDFATfkEoIdagEBQYoCcgEHDrReBgKDiEbbHCjiD/AH4A/AH4AGiFx48cATsAg4daIIWSpMkATuQEbkAgJfbQckJQDyDhJQ3EZwQA1gRKFpBA4gEQQYtwIPMSQYtAIPKADQfqADAQRA5Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4A/AH4A/AH4A/AFkQoMEAQZB6yVJkgCDIPUcuPHAQdAQf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/AEcQoMEAQZB6AH4A/AH4A/AH4AJjlx44CDqBB5yVJkgCDQf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6DhuBB5iSDFoCD/QfcCQYtIIPMAQYoC6gEJQYgC6gEBg6D/AAKD/AAMQQfoA=")) + buffer : require("heatshrink").decompress(atob("AAdx48cATsAg4daIAX3799ATv2wEFDrUAgNHQDyDghaAeQcJKG86D4gRKGgAA4jxKFuBB5iaDF6BB5ZwyD6QAYCC4CD/Qf6Dzg/gQf8H/iD/n//wCD9gP///wQfpBKQf6D4h5BB/yD8jl/IIIABjiD5n4/DAAWAQe8B//8QYfHj//PAaDzHwICCAAP4gYCBQep6DIIYFBRgKD1j/+gB9BQYYKBn/gQen/+BBFQAUH/iDzGoZBHJoOAQeRBDj5BHj6PB0WKlACDJQIAofYZBFBAZBBAGMHPQZB8QYZAEIIcDIOiDI/hB3QZBBFjlx44CDuBBpg4DCIJEfIIPnz15AQeAQeH8gIDBGoJBCnnz54CDZ1UHPQMHIIUAIIKD3II6MBQYQCCQeI1B+BBC/BKCBASGCQeK5B/xBC4BKEn/gAoKDyj//45BFj/xZYSDzgF/IAP+JQrLCQecAgKDBF4cHQYKJDQecAn6EBAAiJEQeZBB/jICAAMcvwMDQevgQwR0CIIiDzgP/BA1/4CD3nAHGhyD3ABqD0ABiD/Qf4ADjiD/gEnQYuQQf6D7gaDFzxB5gFzQYnz4BB5hyDFATfkEoIdagEBQYoCcgEHDrReBhKDhwEBQbYABjiD/AH4A/AH4AGiFx48cATsAg4daIIWSpMkATuQEbkAgJfbQckJQDyDhZxQA1gRKFpBA4gEQQYtwIPMSQYtAIPKADQfqADAQRA5Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4A/AH4A/AH4A/AFkcuPHAQdAIPOSpMkAQaD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4A/AH4A/AH4A/AGUcuPHAQdwIPOSpMkAQaD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4AciSDFoCD/QfcCQYtIIPMAQYoC6gEJQYgC6gEBQf7HCQf4ABiiD9")) } var iconEarth = { From ce0e50ed949eeffc97bd2ec3db1fdb38830c3e4e Mon Sep 17 00:00:00 2001 From: hughbarney Date: Fri, 26 Nov 2021 20:25:28 +0000 Subject: [PATCH 0055/1839] MyLocation - adds menu to set preferred city or setup from GPS --- apps.json | 15 +++++ apps/mylocation/ChangeLog | 1 + apps/mylocation/README.md | 44 +++++++++++++++ apps/mylocation/mylocation.png | Bin 0 -> 1909 bytes apps/mylocation/mylocation.settings.js | 73 +++++++++++++++++++++++++ apps/mylocation/screenshot_1.png | Bin 0 -> 2847 bytes apps/mylocation/screenshot_2.png | Bin 0 -> 2642 bytes apps/mylocation/screenshot_3.png | Bin 0 -> 15562 bytes apps/mylocation/screenshot_4.png | Bin 0 -> 2818 bytes apps/pastel/pastel.app.js | 30 ++++++++++ 10 files changed, 163 insertions(+) create mode 100644 apps/mylocation/ChangeLog create mode 100644 apps/mylocation/README.md create mode 100644 apps/mylocation/mylocation.png create mode 100644 apps/mylocation/mylocation.settings.js create mode 100644 apps/mylocation/screenshot_1.png create mode 100644 apps/mylocation/screenshot_2.png create mode 100644 apps/mylocation/screenshot_3.png create mode 100644 apps/mylocation/screenshot_4.png diff --git a/apps.json b/apps.json index a7a74f4cb..8b1fb586e 100644 --- a/apps.json +++ b/apps.json @@ -4456,5 +4456,20 @@ "storage": [ {"name":"timecal.app.js","url":"timecal.app.js"} ] + }, + { "id": "mylocation", + "name": "My Location", + "shortName":"My Location", + "icon": "mylocation.png", + "screenshots": [{"url":"screenshot_1.png"}], + "version":"0.01", + "description": "My Locations adds a menu in the Settings app to set your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", + "readme": "README.md", + "tags": "tool,utility", + "type": "app", + "supports": ["BANGLEJS", "BANGLEJS2"], + "storage": [ + {"name":"mylocation.settings.js","url":"mylocation.settings.js"} + ] } ] diff --git a/apps/mylocation/ChangeLog b/apps/mylocation/ChangeLog new file mode 100644 index 000000000..7b83706bf --- /dev/null +++ b/apps/mylocation/ChangeLog @@ -0,0 +1 @@ +0.01: First release diff --git a/apps/mylocation/README.md b/apps/mylocation/README.md new file mode 100644 index 000000000..3b39aa947 --- /dev/null +++ b/apps/mylocation/README.md @@ -0,0 +1,44 @@ +# My Location + + *a adds a My Location settings menu, stores GPS lat and lon of your preferred city* + +* My Location is a service app that adds a 'My Location' menu to the settings menu +* Select one of the preset Cities or setup through the GPS +* Other Apps can read this information to do calculations based on location +* When the City shows ??? it means the location has been set through the GPS + +## Example Code + + const LOCATION_FILE = "mylocation.json"; + let location; + + // requires the myLocation app + function loadLocation() { + location = require("Storage").readJSON(LOCATION_FILE,1)||{"lat":51.5072,"lon":0.1276,"location":"London"}; + } + +## Screenshots + +### Select one of the Preset Cities + +* The presets are London, Newcastle, Edinbrough, Paris, New York, Tokyo + +![](screenshot_1.png) + +### Or select 'Set By GPS' to start the GPS + +![](screenshot_2.png) + +### While the GPS is running you will see: + +![](screenshot_3.png) + +### When a GPS fix is received you will see: + +![](screenshot_4.png) + + + +## Creator + +[Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/) diff --git a/apps/mylocation/mylocation.png b/apps/mylocation/mylocation.png new file mode 100644 index 0000000000000000000000000000000000000000..7148990a42a1c8858d933d2a4cb35b80123a5505 GIT binary patch literal 1909 zcmV-*2a5QKP)1f{oIeq9#IX zOf{({O-*cUKk%VRxp+%YMPU&efj|3B}%Gtc{uFh$VRFTVr&05N+hmOTqw5{SsK zRq^~hp6S9jhcVu7mJ0i>}op)z!;xQ{&^&`R#GVwH9WEaeQfJ>BoptFh|R8ypn@@g4s~Z+ zAOYPL+%Al}QXb#%&nSE%3DC#3-bG{mOV}Y--E|?8ANqHT!{ow5VmbiFlKYm+Yg=}jras6GBg@72L>|d5wlEoY`!pQ*klg6p{<$e z$#!B+vczB%x_gHNTpqkfI)1CXn97GaO}wJx(crv3fxPd-g^QPyJirPX+zpdCg^qxx z+HRqt@!gU}&xek#ArY4!IV}HL*|GI}Ifw8OaN;kPoErn37e~l@O--0YqB?4}jo;XW z*U%8=mBiSa!W_zufTp%x&$Q$*##94z^*}BUmc@nj>xj>20>D?LI9MS6!ACTmJw@}W zPjPbDl6>wJS1@?fHzeuwyndoVNc@M_IV<<#JS9jLwtYTe^dcPFZP|{G#NA zlgSN{2MP=3kB|pQ=anAUMi(und(mRV7+O9)PRobKFmvbPee)(_Gnx?~K1@36D!HN| zS5(~V7IWpn{S!nFBaT@20KbkVz;V7ka%>d(M#~j{+-=jB^-&!?SIeSj(PB=tUQ5!k zSUh92Ov)9N&a{tbv?PbILn;!{`^pIjoCBIlH4$@0Z_e~!=%m%MmQoabrG3DgK)wPj z(^M+(Vh2xRNvvr}{R0V3DRW1-p-)Eq3plK9B6Tdbwq%Z^|H#*Eeo|Ca)kc3|kqQ{}9i za){L#)Eq3JXbu73e@4gyARh*`1`D{VK4fhn>?vm| zUkgcMFSt8_dAjvflrXX3}lk(J;L2)mG{uD2UIU%<)dn04%Z zEU)a#GDqILT9#&60f4T3HS0f@UoEZawVs}5zn+It; zdy05}f2An_o|m1Qe_YO3egpt4e-p;OpMX&aLZYviL|-qn{&AGzv_{fbwj#|<)So#+ zqO&6k=}X9h_hgvEXk8A+is_A_SuwHg<-WKLC`J%q##516Wri@bM_#-pp+b46X zY+vZ7kIu)_zXP*srd1hwu>7xwE#@y_@(}=J`&0ix`2m%$U21`%`amV*p+W%wvTO5x z;F+pvRoszmlU-Y0tJJ+>0RVKIco>y8B9p2V!U1N)9*q_f5&DyjEjZR+for11PJ&PI z%yN0Itv52fIQpwCdv<~ZK{z!JVy{A8q8gjsZ+0gfxxXiC>NABhx4bH?2lq4Q zgK!ZSufKt_x339aD2(DTqT80vkG~=!p>r%WONZ(l9n_B#jQ0IcjU&x&LnG%_t>)Zqt1BlDAiAc(cJB&x2{WGTFW%7{v){1Cd|LGtdNV$Q1rxsO zqDp*V00i8|rf9@RleF8mSrIlTCe3=LS63z+-Bahtf^q!F6_u=O$a{+G>s0Q6c>=#T zmiO?o`St$_bFBEXobD{%;>7Hq#T{;TET&slX{Z98uXqMLqxi%Bc~>b^wn3H#4hy{I ziTBF#1@-@~B&e!Qn=`6)^!VSkExB1lz9JT_7Bt(I)LTMa1WN!BB;y)72K)iQ2g!hT vfnGqRQ;-viIVr;N(+lDs-76CL)93#HbI`dUZ#9t@00000NkvXXu0mjf9c-jw literal 0 HcmV?d00001 diff --git a/apps/mylocation/mylocation.settings.js b/apps/mylocation/mylocation.settings.js new file mode 100644 index 000000000..6936e9e69 --- /dev/null +++ b/apps/mylocation/mylocation.settings.js @@ -0,0 +1,73 @@ +(function(back) { + const SETTINGS_FILE = "mylocation.json"; + + // initialize with default settings... + let s = { + 'lat': 51.5072, + 'lon': 0.1276, + 'location': "London" + } + + // ...and overwrite them with any saved values + // This way saved values are preserved if a new version adds more settings + const storage = require('Storage') + let settings = storage.readJSON(SETTINGS_FILE, 1) || {} + const saved = settings || {} + for (const key in saved) { + s[key] = saved[key] + } + + function save() { + settings = s + storage.write(SETTINGS_FILE, settings) + } + + const locations = ["London", "Newcastle", "Edinburgh", "Paris", "New York", "Tokyo","???"]; + const lats = [51.5072 ,54.9783 ,55.9533 ,48.8566 ,40.7128 ,35.6762, 0.0]; + const lons = [-0.1276 ,-1.6178 ,-3.1883 ,2.3522 , -74.0060 ,139.6503, 0.0]; + + E.showMenu({ + '': { 'title': 'My Location' }, + '< Back': back, + 'City': { + value: 0 | locations.indexOf(s.location), + min: 0, max: 6, + format: v => locations[v], + onchange: v => { + if (v != 6) { + s.location = locations[v]; + s.lat = lats[v]; + s.lon = lons[v]; + save(); + } + }, + }, + 'Set From GPS': ()=>setFromGPS() + }) + + function setFromGPS() { + console.log("set from GPS"); + Bangle.setGPSPower(1); + E.showMessage("Waiting for GPS fix. Place watch in the open. Could take 10 minutes. Long press to abort", "GPS Running"); + Bangle.setUI("updown", undefined); + } + + Bangle.on('GPS', (gps) => { + //console.log("."); + if (gps.fix === 0) return; + //console.log("fix from GPS"); + s = {'lat': gps.lat, 'lon': gps.lon, 'location': '???' } + Bangle.buzz(1500); // buzz on first position + Bangle.setGPSPower(0); + save(); + + Bangle.setUI("updown", ()=>{ load() }); + E.showPrompt("Location has been saved from the GPS fix",{ + title:"Location Saved", + buttons : {"OK":1} + }).then(function(v) { + load(); // load default clock + }); + }); + +}) diff --git a/apps/mylocation/screenshot_1.png b/apps/mylocation/screenshot_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c61b6b35272dabcd77f7262d0ae6a2e9099057 GIT binary patch literal 2847 zcmeHJX*`sT9(`tdj6tJeh#^Z^do88mZD>N4QI)x;T<^E+#aA~Xs}2G@$ZgN9v2Y>jlqEg*DD`m%hRa;pL!7t{o6EBwJva6|zJI&ao4NFi8B2XU@d}{= zp^OCpEOgwB$x!Dv<8+vdo+`;DVb(U%`kx4sX_dY85{s(6|Th2LvD>&(-3GSCz) z5HCz4o0oLfU1=p%E76aq4(hkxcl4j}FOM5ilTpu>I1-2N#=}LG^=rR1`(H4!ps$;3 z)&KHGxMe{7N-esDREc7VlZqs#U&W(BbHvZB^M6H#Z(&1iHU?i{G5zi3qOrg@e@mZN z7C>M;_6qu;Ov=@ov5X?!ZYienws0{MHMK~}$$NJ;J|zKu3a!7(kxSHvigBmS4KNU8 zahM-9B5L|cuCjm^wd;|oI)|Dw$@=&~Dn;=YR4!_?q)4iDTe%2!Akl7%3scBK4bqXI zPKbPW5+8jiP^TrLD6i*6GT=(t=i?`93*u7;4`zyT)9Sy8n9_gIWX?`k0;yxL%2ljV z>H#HT7q<6d$GE4d9=vq@f%WTzIVwH1@HF|20yHl7-chDXrfB>0l@V(Xnqc}1g|Kcj zx5CW$^JCp^I#HJ7a3L@ZosecKx1b`zKHW$1tyY z{05Vg_9{TCM$J5shE@YhzfDTHXoXqyM41sC6P8(*raDSF>TR=)`QVx|UE`@{Y!cvl zy;$39Kq_{Fv6BBPOS(Kv{oUuXR#RTOuJ-Zl%JrTDWszD&tG`?5ijukS>!<`Vf9-s) z%L5}$!3S_hul7HeffaXM9r>AdKsz7d=I070P^WEm7Ro?8Om~C!(z$3@WMN8;L*b~n zJor{(D&S_iIRR**vc}jAwUUCYNuMFglV(}hzEy%lnB{Xb{oDq^yZ2E8GD2c+#CZ+y zSq-%3zWH_h*!FG`R>L82OB4CMQ0GgG7-6kv0_F4DVKENX`Euzf7Tg@>=Cf;9}(zL5P$QoqbK@*6TtI}#kBb+4&F9@MKFpy@*J&FD#DS~VuJ4*I%)j& zjSlmnx?^mSDR>18zHG{qJ$PO#u}x1mAppz;{4N@9+cqVZhzHXu?zyiKx%;5~=pL<* z%`&g7D2dl1i0M^q;qrPy2BR_=;)fgiwi`^UOou-h{g+6Uo?;d4eAGlqUf zk({3^)j!)^4lVF4RB*`HHKbr{t;92OPVFV300|t9^+spUsv9;F!7j9j!Y~K}f>Fdi z1)rBM5UeM@Gvl)I1D<yaBs<35`#$y^#nUgB&*xz^@?k02L_ znmf6R+YPqVF8I;fM1X-D?a_>}>usxDN@^ANy~zZ!zj})7Hzxkiz9Gnf5qY7s~*|QVS-**z?@unQ?(Mg*^>FPM|1^ zmpGMH)d$P+86H%4vfUeZU+%_Pd+!8Mq+%0astUwVI~9;GG8G-5sqg3GqwCi7P&J=H z{RidF+IzwK%dc<3ndn^UKdiju?)b%2g_LqSZOO0SV_Y!>ScWgAm89qBgDkHrm3 zzirzsPj8<%aG?G_J5*jkR7Qn(2G*^F?cZEpHBj|vNdh)|5P|K>eRDOr&57M+sKeifi_28K;!Vp&P)rX}koxrrOiIgZ5hCeJ`FA4I!!@!11Oc4f)#)!tSdtQIu zx=F_N#MaFwQ8l!s(AAU*GUAGlTJ+}{3ArnbNFqYN-4J1pt81Z5pU>?Km~PVB!&o?E$8EO7Go`{@cfuwSIPV-jk9_1|Vi;3bJB)z#gd8ffgV?^dm-$2WhH-CpaG0?ZOf5}ve*bMmcJ$v!E++BJ5t?jj| z$*oV}wVOf3Qnc$L7hK1XXzq)#L>m&_ctAE>t@`yd*4Z!k~ z3a}orGZ-3t7GtKhs~+cqL&x)7(gfyoVw9o5mQ04`Z2(3VqmY8Fz~B6huf^CEAt#x; Pix)U!N-|*?xyAkq*A-bw literal 0 HcmV?d00001 diff --git a/apps/mylocation/screenshot_2.png b/apps/mylocation/screenshot_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4c4404540ffebeec33f1a4dbdcdd560d25fbf936 GIT binary patch literal 2642 zcmeHJ`#;l-7oU&G$iu8uQm&1jgrv(Jxg~d%9#3SO%Q8%+2xYdpOv)v!DYpzI)%WW* znIRcVM2SV&a*2J7q-|}5nWxmFKjQoS>3d$UbI$91Ugw8%-sg2*uXpyTlkUH%Z&wF_ zK)-oXdYTX{DIX@@v(?yeSo-tz zdn?Jv{mtkCi#0@;{1ZKN7wG`v`Rk=GzbrEqO867d0;deW9G3V1kX(q>2@oZuoh(ZD z@r7{f@&ne0tH4(*)$Tw|<;|4#K)&ne7v{%pYKwBbv$gB@SW!*X$+0P&${tmeJOj|r3?$L!4T(_Rs^4Mg7Oni$!3J(Bdv2PFT%4{W(F;k; zrHc5(4K3<33(@9d$Y^j&79(|1m=P%WXz9Y!IA^g$O)5!ZY@LJ=(8>nIP5f;js;Fbb|n{LHB zrsVaP>#o+TFXWrZ@>wh0PMGpL{-&d_^x~vCuUK*x2+%q!toDNtij$aY;TtO8{i`Q{ zQP`sMk+1IyKvvDuO?6V6-Qbi;)O1`mggnsH$-M(rBu6C=(1Q2Giq^O$=VFfdT&-Ez zYoEOByl~;k!@n3g;Tbj3~MqIgFV)hLxrQ759}r-RmDZeIG6)k&~z?b#|j;aYQVUaKDU~Ta4V_cK-Xcch~rsBHQ zcqaDS*mqLj2k{sIH{+jsMv0W0mT>t52592=sZ*ZrFfW~?NpZVcX#nNCF1^a7? z6m2qa|FIC;*y1Sz^>Tmwr_4fMmoO@+WnB`t{$4);jqay zCXV>5R$Ale?|J z*xk)Bo8~Pj=9m}<%e+RJzzX@QTHB!knYCcbVKSK;ENKWxOvru zLZW!d@Om2A;9Y_FF$}(lo9<2*sr6U(gsVrtxG>kQ?`U5FkA3k3N(;K~kCrwl!?=5z zaQ!|7mX8M13}gQY zg`I{u3B1~SEX`v7w(POSOW}+C8|~)q8Buc6aQJx9alZ+!#mKzq7MtxWy^>+_hrVHd zV1Zc<;?Gg}w;5T7)+A|Xfo{NO?tQiT>=(q2F6sBk2?J|4m6qKoW!BKV;x@RhJ>N?= zTW^a(Tr-yPVHG>l*K)5sh*>Qit@V)9jGt5^2bNIx8W}5-tn7nH&Hh2?0ag6l_r+ay z-dRkrKh7kEeo;BHFm_E?q^0vUMe6KQV57{iy4jwoo!T^^`P08?R67F0a^uf3?f!K; zsmsi_2+H65!xE{js4mdnov2N@n5!LYVbo+07LbnW>$~<6nYb&BlUP?1dz|*-L6szY zoqKM7ju* zvH-IAXr9NTeM;cqHblapX(OHUs`K)2sXDN6{fn+% zKgN#+994d_uE<5rjF7UjZ>_!gJyFZ^EBaG`)2DGH1q$mRoX@V^ehgqZIH)c+RCsn-8>YCi8^9t1e*ku&Et2^~6_IWCx0k zEmp@A&l~!PzpQ~5`vEvA_9;OKka$5RqQ~~TYGv#eo3#ms4X#fn7QRB{kGO<|oN5zW z=Be2=ea_i@Q7?R!9(k6HMYLT1a8wYDOYLFC%n)syX0eXO!d%Y8WA=N^S}S``l5?w9 z_}pU3CzlH|UM!>;fvh*U=UQUK;=U|0SvrA2U!qwDbfX@jY-D5aD%SFIR|$6wN>MxP z4hD4Otr;jJGH0 z$EfkgZKIa0eKS1JcnzG-OiLv)eTC3^A&sbAIsJazTUjYGK?&UE@ zyuh93&rM@7>jL3Yr)0O)xBA%$SUAQPfb8u((G(3p=qGLw{*V5bOr$EkXP_#pj;2kn Pi$sv8>q(aeXH5D(w(Zo_ literal 0 HcmV?d00001 diff --git a/apps/mylocation/screenshot_3.png b/apps/mylocation/screenshot_3.png new file mode 100644 index 0000000000000000000000000000000000000000..81570670b7988aa92f6e6fedc007c5bedc2a387d GIT binary patch literal 15562 zcmeHL%W~sJ40Nhe<;(s}t~uqHs{I$;{9E~s{FH<4#%n}TA|;M1TjqGl!8CwI4`$@Y z{`K?UKi@e1w)YQv{;{v$-hK!6$>)>Pr>#CQ*6@#WoE0yWU{?Dqgkr`TnlyoyE%@@9nKlCQr&W zU!R-&+fJ*Za6KVPFHGW919Y$bT}d0PS-h*IA$!I+h<8D=0G<=SpjiOV@%}nl{P6R- zV(a$!)x{2A3faG($jr~3xJU%^NnVJI&zR&6(%_Cy;ox|*n98f3a?jCI*F(LwAC`Zl zvHO+4K2G4ZO4MXkq)?^fET7hUI4>K3BQK?DhYNP~aPJzkc>6)$(nPH9V5{mz*38VF z#hV588ck#~_p-G3V^|uYn-h5Rwps~ZG}MSE%JRzUCNKt}5$`eA(AH+J&SiKBY(!dr1$H1mzBN*@!w&t zZ&_YYh@f*o2svWj8!ev13tFf4o2c4X>LA)5Y(RHbh~kO1*IZt-%j&YU>f-$NmG(riPj^|~Id_&##Hn2MJ0C*fi z8eW=RZ|CZE(AaD+_X9|_BMn#h;+=Ww@4{aIBU^ZRZdom`nX8cxVk)l%Hq-p$Du4xA zOrzBTn;A4cmhLg8yMHO0_rv$n?~0)GVp%&5i+9dqY~9~zKxT#w(1udei)FBtwa%+} zC+WFP!b#tnZ}EDD2V6yT)ag>v^Ss!qnq$SQV%J+JLTp65s*)jbC6Y7aj^t&1XrK(1 z4M-?lu0Fh2#-m^b6gI4}p%`v)dXcwCDIH5)Bp6YTGhKm7O@D{S_tbMO>?K|tSyNZk zWerNT@Tyn47y@VU4n_LH8_}U_yB+hjYkfV7_f|#Ky5)Hddxlq+-!gSSAfRmA4&9Kv zC%$C(J+;$#qjG9Q-l_5?55P?@)RfzktQ8KMRPx-};A zTFF%9(qb)L4vu;aO#Di;>z%;Mnmj!_AMoF@>4Bv5QftC+4TDS!H~4toUTdvoin;Gi z9@m>|Gwx^J_jaCUGs!d82-N}-q4MiyBSpGqB4U^uEK*+NJTy3We3>} zFd`dc3vX0X#`rchIGG8&rH&=MtST*4$4)Tc*E^pV^y_yIV>>h26<_5@zwr2+cl`H_kX>>=F7LB=ONaELox)OiA{G0{8v3gXkt{Fs zg3tcBUXubwsUEdIQdxfJy?k7($#Zy1FSSbX@GdP|Eb6sByk{Sd+dZx uGlus8FYwx9qjPmTbG8`H#n5hV$-NiTxw?HXXNzyv_epd!#}*;qB<4S8=}L+K literal 0 HcmV?d00001 diff --git a/apps/mylocation/screenshot_4.png b/apps/mylocation/screenshot_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ffae679c9dd8828f966f5873891f1d6e51961248 GIT binary patch literal 2818 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 '' }, ID_DATE: { calc: () => {var d = (new Date).toString().split(" "); return d[2] + ' ' + d[1] + ' ' + d[3];} }, ID_DAY: { calc: () => {var d = require("locale").dow(new Date).toLowerCase(); return d[0].toUpperCase() + d.substring(1);} }, + ID_SR: { calc: () => 'Sunrise: ' + sunRise }, + ID_SS: { calc: () => 'Sunset: ' + sunSet }, ID_STEP: { calc: () => 'Steps: ' + stepsWidget().getSteps() }, ID_BATT: { calc: () => 'Battery: ' + E.getBattery() + '%' }, ID_MEM: { calc: () => {var val = process.memory(); return 'Ram: ' + Math.round(val.usage*100/val.total) + '%';} }, @@ -169,6 +196,9 @@ Bangle.setUI("clockupdown", btn=> { loadSettings(); loadFonts(); +loadLocation(); +updateSunRiseSunSet(new Date(), location.lat, location.lon); + g.clear(); var secondInterval = setInterval(draw, 1000); draw(); From 070558a0a62027fc67e9d54b45ef81e2166d6fab Mon Sep 17 00:00:00 2001 From: hughbarney Date: Fri, 26 Nov 2021 20:48:27 +0000 Subject: [PATCH 0056/1839] MyLocation - adds menu to set preferred city or setup from GPS --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 8b1fb586e..dc5d748a8 100644 --- a/apps.json +++ b/apps.json @@ -4466,7 +4466,7 @@ "description": "My Locations adds a menu in the Settings app to set your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", "readme": "README.md", "tags": "tool,utility", - "type": "app", + "type": "widget", "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ {"name":"mylocation.settings.js","url":"mylocation.settings.js"} From b426c479a32595b592acc1eb68a202e3ed5f0c17 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Fri, 26 Nov 2021 21:29:46 +0000 Subject: [PATCH 0057/1839] Pastel added dependancy on MyLocation app, display sunrise,sunset times --- apps.json | 3 ++- apps/pastel/ChangeLog | 3 ++- apps/pastel/README.md | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index dc5d748a8..1c4b074dc 100644 --- a/apps.json +++ b/apps.json @@ -4085,9 +4085,10 @@ "id": "pastel", "name": "Pastel Clock", "shortName": "Pastel", - "version": "0.06", + "version": "0.08", "description": "A Configurable clock with custom fonts and background", "icon": "pastel.png", + "dependencies": {"mylocation":"type"}, "screenshots": [{"url":"screenshot_pastel.png"}], "type": "clock", "tags": "clock", diff --git a/apps/pastel/ChangeLog b/apps/pastel/ChangeLog index 6bfd2ce59..2ede0e161 100644 --- a/apps/pastel/ChangeLog +++ b/apps/pastel/ChangeLog @@ -3,5 +3,6 @@ 0.03: Make it work with Gadgetbridge, Notifications fullscreen on a Bangle 2 0.04: Leave space at the bottom for Chrono widget, set back option at first option 0.05: Added 2 new fonts -0.06: COnverted fonts to font modules +0.06: Converted fonts to font modules 0.07: Added info line that cycles on BTN1/BTN3 (or vitual buttons on a bangle 2) +0.08: Added dependancy on MyLocation diff --git a/apps/pastel/README.md b/apps/pastel/README.md index f183005a9..151837a66 100644 --- a/apps/pastel/README.md +++ b/apps/pastel/README.md @@ -8,6 +8,7 @@ * Has a settings menu, change font, enable/disable the grid * On Bangle 1 use BTN1,BTN3 to cycle through the info display (Date, ID, Batt %, Ram % etc) * On Bangle 2 touch the top right/top left to cycle through the info display (Date, ID, Batt %, Ram % etc) +* Uses mylocation.json from MyLocation app to calculate sunrise and sunset times for your location I came up with the name Pastel due to the shade of the grid background. From 21fe6e7ea486ee553bd1bac8399d153c50171380 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Fri, 26 Nov 2021 21:52:05 +0000 Subject: [PATCH 0058/1839] Pastel added dependancy on MyLocation app, display sunrise,sunset times --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 1c4b074dc..f659fcbc4 100644 --- a/apps.json +++ b/apps.json @@ -4088,7 +4088,7 @@ "version": "0.08", "description": "A Configurable clock with custom fonts and background", "icon": "pastel.png", - "dependencies": {"mylocation":"type"}, + "dependencies": {"mylocation":"widget"}, "screenshots": [{"url":"screenshot_pastel.png"}], "type": "clock", "tags": "clock", From 3fbb46b046c65d8d9f1a37b600bddc0ee1e16e03 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sat, 27 Nov 2021 11:23:03 +0000 Subject: [PATCH 0059/1839] Pastel, recalc sunrise,sunset every hour --- apps.json | 2 +- apps/pastel/pastel.app.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index f659fcbc4..322a90d96 100644 --- a/apps.json +++ b/apps.json @@ -4086,7 +4086,7 @@ "name": "Pastel Clock", "shortName": "Pastel", "version": "0.08", - "description": "A Configurable clock with custom fonts and background", + "description": "A Configurable clock with custom fonts and background. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", "icon": "pastel.png", "dependencies": {"mylocation":"widget"}, "screenshots": [{"url":"screenshot_pastel.png"}], diff --git a/apps/pastel/pastel.app.js b/apps/pastel/pastel.app.js index 8007ac031..aa4f6abf8 100644 --- a/apps/pastel/pastel.app.js +++ b/apps/pastel/pastel.app.js @@ -23,6 +23,7 @@ function extractTime(d){ var sunRise = "00:00"; var sunSet = "00:00"; +var drawCount = 0; function updateSunRiseSunSet(now, lat, lon, line){ // get today's sunlight times for lat/lon @@ -175,6 +176,10 @@ function draw() { g.setFontLatoSmall(); g.setFontAlign(0, -1); g.drawString((infoData[infoMode].calc()), w/2, h - 24 - 24); + + if (drawCount % 3600 == 0) + updateSunRiseSunSet(new Date(), location.lat, location.lon); + drawCount++; } // Only update when display turns on @@ -197,7 +202,6 @@ Bangle.setUI("clockupdown", btn=> { loadSettings(); loadFonts(); loadLocation(); -updateSunRiseSunSet(new Date(), location.lat, location.lon); g.clear(); var secondInterval = setInterval(draw, 1000); From 38c6e16010837c73e32022bb7ce999402f1a44b4 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 29 Nov 2021 16:29:34 +0000 Subject: [PATCH 0060/1839] new about pixels --- apps.json | 2 +- apps/about/ChangeLog | 1 + apps/about/app-bangle2.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index d59636f57..925d1f655 100644 --- a/apps.json +++ b/apps.json @@ -135,7 +135,7 @@ { "id": "about", "name": "About", - "version": "0.11", + "version": "0.12", "description": "Bangle.js About page - showing software version, stats, and a collaborative mural from the Bangle.js KickStarter backers", "icon": "app.png", "tags": "tool,system", diff --git a/apps/about/ChangeLog b/apps/about/ChangeLog index 03e920a9a..f5638fdd2 100644 --- a/apps/about/ChangeLog +++ b/apps/about/ChangeLog @@ -9,3 +9,4 @@ 0.09: Actual Bangle.js 1 pixels as of 13 Oct 2021 0.10: Added separate Bangle.js 2 file with Bangle.js 2 kickstarter pixels (as of 28 Oct 2021) 0.11: Bangle.js2: New pixels, btn1 to exit +0.12: Actual pixels as of 29th Nov 2021 diff --git a/apps/about/app-bangle2.js b/apps/about/app-bangle2.js index 32e5bafae..978d36193 100644 --- a/apps/about/app-bangle2.js +++ b/apps/about/app-bangle2.js @@ -6,7 +6,7 @@ var ENV = process.env; var MEM = process.memory(); var s = require("Storage"); -var img = atob("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"); +var img = atob("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n/2wAAABBCQAEGEmBJFoAABIoooxwgPoAddoCEkFFFAEwwAGwAHJIIJBAAAG2AjDAG/n+AABBBBAggXi3/xI13/////4AAABICQDEk0mBAFqABIHCSH2wkgw4FDCCHnAooAoGAAAAAwFttGAAAAGGAkkkkn/ttrADAAAAAX6nPhStv////+mmbYBBCQZY2AGAAACABIoqSookEAAADFCSEnbbbAFigAAAMEAFA2wAAA/q6gEkAA4AAFBBEAkgEHghJiR13////880cYBAIDLLAAAAAkCABAHCSHCAkBBHAJKCDbFArAAEEgkIMkAFAGAAAAvq6DE8AYGPOFAAEAggEUiOOIJbf////+mmbYAAABZZA2wEggiQQQAowoAQCBIHBICIDAFFYA2GEEENMEAFAGAQQYtqSw0kDDAHAFCCEYggcHgJxIAfb////840BJA9FALIAAAggkACCkEnAHACopB/JJJJDbFrDSww0AEAIwAFAkgSTZJmBwwgjbGIOFBJEYkgcAAH/BpbbAAADAAmIQHFoABHMkkEAggAAgkgggEgEDbG222PvvFdCAwwwBJJIAAAAAAQQZBgB2wgjbAAAADAAbADYAUg4FFkjAAHDgE0IQA9FAABMkgAAgEAAkEEABJJJDr2GG2PvvFAoSDADBJJAAGWAAAoABJgBwwAAAAAARP8gYYYYAWg4FIijbDDbkEmQSQAAAAEkkgAAAAgAAAAggAAgjb2222PvvbDbADYbBJJAACiAAAooBhk5YDH/CACCBP8gbADYAUg4BFkjDADDgk0gQQkgAAGAAAGABJg2AAHEHAAEAF2AA1PvvDbAYDDDYBAYAGWAAAoEkA/ADY//6CCARP8gSQAAAbbYAAtrADDDwAmgSQAkkkAYDAFGSIkGAAASkkAggA+228N//AYDDDAAbBAYAbYAAAov/gA/DY446HCCAJJFQFAEkAYAMgSrDDDDSQMEkB4AAwGADAouWIIGAAAW0kA44AFotBJASbaQYDAAGxYYYYYAAos//8HAYD446A6AQABFQFAEAgbYIESrDDAbQBIoQYEgGAAYAYFCWJBwAAASkkAIIkQDAADbabaAA2AAABbbYbYgAtt778AAAA//6/6CAABFQFAEAgYYIEtobAAgSIIGABAAAAGADDDH/JBAAAA4A4ABAigFAASTiaahABgdoBAAAAFtAAAn/gAAtoH/CQSAQIBFSVAEkAbJMgJIBJEgRAIqSA4gAAAYDYYfnAAAHHAAH/AIIkQBQAATjTThABgYqBAAA2ttoAAd8YJAAoA+2SWywBIFtFtEAgYYAA54BAggAAECABkgAAGADADH/AAAHHAAAAAAAigoDAATcccZhhgdqCH/AwssoAAbzYIAFAAGACGAQ4w4w4w4w4bYAAJIBBkkAAACSP/4AAAYAdvQQAAAAAGAAAA/AH+AEAATbjjYgggaCSJJA2ttoAAYYYIAAAA+GAGAwbbgEJMMAAAAAA2wBJAgAg5//J/4AAGAAF/CAAAAGWWWWLI/GH4AoAQQbbbAEAkiSA//AwllgAAYRYJAA3AH2AAGwbbAAG2wAG2wAAOIAAAAEEPJJJP8kkAEUlvCJIAAAwwwwLIAGJJGAACJASQYAAAACAIAA2EkAAAaIYBAA/AHFAAAADAAAwAG2wnOAAEAAAAX4E5/JJJ8nkFEigAC/4AAAwxwwLIAGJB4AAAIIAQb7AwASQYAAAgAkgARIEBAAA/4AAAAHHHEn8gA2AIgAAggAQAH4gAAAJJM/8tEkSAAtqSJAGAGAAAgAIhIEAAIOCG4GAAGFzbYuAgAgACIBtJAAA44EAA5IggEn8gGAwgIM3EACQAAEkAAbe20nkFEAQQ1wAQIIwxwwkgkkkACYAAIIQAYAwwwAQYGAIgAkgRABoAAAAAomgoxgkgEn8gADY5hg+EAAAFtAAH4YGSkkkAICCCGuCQIIAAAAoA222AAAAAJASQ4AG2AAozAGAgAAgIJItAAAAAAECA8gEAAAAAAoFQDPcggAQFFAQAADEkkngBxAQQA1wAJA23gJFAkkkAFwQAQAGAD7AwAQUEAoAkgkgFEkoGDtoooAWSACAQAAAAAHAQYAxggGwFtDbbAAYAE//AIACAAAAAJIOk/JAoAAgAHIUkQAAABJAAAGEgGMIAAAArsJtwztFFFFSSQSQQAkQ/9AoEAGGVQk1AAFroAbYAEngBxFtAA/HABBG4kISQ4EAAAAQQQCCFFotAFFsEtAAAAAFdEMAwDdoooAQSCCCQAmgJIbAkkG2qoG2wADrtoqSJEACAIFkoAAHABGOE4IAAAkkAAAiSgCCAIAIAAAAAAAAH//FoFFAGbbYAAAACACAQAUgSQSX4AGGqsE2ASDbvooABEATQbdkoI/HQAAACQAkkgAAAAAkEgAAFJANGG2GAYAAYHAQQFFAAwZJAAEgkBIAA444QQQX6SSSVUkxwXUgttqSBEAQQYdtBI/AAAAAQCw/X4w84AAgggAQFIINGGAGADADknAEAYAYwwZAH/EEEIAAABJASQSABAiBqsE2ISU8oooBBECACbdAOxICSAAAWyA6S4AigAAgAgAQFIBNGAGGADDD2nGEGD7AGAZBHPEEEIAAAAgAQAQQBkEBVUExwQUgooqSJMgFAYFFhJJSSQAAQCAkkgA84AAgAgCCFIAN2G2GwAYY03A2wXAH/6ZJH/EAEBIAAHHAQASABgkB"); var imgHeight = g.imageMetrics(img).height; var imgScroll = Math.floor(Math.random()*imgHeight); From 22d06c8cf6f6fb7a1e0c899480cb8c40785d81f0 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Mon, 29 Nov 2021 18:45:44 +0000 Subject: [PATCH 0061/1839] Pastel changed dependancy on MyLocation to type app --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 322a90d96..eec32218b 100644 --- a/apps.json +++ b/apps.json @@ -4088,7 +4088,7 @@ "version": "0.08", "description": "A Configurable clock with custom fonts and background. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", "icon": "pastel.png", - "dependencies": {"mylocation":"widget"}, + "dependencies": {"mylocation":"app"}, "screenshots": [{"url":"screenshot_pastel.png"}], "type": "clock", "tags": "clock", From 6510e4b7d2965f34404f8973c5d802adfa933d6c Mon Sep 17 00:00:00 2001 From: hughbarney Date: Mon, 29 Nov 2021 19:02:01 +0000 Subject: [PATCH 0062/1839] Pastel added dependancy on widpedom --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index fa33df5ed..770f2a286 100644 --- a/apps.json +++ b/apps.json @@ -4110,6 +4110,7 @@ "description": "A Configurable clock with custom fonts and background. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", "icon": "pastel.png", "dependencies": {"mylocation":"app"}, + "dependencies": {"widpedom":"app"}, "screenshots": [{"url":"screenshot_pastel.png"}], "type": "clock", "tags": "clock", From 3fa435e57ddde56b59c75074adc0831f9ae2ba67 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Mon, 29 Nov 2021 19:58:19 +0000 Subject: [PATCH 0063/1839] Pastel, MyLocation updated README files --- apps/mylocation/README.md | 4 +--- apps/pastel/README.md | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/mylocation/README.md b/apps/mylocation/README.md index 3b39aa947..6ae1dd530 100644 --- a/apps/mylocation/README.md +++ b/apps/mylocation/README.md @@ -39,6 +39,4 @@ -## Creator - -[Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/) +Written by: [Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/) diff --git a/apps/pastel/README.md b/apps/pastel/README.md index 151837a66..66ae0e189 100644 --- a/apps/pastel/README.md +++ b/apps/pastel/README.md @@ -1,6 +1,6 @@ # Pastel Clock - *a configurable clock with custom fonts and background* + *a configurable clock with custom fonts and background. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times* * Designed specifically for Bangle 1 and Bangle 2 * A choice of 7 different custom fonts @@ -9,12 +9,12 @@ * On Bangle 1 use BTN1,BTN3 to cycle through the info display (Date, ID, Batt %, Ram % etc) * On Bangle 2 touch the top right/top left to cycle through the info display (Date, ID, Batt %, Ram % etc) * Uses mylocation.json from MyLocation app to calculate sunrise and sunset times for your location - +* Uses pedometer widget to get latest step count +* Dependant apps are installed when Pastel installs I came up with the name Pastel due to the shade of the grid background. -## Creator -[Hugh Barney](https://github.com/hughbarney) +Written by: [Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/) ## Lato ![](screenshot_lato.png) From b50faa919a9f8c50687a16435d7db946771b674b Mon Sep 17 00:00:00 2001 From: hughbarney Date: Mon, 29 Nov 2021 20:12:25 +0000 Subject: [PATCH 0064/1839] Pebble - long live the rebellion --- apps.json | 18 ++++- apps/pebble/ChangeLog | 1 + apps/pebble/icons8-sport-shoes-64.png | Bin 0 -> 2522 bytes apps/pebble/pebble.app.js | 103 ++++++++++++++++++++++++++ apps/pebble/pebble.png | Bin 0 -> 1213 bytes apps/pebble/pebble.settings.js | 38 ++++++++++ apps/pebble/pebble_screenshot.png | Bin 0 -> 2799 bytes apps/pebble/pebble_screenshot2.png | Bin 0 -> 2736 bytes apps/pebble/pebble_screenshot3.png | Bin 0 -> 2788 bytes 9 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 apps/pebble/ChangeLog create mode 100644 apps/pebble/icons8-sport-shoes-64.png create mode 100644 apps/pebble/pebble.app.js create mode 100644 apps/pebble/pebble.png create mode 100644 apps/pebble/pebble.settings.js create mode 100644 apps/pebble/pebble_screenshot.png create mode 100644 apps/pebble/pebble_screenshot2.png create mode 100644 apps/pebble/pebble_screenshot3.png diff --git a/apps.json b/apps.json index 770f2a286..cfac33be3 100644 --- a/apps.json +++ b/apps.json @@ -4543,5 +4543,21 @@ "storage": [ {"name":"mylocation.settings.js","url":"mylocation.settings.js"} ] - } + }, + { + "id": "pebble", + "name": "Pebble Clock", + "shortName": "Pebble", + "version": "0.01", + "description": "A pebble style clock to keep the rebellion going", + "icon": "pebble.png", + "dependencies": {"widpedom":"app"}, + "screenshots": [{"url":"screenshot_pebble.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"pebble.app.js","url":"pebble.app.js"}, + {"name":"pebble.img","url":"pebble.icon.js","evaluate":true}, + } ] diff --git a/apps/pebble/ChangeLog b/apps/pebble/ChangeLog new file mode 100644 index 000000000..9db0e26c5 --- /dev/null +++ b/apps/pebble/ChangeLog @@ -0,0 +1 @@ +0.01: first release diff --git a/apps/pebble/icons8-sport-shoes-64.png b/apps/pebble/icons8-sport-shoes-64.png new file mode 100644 index 0000000000000000000000000000000000000000..4ae00db96a02ace82a8f08eb43bbf32a0c08b255 GIT binary patch literal 2522 zcmV<02_^Q4P)^p0K_gw z1`vtanBN840CC8$+eCW@$F4@i1Bt-#o7uUZkXtz34#08V!o^I#dk!{g4V4vT7!3Ns zfG6Mzd=HdcShvqu`WbBmNKHJ8T%jQN&dJz2IClNs7B~xh0VDv&EUe#aES&*yKy+1Q zxs{`nGwz;Vq$Zui*3OP4D;`CuR8mz@CKCj~5AXsUfq&C(+|57+oCGF!X-fd^1*-cP zb2;#_m6ej^k3NN~n|rq}KYo8ZmE~n!oAkg(KnQRNn9)bwJ|PFz1I}IAynxxjK0w=t znEAk5K`^W~QUnHh09Z1s(+yKoaKc=vU;J@7Plfr}vWU?pGxQUFtb z8PHLn>;oe1d2Ah_5m9K2ZM?HOnv(onfQ!It-~?BUZ~>;Zw@(3(D-?vxyq7skAI5uR zK&OBpn20;{B{3hqOJ#8Z08Y-Xj2Rn@w~sGQPA*s}m7V7o7hWXx`@@tL7j`t2051c( z0Aqg{unPF+=oxcZ_}pf^U7TocsAuaF4^ohwaoqrFJ9}nCEN0f?Xk0wJu6drxWF-EZ z1Ko`1C3Qe@mm>wp;|8$J7$_}xDrB&O^ z9V7g??RFo&-nW;wHXZXO4`F7=Kvr&!qe*LE+_YItoIM|aps8VWZ>aFa_2ud`uV@CL{Z!dxB+XyycqHY7~&rYK%2?pGtE`RA3i`qRyy_$ zj!c*`oz%p$RF;=A*j>ZArK8w&=sbxzwYYkCF>l4=*NxTCswb-LfSa$CO_Uno^7tW`G53cnAN(Mask!vJh~Vmx}I zz>7PQ09dkSJ=Q84i|GbU4ddY#Hh28H9nf5r>{`76qaavJv?p%&9?shJn;7ov$H`;g z(W2EdHOPa7(}(fO&SYvEb&MQ8fzZ3dEv|jn{QL14GY-sq6AyOIcN=F0p;Xym=jz7r zG2@vrHv<2Vi5BmGNw23e*E|qcS5=U7_D2-*0c`tI2$>ff*s(tsxm?ae&up}~b_ZdR zOUX@100{4v0eW34b)`j|KKKQjS4Hviib$$Ui!CO+?dd=A^t>tPTg(;p_lFK32m+7X z=Yzku6Kl4g!Dtc)yMGyjhx=Mg_ow)d4e9t8&}o1^W;zXfrjqbhFdL(8!`)FyPSRPP zdteTEsfjl%diuyg5@L_ga``eMke!iAQNaaV9aX&ea3K4R7jh!05_>0SA|G3G!+O`l z*2$&gqg%HO(5U2$9%jq)k;BM*FO)w_bf=~HGOs-u-PigZFqhQ3-!u z?Lh!GJrabq)c~IT`#As>t$qfLy+fb1u8oLRZy>Lvn9p{;*U@f;M28!Ad2ie zRn3l<|H?}{|I;Vw13TZNuCg2tuR#Qi4d&#rBQ#xVB*@2w=Jk)}2S*=b3f{&FuFvEO0Tcg}Ri>lXb3WHR1=+?TklMsgC*aPq`)0zxLB zQdpso%aF@{zGA8_E#}~^4?rekR`>!gHP&+`E*6;#-uiPWMU~CG`B?@snT+MnZbCMo z_f?o6iU^{JNf6PSjOa}QI)jl*&CR68e#^P9KBugG;FZZ_xVYXzU2P3O;m@vm95o77 z%^t|6Jq4UT9D}>x=w5Yh@0JZ1^lf!*SMx&9X(>$2q-pazQXVK|R1k4Oa z@El5RO0fEs`p1yBpP#%DJ& zafD-!LBq$nvT08NrP=Ad>P&vZkL1K3$4aRrFmy8IC54m}T)zXg4Z*8Huv7Y+UVrokYDalHuI5QQ4?#h;;*PtN;1y8_t%(P_UV~T#b?scf)PDzQ^_)_Ibc&x?Fe%T?fH(z^l5V z3^&h#m;?cNA4cSUM- literal 0 HcmV?d00001 diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js new file mode 100644 index 000000000..5ef8099c6 --- /dev/null +++ b/apps/pebble/pebble.app.js @@ -0,0 +1,103 @@ +// inspired by +//https://apps.rebble.io/en_US/application/55cf75fc61e031bb4b000025?dev_settings=true§ion=watchfaces + +Graphics.prototype.setFontQahiri = function(scale) { + // Actual height 60 (60 - 1) + g.setFontCustom(atob("AAAAAAAAfAAAAAAAAAAAAP4AAAAAAAAAAAD/AAAAAAAAAAAB/wAAAAAAAAAAAf8AAAAAAAAAAAH/AAAAAAAAAAAA/wAAAAAAAAAAAH4AAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAB8AAAAAAAAAAAD/gAAAAAAAAAAH/4AAAAAAAAAAP/8AAAAAAAAAAP/4AAAAAAAAAAf/4AAAAAAAAAA//wAAAAAAAAAB//gAAAAAAAAAD//AAAAAAAAAAD//AAAAAAAAAAH/+AAAAAAAAAAP/8AAAAAAAAAAf/4AAAAAAAAAAf/4AAAAAAAAAA//wAAAAAAAAAB//gAAAAAAAAAD//AAAAAAAAAAH/+AAAAAAAAAAH/+AAAAAAAAAAP/8AAAAAAAAAAH/4AAAAAAAAAAB/wAAAAAAAAAAAPwAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD/AAAD/AAAAAAA/wAAA/wAAAAAAP8AAAP8AAAAAAD/AAAD/AAAAAAA/wAAA/wAAAAAAP8AAAP8AAAAAAD/AAAD/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAH///gH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///AAAAAAAAAAP//wAAAAAAAAAD//8AAAAAAAAAA///AAAAAAAAAAP//wAAAAAAAAAD//8AAAAAAAAAA///AAAAAAAAAAP//wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAH8A///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAH8A///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+AAfAAAAAAAAAfwAP4AAAAAAAAP8AD/AAAAAAAAD/gB/wAAAAAAAA/4Af8AAAAAAAAP+AH/AAAAAAAAD/AA/wAAAAAAAAfgAH4AAAAAAAABwAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("DR0bDBsbGxsbGxsbDQ=="), 80+(scale<<8)+(1<<16)); +} + +const SETTINGS_FILE = "pebble.json"; +let settings; + +function loadSettings() { + settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green'}; +} + +var img = require("heatshrink").decompress(atob("oFAwkGswA/AH4A/AH4A/AH4A/AFEAD74gdsAfBELlggMhD70iILsAiUAIKQRBgxAHgUiIKQQJUAMSD4JBQsBVBIAq/DEAJBCJ45VHkAxEDwKfDIIUREBq2BmcQCAQeCkczmRBEiAgND4MxSoYGBAAQgCAAohKDARhBG4IeDEAQ8BAA5fJABgpBgFDgEiQgJEHT4IeMmMBkMFAYJJDEQaYDiYfMkECiEEoEDBAX//8ykJsBD4MAWwIALiBeCqAyDn//BoYgBgAeMYAMhgE0CRIOBD58BkEEmCRKkEGD5szkUQqdASJUxD4MAgKBKmUigFEGJZgBAATODFw0CkEBmoOJAAQdB7owBOBDdCgbdED5fd6pRIgDdCeBkxD4fdeAgNEkMFmheLdgIfE6BgGmDdCoDdKDwYfD6gzGiBeBrpLHXYUQXIMgD4NND4SAFZgMRgAKBPwroBBYIeBIAL/CADESL4VmsAcWgMRkQeDAAMAkQAWMAQeCD4MSDqqdBDwgfBAC8GDwiAXDowA/AH4A/AH4A/AH4A/AEA")); + +const h = g.getHeight(); +const w = g.getWidth(); +const ha = 2*h/5 - 8; +const h2 = 3*h/5 - 10; +const h3 = 7*h/8; + +function draw() { + var date = new Date(); + var da = date.toString().split(" "); + //var timeStr = require("locale").time(date,1); // causes screen corruption ??? + var timeStr = da[4].substr(0,5); + const t = 6; + + g.reset(); + g.setColor(settings.bg); + g.fillRect(0, 0, w, h2 - t); + + // contrast bar + g.setColor(g.theme.fg); + g.fillRect(0, h2 - t, w, h2); + + // day and steps + g.setColor('#000'); // really needs to be black regardless of theme + g.setFont('Vector', 22); + g.setFontAlign(0, -1); + g.drawString(da[0], w/4, ha); // day of week + g.drawString(getSteps(), 3*w/4, ha); + + // time + g.setColor(g.theme.bg); + g.fillRect(0, h2, w, h3); + g.setFontQahiri(); + g.setFontAlign(0, -1); + g.setColor(g.theme.fg); + g.drawString(timeStr, w/2, h2 - 8); + + // contrast bar + g.setColor(g.theme.fg); + g.fillRect(0, h3, w, h3 + t); + + // the bottom + g.setColor(settings.bg); + g.fillRect(0, h3 + t, w, h); + + g.setColor(settings.bg); + g.drawImage(img, w/2 + ((w/2) - 64)/2, 10, { scale: 1 }); + drawCalendar(((w/2) - 48)/2, 10, 48, 4, da[2]); +} + +// at x,y width:wi thicknes:th +function drawCalendar(x,y,wi,th,str) { + g.setColor(g.theme.fg); + g.fillRect(x, y, x + wi, y + wi); + g.setColor(g.theme.bg); + g.fillRect(x + th, y + th, x + wi - th, y + wi - th); + g.setColor(g.theme.fg); + + var hook_t = 6; + // first calendar hook, one third in + g.fillRect(x + (wi/3) - (th/2), y - hook_t, x + wi/3 + th - (th/2), y + hook_t); + // second calendar hook, two thirds in + g.fillRect(x + (2*wi/3) -(th/2), y - hook_t, x + 2*wi/3 + th - (th/2), y + hook_t); + + g.setFont('Vector', 22); + g.setFontAlign(0, 0); + g.drawString(str, x + wi/2 + th/2, y + wi/2 + th/2); +} + +function getSteps() { + if (WIDGETS.wpedom !== undefined) { + return WIDGETS.wpedom.getSteps(); + } + return '????'; +} + +g.clear(); +Bangle.loadWidgets(); +/* + * we are not drawing the widgets as we are taking over the whole screen + * so we will blank out the draw() functions of each widget + */ +for (var wd of WIDGETS) {wd.draw=()=>{};} +loadSettings(); +setInterval(draw, 15000); // refresh every 15s +draw(); +Bangle.setUI("clock"); diff --git a/apps/pebble/pebble.png b/apps/pebble/pebble.png new file mode 100644 index 0000000000000000000000000000000000000000..10f5adb56b224f3e4d037c4d195fbd9efc81b959 GIT binary patch literal 1213 zcmV;u1Va0XP)POM$%3@Whhhyn@nYhxDeg-e<-cZ zYFr2k?%buN)IY$D3u)c7&`lO@rMoJkr~#QIf+Nxtsa1-};Ey=&+{^zdH@zOnM{mX zvjtWIh=|(&%XQtCm^E8qH2}cN%z6O8ZE6bK^H45MbUEA#JEV9`wMn*=ov6V^% zySuwkO0~5~DF?#<%d&1sDYbW0Hk-xj>T1XM!^1;VDwVeD28LA&YzBCqmmwl;+y4GO zgb;{C^xd7DoZ$HQ*iU*PlgY#ig+iSt(^m8u_dq(G-UG14rPmA*y;>|5zciuESp-cK zzzd8G0~P~16+jM57D5&SEX%sZrKQ7UAq-RlmX?-oDy4Ra==sOnq?EQ&YLqXv|L}5|Ola!1|954-`%Wb(F@@^;gu`v9KmHh$=b zz?A|0PN3hg)_~-=MDC3mBG9he1EGlU<1aQo_~dDZ%=}?Bz_u0A^B$@-pn9+O6{;nG zYf}<`Kd>0H)5AUs5CP97fT*MJ>ls1HVDZr?Fg>Z@^Z2lhdcFPy5q)~`|M@n#Ym7~U z@i=f}MB(%|LZi#=!uS}FOsYUTu4=XV)%yDS`#mKI!$r`xf!P^_vHy8YA_Oo!r7#)r z!*gJK77zlsHtGN2E=(GYo6bbfrL6?V#{kEEG$bCJKfoG|15-%_#@%gTE_Ep!jRH5W zKPrx~n8GvTm)X0XOWzAv5#aiC_;mso1HT!XnVETOb91x#hsS?5Ha6yc10G}G4G==a z0W_D;`+?$l(-}Oj4Cr?P{buM5U@d|Tm+;LG`eQJ?aQA2PHJY`D-~SMJ@1qG$N#hLt z5V$g+-wE`afj8jn?CfJ9#B)u53qj%sekt5&H16ecxu1HCANV^UEJJTVs3G8Y_SYob z=a51f;5ZH($KlGQF9aO|PtK#9bBHKZPJs*{qGFiNOdzGa6DB^;5D-GVDW%+j=2&bW z4obR2luslQ`(eacDoQGqdX0!a=g{)uPN`Hf^6CuNH258Wo{y_`LBW(Tivi_w`7Z!> zIka>rrJig9&iR&6s|Cxlj2XbW7bpP8>Kf+e=CHQ52Fud_-hX;}itX)f?MqVtJlnQI zRr*e_8K9IZ_^r}bR#vdQyxcMV;NU>}(iDKQsrQ8d-aFu;5Vn2IdwY9OO8KrDkB*Ky zy)$y0J8xG=4+z` b5C9$mizYm;5j?(%00000NkvXXu0mjfggZkP literal 0 HcmV?d00001 diff --git a/apps/pebble/pebble.settings.js b/apps/pebble/pebble.settings.js new file mode 100644 index 000000000..b60600316 --- /dev/null +++ b/apps/pebble/pebble.settings.js @@ -0,0 +1,38 @@ +(function(back) { + const SETTINGS_FILE = "pebble.json"; + + // initialize with default settings... + let s = {'bg': '#0f0', 'color': 'Green'} + + // ...and overwrite them with any saved values + // This way saved values are preserved if a new version adds more settings + const storage = require('Storage') + let settings = storage.readJSON(SETTINGS_FILE, 1) || s; + const saved = settings || {} + for (const key in saved) { + s[key] = saved[key] + } + + function save() { + settings = s + storage.write(SETTINGS_FILE, settings) + } + + var color_options = ['Green','Orange','Cyan','Perple','Red','Blue']; + var bg_code = ['#0f0','#ff0','#0ff','#f0f','#f00','#00f']; + + E.showMenu({ + '': { 'title': 'Pebble Clock' }, + '< Back': back, + 'Colour': { + value: 0 | color_options.indexOf(s.color), + min: 0, max: 5, + format: v => color_options[v], + onchange: v => { + s.color = color_options[v]; + s.bg = bg_code[v]; + save(); + }, + } + }); +}) diff --git a/apps/pebble/pebble_screenshot.png b/apps/pebble/pebble_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..d618368db84657fdc60e478c4507fac2bb9c931f GIT binary patch literal 2799 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 Z1IS-lm>yN9{UNZe0B!4JQ)!J${WlQI5-k7# literal 0 HcmV?d00001 From 6642b216066519d90e1bb0b46c1c8b731ff270b8 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Mon, 29 Nov 2021 20:27:25 +0000 Subject: [PATCH 0065/1839] added pebble icon --- apps/pebble/pebble.app.js | 35 +++++++++++++++++++++++++---------- apps/pebble/pebble.icon.js | 1 + 2 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 apps/pebble/pebble.icon.js diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 5ef8099c6..6b7f7b492 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -1,5 +1,3 @@ -// inspired by -//https://apps.rebble.io/en_US/application/55cf75fc61e031bb4b000025?dev_settings=true§ion=watchfaces Graphics.prototype.setFontQahiri = function(scale) { // Actual height 60 (60 - 1) @@ -21,13 +19,26 @@ const ha = 2*h/5 - 8; const h2 = 3*h/5 - 10; const h3 = 7*h/8; +let batterWarning = false; + function draw() { - var date = new Date(); - var da = date.toString().split(" "); - //var timeStr = require("locale").time(date,1); // causes screen corruption ??? - var timeStr = da[4].substr(0,5); + let date = new Date(); + let da = date.toString().split(" "); + //let timeStr = require("locale").time(date,1); // causes screen corruption ??? + let timeStr = da[4].substr(0,5); const t = 6; + // turn the warning on once we have dipped below 30% + if (E.getBattery() < 30) + batterWarning = true; + + // turn the warning off once we have dipped above 40% + if (E.getBattery() > 40) + batterWarning = false; + + // for testing only + batterWarning = true; + g.reset(); g.setColor(settings.bg); g.fillRect(0, 0, w, h2 - t); @@ -37,14 +48,18 @@ function draw() { g.fillRect(0, h2 - t, w, h2); // day and steps - g.setColor('#000'); // really needs to be black regardless of theme + if (settings.color == 'Blue' || settings.color == 'Red') + g.setColor('#fff'); // white on blue or red best contrast + else + g.setColor('#000'); // otherwise black regardless of theme + g.setFont('Vector', 22); g.setFontAlign(0, -1); g.drawString(da[0], w/4, ha); // day of week g.drawString(getSteps(), 3*w/4, ha); // time - g.setColor(g.theme.bg); + g.setColor(!batteryWarning ? g.theme.bg ? '#f00'); g.fillRect(0, h2, w, h3); g.setFontQahiri(); g.setFontAlign(0, -1); @@ -72,7 +87,7 @@ function drawCalendar(x,y,wi,th,str) { g.fillRect(x + th, y + th, x + wi - th, y + wi - th); g.setColor(g.theme.fg); - var hook_t = 6; + let hook_t = 6; // first calendar hook, one third in g.fillRect(x + (wi/3) - (th/2), y - hook_t, x + wi/3 + th - (th/2), y + hook_t); // second calendar hook, two thirds in @@ -96,7 +111,7 @@ Bangle.loadWidgets(); * we are not drawing the widgets as we are taking over the whole screen * so we will blank out the draw() functions of each widget */ -for (var wd of WIDGETS) {wd.draw=()=>{};} +for (let wd of WIDGETS) {wd.draw=()=>{};} loadSettings(); setInterval(draw, 15000); // refresh every 15s draw(); diff --git a/apps/pebble/pebble.icon.js b/apps/pebble/pebble.icon.js new file mode 100644 index 000000000..ecd7feb7f --- /dev/null +++ b/apps/pebble/pebble.icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("oFAwgNKiIAIFqofegIf/DAUzAAMyAwUQD60T/4ACD7Q/cPxIf/YCofcDhYiSXYYfuUZgf/D/4f/D6USkUgD/4fuogAID6vtDw/UD6vu6geF73kb6vuEAtN9wfYMIneD7JADDwIfaIAJdBD7YgBHwQfbAAgfkf6Qf/D/4feogAID6oAND/4f/iAdJD/4f/D/4fUDxYABD74iODiAftTZgfnYYczAAMyD7UT/4ACH/S+bD8DAKD9Y=")) From 4d107148c78d5a7211e2e08664052014059b5371 Mon Sep 17 00:00:00 2001 From: jeffyactive Date: Mon, 29 Nov 2021 21:31:53 -0500 Subject: [PATCH 0066/1839] Added SensiBLE app --- apps.json | 17 ++++ apps/sensible/ChangeLog | 1 + apps/sensible/README.md | 35 +++++++ apps/sensible/sensible-icon.js | 1 + apps/sensible/sensible.js | 163 +++++++++++++++++++++++++++++++++ apps/sensible/sensible.png | Bin 0 -> 1716 bytes 6 files changed, 217 insertions(+) create mode 100644 apps/sensible/ChangeLog create mode 100644 apps/sensible/README.md create mode 100644 apps/sensible/sensible-icon.js create mode 100644 apps/sensible/sensible.js create mode 100644 apps/sensible/sensible.png diff --git a/apps.json b/apps.json index 1c614c592..5ccbecd98 100644 --- a/apps.json +++ b/apps.json @@ -4526,5 +4526,22 @@ {"name":"93dub.app.js","url":"app.js"}, {"name":"93dub.img","url":"app-icon.js","evaluate":true} ] + }, + { + "id": "sensible", + "name": "SensiBLE", + "shortName": "SensiBLE", + "version": "0.01", + "description": "Collect, display and advertise real-time sensor data.", + "icon": "sensible.png", + "type": "app", + "tags": "tool,sensors", + "supports" : [ "BANGLEJS2" ], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + { "name": "sensible.app.js", "url": "sensible.js" }, + { "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true } + ] } ] diff --git a/apps/sensible/ChangeLog b/apps/sensible/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/sensible/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/sensible/README.md b/apps/sensible/README.md new file mode 100644 index 000000000..f79b61aea --- /dev/null +++ b/apps/sensible/README.md @@ -0,0 +1,35 @@ +# Sensible + +Collect all the sensor data from the Bangle.js 2, display the live readings in menu pages, and broadcast in Bluetooth Low Energy (BLE) advertising packets to any listening devices in range. + + +## Usage + +The advertising packets will be recognised by [Pareto Anywhere](https://www.reelyactive.com/pareto/anywhere/) open source middleware and any other program which observes the standard packet types. Also convenient for testing individual sensors of the Bangle.js 2 via the menu interface. + + +## Features + +Currently implements: +- Accelerometer +- Barometer +- GPS +- Heart Rate Monitor +- Magnetometer + +in the menu display but NOT YET in Bluetooth Low Energy advertising (which will be implemented in a subsequent version). + + +## Controls + +Browse and control sensors using the standard Espruino menu interface. + + +## Requests + +[Contact reelyActive](https://www.reelyactive.com/contact/) for support/updates. + + +## Creator + +Developed by [jeffyactive](https://github.com/jeffyactive) of [reelyActive](https://www.reelyactive.com) diff --git a/apps/sensible/sensible-icon.js b/apps/sensible/sensible-icon.js new file mode 100644 index 000000000..f904fc7f3 --- /dev/null +++ b/apps/sensible/sensible-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkG/4AG+cilGIxGCkU/B44AGmQUBAAsjCyoYN+QWJAAMvCxsjLQXzG4gYIOIZwG+YLDCw34BRIkFx4JFHQRDElGCJYgOCFw5RCPQwJFGAg4BIoSRIDAQQEG4YLBHgYAGJQIjCJ4RGBDoU4SIqNDwYwDJAQEDFwSRGDAQfBFQgIDFwQtDRoowBAgQDEDYQzC7oACTogrEA4IfF/4WDDAY/Fx4CCEYQbB/oXF74TDCAYGBUoIDDCwowCUoIkBAYSABGwIDCLogADBIKMCAYRODLwRGGJAaMFPwghBnoXJHoJ8DF4Q5DC5HTKogVBgAAFpoXH6oQGAA1dC7/UC5sNC4/dCA0QAwsEC50BC40AC5FQC4sgMB4XFgUwC40FC4/QBwkD+B5HDA6oFh/xSREFqtVbogMEj/yVxkFMwRgEl//Y5sAqhgF///SA4AHghgDgQXBPBAAHrpICh4XBMBoADC4ReBAALxHABUBCwX/bI4AKgYXD+YXRn4XDSKCNDAAZ5QOoZhSLohhESRkBLopJQIo4YOCxYYCJQ0BCxoACmURCoMRkYOI")) \ No newline at end of file diff --git a/apps/sensible/sensible.js b/apps/sensible/sensible.js new file mode 100644 index 000000000..eaebd5c2b --- /dev/null +++ b/apps/sensible/sensible.js @@ -0,0 +1,163 @@ +/** + * Copyright reelyActive 2021 + * We believe in an open Internet of Things + */ + + +// Non-user-configurable constants +const APP_ID = 'sensible'; + + +// Global variables +let acc, bar, hrm, mag; +let isAccMenu, isBarMenu, isGpsMenu, isHrmMenu, isMagMenu = false; +let barEnabled, gpsEnabled, hrmEnabled, magEnabled = true; + + +// Menus +let mainMenu = { + "": { "title": "-- SensiBLE --" }, + "Acceleration": function() { E.showMenu(accMenu); isAccMenu = true; }, + "Barometer": function() { E.showMenu(barMenu); isBarMenu = true; }, + "GPS": function() { E.showMenu(gpsMenu); isGpsMenu = true; }, + "Heart Rate": function() { E.showMenu(hrmMenu); isHrmMenu = true; }, + "Magnetometer": function() { E.showMenu(magMenu); isMagMenu = true; } +}; +let accMenu = { + "": { "title" : "- Acceleration -" }, + "State": { value: "On" }, + "x": { value: null }, + "y": { value: null }, + "z": { value: null }, + "<-": function() { E.showMenu(mainMenu); isAccMenu = false; }, +}; +let barMenu = { + "": { "title" : "- Barometer -" }, + "State": { + value: barEnabled, + format: v => v ? "On" : "Off", + onchange: v => { barEnabled = v; Bangle.setBarometerPower(v, APP_ID); } + }, + "Altitude": { value: null }, + "Press": { value: null }, + "Temp": { value: null }, + "<-": function() { E.showMenu(mainMenu); isBarMenu = false; }, +}; +let gpsMenu = { + "": { "title" : "- GPS -" }, + "State": { + value: gpsEnabled, + format: v => v ? "On" : "Off", + onchange: v => { gpsEnabled = v; Bangle.setGPSPower(v, APP_ID); } + }, + "Lat": { value: null }, + "Lon": { value: null }, + "Altitude": { value: null }, + "Satellites": { value: null }, + "HDOP": { value: null }, + "<-": function() { E.showMenu(mainMenu); isGpsMenu = false; }, +}; +let hrmMenu = { + "": { "title" : "- Heart Rate -" }, + "State": { + value: hrmEnabled, + format: v => v ? "On" : "Off", + onchange: v => { hrmEnabled = v; Bangle.setHRMPower(v, APP_ID); } + }, + "BPM": { value: null }, + "Confidence": { value: null }, + "<-": function() { E.showMenu(mainMenu); isHrmMenu = false; }, +}; +let magMenu = { + "": { "title" : "- Magnetometer -" }, + "State": { + value: magEnabled, + format: v => v ? "On" : "Off", + onchange: v => { magEnabled = v; Bangle.setCompassPower(v, APP_ID); } + }, + "x": { value: null }, + "y": { value: null }, + "z": { value: null }, + "Heading": { value: null }, + "<-": function() { E.showMenu(mainMenu); isMagMenu = false; }, +}; + + +// Update acceleration +Bangle.on('accel', function(newAcc) { + acc = newAcc; + + if(isAccMenu) { + accMenu.x.value = acc.x.toFixed(2); + accMenu.y.value = acc.y.toFixed(2); + accMenu.z.value = acc.z.toFixed(2); + E.showMenu(accMenu); + } +}); + +// Update barometer +Bangle.on('pressure', function(newBar) { + bar = newBar; + + if(isBarMenu) { + barMenu.Altitude.value = bar.altitude.toFixed(1) + 'm'; + barMenu.Press.value = bar.pressure.toFixed(1) + 'mbar'; + barMenu.Temp.value = bar.temperature.toFixed(1) + 'C'; + E.showMenu(barMenu); + } +}); + +// Update GPS +Bangle.on('GPS', function(newGps) { + gps = newGps; + + if(isGpsMenu) { + gpsMenu.Lat.value = gps.lat.toFixed(4); + gpsMenu.Lon.value = gps.lon.toFixed(4); + gpsMenu.Altitude.value = gps.alt + 'm'; + gpsMenu.Satellites.value = gps.satellites; + gpsMenu.HDOP.value = (gps.hdop * 5).toFixed(1) + 'm'; + E.showMenu(gpsMenu); + } +}); + +// Update heart rate monitor +Bangle.on('HRM', function(newHrm) { + hrm = newHrm; + + if(isHrmMenu) { + hrmMenu.BPM.value = hrm.bpm; + hrmMenu.Confidence.value = hrm.confidence + '%'; + E.showMenu(hrmMenu); + } +}); + +// Update magnetometer +Bangle.on('mag', function(newMag) { + mag = newMag; + + if(isMagMenu) { + magMenu.x.value = mag.x; + magMenu.y.value = mag.y; + magMenu.z.value = mag.z; + magMenu.Heading.value = mag.heading.toFixed(1); + E.showMenu(magMenu); + } +}); + + +// Special function to handle display switch on +//Bangle.on('lcdPower', (on) => { +// if(on) { +// E.showMenu(mainMenu); +// } +//}); + + +// On start: +g.clear(); +Bangle.setBarometerPower(true, APP_ID); +Bangle.setGPSPower(true, APP_ID); +Bangle.setHRMPower(true, APP_ID); +Bangle.setCompassPower(true, APP_ID); +E.showMenu(mainMenu); \ No newline at end of file diff --git a/apps/sensible/sensible.png b/apps/sensible/sensible.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e3dfbef76d1f4d89f0836f150715a1a796e870 GIT binary patch literal 1716 zcmV;l221&gP);L88V%$8I>Vz!-GZ43L{7;uQ&8ysK#o0edR-0 zk;iMxjUc2NN@yDDaCaJvM}rMJ)x7=Z=f!20r|+*WuD(`xv+1h6x$RyD0vGs+B$iNs zGIcKq6AO-joa%MMyCHi^+vsnL)O6!B517tc9BnSz;0-84@tc_k)I6gy3L!xoy5Pmo z-~T!yQVR%0{KoRL*L&D)Eu6V-LpvcHmXZ%4TB z{}_r-zq{$+s5PaL%gj;fW?a0p@!iTW^FcP5P ztD;ju$}t8iRse}-lTB=CcJ3iDFBrn{dm_=(w&}zL)`p|;c%p|CN2&74Ew(Da<>YVt z$=CkIU##G*fAMa`;X?8A>1NgrD*1uUIdPFK!GJgg1Vf9>m26?;Hzn*rzSG)1B(0Dw zMX%axlb?vX^4n`By5>H{f5EY6`!dLuIfcJ=hE<{E)m1+;5)d{yrMU_r$g!nGMJJKu z+?}06Q#{XOZsjG$g)zhO*c)q8i?rZqy!-uIav$nw+BAc2mu@Q>qh$L8S|+ir>XOH6 zaz4y(RhC;U_0*yQ_FA~r?36zNm~|3|?TT|jxY~g_9BD7{Ez%r9JEHRkYxl6< z8;;hox(QjovV2+h_PEUp)vCV3edI^6w@kK4AZJ1lW%-HU6>%>w^L*}L$5`FK?wt%z z*(J@S);sRG{nV1a!?|z}-zl_%1XLm?$e9pMA~W#fk^*jMs%IFm@q_mZOO9J#Cbd@W zQ0wW6%g056vFpkhEqjGQlqClz<#U*l>~~H5WlI;ze)qgarev3i$^UZaP$hj~GpCCT zpZs)i#L_}B4*hXnOhS}t!3-A`7RKpA-rH13XJo`uDlLSDhH`;{fi$gw4P&U1&d451 zsk9)N(QjzpNUEeWj1wr876dc;Z`rW^T&GG*Pn>z5QfWaj6BQLj)7mJWM8)((%N(v> zUrOZ_f|48P(Gh;|5bIuMo^6BqY$ZPfQ%jxjv_QJ;s{Rl*cOsGbWRX zrhCGeaL)P>mGm7AA9DeHD32O~na0M(K7Dl5DlssSTOPyNKc&JxVtP-{Dr~@v@PQT^ zt9x=Ofj>QVurLl*#BjOeg(#oQU7ba(h*A9k=lg%d1}}awW@Tm3#fJm-Z*qh%56PYV z@C8~a2W&`&>~?!lP!L`34PZ;+pX2t%NdpZ2`aeo*M8E)SNQMA|!9YuT6(d8X8Mbvi zT@nEUq7%uG)oKk64yIMT4NRk&>D+t6X&%xrpfCiiUcH(Y`T>vhKu3*HU!UH8sU&l70XcZxyN5a0ET_xia5A$f`k zd>P`qW&wsougpx4fJ%PCy`l$0A{rVR5)%_2_A;4=!JcKF Date: Mon, 29 Nov 2021 21:48:30 -0500 Subject: [PATCH 0067/1839] Corrected variable initialisation --- apps.json | 2 +- apps/sensible/ChangeLog | 1 + apps/sensible/sensible.js | 45 +++++++++++++++++++-------------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/apps.json b/apps.json index 5ccbecd98..a5c9263d2 100644 --- a/apps.json +++ b/apps.json @@ -4531,7 +4531,7 @@ "id": "sensible", "name": "SensiBLE", "shortName": "SensiBLE", - "version": "0.01", + "version": "0.02", "description": "Collect, display and advertise real-time sensor data.", "icon": "sensible.png", "type": "app", diff --git a/apps/sensible/ChangeLog b/apps/sensible/ChangeLog index 5560f00bc..ba597a22f 100644 --- a/apps/sensible/ChangeLog +++ b/apps/sensible/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: Corrected variable initialisation diff --git a/apps/sensible/sensible.js b/apps/sensible/sensible.js index eaebd5c2b..c569ff720 100644 --- a/apps/sensible/sensible.js +++ b/apps/sensible/sensible.js @@ -10,8 +10,15 @@ const APP_ID = 'sensible'; // Global variables let acc, bar, hrm, mag; -let isAccMenu, isBarMenu, isGpsMenu, isHrmMenu, isMagMenu = false; -let barEnabled, gpsEnabled, hrmEnabled, magEnabled = true; +let isAccMenu = false; +let isBarMenu = false; +let isGpsMenu = false; +let isHrmMenu = false; +let isMagMenu = false; +let isBarEnabled = true; +let isGpsEnabled = true; +let isHrmEnabled = true; +let isMagEnabled = true; // Menus @@ -34,9 +41,9 @@ let accMenu = { let barMenu = { "": { "title" : "- Barometer -" }, "State": { - value: barEnabled, + value: isBarEnabled, format: v => v ? "On" : "Off", - onchange: v => { barEnabled = v; Bangle.setBarometerPower(v, APP_ID); } + onchange: v => { isBarEnabled = v; Bangle.setBarometerPower(v, APP_ID); } }, "Altitude": { value: null }, "Press": { value: null }, @@ -46,9 +53,9 @@ let barMenu = { let gpsMenu = { "": { "title" : "- GPS -" }, "State": { - value: gpsEnabled, + value: isGpsEnabled, format: v => v ? "On" : "Off", - onchange: v => { gpsEnabled = v; Bangle.setGPSPower(v, APP_ID); } + onchange: v => { isGpsEnabled = v; Bangle.setGPSPower(v, APP_ID); } }, "Lat": { value: null }, "Lon": { value: null }, @@ -60,9 +67,9 @@ let gpsMenu = { let hrmMenu = { "": { "title" : "- Heart Rate -" }, "State": { - value: hrmEnabled, + value: isHrmEnabled, format: v => v ? "On" : "Off", - onchange: v => { hrmEnabled = v; Bangle.setHRMPower(v, APP_ID); } + onchange: v => { isHrmEnabled = v; Bangle.setHRMPower(v, APP_ID); } }, "BPM": { value: null }, "Confidence": { value: null }, @@ -71,9 +78,9 @@ let hrmMenu = { let magMenu = { "": { "title" : "- Magnetometer -" }, "State": { - value: magEnabled, + value: isMagEnabled, format: v => v ? "On" : "Off", - onchange: v => { magEnabled = v; Bangle.setCompassPower(v, APP_ID); } + onchange: v => { isMagEnabled = v; Bangle.setCompassPower(v, APP_ID); } }, "x": { value: null }, "y": { value: null }, @@ -146,18 +153,10 @@ Bangle.on('mag', function(newMag) { }); -// Special function to handle display switch on -//Bangle.on('lcdPower', (on) => { -// if(on) { -// E.showMenu(mainMenu); -// } -//}); - - -// On start: +// On start: enable sensors and display main menu g.clear(); -Bangle.setBarometerPower(true, APP_ID); -Bangle.setGPSPower(true, APP_ID); -Bangle.setHRMPower(true, APP_ID); -Bangle.setCompassPower(true, APP_ID); +Bangle.setBarometerPower(isBarEnabled, APP_ID); +Bangle.setGPSPower(isGpsEnabled, APP_ID); +Bangle.setHRMPower(isHrmEnabled, APP_ID); +Bangle.setCompassPower(isMagEnabled, APP_ID); E.showMenu(mainMenu); \ No newline at end of file From 8775a6f3392fedbb2385dde7558254ae5ba559ec Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:24:43 +0100 Subject: [PATCH 0068/1839] Create ChangeLog --- apps/poweroff/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/poweroff/ChangeLog diff --git a/apps/poweroff/ChangeLog b/apps/poweroff/ChangeLog new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/apps/poweroff/ChangeLog @@ -0,0 +1 @@ + From c822b62789b269d9f1732e3e664a4670dd4d233a Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:36:28 +0100 Subject: [PATCH 0069/1839] Create app.js --- apps/poweroff/app.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 apps/poweroff/app.js diff --git a/apps/poweroff/app.js b/apps/poweroff/app.js new file mode 100644 index 000000000..303e78d03 --- /dev/null +++ b/apps/poweroff/app.js @@ -0,0 +1,13 @@ +g.clear(); + +g.setFont("6x8",2).setFontAlign(0,0); + var x = g.getWidth()/2; + var y = g.getHeight()/2 + 10; + g.drawString("Powering off...", x, y); + +setTimeout(function() { + if (Bangle.softOff) Bangle.softOff(); else Bangle.off(); +}, 1000); + +Bangle.loadWidgets(); +Bangle.drawWidgets(); From eeb3206a095f0a9db31c0a95b917b2b2d506f5e0 Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:39:36 +0100 Subject: [PATCH 0070/1839] Create Readme.md --- apps/poweroff/Readme.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 apps/poweroff/Readme.md diff --git a/apps/poweroff/Readme.md b/apps/poweroff/Readme.md new file mode 100644 index 000000000..0595b6d6c --- /dev/null +++ b/apps/poweroff/Readme.md @@ -0,0 +1,13 @@ +# PowerOff + +Simple app to power off your Bangle.js + +## Usage + +Start the app shutdowns your Bangle.js watch after a short delay. + +## Creator +Marco (@myxor) + +## Icon +Icon taken from https://materialdesignicons.com/ Apache License 2.0 From eef1569c9900cce4eb7c779aa6b51a7bc60682dc Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:41:49 +0100 Subject: [PATCH 0071/1839] Create app-icon.js --- apps/poweroff/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/poweroff/app-icon.js diff --git a/apps/poweroff/app-icon.js b/apps/poweroff/app-icon.js new file mode 100644 index 000000000..3d3af6ac7 --- /dev/null +++ b/apps/poweroff/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwIpmgfAArUDAoIGCg+D4PgAoMPAoPwAoMfAoP4AoM/C4P8AoM+AoN8AoN8AoM+AoN4AoMeAo/4AoMfAoPwAoMPArRQCFIRQCGoQCBHYYFEKARNCAQQICn4CBMoUfwEBEwUP4EDGQUH/EfRIUD///SoUBAoOAUQV//ytDh4cCAF4A=")) From f73055253e76284dd520080ad03cefac225b9d18 Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:42:30 +0100 Subject: [PATCH 0072/1839] Add files via upload --- apps/poweroff/app.png | Bin 0 -> 905 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/poweroff/app.png diff --git a/apps/poweroff/app.png b/apps/poweroff/app.png new file mode 100644 index 0000000000000000000000000000000000000000..dc2a206855c7d024d1efbaea336ebcc48d9497b0 GIT binary patch literal 905 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCmUKs7M+SzC{oH>NS%G|oWRD45dJguM!v-tY$DUh!@P+6=(yLU`z6LcLCBs@Y8vBJ&@uo z@Q5r1(g|SvA=~LZ0|QgHr;B4q#=W;QeY1ldMcU3^$<)5*ubsNaJm9@Yl)Oa&Cv}s&qTk6uBGHw`=wr?O#y5mWe^!ru13k z+>K|}vo5psRd2krY zuzEP&2|m2~zyj3+EmYY(DXdq;+~HF69wxvk365>xxX#l?WE;*cb9jo*7rv+$b@`M&i>4sCBK2; z#==MDf{byicid-M;D0n;nW-l5qZ>EF-s|i8I5sT1+9J>(uXRsKFrm9^e>B6HRTbeK z!plWC7Wm)4nZ~KeV5}v_XEND!*EgSKTA7T?uRILmvpiw+MU$a;)pgG9L#_)Jan0{! zCu1dJpY@eN-{$PHO*+d{ZrXggQq5K}n_0!zd!Dxbf%FG9jPJ`QMaq9% zQ`x|OV4KFXV7717+jg^_Wi)SCd|+M*ySCc=enxZYC({~h1J5p3Fk|-LaJhKF6~WJ% z9eEFwPM_}x3t9SYoAS9?{4AP`k9C_uR_xWts9tUI`*P#0m6ke6?MuF?m@0Ii7rO8A zWNn9!_uG}PCl;@}baCdnsoKC4@_*?+#-J-#KIR-XiU+1o)e_f;l9a@fRIB8oR3OD* zWME{dYiOuzY!G5#Ze?s@Wn!#tU|?lnu&CJV4T^@`{FKbJO57SQ>-7ZyH86O(`njxg HN@xNAl{#*T literal 0 HcmV?d00001 From ea10cea706d638de3827202fde9400317412e142 Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:44:45 +0100 Subject: [PATCH 0073/1839] Update Readme.md --- apps/poweroff/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/poweroff/Readme.md b/apps/poweroff/Readme.md index 0595b6d6c..3aeff5e8d 100644 --- a/apps/poweroff/Readme.md +++ b/apps/poweroff/Readme.md @@ -1,4 +1,4 @@ -# PowerOff +# Poweroff Simple app to power off your Bangle.js From 166994311e6bfacbd6b1327a41800a489bf05852 Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:46:04 +0100 Subject: [PATCH 0074/1839] Add app to apps.json --- apps.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 1c614c592..b8ef18570 100644 --- a/apps.json +++ b/apps.json @@ -4526,5 +4526,19 @@ {"name":"93dub.app.js","url":"app.js"}, {"name":"93dub.img","url":"app-icon.js","evaluate":true} ] - } + }, + { "id": "poweroff", + "name": "Poweroff", + "shortName":"Poweroff", + "version":"0.01", + "description": "Simple app to power off your Bangle.js", + "icon": "app.png", + "tags": "", + "supports" : ["BANGLEJS", "BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"poweroff.app.js","url":"app.js"}, + {"name":"poweroff.img","url":"app-icon.js","evaluate":true} + ] +} ] From a08a8d8a24139b29d091f0c6847d80612066eef4 Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:52:29 +0100 Subject: [PATCH 0075/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index b8ef18570..1f85d0ec6 100644 --- a/apps.json +++ b/apps.json @@ -4533,7 +4533,7 @@ "version":"0.01", "description": "Simple app to power off your Bangle.js", "icon": "app.png", - "tags": "", + "tags": "poweroff, shutdown", "supports" : ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "storage": [ From 4a852e713834b4163acff86a1a9edba5cab2f91c Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:52:47 +0100 Subject: [PATCH 0076/1839] Rename Readme.md to README.md --- apps/poweroff/{Readme.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/poweroff/{Readme.md => README.md} (100%) diff --git a/apps/poweroff/Readme.md b/apps/poweroff/README.md similarity index 100% rename from apps/poweroff/Readme.md rename to apps/poweroff/README.md From ffd7eebf258636c52f07e82b5fe8fe787c77cb36 Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:59:20 +0100 Subject: [PATCH 0077/1839] Change icon to black --- apps/poweroff/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/poweroff/app-icon.js b/apps/poweroff/app-icon.js index 3d3af6ac7..7caf256a2 100644 --- a/apps/poweroff/app-icon.js +++ b/apps/poweroff/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwIpmgfAArUDAoIGCg+D4PgAoMPAoPwAoMfAoP4AoM/C4P8AoM+AoN8AoN8AoM+AoN4AoMeAo/4AoMfAoPwAoMPArRQCFIRQCGoQCBHYYFEKARNCAQQICn4CBMoUfwEBEwUP4EDGQUH/EfRIUD///SoUBAoOAUQV//ytDh4cCAF4A=")) +require("heatshrink").decompress(atob("mEwwMB/4Ak/k/ArX8AoIGC/F8n0fAoPwAoMPAoPgAoMHAoPAC4MDAoPBAoODAoODAoPBAoOHAoPhAo8HAoPgAoMPAoPwArRQCFIRQCGoQCBHYYFEKARNCAQQIC4ACBMoXgv/+EwXwn/8GQX4g/gRIX8b4KVC/wFBv6iCwDnE+AcCAF4=")) From 31dba4df497d464374237b9617f576d3cda54f15 Mon Sep 17 00:00:00 2001 From: Marco H Date: Tue, 30 Nov 2021 08:59:37 +0100 Subject: [PATCH 0078/1839] Change icon to black --- apps/poweroff/app.png | Bin 905 -> 882 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/poweroff/app.png b/apps/poweroff/app.png index dc2a206855c7d024d1efbaea336ebcc48d9497b0..5c199c3baa43660d2ff1589bfcef3fc8826da228 100644 GIT binary patch delta 701 zcmV;u0z&^!p*h(sch)np)`?^ZuzB>@HWg(zUPDI=g_n1`h=6@NQ`*TBs#V_KqRQ3Kur zWBp400PuN5Vzm+iYAb$U0``YaewRqT(=HVdaK$rb3D_Ab`Srj%PtZwVQvm^6fTx~u zZ-Ai?0-be-ij( zab*O*fyd&zaSH)QM1Lkg@>#wQTR4@4YrE1e?-T;JMUjQAG|R&2U_b#w!e+Ubfo2NH zwSKL|RmosoUIUGQ@1nmgpn$ES|II?cyy)*%CNm(K27g(7=X)7w1k8#4No6uckiO>% zc@doD{|Bp%u8`%W0xXDFr!5>;frfB=A%K93B1WSf+k{7?H**^elOF~aMU01*S7$Hq zO9Yt0=2RmAo(bPg^oxa>TcnHAL`e||aNFbehIR7bs^lwAuqld7r(s~){ zVFZ}XNTf)6iMzXfWe~VZx<=$_P26cmusN?`6!!w2M@R#AP*8fQwEWYdirdQ^#l1<5 z@$cl~EASq7Fg61`Z;OaTB9Ta>6n_B`TO^Ik8v_5JlN$pf4>dSCGBYbMFgh?WmX#Hz jlS~658#OpOGBYbMFgh?W=g6%Z00000NkvXXu0mjf^KCo2 delta 724 zcmV;_0xSLU28jodhkuJnL_t(&-tC!9Yg0iKhR@V!D@I!pAu4KX5wxI)|3F=7w6B)qRyzt*8r?C`6RUMQ-Ws=_HxloJm3MyUGc3 z&Uv57Ff;c?Bv-CnxmHpxR$+i8jhu_pt1A{jr<4P%v@!z#1%E3O?bONy0BjeLr@&PM z^P?j25*V@McvCOXpraet3 zf!+)Nn}GYCdar<<7yy?&&Bg#%XMD&K>H=Rz%oKL}JkGw&MYGzCaO+*8A=z@R0- zglg~}=xdS_1b>i>?FGszW!%bq5%{HwpAN_i21v$_sFa_;Itzf4s_;8tRRn;7=T|u1 zEHC6BJFMbK=iJ}6XGY06_eVtTs;`e&031~DV{7vbY9Fuw*rDP#5dmJSxZeVxPsLv& z0(?>NMhgJF*RPHUu%^|75P%;l-Wm~Li;BNn0L-d*SAU2TrxXaFPv6;Q2_XP8Djp6r zlSR7rOr|Pn0jJdAQVu!DGW00`bE?+~i^4^qq6(jh0B~0Ir~pN);&(ikx%GzTHvk`1 zkK2~Bvm5xW8cYFgztu>t(+@n?>7dP`l}6WCuCaC?67$zRb+4G3Pnz`rFFehrvMi@$ z**x^rdw&LWn*$_GOP(t)z-Qn*0q=K`Ss(GNd4LbVwkYOP2KIZly9LbwH-MwSo@56r zCZCT1Hyh-ZfqhZUryw>1Pq5Q-pwtobDTr?1BFoQ+R#c_-wj<7(4+JRz<1KWFr1m5=AdAlu-$dlCh)hfEsTu2$bFR|Sna-6fSFT+DrTzg@)YS28 z#WG)$1Op-uGc-ChGb=DKIxsMzb2jXgH3K3WGc-ChGb=DKIxsNPE{;$D0000 Date: Tue, 30 Nov 2021 09:04:43 +0100 Subject: [PATCH 0079/1839] Update ChangeLog --- apps/poweroff/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/poweroff/ChangeLog b/apps/poweroff/ChangeLog index 8b1378917..1a3bc1757 100644 --- a/apps/poweroff/ChangeLog +++ b/apps/poweroff/ChangeLog @@ -1 +1 @@ - +0.01: New app! From ac1425ca7cfaf46041790a3223e1f3383f7a2ae2 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 13:07:56 +0000 Subject: [PATCH 0080/1839] set mylocation to an app --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index cfac33be3..e77ef0840 100644 --- a/apps.json +++ b/apps.json @@ -4538,7 +4538,7 @@ "description": "My Locations adds a menu in the Settings app to set your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", "readme": "README.md", "tags": "tool,utility", - "type": "widget", + "type": "app", "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ {"name":"mylocation.settings.js","url":"mylocation.settings.js"} From 5b7bbd83db31769a8b255821729d1cad5d5a81c8 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 13:30:13 +0000 Subject: [PATCH 0081/1839] Pebble: added README, battery warning if below 30% --- apps.json | 1 + apps/pebble/README.md | 17 +++++++++++++++++ apps/pebble/pebble.app.js | 14 ++++++-------- 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 apps/pebble/README.md diff --git a/apps.json b/apps.json index ab74c9ee1..13838a962 100644 --- a/apps.json +++ b/apps.json @@ -4581,6 +4581,7 @@ "shortName": "Pebble", "version": "0.01", "description": "A pebble style clock to keep the rebellion going", + "readme": "README.md", "icon": "pebble.png", "dependencies": {"widpedom":"app"}, "screenshots": [{"url":"screenshot_pebble.png"}], diff --git a/apps/pebble/README.md b/apps/pebble/README.md new file mode 100644 index 000000000..f0de5ce73 --- /dev/null +++ b/apps/pebble/README.md @@ -0,0 +1,17 @@ +# Pebble + + *a Pebble style clock with configurable background color, to keep the revolution going* + +* Designed specifically for Bangle 2 +* A choice of 6 different background colous through its setting menu +* Supports the Light and Dark themes +* Uses pedometer widget to get latest step count +* Dependant apps are installed when Pebble installs +* Uses the whole screen, widgets are made invisible but still run in the background +* When battery is less than 30% main screen goes Red + +![](pebble_screenshot.png) +![](pebble_screenshot2.png) +![](pebble_screenshot3.png) + +Written by: [Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/) diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 6b7f7b492..62159055d 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -19,7 +19,7 @@ const ha = 2*h/5 - 8; const h2 = 3*h/5 - 10; const h3 = 7*h/8; -let batterWarning = false; +let batteryWarning = false; function draw() { let date = new Date(); @@ -30,14 +30,11 @@ function draw() { // turn the warning on once we have dipped below 30% if (E.getBattery() < 30) - batterWarning = true; + batteryWarning = true; // turn the warning off once we have dipped above 40% if (E.getBattery() > 40) - batterWarning = false; - - // for testing only - batterWarning = true; + batteryWarning = false; g.reset(); g.setColor(settings.bg); @@ -59,11 +56,12 @@ function draw() { g.drawString(getSteps(), 3*w/4, ha); // time - g.setColor(!batteryWarning ? g.theme.bg ? '#f00'); + // white on red for battery warning + g.setColor(!batteryWarning ? g.theme.bg : '#f00'); g.fillRect(0, h2, w, h3); g.setFontQahiri(); g.setFontAlign(0, -1); - g.setColor(g.theme.fg); + g.setColor(!batteryWarning ? g.theme.fg : '#fff'); g.drawString(timeStr, w/2, h2 - 8); // contrast bar From 78c3791c1e6af33dc127418a172a22b0b9c96df9 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 13:48:20 +0000 Subject: [PATCH 0082/1839] Pebble screenshot updated --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 13838a962..4c1b0bed6 100644 --- a/apps.json +++ b/apps.json @@ -4584,7 +4584,7 @@ "readme": "README.md", "icon": "pebble.png", "dependencies": {"widpedom":"app"}, - "screenshots": [{"url":"screenshot_pebble.png"}], + "screenshots": [{"url":"pebble_screenshot.png"}], "type": "clock", "tags": "clock", "supports": ["BANGLEJS2"], From c1a48e7b48ddb4087b63171bde681ea1e79ca76f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 00:09:52 +0800 Subject: [PATCH 0083/1839] Try different JSON format --- apps/authentiwatch/interface.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 12c0c1d8d..0b7774557 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -333,7 +333,8 @@ function loadTokens() { */ function saveTokens() { Util.showModal('Saving...'); - Puck.write(`\x10require('Storage').write(${JSON.stringify('authentiwatch.json')},${JSON.stringify(tokens)})\n`,()=>{ + let save={data:tokens,count:tokens.length}; + Puck.write(`\x10require('Storage').write(${JSON.stringify('authentiwatch.json')},${JSON.stringify(save)})\n`,()=>{ Util.hideModal(); }); } From 0e3b17be6757527c1f372fa8b9d5bbc8f3985035 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 16:12:47 +0000 Subject: [PATCH 0084/1839] Added icon for mylocation --- apps.json | 5 ++--- apps/mylocation/mylocation.icon.js | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 apps/mylocation/mylocation.icon.js diff --git a/apps.json b/apps.json index 4c1b0bed6..8c6d5c9c5 100644 --- a/apps.json +++ b/apps.json @@ -4110,7 +4110,6 @@ "description": "A Configurable clock with custom fonts and background. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", "icon": "pastel.png", "dependencies": {"mylocation":"app"}, - "dependencies": {"widpedom":"app"}, "screenshots": [{"url":"screenshot_pastel.png"}], "type": "clock", "tags": "clock", @@ -4572,7 +4571,8 @@ "type": "app", "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ - {"name":"mylocation.settings.js","url":"mylocation.settings.js"} + {"name":"mylocation.settings.js","url":"mylocation.settings.js"}, + {"name":"mylocation.img","url":"mylocation.icon.js","evaluate": true } ] }, { @@ -4583,7 +4583,6 @@ "description": "A pebble style clock to keep the rebellion going", "readme": "README.md", "icon": "pebble.png", - "dependencies": {"widpedom":"app"}, "screenshots": [{"url":"pebble_screenshot.png"}], "type": "clock", "tags": "clock", diff --git a/apps/mylocation/mylocation.icon.js b/apps/mylocation/mylocation.icon.js new file mode 100644 index 000000000..bfb38d5ac --- /dev/null +++ b/apps/mylocation/mylocation.icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4UA///t/7j/P3/vB4cBqtVoAbHBQIABBQ0FBYdQBYsVBYdUERIkGHIQADHoguEGAwuEGAwKFBZg8DHQw8EBYNf/1Vq3/8oLDIwNf/Wpv//0oLG9Wq3/qBYJUCBYuqBaBqBBYW+BepHEBbybCBYP+BYSnErYLDyoLFAANq/r8Ga5T7MBZZUBAAhSCfhA6DBZhIGBQg8FHQg8GHQgwGFwowFBQwwDFwwLMlS7Bqta1AKEn2q1K1C1WgBYf/1WqBYIDB1QKCgYLC0taBYoXB/QICBY0//7vBAAQ8EEgIABCwwME9QVEA")) From f127bef66b9c4c88e8094594a90ac4aad53b26e9 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 00:14:47 +0800 Subject: [PATCH 0085/1839] Load new JSON format --- apps/authentiwatch/interface.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 0b7774557..17b7648ea 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -322,7 +322,8 @@ function loadTokens() { Puck.eval(`require('Storage').read(${JSON.stringify('authentiwatch.json')})`,data=>{ Util.hideModal(); try { - tokens = JSON.parse(data); + let saved = JSON.parse(data); + tokens = saved.data; updateTokens(); } catch { tokens = []; From 51c91bf9eede044c0093bf265855d149547697d2 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 00:17:26 +0800 Subject: [PATCH 0086/1839] Rename variable --- apps/authentiwatch/interface.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 17b7648ea..6b39c148b 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -322,8 +322,8 @@ function loadTokens() { Puck.eval(`require('Storage').read(${JSON.stringify('authentiwatch.json')})`,data=>{ Util.hideModal(); try { - let saved = JSON.parse(data); - tokens = saved.data; + let load = JSON.parse(data); + tokens = load.data; updateTokens(); } catch { tokens = []; From 989dc5ccd4ede2fcc8f9bc82d9d5c4ad84981360 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 00:18:44 +0800 Subject: [PATCH 0087/1839] Use new JSON format. --- apps/authentiwatch/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 43eff4709..c1316fe45 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -8,6 +8,7 @@ const algos = { }; var tokens = require("Storage").readJSON("authentiwatch.json", true) || []; +tokens = tokens.data; // QR Code Text // From e1c67cf345cf0b1093caa7c41c8e8981de8f24cb Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 00:22:23 +0800 Subject: [PATCH 0088/1839] Save in new JSON format too --- apps/authentiwatch/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index c1316fe45..da8b6d220 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -258,7 +258,8 @@ function onSwipe(e) { } if (e == -1 && state.curtoken != -1 && tokens[state.curtoken].period <= 0) { tokens[state.curtoken].period--; - require("Storage").writeJSON("authentiwatch.json", tokens); + let save={data:tokens,count:tokens.length}; + require("Storage").writeJSON("authentiwatch.json", save); state.nextTime = 0; state.hide = 2; draw(); From f094cc6e354ada59d50719bd8af60bfe1f258cb3 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 00:25:00 +0800 Subject: [PATCH 0089/1839] Update ChangeLog --- apps/authentiwatch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/ChangeLog b/apps/authentiwatch/ChangeLog index 7b83706bf..67cb00c67 100644 --- a/apps/authentiwatch/ChangeLog +++ b/apps/authentiwatch/ChangeLog @@ -1 +1,2 @@ +0.02: Fix JSON save format 0.01: First release From 31eaeadee2929e93fdee2ee01974cf2779e5ed13 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 00:26:39 +0800 Subject: [PATCH 0090/1839] Update Authentiwatch version --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 2e338a432..36102264e 100644 --- a/apps.json +++ b/apps.json @@ -4433,7 +4433,7 @@ "shortName": "AuthWatch", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], - "version": "0.01", + "version": "0.02", "description": "Google Authenticator compatible tool.", "tags": "tool", "interface": "interface.html", From 4669099645a46062a63a9e77771b7ab1cf531ef2 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 18:11:08 +0000 Subject: [PATCH 0091/1839] MyLocation added mylocation.app.js --- apps.json | 1 + apps/mylocation/mylocation.app.js | 74 +++++++++++++++++++++++++ apps/mylocation/mylocation.settings.js | 75 ++------------------------ 3 files changed, 78 insertions(+), 72 deletions(-) create mode 100644 apps/mylocation/mylocation.app.js diff --git a/apps.json b/apps.json index 8c6d5c9c5..0f2d7b738 100644 --- a/apps.json +++ b/apps.json @@ -4571,6 +4571,7 @@ "type": "app", "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ + {"name":"mylocation.apps.js","url":"mylocation.app.js"}, {"name":"mylocation.settings.js","url":"mylocation.settings.js"}, {"name":"mylocation.img","url":"mylocation.icon.js","evaluate": true } ] diff --git a/apps/mylocation/mylocation.app.js b/apps/mylocation/mylocation.app.js new file mode 100644 index 000000000..49e74a025 --- /dev/null +++ b/apps/mylocation/mylocation.app.js @@ -0,0 +1,74 @@ +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +const SETTINGS_FILE = "mylocation.json"; + +// initialize with default settings... +let s = { + 'lat': 51.5072, + 'lon': 0.1276, + 'location': "London" +} + +// ...and overwrite them with any saved values +// This way saved values are preserved if a new version adds more settings +const storage = require('Storage') +let settings = storage.readJSON(SETTINGS_FILE, 1) || {} +const saved = settings || {} +for (const key in saved) { + s[key] = saved[key] +} + +function save() { + settings = s + storage.write(SETTINGS_FILE, settings) +} + +const locations = ["London", "Newcastle", "Edinburgh", "Paris", "New York", "Tokyo","???"]; +const lats = [51.5072 ,54.9783 ,55.9533 ,48.8566 ,40.7128 ,35.6762, 0.0]; +const lons = [-0.1276 ,-1.6178 ,-3.1883 ,2.3522 , -74.0060 ,139.6503, 0.0]; + +function setFromGPS() { + console.log("set from GPS"); + Bangle.setGPSPower(1); + E.showMessage("Waiting for GPS fix. Place watch in the open. Could take 10 minutes. Long press to abort", "GPS Running"); + Bangle.setUI("updown", undefined); +} + +Bangle.on('GPS', (gps) => { + //console.log("."); + if (gps.fix === 0) return; + //console.log("fix from GPS"); + s = {'lat': gps.lat, 'lon': gps.lon, 'location': '???' } + Bangle.buzz(1500); // buzz on first position + Bangle.setGPSPower(0); + save(); + + Bangle.setUI("updown", ()=>{ load() }); + E.showPrompt("Location has been saved from the GPS fix",{ + title:"Location Saved", + buttons : {"OK":1} + }).then(function(v) { + load(); // load default clock + }); +}); + + +E.showMenu({ + '': { 'title': 'My Location' }, + '< Back': back, + 'City': { + value: 0 | locations.indexOf(s.location), + min: 0, max: 6, + format: v => locations[v], + onchange: v => { + if (v != 6) { + s.location = locations[v]; + s.lat = lats[v]; + s.lon = lons[v]; + save(); + } + }, + }, + 'Set From GPS': ()=>setFromGPS() +}); diff --git a/apps/mylocation/mylocation.settings.js b/apps/mylocation/mylocation.settings.js index 6936e9e69..4767c4732 100644 --- a/apps/mylocation/mylocation.settings.js +++ b/apps/mylocation/mylocation.settings.js @@ -1,73 +1,4 @@ (function(back) { - const SETTINGS_FILE = "mylocation.json"; - - // initialize with default settings... - let s = { - 'lat': 51.5072, - 'lon': 0.1276, - 'location': "London" - } - - // ...and overwrite them with any saved values - // This way saved values are preserved if a new version adds more settings - const storage = require('Storage') - let settings = storage.readJSON(SETTINGS_FILE, 1) || {} - const saved = settings || {} - for (const key in saved) { - s[key] = saved[key] - } - - function save() { - settings = s - storage.write(SETTINGS_FILE, settings) - } - - const locations = ["London", "Newcastle", "Edinburgh", "Paris", "New York", "Tokyo","???"]; - const lats = [51.5072 ,54.9783 ,55.9533 ,48.8566 ,40.7128 ,35.6762, 0.0]; - const lons = [-0.1276 ,-1.6178 ,-3.1883 ,2.3522 , -74.0060 ,139.6503, 0.0]; - - E.showMenu({ - '': { 'title': 'My Location' }, - '< Back': back, - 'City': { - value: 0 | locations.indexOf(s.location), - min: 0, max: 6, - format: v => locations[v], - onchange: v => { - if (v != 6) { - s.location = locations[v]; - s.lat = lats[v]; - s.lon = lons[v]; - save(); - } - }, - }, - 'Set From GPS': ()=>setFromGPS() - }) - - function setFromGPS() { - console.log("set from GPS"); - Bangle.setGPSPower(1); - E.showMessage("Waiting for GPS fix. Place watch in the open. Could take 10 minutes. Long press to abort", "GPS Running"); - Bangle.setUI("updown", undefined); - } - - Bangle.on('GPS', (gps) => { - //console.log("."); - if (gps.fix === 0) return; - //console.log("fix from GPS"); - s = {'lat': gps.lat, 'lon': gps.lon, 'location': '???' } - Bangle.buzz(1500); // buzz on first position - Bangle.setGPSPower(0); - save(); - - Bangle.setUI("updown", ()=>{ load() }); - E.showPrompt("Location has been saved from the GPS fix",{ - title:"Location Saved", - buttons : {"OK":1} - }).then(function(v) { - load(); // load default clock - }); - }); - -}) + // just go right to our app + load("mylocation.app.js"); +})(); From 7caac64a8653f06f95650228abc98018de8df9b8 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 30 Nov 2021 20:40:33 +0100 Subject: [PATCH 0092/1839] widbars: new widget --- apps.json | 17 +++++++++- apps/widbars/ChangeLog | 1 + apps/widbars/README.md | 14 ++++++++ apps/widbars/icon.png | Bin 0 -> 2294 bytes apps/widbars/screenshot.png | Bin 0 -> 2377 bytes apps/widbars/widget.js | 62 ++++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 apps/widbars/ChangeLog create mode 100644 apps/widbars/README.md create mode 100644 apps/widbars/icon.png create mode 100644 apps/widbars/screenshot.png create mode 100644 apps/widbars/widget.js diff --git a/apps.json b/apps.json index 2e338a432..bca8d6cbd 100644 --- a/apps.json +++ b/apps.json @@ -4557,5 +4557,20 @@ { "name": "sensible.app.js", "url": "sensible.js" }, { "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true } ] -} +}, + { + "id": "widbars", + "name": "Bars Widget", + "version": "0.01", + "description": "Display several measurements as vertical bars.", + "icon": "icon.png", + "screenshots": [{"url":"screenshot.png"}], + "readme": "README.md", + "type": "widget", + "tags": "widget", + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"widbars.wid.js","url":"widget.js"} + ] + } ] diff --git a/apps/widbars/ChangeLog b/apps/widbars/ChangeLog new file mode 100644 index 000000000..4c21f3ace --- /dev/null +++ b/apps/widbars/ChangeLog @@ -0,0 +1 @@ +0.01: New Widget! diff --git a/apps/widbars/README.md b/apps/widbars/README.md new file mode 100644 index 000000000..eba5cc347 --- /dev/null +++ b/apps/widbars/README.md @@ -0,0 +1,14 @@ +# Bars Widget + +A simple widget that display several measurements as vertical bars. + +![Screenshot](screenshot.png) + +## Measurements from left to right: + +- Current heart rate, on a scale from 0-200 bpm (*red*)
+ Only if available: this widget does not turn on HRM monitoring by itself. +- Device temperature, on a scale from 0-50 °C (*yellow*) +- Flash storage space used (*blue/cyan*) +- Memory usage (*magenta*) +- Battery charge (*green*) \ No newline at end of file diff --git a/apps/widbars/icon.png b/apps/widbars/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..59f78d66623a8aaf97376d6290bbfba9afcfe99b GIT binary patch literal 2294 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+Ra#5mg6=I{O2ih1QJ|89)}y=%MEh;6i7*4#-3?s z`X#a2qRa&aqOeeH=3jq``2!!~l1+%5Q%T9<6G|vl@sREQly!GDto!=-V+g+=`pq>! z=<>IjT#xw`{qeTo#BlAg-{fP2@*&7wg0}{Wtk2_KN%Yh1ci|9J=6*;e^S!F=5Y&%} zOO@jrF12=}zs*Aj!%8Cp$P-QPyj}OaHSqd%zT&HQ@7Fx^YELp~f*>k(RF8iDWXp8e2oEm@Tzu;H7YseQ!=Vv94zzp`^MjE^Mi!ZScQqtf zG#wtbjO|V_nAl))zm_FjjBmsaI8fD`H%5!&N74uC}`l6$4FT zv_u_5X1~djwmo9GMmW9_{2JN)Eytmb|^p&jvra zj7V1#Ih!wAK`&Cjh8oJ8-Z2Y=I5~KW%fRP#&~NYj2d)YR<1(|dS8dxOT68zx@{4DW zc@ganA!m3T0$?IwM<|032+k(wqf5>*5jzJvW)M`NIr%^h47eC+KuHSTCo)W#6dP;U zt+^B_k#-|DY54f$8Qc_KK~@M6{=*@|hiddO#28cLm`yCPCZ9rzDJ4#tHmFIXE|=lWu7N1@u(dPE=QRLTZlYjOMC_Wvcw zmn=qdm=fT3WjZc`J#$CG6s;qHr4w_F@Jg|*Yj49eZF8;SN2NBsm&V>W9x!|7$wOvy z)3;WoWeK#VA1J8#8)u=wzz-;3LCgZ$FegZsIeL%6__Ls-bDndyIWd@YFF=AC$XWlI zv3-wqBllsYXS=%LNRrB$(y(6-Kf7CK@;9mUTF^gG$eihHFeo|7(#s1_$w0@O8-=7H3To9PntLe~#fHNVjL%c`2Ux_+pt`P{6p zRW+ZR^|fI0xmjPg=5w>&2JEVTIE=MU21P4a8Hr_z)*$IP7NIo3>!(|xP%Te{r6xfBTr!U$q*)xLofM_d)SiP!4qdPN{=#N`Nd2&z~- zjFh}8X`Ye$#QEz$*Z^*hnGm+|+#BH}_RcZ!jQ~OCKQNa z`&D!M&;=QI6&)d=qw-GIIHBv-AR9Wjtf#WlM32B-W~zE-6I2G7wEf>Rd`-m}a55qg zW%hM8?CO%y)$Udufn!3o&H- z{Mu@DiCT${6(VbTcoJ&z5fjI9jR_FA*cfgFk49}L4Q^+5aAVtu$28aGtY5*cmDc8T zL^s|Ac66hz4PPEMm)q==c03*!CxX6Ln-c^-_Ca?6fvXeh#MvlQUz_e|(JERBtf2q( ztI7%0hQk8bg%)77NiO>G7?*2Q2@nO}8bMJfX*yBTVW^4s`qsqYY(9KLX7e2+FY57j z_b45kJ>;wRJZBMm}1n0+8UUYwsnH@ z=WD~Fn@8Oq?4x94!-SM34S(=aym&}t?{FGfK2uO~UL$=K$Sfq?%LRkIM7S6y9Bm5T zH+LLsuDHebkF9w(@M-&@AnX{iV*Uok=WuD3z2z?e00D$)LqkwWLqi~Na&Km7Y-Iod zc$|HaJxIeq9K~N#rJ@ywb`TNCP@OD@iaKf)icq1{3avVrT>1q~8j=(jN5Qq=;KyRs z!Nplu2UkH5`~Y!tb5eAX691PJTEuv8+>dwn9(V5mpttSBkO z=ftB1U6A;Z>$1yloC^*MJTq*hQ}e`OVzJQ1avQUvp%PCLM-)|~d?Dkq!g-6cTCTF@ zJ^2fRIc;T`>of-u$0C-Hga{c`lu(9+D6JYPCQ`H?^Y9Ni{v^3%a+Scyv49FxNRA); z4}N!R<|oG8q+kr_e6j71VIZ&zG-|f}eQeu}6TtrrTxl(Tr4Gz|l3r_Rkt3jQ8@RY` zY4RR$xdZe+>5?HilAorK&jasg^i5eHbPIH^xxF>_arywHsjI{daBv8W6exS$RA}Dq+5rlHAPfc2ExP}e*99CAMJBzS zz~^u1q^zn~xwcrm0A|u{3p#T5? literal 0 HcmV?d00001 diff --git a/apps/widbars/screenshot.png b/apps/widbars/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..146e085e3bd42a99fc342e62a86a5a88471d815a GIT binary patch literal 2377 zcmds({Xf%tAICr6&D^Yn6Sg{}uW+Wd%@-kDD{7>M;5WfELo7^xF{{MV===J7l_=ls%g~)}MQy zb|o5e$Mz}5CJH!L=dLyA>}<37sHm>4F0fj@$EZLI0&|&BP>TTwBwm97qg4J24P1l> zsEqR6pr@933BszEte7VkG;xd|A{hcXT&Co|h>GGg)%MTl`K94Ykc1gVw0z=ZoURt= zpn9jVTJTk`(-1J~mi8MHK)D;yAAp`2t0ZLrqy2Pa62|Q(mU9U;%nZT9^6Wf5rgMU}brkmY_fuaia;?Uw&JVy9Fdy*1G>dNPcxq z4$h@YhV`XuFYC5zF`lpfrN0FYc98a&MH@=;czR7QuDNz$@L=IwQTIi(QX)@k3sPIi zD!6hFF{n1MD$@}PPr>Fnp;ZTcmhX(jF$lccicT+0Ox~0y`AaSY5E5@SuJpX zr{kL$bS!ruz=3m-_j=*gL+Uh2;y0YSln;7M^;`ADZ}wlR#yYL<$^pjC@{Qg{Iw=c| zfTDfOYNUIL^%lzzRba;GwgPtHp0-*~vwX{)z=$zKgz#%c2JsBdPGG)f zG9xKEAVqc5?n^wfx?)++cNiy4G-&nTUgSnjCwd6O*^s3zO<}E}i<}Ic^ShQ9$;6?cg7_jp2z6 zG|CRv$15EXCUF(br#-*zy)Y?Yi`y!X9~+8Sued`Kncu!Ohn)1VO%~=t!7kWZUAHfJ zc~qCIX)KsH(tYX?FE8d(bnUwOP1d4JW6w>U5F;-*;ouB6#`EVW*a<_M5sBTajQV~? z8qnbTQnO(j<12XU$ola=I>|ciW*Ard)}j^5nJ@k-v@C1(Awzl2`IZdo41r%Qp^oHJd>#g4DcY@^9LM8C)4 z>-=p9xFk|xl;C&+hu&r@;QxgZKI|Ra*1ku5oPWClRV})yvnJ8WiaCJ`4r8A@jOI9vwf#ugwM2Z`}BjlljiRR#+JHv$>onbpQ2$d*)6GmcdpP zzC&1$Q|LP9;ZmNw>_RG{3VnQQaO4L3!ZC%o&WL?pJD@Fe>3FMVFzc{DjTYsbSSTQ@ z^d{`FX?Izn%hR0`1ayQ>&1_J_`wqu8!i_AN=c(UHbeqlo(Hjj>GaWj`3v z-)=WQbxf%THtq2*cOVQu2szXur9a*U;j|10CN<54hmNI$EK;7^|BCl?fmsJ=l$$rt zBq+bLN?nPkEi&i-wk98I-8@>&}I;P&YJ+a%zP2 z{Fd>(;yC`Flo(Dz(XHK|nnyNPX4`qO2MhsI@+j(7T{H)^`|yA)!x|BGZhW>QAWLx{ z_Cg#Vq3aj;C7BaB<3S9IK=R95-rc-}cF9`~N9>&0+@|0Niap*p9De;Tr%GkdhN=n2 z+US+@WMblZ<&Q_8uIer@=E>os;acJAJ~d7&57bp&ue(RSBCPy7)|_LP#OEcSaFJc@ zve}Ft+BTaXB{a& { + const h=24, // widget height + w=3, // width of single bar + bars=3; // number of bars + + // We show HRM if available, but don't turn it on + let bpm,rst,con=10; // always ignore HRM with confidence below 10% + function noHrm() { // last value is no longer valid + if (rst) clearTimeout(rst); + rst=bpm=undefined; con=10; + WIDGETS["bars"].draw(); + } + Bangle.on('HRM', hrm=>{ + if (hrm.confidence>con || hrm.confidence>=80) { + bpm=hrm.confidence; + con=hrm.confidence; + WIDGETS["bars"].draw(); + if (rst) clearTimeout(rst); + rst = setTimeout(noHrm, 10*60*1000); // forget HRM after 10 minutes + } + }); + + /** + * Draw a bar + * + * @param {int} x left + * @param {int} y top (of full bar) + * @param {string} col Color + * @param {number} f Fraction of bar to draw + */ + function bar(x,y, col,f) { + if (!f) f = 0; // for f=NaN: set it to 0 -> don't even draw the bottom pixel + if (f>1) f = 1; + if (f<0) f = 0; + const top = Math.round((h-1)*(1-f)); + // use Math.min/max to make sure we stay within widget boundaries for f=0/f=1 + 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 + } + function draw() { + g.reset(); + const x = this.x, y = this.y, + m = process.memory(); + let b=0; + 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 + 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); + } + + let redraw; + Bangle.on('lcdPower', on => { + if (redraw) clearInterval(redraw) + redraw = undefined; + if (on) { + WIDGETS["bars"].draw(); + redraw = setInterval(()=>WIDGETS["bars"].draw, 10*1000); // redraw every 10 seconds + } + }); + WIDGETS["bars"]={area:"tr",width: bars*w,draw:draw}; +})() From 8580952e69609f53736089e72e1028117fd5c09f Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 30 Nov 2021 21:06:23 +0100 Subject: [PATCH 0093/1839] widbars: comment out HRM/temperature They didn't seem very useful --- apps/widbars/README.md | 3 ++- apps/widbars/icon.png | Bin 2294 -> 2085 bytes apps/widbars/screenshot.png | Bin 2377 -> 9787 bytes apps/widbars/widget.js | 41 ++++++++++++++++++++---------------- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/apps/widbars/README.md b/apps/widbars/README.md index eba5cc347..c1cb73a96 100644 --- a/apps/widbars/README.md +++ b/apps/widbars/README.md @@ -5,10 +5,11 @@ A simple widget that display several measurements as vertical bars. ![Screenshot](screenshot.png) ## Measurements from left to right: - + - Flash storage space used (*blue/cyan*) - Memory usage (*magenta*) - Battery charge (*green*) \ No newline at end of file diff --git a/apps/widbars/icon.png b/apps/widbars/icon.png index 59f78d66623a8aaf97376d6290bbfba9afcfe99b..3d6fcb053ae67d78eb078acb8a54ab2c15585db7 100644 GIT binary patch delta 1623 zcmV-d2B`V=5v352BYy?7dQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+O=0(cI>DQ z{nsdZ2!H^=aCk^-^$hOtdxKrCB$ZU1oLi2K1F|Ic7DABz?_Z;T@C!Lbib+bYIXnDf zjWsm96nFgUetH-8bN~1p!v7EbbR7uj;+v$jQ@)`;-9EV3@PGZWpUOEB%BkoaxG3ah zIpAg9JBj{q^!s=!s(QTSTIAl<9*%aLg4>nzX4$H*O4k2$-w_2U%>*e9LD{q0&vJOc z>-OAmuP5`CLvQ2AiO>YTcmhBkrgv$by9ek2^VSpnKj&OMk!j&f%kTrr5 zXp9`LzW8moZhONQSe_oD!9$tHCr>Z>Zt$Ip%*KMqyMJ=U3VwwZxo~4Kx1Nv!A>K~j z(gyf)o%FlA_(7^0X96+QV|Z1LuqA(zk|tHP7aQvo1??F47A1fqA@bMo0c z2|>IEjs*lYc#ee-IvDUNg$XA^WX^#kl(1~$8}VB#hvMs8ZGh%*bgsoX$Tj0y20 zu^@(8;(ruVN;yd?lxk|3bId8{EO{llCM;2sWDzM+r4=r*q>_u2Qfg^6R7MU=HCL&n z*4kR2215mqacq{7NTjaR$ah^k7^T z0|@A_ICI6v7#4GjGgku^MG9~-EpBM~#TY1z>O(Sr!1|6lI`sWs9o@V48+G(~w%@7avel&|O~r=I zT<7W$Y)7_-%2t+=_PT9YY6819U`#{kbH%EaVLHc1CiwFRAh9;2sA?xw9&q&=C2-=S z3xZU$LJ{^YDV#N>s{wb@4&|EbiiFU0jDH2lkC8+#h8$4UZ$$vM`Ft2RqD9#b6I}Fa;`*tjhu~^$C3>6K3N~_16eiYoqdDv?3N;b-fM5!< zC{flZN0Elz=lgn!k_hJ)k9!*-FcEt=w-^Ia~Xzp*?RwJ;rXAJO=R zNgU^Pog;?IrC<9A6+B|Aw|#tpNH1+#Z`Y6u#g4M6M;roFo9GISjACQDitbje`lCiW z0xq`|5FLR)E8;v(+F%}K)#nfRvsUyc6!oZE(Czl;Q)opq@2aarwG`J|RezrmjWSkE z=hF^Yk=9m$c6SPe)p7W`2?;;gbux29+HsB;&ORQj$S zbIWJpr~N4W`Y!ymo5xuLM@br-Oi}|H_{QNC9p@xz|Qfa&qS?Y43V+ImyGvI;(@Xe>na= z0RR9100000000000000000000fE@wnaB^>EX>4U6ba`-PAZ2)IW&i+q+Ra#5mg6=I z{O2ih1QJ|89)}y=%MEh;6i7*4#-3?s`X#a2qRa&aqOeeH=3jq``2!!~l1+%5Q%T9< z6G|vl@sREQly!GDto!=-V+g+=`pq>!=<>IjT#xw`{qeTo#D8$@vESrlgz_QCU4pj; zimcD$UP<)R?swr3ROWt2CG)+i?GV(DiA$B^8!okWqrc5V2g6Du0>~3h@4Q|2yfyIp zb-v=OckkCc^lDEsXo5fY3WGds?`*BTH_(HT&nNS2{p;z;_*9R6|76Q_*a#0V2V8vW z_ZJL3xx=9mJ%0|gd=c}5kwr!pnR|CNBv>>Z9<_|^PBEC+U~<2fC0vYe#51p};L5hz z4$6n^w&CioI07qTTyVoxCvL8`yABltO=7e}9Ykqg_DqF3IC3BdmlI-N{O}pfb(#h= z22YnRZsC@N*IfqkaF|LC!W@>oz0A)BKe>!ZR}(p#FMnG>FH*mT8p@pBF$;t^Ie3f9 zz~^<)Z}0pEt_lX@GPAN*ZQCMRbT{Afi)W8{5$z5kXLuX}U?N~gD1#6P&L-!hOU^P8 zI|n;v5LBT#`9KW}xEN_bNebR4GEA8i8*A9DxfCgpb|W`w`1s@*+!S9yRtORP!y&_m zYVQcGR;6VLw5A^@sQDXbp}@coC}2U% z0@^SqNR~NzkHYw~prmu2bGA7#m~<~df*QzK|C+IVk98yWVWnrgy5UHY%9_%!Uk^XK zTWIn(sq|XVKTyfgH>vbS(B~?d`b{dm6MyuvO2&SZN^b>ys*?E_nkq}mAqrv?0LXl( z+oKv}dkrelv?tTY((qC-lSc$2hx;ATNg8Sh;&are`QemmF0m;MhweHevdfNFUELtq zsqE5O&lvj4KDTb793Ase9wvI$FXW^ahCWBBQB!t)BjMJXL!?lOd!;9ylP-y<7JnyH z0@O8-=7H3To9PntLe~#fHNVjL%c`2Ux_+pt`P{6pRW+ZR^|fI0xmjPg=5w>&2JEVT zIE=MU21P4a8Hr_z)*$IP7NIo3>!(|xP%Te{r6 zxfBTr!U$q*)xLofM_d)SiP!4qdVfVAYQ*ITbO@?gJdBjQDrugP`^5R{K-d6oj+qd) z@!T8XB=*u1%x?wQopsG;=IwmwChQ7UT?5rTFcq$Wcw`Upp&-xDe-UdxQTr=eo3E(- zHDkv)@q%b;lJ18(f)|{SS;l%dSI5Z9al(+yO(qnGVf$5c`_Kg$coiKXp?{((F}I=8H+veHD4z+GmldS(+;2AQ<|-!pto#TjriA`oTvbvEqklF`-fRvm$3Lbc8T zmc=U%{=F*5-6XH{Jzybfc~fUmiA>+w7Ef zJRTS)g1%Rq69hl@L3aUxs}t(P*(g(Ao9<}QDq0Gxp#Sx&$_dqm!vffa7GSkWF8cBq zmuplB5Cz{FK~X1ZI#JSLsEPOb*2Lg!K72!F^Bp8F>hX5>C>@(UJZBMm}1n0+8UUYwsnH@=WD~Fn@8Oq?4x94!-SM3 z4S(=aym&}t?{FGfK2uO~UL$=K$Sfq?%LRkIM7S6y9Bm5TH+LLsuDHebkF9w(@M-&@ zAnX{iV*Uok=WuD3y#nPgv*88A0e=uK#XmEf0001dNkl1snfL0Q?(p Y0EKxHVo(JBI{*Lx07*qoM6N<$f@~~kod5s; diff --git a/apps/widbars/screenshot.png b/apps/widbars/screenshot.png index 146e085e3bd42a99fc342e62a86a5a88471d815a..ae85e42f5512bea974b069e37fe222c870db9e20 100644 GIT binary patch literal 9787 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∓xa5}{Mq#4?OGe$!443PswLE9c|w!vYX*^6l~;8pKjczC%+RqS{>gqdl_ z^J0O2D4VD*csRtvfAph(n$)1@u)-1zUY8T1;!E%Fm#8$S!y6^`|ntA@nNd#P=;zN1_uWj!iAov+4)NO?~_0GgYR$u zvORqNBgr5-x8eV6+8Rz6iAa{w002Nm*hxvL$xBK7FAe;k@|_=;DkAqooOIY!v!WC) z+6xnFT&;jPCQi^EFHWsw5&4^7w$U4$GI1I%0cZfcyE|&WG%&2Mi=Zok`2qOi?yljH ziv2eW*I>xUbu-!fnaukdP-0?TyT$=uooiLT&%u#yj0e+rGJq+GXl`I$DVn83w=2+p zwRdoCoMGcz^zQz^B#;gzn(C8z8YR;!Aq=)V&3}&lQP03QbUaiBZ=CXydfqbWl8=Ip zBFyDju6aN7*}Qpf#Eqo2v;GUyxMYS7SfB=U+9F5qO9bIy%`HAu z@@I-B6mI+W-+_)Bi8zqIs77`y!4>FJ0cj=Vy9`80%=8+ zDYG!wHV?}GG%OU4#;!h|=Pz%7@|wCKG*?%|1Y8FHt%EJ&%f8?Km1{c~wM1@xJy>(q z|5g*=%@sk?|NOu6D%BJG&mpAM2}C^-KyC_rvL;lCh)hrF^3!Y>puoKMUI;eE*f z035fxw1n2bwS}$oq;d*O@z0kpe;PO69sUVkvR_DE`rSKPF}<)PM5+3;*vL|Gg3gySN!9;eRj$^4}2Kiqx7r_6L7s?-|1;M%43p5svas^Bj&PemL^ItZsnjVM#~(4E zOwJp*iQfG5R`FMGSVdOMoWC-;z}a%<@y>Dkj<>hfg~Dz=^kq%RHq&*^Sl=dfL8s}} zE-cEjh1%q^mu$SjZvJk2?&Ki>AEu=z)8sVOG%DY3r-~`s@}g zZ8qQ0#VJe_*@L6^@cWzf*b=jU`rvuRkG+f#0`1 zo5;1d_eEdQz^iL(;O~AqzXITWQk6zsjH-x0j}r{}(v^{bL#e@;yUpFQYP-qYdBDG(dPW=zGN z`)P|opU-KRg0i$q(}czOTtMdHPHGp5%22gtrNfcsE3K7A%AJXrZGLMpHj1B-^TWi)BWRNAfKWgn#rur zdi;p`{-IZf8#QMT+nY5KDdW)E{&37Tr?1TJ#pfI?L!U;po&r$H#vkRtzXidn|p~Fz8{%3}qNxzJ(6`m@Wo20AV-D6E$r5h4@JF`D~%nEq+ zRfw_S68aXQ;Hj!y^_rTLE8#HKyERc_uf zvK+^pkbv|1E!8jeH5j`k1MI2y1uZg(ub9?ExxHK7o;o+&H-cvUI$8H4nKtt7AIPwD z8%9LqR%_nDXmX(E^Gw75Z?2M#LG59YDG9oIHVPmdUxQXWabQNndS;^GLnL*hyIUD``6P|Cf#aH;4S6O!8kG0{BNl k;s1!~f8qa!mShjfO$C>0pjsLKvlIr9mr;>!kTeVXAI$A3ApigX literal 2377 zcmds({Xf%tAICr6&D^Yn6Sg{}uW+Wd%@-kDD{7>M;5WfELo7^xF{{MV===J7l_=ls%g~)}MQy zb|o5e$Mz}5CJH!L=dLyA>}<37sHm>4F0fj@$EZLI0&|&BP>TTwBwm97qg4J24P1l> zsEqR6pr@933BszEte7VkG;xd|A{hcXT&Co|h>GGg)%MTl`K94Ykc1gVw0z=ZoURt= zpn9jVTJTk`(-1J~mi8MHK)D;yAAp`2t0ZLrqy2Pa62|Q(mU9U;%nZT9^6Wf5rgMU}brkmY_fuaia;?Uw&JVy9Fdy*1G>dNPcxq z4$h@YhV`XuFYC5zF`lpfrN0FYc98a&MH@=;czR7QuDNz$@L=IwQTIi(QX)@k3sPIi zD!6hFF{n1MD$@}PPr>Fnp;ZTcmhX(jF$lccicT+0Ox~0y`AaSY5E5@SuJpX zr{kL$bS!ruz=3m-_j=*gL+Uh2;y0YSln;7M^;`ADZ}wlR#yYL<$^pjC@{Qg{Iw=c| zfTDfOYNUIL^%lzzRba;GwgPtHp0-*~vwX{)z=$zKgz#%c2JsBdPGG)f zG9xKEAVqc5?n^wfx?)++cNiy4G-&nTUgSnjCwd6O*^s3zO<}E}i<}Ic^ShQ9$;6?cg7_jp2z6 zG|CRv$15EXCUF(br#-*zy)Y?Yi`y!X9~+8Sued`Kncu!Ohn)1VO%~=t!7kWZUAHfJ zc~qCIX)KsH(tYX?FE8d(bnUwOP1d4JW6w>U5F;-*;ouB6#`EVW*a<_M5sBTajQV~? z8qnbTQnO(j<12XU$ola=I>|ciW*Ard)}j^5nJ@k-v@C1(Awzl2`IZdo41r%Qp^oHJd>#g4DcY@^9LM8C)4 z>-=p9xFk|xl;C&+hu&r@;QxgZKI|Ra*1ku5oPWClRV})yvnJ8WiaCJ`4r8A@jOI9vwf#ugwM2Z`}BjlljiRR#+JHv$>onbpQ2$d*)6GmcdpP zzC&1$Q|LP9;ZmNw>_RG{3VnQQaO4L3!ZC%o&WL?pJD@Fe>3FMVFzc{DjTYsbSSTQ@ z^d{`FX?Izn%hR0`1ayQ>&1_J_`wqu8!i_AN=c(UHbeqlo(Hjj>GaWj`3v z-)=WQbxf%THtq2*cOVQu2szXur9a*U;j|10CN<54hmNI$EK;7^|BCl?fmsJ=l$$rt zBq+bLN?nPkEi&i-wk98I-8@>&}I;P&YJ+a%zP2 z{Fd>(;yC`Flo(Dz(XHK|nnyNPX4`qO2MhsI@+j(7T{H)^`|yA)!x|BGZhW>QAWLx{ z_Cg#Vq3aj;C7BaB<3S9IK=R95-rc-}cF9`~N9>&0+@|0Niap*p9De;Tr%GkdhN=n2 z+US+@WMblZ<&Q_8uIer@=E>os;acJAJ~d7&57bp&ue(RSBCPy7)|_LP#OEcSaFJc@ zve}Ft+BTaXB{a&{ - if (hrm.confidence>con || hrm.confidence>=80) { - bpm=hrm.confidence; - con=hrm.confidence; - WIDGETS["bars"].draw(); - if (rst) clearTimeout(rst); - rst = setTimeout(noHrm, 10*60*1000); // forget HRM after 10 minutes - } - }); + // Note: HRM/temperature are commented out (they didn't seem very useful) + // If re-adding them, also adjust `bars` + + // ==HRM start== + // // We show HRM if available, but don't turn it on + // let bpm,rst,con=10; // always ignore HRM with confidence below 10% + // function noHrm() { // last value is no longer valid + // if (rst) clearTimeout(rst); + // rst=bpm=undefined; con=10; + // WIDGETS["bars"].draw(); + // } + // Bangle.on('HRM', hrm=>{ + // if (hrm.confidence>con || hrm.confidence>=80) { + // bpm=hrm.confidence; + // con=hrm.confidence; + // WIDGETS["bars"].draw(); + // if (rst) clearTimeout(rst); + // rst = setTimeout(noHrm, 10*60*1000); // forget HRM after 10 minutes + // } + // }); + // ==HRM end== /** * Draw a bar @@ -42,8 +47,8 @@ const x = this.x, y = this.y, m = process.memory(); let b=0; - 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 - 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 + // ==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); From a44d542053941c7bb588e3d444aeb02ad6aba676 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 30 Nov 2021 22:30:28 +0100 Subject: [PATCH 0094/1839] widbatpc: Fix drawing the bar when charging --- apps.json | 2 +- apps/widbatpc/ChangeLog | 1 + apps/widbatpc/README.md | 4 ++-- apps/widbatpc/widget.js | 16 ++++++++-------- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/apps.json b/apps.json index 2e338a432..351d03bd8 100644 --- a/apps.json +++ b/apps.json @@ -872,7 +872,7 @@ "id": "widbatpc", "name": "Battery Level Widget (with percentage)", "shortName": "Battery Widget", - "version": "0.13", + "version": "0.14", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage", "icon": "widget.png", "type": "widget", diff --git a/apps/widbatpc/ChangeLog b/apps/widbatpc/ChangeLog index 09e4fabf4..99822b5a9 100644 --- a/apps/widbatpc/ChangeLog +++ b/apps/widbatpc/ChangeLog @@ -10,3 +10,4 @@ 0.11: Don't overwrite existing settings on app update 0.12: Fixed for Bangle 2 0.13: Fillbar setting added, see README +0.14: Fix drawing the bar when charging diff --git a/apps/widbatpc/README.md b/apps/widbatpc/README.md index c75154f72..48c6070f4 100644 --- a/apps/widbatpc/README.md +++ b/apps/widbatpc/README.md @@ -5,12 +5,12 @@ Show the current battery level and charging status in the top right of the clock Works with Bangle 1 and Bangle 2 When the fillbar setting is on the level colour will fill the entire -bar. This makes for an easier to read dsiplay when the charge is +bar. This makes for an easier to read display when the charge is below 50%. ![](widbatpc.full.jpg) -When the fillbar setting is off the level colour will follow the battry percentage +When the fillbar setting is off the level colour will follow the battery percentage ![](widbatpc.part.jpg) diff --git a/apps/widbatpc/widget.js b/apps/widbatpc/widget.js index caecf8ae4..3e5ff47b4 100644 --- a/apps/widbatpc/widget.js +++ b/apps/widbatpc/widget.js @@ -79,20 +79,20 @@ // else... var s = 39; var x = this.x, y = this.y; - const l = E.getBattery(); - let xl = x+4+l*(s-12)/100; + const l = E.getBattery(), + c = levelColor(l); - // show bar full in the level color, as you cant see the color if the bar is too small - if (setting('fillbar')) - xl = x+4+100*(s-12)/100; - - c = levelColor(l); - if (Bangle.isCharging() && setting('charger')) { g.setColor(chargerColor()).drawImage(atob( "DhgBHOBzgc4HOP////////////////////3/4HgB4AeAHgB4AeAHgB4AeAHg"),x,y); x+=16; } + + let xl = x+4+l*(s-12)/100; + // show bar full in the level color, as you can't see the color if the bar is too small + if (setting('fillbar')) + xl = x+4+100*(s-12)/100; + g.setColor(g.theme.fg); g.fillRect(x,y+2,x+s-4,y+21); g.clearRect(x+2,y+4,x+s-6,y+19); From e3745f94fc0fd7bf367727a1fa2f43c26bde89b5 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 22:43:45 +0000 Subject: [PATCH 0095/1839] Mylocation: make into an app --- apps.json | 6 +- apps/mylocation/mylocation.app.js | 94 +++++++++++++++++-------------- 2 files changed, 55 insertions(+), 45 deletions(-) diff --git a/apps.json b/apps.json index 0f2d7b738..5442c4d88 100644 --- a/apps.json +++ b/apps.json @@ -4568,13 +4568,15 @@ "description": "My Locations adds a menu in the Settings app to set your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", "readme": "README.md", "tags": "tool,utility", - "type": "app", "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ - {"name":"mylocation.apps.js","url":"mylocation.app.js"}, + {"name":"mylocation.app.js","url":"mylocation.app.js"}, {"name":"mylocation.settings.js","url":"mylocation.settings.js"}, {"name":"mylocation.img","url":"mylocation.icon.js","evaluate": true } ] + "data": [ + {"name":"mylocation.json"} + ] }, { "id": "pebble", diff --git a/apps/mylocation/mylocation.app.js b/apps/mylocation/mylocation.app.js index 49e74a025..43d6addb1 100644 --- a/apps/mylocation/mylocation.app.js +++ b/apps/mylocation/mylocation.app.js @@ -1,7 +1,9 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); +console.log("myloc start"); const SETTINGS_FILE = "mylocation.json"; +let settings; // initialize with default settings... let s = { @@ -10,18 +12,14 @@ let s = { 'location': "London" } -// ...and overwrite them with any saved values -// This way saved values are preserved if a new version adds more settings -const storage = require('Storage') -let settings = storage.readJSON(SETTINGS_FILE, 1) || {} -const saved = settings || {} -for (const key in saved) { - s[key] = saved[key] +function loadSettings() { + console.log("loadSettings()"); + settings = require('Storage').readJSON(SETTINGS_FILE, 1) || s; } function save() { settings = s - storage.write(SETTINGS_FILE, settings) + require('Storage').write(SETTINGS_FILE, settings) } const locations = ["London", "Newcastle", "Edinburgh", "Paris", "New York", "Tokyo","???"]; @@ -30,45 +28,55 @@ const lons = [-0.1276 ,-1.6178 ,-3.1883 ,2.3522 , -74.0060 ,139.6503, 0.0]; function setFromGPS() { console.log("set from GPS"); + Bangle.on('GPS', (gps) => { + //console.log("."); + if (gps.fix === 0) return; + //console.log("fix from GPS"); + s = {'lat': gps.lat, 'lon': gps.lon, 'location': '???' } + Bangle.buzz(1500); // buzz on first position + Bangle.setGPSPower(0); + save(); + + Bangle.setUI("updown", ()=>{ load() }); + E.showPrompt("Location has been saved from the GPS fix",{ + title:"Location Saved", + buttons : {"OK":1} + }).then(function(v) { + load(); // load default clock + }); + }); + Bangle.setGPSPower(1); E.showMessage("Waiting for GPS fix. Place watch in the open. Could take 10 minutes. Long press to abort", "GPS Running"); Bangle.setUI("updown", undefined); } -Bangle.on('GPS', (gps) => { - //console.log("."); - if (gps.fix === 0) return; - //console.log("fix from GPS"); - s = {'lat': gps.lat, 'lon': gps.lon, 'location': '???' } - Bangle.buzz(1500); // buzz on first position - Bangle.setGPSPower(0); - save(); - - Bangle.setUI("updown", ()=>{ load() }); - E.showPrompt("Location has been saved from the GPS fix",{ - title:"Location Saved", - buttons : {"OK":1} - }).then(function(v) { - load(); // load default clock - }); -}); - - -E.showMenu({ - '': { 'title': 'My Location' }, - '< Back': back, - 'City': { - value: 0 | locations.indexOf(s.location), - min: 0, max: 6, - format: v => locations[v], - onchange: v => { - if (v != 6) { - s.location = locations[v]; - s.lat = lats[v]; - s.lon = lons[v]; - save(); +function showMainMenu() { + console.log("showMainMenu"); + const mainmenu = { + '': { 'title': 'My Location' }, + '{ load(); }, + 'City': { + value: 0 | locations.indexOf(s.location), + min: 0, max: 6, + format: v => locations[v], + onchange: v => { + if (v != 6) { + s.location = locations[v]; + s.lat = lats[v]; + s.lon = lons[v]; + save(); + } } }, - }, - 'Set From GPS': ()=>setFromGPS() -}); + 'Set From GPS': ()=>{ setFromGPS(); } + } + + console.log("showMainMenu 2"); + + return E.showMenu(mainmenu); +} + +loadSettings(); +showMainMenu(); +console.log("myloc end"); From 4cbd7e8ea63c5aef83f72ceedcad7a2cc811917d Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 22:46:37 +0000 Subject: [PATCH 0096/1839] Mylocation: make into an app --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 5442c4d88..fc40f83bc 100644 --- a/apps.json +++ b/apps.json @@ -4573,7 +4573,7 @@ {"name":"mylocation.app.js","url":"mylocation.app.js"}, {"name":"mylocation.settings.js","url":"mylocation.settings.js"}, {"name":"mylocation.img","url":"mylocation.icon.js","evaluate": true } - ] + ], "data": [ {"name":"mylocation.json"} ] From 8e56dce22c49a1a80b4dc9142092ea5238ab34ad Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 23:10:36 +0000 Subject: [PATCH 0097/1839] Mylocation: make into an app --- apps/mylocation/mylocation.app.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/mylocation/mylocation.app.js b/apps/mylocation/mylocation.app.js index 43d6addb1..fb2f73fa7 100644 --- a/apps/mylocation/mylocation.app.js +++ b/apps/mylocation/mylocation.app.js @@ -1,6 +1,5 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); -console.log("myloc start"); const SETTINGS_FILE = "mylocation.json"; let settings; @@ -13,7 +12,6 @@ let s = { } function loadSettings() { - console.log("loadSettings()"); settings = require('Storage').readJSON(SETTINGS_FILE, 1) || s; } @@ -27,7 +25,6 @@ const lats = [51.5072 ,54.9783 ,55.9533 ,48.8566 ,40.7128 ,35.6762, 0.0]; const lons = [-0.1276 ,-1.6178 ,-3.1883 ,2.3522 , -74.0060 ,139.6503, 0.0]; function setFromGPS() { - console.log("set from GPS"); Bangle.on('GPS', (gps) => { //console.log("."); if (gps.fix === 0) return; @@ -71,12 +68,8 @@ function showMainMenu() { }, 'Set From GPS': ()=>{ setFromGPS(); } } - - console.log("showMainMenu 2"); - return E.showMenu(mainmenu); } loadSettings(); showMainMenu(); -console.log("myloc end"); From 8ad8ed15dc8e9fe4091d2f3a5b1faf7b828bb0c5 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 23:15:45 +0000 Subject: [PATCH 0098/1839] Mylocation: make into an app --- apps.json | 1 - 1 file changed, 1 deletion(-) diff --git a/apps.json b/apps.json index fc40f83bc..1fab6aa98 100644 --- a/apps.json +++ b/apps.json @@ -4571,7 +4571,6 @@ "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ {"name":"mylocation.app.js","url":"mylocation.app.js"}, - {"name":"mylocation.settings.js","url":"mylocation.settings.js"}, {"name":"mylocation.img","url":"mylocation.icon.js","evaluate": true } ], "data": [ From 848ccd2be996e5127d09e36960775e5cb45a4143 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 23:16:56 +0000 Subject: [PATCH 0099/1839] Mylocation: make into an app --- apps/mylocation/mylocation.settings.js | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 apps/mylocation/mylocation.settings.js diff --git a/apps/mylocation/mylocation.settings.js b/apps/mylocation/mylocation.settings.js deleted file mode 100644 index 4767c4732..000000000 --- a/apps/mylocation/mylocation.settings.js +++ /dev/null @@ -1,4 +0,0 @@ -(function(back) { - // just go right to our app - load("mylocation.app.js"); -})(); From 7785c7ea56867250df5985d0a27a7fd35478e501 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 30 Nov 2021 23:38:29 +0000 Subject: [PATCH 0100/1839] Mylocation: make into an app --- apps.json | 3 ++- apps/mylocation/README.md | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 1fab6aa98..371a4f2f3 100644 --- a/apps.json +++ b/apps.json @@ -4563,9 +4563,10 @@ "name": "My Location", "shortName":"My Location", "icon": "mylocation.png", + "type": "app", "screenshots": [{"url":"screenshot_1.png"}], "version":"0.01", - "description": "My Locations adds a menu in the Settings app to set your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", + "description": "Sets and stores the lat and long of your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", "readme": "README.md", "tags": "tool,utility", "supports": ["BANGLEJS", "BANGLEJS2"], diff --git a/apps/mylocation/README.md b/apps/mylocation/README.md index 6ae1dd530..aa9a04b81 100644 --- a/apps/mylocation/README.md +++ b/apps/mylocation/README.md @@ -1,8 +1,7 @@ # My Location - *a adds a My Location settings menu, stores GPS lat and lon of your preferred city* + *Sets and stores GPS lat and lon of your preferred city* -* My Location is a service app that adds a 'My Location' menu to the settings menu * Select one of the preset Cities or setup through the GPS * Other Apps can read this information to do calculations based on location * When the City shows ??? it means the location has been set through the GPS From 312bed6491d7a9341c7f9de4d1f309e2f85b3fe5 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:00:58 +0900 Subject: [PATCH 0101/1839] Create app.js --- apps/a_speech_timer/app.js | 173 +++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 apps/a_speech_timer/app.js diff --git a/apps/a_speech_timer/app.js b/apps/a_speech_timer/app.js new file mode 100644 index 000000000..dae2545b2 --- /dev/null +++ b/apps/a_speech_timer/app.js @@ -0,0 +1,173 @@ +Graphics.prototype.setFontMichroma36 = function() { +g.setFontCustom(atob("AAAAAAAAAAAAAAAAeAAAAAeAAAAAeAAAAAeAAAAAAAAAAAAAAAAAAAAAAAGAAAAA+AAAAD+AAAAP+AAAA/8AAAD/wAAAf/AAAB/4AAAH/gAAAf+AAAB/4AAAH/gAAAf+AAAAfwAAAAfAAAAAcAAAAAAAAAAAAAAAAAAAAAAAA///AAD///wAH///4AP///8APwAD+APAAAeAeAAAeAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAeAPAAAeAPwAD+AP///8AH///4AD///wAA///AAAAAAAAAAAAAAAAAAAAAEAAAAAOAAAAAfAAAAA+AAAAB8AAAAD8AAAAH4AAAAPwAAAAPgAAAAfAAAAAf///+Af///+Af///+Af///+AAAAAAAAAAAAAAAAAAAAAAAAAA/Af+AD/A/+AH/B/+AP/D/+APwD4eAPADweAfADweAeADweAeADweAeADweAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAPgeAeAPAeAeAPAeAeAPAeAeAPAeAfAPAeAPw/AeAP/+AeAH/+AeAD/8AeAB/wAOAAAAAAAAAAAAAAAAAAAAAAAAAB8APgAD8AP4AH8AP8AP8AP8APgAB+AfAAAeAeAAAeAeAAAPAeAAAPAeAAAPAeAAAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAeAfAeAeAPx/h+AP///+AH///8AD///4AB/h/gAAAAAAAAAAAAAAAAAAAAAAeAAAAA/AAAAA/AAAAB/AAAAD/AAAAH/AAAAPvAAAAPPAAAAfPAAAA+PAAAB8PAAAD4PAAADwPAAAHwPAAAPgPAAAfAPAAA+APAAA8APAAB8APAAD4APAAHwAPAAPgAPAAPAAPAAfAAPAAf///+Af///+Af///+Af///+AAAAPAAAAAPAAAAAPAAAAAPAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAf/8PgAf/8P4Af/8P8Af/8P8AeB4A+AeB4AeAeDwAeAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAfAeDwAeAeD4A+AeD+D+AeB//8AeB//4AeA//4AAAP/AAAAAAAAAAAAAAAAAAAAAAAAAAA///AAD///wAH///4AH///8AP4fB+APAeAeAfA8AeAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAfA8APAPA+AeAPgeAeAP8fh+AH8f/8AD8P/8AA8H/4AAAB/gAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAAeAAAAAeAAAAAeAAAAAeAAAAAeAAACAeAAAGAeAAAOAeAAAeAeAAA+AeAAD+AeAAH8AeAAP4AeAAfwAeAA/gAeAB/AAeAD+AAeAP4AAeAfwAAeA/gAAeB/AAAeD+AAAeH8AAAefwAAAe/gAAAf/AAAAf+AAAAf8AAAAf4AAAAfgAAAAfAAAAAAAAAAAAAAAAAAAAAAAAAAMAAB+B/wAD/j/4AH/3/8AP///+AP//A+AfB+AeAeA+AeAeA+APAeA+APAeA+APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA+APAeA+APAeA+APAeA+AOAeA+AeAPh/A+AP///+AP/3/8AH/3/8AB/D/wAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAD/4HAAH/8HwAP/+H4AP5/H8AfAfA8AeAPAeAeAPAeAeAPAeAeAHgfAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHAPAeAPAOAeAPAeAPAPAeAPwfB+AP///8AH///4AD///wAA///AAAAAAAAAAAAAAAAAAAAAAAAAAAB8DwAAB8HwAAB8HwAAB8DwAAAAAAAAAAAAA"), 46, atob("CBIkESMjJCMjIyMjCA=="), 36+(1<<8)+(1<<16)); +}; + +Graphics.prototype.setFontMichroma16 = function(scale) { +g.setFontCustom(atob("AAAAGAAYAAAAGAB4A/APwD4AeADgAAAAAAA/8H/4YBjAGMAcwBzAHMAcwBzAHMAYYBh/+D/wAAAAABgAOABwAGAA//h/+AAAAAA4+Hn4YZjhmMOYw5jDmMMYwxjDGOMYYxh/GD4YAAAAADBwcHhgGOAYwBzHHMccxxzHHMcc5xhnGH/4PfAAAAAAAOAB4APgB2AGYAxgHGA4YDBgYGD/+P/4AOAAYAAAAAD+cP547BjsGOwc7BzsHOwc7BzsHOwY7zjv+APgAAAAAD/wf/hmGOYYxhzGHMYcxhzGHOYYZhh3uDP4AeAAAEAA4ADgAOAI4DjgeODw4eDjgOcA7gD8APgA8AAAAAAAAAA58H/4bxjmGMYcxhzGHMYcxhzGHOYYbxh/+DnwAAAAADxgfnBnOOMYwxjDHMMcwxzDHMMY4xhjOH/4P/AAAAAABnAGcAAA"), 46, atob("BAgQCBAQEBAQEBAQBA=="), 16+(scale<<8)+(1<<16)); +}; + +function timeToString(duration) { + var hrs = ~~(duration / 3600); + var mins = ~~((duration % 3600) / 60); + var secs = ~~duration % 60; + var ret = ""; + if (hrs > 0) { + ret += "" + hrs + ":" + (mins < 10 ? "0" : ""); + } + ret += "" + mins + ":" + (secs < 10 ? "0" : ""); + ret += "" + secs; + return ret; +} + +var newtimer_left_from = 60; +var newtimer_left_to = 2*60; + +var newtimer_right_from = 5*60; +var newtimer_right_to = 7*60; + +var current_from = 5*60; +var current_mid = 6*60; +var current_to = 7*60; +var current_value = 0; + +var timerinterval; +var istimeron = false; + +var islocked = false; + +function countDown() { + current_value++; + draw(); + + if (current_value == current_from) { + Bangle.buzz(500); + } else if (current_value == current_mid) { + Bangle.buzz(400).then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 800)); + }).then(()=>{ + return Bangle.buzz(500); + }); + } else if (current_value == current_to) { + Bangle.buzz(300).then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 600)); + }).then(()=>{ + Bangle.buzz(300).then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 600)); + }).then(()=>{ + return Bangle.buzz(500); + }); + }); + } + +} + +Bangle.on('touch',(touchside, touchdata)=>{ + if (!islocked && istimeron && touchdata.y > (100+10)) { + Bangle.buzz(40); + istimeron = false; + clearInterval(timerinterval); + } else if (touchdata.y > 24 && touchdata.y < (100-10)) { + Bangle.buzz(40); + islocked = !islocked; + } else if (!islocked && touchdata.y > (100+10) && touchdata.x > 88 + 10) { + Bangle.buzz(40); + current_from = newtimer_right_from; + current_to = newtimer_right_to; + current_mid = (current_from + current_to) / 2; + current_value = 0; + if (timerinterval) clearInterval(timerinterval); + timerinterval = setInterval(countDown, 1000); + istimeron = true; + } else if (!islocked && touchdata.y > (100+10) && touchdata.x < 88 - 10) { + Bangle.buzz(40); + current_from = newtimer_left_from; + current_to = newtimer_left_to; + current_mid = (current_from + current_to) / 2; + current_value = 0; + if (timerinterval) clearInterval(timerinterval); + timerinterval = setInterval(countDown, 1000); + istimeron = true; + } + showInstructions = false; + draw(); +}); + +Bangle.on('swipe',(swiperight, swipedown)=>{ + console.log(swiperight); + console.log(swipedown); + + if (swiperight == -1) { + if (newtimer_left_from >= 60) { + newtimer_left_from += 60; + newtimer_left_to += 60; + } else { // special case for 0:30 to 1:00 + newtimer_left_from = 60; + newtimer_left_to = 120; + } + newtimer_right_from += 60; + newtimer_right_to += 60; + draw(); + } else if (swiperight == 1) { + if (newtimer_left_from > 60) { + newtimer_left_from -= 60; + newtimer_left_to -= 60; + } else { // special case for 0:30 to 1:00 + newtimer_left_from = 30; + newtimer_left_to = 60; + } + + if (newtimer_right_from > 120) { + newtimer_right_from -= 60; + newtimer_right_to -= 60; + } + draw(); + } +}); + +var drawTimeout; +var showInstructions = true; + +function draw() { + g.reset(); + if (current_value >= current_to) { g.setBgColor("#F00"); } + else if (current_value >= current_mid) { g.setBgColor("#FF0"); } + else if (current_value >= current_from) { g.setBgColor("#8F8"); } + g.clearRect(0,24,176,176); + + g.reset(); + g.setFontAlign(0, 0); + + g.setFont("Michroma36").drawString(timeToString(current_value), 88, 62); + + g.setFont("HaxorNarrow7x17"); + g.drawString(timeToString(current_from), 44, 62+26); + g.drawString(timeToString(current_mid), 88, 62+26); + g.drawString(timeToString(current_to), 132, 62+26); + + if (current_value >= current_from) { g.drawRect(44-1,62+26+9,44+1,62+26+9+1); } + if (current_value >= current_mid) { g.drawRect(88-1,62+26+9,88+1,62+26+9+1); } + if (current_value >= current_to) { g.drawRect(132-1,62+26+9,132+1,62+26+9+1); } + + if (showInstructions) { + g.setFont("6x8").drawString("Tapping timer locks buttons", 88, 100+5); + g.setFont("6x8").drawString("<= Swipe to change time =>", 88, 168); + } + + g.setColor(islocked ? "#444" : "#000"); + g.setFont("Michroma16"); + g.drawString(timeToString(newtimer_left_from), 44, 138-9); + g.drawString(timeToString(newtimer_left_to), 44, 138+9); + g.drawString(timeToString(newtimer_right_from), 132, 138-9); + g.drawString(timeToString(newtimer_right_to), 132, 138+9); + + g.drawRect(0+8,138-24, 88-9+1, 138+22+1); + g.drawRect(0+8,138-24, 88-9, 138+22); + g.drawRect(88+8,138-24, 176-10+1, 138+22+1); + g.drawRect(88+8,138-24, 176-10, 138+22); +} + +require("FontHaxorNarrow7x17").add(Graphics); +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +draw(); From 673fa8820f779a79bcfa46819990e5717a4d49ba Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:01:48 +0900 Subject: [PATCH 0102/1839] Add files via upload --- apps/a_speech_timer/app.png | Bin 0 -> 3036 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/a_speech_timer/app.png diff --git a/apps/a_speech_timer/app.png b/apps/a_speech_timer/app.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb777fa7988b5d0a44e31d7238925f0ca47027a GIT binary patch literal 3036 zcmaJ@3p`Z$7r!HUj7_!?B{4>i$zz^u&6t_Q$XoJCMH*&gm7T#^Y#jC4Ec1rSneYmM!f8k4B7!W3=T`g;)ob59BV=ZWegs`71mpW zD&=6Cy*vO=0XH2|=zlRJNH2(<$bM!H+ ze;g*D1uuZ+ld<3E051S(=FRrM#EQWHUHCS$rnjNa!yrz6kXE zFW?fz5+Im+q9a&|bQ+&VrSTaQS@|1damE;|8(97(cp}Es5JMo!Qu{C4&v-0D86d+K zSmv8(Da#VeFL7`~-MCy9<=;KM;KMw6(Pj}&Ldz<8Nrf-8&-^afKNKj4{JR$^(23~i zJ^)adwx#ZH^HjcdR%o+lzgnYYD!(Q1uAQq?6ESlhF}fq!qhPi4bsWnFSrnj`506*+ zdQ?>81vNOTu7ZQ+2Z)e{2Kxf=sT!w~>?Bj+;}bzo%x>4c?~Q1?MG;JkM&_P3pPeA% zdH&D6*1aDb-C|_K8hEz1%s+K&RGNz;siY&|&kygrud_$GE5>W0X1xaRc>GEo(i$Bd z)n|z3lmX@TWKDD~Nr>YQwLhy%xLGvPbA#vZ-dUHh(wm-QnG57GYGWWOnkfFBts#B& z7k8bjy1&M{E_D?G6VNWcV4qc`vU%gijhi;fwp(Iy$q^oV_cGlI3IxRVHky$@psxTRdE~h>`Z{(6U104+r9Bn$P0T?@V=(rtq0lZ^;fx(Itn|4G+>k%)R41zRD{|5NaB%~Lw>w$Qt!dRL9I5}S`y>w?Qahq_sNRbS1)o_Yw!Cd z`D|CgiSsR|r2UN|kq&uA^mL`w^vI)2fkU@pv4dAye((Iz-rk;Ed{gkMZ*t_(_NbYM z)k2=?!$y&=9;wwdX}J;A;R^7g2bo$c(%t@H?tM9@H@x`_);`mS*;#zrVQ%gno_QyE zmFC(X){@vqxX}?lr@}`_h419UUF%85y>@399R*HBk}q zA~}0SKbvQ2`HcISm6q5mzD`c6zs%L2fWbC7Y>Rx0dHnk2fnz;4#2c#p zTXU58rVqCMY)2iuOslI38&~ZGQ~6{d59M8De%JC8OIp4KfrwK*?M{n+_j+*PUd8}< zXnOqVAv&FEZCwT-_PSnlQa+dWs=slz#WEIR{)@uB}_@7b(;2x8vredha zJe7jC+4mH?NlbbDdYiYTsr}}knPhBgQ2cP0=A9KM9gezN?s^ zEf>_9L#T9r1hX@fvv9N9q~iROs`j?uI7fDh)|>5==4}7AX3Xb#6VpoX!tqjL^`osJ z^7V2BX4Eb2;G5ZK=wjmaRod!%=fFO)x3Ov0tbOFGLqimbj(4QRbX{PTTP16-g6^Kw zGxR7y8W=!FqhngFVxF9(UpYMD5heW9QYY=DG5?)&nm#;pcWlp3`zy{{iy9gl`qIE} zOmAg~rLnoXRzzXj~B%aEQKeqLAH00wSCC`!wh8i%#MVt_U|M>}vK{Q@Gu{N<&}W+cQ9m7-o`4 zsLFJ(p_8KLwz*x>R8`@Pf!xQ=f0xx3SlM;2%WH^)AmVN_YFmR#N%*#S32VjC~%Lglw6 z#l^)r{Xks1QpxqLw(IWQu>NpWGqqmnqH+6nH*gYU# yJ4%fcGfsA|u23h2XeHGe^>e7deLFk-@M$Mu_WQQ7zPGYpR9h=2YN^G+xW54KKFVwW literal 0 HcmV?d00001 From 9033db08bf1a56d1f852a60795eb75d2bdee0f70 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:03:45 +0900 Subject: [PATCH 0103/1839] Create app-icon.js --- apps/a_speech_timer/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/a_speech_timer/app-icon.js diff --git a/apps/a_speech_timer/app-icon.js b/apps/a_speech_timer/app-icon.js new file mode 100644 index 000000000..1fdb2c509 --- /dev/null +++ b/apps/a_speech_timer/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgP//kAj//AAP5/+PApH7//PAonvAoXzAonj//nApHggEHAoWAgA5BAAJCCAoU/IYIFCv///w0CAonrv/HAoXLv+DAogLFgPeAoV+nlOAoV4/8+AoV79+eFIVzAof7u/v5xBCs4FL84FE//O74FBu4FB64FD73TAoNz/+eAoV5IIIFCvl8vwFCv8A/wFDO4IFFFIQFCGoSVFUIqtDh65D/1vYof+Y4LLDw7dD/0ndIYRCeoQFC/P/z/+i///oFBGoX8gEfAgI=")) From da133e2ccd7ee837d078430095733180929fff4b Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:09:06 +0900 Subject: [PATCH 0104/1839] Create ChangeLog --- apps/a_speech_timer/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/a_speech_timer/ChangeLog diff --git a/apps/a_speech_timer/ChangeLog b/apps/a_speech_timer/ChangeLog new file mode 100644 index 000000000..4a8e3fbe7 --- /dev/null +++ b/apps/a_speech_timer/ChangeLog @@ -0,0 +1 @@ +1.00: Release (2021/12/01) From 18c3461e6e4191433897f3b1e10a9f68f7b97fa8 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:20:41 +0900 Subject: [PATCH 0105/1839] Create README.md --- apps/a_speech_timer/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 apps/a_speech_timer/README.md diff --git a/apps/a_speech_timer/README.md b/apps/a_speech_timer/README.md new file mode 100644 index 000000000..98d2d4517 --- /dev/null +++ b/apps/a_speech_timer/README.md @@ -0,0 +1,12 @@ +# A Speech Timer + +* A timer designed to help keeping your speeches and presentations to time +* Vibrates 1-2-3 times and changes screen color within the target time range. + * Example for a 5 to 7 minutes speech: vibrates once at 5:00 (green), twice at 6:00 (yellow), thrice at 7:00 (red). +* Use the buttons to start a timer +* Swipe left or right to choose different target times + +![](screenshot.png) + +## Creator +[@alainsaas](https://github.com/alainsaas) From 13b01fe82955ca3ba595ed115fd1bfc6acd7a4fc Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:20:52 +0900 Subject: [PATCH 0106/1839] Add files via upload --- apps/a_speech_timer/screenshot0.png | Bin 0 -> 3276 bytes apps/a_speech_timer/screenshot1.png | Bin 0 -> 3457 bytes apps/a_speech_timer/screenshot2.png | Bin 0 -> 3401 bytes apps/a_speech_timer/screenshot3.png | Bin 0 -> 3374 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/a_speech_timer/screenshot0.png create mode 100644 apps/a_speech_timer/screenshot1.png create mode 100644 apps/a_speech_timer/screenshot2.png create mode 100644 apps/a_speech_timer/screenshot3.png diff --git a/apps/a_speech_timer/screenshot0.png b/apps/a_speech_timer/screenshot0.png new file mode 100644 index 0000000000000000000000000000000000000000..ee3ababc1abf849d688e97c5ceb8d3ae8180f05c GIT binary patch literal 3276 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 literal 0 HcmV?d00001 diff --git a/apps/a_speech_timer/screenshot1.png b/apps/a_speech_timer/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..69ea91e95332e8b97e6de3205f72319215bd6195 GIT binary patch literal 3457 zcmcha`8(U&_QyY;h@n)>s#=2RrKVPWmC~YU(?Lm9)liY5XoDycjwzw$8jh>S(1TK{ z12IoErso)Iu1W|(Rcc5KHN?!#xqrd^>HEXp>)C7Vz4m^d_g?#X?RbWm@xwibDCcww-%j#y)Tm$-BBTa$Q{?iNGNrpGgui6BmmvV-JC)AEdrEL-CIqOA* zQGkwV7lzP38K3(5_10*%_r=%5!~LE0{G&pOnbfudPprEV5ISSdc(62iQUIve-Ee}78x&u-!5@2b>FodGrTBRFnRg;#O7Ih3`VI4WXfw?&>O{*~1(AA7ESqWl{GjC9}s_^6T+B5@SVMgf1j)+xt)Kzz9wMXw>U#{8<=Myj{Pvr5>6^ zD4nSpwDZ&#Z}h>9Dv=VV)vb8(N?V19Zw=JqboyLm_x6^HYE^qG`NVWGg@q~Y7 zKo@4iCQ#?}~QjPDAuFF-5K;Km7NGfCQ`T3wBmA87$~%SQ>M@-ks~@0|&r;o%D02j>A4Tt3X7*na+ggmaPE3Nw(zwda^r>{6~HRC{flNXW$lRKFjc?@Io zX^MtmJzKgsGqrIuTgru{JsJ5_+Dpv!*z?a_3pT7-Cfc(aL({o5OR8WYY4-KnVd8qS zsGd@M3G(z-l~1IYuqC(+i_=^UZ(na!+A#KnpLG$L2_R>OV2$CEjawA`#d`#n)aZ`~ z2~<{|0L)h5FmMJYZS{ftzyv5Oi%{}aRUpaDbO$s;AVFcmk`ZPg$QHFKVo8ZoSlB#) z(}Dt+*q{qeWh4OY%yVrTWdazsr7Z;WLRWWXRUxqu$f#nj1x;OnM5CFA=}U@IV87fN z&>+~wmElc6f$2?M6cok_EjPQIRrx z_6ITzK8m?+-5_~Li5`=@JB?<0wstiQF>Vy!r@{Gs-NdlhGVSdo8#ng`-OY4#Xk!(+ zR+TKA+eA%PARJ1f5qrX8%q`fxaAf=!?VX%dY(V0tBP1R(FwvDDTfxt>BK4XVbIy}- z?u^@JB6>@PgrFn@QPjdXCXZUpE^RIFX2jz-@~NUi(+Le#KGNTq1Yr9Xyj|>A9&O7N zOkNgeyip1|>FYjuLqHr?+C`kjgA*v)JsUoT7^%R=!KyUX_d*M=FF-ky&1PwD)a|?h z+)c*tNq{^wbHQQW3a$X3-z`N=p3DGXP#Gz4klxVWl5VzFho00XG?s`_L?HUIuT+v% zA$GtKYWj(&5C+`89iehngTxQ!KFfCWn694Fpp4SObo`Rm6iINtRgIwa>XluJGQ@3#1g(-LKP=3*vcKO0xM?o`urxJVUKZ^Qf6_NUl*}=qrMjoH0+%1h z3z5UT_>;4TGh<(!w{;>Orvw^#o}Y}f zf1dDV8$-IThwOWKV!Z4kS}w7mxs>cj>sScp$u|@^xDE|2*0t06MMA--&`FyQWQz zMvq-)G>vsFD#+U&iK+|+-mP(_c2scsc3x9Gxol#9$f)cl%Ae7Yz%3zgFI@wgG`)j& z?EI6y?Xa8@stn2qB15uP*BH)UbNOaqVUtnbHh#+A&;E_e0iNw%AiFroT(BJuDd)G) z9xvr7aMe6p95H_B+oKd(+AMP4>^I`*}W&KmF@!(0cpYx&?`FiOz3$-+%aQWHMVb7dfBcE*4*L@p%9|ul zcsiNqA#s3eYa8dOZ(2~YN~Cw&GCZ5b9(Dfu-rlPvSHI~?T~t_@vpQ7Pnye;2)X3?o zl{J|RXql_jv)KJjJh9A2z>Y; zcEpxjQL&I`MG$?-e)a)Jg{-B@%vm>3@lz^+hTK%pOXPJUu)mGwez3ph72#*uM; zhc4n~?Nx*v>Qs`e%OfbOZ-OoVR-`auq>R}?zwdl8_Jdr#WW$+$&(BSVO&s$6_4S*2 zO`Qxuz2Qv<6=gcMsKpUT6c69U+qyyfw15>G5!>-WSW}vUSVgTU!j zUJ2B`=zXeATA~YLV%EXownAw~1e$!;}PPN(Ijn7w_=!>=BU#ki2+ z2|dp)K@to*Q$tm5xXQ_g^UyP4wf66IY&IdK^0oCHj1*vo?p)}NENmCOnx)5IrI|- z%!w+Ihw&Sfx?;w0^>bI2p_x+6*>`Un+Pt*qsG|RSDMD`<>uz5U+w_4^Jy`CTrS*L~ z?>asiuzJ@(-A|HIyq+@gnp?<*A1MhMq$Q;)u6B*JQ_|d1k7`{gCIhutb&}kxiXuqn z{Vx^CQucEHbsLmBIpY5j`2*nohhK^7HCz6Fw7-qV>~U5eYp><%oOL@;_}=`ooe16n ztQ1TEE76MYkS9W5ve2E}wb=CJr#;=5 zvC&+pik`t@Te%2UmVa5p#soMg>Fl`21-Ecv=A(Qr&*g8^>0EH*U{ytgxNf0#8a14Y iV9sX0*}bPYpZr(h--R)ASGj*G;N~?;^HNhx1>If>1T2iXeEo@4xroTW`Iy);W8fv(Mgpt-a6w?R}CR?X3l1r(gg8 z2-sY`;>4kK|4d#U&RW|vkK_>Wo|CmXP%|LC%(=v6bH&Uh3b|T{h?tiFCS}%^pX?PEUcb);MXNsa((1YP$Le zezB2yL+bA!;l-q&(W>o*!vjzPdh3@tSLq}7Uf-~^VEykGtEp|mLW6YZ`=C&n!ES0$ z-+=q6fG-RPYiB5~ur59zmMcf#VT62$_{jUImk}R#iP1UdypPTipekQj#rioV&08dW6O@P30Dr~Dzai%+aF$HPV7IE@EyG_ zjpcHmGP_zjzV+kgi`4gzGH1y|K@~YQO~O&&WyOXMmyZRrJVVsQXw9xkjEc)v7J|*71K9!}W}AxEW#)GJ z8=4^eG``N4i6zc&gEGv`H`5ve7y({GEP?4G=B_9*W7s7jiydF9fa2aD-@)(?ho5x+ zns84x{Xr<9c;Dt4oU$yoF^OPUAc({-nKD?}PGFiX5zI{?Ri;O)D4zOS?{Ne1kxv&1 zv~5Rn>F-qL#ARv0Xd^Sq`)bdjgz#UflTE3c95=}dgr%IjC?yiwu6z)y6Pbp^A~=R} zfgC-ZyQ8N~;v~2J)Pv?FcNy@U_5ZO|4jwn5I#<3c>-5T47H)1sNe$yQ9ZN>}`@fK^ zHyg&QcLNyLdpw)9+LF=t-}t*5e7vW}kAGo%P#c;4k<|u7uObetc7%)>*Bx#}tiAq; z*pRJ5w{@+LBoSsbwc~=QMX+y7xFt47p*G|dg*BT@PIiR(IY2LWv?Gf($4ykiN+A$d zFR^d=1r8A7w}#8%GVF^B#3{bCKq&Xd@N)Jh#N)VhH4eCJ5c>-fNJ%IW6{J{~I}Grn zw8DrS*`*(S4?s1ZbT?B#w(#;L4O|yx7{*I08C7CH>m>BOKrkkJZ@v`})`5R=_8r|DLMk4LzvM8Otko}QI9K9jnoA3Kc|M`cfGnp1j0fSys%WUTUi49G9_jP z;(m|Vh6{UQz#unz(d!bgEsbZ%3x%n_1a+J*2khIKQhbXo>9n@Rkc9fK?vp+CjR=U* z9`DVpFdig`nLP!GGKb#zB1(beIHBC2jW|T~IckAbS=5A-r7f}8EY$?R+v?|?zT}5Q3ynmm;?gD9cD&y2G<1E z*MRkh6& zZZ!D28?K2q5QB5><^`kB-Ki7_D>4#Yzli}isQKdOK2asyP%F)NQULCvpFowHMo2^y zEQ?E@d$dXzQFNMUIwl`C@cMqRU5uCyy8L?Wv&&vgED|BL*dTD;$=lJUxK~&{ zgSh}>QUau6gnqeJVgAA!$>pagCl-$mwpaV<>2J@4Pgs<@R#u#KYmQ=oQ?4i%(K!XJ zn)fXcems=a4$P7M$m~d(|D^ByTyAysW2QRTI6bfV;hj9MAwHPTNg18F1_`S)k%Cuw z5B@v_rmA)olZT3x#Fsq2sZ3rJCnMhkF7HuK;y+(zge>J0*Vm_iZ_-^C0(yET`2d~6 z#b?@NNXfR6`vWw^GSi)$d=rq8^F z{2nr3`h$Z-+ zpz^;XmMP9|79AEoR#>$u2TuUm6UD&y2(n&6iJkFqTjWSr&1sg%2{eb-Tg}b9@H0N+?a2&urr`g<{6zB- zwDP;VY;CMf{#gLg-up;0|EaTW_+9A+E5RXcT@n+RSkdx2p*a8h*~Mv(TI0zH>bY-T z37@?Gg3t;F(HRDME9^2|?u70=A>o0&u5|dq-{^QO?#7(s>;)$pI(UVx0Mxiz5w!@1 z<@C1gCaxTz#O0O|lZB_keMP*1e|hNLoZu$JGufo=%2K~jAU9?q=FZ%0#^=h%r~)gX zJpKuOxx}7JVyg(EKdFn)Kh8t>D3eS6r0Uvg=#Jv9Eh8}(ITp!cuNHV~f|If!2vf6U z-}JF48EW?D3wZQr^Gw&B zdB=_r2-T`1ovqukQcejs=0;cEm`5?tBWEhKSO{%5<{9)@P6GS zc(=Hl`^mF_YJ;*4sUFrlUbmH&PZvinW%7J{pe}`WkNqU^ryI>>>6v~t-{t^=q|r5g z%3)&TG!{O6?E}0pGqAd7F9g(tv3{%&dU^A_fzK+kghmVahW*3TjmM&%z|@BTPM{-# zO?~5u zHL9i5Ymr%C+aiHTu}nd>NI&;&N+ksviqOXH603&phf||g)oGqr);^ef%=vX|`}xj} zGLhI)erM^|05z_47@jnKXb1t}M;)CrS=Ya6Im zi{?lUPG9gmD6Y_3$p<20wD{nE0EcdrSK@{dDwMX!3sT_~&=zOt0C?}&XUuu%#v|1_ zpb`JZ-$+<u{-<^}P2yM?izkEGV_n2{f#Yw)miqop^ z3GVrZfV4#t@x=JBz-&#l4x#l&4xc7Gda~qogtAK8x2%qTKMH2)<~$8uSk-uG;*wo{ z0x5&;N18c>;vV|S31|s`lsW3%@(hO7Dex0|Art4dtEz!U^gjCSQ#IVGd;=%D$&HYS zmy&2zoM)Ld-6P92;h*Dw(%Tgp5!jsvL%FH+=)3v5qR733Mi*$K#*tbIo>5?SW+f#t zKqch}@*G$*O$65Dd~d-@)w!bz(0QIP7N?1d6S(-7Ij6@mXOf6MAoy+EQAf?i6wnay fvD^PYu@6C|G?r|FX*!YfHv()d?XT3BqaOYXrs`nl literal 0 HcmV?d00001 diff --git a/apps/a_speech_timer/screenshot3.png b/apps/a_speech_timer/screenshot3.png new file mode 100644 index 0000000000000000000000000000000000000000..7b67b6f0156354dc839f5194e1a1fbc1c54ed9a1 GIT binary patch literal 3374 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 bvNGFCP4eAd222Y+K)?liN4u7DzS;i;FilcV literal 0 HcmV?d00001 From 8f0856d8716af6e1058a9923e0e5850734303d72 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:21:21 +0900 Subject: [PATCH 0107/1839] Update README.md --- apps/a_speech_timer/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/a_speech_timer/README.md b/apps/a_speech_timer/README.md index 98d2d4517..a6568649f 100644 --- a/apps/a_speech_timer/README.md +++ b/apps/a_speech_timer/README.md @@ -6,7 +6,10 @@ * Use the buttons to start a timer * Swipe left or right to choose different target times -![](screenshot.png) +![](screenshot0.png) +![](screenshot1.png) +![](screenshot2.png) +![](screenshot3.png) ## Creator [@alainsaas](https://github.com/alainsaas) From 541adf4c16c7bf2e522c3343b7675831b9e13343 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:22:44 +0900 Subject: [PATCH 0108/1839] Update README.md --- apps/a_speech_timer/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/a_speech_timer/README.md b/apps/a_speech_timer/README.md index a6568649f..098c352f3 100644 --- a/apps/a_speech_timer/README.md +++ b/apps/a_speech_timer/README.md @@ -5,6 +5,7 @@ * Example for a 5 to 7 minutes speech: vibrates once at 5:00 (green), twice at 6:00 (yellow), thrice at 7:00 (red). * Use the buttons to start a timer * Swipe left or right to choose different target times +* Touching the timer on the upper part of the screen locks (or unlocks) the buttons to prevent accidental changes ![](screenshot0.png) ![](screenshot1.png) From 3507dcde457b78beede4ee033af1f38090a1a71d Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:26:52 +0900 Subject: [PATCH 0109/1839] Update apps.json --- apps.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps.json b/apps.json index 36102264e..cb8a460f7 100644 --- a/apps.json +++ b/apps.json @@ -4557,5 +4557,19 @@ { "name": "sensible.app.js", "url": "sensible.js" }, { "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true } ] +}, +{ + "id":"a_speech_timer", + "name":"A Speech TImer", + "icon": "app.png", + "version":"1.00", + "description": "A timer designed to help keeping your speeches and presentations to time.", + "tags": "tool,timer", + "readme":"README.md", + "supports":["BANGLEJS2"], + "storage": [ + {"name":"a_speech_timer.app.js","url":"app.js"}, + {"name":"a_speech_timer.img","url":"app-icon.js","evaluate":true} + ] } ] From 3c7d6b795d50aac5d6c3945a4a9af1ee013154ad Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Wed, 1 Dec 2021 15:28:23 +0900 Subject: [PATCH 0110/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index cb8a460f7..50f02c953 100644 --- a/apps.json +++ b/apps.json @@ -4560,7 +4560,7 @@ }, { "id":"a_speech_timer", - "name":"A Speech TImer", + "name":"A Speech Timer", "icon": "app.png", "version":"1.00", "description": "A timer designed to help keeping your speeches and presentations to time.", From 43312a782a58cbbe6cf2f8c4d49ae1d898bc82d5 Mon Sep 17 00:00:00 2001 From: Marco H Date: Wed, 1 Dec 2021 10:23:07 +0100 Subject: [PATCH 0111/1839] Update README.md Fix spelling of the Scottish capital city in the README :) --- apps/mylocation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mylocation/README.md b/apps/mylocation/README.md index aa9a04b81..fd597397a 100644 --- a/apps/mylocation/README.md +++ b/apps/mylocation/README.md @@ -20,7 +20,7 @@ ### Select one of the Preset Cities -* The presets are London, Newcastle, Edinbrough, Paris, New York, Tokyo +* The presets are London, Newcastle, Edinburgh, Paris, New York, Tokyo ![](screenshot_1.png) From f3dffdb3e1d43cce05fde4a1bd31d043c758eedb Mon Sep 17 00:00:00 2001 From: Marco H Date: Wed, 1 Dec 2021 13:44:12 +0100 Subject: [PATCH 0112/1839] Change app icon to white --- apps/poweroff/app.png | Bin 882 -> 425 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/poweroff/app.png b/apps/poweroff/app.png index 5c199c3baa43660d2ff1589bfcef3fc8826da228..2b088b7216ce9d0ff9b61ea41f3002ce6bca7ad8 100644 GIT binary patch delta 399 zcmV;A0dW5E2B`y(B!3BTNLh0L01FZT01FZU(%pXi00047NklefJI>4dkt7M*1d%l z7LWzD2qX6yuCM@)nE6OCHJ^G23Gf`LG~(5IoLWdofG*H`uK}Is?W-7v0xT!0#9EYv zWpV4;LjgMZ8~2m|%dv_;7LyWCX|%g`1av!^#hVFa9qZ1&cLM^C{Z&DIH2&ukihLoX z4kC}m{P_ul{(q~n-06Df75vf!EMh#1NUUOnCLoP?MC>FwFiR7F!(JoEStC=kV#ql> z0ZERK9!;YILwdnV36P>l0{~~@kpU}aT7UqYB_i9r^g;D%PDHLkV1mB0t8@SW delta 859 zcmZ3<{E2OXNJhzJaYXwRLK1vi?bN-y#`FD1c#Cc4 zC&Vr=3D#hISA8sQvtJ$m1(n*TyFWe2U!1A8j$UHGB6Zz4sza+g&HNt~EJ*=w*Tfqw}G(ozolBxK3`Z zTYEJ0WI}8lb8o}@Mf-IZG^}0p|E$x2JulvesTnKGVvDSOUM-oya;Ed2XR49wgniGs zDh1~}{m;I-Z{39Yr%Rc1IwF?q%7izz71Ss;G;}MuEtb9A;=aVZSekdTJe!znPy4j+ zbo~$BEHe&03sGjA$9doPOLyz6=q25kT|5Oj3vNID-d6hQ!Kx?P{u?yAe3vIC+e2-O=-|M*ZO1zv8xab_?%ki#`*0`E=c7u?Fh{h4l&Yd7>+~+0SQq zSGI92GrP0;{X~`-XFZm9RCn&)U7ISf!)uq@lT6<`neH1b*C&d6XPW2k!CW2?P_=T) zpUVroZl9Jpy4SP!wXiZW);2J(GBB7nRdgAOj@gTe~DWM4fNdsc$ From 2d190278f224253b969b8a0c742166d4fe193147 Mon Sep 17 00:00:00 2001 From: Marco H Date: Wed, 1 Dec 2021 13:45:24 +0100 Subject: [PATCH 0113/1839] Change app icon color to white --- apps/poweroff/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/poweroff/app-icon.js b/apps/poweroff/app-icon.js index 7caf256a2..16c0ad8e7 100644 --- a/apps/poweroff/app-icon.js +++ b/apps/poweroff/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwMB/4Ak/k/ArX8AoIGC/F8n0fAoPwAoMPAoPgAoMHAoPAC4MDAoPBAoODAoODAoPBAoOHAoPhAo8HAoPgAoMPAoPwArRQCFIRQCGoQCBHYYFEKARNCAQQIC4ACBMoXgv/+EwXwn/8GQX4g/gRIX8b4KVC/wFBv6iCwDnE+AcCAF4=")) +require("heatshrink").decompress(atob("mEwwIpmgfAAqkCAoNAAoMHAoPgAoMPwfB+AFBj/D4f4AoM/AoP8AoQRBAoV/DoP+AoN+AoN+AoP8AoM/Ao/4AoMfAsBQCAo5QDAo5KCAQV/AQJZCn+AgIUD4EDAoUf+EPFgUP///RIUHAoKVCgYFBVAYFBWYc/EQQAvA")) From e2a4428be2a8369d51c30b4b34d367983f35c672 Mon Sep 17 00:00:00 2001 From: Marco H Date: Wed, 1 Dec 2021 13:48:03 +0100 Subject: [PATCH 0114/1839] Fix gramar and link in README --- apps/poweroff/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/poweroff/README.md b/apps/poweroff/README.md index 3aeff5e8d..9fcb250a1 100644 --- a/apps/poweroff/README.md +++ b/apps/poweroff/README.md @@ -4,10 +4,10 @@ Simple app to power off your Bangle.js ## Usage -Start the app shutdowns your Bangle.js watch after a short delay. +Start the app to shutdown your Bangle.js watch after a short delay. ## Creator -Marco (@myxor) +Marco ([myxor](https://github.com/myxor)) ## Icon Icon taken from https://materialdesignicons.com/ Apache License 2.0 From 871c345cea41816a167170ef019fd6f041f0ccb0 Mon Sep 17 00:00:00 2001 From: Marco H Date: Wed, 1 Dec 2021 13:49:25 +0100 Subject: [PATCH 0115/1839] Update README.md --- apps/poweroff/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/poweroff/README.md b/apps/poweroff/README.md index 9fcb250a1..d9d7a8dbc 100644 --- a/apps/poweroff/README.md +++ b/apps/poweroff/README.md @@ -10,4 +10,4 @@ Start the app to shutdown your Bangle.js watch after a short delay. Marco ([myxor](https://github.com/myxor)) ## Icon -Icon taken from https://materialdesignicons.com/ Apache License 2.0 +Icon taken from [materialdesignicons](https://materialdesignicons.com) under Apache License 2.0 From ca6b73e3e48c2a2b1ee157a6d02d166a0195324c Mon Sep 17 00:00:00 2001 From: Marco H Date: Wed, 1 Dec 2021 13:54:49 +0100 Subject: [PATCH 0116/1839] Icon white with 1px black border --- apps/poweroff/app.png | Bin 425 -> 620 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/poweroff/app.png b/apps/poweroff/app.png index 2b088b7216ce9d0ff9b61ea41f3002ce6bca7ad8..aa186ab200fbadea33ae991b14989b237d77095c 100644 GIT binary patch delta 575 zcmV-F0>J&L1MCElIDY~jNklLNbI20=a0hUbM zT;Q$+EcALwAneQKGTV&6jKE7rU>U^z3vjOj`v&uG@$BDD!>?$-G>l;TF#`0Nm~ZO< z?s41_*n67`>(gL89#Gig>$2Qyfc0=5iPhywj21tipjFC5;D2jyoYrw8y;xkwHO>qY z$wUt2)B?$<2LZ1_d$0)8)vE>-f-MI!IpJWRoaF&g$@f;FE8wmw%E5wUOJ0OUD?JW0 zBLRo`2hj1R?QOTD(^}uO-2y;)fQYCK~}5!>WILUKh;urXtK91tANnNA1JiTh^tw8b5lXrq}62 zl{~}V!f71!8rqYI5tvo?s###sYE`F594z(XRY{?+_a2CK9f+_|)_+5t7)_p>9^!;uJ+pG*-f`ORsCLQ^ zAl+3(9yksljC3ZiC{L%z0 zVmymTtYU;FAajj)MC>FwFiR7F!(JoEStC=kV#ql>0ZERK9!;YILwdnV36P>l0{~~@ zkpU}aT7UqYB_i9r^g;BdjJ3c From a789e0bea4945dd4461469b26f25744a9a3dc46d Mon Sep 17 00:00:00 2001 From: Marco H Date: Wed, 1 Dec 2021 13:55:25 +0100 Subject: [PATCH 0117/1839] Icon white with 1px black border --- apps/poweroff/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/poweroff/app-icon.js b/apps/poweroff/app-icon.js index 16c0ad8e7..81a2527b5 100644 --- a/apps/poweroff/app-icon.js +++ b/apps/poweroff/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwIpmgfAAqkCAoNAAoMHAoPgAoMPwfB+AFBj/D4f4AoM/AoP8AoQRBAoV/DoP+AoN+AoN+AoP8AoM/Ao/4AoMfAsBQCAo5QDAo5KCAQV/AQJZCn+AgIUD4EDAoUf+EPFgUP///RIUHAoKVCgYFBVAYFBWYc/EQQAvA")) +require("heatshrink").decompress(atob("mEwgIolgfAAqkCAoNAAoMHAoPgAoMPwfB+AFBj/D4f4AoM/AoP8AoQRBAoV/DoP+AoN+AoN+AoP8AoM/Ao/4AoMfAsBQCAo5QDAo5KCAQV/AQJZCn+AgIUD4EDAoUf+EPFgUP///RIUHAoKVCgYFBVAYFBWYc/EQQAvA")) From dfd7a02e12f977e45699b6a1bbbd49c22a385633 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 21:26:41 +0800 Subject: [PATCH 0118/1839] Show placeholder "Calculating" Fixes #2 --- apps/authentiwatch/app.js | 43 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index da8b6d220..b5c306b8b 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -6,8 +6,11 @@ const algos = { "SHA256":{sha:crypto.SHA256,retsz:32,blksz:64 }, "SHA1" :{sha:crypto.SHA1 ,retsz:20,blksz:64 }, }; +const calculating = "Calculating"; +const notokens = "No tokens"; +const notsupported = "Not supported"; -var tokens = require("Storage").readJSON("authentiwatch.json", true) || []; +var tokens = require("Storage").readJSON("authentiwatch.json", true) || {data:[],count:0}; tokens = tokens.data; // QR Code Text @@ -67,9 +70,8 @@ function do_hmac(key, message, algo) { var v = new DataView(ret, ret[ret.length - 1] & 0x0F, 4); return v.getUint32(0) & 0x7FFFFFFF; } -function hotp(token) { +function hotp(d, token, dohmac) { var tick; - var d = new Date(); if (token.period > 0) { // RFC6238 - timed var seconds = Math.floor(d.getTime() / 1000); @@ -82,15 +84,17 @@ function hotp(token) { var v = new DataView(msg.buffer); v.setUint32(0, tick >> 16 >> 16); v.setUint32(4, tick & 0xFFFFFFFF); - var ret = ""; - try { - var hash = do_hmac(b32decode(token.secret), msg, token.algorithm.toUpperCase()); - ret = "" + hash % Math.pow(10, token.digits); - while (ret.length < token.digits) { - ret = "0" + ret; + var ret = calculating; + if (dohmac) { + try { + var hash = do_hmac(b32decode(token.secret), msg, token.algorithm.toUpperCase()); + ret = "" + hash % Math.pow(10, token.digits); + while (ret.length < token.digits) { + ret = "0" + ret; + } + } catch(err) { + ret = notsupported; } - } catch(err) { - ret = "Not supported"; } return {hotp:ret, next:((token.period > 0) ? ((tick + 1) * token.period * 1000) : d.getTime() + 30000)}; } @@ -158,6 +162,9 @@ function draw() { var d = new Date(); if (state.curtoken != -1) { var t = tokens[state.curtoken]; + if (state.otp == calculating) { + state.otp = hotp(d, t, true).hotp; + } if (d.getTime() > state.nextTime) { if (state.hide == 0) { // auto-hide the current token @@ -168,7 +175,7 @@ function draw() { state.nextTime = 0; } else { // time to generate a new token - var r = hotp(t); + var r = hotp(d, t, state.otp != ""); state.nextTime = r.next; state.otp = r.hotp; if (t.period <= 0) { @@ -196,7 +203,13 @@ function draw() { if (state.drawtimer) { clearTimeout(state.drawtimer); } - state.drawtimer = setTimeout(draw, (tokens[state.curtoken].period > 0) ? 1000 : state.nexttime - d.getTime()); + var dly; + if (tokens[state.curtoken].period > 0) { + dly = (state.otp == calculating) ? 1 : 1000; + } else { + dly = state.nexttime - d.getTime(); + } + state.drawtimer = setTimeout(draw, dly); if (tokens[state.curtoken].period <= 0) { state.hide = 0; } @@ -211,7 +224,7 @@ function draw() { } else { g.setFont("Vector", 30); g.setFontAlign(0, 0, 0); - g.drawString("No tokens", Bangle.appRect.x + Bangle.appRect.w / 2,Bangle.appRect.y + Bangle.appRect.h / 2, false); + g.drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2,Bangle.appRect.y + Bangle.appRect.h / 2, false); } } @@ -232,6 +245,7 @@ function onTouch(zone, e) { if (y > Bangle.appRect.h) { state.listy += (y - Bangle.appRect.h); } + state.otp = ""; } state.nextTime = 0; state.curtoken = id; @@ -261,6 +275,7 @@ function onSwipe(e) { let save={data:tokens,count:tokens.length}; require("Storage").writeJSON("authentiwatch.json", save); state.nextTime = 0; + state.otp = ""; state.hide = 2; draw(); } From 60a8c487ad9035780ffbaf0a9a5db88d9743fe99 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:05:53 +0800 Subject: [PATCH 0119/1839] Support updated settings file --- apps/authentiwatch/app.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index b5c306b8b..58e64a48d 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -10,8 +10,9 @@ const calculating = "Calculating"; const notokens = "No tokens"; const notsupported = "Not supported"; -var tokens = require("Storage").readJSON("authentiwatch.json", true) || {data:[],count:0}; -tokens = tokens.data; +var settings = require("Storage").readJSON("authentiwatch.json", true) || {tokens:[],misc:{}}; +if (settings.data ) tokens = settings.data ; /* v0.02 settings */ +if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ // QR Code Text // @@ -272,8 +273,8 @@ function onSwipe(e) { } if (e == -1 && state.curtoken != -1 && tokens[state.curtoken].period <= 0) { tokens[state.curtoken].period--; - let save={data:tokens,count:tokens.length}; - require("Storage").writeJSON("authentiwatch.json", save); + let newsettings={tokens:tokens,misc:settings.misc}; + require("Storage").writeJSON("authentiwatch.json", newsettings); state.nextTime = 0; state.otp = ""; state.hide = 2; From d4ddf22399667a2cb98f73c375a98f11869512a3 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:15:55 +0800 Subject: [PATCH 0120/1839] Try new JSON settings format --- apps/authentiwatch/interface.html | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 6b39c148b..322a03448 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -35,8 +35,9 @@ const otpAuthUrl = 'otpauth://'; const tokentypes = ['TOTP (Timed)', 'HOTP (Counter)']; -/* Array of TOTP tokens */ -var tokens=[]; +/* Settings */ +var settings = {tokens:[], misc:{}}; +var tokens = settings.tokens; /* Remove any non-base-32 characters from the given string and collapses * whitespace to a single space. Optionally removes all whitespace from @@ -319,23 +320,21 @@ function doScan() { */ function loadTokens() { Util.showModal('Loading...'); - Puck.eval(`require('Storage').read(${JSON.stringify('authentiwatch.json')})`,data=>{ + Puck.eval(`require('Storage').readJSON(${JSON.stringify('authentiwatch.json')})`,data=>{ Util.hideModal(); - try { - let load = JSON.parse(data); - tokens = load.data; - updateTokens(); - } catch { - tokens = []; - } + if (data.data ) settings.tokens = data.data ; /* v0.02 settings */ + if (data.tokens) settings.tokens = data.tokens; /* v0.03+ settings */ + if (data.misc ) settings.misc = data.misc ; /* v0.03+ settings */ + tokens = settings.tokens; + updateTokens(); }); } /* Save settings as a JSON file on the watch. */ function saveTokens() { Util.showModal('Saving...'); - let save={data:tokens,count:tokens.length}; - Puck.write(`\x10require('Storage').write(${JSON.stringify('authentiwatch.json')},${JSON.stringify(save)})\n`,()=>{ + let newsettings={tokens:tokens,misc:settings.misc}; + Puck.write(`\x10require('Storage').writeJSON(${JSON.stringify('authentiwatch.json')},${JSON.stringify(newsettings)})\n`,()=>{ Util.hideModal(); }); } From 16f20970d9294d144347cfb02605d1ddc4472be2 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:21:21 +0800 Subject: [PATCH 0121/1839] Limit scanned label length Fixed #5 --- apps/authentiwatch/interface.html | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 322a03448..26533b17b 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -262,6 +262,7 @@ qrcode.callback = res => { scanning = false; editToken(parseInt(document.forms['edittoken'].elements['tokenid'].value)); t['label'] = (t['issuer'] == '') ? t['account'] : t['issuer'] + ' (' + t['account'] + ')'; + t['label'] = t['label'].substr(0, 10); var fe = document.forms['edittoken'].elements; if (res.startsWith(otpAuthUrl + 'hotp/')) { t['period'] = '30'; From 4d239bf71e5cc8312e3a5c762088c27ad9f20491 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:24:43 +0800 Subject: [PATCH 0122/1839] Version 0.03 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 55a43f5db..40cd5df65 100644 --- a/apps.json +++ b/apps.json @@ -4434,7 +4434,7 @@ "shortName": "AuthWatch", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], - "version": "0.02", + "version": "0.03", "description": "Google Authenticator compatible tool.", "tags": "tool", "interface": "interface.html", From 21961edf42856a2b82f45a8bbbb6751247fa658d Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:26:01 +0800 Subject: [PATCH 0123/1839] Update ChangeLog --- apps/authentiwatch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/ChangeLog b/apps/authentiwatch/ChangeLog index 67cb00c67..50cf3fcea 100644 --- a/apps/authentiwatch/ChangeLog +++ b/apps/authentiwatch/ChangeLog @@ -1,2 +1,3 @@ +0.03: Add "Calculating" placeholder, update JSON save format 0.02: Fix JSON save format 0.01: First release From 26cc978a40ffcf415db086025cc63910f7e8e943 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:29:37 +0800 Subject: [PATCH 0124/1839] Update README.md --- apps/authentiwatch/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/authentiwatch/README.md b/apps/authentiwatch/README.md index 403770c2b..8c0d9509b 100644 --- a/apps/authentiwatch/README.md +++ b/apps/authentiwatch/README.md @@ -1,5 +1,8 @@ # Authentiwatch - 2FA Authenticator +* GitHub: https://github.com/andrewgoz/Authentiwatch +* Bleeding edge AppLoader: https://andrewgoz.github.io/Authentiwatch/ + ## Supports * Google Authenticator compatible 2-factor authentication From 3305a5db6ab4e40ef45ea54513c656b503195450 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 23:23:44 +0800 Subject: [PATCH 0125/1839] Colour icon --- apps/authentiwatch/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/app-icon.js b/apps/authentiwatch/app-icon.js index 27ced695e..c901fb843 100644 --- a/apps/authentiwatch/app-icon.js +++ b/apps/authentiwatch/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mUywkBiIADCxoTFAAcQGBwY/DDQIKDBiMDDCgGCBI4YMGAIDFDCAFEBQwYLFgIYEGQgYMApoYJGAJjFMogYMSQgCDDBwDCY4oMEDBZgHHQQYQf4oYVBgwYQBogYPPYZpFDBKMEDAbdDCxT9IDYIFFABqSEAogySQYoWNFgrFDJZoQBJggYRBwhLGDBwyFDCZGEDCYAEDGrIMbwhnGDEpLGAwxlLFQgQDJiYoFDDAZDDCpMDMpQOCNxQYNBo4KKBpwYYBYJ8NeJgYkLBQY8UYQXVGQIwN")) +require("heatshrink").decompress(atob("mEwxH+AH4AD64ADFlgAFF04INFz4LUF0QwjEBwv/FzwwgF/4v/F6nMAAWi1AFD5nOeEHPEweoFooAB5/X5wvdFwotG5nN6/WAoQuaEoguHSYPQLwIIDF8uo5ouB6AJEFzuiFwup5/WFwI6GL0esXYKMBHYy9j1WqfBSOhBIYKJF8gAKF/4v6cZAvhGDAuWSDAvXMCwuYF+AwUFzX+0XGGAgxKFrYuBAAQxEeg4tcF4oABBQnGAAgv/F6b5KXsIvIGAqNnF/69fX8ZeSF7btNR8IuOF75ePL8ouOd74NKF8IANF94wEF1QAXA")) From 86ea0554b37139afc295437d45b2d85c9b4aee3c Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 23:26:45 +0800 Subject: [PATCH 0126/1839] Colour icon --- apps/authentiwatch/app.png | Bin 964 -> 1630 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/authentiwatch/app.png b/apps/authentiwatch/app.png index 208fb63b348a960529406347f23aa9363271a388..8775d3e4079e80a8af83fd03b7dc92619e23d648 100644 GIT binary patch literal 1630 zcmV-k2BGN({N<~^ig*p|{RvHL|#Kc=E zP^r93Egw*|eMJ2LRR>6DV(J$r7#lBTl{SHdXd)^=6tyrk0pCDdd68h+##X#4)O~T9 zlEkUs?!9LpY&Xu09s67xRs5wRJ$~*vet!R)b9_(kg&(=3Q(u%$r&lYbc51D+ipW}^ zAD9%882ft|4Kb=l*R7xEJ)&QT(&d%Q4iJ4GA2ims1j|#lj`nsjy0g}n& z=fL$q3b;NVk3SW(cC7-M5_HE;%?udgoIkU^)D(E zWRQsbPiwu}ah#1>lRozmj|n^^aD@k5#S-N6xLtAb%lkPWjZs8c34rFi3;Dfgvt3Uk zqW^hG40xV*R77r4vqyhD^$*5Hhyl17=5kny8>R-I>)+k9YCz`+|~LU zw#!w#71ThW`#>g>8PZeZ|5E8kL|xYm$K!`w7Tc#zmn_G?fQE4+Zx8PFiY z9`E01V6Q2Q@eG{%E4OOJ2ektWC2$oCuUQBWaP}mW=D=RI0r&C)5E(&=Ul$X(EfJx# zpuY&)WgTyu@Rc5_n0u5 z?tv%#iIM|72^MYEs_g8mlnODTbB7S;6uAO)$LITquRpL2IMgbTkpT@?`*S4+?C4_f zYJ5fCpU9ksnVItE?p_!etOGtDZ#H2vn*mL~f7`n*gu^Uc5;af)3|_{?g?ACW!Hl69 zHbF8nAcCtKU2FtY`7F))&BsRf0;5f=A?wds7LwWKOjOUT(r8vYy%<)p-NGH}kP*Uark`g~4@TGGhqNg8b96!EE_J z8xOY59N}yz%0TsV^*G%dheUrJz@_8gat)6MIZg*MFfq;+JdTE<5RR9Z5tL2L}m za?p1^st^8OG<)P)^S^vm!TzQ6ctQhCuG~Vga#I$%HwFaFU7P}J|1~Wbm#*77CF3PD@jBbljQH~+JTtP3yg%PmosE8I;7#M1ri)iJKe)^gg_Y5Xosc&pGj-dxF`zQCMZT@h8lgz#tN9^hS4Le7e< zE%1EM7hDk4z>@&~gxINe}JmN(x^HNV2#FC>_Rq)?OOy9_fSi2F4O^ch*3yb`s@?i z1G#?*97nz3G*AI-1NQs;>;U?JQQ$A|3-|SWjpa|Gb^Y>RlRNsji4&tdEh;84fQ2lbO2fOf*u2Fe=Wtn1g)r@+Vr;j zd;xYCxDG1StRjVX{^-Ii#z7srTrqbIyezQOiUL6|@W>b3A#$%`y~3?WO?Dlx&x!(| z5ii#V@ixdR;54cf`5qGBBHjvhE5z=$Q5zya<#BL_J{;g|(FA!_>_;_r2lchA;G-sh ztv*hzhBG4e294bTe}2ZUKrp8X;2}y(Eo%ORaom$)g~sjxA1vwMhareuZ9#mb4V<2Q zf+^%5bQ4AByV=0W=HsvsA zSC2ZQl!TBJ;YVFvdn$cEl_(3S)#(aqZ!z_aJ!&NmknbE!yvLlGt-)&b)}P{eSu;Vd84mq`~ Date: Wed, 1 Dec 2021 23:42:17 +0800 Subject: [PATCH 0127/1839] Improve token display Limit label length. Reduce digits font size until it fits. --- apps/authentiwatch/app.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 58e64a48d..7b442e0e8 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -115,7 +115,7 @@ function drawToken(id, r) { var y1 = r.y; var x2 = r.x + r.w - 1; var y2 = r.y + r.h - 1; - var adj; + var adj, sz; g.setClipRect(Math.max(x1, Bangle.appRect.x ), Math.max(y1, Bangle.appRect.y ), Math.min(x2, Bangle.appRect.x2), Math.min(y2, Bangle.appRect.y2)); if (id == state.curtoken) { @@ -135,7 +135,7 @@ function drawToken(id, r) { adj = (y1 + y2) / 2; } g.clearRect(x1, y1, x2, y2); - g.drawString(tokens[id].label, (x1 + x2) / 2, adj, false); + g.drawString(tokens[id].label.substr(0, 10), (x1 + x2) / 2, adj, false); if (id == state.curtoken) { if (tokens[id].period > 0) { // timed - draw progress bar @@ -149,7 +149,10 @@ function drawToken(id, r) { adj = 5; } // digits just below label - g.setFont("Vector", (state.otp.length > 8) ? 26 : 30); + sz = 30; + do { + g.setFont("Vector", sz--); + } while (g.stringWidth(state.otp) > r.w); g.drawString(state.otp, (x1 + x2) / 2 + adj, y1 + 16, false); } // shaded lines top and bottom From 3baa465f01e5df16ff15311ec91c7896eabd345d Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Wed, 1 Dec 2021 19:34:52 +0100 Subject: [PATCH 0128/1839] remove Settings module Better not to have this at all than to have a library that you can't actually use in widgets/boot/settings code --- README.md | 12 ++++-- modules/Settings.js | 101 -------------------------------------------- 2 files changed, 8 insertions(+), 105 deletions(-) delete mode 100644 modules/Settings.js diff --git a/README.md b/README.md index 20ae8afb2..8e186cf79 100644 --- a/README.md +++ b/README.md @@ -384,14 +384,18 @@ Example `settings.js` ```js // make sure to enclose the function in parentheses (function(back) { - function get(key, def) { return require('Settings').get('myappid', key, def); } - function set(key, value) { require('Settings').set('myappid', key, value); } + let settings = require('Storage').readJSON('myappid.json',1)||{}; + if (typeof settings.monkeys !== "number") settings.monkeys = 12; // default value + function save(key, value) { + settings[key] = value; + require('Storage').write('myappid.json', settings); + } const appMenu = { '': {'title': 'App Settings'}, '< Back': back, 'Monkeys': { - value: get('monkeys', 12), - onchange: (m) => set('monkeys', m) + value: settings.monkeys, + onchange: (m) => {save('monkeys', m)} } }; E.showMenu(appMenu) diff --git a/modules/Settings.js b/modules/Settings.js deleted file mode 100644 index 0828b4655..000000000 --- a/modules/Settings.js +++ /dev/null @@ -1,101 +0,0 @@ -/* -- Read/write app settings, stored in .json -- Read/write global settings (stored in setting.json) - -Usage: -``` -// read a single app setting -value = require('Settings').get(appid, key, default); -// omit key to read all app settings -value = require('Settings').get(appid); -// write a single app setting -require('Settings').set(appid, key, value) -// omit key and pass an object as values to overwrite all settings -require('Settings').set(appid, values) - -// read Bangle settings by passing the Bangle object instead of an app name -value = require('Settings').get(Bangle, key, default); -// read all global settings -values = require('Settings').get(Bangle); -// write a global setting -require('Settings').set(Bangle, key, value) -``` - -For example: -``` -require('Settings').set('test', 'foo', 123); // writes to 'test.json' -require('Settings').set('test', 'bar', 456); // updates 'test.json' -// 'test.json' now contains {baz:123,bam:456} -baz = require('Settings').get('test', 'foo'); // baz = 123 -def = require('Settings').get('test', 'jkl', 789); // def = 789 -all = require('Settings').get('test'); // all = {foo: 123, bar: 456} -baz = require('Settings').get('test', 'baz'); // baz = undefined - -// read global setting -vibrate = require('Settings').get(Bangle, 'vibrate', true); - -// Hint: if your app reads multiple settings, you can create a helper function: -function s(key, def) { return require('Settings').get('myapp', key, def); } -var foo = s('foo setting', 'default value'), bar = s('bar setting'); -``` - -*/ - -/** - * Read setting value from file - * - * @param {string} file Settings file - * @param {string} key Setting to get, omit to get all settings as object - * @param {*} def Default value - * @return {*} Setting value (or default if not found) - */ -function get(file, key, def) { - var s = require("Storage").readJSON(file); - if (def===undefined && ["object", "undefined"].includes(typeof key)) { - // get(file) or get(file, def): get all settings - return (s!==undefined) ? s : key; - } - return ((typeof s==="object") && (key in s)) ? s[key] : def; -} - -/** - * Write setting value to file - * - * @param {string} file Settings file - * @param {string} key Setting to change, omit to replace all settings - * @param {*} value Value to store - */ -function set(file, key, value) { - if (value===undefined && typeof key==="object") { - // set(file, value): overwrite settings completely - require("Storage").writeJSON(file, key); - return; - } - var s = require("Storage").readJSON(file, 1); - if (typeof s!=="object") s = {}; - s[key] = value; - require("Storage").write(file, s); -} - -/** - * Read setting value - * - * @param {string|object} app App name or Bangle - * @param {string} key Setting to get, omit to get all settings as object - * @param {*} def Default value - * @return {*} Setting value (or default if not found) - */ -exports.get = function(app, key, def) { - return get((app===Bangle) ? 'setting.json' : app+".json", key, def); -}; - -/** - * Write setting value - * - * @param {string|object} app App name or Bangle - * @param {string} key Setting to change, omit to replace all settings - * @param {*} val Value to store - */ -exports.set = function(app, key, val) { - set((app===Bangle) ? 'setting.json' : app+".json", key, val); -}; From bd8bb638d434df8a8cbfab84272f39d1a86b0755 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Wed, 1 Dec 2021 20:29:34 +0000 Subject: [PATCH 0129/1839] Pebble: deploy pebble.settings.js in apps.json --- apps.json | 3 ++- apps/pebble/ChangeLog | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 55a43f5db..4df02be1a 100644 --- a/apps.json +++ b/apps.json @@ -4628,7 +4628,7 @@ "id": "pebble", "name": "Pebble Clock", "shortName": "Pebble", - "version": "0.01", + "version": "0.02", "description": "A pebble style clock to keep the rebellion going", "readme": "README.md", "icon": "pebble.png", @@ -4638,6 +4638,7 @@ "supports": ["BANGLEJS2"], "storage": [ {"name":"pebble.app.js","url":"pebble.app.js"}, + {"name":"pebble.settings.js","url":"pebble.settings.js"}, {"name":"pebble.img","url":"pebble.icon.js","evaluate":true} ] } diff --git a/apps/pebble/ChangeLog b/apps/pebble/ChangeLog index 9db0e26c5..d352d98b6 100644 --- a/apps/pebble/ChangeLog +++ b/apps/pebble/ChangeLog @@ -1 +1,2 @@ 0.01: first release +0.02: included deployment of pebble.settings.js in apps.json From 7a1bb02bced4f0080d838bbe7ca3923b1e8d665f Mon Sep 17 00:00:00 2001 From: hughbarney Date: Wed, 1 Dec 2021 21:07:41 +0000 Subject: [PATCH 0130/1839] Pebble: updated README --- apps/pebble/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pebble/README.md b/apps/pebble/README.md index f0de5ce73..4b0233781 100644 --- a/apps/pebble/README.md +++ b/apps/pebble/README.md @@ -3,7 +3,7 @@ *a Pebble style clock with configurable background color, to keep the revolution going* * Designed specifically for Bangle 2 -* A choice of 6 different background colous through its setting menu +* A choice of 6 different background colous through its setting menu. Goto Settings, App/Widget settings, Pebble. * Supports the Light and Dark themes * Uses pedometer widget to get latest step count * Dependant apps are installed when Pebble installs From 012982e910436c5abe2ad6f28f68a96762343a18 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 16:03:22 +0800 Subject: [PATCH 0131/1839] Update README.md --- apps/authentiwatch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/README.md b/apps/authentiwatch/README.md index 8c0d9509b..8d0e74a0c 100644 --- a/apps/authentiwatch/README.md +++ b/apps/authentiwatch/README.md @@ -1,6 +1,6 @@ # Authentiwatch - 2FA Authenticator -* GitHub: https://github.com/andrewgoz/Authentiwatch +* GitHub: https://github.com/andrewgoz/Authentiwatch <-- Report bugs here * Bleeding edge AppLoader: https://andrewgoz.github.io/Authentiwatch/ ## Supports From cb8ee706252666bbfd215af26ecd87acc39d077c Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 16:05:36 +0800 Subject: [PATCH 0132/1839] Update app.js --- apps/authentiwatch/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 7b442e0e8..85c76b5d1 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -152,7 +152,7 @@ function drawToken(id, r) { sz = 30; do { g.setFont("Vector", sz--); - } while (g.stringWidth(state.otp) > r.w); + } while (g.stringWidth(state.otp) > (r.w - adj)); g.drawString(state.otp, (x1 + x2) / 2 + adj, y1 + 16, false); } // shaded lines top and bottom @@ -228,7 +228,7 @@ function draw() { } else { g.setFont("Vector", 30); g.setFontAlign(0, 0, 0); - g.drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2,Bangle.appRect.y + Bangle.appRect.h / 2, false); + g.drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2, Bangle.appRect.y + Bangle.appRect.h / 2, false); } } From ce2d1822477e9bc1468fc77f5ce31f4dc850a8cf Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 2 Dec 2021 09:43:03 +0000 Subject: [PATCH 0133/1839] tweak 2v11 firmware mentions --- apps.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 029cf4869..a72ccdfc1 100644 --- a/apps.json +++ b/apps.json @@ -87,7 +87,7 @@ "id": "health", "name": "Health Tracking", "version": "0.08", - "description": "Logs health data and provides an app to view it (BETA - requires firmware 2v11)", + "description": "Logs health data and provides an app to view it (requires firmware 2v10.100 or later)", "icon": "app.png", "tags": "tool,system,health", "supports": ["BANGLEJS","BANGLEJS2"], @@ -4150,7 +4150,7 @@ "id": "waveclk", "name": "Wave Clock", "version": "0.02", - "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**", + "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: Works on any Bangle.js 2, but requires firmware 2v11 or later on Bangle.js 1**", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], "type": "clock", @@ -4166,7 +4166,7 @@ "id": "floralclk", "name": "Floral Clock", "version": "0.01", - "description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**", + "description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: Works on any Bangle.js 2 but requires firmware 2v11 or later on Bangle.js 1**", "icon": "app.png", "screenshots": [{"url":"screenshot_floral.png"}], "type": "clock", From 5b967184b671315b2d474e1f5eefeff9073c1bb0 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 2 Dec 2021 10:07:45 +0000 Subject: [PATCH 0134/1839] 0.03: Fix unfreed memory, and clearInterval that disabled all clocks at midnight (fix #946) Fix app icon Change menu order so 'back' is at the top --- apps.json | 4 ++-- apps/qalarm/ChangeLog | 5 ++++- apps/qalarm/app-icon.js | 2 +- apps/qalarm/app.js | 10 +++++----- apps/qalarm/boot.js | 2 +- apps/qalarm/qalarmcheck.js | 9 ++++++--- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/apps.json b/apps.json index a72ccdfc1..95a6feab5 100644 --- a/apps.json +++ b/apps.json @@ -4310,7 +4310,7 @@ "name": "Q Alarm and Timer", "shortName": "Q Alarm", "icon": "app.png", - "version": "0.02", + "version": "0.03", "description": "Alarm and timer app with days of week and 'hard' option.", "tags": "tool,alarm,widget", "supports": ["BANGLEJS", "BANGLEJS2"], @@ -4535,7 +4535,7 @@ "description": "Simple app to power off your Bangle.js", "icon": "app.png", "tags": "poweroff, shutdown", - "supports" : ["BANGLEJS", "BANGLEJS2"], + "supports" : ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "storage": [ {"name":"poweroff.app.js","url":"app.js"}, diff --git a/apps/qalarm/ChangeLog b/apps/qalarm/ChangeLog index 135e69d23..fb6c751bb 100644 --- a/apps/qalarm/ChangeLog +++ b/apps/qalarm/ChangeLog @@ -1,2 +1,5 @@ 0.01: First version! -0.02: Fixed alarms not working and localised days of week. \ No newline at end of file +0.02: Fixed alarms not working and localised days of week. +0.03: Fix unfreed memory, and clearInterval that disabled all clocks at midnight + Fix app icon + Change menu order so 'back' is at the top diff --git a/apps/qalarm/app-icon.js b/apps/qalarm/app-icon.js index 1a014b796..12d2c103f 100644 --- a/apps/qalarm/app-icon.js +++ b/apps/qalarm/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("/wA/AH4A/AH4AF0WiF1wwtF73GB53MAAgkY4wABFqIxPEhQuXGB4vUFxYwMEpBpGBwouNGAwfFF5I1KF6ZQHGAwNLFx4wHF/4v/F/4v/AoYGDF6gaFF5AwHL7QuMBJQvWEpwvxBQ4uRGBAkJT4wuWGBIuIRjKRNF8wwXFy4wWFzIwU53NFzPN5wuR5/PGK4tBDYSNQ5wVCCwIzBAAQoIAAQWGSJ5HFDYYAQIYTCRKRIeBAAYmDAAZsJMCQAbeCAybFiQ0XFTQAIzgAGFcYvz0QAGF84wGF1AwFF1QA/AH4A/ADQ=")) +require("heatshrink").decompress(atob("mEw4UA///gH+93+oH9Jf8AgfABZMP+ALRmADCitUAgUMAQP8AQMBqtVoAFBn4CBDwUFBYNQFAQLEioLBEgQLBgfwE4IKBAAI3BBYXAE4ILE/gJBAIM8HQQ8CngL/n4LFKYR3BhgLFNYSDCBYqPFBZKzBUwSoDWYTLBUwSoDZYQABBQa0DBZCoBAAY6EcojhEHgoACkoLFrALD1WVBQdW1QLDtQMDBQOpHQmqAAg8DIwQKEJAg6FMApfLDIoJFAAX//4KIBbE/aAIAIh7oBAH4A==")) diff --git a/apps/qalarm/app.js b/apps/qalarm/app.js index 64f601bf6..ad071adf0 100644 --- a/apps/qalarm/app.js +++ b/apps/qalarm/app.js @@ -41,6 +41,7 @@ function getCurrentTime() { function showMainMenu() { const menu = { "": { title: "Alarms" }, + "< Back" : () => load(), "New Alarm": () => showEditAlarmMenu(-1), "New Timer": () => showEditTimerMenu(-1), }; @@ -54,9 +55,7 @@ function showMainMenu() { else showEditAlarmMenu(idx); }; }); - menu["< Back"] = () => { - load(); - }; + menu if (WIDGETS["qalarm"]) WIDGETS["qalarm"].reload(); return E.showMenu(menu); @@ -86,6 +85,7 @@ function showEditAlarmMenu(alarmIndex, alarm) { const menu = { "": { title: alarm.msg ? alarm.msg : "Alarms" }, + "< Back" : showMainMenu, Hours: { value: hrs, onchange: function (v) { @@ -162,7 +162,6 @@ function showEditAlarmMenu(alarmIndex, alarm) { showMainMenu(); }; } - menu["< Back"] = showMainMenu; return E.showMenu(menu); } @@ -206,6 +205,7 @@ function showEditTimerMenu(timerIndex) { const menu = { "": { title: "Timer" }, + "< Back" : showMainMenu, Hours: { value: hrs, onchange: function (v) { @@ -264,7 +264,7 @@ function showEditTimerMenu(timerIndex) { showMainMenu(); }; } - menu["< Back"] = showMainMenu; + return E.showMenu(menu); } diff --git a/apps/qalarm/boot.js b/apps/qalarm/boot.js index 6713ad9e1..5e9560ee2 100644 --- a/apps/qalarm/boot.js +++ b/apps/qalarm/boot.js @@ -1 +1 @@ -eval(require("Storage").read("qalarmcheck.js")); +(function() { eval(require("Storage").read("qalarmcheck.js")); })() diff --git a/apps/qalarm/qalarmcheck.js b/apps/qalarm/qalarmcheck.js index 9a3f10d5e..8dac43800 100644 --- a/apps/qalarm/qalarmcheck.js +++ b/apps/qalarm/qalarmcheck.js @@ -4,7 +4,10 @@ print("Checking for alarms..."); -clearInterval(); +if (Bangle.QALARM) { + clearInterval(Bangle.QALARM); + Bangle.QALARM = undefined; +} function getCurrentTime() { let time = new Date(); @@ -29,13 +32,13 @@ let nextAlarms = (require("Storage").readJSON("qalarm.json", 1) || []) .sort((a, b) => a.t - b.t); if (nextAlarms[0]) { - setTimeout(() => { + Bangle.QALARM = setTimeout(() => { eval(require("Storage").read("qalarmcheck.js")); load("qalarm.js"); }, nextAlarms[0].t - t); } else { // No alarms found: will re-check at midnight - setTimeout(() => { + Bangle.QALARM = setTimeout(() => { eval(require("Storage").read("qalarmcheck.js")); }, 86400000 - t); } From 9d26a6448ef93694da643b6152439bc4db516e96 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 2 Dec 2021 10:28:38 +0000 Subject: [PATCH 0135/1839] launcher 0.09: Bangle.js 2 - pressing the button goes back to clock (fix #971) After 10s of being locked, the launcher goes back to the clock screen --- apps.json | 2 +- apps/launch/ChangeLog | 2 ++ apps/launch/app-bangle1.js | 9 +++++++++ apps/launch/app-bangle2.js | 13 +++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 95a6feab5..877218135 100644 --- a/apps.json +++ b/apps.json @@ -104,7 +104,7 @@ "id": "launch", "name": "Launcher", "shortName": "Launcher", - "version": "0.08", + "version": "0.09", "description": "This is needed to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", "icon": "app.png", "type": "launch", diff --git a/apps/launch/ChangeLog b/apps/launch/ChangeLog index bd8a9bd03..3b9dbc30c 100644 --- a/apps/launch/ChangeLog +++ b/apps/launch/ChangeLog @@ -6,3 +6,5 @@ 0.06: Use Bangle.setUI for buttons 0.07: Theme colours fix 0.08: Merge Bangle.js 1 and 2 launchers +0.09: Bangle.js 2 - pressing the button goes back to clock (fix #971) + After 10s of being locked, the launcher goes back to the clock screen diff --git a/apps/launch/app-bangle1.js b/apps/launch/app-bangle1.js index 3d4682e55..f779f5de4 100644 --- a/apps/launch/app-bangle1.js +++ b/apps/launch/app-bangle1.js @@ -64,3 +64,12 @@ Bangle.setUI("updown",dir=>{ }); Bangle.loadWidgets(); Bangle.drawWidgets(); +// 10s of inactivity goes back to clock +if (Bangle.setLocked) Bangle.setLocked(false); // unlock initially +var lockTimeout; +Bangle.on('lock', locked => { + if (lockTimeout) clearTimeout(lockTimeout); + lockTimeout = undefined; + if (locked) + lockTimeout = setTimeout(_=>load(), 10000); +}); diff --git a/apps/launch/app-bangle2.js b/apps/launch/app-bangle2.js index 8b66247c5..9a7aa81ed 100644 --- a/apps/launch/app-bangle2.js +++ b/apps/launch/app-bangle2.js @@ -46,3 +46,16 @@ E.showScroller({ } } }); + +// pressing button goes back +setWatch(_=>load(), BTN1, {edge:"falling"}); + +// 10s of inactivity goes back to clock +Bangle.setLocked(false); // unlock initially +var lockTimeout; +Bangle.on('lock', locked => { + if (lockTimeout) clearTimeout(lockTimeout); + lockTimeout = undefined; + if (locked) + lockTimeout = setTimeout(_=>load(), 10000); +}); From 56b9e04ff0575334c07849bf83f829fc98c08472 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 2 Dec 2021 10:37:08 +0000 Subject: [PATCH 0136/1839] new core --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 50aa45f13..cd3b4def8 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 50aa45f13f06cc2f40684971d4c0a68d061b1f3c +Subproject commit cd3b4def869cac4d7f18e7329e640e51b26758c8 From 5fe942446b5b85144516cf3f1ae6cc3715b5ca38 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 21:54:53 +0800 Subject: [PATCH 0137/1839] Update app.js --- apps/authentiwatch/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 85c76b5d1..b3240ddbb 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -235,7 +235,7 @@ function draw() { function onTouch(zone, e) { if (e) { var id = Math.floor((state.listy + (e.y - Bangle.appRect.y)) / tokenentryheight); - if (id == state.curtoken || tokens.length == 0) { + if (id == state.curtoken || tokens.length == 0 || id >= tokens.length) { id = -1; } if (state.curtoken != id) { From d7ec86b716aaaf90d72c758307c0eb31a7ca3c28 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 21:56:36 +0800 Subject: [PATCH 0138/1839] Authentiwatch: version 0.04 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 877218135..2af3ab133 100644 --- a/apps.json +++ b/apps.json @@ -4434,7 +4434,7 @@ "shortName": "AuthWatch", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], - "version": "0.03", + "version": "0.04", "description": "Google Authenticator compatible tool.", "tags": "tool", "interface": "interface.html", From 5856db39e4671807fcf09197d5d65784d669c87f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 21:58:13 +0800 Subject: [PATCH 0139/1839] Update ChangeLog --- apps/authentiwatch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/ChangeLog b/apps/authentiwatch/ChangeLog index 50cf3fcea..1a7b5ee5e 100644 --- a/apps/authentiwatch/ChangeLog +++ b/apps/authentiwatch/ChangeLog @@ -1,3 +1,4 @@ +0.04: Fix tapping at very bottom of list 0.03: Add "Calculating" placeholder, update JSON save format 0.02: Fix JSON save format 0.01: First release From 257e73d8691d03597d4abce34516c90d9610af4f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 23:11:58 +0800 Subject: [PATCH 0140/1839] Update ChangeLog --- apps/authentiwatch/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/ChangeLog b/apps/authentiwatch/ChangeLog index 1a7b5ee5e..294d680be 100644 --- a/apps/authentiwatch/ChangeLog +++ b/apps/authentiwatch/ChangeLog @@ -1,4 +1,4 @@ -0.04: Fix tapping at very bottom of list +0.04: Fix tapping at very bottom of list, inactivity exits to clock 0.03: Add "Calculating" placeholder, update JSON save format 0.02: Fix JSON save format 0.01: First release From e7dcd59295ae770057f26780a096aea4de945e8b Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 23:55:46 +0800 Subject: [PATCH 0141/1839] Exit to clock on inactivity --- apps/authentiwatch/app.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index b3240ddbb..9ed1abff5 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -164,6 +164,10 @@ function drawToken(id, r) { function draw() { var d = new Date(); + if (state.idletimer) { + clearTimeout(state.idletimer); + } + state.idletimer = setTimeout(_=>load(), 10000); if (state.curtoken != -1) { var t = tokens[state.curtoken]; if (state.otp == calculating) { @@ -203,7 +207,8 @@ function draw() { y += tokenentryheight; } if (drewcur) { - // the current token has been drawn - draw it again in 1sec + // the current token has been drawn - schedule a redraw + clearTimeout(state.idletimer); if (state.drawtimer) { clearTimeout(state.drawtimer); } From c537d5c5f775051dc4dad030ac9c059c622d188f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Fri, 3 Dec 2021 00:06:30 +0800 Subject: [PATCH 0142/1839] Touch resets idle timeout --- apps/authentiwatch/app.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 9ed1abff5..e399b3e3b 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -110,6 +110,13 @@ var state = { hide:0 }; +function resetIdle() { + if (state.idletimer) { + clearTimeout(state.idletimer); + } + state.idletimer = setTimeout(_=>load(), 10000); +} + function drawToken(id, r) { var x1 = r.x; var y1 = r.y; @@ -164,10 +171,7 @@ function drawToken(id, r) { function draw() { var d = new Date(); - if (state.idletimer) { - clearTimeout(state.idletimer); - } - state.idletimer = setTimeout(_=>load(), 10000); + resetIdle(); if (state.curtoken != -1) { var t = tokens[state.curtoken]; if (state.otp == calculating) { @@ -238,6 +242,7 @@ function draw() { } function onTouch(zone, e) { + resetIdle(); if (e) { var id = Math.floor((state.listy + (e.y - Bangle.appRect.y)) / tokenentryheight); if (id == state.curtoken || tokens.length == 0 || id >= tokens.length) { @@ -265,6 +270,7 @@ function onTouch(zone, e) { } function onDrag(e) { + resetIdle(); if (e.x > g.getWidth() || e.y > g.getHeight()) return; if (e.dx == 0 && e.dy == 0) return; var newy = Math.min(state.listy - e.dy, tokens.length * tokenentryheight - Bangle.appRect.h); @@ -276,6 +282,7 @@ function onDrag(e) { } function onSwipe(e) { + resetIdle(); if (e == 1) { Bangle.showLauncher(); } @@ -291,6 +298,7 @@ function onSwipe(e) { } function bangle1Btn(e) { + resetIdle(); if (tokens.length > 0) { if (state.curtoken == -1) { state.curtoken = state.prevcur; From 43a68fb908f7eca0adf27079b5be3cbfa2236fac Mon Sep 17 00:00:00 2001 From: hughbarney Date: Thu, 2 Dec 2021 19:01:40 +0000 Subject: [PATCH 0143/1839] Pebble: 0.03 changed font to Leco1976, updated screenshots --- apps.json | 2 +- apps/pebble/ChangeLog | 1 + apps/pebble/pebble.app.js | 23 ++++++++++++++--------- apps/pebble/pebble_screenshot.png | Bin 2799 -> 2560 bytes apps/pebble/pebble_screenshot2.png | Bin 2736 -> 2531 bytes apps/pebble/pebble_screenshot3.png | Bin 2788 -> 2617 bytes 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apps.json b/apps.json index 877218135..8e0de6827 100644 --- a/apps.json +++ b/apps.json @@ -4628,7 +4628,7 @@ "id": "pebble", "name": "Pebble Clock", "shortName": "Pebble", - "version": "0.02", + "version": "0.03", "description": "A pebble style clock to keep the rebellion going", "readme": "README.md", "icon": "pebble.png", diff --git a/apps/pebble/ChangeLog b/apps/pebble/ChangeLog index d352d98b6..54f2e7452 100644 --- a/apps/pebble/ChangeLog +++ b/apps/pebble/ChangeLog @@ -1,2 +1,3 @@ 0.01: first release 0.02: included deployment of pebble.settings.js in apps.json +0.03: Changed time font to LECO1976Regular42 diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 62159055d..45cce90e4 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -1,7 +1,11 @@ +Graphics.prototype.setFontLECO1976Regular42 = function(scale) { + // Actual height 42 (41 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60+(scale<<8)+(1<<16)); +} -Graphics.prototype.setFontQahiri = function(scale) { - // Actual height 60 (60 - 1) - g.setFontCustom(atob("AAAAAAAAfAAAAAAAAAAAAP4AAAAAAAAAAAD/AAAAAAAAAAAB/wAAAAAAAAAAAf8AAAAAAAAAAAH/AAAAAAAAAAAA/wAAAAAAAAAAAH4AAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAB8AAAAAAAAAAAD/gAAAAAAAAAAH/4AAAAAAAAAAP/8AAAAAAAAAAP/4AAAAAAAAAAf/4AAAAAAAAAA//wAAAAAAAAAB//gAAAAAAAAAD//AAAAAAAAAAD//AAAAAAAAAAH/+AAAAAAAAAAP/8AAAAAAAAAAf/4AAAAAAAAAAf/4AAAAAAAAAA//wAAAAAAAAAB//gAAAAAAAAAD//AAAAAAAAAAH/+AAAAAAAAAAH/+AAAAAAAAAAP/8AAAAAAAAAAH/4AAAAAAAAAAB/wAAAAAAAAAAAPwAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD/AAAD/AAAAAAA/wAAA/wAAAAAAP8AAAP8AAAAAAD/AAAD/AAAAAAA/wAAA/wAAAAAAP8AAAP8AAAAAAD/AAAD/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAH///gH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///AAAAAAAAAAP//wAAAAAAAAAD//8AAAAAAAAAA///AAAAAAAAAAP//wAAAAAAAAAD//8AAAAAAAAAA///AAAAAAAAAAP//wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAH8A///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAP8B///8AAAAAAD/Af///AAAAAAA/wH///wAAAAAAH8A///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA/wAAAAAAAAAAAP8AAAAAAAAAAAD/AAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD///4D/AAAAAAA///+A/wAAAAAAP///gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA/wH+A/wAAAAAAP8B/gP8AAAAAAD/Af4D/AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAP/////8AAAAAAD//////AAAAAAA//////wAAAAAAH/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+AAfAAAAAAAAAfwAP4AAAAAAAAP8AD/AAAAAAAAD/gB/wAAAAAAAA/4Af8AAAAAAAAP+AH/AAAAAAAAD/AA/wAAAAAAAAfgAH4AAAAAAAABwAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("DR0bDBsbGxsbGxsbDQ=="), 80+(scale<<8)+(1<<16)); +Graphics.prototype.setFontLECO1976Regular22 = function(scale) { + // Actual height 22 (21 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22+(scale<<8)+(1<<16)); } const SETTINGS_FILE = "pebble.json"; @@ -15,7 +19,7 @@ var img = require("heatshrink").decompress(atob("oFAwkGswA/AH4A/AH4A/AH4A/AFEAD7 const h = g.getHeight(); const w = g.getWidth(); -const ha = 2*h/5 - 8; +const ha = 2*h/5 - 4; const h2 = 3*h/5 - 10; const h3 = 7*h/8; @@ -24,7 +28,6 @@ let batteryWarning = false; function draw() { let date = new Date(); let da = date.toString().split(" "); - //let timeStr = require("locale").time(date,1); // causes screen corruption ??? let timeStr = da[4].substr(0,5); const t = 6; @@ -50,19 +53,21 @@ function draw() { else g.setColor('#000'); // otherwise black regardless of theme - g.setFont('Vector', 22); + g.setFontLECO1976Regular22(); g.setFontAlign(0, -1); - g.drawString(da[0], w/4, ha); // day of week + g.drawString(da[0].toUpperCase(), w/4, ha); // day of week g.drawString(getSteps(), 3*w/4, ha); // time // white on red for battery warning g.setColor(!batteryWarning ? g.theme.bg : '#f00'); g.fillRect(0, h2, w, h3); - g.setFontQahiri(); + + g.setFontLECO1976Regular42(); g.setFontAlign(0, -1); g.setColor(!batteryWarning ? g.theme.fg : '#fff'); - g.drawString(timeStr, w/2, h2 - 8); + //g.drawString(timeStr, w/2, h2 - 8); + g.drawString(timeStr, w/2, h2 + 8); // contrast bar g.setColor(g.theme.fg); diff --git a/apps/pebble/pebble_screenshot.png b/apps/pebble/pebble_screenshot.png index d618368db84657fdc60e478c4507fac2bb9c931f..f0bd2dd53a98fbbcca1e0198ad8c77d73ffe4fde 100644 GIT binary patch literal 2560 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 From 2fc3cee13926258243f86a791c2e175cc9ceb07b Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 11:27:53 -0800 Subject: [PATCH 0144/1839] Create app.js --- apps/pooqroman/app.js | 764 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 764 insertions(+) create mode 100644 apps/pooqroman/app.js diff --git a/apps/pooqroman/app.js b/apps/pooqroman/app.js new file mode 100644 index 000000000..a5de57210 --- /dev/null +++ b/apps/pooqroman/app.js @@ -0,0 +1,764 @@ +// pooqRoman +// +// Copyright (c) 2021 Stephen P Spackman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// Notes: +// +// This only works for Bangle 2. + +////////////////////////////////////////////////////////////////////////////// +/* System integration */ + +const storage = require('Storage'); + +const settings = storage.readJSON("setting.json", true) || {}; + +const alarms = storage.readJSON('alarm.json', true) || []; + +/* + { on : true, + hr : 6.5, // hours + minutes/60 + msg : "Eat chocolate", + last : 0, // last day of the month we alarmed on - so we don't alarm twice in one day! + rp : true, // repeat + as : false, // auto snooze + timer : 5, // OPTIONAL - if set, this is a timer and it's the time in minutes + } +*/ + +////////////////////////////////////////////////////////////////////////////// +/* Face-specific options */ + +class Options { + // Protocol: subclasses must have static id and defaults fields. + // Only fields named in the defaults will be saved. + constructor() { + this.id = this.constructor.id; + this.file = `${this.id}.opt`; + this.backing = storage.readJSON(this.file, true) || {}; + this.defaults = this.constructor.defaults; + Object.keys(this.defaults).forEach(k => this.bless(k)); + } + + writeBack(delay) { + if (this.timeout) clearTimeout(this.timeout); + this.timeout = setTimeout( + () => { + this.timeout = null; + storage.writeJSON(this.file, this.backing); + }, + delay + ); + } + + bless(k) { + Object.defineProperty(this, k, { + get: () => this.backing[k] == null ? this.defaults[k] : this.backing[k], + set: v => { + this.backing[k] = v; + // Ten second writeback delay, since the user will roll values up and down. + this.writeBack(10000); + return v; + } + }); + } + + showMenu(m) { + if (m) { + for (const k in m) if ('init' in m[k]) m[k].value = m[k].init(); + m[''].selected = -1; // Workaround for self-selection bug. + } + E.showMenu(m); + } + + reset() { + this.backing = {}; + this.writeBack(0); + } + + interact() {this.showMenu(this.menu);} +} + +class RomanOptions extends Options { + constructor() { + super(); + this.menu = { + '': {title: '* face options *'}, + '< Back': _ => {this.showMenu(); this.emit('done');}, + Ticks: { + init: _ => this.resolution, + min: 0, max: 3, + onchange: x => this.resolution = x, + format: x => ['seconds', 'seconds (up)', 'minutes', 'hours'][x] + }, + 'Display': { + init: _ => this.o24h == null ? 0 : 1 + this.o24h, + min: 0, max: 2, + onchange: x => this.o24h = [null, 0, 1][x], + format: x => ['system', '12h', '24h'][x] + }, + 'Day of Week': { + init: _ => this.dow, + onchange: x => this.dow = x + }, + Calendar: { + init: _ => this.calendric, + min: 0, max: 2, + onchange: x => this.calendric = x, + format: x => ['none', 'day', 'date'][x] + }, + Defaults: _ => {this.reset();} + }; + } +} + +RomanOptions.id = 'pooqroman'; + +RomanOptions.defaults = { + resolution: 1, + dow: true, + calendric: 2, + o24h: !settings["12hour"], + bg: g.theme.bg, + fg: g.theme.fg, + barBg: g.theme.fg, + barFg: g.theme.bg, + hourFg: g.theme.fg, + minuteFg: g.theme.fg, + secondFg: g.theme.fg2, + rectFg: g.theme.fg, + hubFg: g.theme.fg, + alarmFg: '#f00', + timerFg: '#0f0', + active: g.theme.fg2, +}; + +////////////////////////////////////////////////////////////////////////////// +/* Assets (generated by resourcer.js, in this directory) */ + +const heatshrink = require('heatshrink'); +const dec = x => E.toString(heatshrink.decompress(atob(x))); +const romanPartsF = [ + dec( + 'wEBsEB3//7//9//+0AjUAguAg3AgYQJjfAgv+gH/8Fg/0gh/AgP4gf2h/j/+BCAP' + + 'wgFggEggEQgEMgEHwEDEIIyDuED3kD7+H9vn2k/hEPgMP4Xevd+j4QB7kA9kAmkA' + + 'hUGgOH8Hn3le4+GgH32PuvfGj+CCAMDgXD4dz+evt9DgcL7fXn87h8NCAMP+Ef/0' + + 'eg+egPugF2j0bCAPAh3wh88h8P/8BNwI' + ), 97, dec('gUDgUGgUJgYFBhsBhMJhgA=='), 17 +];const fontF = [ + dec( + 'AAUwAIM/4F/8HguHAmABBAoIJBBoIUBkEwsEw//wAIIdDBoUQBoIfC+HB+Hj2F/m' + + 'E+CIXAoHEsHMuHcmH8mHuuHH8GBGIUAwEBwEHwH/wH5+EBAIILCCAP8oH8EYXMmA' + + 'BB5wjCgYjCAYMP8E+uF8mHsCIWHCIgCBAIXw4fw54tBgBsBGgUAnKLC99w40wAII' + + 'FBBIINBCIM8gF+iHnmHDuHD8HnDYMAjizEMYJJBn+A+OAAYIHBBYKjDXYKvDYZYP' + + 'D40AAIYMBZYgkC4Hg4DnDuH/8H/BYIVCv/wnEAjwBCAoIJBEIYRFh0Ag8AgPAEYQ' + + 'RCJIJNBfYRXKnFAvlg9ihE8dwsfgkLFHMYgJF8DNCh+AUYWAA4ILBAAJGB/4PB+D' + + '9CgADCEoIPCJobbBB4IBBAoJdDEgXggvwhuwAIcH8EDRIh/BhkwAIMOuAPCMYQDB' + + 'A4ILBCIcGsECoAPLU4oPDH42ggeAB4XEg/mh1zhkzh03g/+h/4J4nwg0AhjbDRII' + + 'vCt/wAIIVFAoKTBCYIXBDIYHHEIYVFGJJxHSI8P/8H/6hLF44BBM4IABg8gh6NEh' + + 'vwgngBoITBv/Av7PBV4kAsArCfYIVBuEABYNwA4I3BD4cPL4UAM4IXBBYQfC4kP8' + + '0AucAmcAu8PXogA=' + ), 32, dec('gINMgUAhMHhIAGCQ0KAQIKBgwEBgcIBAQVEhIJBhAeIBQIADAoUDEQULBQcHg4FD' + + 'CII='), 16 +]; +const lockI = dec('iMSwMAgfwgf8geHgeB4PA8HguFwnH//9//+4gPf//v//3gE7//9//+8EHCAO///A'); +const batteryI = dec('h8SwMAgPggfAv/4//x//j//H/+P/8f/0//gOOA=='); +const chargeI = dec('h0MwIEBkEBwEMgFwgeAj/w/+AjkA8EDgEYgFAA=='); +const GPSI = dec('iUQwMAhEAgsAgUggFEgEKvEBn0Aj+AgfgglygsJosgxNGiNIgWJ4FBEoM4gA'); +const HRMI = dec('iMRwMAnken8fzfd7v+/3/v9/38/z+b5tiiM3/eP/+D/+AAIM/wEPwEDwEAAIIA=='); +const compassI = dec('iMRwMAgfgg/8g8ng0Q40ImcOjcHg+DwfB4Ph2Hw7FsolmkUxwEwuFwj/wEIMAA=='); + +////////////////////////////////////////////////////////////////////////////// +/* Squeezable strings */ + +class Formattable { + width(g) {return this.w != null ? this.w : (this.w = g.stringWidth(this.text));} + print(g, x, y) {g.drawString(this.text, x, y); return this.width();} +} + +class Fixed extends Formattable { + constructor(text) { + super(); + this.text = text; + } + squeeze() {return false;} +} + +class Squeezable extends Formattable { + constructor(named, index) { + super(); + this.named = named; + this.index = index; + this.end = index + named.forms; + } + squeeze() { + if (this.index >= this.end) return false; + this.index++; + this.w = null; + return true; + } + get text() {return this.named.table[this.index];} +} + +class Named { + constructor(forms, table) { + this.forms = forms; + this.table = table; + } + on(index) {return new Squeezable(this, this.forms * index);} +} + +////////////////////////////////////////////////////////////////////////////// +/* Face */ + +// Static geometry +const barW = 26, barH = g.getHeight(), barX = g.getWidth() - barW, barY = 0; +const faceW = g.getWidth() - barW, faceH = g.getHeight(); +const faceX = 0, faceY = 0, faceCX = faceW / 2, faceCY = faceH / 2; +const rectX = faceX + 35, rectY = faceY + 24, rectW = 80, rectH = 128; + +// Extended-Roman-numeral labels +const layout = E.toUint8Array( + 75, 23, // XII + 132, 24, // I + 132, 61, // II + 132, 97, // III + 132, 133, // IV + 132, 170, // V + 75, 171, // VI + 18, 170, // VII + 18, 133, // VIII + 18, 97, // IX + 18, 61, // X + 18, 24 // XI +); + +const numeral = (n, options) => [ + 'n', // 0 + 'abc', // I + 'abdc', // II + 'abddc', // III + 'abefg', // IV + 'hfg', // V + 'hfibc', // VI + 'hfibdc', // VII + 'hfibddc', // VIII + 'abjk', // IX + 'kjk', // X + 'kjbc', // XI + 'kjbdc', // XII + 'kjbddc', // XIII + 'kjbefg', // XIV + 'kjefg', // XV + 'labc', // XVI + 'labdc', // XVII + 'labddc', // XVIII + 'kjbjk', // XIX + 'kjjk', // XX + 'mabc', // XXI + 'mabdc', // XXII + 'mabddc', // XXIII +][options.o24h ? n % 24 : (n + 11) % 12 + 1]; + +const formatMonth = new Named(4, [ + 'January', 'Jan.', 'Jan', 'I', + 'February', 'Feb.', 'Feb', 'II', + 'March', 'Mar.', 'Mar', 'III', + 'April', 'Apr.', 'Apr', 'IV', + 'May', 'May', 'May', 'V', + 'June', 'June', 'Jun', 'VI', + 'July', 'July', 'Jul', 'VII', + 'August', 'Aug.', 'Aug', 'VIII', // VIII *is* narrower than Aug, our I is thin. + 'September', 'Sept.', 'Sep', 'IX', + 'October', 'Oct.', 'Oct', 'X', + 'November', 'Nov.', 'Nov', 'XI', + 'December', 'Dec.', 'Dec', 'XII' +]); +const formatDom = { + on: d => new Fixed(d.toString()) +}; +const formatDow = new Named(4, [ + 'Sunday', 'Sun.', 'Sun', 'Su', + 'Monday', 'Mon.', 'Mon', 'M', + 'Tuesday', 'Tues.', 'Tue', 'Tu', + 'Wednesday', 'Weds.', 'Wed', 'W', + 'Thursday', 'Thurs.', 'Thu', 'Th', + 'Friday', 'Fri.', 'Fri', 'F', + 'Saturday', 'Sat.', 'Sat', 'Sa' +]); + +const isString = x => typeof x == 'string'; +const imageWidth = i => isString(i) ? i.charCodeAt(0) : i.width; +const imageHeight = i => isString(i) ? i.charCodeAt(1) : i.height; + +const events = { + // Items are {time: number, wall: boolean, priority: number, + // past: bool, future: bool, precision: number, + // colour: colour, dramatic?: bool, event?: any} + fixed: [{time: Number.POSITIVE_INFINITY}], // indexed by ms absolute + wall: [{time: Number.POSITIVE_INFINITY}], // indexed by nominal ms + TZ ms + + clean: function(now, l) { + let o = now.getTimezoneOffset() * 60000; + let tf = now.getTime() + l, tw = tf - o; + // Discard stale events: + while (this.wall[0].time <= tw) this.wall.shift(); + while (this.fixed[0].time <= tf) this.fixed.shift(); + }, + + scan: function(now, from, to, f) { + result = Infinity; + let o = now.getTimezoneOffset() * 60000; + let t = now.getTime() - o; + let c, p, i, l = from - o, h = to - o; + for (i = 0; (c = this.wall[i]).time < l; i++) ; + for (; (c = this.wall[i]).time < h; i++) { + if ((p = c.time < t) ? c.past : c.future) + result = Math.min(result, f(c, new Date(c.time + o), p)); + } + l += o; h += o; t += o; + for (i = 0; (c = this.fixed[i]).time < l; i++) ; + for (; (c = this.fixed[i]).time < h; i++) { + if ((p = c.time < t) ? c.past : c.future) + result = Math.min(f(c, new Date(c.time), p)); + } + return result; + }, + + span: function(now, width) { + let o = now.getTimezoneOffset() * 60000; + let t = now.getTime() - o; + let lfence = [], rfence = []; + this.scan(now, now - width, now + width, (e, d, p) => { + if (p) { + for (let j = 0; j <= e.priority; j++) { + if (e.time < (lfence[e.priority] || t)) lfence[e.priority] = e.time; + } + } else { + for (let j = 0; j <= e.priority; j++) { + if (e.time > (rfence[e.priority] || t)) rfence[e.priority] = e.time; + } + } + }); + for (let j = 0; ; j += 0.5) { + if ((rfence[Math.ceil(j)] - lfence[Math.floor(j)] || 0) <= width) { + return [lfence[Math.floor(j)] || t, rfence[Math.ceil(j)] || t]; + } + } + }, + + insert: function(t, wall, e) { + let v = wall ? this.wall : this.fixed; + e.time = t = t - (wall ? t.getTimezoneOffset() * 60000 : 0); + v.splice(v.findIndex(x => x.time > t), 0, e); + }, + + loadFromSystem: function(options) { + alarms.forEach(x => { + if (x.on) { + const t = new Date(); + let h = x.hr; + let m = h % 1 * 60; + let s = m % 1 * 60; + let ms = s % 1 * 1000; + t.setHours(h - h % 1, m - m % 1, s - s % 1, ms); + // There's a race condition here, but I'm not sure what we can do about it. + if (t < Date.now() || x.last === t.getDate()) t.setDate(t.getDate() + 1); + this.insert(t, true, { + priority: 0, + past: false, // System alarms seem uninteresting if past? + future: true, + precision: x.timer ? 1000 : 60000, + colour: x.timer ? options.timerFg : options.alarmFg, + event: x + }); + } + }); + return this; + }, +}; + +////////////////////////////////////////////////////////////////////////////// +/* The main face logic */ + +class Sidebar { + constructor(g, x, y, w, h, options) { + this.g = g; + this.options = options; + this.x = x; + this.y = this.initY = y; + this.h = h; + this.rate = Infinity; + this.doLocked = Sidebar.status(_ => Bangle.isLocked(), lockI); + this.doHRM = Sidebar.status(_ => Bangle.isHRMOn(), HRMI); + this.doGPS = Sidebar.status(_ => Bangle.isGPSOn(), GPSI, Sidebar.gpsColour(options)); + } + reset(rate) {this.y = this.initY; this.rate = rate; return this;} + print(t) { + this.y += 4 + t.print( + this.g.setColor(this.options.barFg).setFontAlign(-1, 1, 1), + this.x + 3, this.y + 4 + ); + return this; + } + pad(n) {this.y += n; return this;} + free() {return this.h - this.y;} + static status(p, i, c) { + return function() { + if (p()) { + this.g.setColor(c ? c() : this.options.barFg) + .drawImage(i, this.x + 4, this.y += 4); + this.y += imageHeight(i); + } + return this; + }; + } + static gpsColour(o) { + const fix = Bangle.getGPSFix(); + return fix && fix.fix ? o.active : o.barFg; + } + doPower() { + const c = Bangle.isCharging(); + const b = E.getBattery(); + if (c || b < 50) { + let g = this.g, x = this.x, y = this.y, options = this.options; + g.setColor(options.barFg).drawImage(batteryI, x + 4, y + 4); + g.setColor(b <= 10 ? '#f00' : b <= 30 ? '#ff0' : '#0f0'); + const h = 13 * (100 - b) / 100; + g.fillRect(x + 8, y + 7 + h, x + 17, y + 20); + // Espruino disallows blank leading rows in icons, for some reason. + if (c) g.setColor(options.barBg).drawImage(chargeI, x + 4, y + 8); + this.y = y + imageHeight(batteryI) + 4; + } + return this; + } + doCompass() { + if (Bangle.isCompassOn()) { + const c = Bangle.getCompass(); + const a = c && this.rate <= 1000; + this.g.setColor(a ? this.options.active : this.options.barFg).drawImage( + compassI, + this.x + 4 + imageWidth(compassI) / 2, + this.y + 4 + imageHeight(compassI) / 2, + a ? {rotate: c.heading / 180 * Math.PI} : undefined + ); + this.y += 4 + imageHeight(compassI); + } + return this; + } +} + +class Roman { + constructor(g, events) { + this.g = g; + this.state = {}; + const options = this.options = new RomanOptions(); + this.events = events.loadFromSystem(this.options); + this.timescales = [1000, [1000, 60000], 60000, 3600000]; + this.sidebar = new Sidebar(g, barX, barY, barW, barH, options); + this.hours = Roman.hand(g, 3, 0.5, 12, _ => options.hourFg); + this.minutes = Roman.hand(g, 2, 0.9, 60, _ => options.minuteFg); + this.seconds = Roman.hand(g, 1, 0.9, 60, _ => options.secondFg); + } + + reset() {this.state = {}; this.g.clear(true);} + + doIcons(which) {this.state.iconsOk = null;} + + // Watch hands. These could be improved, graphically. + // If we restricted them to 60 positions, we could feasibly hand-draw them? + static hand(g, w, l, d, c) { + return p => { + g.setColor(c()); + p = ((12 * p / d) + 1) % 12; + let h = l * rectW / 2; + let v = l * rectH / 2; + let poly = + p <= 2 ? [faceCX + w, faceCY, faceCX - w, faceCY, + faceCX + h * (p - 1), faceCY - v, + faceCX + h * (p - 1) + 1, faceCY - v] + : p < 6 ? [faceCX + 1, faceCY + w, faceCX + 1, faceCY - w, + faceCX + h, faceCY + v / 2 * (p - 4), + faceCX + h, faceCY + v / 2 * (p - 4) + 1] + : p <= 8 ? [faceCX - w, faceCY + 1, faceCX + w, faceCY + 1, + faceCX - h * (p - 7), faceCY + v, + faceCX - h * (p - 7) - 1, faceCY + v] + : [faceCX, faceCY - w, faceCX, faceCY + w, + faceCX - h, faceCY - v / 2 * (p - 10), + faceCX - h, faceCY - v / 2 * (p - 10) - 1]; + g.fillPoly(poly); + }; + } + + static pos(p, r) { + let h = r * rectW / 2; + let v = r * rectH / 2; + p = (p + 1) % 12; + return p <= 2 ? [faceCX + h * (p - 1), faceCY - v] + : p < 6 ? [faceCX + h, faceCY + v / 2 * (p - 4)] + : p <= 8 ? [faceCX - h * (p - 7), faceCY + v] + : [faceCX - h, faceCY - v / 2 * (p - 10)]; + } + + alert(e, date, now, past) { + const g = this.g; + g.setColor(e.colour); + const dt = date - now; + if (e.precision < 60000 && dt >= 0 && e.future && dt <= 59000) { // Seconds away + const p = Roman.pos(date.getSeconds() / 5, 0.95); + g.drawLine(faceCX, faceCY, p[0], p[1]); + return 1000; + } else if (e.precision < 3600000 && dt >= 0 && e.future && dt <= 3540000) { // Minutes away + const p = Roman.pos(date.getMinutes() / 5 + date.getSeconds() / 300, 0.8); + g.drawLine(p[0] - 5, p[1], p[0] + 5, p[1]); + g.drawLine(p[0], p[1] - 5, p[0], p[1] + 5); + return dt < 119000 ? 1000 : 60000; // Turn on second hand two minutes up. + } else if (e.precision < 43200000 && dt >= 0 ? e.future : e.past) { // Hours away + const p = Roman.pos(date.getHours() + date.getMinutes() / 60, 0.6); + const poly = [p[0] - 4, p[1], p[0], p[1] - 4, p[0] + 4, p[1], p[0], p[1] + 4]; + if (date >= now) g.fillPoly(poly); + else g.drawPoly(poly, true); + return 3600000; + } + return Infinity; + } + + render(d, rate) { + const g = this.g; + const state = this.state; + const options = this.options; + const events = this.events; + events.clean(d, -39600000); // 11h + + // Sidebar: icons and date + if (d.getDate() !== state.date || !state.iconsOk) { + const sidebar = this.sidebar; + state.date = d.getDate(); + state.iconsOk = true; + g.setColor(options.barBg).fillRect(barX, barY, barX + barW, barY + barH); + + sidebar.reset(rate).doLocked().doPower().doGPS().doHRM().doCompass(); + g.setFontCustom.apply(g, fontF); + let formatters = []; + let month, dom, dow; + if (options.calendric > 1) { + formatters.push(month = formatMonth.on(d.getMonth())); + } + if (options.calendric > 0) { + formatters.push(dom = formatDom.on(d.getDate())); + } + if (options.dow) { + formatters.push(dow = formatDow.on(d.getDay())); + } + // Obnoxiously inefficient iterative method :( + let ava = sidebar.free() - 3, use, i = 0, j = 0; + while ((use = formatters.reduce((l, f) => l + f.width(g) + 4, 0)) > ava && + j < formatters.length) + for (j = 0; + !formatters[i++ % formatters.length].squeeze() && + j < formatters.length; + j++) ; + if (dow) sidebar.print(dow); + sidebar.pad(ava - use); + if (month) sidebar.print(month); + if (dom) sidebar.print(dom); + } + + // Hour labels and (purely aesthetic) box; clear inner face. + let keyHour = d.getHours() < 12 ? 1 : 13; + let alertSpan = events.span(d, 43200000); + let l = Math.floor(alertSpan[0] / 3600000) % 24; + let h = Math.ceil(alertSpan[1] / 3600000) % 24; + if ((l - keyHour + 24) % 24 >= 12) keyHour = l; + else if ((h - keyHour + 24) % 24 >= 12) keyHour = (h + 13) % 24; + if (keyHour !== state.keyHour) { + state.keyHour = keyHour; + g.setColor(options.bg) + .fillRect(faceX, faceY, faceX + faceW, faceY + faceH) + .setFontCustom.apply(g, romanPartsF) + .setFontAlign(0, 1) + .setColor(options.fg); + // In order to deal with timezone changes more logic will be required, + // since the labels may be in unusual locations (even offset when + // a non-integral zone is involved). The value of keyHour can be + // anything in [hr-12, hr] mod 24. + for (let h = keyHour; h < keyHour + 12; h++) { + g.drawString( + numeral(h % 24, options), + faceX + layout[h % 12 * 2], + faceY + layout[h % 12 * 2 + 1] + ); + } + g.setColor(options.rectFg) + .drawRect(rectX, rectY, rectX + rectW - 1, rectY + rectH - 1); + } else { + g.setColor(options.bg) + .fillRect(rectX + 1, rectY + 1, rectX + rectW - 2, rectY + rectH - 2) + .setColor(options.fg); + } + + // Alerts + let b = new Date(d.getTime()); + b.setHours(keyHour, 0, 0, 0); + if (b > d) b.setDate(b.getDate() - 1); + let requestedRate = events.scan( + d, b, b + 43200000, (e, t, p) => this.alert(e, t, d, p) + ); + if (rate > requestedRate) rate = requestedRate; + + // Hands + // Here we are using incremental hands for hours and minutes. + // If we quantised, we could use hand-crafted bitmaps, though. + this.hours(d.getHours() + d.getMinutes() / 60); + if (rate < 3600000) { + this.minutes(d.getMinutes() + d.getSeconds() / 60); + } + if (rate < 60000) this.seconds(d.getSeconds()); + g.setColor(options.hubFg).fillCircle(faceCX, faceCY, 3); + return requestedRate; + } +} + +////////////////////////////////////////////////////////////////////////////// +/* Master clock */ + +class Clock { + constructor(face) { + this.face = face; + this.timescales = face.timescales; + this.options = face.options; + this.rates = {}; + + this.options.on('done', () => this.start()); + + this.listeners = { + lcdPower: on => on ? this.active() : this.inactive(), + charging: () => {face.doIcons('charging'); this.active();}, + lock: () => {face.doIcons('locked'); this.active();}, + faceUp: up => {this.conservative = !up; this.active();}, + drag: e => { + if (this.t0) { + if (e.b) { + e.x > this.xN && (this.xN = e.x) || e.x > this.xX && (this.xX = e.x); + e.y > this.yN && (this.yN = e.y) || e.y > this.yX && (this.xY = e.y); + } else if (this.xX - this.xN < 20) { + if (e.y - this.e0.y < -50) { + this.options.resolution > 0 && this.options.resolution--; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + } else if (e.y - this.e0.y > 50) { + this.options.resolution < this.timescales.length - 1 && + this.options.resolution++; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + } else if (this.yX - this.yN < 20 && Date.now() - this.t0 > 500) { + this.stop(); + this.options.interact(); + } + this.t0 = null; + } + } else if (e.b) { + this.t0 = Date.now(); this.e0 = e; + this.xN = this.xX = e.x; this.yN = this.yX = e.y; + } + } + }; + } + + redraw(rate) { + const now = this.updated = new Date(); + if (this.refresh) this.face.reset(); + this.refresh = false; + rate = this.face.render(now, rate); + if (rate !== this.rates.face) { + this.rates.face = rate; + this.active(); + } + return this; + } + + inactive() { + this.timeout && clearTimeout(this.timeout); + this.exception && clearTimeout(this.exception); + this.interval && clearInterval(this.interval); + this.timeout = this.exception = this.interval = this.rate = null; + return this; + } + + active() { + const prev = this.rate; + const now = Date.now(); + let rate = Infinity; + for (const k in this.rates) { + let r = this.rates[k]; + r === +r || (r = r[+this.conservative]) + r < rate && (rate = r); + } + const delay = rate - now % rate + 1; + this.refresh = true; + + if (rate !== prev) { + this.inactive(); + this.redraw(rate); + if (rate < 31622400000) { // A year! + this.timeout = setTimeout( + () => { + this.inactive(); + this.interval = setInterval(() => this.redraw(rate), rate); + if (delay > 1000) this.redraw(rate); + this.rate = rate; + }, delay + ); + } + } else if (rate > 1000) { + if (!this.exception) this.exception = setTimeout(() => { + this.redraw(rate); + this.exception = null; + }, this.updated + 1000 - Date.now()); + } + return this; + } + + stop() { + this.inactive(); + for (const l in this.listeners) { + Bangle.removeListener(l, this.listeners[l]); + } + return this; + } + + start() { + this.inactive(); // Reset to known state. + this.conservative = false; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + for (const l in this.listeners) { + Bangle.on(l, this.listeners[l]); + } + Bangle.setUI('clock'); + return this; + } +} + +////////////////////////////////////////////////////////////////////////////// +/* Main */ + +const clock = new Clock(new Roman(g, events)).start(); From ad96a97ae9fc12d8d93dceb60d1c861ce60ad630 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 11:34:25 -0800 Subject: [PATCH 0145/1839] Create app-icon.js --- apps/pooqroman/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/pooqroman/app-icon.js diff --git a/apps/pooqroman/app-icon.js b/apps/pooqroman/app-icon.js new file mode 100644 index 000000000..20a9c8b0a --- /dev/null +++ b/apps/pooqroman/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkBiIAWiEAgIpKEwgrFgAaBgIcBAAwREC4oVBBoQoCAQoXJBogXqI653DC6SnEC9RHXX/6/kSgIAGU5wAICQhfGACAX/C/4AOXIIX/C/4X/C/4XUgEBF6wYHI6AYGL6MACIgXRCIISDR6QYEU6YYDX6gYCAAKxHDB4XTDAYXUL6oAgA==")) From 8ff08cbaab00ce915eac1cf66ac2af4aaee220d9 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 11:35:39 -0800 Subject: [PATCH 0146/1839] Create resourcer.js --- apps/pooqroman/resourcer.js | 721 ++++++++++++++++++++++++++++++++++++ 1 file changed, 721 insertions(+) create mode 100644 apps/pooqroman/resourcer.js diff --git a/apps/pooqroman/resourcer.js b/apps/pooqroman/resourcer.js new file mode 100644 index 000000000..c172812c7 --- /dev/null +++ b/apps/pooqroman/resourcer.js @@ -0,0 +1,721 @@ +// pooqRoman resource maker +// +// Copyright (c) 2021 Stephen P Spackman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// Notes: +// +////////////////////////////////////////////////////////////////////////////// +/* ==ASSETS== */ + +const heatshrink = require('heatshrink'); + +const enc = x => { + const d = btoa(require("heatshrink").compress(x)); + var r = "'" + d.substr(0, 64); + for (let i = 64; i < d.length; i += 64) r += "' +\n '" + d.substr(i, 64); + return r + "'"; +}; + +const prepBitmap = (name, data) => { + const image = Graphics.createImage(data); + const raw = String.fromCharCode(image.width, image.height, 0x81, 0) + image.buffer; + const x = ` +const ${name}I = dec(${enc(raw)}); +`; + return x; +}; + +const prepFont = (name, data) => { + const image = Graphics.createImage(data); + const lengths = Uint8Array(256); + const offsets = Uint16Array(256); + const adjustments = Uint16Array(256); + let min = Infinity, max = -Infinity; + const lines = data.split('\n'); + let m; + // This regexp is clearly suboptimal, but Espruino's regexp engine is really wonky + // and doesn't process nested parentheses or alternation correctly. + for (let i = 0; i < 5 && !(m = /^(<*)=([*\d]+)(=*)(>*)$/.exec(lines[i])); i++); + if (!m) throw new Error('Missing or incorrect header'); + const desc = m[1].length, body = 1 + m[2].length + m[3].length, asc = m[4].length; + const h = desc + body + asc; + let width = m[2] == '*' ? null : +m[2]; + let c = null, o = 0; + lines.forEach((line, l) => { + if (m = /^(<*)(=)([*\d]*)(=*)(>*)$/.exec(line) || /^(<*)(-)(.)(-*)(>*)$/.exec(line)) { + const h = m[2] == '='; + if (m[1].length > desc || h && m[1].length != desc) + throw new Error('Invalid descender height at ' + l); + if (m[2].length + m[3].length + m[4].length != body) + throw new Error('Invalid body height at ' + l); + if (m[5].length > asc || h && m[5].length != asc) + throw new Error('Invalid ascender height at ' + l); + if (c != null) { + lengths[c] = l - o; + if (width !== null && width !== lengths[c]) + throw new Error( + `Character has width ${lengths[c]} != ${width} at ${offsets[c]}` + ); + c = null + } + if (!h) { + c = m[3].charCodeAt(0); + if (c < min) min = c; + if (c > max) max = c; + o = l + 1; + offsets[c] = l; + adjustments[c] = m[1].length + } + } + }); + const xoffs = Uint8Array(lines.length); + const ypos = Uint16Array(lines.length); + ypos.fill(0xffff); + const w0 = lengths[min]; + let widths = ''; + for (c = min, o = 0; c <= max; c++) { + for (i = 0, j = offsets[c]; i < lengths[c]; i++) { + xoffs[j] = asc + body + adjustments[c] - 1; + ypos[j++] = o++; + } + widths += String.fromCharCode(lengths[c]); + } + const raster = Graphics.createArrayBuffer(h, o, 1, {msb: true}); + const writer = Graphics.createCallback( + image.width, image.height, 1, + (x, y, col) => raster.setPixel(xoffs[y] - x, ypos[y], col) + ); + writer.drawImage(image); + if (width === null) width = `dec(${enc(widths)})`; + const x = `const ${name}F = [ + dec( + ${enc(raster.buffer)} + ), ${min}, ${width}, ${h} +];`; + return x; +}; + +res = ` +const heatshrink = require('heatshrink'); +const dec = x => E.toString(heatshrink.decompress(atob(x))); +`; + +res += prepFont('romanParts', ` +<=*============== +-a-------------- +x x +xx xx +-b-------------- +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +-c-------------- +xx xx +x x +-d-------------- +xx xx +xx xx +xx xx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +-e-------------- +xx xx +x xxxx +<-f-------------- + xxxxxxxx + xxxxxxxxxxx + xxxxxxx xx + xxxxxx x +xxxxx + xxxxxx x + xxxxxxx xx + xxxxxxxxxxx + xxxxxxxx +-g-------------- + xxxx + xx + x +-h-------------- + x + xx + xxxx +-i-------------- +x xxxx +xx xx +-j-------------- +xx xx +xxx xxx +xxxx xxxx +xxxxxx xxxxxx +xx xxxx xxxx xx +x xxxxxx x + xxxx +x xxxxxx x +xx xxxx xxxx xx +xxxxxx xxxxxx +xxxx xxxx +xxx xxx +xx xx +-k-------------- +x x +<-l-------------- + xx x + xxxxxx xx + xxxx xxxx xxx + xxxx xx xxxx x +xxx xx + xxxx xx xxxx x + xxxx xxxx xxx + xxxxxx xx + xx x +-m-------------- +x xx x +xx xxxx xx +xxx xxxxxx xxx +x xxxx xx xxxx x + xx xx +x xxxx xx xxxx x +xxx xxxxxx xxx +xx xxxx xx +x xx x +-n-------------- + xxxxxxxx + xxxxxxxxxxxx + xxxx xxxx +xxxx xxxx +xxx xxx +xx xxxx xx +xx xxxx xx +xxx xxx +xxxx xxxx + xxxx xxxx + xxxxxxxxxxxx + xxxxxxxx +<=*============== +`); + +res += prepFont('font', ` +<<<<=*======>>>> +- ------ + +-.------ +xx +xx +-0------>>>> + xxxxxxxx + xxxxxxxxxx +xxx xxx +xx xx +xx xx +xxx xxx + xxxxxxxxxx + xxxxxxxx + +-1------>>>> +xx x +xx xx +xxxxxxxxxxxx +xxxxxxxxxxxx +xx +xx + +-2------>>>> +x x +xx xx +xxx xxx +xxxx xx +xxxxx xx +xx xxx xxx +xx xxxxxxx +xx xxxxx + +-3------>>>> + x xx + xx x xx +xxx xx xx +xx xxx xx +xx xxxxxx +xxx xxx xxx + xxxxxx xx + xxx x + +-4------>>>> + x + xx + xxxx + xxxxxxxxx +xxxxx xxxxx +xxxxx + xx + xx + +-5------>>>> + x xxxxxx + xx xxxxxx +xxx xx xx +xx xx xx +xx xx xx +xxx xxx xx + xxxxxx xx + xxxx + +-6------>>>> + xxxx + xxxxxxx +xxx xxxxx +xx xxxxx +xx xx xxx +xxx xxx xx + xxxxxx x + xxxx + +-7------>>>> + xx + xx +xxxx xx +xxxxxx xx + xxxx xx + xxxxxx + xxxx + x + +-8------>>>> + xxx xxx + xxxxxxxxxx +xxx xxxx xxx +xx xx xx +xx xx xx +xxx xxxx xxx + xxxxxxxxxx + xxx xxx + +-9------>>>> + xxxx +x xxxxxx +xx xxx xxx +xxx xx xx + xxxxx xx + xxxxx xxx + xxxxxxx + xxx + +-A------>>>> +xx +xxxxx + xxxxxxx + xxxxxxx + xx xxxx + xxxxxxx + xxxxxxx +xxxxx +xx + +-D------>>>> +xx xx +xxxxxxxxxxxx +xxxxxxxxxxxx +xx xx +xx xx +xxx xxx + xxxxxxxxxx + xxxxxxxx + +-F------>>>> +xxxxxxxxxxxx +xxxxxxxxxxxx + xx xx + xx xx + xx xx + xx +-I------>>>> +xxxxxxxxxxxx +xxxxxxxxxxxx + +-J------>>>> + xx + xxx xx +xxx xx +xx xx +xxx xx + xxxxxxxxxxx + xxxxxxxxxx + xx +-M------>>>> +xxxxxxxxxxxx +xxxxxxxxxxx + xxx + xxxx + xxxx + xxx +xxxxxxxxxxx +xxxxxxxxxxxx + +-N------>>>> +xxxxxxxxxxxx +xxxxxxxxxxx + xxx + xxx + xxx + xxx + xxxxxxxxxxx +xxxxxxxxxxxx + +-O------>>>> + xxxxxxxx + xxxxxxxxxx +xxx xxx +xx xx +xx xx +xxx xxx + xxxxxxxxxx + xxxxxxxx + +-S------>>>> + x xxx + xx xxxxx +xxx xx xxx +xx xx xx +xx xx xx +xxx xx xxx + xxxxx xx + xxx x + +-T------>>>> + xx + xx + xx +xxxxxxxxxxxx +xxxxxxxxxxxx + xx + xx + xx +-V------>>>> + xxx + xxxxxx + xxxxx +xxxxx + xxxxx + xxxxxx + xxx + +-W------>>>> + xxxx + xxxxxxxx +xxxxxxxx + xxxx + xxxx + xxxx +xxxxxxxx + xxxxxxxx + xxxx +-X------>>>> +xx xx +xxx xxx + xxx xxx + xxxx + xxxx + xxx xxx +xxx xxx +xx xx + +-a------ + xxx +xxxxx x +xx xx xx +xx xx xx +xx xx xx + xxxxxx +xxxxxx + +-b------>>>> +xxxxxxxxxxxx + xxxxxxxxxxx +xx xx +xx xx +xxx xxx + xxxxxx + xxxx + +-c------ + xxxx + xxxxxx +xxx xxx +xx xx +xx xx + xx xx + x x + +-d------>>>> + xxxx + xxxxxx +xxx xxx +xx xx +xx xx + xxxxxxxxxxx +xxxxxxxxxxxx + +-e------ + xxxx + xxxxxx +xx xx xx +xx xx xx +xx xx xx + x xxxx + xxx + +<<<<-g------ + x xxxx + xx xxxxxx +xx xxx xxx +xx xx xx +xxx xx xxx + xxxxxxxxxx + xxxxxxxxx + +-h------>>>> +xxxxxxxxxxxx +xxxxxxxxxxxx + xx + xx + xxx +xxxxxxx +xxxxxx + +-i------>>>> +xxxxxxxx xx +xxxxxxxx xx + +-l------>>>> +xxxxxxxxxxxx +xxxxxxxxxxxx + +-m------ +xxxxxxxx +xxxxxxx + xxx + xxx +xxxxxxx +xxxxxxx + xxx + xxx +xxxxxxx +xxxxxx + +-n------ +xxxxxxxx +xxxxxxx + xxx + xx + xxx +xxxxxxx +xxxxxx + +-o------ + xxxx + xxxxxx +xxx xxx +xx xx +xxx xxx + xxxxxx + xxxx + +<<<<-p------ +xxxxxxxxxxxx +xxxxxxxxxxx + xx xx + xx xx + xxx xxx + xxxxxx + xxxx + +-r------ +xxxxxxxx +xxxxxxx + xxx + xx + xx + xx + +-s------ + x xxx +xx xxxxx +xx xx xx +xx xx xx +xxxxx xx + xxx x + +-t------>>>> + xx + xxxxxxxxx + xxxxxxxxxx +xxx xx +xx xx +xx xx + xx + +-u------ + xxxxxx + xxxxxxx +xxx +xx +xxx + xxxxxxx +xxxxxxxx + +-v------ + xx + xxxx + xxxx +xxxx + xxxx + xxxx + xx + +<<<<-y------ + x xxxxxx + xx xxxxxxx +xx xxx +xx xx +xxx xxx + xxxxxxxxxxx + xxxxxxxxx + +<<<<=*======>>>> +`); + +res += prepBitmap('lock', ` + xxxxxx + xxxxxxxx + xxx xxx + xxx xxx + xxx xxx + xxx xxx + xxx xxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxx xxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxx xxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxx xxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx +`); + +res += prepBitmap('battery', ` + xxxx + xxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx +`); + +res += prepBitmap('charge', ` + x + xx + xx + xxx + xxx + xxxxxxxxx + xxxxxxxxx + xxx + xxx + xx + xx + x +`); + +res += prepBitmap('GPS', ` + x + x x + x x + x x + x x xxxx + x xxxxx + xxxxxx + xxxxx + x xxx x + x x x x x + x x x x x + x x xx x x + x x x x + x xxx x + x + xxx +`); + +res += prepBitmap('HRM', ` + xxxx xxxx + xxxxxx xxxxxx + xx xxxx xxx xxx +xxx xxxxxxxx xxxx +xxx xxxxxxxx xxxx +xxx xxxxxxxx xxxx +xx xxxxxxx xxxx +xx xx xxxx xx x + xx x x x + xx xxxxxxxx xxx + xxxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxx + xxxxxxx + xxxxx + xxx + x +`); + +res += prepBitmap('compass', ` + xxxxx + xxxxxxxxx + xxx x xxx + xx x xx + xx x xx + xx xxx xx +xx xxx xx +xx xxx xx +xx xxx xx +xx xx xx xx +xx xx xx xx + xx x x xx + xx x x xx + xx xx + xxx xxx + xxxxxxxxx + xxxxx +`); + +print(res); From 4803365ab3f8a6b3e2f9a6f650b642326a952010 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 11:49:28 -0800 Subject: [PATCH 0147/1839] Update app.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conform to filename conventions for our settings file—it is json. --- apps/pooqroman/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pooqroman/app.js b/apps/pooqroman/app.js index a5de57210..8da638159 100644 --- a/apps/pooqroman/app.js +++ b/apps/pooqroman/app.js @@ -52,7 +52,7 @@ class Options { // Only fields named in the defaults will be saved. constructor() { this.id = this.constructor.id; - this.file = `${this.id}.opt`; + this.file = `${this.id}.json`; this.backing = storage.readJSON(this.file, true) || {}; this.defaults = this.constructor.defaults; Object.keys(this.defaults).forEach(k => this.bless(k)); From 98bb9c28b3aac54a7a65e2eefd28dccba5a8dbef Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 12:02:15 -0800 Subject: [PATCH 0148/1839] Add files via upload --- apps/pooqroman/app.png | Bin 0 -> 403 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/pooqroman/app.png diff --git a/apps/pooqroman/app.png b/apps/pooqroman/app.png new file mode 100644 index 0000000000000000000000000000000000000000..6edeebbd6e2598d0cf11410655545031ac18ddd0 GIT binary patch literal 403 zcmV;E0c`$>P)Px$O-V#SRA@u(nc)t@AP9ul_kZXuCNm)nyrV50ChVs&^y2`HJzkstj_>~8ierrH zu{%-cx+|Y!eP|~Q=7v{ecR;~SiJ(GTZ6F~mpy69WSg^x}8ApnS6_^ga4WjudSOaLO zWqQaW_R@?^6{M)AL^y?*A}(74OdGXYE>o9KqOijwyi)$R3kqBq5!=pK|=e=xC_yX zFF Date: Thu, 2 Dec 2021 12:16:53 -0800 Subject: [PATCH 0149/1839] Add files via upload Upload the right file this time :-}. --- apps/pooqroman/app.png | Bin 403 -> 3969 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/pooqroman/app.png b/apps/pooqroman/app.png index 6edeebbd6e2598d0cf11410655545031ac18ddd0..bd27186e04c7051f73cdf3c4e1e7afb2bcfde97d 100644 GIT binary patch literal 3969 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 Date: Thu, 2 Dec 2021 12:53:18 -0800 Subject: [PATCH 0150/1839] Create README.md --- apps/pooqroman/README.md | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 apps/pooqroman/README.md diff --git a/apps/pooqroman/README.md b/apps/pooqroman/README.md new file mode 100644 index 000000000..7d611c833 --- /dev/null +++ b/apps/pooqroman/README.md @@ -0,0 +1,42 @@ +# pooq Roman—a classic watch face with amusing dynamicity + +This is a normal watch face for telling the time. +It is unusual in that it supports the 24 hour clock by dynamically updating the labels on the face +(so, if you enable 24 hour mode, you will get to see a hand pointing to XXIII o'clock each evening). + +The date and day of the week can also be displayed, and they choose their own spelling depending on the available screen space. It's fun! + +## Options + +Because sometimes I don't want to burn what I'm cooking and other times I'm lazy and just want to know if it's afternoon yet, +you can alter the number of hands on the display. When the watch is unlocked, slide up to add minute and second hands, or down to remove the distraction. +There's also a setting that displays the second hand, but only if the watch is perfectly face-to-the-sky, in case you want +the ability to check the _exact_ time, hands free, without the impact on battery life this usually entails. + +Although we genrally obey the system-wide theming, you can long press on the display for a menu of additional options specific to the face. +You can also override the system 12/24 hour setting just for this face here, since it's, well, a rather different experience than with numeric displays. + +One other thing: there's some integration with system timers and alarms; they will show as small pips at the appropriate places +in the day around the display. When they come within an hour, the pips turn to crosses relating to the minute hand, and the minute +hand turns itself on. When timers are mere seconds away, the display changes again and the second hand activates itself, so you +can watch as your doom approaches. + +## Limitations + +Since this is intended as a design exercise, it does not and will probably never support the Bangle's standard widgets. +Sorry about that, but control of all the pixels was just too important to me. + +There's also no support for internationalisation at present. This irks me, but… well, talk to me about it if there's a language you'd like. + +## The future + +The design is begging for integration with host-device calendars, and proper time zone/DST support. We'll see what the future holds. + +## Feedback + +[I'd be happy to hear your feedback](https://www.github.com/stephenPspackman) if you have comments or find any bugs, or (most especially) +if you find this work interesting. + +## By + +Made by [Stephen P Spackman](https://www.github.com/stephenPspackman). From 2906e228bad106b86c176ccf8e1639f3c67dd556 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 12:54:03 -0800 Subject: [PATCH 0151/1839] Update apps.json --- apps.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps.json b/apps.json index 877218135..ae86dddc7 100644 --- a/apps.json +++ b/apps.json @@ -4641,5 +4641,21 @@ {"name":"pebble.settings.js","url":"pebble.settings.js"}, {"name":"pebble.img","url":"pebble.icon.js","evaluate":true} ] + }, + { "id": "pooqroman", + "name": "pooq Roman watch face", + "shortName":"pooq Roman", + "version":"0.0.0", + "description": "A classic watch face with a certain dynamicity. Most amusing in 24h mode. Slide up to show more hands, down for less(!). By design does not support standard widgets, sorry!", + "icon": "app.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "allow_emulator":true, + "readme": "README.md", + "storage": [ + {"name":"pooqroman.app.js","url":"app.js"}, + {"name":"pooqroman.img","url":"app-icon.js","evaluate":true} + ] } ] From ade94521b7da3217c6210d0d5e8873012719a792 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 12:57:25 -0800 Subject: [PATCH 0152/1839] Update README.md Github flubs UTF-8? Really? --- apps/pooqroman/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/pooqroman/README.md b/apps/pooqroman/README.md index 7d611c833..b41a4a316 100644 --- a/apps/pooqroman/README.md +++ b/apps/pooqroman/README.md @@ -1,4 +1,4 @@ -# pooq Roman—a classic watch face with amusing dynamicity +# pooq Roman: a classic watch face with amusing dynamicity This is a normal watch face for telling the time. It is unusual in that it supports the 24 hour clock by dynamically updating the labels on the face @@ -26,7 +26,7 @@ can watch as your doom approaches. Since this is intended as a design exercise, it does not and will probably never support the Bangle's standard widgets. Sorry about that, but control of all the pixels was just too important to me. -There's also no support for internationalisation at present. This irks me, but… well, talk to me about it if there's a language you'd like. +There's also no support for internationalisation at present. This irks me, but... well, talk to me about it if there's a language you'd like. ## The future From 32980bf3befaf7a047cfc808df2d9cbd547813ce Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu, 2 Dec 2021 13:04:29 -0800 Subject: [PATCH 0153/1839] Update apps.json Declare pooqroman.json, our private config file. --- apps.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps.json b/apps.json index ae86dddc7..26c4303c8 100644 --- a/apps.json +++ b/apps.json @@ -4656,6 +4656,9 @@ "storage": [ {"name":"pooqroman.app.js","url":"app.js"}, {"name":"pooqroman.img","url":"app-icon.js","evaluate":true} + ], + "data": [ + {"name":"pooqroman.json"} ] } ] From c24f67b06bbb5417355398149b8e4ad12f8d0c19 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 23 Nov 2021 21:25:26 +0100 Subject: [PATCH 0154/1839] settings: remove Quiet Mode LCD options Updating these will be handled by the Quiet Mode Schedule app (qmsched) --- apps.json | 2 +- apps/setting/ChangeLog | 1 + apps/setting/README.md | 2 - apps/setting/settings.js | 129 ++++----------------------------------- 4 files changed, 14 insertions(+), 120 deletions(-) diff --git a/apps.json b/apps.json index 877218135..26dfd1704 100644 --- a/apps.json +++ b/apps.json @@ -119,7 +119,7 @@ { "id": "setting", "name": "Settings", - "version": "0.33", + "version": "0.34", "description": "A menu for setting up Bangle.js", "icon": "settings.png", "tags": "tool,system", diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index faa50405f..d840654fe 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -36,3 +36,4 @@ 0.31: Remove Bangle 1 settings when running on Bangle 2 0.32: Fix 'beep' menu on Bangle.js 2 0.33: Really fix 'beep' menu on Bangle.js 2 this time +0.34: Remove Quiet Mode LCD settings: now handled by Quiet Mode Schedule app diff --git a/apps/setting/README.md b/apps/setting/README.md index 1875fc3b0..fb567030f 100644 --- a/apps/setting/README.md +++ b/apps/setting/README.md @@ -44,6 +44,4 @@ The exact effects depend on the app. In general the watch will not wake up by i - Off: Normal operation - Alarms: Stops notifications, but "alarm" apps will still work - Silent: Blocks even alarms -* **LCD Brightness**, **LCD Timeout**, **Wake on X**: - Override default settings while Quit Mode is active (either as *Alarms* or *Silent*) \ No newline at end of file diff --git a/apps/setting/settings.js b/apps/setting/settings.js index fcf651b6f..9432d0a38 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -7,17 +7,12 @@ let settings; function updateSettings() { //storage.erase('setting.json'); // - not needed, just causes extra writes if settings were the same - if (Object.keys(settings.qmOptions).length === 0) delete settings.qmOptions; storage.write('setting.json', settings); - if (!('qmOptions' in settings)) settings.qmOptions = {}; // easier if this always exists in this file } function updateOptions() { updateSettings(); Bangle.setOptions(settings.options) - if (settings.quiet) { - Bangle.setOptions(settings.qmOptions) - } } function gToInternal(g) { @@ -56,18 +51,12 @@ function resetSettings() { twistMaxY: -800, twistTimeout: 1000 }, - // Quiet Mode options: - // we only set these if we want to override the default value - // qmOptions: {}, - // qmBrightness: undefined, - // qmTimeout: undefined, }; updateSettings(); } settings = storage.readJSON('setting.json', 1); if (!settings) resetSettings(); -if (!('qmOptions' in settings)) settings.qmOptions = {}; // easier if this always exists in here const boolFormat = v => v ? "On" : "Off"; @@ -130,7 +119,16 @@ function showMainMenu() { } } }, - "Quiet Mode": ()=>showQuietModeMenu(), + "Quiet Mode": { + value: settings.quiet|0, + format: v => ["Off", "Alarms", "Silent"][v%3], + onchange: v => { + settings.quiet = v%3; + updateSettings(); + updateOptions(); + if ("qmsched" in WIDGETS) WIDGETS["qmsched"].draw(); + }, + }, 'Locale': ()=>showLocaleMenu(), 'Select Clock': ()=>showClockMenu(), 'Set Time': ()=>showSetTimeMenu(), @@ -352,9 +350,7 @@ function showLCDMenu() { onchange: v => { settings.brightness = v || 1; updateSettings(); - if (!(settings.quiet && "qmBrightness" in settings)) { - Bangle.setLCDBrightness(settings.brightness); - } + Bangle.setLCDBrightness(settings.brightness); } }, 'LCD Timeout': { @@ -365,9 +361,7 @@ function showLCDMenu() { onchange: v => { settings.timeout = 0 | v; updateSettings(); - if (!(settings.quiet && "qmTimeout" in settings)) { - Bangle.setLCDTimeout(settings.timeout); - } + Bangle.setLCDTimeout(settings.timeout); } }, 'Wake on BTN1': { @@ -455,105 +449,6 @@ function showLCDMenu() { }); return E.showMenu(lcdMenu) } -function showQuietModeMenu() { - // we always keep settings.quiet and settings.qmOptions - // other qm values are deleted when not set - const modes = ["Off", "Alarms", "Silent"]; - const qmDisabledFormat = v => v ? "Off" : "-"; - const qmMenu = { - "": {"title": "Quiet Mode"}, - "< Back": () => showMainMenu(), - "Quiet Mode": { - value: settings.quiet|0, - format: v => modes[v%3], - onchange: v => { - settings.quiet = v%3; - updateSettings(); - updateOptions(); - if ("qmsched" in WIDGETS) {WIDGETS["qmsched"].draw();} - }, - }, - "LCD Brightness": { - value: settings.qmBrightness || 0, - min: 0, // 0 = use default - max: 1, - step: 0.1, - format: v => (v>0.05) ? v : "-", - onchange: v => { - if (v>0.05) { // prevent v=0.000000000000001 bugs - settings.qmBrightness = v; - } else { - delete settings.qmBrightness; - } - updateSettings(); - if (settings.qmBrightness) { // show result, even if not quiet right now - Bangle.setLCDBrightness(v); - } else { - Bangle.setLCDBrightness(settings.brightness); - } - }, - }, - "LCD Timeout": { - value: settings.qmTimeout || 0, - min: 0, // 0 = use default (no constant on for quiet mode) - max: 60, - step: 5, - format: v => v>1 ? v : "-", - onchange: v => { - if (v>1) { - settings.qmTimeout = v; - } else { - delete settings.qmTimeout; - } - updateSettings(); - if (settings.quiet && v>1) { - Bangle.setLCDTimeout(v); - } else { - Bangle.setLCDTimeout(settings.timeout); - } - }, - }, - // we disable wakeOn* events by overwriting them as false in qmOptions - // not disabled = not present in qmOptions at all - "Wake on FaceUp": { - value: "wakeOnFaceUp" in settings.qmOptions, - format: qmDisabledFormat, - onchange: () => { - if ("wakeOnFaceUp" in settings.qmOptions) { - delete settings.qmOptions.wakeOnFaceUp; - } else { - settings.qmOptions.wakeOnFaceUp = false; - } - updateOptions(); - }, - }, - "Wake on Touch": { - value: "wakeOnTouch" in settings.qmOptions, - format: qmDisabledFormat, - onchange: () => { - if ("wakeOnTouch" in settings.qmOptions) { - delete settings.qmOptions.wakeOnTouch; - } else { - settings.qmOptions.wakeOnTouch = false; - } - updateOptions(); - }, - }, - "Wake on Twist": { - value: "wakeOnTwist" in settings.qmOptions, - format: qmDisabledFormat, - onchange: () => { - if ("wakeOnTwist" in settings.qmOptions) { - delete settings.qmOptions.wakeOnTwist; - } else { - settings.qmOptions.wakeOnTwist = false; - } - updateOptions(); - }, - }, - }; - return E.showMenu(qmMenu); -} function showLocaleMenu() { const localemenu = { From d743b2266abf069297de59248cb366d6b04ec63c Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 23 Nov 2021 21:27:37 +0100 Subject: [PATCH 0155/1839] boot: remove Quiet Mode options Updating these will be handled by the Quiet Mode Schedule app (qmsched) --- apps.json | 2 +- apps/boot/ChangeLog | 1 + apps/boot/bootupdate.js | 8 +------- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/apps.json b/apps.json index 26dfd1704..505412e2f 100644 --- a/apps.json +++ b/apps.json @@ -16,7 +16,7 @@ { "id": "boot", "name": "Bootloader", - "version": "0.36", + "version": "0.37", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "icon": "bootloader.png", "type": "bootloader", diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 98f80efd9..ffc2be495 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -40,3 +40,4 @@ 0.35: Add Bangle.appRect polyfill Don't set beep vibration up on Bangle.js 2 (built in) 0.36: Add comments to .boot0 to make debugging a bit easier +0.37: Remove Quiet Mode settings: now handled by Quiet Mode Schedule app diff --git a/apps/boot/bootupdate.js b/apps/boot/bootupdate.js index d642426c2..daf311fe6 100644 --- a/apps/boot/bootupdate.js +++ b/apps/boot/bootupdate.js @@ -78,13 +78,7 @@ boot += `E.on('errorFlag', function(errorFlags) { if (global.save) boot += `global.save = function() { throw new Error("You can't use save() on Bangle.js without overwriting the bootloader!"); }\n`; // Apply any settings-specific stuff if (s.options) boot+=`Bangle.setOptions(${E.toJS(s.options)});\n`; -if (s.quiet && s.qmOptions) boot+=`Bangle.setOptions(${E.toJS(s.qmOptions)});\n`; -if (s.quiet && s.qmBrightness) { - if (s.qmBrightness!=1) boot+=`Bangle.setLCDBrightness(${s.qmBrightness});\n`; -} else { - if (s.brightness && s.brightness!=1) boot+=`Bangle.setLCDBrightness(${s.brightness});\n`; -} -if (s.quiet && s.qmTimeout) boot+=`Bangle.setLCDTimeout(${s.qmTimeout});\n`; +if (s.brightness && s.brightness!=1) boot+=`Bangle.setLCDBrightness(${s.brightness});\n`; if (s.passkey!==undefined && s.passkey.length==6) boot+=`NRF.setSecurity({passkey:${s.passkey}, mitm:1, display:1});\n`; if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`; // Pre-2v10 firmwares without a theme/setUI From 3595fab079eb6a91596bc994c7d744109ed5c4fc Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 26 Nov 2021 20:05:40 +0100 Subject: [PATCH 0156/1839] qmsched: manage LCD options Also migrates old settings file: we now store options in qmsched.json, instead of in the global setting.json. --- apps.json | 7 +- apps/qmsched/ChangeLog | 1 + apps/qmsched/README.md | 15 +- apps/qmsched/app.js | 188 ++++++++++++++++++---- apps/qmsched/boot.js | 10 +- apps/qmsched/lib.js | 31 ++-- apps/qmsched/screenshot_b1_edit.png | Bin 0 -> 3610 bytes apps/qmsched/screenshot_b1_lcd.png | Bin 0 -> 4167 bytes apps/qmsched/screenshot_b1_main.png | Bin 0 -> 4050 bytes apps/qmsched/screenshot_b2_edit.png | Bin 0 -> 2946 bytes apps/qmsched/screenshot_b2_lcd.png | Bin 0 -> 3352 bytes apps/qmsched/screenshot_b2_main.png | Bin 0 -> 3226 bytes apps/qmsched/screenshot_edit.png | Bin 3644 -> 0 bytes apps/qmsched/screenshot_main.png | Bin 3661 -> 0 bytes apps/qmsched/screenshot_widget_alarms.png | Bin 3965 -> 0 bytes apps/qmsched/screenshot_widget_silent.png | Bin 3890 -> 0 bytes apps/qmsched/widget.js | 4 +- 17 files changed, 199 insertions(+), 57 deletions(-) create mode 100644 apps/qmsched/screenshot_b1_edit.png create mode 100644 apps/qmsched/screenshot_b1_lcd.png create mode 100644 apps/qmsched/screenshot_b1_main.png create mode 100644 apps/qmsched/screenshot_b2_edit.png create mode 100644 apps/qmsched/screenshot_b2_lcd.png create mode 100644 apps/qmsched/screenshot_b2_main.png delete mode 100644 apps/qmsched/screenshot_edit.png delete mode 100644 apps/qmsched/screenshot_main.png delete mode 100644 apps/qmsched/screenshot_widget_alarms.png delete mode 100644 apps/qmsched/screenshot_widget_silent.png diff --git a/apps.json b/apps.json index 505412e2f..5c6b78482 100644 --- a/apps.json +++ b/apps.json @@ -3797,10 +3797,11 @@ "id": "qmsched", "name": "Quiet Mode Schedule and Widget", "shortName": "Quiet Mode", - "version": "0.03", - "description": "Automatically turn Quiet Mode on or off at set times", + "version": "0.04", + "description": "Automatically turn Quiet Mode on or off at set times, and change LCD options while Quiet Mode is active.", "icon": "app.png", - "screenshots": [{"url":"screenshot_edit.png"},{"url":"screenshot_main.png"},{"url":"screenshot_widget_alarms.png"},{"url":"screenshot_widget_silent.png"}], + "screenshots": [{"url":"screenshot_b1_main.png"},{"url":"screenshot_b1_edit.png"},{"url":"screenshot_b1_lcd.png"}, + {"url":"screenshot_b2_main.png"},{"url":"screenshot_b2_edit.png"},{"url":"screenshot_b2_lcd.png"}], "tags": "tool,widget", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", diff --git a/apps/qmsched/ChangeLog b/apps/qmsched/ChangeLog index 27b5421e8..0b8d67e76 100644 --- a/apps/qmsched/ChangeLog +++ b/apps/qmsched/ChangeLog @@ -1,3 +1,4 @@ 0.01: First version 0.02: Add widget 0.03: Bangle.js 2 support +0.04: Move Quiet Mode LCD options from global settings to this app diff --git a/apps/qmsched/README.md b/apps/qmsched/README.md index 033014789..535ae56e4 100644 --- a/apps/qmsched/README.md +++ b/apps/qmsched/README.md @@ -1,9 +1,14 @@ # Quiet Mode Schedule and Widget -Automatically turn Quiet Mode on or off at set times, and display a widget when enabled. +Automatically turn Quiet Mode on or off at set times, and display a widget when Quiet Mode is active. -### Edit Schedule: -![Main menu](screenshot_main.png) ![Edit Schedule menu](screenshot_edit.png) +| Bangle.js 1 | Bangle.js 2 | +|:---------------------------------------------:|:---------------------------------------------:| +| (widget: Silent mode) | (widget: Alarms mode) | +| ![Main menu](screenshot_b1_main.png) | ![Main menu](screenshot_b2_main.png) | +| ![Edit Schedule menu](screenshot_b1_edit.png) | ![Edit Schedule menu](screenshot_b2_edit.png) | +| ![LCD Options menu](screenshot_b1_lcd.png) | ![LCD Options menu](screenshot_b2_lcd.png) | -### Widget: -![Widget, quiet mode: silent](screenshot_widget_silent.png) ![Widget, quiet mode: alarms](screenshot_widget_alarms.png) +### LCD Settings: + +If set, these override the default LCD settings while Quiet Mode is active. \ No newline at end of file diff --git a/apps/qmsched/app.js b/apps/qmsched/app.js index c6377d4ba..7be3339fb 100644 --- a/apps/qmsched/app.js +++ b/apps/qmsched/app.js @@ -2,27 +2,74 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); const modeNames = ["Off", "Alarms", "Silent"]; -let scheds = require("Storage").readJSON("qmsched.json", 1); -/*scheds = [ - { hr : 6.5, // hours + minutes/60 - mode : 1, // quiet mode (0/1/2) - } -];*/ -if (!scheds) { - // set default schedule on first load of app - scheds = [ - {"hr": 8, "mode": 0}, - {"hr": 22, "mode": 1}, - ]; - require("Storage").writeJSON("qmsched.json", scheds); + +// load global brightness setting +let bSettings = require('Storage').readJSON('setting.json',true)||{}; +let current = 0|bSettings.quiet; +delete bSettings; // we don't need any other global settings + + + + + + +/** + * Save settings to qmsched.json + */ +function save() { + require('Storage').writeJSON('qmsched.json', settings); } -if (scheds.length && scheds.some(s => "last" in s)) { - // cleanup: remove "last" values (used by old versions) - scheds = scheds.map(s => { - delete s.last; - return s; - }); - require("Storage").writeJSON("qmsched.json", scheds); +function get(key, def) { + return (key in settings) ? settings[key] : def; +} +function set(key, val) { + settings[key] = val; save(); + scheds = settings.scheds; options = settings.options; // update references +} +function unset(key) { + delete settings[key]; save(); +} + +let settings, + scheds, options; // references for convenience +/** + * Load settings file, check if we need to migrate old setting formats to new + */ +function loadSettings() { + settings = require('Storage').readJSON("qmsched.json", true) || {}; + + if (Array.isArray(settings)) { + // migrate old file (plain array of schedules, qmOptions stored in global settings file) + require("Storage").erase("qmsched.json"); // need to erase old file, or Things Break, somehow... + let bOptions = require('Storage').readJSON('setting.json',true)||{}; + settings = { + options: bOptions.qmOptions || {}, + scheds: settings, + }; + // store new format + save(); + // and clean up qmOptions from global settings file + delete bOptions.qmOptions; + require('Storage').writeJSON('setting.json',bOptions); + } + // apply defaults + settings = Object.assign({ + options: {}, // Bangle options to override during quiet mode, default = none + scheds: [ + // default schedule: + {"hr": 8, "mode": 0}, + {"hr": 22, "mode": 1}, + ], + }, settings); + scheds = settings.scheds; options = settings.options; + + if (scheds.length && scheds.some(s => "last" in s)) { + // cleanup: remove "last" values (used by older versions) + set('scheds', scheds.map(s => { + delete s.last; + return s; + })); + } } function formatTime(t) { @@ -32,29 +79,35 @@ function formatTime(t) { } function showMainMenu() { - let menu = {"": {"title": "Quiet Mode"}}; + let _m, menu = { + "": {"title": "Quiet Mode"}, + "< Exit": () => load() + }; // "Current Mode""Silent" won't fit on Bangle.js 2 - menu["Current" + ((process.env.HWVERSION===2)?"":" Mode")]= { - value: (require("Storage").readJSON("setting.json", 1) || {}).quiet|0, + menu["Current"+((process.env.HWVERSION===2) ? "" : " Mode")] = { + value: current, format: v => modeNames[v], onchange: function(v) { if (v<0) {v = 2;} if (v>2) {v = 0;} require("qmsched").setMode(v); + current = v; this.value = v; }, }; scheds.sort((a, b) => (a.hr-b.hr)); scheds.forEach((sched, idx) => { - const name = modeNames[sched.mode]; - const txt = formatTime(sched.hr)+" ".repeat(14-name.length)+name; - menu[txt] = function() { - showEditMenu(idx); + menu[formatTime(sched.hr)] = { + format: () => modeNames[sched.mode], // abuse format to right-align text + onchange: function() { + _m.draw = ()=> {}; // prevent redraw of main menu over edit menu + showEditMenu(idx); + } }; }); menu["Add Schedule"] = () => showEditMenu(-1); - menu["< Back"] = () => {load();}; - return E.showMenu(menu); + menu["LCD Settings"] = () => showOptionsMenu(); + _m = E.showMenu(menu); } function showEditMenu(index) { @@ -69,6 +122,7 @@ function showEditMenu(index) { } const menu = { "": {"title": (isNew ? "Add" : "Edit")+" Schedule"}, + "< Cancel": () => showMainMenu(), "Hours": { value: hrs, onchange: function(v) { @@ -110,18 +164,88 @@ function showEditMenu(index) { } else { scheds[index] = getSched(); } - require("Storage").writeJSON("qmsched.json", scheds); + save(); showMainMenu(); }; if (!isNew) { menu["> Delete"] = function() { scheds.splice(index, 1); - require("Storage").writeJSON("qmsched.json", scheds); + save(); showMainMenu(); }; } - menu["< Cancel"] = showMainMenu; return E.showMenu(menu); } +function showOptionsMenu() { + const disabledFormat = v => v ? "Off" : "-"; + function toggle(option) { + // we disable wakeOn* events by setting them to `false` in options + // not disabled = not present in options at all + if (option in options) { + delete options[option]; + } else { + options[option] = false; + } + save(); + } + let resetTimeout; + const oMenu = { + "": {"title": "LCD Settings"}, + "< Back": () => showMainMenu(), + "LCD Brightness": { + value: get("brightness", 0), + min: 0, // 0 = use default + max: 1, + step: 0.1, + format: v => (v>0.05) ? v : "-", + onchange: v => { + if (v>0.05) { // prevent v=0.000000000000001 bugs + set("brightness", v); + Bangle.setLCDBrightness(v); // show result, even if not quiet right now + // restore brightness after half a second + if (resetTimeout) clearTimeout(resetTimeout); + resetTimeout = setTimeout(() => { + resetTimeout = undefined; + require("qmsched").setMode(current); + }, 500); + } else { + unset("brightness"); + require("qmsched").setMode(current); + } + }, + }, + "LCD Timeout": { + value: get("timeout", 0), + min: 0, // 0 = use default (no constant on for quiet mode) + max: 60, + step: 5, + format: v => v>1 ? v : "-", + onchange: v => { + if (v>1) set("timeout", v); + else unset("timeout"); + }, + }, + // we disable wakeOn* events by overwriting them as false in options + // not disabled = not present in options at all + "Wake on FaceUp": { + value: "wakeOnFaceUp" in options, + format: disabledFormat, + onchange: () => {toggle("wakeOnFaceUp");}, + }, + "Wake on Touch": { + value: "wakeOnTouch" in options, + format: disabledFormat, + onchange: () => {toggle("wakeOnTouch");}, + }, + "Wake on Twist": { + value: "wakeOnTwist" in options, + format: disabledFormat, + onchange: () => {toggle("wakeOnTwist");}, + }, + }; + return E.showMenu(oMenu); +} + +loadSettings(); showMainMenu(); diff --git a/apps/qmsched/boot.js b/apps/qmsched/boot.js index 2712cab30..c3bc49b58 100644 --- a/apps/qmsched/boot.js +++ b/apps/qmsched/boot.js @@ -1,7 +1,13 @@ // apply Quiet Mode schedules (function qm() { - let scheds = require("Storage").readJSON("qmsched.json", 1) || []; - if (!scheds.length) { return;} + let bSettings = require('Storage').readJSON('setting.json',true)||{}; + const curr = 0|bSettings.quiet; + delete bSettings; + if (curr) require("qmsched").applyOptions(curr); // no need to re-apply default options + + let settings = require('Storage').readJSON('qmsched.json',true)||{}; + let scheds = settings.scheds||[]; + if (!scheds.length) {return;} const now = new Date(), hr = now.getHours()+(now.getMinutes()/60)+(now.getSeconds()/3600); // current (decimal) hour scheds.sort((a, b) => a.hr-b.hr); diff --git a/apps/qmsched/lib.js b/apps/qmsched/lib.js index a3d36ed34..9b307769a 100644 --- a/apps/qmsched/lib.js +++ b/apps/qmsched/lib.js @@ -1,18 +1,23 @@ +/** + * Apply LCD options for given mode + * @param {int} mode Quiet Mode + */ +exports.applyOptions = function(mode) { + const s = require("Storage").readJSON(mode ? "qmsched.json" : "setting.json", 1) || {}; + const get = (k, d) => k in s ? s[k] : d; + Bangle.setOptions(get("options", {})); + Bangle.setLCDBrightness(get("brightness", 1)); + Bangle.setLCDTimeout(get("timeout", 10)); +}; /** * Set new Quiet Mode and apply Bangle options * @param {int} mode Quiet Mode */ exports.setMode = function(mode) { - let s = require("Storage").readJSON("setting.json", 1) || {}; - s.quiet = mode; - require("Storage").writeJSON("setting.json", s); - if (s.options) Bangle.setOptions(s.options); - if (mode && s.qmOptions) Bangle.setOptions(s.qmOptions); - if (mode && s.qmBrightness) { - if (s.qmBrightness!=1) Bangle.setLCDBrightness(s.qmBrightness); - } else { - if (s.brightness && s.brightness!=1) Bangle.setLCDBrightness(s.brightness); - } - if (mode && s.qmTimeout) Bangle.setLCDTimeout(s.qmTimeout); - if (typeof (WIDGETS)!=="undefined" && "qmsched" in WIDGETS) {WIDGETS["qmsched"].draw();} -}; \ No newline at end of file + require("Storage").writeJSON("setting.json", Object.assign( + require("Storage").readJSON("setting.json", 1) || {}, + {quiet:mode} + )); + exports.applyOptions(mode); + if (WIDGETS && "qmsched" in WIDGETS) WIDGETS["qmsched"].draw(); +}; diff --git a/apps/qmsched/screenshot_b1_edit.png b/apps/qmsched/screenshot_b1_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..ec82e92e6d2de47b89b0f76f18bd1fa58f7a14a6 GIT binary patch literal 3610 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 literal 0 HcmV?d00001 diff --git a/apps/qmsched/screenshot_b1_lcd.png b/apps/qmsched/screenshot_b1_lcd.png new file mode 100644 index 0000000000000000000000000000000000000000..16f9356b89928349ae9a2c4af41dad3cb0c981b2 GIT binary patch literal 4167 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 literal 0 HcmV?d00001 diff --git a/apps/qmsched/screenshot_b1_main.png b/apps/qmsched/screenshot_b1_main.png new file mode 100644 index 0000000000000000000000000000000000000000..803ca69d5607ef9ee696fe121749d49243e70467 GIT binary patch literal 4050 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 literal 0 HcmV?d00001 diff --git a/apps/qmsched/screenshot_b2_lcd.png b/apps/qmsched/screenshot_b2_lcd.png new file mode 100644 index 0000000000000000000000000000000000000000..3f06488c39c6741575b4223b811533352dc5f046 GIT binary patch literal 3352 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 JuhBzC{|gbmTl)Y2 literal 0 HcmV?d00001 diff --git a/apps/qmsched/screenshot_b2_main.png b/apps/qmsched/screenshot_b2_main.png new file mode 100644 index 0000000000000000000000000000000000000000..f6d22a8b8184cce576295a1376f11da88bb96f73 GIT binary patch literal 3226 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 VS$oi8ar|rmS4^yptBvq6{|2w$^<@A6 literal 0 HcmV?d00001 diff --git a/apps/qmsched/screenshot_edit.png b/apps/qmsched/screenshot_edit.png deleted file mode 100644 index 88b7fcad4ac9df533f69b14675f1dcf3d9c25b1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3644 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 diff --git a/apps/qmsched/screenshot_widget_alarms.png b/apps/qmsched/screenshot_widget_alarms.png deleted file mode 100644 index 52dbe246463d0e7d9567d37683f8ecd9535f5414..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3965 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 E52Ui~sQ>@~ diff --git a/apps/qmsched/screenshot_widget_silent.png b/apps/qmsched/screenshot_widget_silent.png deleted file mode 100644 index 38b133650f7f83ee1ca429652f9177f95af5159d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3890 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 {return;} // no alarms // alarms still on: draw alarm icon in bottom-right corner From b595e603334f701cc5feb7e29a2eae804e4b250c Mon Sep 17 00:00:00 2001 From: hughbarney Date: Thu, 2 Dec 2021 22:17:00 +0000 Subject: [PATCH 0157/1839] Pebble: switched to LECO1976 font and slanting boot icon --- apps/pebble/ChangeLog | 2 +- apps/pebble/LECO 1976-Regular.otf | Bin 0 -> 26432 bytes apps/pebble/icons8-sport-shoes-64.png | Bin 2522 -> 0 bytes apps/pebble/pebble.app.js | 11 +++++------ apps/pebble/pebble_screenshot.png | Bin 2560 -> 2426 bytes apps/pebble/pebble_screenshot2.png | Bin 2531 -> 2549 bytes apps/pebble/pebble_screenshot3.png | Bin 2617 -> 2335 bytes 7 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 apps/pebble/LECO 1976-Regular.otf delete mode 100644 apps/pebble/icons8-sport-shoes-64.png diff --git a/apps/pebble/ChangeLog b/apps/pebble/ChangeLog index 54f2e7452..fc3ff3ba4 100644 --- a/apps/pebble/ChangeLog +++ b/apps/pebble/ChangeLog @@ -1,3 +1,3 @@ 0.01: first release 0.02: included deployment of pebble.settings.js in apps.json -0.03: Changed time font to LECO1976Regular42 +0.03: Changed time+calendar font to LECO1976Regular, changed to slanting boot diff --git a/apps/pebble/LECO 1976-Regular.otf b/apps/pebble/LECO 1976-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..05a318224400bacae73f2529f448f780f61b414f GIT binary patch literal 26432 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 F{|A0DE;axF literal 0 HcmV?d00001 diff --git a/apps/pebble/icons8-sport-shoes-64.png b/apps/pebble/icons8-sport-shoes-64.png deleted file mode 100644 index 4ae00db96a02ace82a8f08eb43bbf32a0c08b255..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2522 zcmV<02_^Q4P)^p0K_gw z1`vtanBN840CC8$+eCW@$F4@i1Bt-#o7uUZkXtz34#08V!o^I#dk!{g4V4vT7!3Ns zfG6Mzd=HdcShvqu`WbBmNKHJ8T%jQN&dJz2IClNs7B~xh0VDv&EUe#aES&*yKy+1Q zxs{`nGwz;Vq$Zui*3OP4D;`CuR8mz@CKCj~5AXsUfq&C(+|57+oCGF!X-fd^1*-cP zb2;#_m6ej^k3NN~n|rq}KYo8ZmE~n!oAkg(KnQRNn9)bwJ|PFz1I}IAynxxjK0w=t znEAk5K`^W~QUnHh09Z1s(+yKoaKc=vU;J@7Plfr}vWU?pGxQUFtb z8PHLn>;oe1d2Ah_5m9K2ZM?HOnv(onfQ!It-~?BUZ~>;Zw@(3(D-?vxyq7skAI5uR zK&OBpn20;{B{3hqOJ#8Z08Y-Xj2Rn@w~sGQPA*s}m7V7o7hWXx`@@tL7j`t2051c( z0Aqg{unPF+=oxcZ_}pf^U7TocsAuaF4^ohwaoqrFJ9}nCEN0f?Xk0wJu6drxWF-EZ z1Ko`1C3Qe@mm>wp;|8$J7$_}xDrB&O^ z9V7g??RFo&-nW;wHXZXO4`F7=Kvr&!qe*LE+_YItoIM|aps8VWZ>aFa_2ud`uV@CL{Z!dxB+XyycqHY7~&rYK%2?pGtE`RA3i`qRyy_$ zj!c*`oz%p$RF;=A*j>ZArK8w&=sbxzwYYkCF>l4=*NxTCswb-LfSa$CO_Uno^7tW`G53cnAN(Mask!vJh~Vmx}I zz>7PQ09dkSJ=Q84i|GbU4ddY#Hh28H9nf5r>{`76qaavJv?p%&9?shJn;7ov$H`;g z(W2EdHOPa7(}(fO&SYvEb&MQ8fzZ3dEv|jn{QL14GY-sq6AyOIcN=F0p;Xym=jz7r zG2@vrHv<2Vi5BmGNw23e*E|qcS5=U7_D2-*0c`tI2$>ff*s(tsxm?ae&up}~b_ZdR zOUX@100{4v0eW34b)`j|KKKQjS4Hviib$$Ui!CO+?dd=A^t>tPTg(;p_lFK32m+7X z=Yzku6Kl4g!Dtc)yMGyjhx=Mg_ow)d4e9t8&}o1^W;zXfrjqbhFdL(8!`)FyPSRPP zdteTEsfjl%diuyg5@L_ga``eMke!iAQNaaV9aX&ea3K4R7jh!05_>0SA|G3G!+O`l z*2$&gqg%HO(5U2$9%jq)k;BM*FO)w_bf=~HGOs-u-PigZFqhQ3-!u z?Lh!GJrabq)c~IT`#As>t$qfLy+fb1u8oLRZy>Lvn9p{;*U@f;M28!Ad2ie zRn3l<|H?}{|I;Vw13TZNuCg2tuR#Qi4d&#rBQ#xVB*@2w=Jk)}2S*=b3f{&FuFvEO0Tcg}Ri>lXb3WHR1=+?TklMsgC*aPq`)0zxLB zQdpso%aF@{zGA8_E#}~^4?rekR`>!gHP&+`E*6;#-uiPWMU~CG`B?@snT+MnZbCMo z_f?o6iU^{JNf6PSjOa}QI)jl*&CR68e#^P9KBugG;FZZ_xVYXzU2P3O;m@vm95o77 z%^t|6Jq4UT9D}>x=w5Yh@0JZ1^lf!*SMx&9X(>$2q-pazQXVK|R1k4Oa z@El5RO0fEs`p1yBpP#%DJ& zafD-!LBq$nvT08NrP=Ad>P&vZkL1K3$4aRrFmy8IC54m}T)zXg4Z*8Huv7Y+UVrokYDalHuI5QQ4?#h;;*PtN;1y8_t%(P_UV~T#b?scf)PDzQ^_)_Ibc&x?Fe%T?fH(z^l5V z3^&h#m;?cNA4cSUM- diff --git a/apps/pebble/pebble.app.js b/apps/pebble/pebble.app.js index 45cce90e4..ce9ab3340 100644 --- a/apps/pebble/pebble.app.js +++ b/apps/pebble/pebble.app.js @@ -15,7 +15,7 @@ function loadSettings() { settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'bg': '#0f0', 'color': 'Green'}; } -var img = require("heatshrink").decompress(atob("oFAwkGswA/AH4A/AH4A/AH4A/AFEAD74gdsAfBELlggMhD70iILsAiUAIKQRBgxAHgUiIKQQJUAMSD4JBQsBVBIAq/DEAJBCJ45VHkAxEDwKfDIIUREBq2BmcQCAQeCkczmRBEiAgND4MxSoYGBAAQgCAAohKDARhBG4IeDEAQ8BAA5fJABgpBgFDgEiQgJEHT4IeMmMBkMFAYJJDEQaYDiYfMkECiEEoEDBAX//8ykJsBD4MAWwIALiBeCqAyDn//BoYgBgAeMYAMhgE0CRIOBD58BkEEmCRKkEGD5szkUQqdASJUxD4MAgKBKmUigFEGJZgBAATODFw0CkEBmoOJAAQdB7owBOBDdCgbdED5fd6pRIgDdCeBkxD4fdeAgNEkMFmheLdgIfE6BgGmDdCoDdKDwYfD6gzGiBeBrpLHXYUQXIMgD4NND4SAFZgMRgAKBPwroBBYIeBIAL/CADESL4VmsAcWgMRkQeDAAMAkQAWMAQeCD4MSDqqdBDwgfBAC8GDwiAXDowA/AH4A/AH4A/AH4A/AEA")); +var img = require("heatshrink").decompress(atob("oFAwkEogA/AH4A/AH4A/AH4A/AE8AAAoeXoAfeDQUBmcyD7A+Dh///8QD649CiAfaHwUvD4sEHy0DDYIfEICg+Cn4fHICY+DD4nxcgojOHwgfEIAYfRCIQaDD4ZAFD5r7DH4//kAfRCIZ/GAAnwD5p9DX44fTHgYSBf4ofVDAQEBl4fFUAgfOXoQzBgIfFBAIfPP4RAEAoYAB+cRiK/SG4h/WIBAfXIA7CBAAswD55AHn6fUIBMCD65AHl4gCmcziAfQQJqfQQJpiDgk0IDXxQLRAEECaBM+QgRYRYgUIA0CD4ggSQJiDCiAKBICszAAswD55AHABKBVD7BAFABIqBD5pAFABPxD55AOD6BADiIAJQAyxLABwf/gaAPAH4A/AH4ARA==")); const h = g.getHeight(); const w = g.getWidth(); @@ -66,7 +66,6 @@ function draw() { g.setFontLECO1976Regular42(); g.setFontAlign(0, -1); g.setColor(!batteryWarning ? g.theme.fg : '#fff'); - //g.drawString(timeStr, w/2, h2 - 8); g.drawString(timeStr, w/2, h2 + 8); // contrast bar @@ -78,8 +77,8 @@ function draw() { g.fillRect(0, h3 + t, w, h); g.setColor(settings.bg); - g.drawImage(img, w/2 + ((w/2) - 64)/2, 10, { scale: 1 }); - drawCalendar(((w/2) - 48)/2, 10, 48, 4, da[2]); + g.drawImage(img, w/2 + ((w/2) - 64)/2, 1, { scale: 1 }); + drawCalendar(((w/2) - 42)/2, 14, 42, 4, da[2]); } // at x,y width:wi thicknes:th @@ -96,9 +95,9 @@ function drawCalendar(x,y,wi,th,str) { // second calendar hook, two thirds in g.fillRect(x + (2*wi/3) -(th/2), y - hook_t, x + 2*wi/3 + th - (th/2), y + hook_t); - g.setFont('Vector', 22); + g.setFontLECO1976Regular22(); g.setFontAlign(0, 0); - g.drawString(str, x + wi/2 + th/2, y + wi/2 + th/2); + g.drawString(str, x + wi/2, y + wi/2 + th); } function getSteps() { diff --git a/apps/pebble/pebble_screenshot.png b/apps/pebble/pebble_screenshot.png index f0bd2dd53a98fbbcca1e0198ad8c77d73ffe4fde..169df2d22cf0abf143620b2698393b8bed9f6706 100644 GIT binary patch literal 2426 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 REZoNda}z7$azoeq{{h`>onrt1 literal 2531 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 u#YLbJDL`Tpgvv?)aOj3KpZ@ Date: Fri, 3 Dec 2021 12:02:31 +0800 Subject: [PATCH 0158/1839] Rework idle timeout. --- apps/authentiwatch/app.js | 50 ++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index e399b3e3b..01b30a913 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -110,13 +110,6 @@ var state = { hide:0 }; -function resetIdle() { - if (state.idletimer) { - clearTimeout(state.idletimer); - } - state.idletimer = setTimeout(_=>load(), 10000); -} - function drawToken(id, r) { var x1 = r.x; var y1 = r.y; @@ -153,14 +146,14 @@ function drawToken(id, r) { // counter - draw triangle as swipe hint let yc = (y1 + y2) / 2; g.fillPoly([0, yc, 10, yc - 10, 10, yc + 10, 0, yc]); - adj = 5; + adj = 10; } // digits just below label sz = 30; do { g.setFont("Vector", sz--); } while (g.stringWidth(state.otp) > (r.w - adj)); - g.drawString(state.otp, (x1 + x2) / 2 + adj, y1 + 16, false); + g.drawString(state.otp, (x1 + adj + x2) / 2, y1 + 16, false); } // shaded lines top and bottom g.setColor(0.5, 0.5, 0.5); @@ -170,6 +163,8 @@ function drawToken(id, r) { } function draw() { + var timerfn = load; + var timerdly = 10000; var d = new Date(); resetIdle(); if (state.curtoken != -1) { @@ -216,13 +211,12 @@ function draw() { if (state.drawtimer) { clearTimeout(state.drawtimer); } - var dly; if (tokens[state.curtoken].period > 0) { - dly = (state.otp == calculating) ? 1 : 1000; + timerdly = (state.otp == calculating) ? 1 : 1000; // timed } else { - dly = state.nexttime - d.getTime(); + timerdly = state.nexttime - d.getTime(); // counter } - state.drawtimer = setTimeout(draw, dly); + timerfn = draw; if (tokens[state.curtoken].period <= 0) { state.hide = 0; } @@ -239,10 +233,13 @@ function draw() { g.setFontAlign(0, 0, 0); g.drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2, Bangle.appRect.y + Bangle.appRect.h / 2, false); } + if (state.drawtimer) { + clearTimeout(state.drawtimer); + } + state.drawtimer = setTimeout(timerfn, timerdly); } function onTouch(zone, e) { - resetIdle(); if (e) { var id = Math.floor((state.listy + (e.y - Bangle.appRect.y)) / tokenentryheight); if (id == state.curtoken || tokens.length == 0 || id >= tokens.length) { @@ -264,28 +261,20 @@ function onTouch(zone, e) { state.nextTime = 0; state.curtoken = id; state.hide = 2; - draw(); } } + draw(); } function onDrag(e) { - resetIdle(); if (e.x > g.getWidth() || e.y > g.getHeight()) return; if (e.dx == 0 && e.dy == 0) return; var newy = Math.min(state.listy - e.dy, tokens.length * tokenentryheight - Bangle.appRect.h); - newy = Math.max(0, newy); - if (newy != state.listy) { - state.listy = newy; - draw(); - } + state.listy = Math.max(0, newy); + draw(); } function onSwipe(e) { - resetIdle(); - if (e == 1) { - Bangle.showLauncher(); - } if (e == -1 && state.curtoken != -1 && tokens[state.curtoken].period <= 0) { tokens[state.curtoken].period--; let newsettings={tokens:tokens,misc:settings.misc}; @@ -293,12 +282,11 @@ function onSwipe(e) { state.nextTime = 0; state.otp = ""; state.hide = 2; - draw(); } + draw(); } function bangle1Btn(e) { - resetIdle(); if (tokens.length > 0) { if (state.curtoken == -1) { state.curtoken = state.prevcur; @@ -315,6 +303,8 @@ function bangle1Btn(e) { state.curtoken = -1; state.nextTime = 0; onTouch(0, fakee); + } else { + draw(); // resets idle timer } } @@ -322,9 +312,9 @@ Bangle.on('touch', onTouch); Bangle.on('drag' , onDrag ); Bangle.on('swipe', onSwipe); if (typeof BTN2 == 'number') { - setWatch(function(){bangle1Btn(-1); }, BTN1, {edge:"rising", debounce:50, repeat:true}); - setWatch(function(){Bangle.showLauncher();}, BTN2, {edge:"rising", debounce:50, repeat:true}); - setWatch(function(){bangle1Btn( 1); }, BTN3, {edge:"rising", debounce:50, repeat:true}); + setWatch(function(){bangle1Btn(-1);}, BTN1, {edge:"rising", debounce:50, repeat:true}); + setWatch(function(){load(); }, BTN2, {edge:"rising", debounce:50, repeat:true}); + setWatch(function(){bangle1Btn( 1);}, BTN3, {edge:"rising", debounce:50, repeat:true}); } Bangle.loadWidgets(); From 517ff25fc24f586cc7c0334fc9de503a2163e195 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Fri, 3 Dec 2021 12:07:26 +0800 Subject: [PATCH 0159/1839] Update app.js --- apps/authentiwatch/app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 01b30a913..6fee5f3ea 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -166,7 +166,6 @@ function draw() { var timerfn = load; var timerdly = 10000; var d = new Date(); - resetIdle(); if (state.curtoken != -1) { var t = tokens[state.curtoken]; if (state.otp == calculating) { From 36ae60a81a2e5492ebaf04c35fb8b24c28f64e01 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Fri, 3 Dec 2021 12:15:44 +0800 Subject: [PATCH 0160/1839] Update app.js --- apps/authentiwatch/app.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 6fee5f3ea..b0ff24c75 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -206,10 +206,6 @@ function draw() { } if (drewcur) { // the current token has been drawn - schedule a redraw - clearTimeout(state.idletimer); - if (state.drawtimer) { - clearTimeout(state.drawtimer); - } if (tokens[state.curtoken].period > 0) { timerdly = (state.otp == calculating) ? 1 : 1000; // timed } else { From 184a57ef4251029fa1daa18e259b27e3e5ec3663 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Fri, 3 Dec 2021 12:24:46 +0800 Subject: [PATCH 0161/1839] Update app.js --- apps/authentiwatch/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index b0ff24c75..2c6d09619 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -10,6 +10,8 @@ const calculating = "Calculating"; const notokens = "No tokens"; const notsupported = "Not supported"; +// sample settings: +// {tokens:[{"algorithm":"SHA1","digits":6,"period":30,"issuer":"","account":"","secret":"Bbb","label":"Aaa"}],misc:{}} var settings = require("Storage").readJSON("authentiwatch.json", true) || {tokens:[],misc:{}}; if (settings.data ) tokens = settings.data ; /* v0.02 settings */ if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ From 633cad5cd3f312bc9db84623dfe4e9b6d7199e57 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Fri, 3 Dec 2021 00:11:07 -0800 Subject: [PATCH 0162/1839] Update app.js Fix (hopefully) time zone issues and boundaries in the event scanner. --- apps/pooqroman/app.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/pooqroman/app.js b/apps/pooqroman/app.js index 8da638159..0628196a1 100644 --- a/apps/pooqroman/app.js +++ b/apps/pooqroman/app.js @@ -305,6 +305,8 @@ const formatDow = new Named(4, [ 'Saturday', 'Sat.', 'Sat', 'Sa' ]); +const hceil = x => Math.ceil(x / 3600000) * 3600000; +const hfloor = x => Math.floor(x / 3600000) * 3600000; const isString = x => typeof x == 'string'; const imageWidth = i => isString(i) ? i.charCodeAt(0) : i.width; const imageHeight = i => isString(i) ? i.charCodeAt(1) : i.height; @@ -343,24 +345,24 @@ const events = { return result; }, - span: function(now, width) { + span: function(now, from, to, width) { let o = now.getTimezoneOffset() * 60000; let t = now.getTime() - o; let lfence = [], rfence = []; - this.scan(now, now - width, now + width, (e, d, p) => { + this.scan(now, from, to, (e, d, p) => { if (p) { for (let j = 0; j <= e.priority; j++) { - if (e.time < (lfence[e.priority] || t)) lfence[e.priority] = e.time; + if (d < (lfence[e.priority] || t)) lfence[e.priority] = d; } } else { for (let j = 0; j <= e.priority; j++) { - if (e.time > (rfence[e.priority] || t)) rfence[e.priority] = e.time; + if (d > (rfence[e.priority] || t)) rfence[e.priority] = d; } } }); for (let j = 0; ; j += 0.5) { if ((rfence[Math.ceil(j)] - lfence[Math.floor(j)] || 0) <= width) { - return [lfence[Math.floor(j)] || t, rfence[Math.ceil(j)] || t]; + return [lfence[Math.floor(j)] || now, rfence[Math.ceil(j)] || now]; } } }, @@ -584,11 +586,9 @@ class Roman { // Hour labels and (purely aesthetic) box; clear inner face. let keyHour = d.getHours() < 12 ? 1 : 13; - let alertSpan = events.span(d, 43200000); - let l = Math.floor(alertSpan[0] / 3600000) % 24; - let h = Math.ceil(alertSpan[1] / 3600000) % 24; - if ((l - keyHour + 24) % 24 >= 12) keyHour = l; - else if ((h - keyHour + 24) % 24 >= 12) keyHour = (h + 13) % 24; + let alertSpan = events.span(d, hceil(d) - 39600000, hfloor(d) + 39600000, 39600000); + let l = alertSpan[0].getHours(), h = alertSpan[1].getHours(); + if ((l - keyHour + 24) % 24 >= 12 || (h - keyHour + 24) % 24 >= 12) keyHour = l; if (keyHour !== state.keyHour) { state.keyHour = keyHour; g.setColor(options.bg) @@ -616,11 +616,9 @@ class Roman { } // Alerts - let b = new Date(d.getTime()); - b.setHours(keyHour, 0, 0, 0); - if (b > d) b.setDate(b.getDate() - 1); let requestedRate = events.scan( - d, b, b + 43200000, (e, t, p) => this.alert(e, t, d, p) + d, hfloor(alertSpan[0] + 0), hceil(alertSpan[1] + 0) + 1, + (e, t, p) => this.alert(e, t, d, p) ); if (rate > requestedRate) rate = requestedRate; From 76d40a74503ac8dd60ff3fdd8cc4ac8f153c01a9 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Fri, 3 Dec 2021 00:21:11 -0800 Subject: [PATCH 0163/1839] Update app.js Project configuration has weird objections to tabs. --- apps/pooqroman/app.js | 835 +++++++++++++++++++++--------------------- 1 file changed, 417 insertions(+), 418 deletions(-) diff --git a/apps/pooqroman/app.js b/apps/pooqroman/app.js index 0628196a1..d25fcf1a8 100644 --- a/apps/pooqroman/app.js +++ b/apps/pooqroman/app.js @@ -51,47 +51,46 @@ class Options { // Protocol: subclasses must have static id and defaults fields. // Only fields named in the defaults will be saved. constructor() { - this.id = this.constructor.id; - this.file = `${this.id}.json`; - this.backing = storage.readJSON(this.file, true) || {}; - this.defaults = this.constructor.defaults; - Object.keys(this.defaults).forEach(k => this.bless(k)); + this.id = this.constructor.id; + this.file = `${this.id}.json`; + this.backing = storage.readJSON(this.file, true) || {}; + this.defaults = this.constructor.defaults; + Object.keys(this.defaults).forEach(k => this.bless(k)); } writeBack(delay) { - if (this.timeout) clearTimeout(this.timeout); - this.timeout = setTimeout( - () => { - this.timeout = null; - storage.writeJSON(this.file, this.backing); - }, - delay - ); + if (this.timeout) clearTimeout(this.timeout); + this.timeout = setTimeout( + () => { + this.timeout = null; + storage.writeJSON(this.file, this.backing); + }, + delay + ); } bless(k) { - Object.defineProperty(this, k, { - get: () => this.backing[k] == null ? this.defaults[k] : this.backing[k], - set: v => { - this.backing[k] = v; - // Ten second writeback delay, since the user will roll values up and down. - this.writeBack(10000); - return v; - } - }); - } + Object.defineProperty(this, k, { + get: () => this.backing[k] == null ? this.defaults[k] : this.backing[k], + set: v => { + this.backing[k] = v; + // Ten second writeback delay, since the user will roll values up and down. + this.writeBack(10000); + } + }); + } showMenu(m) { - if (m) { - for (const k in m) if ('init' in m[k]) m[k].value = m[k].init(); - m[''].selected = -1; // Workaround for self-selection bug. - } - E.showMenu(m); + if (m) { + for (const k in m) if ('init' in m[k]) m[k].value = m[k].init(); + m[''].selected = -1; // Workaround for self-selection bug. + } + E.showMenu(m); } reset() { - this.backing = {}; - this.writeBack(0); + this.backing = {}; + this.writeBack(0); } interact() {this.showMenu(this.menu);} @@ -99,34 +98,34 @@ class Options { class RomanOptions extends Options { constructor() { - super(); - this.menu = { - '': {title: '* face options *'}, - '< Back': _ => {this.showMenu(); this.emit('done');}, - Ticks: { - init: _ => this.resolution, - min: 0, max: 3, - onchange: x => this.resolution = x, - format: x => ['seconds', 'seconds (up)', 'minutes', 'hours'][x] - }, - 'Display': { - init: _ => this.o24h == null ? 0 : 1 + this.o24h, - min: 0, max: 2, - onchange: x => this.o24h = [null, 0, 1][x], - format: x => ['system', '12h', '24h'][x] - }, - 'Day of Week': { - init: _ => this.dow, - onchange: x => this.dow = x - }, - Calendar: { - init: _ => this.calendric, - min: 0, max: 2, - onchange: x => this.calendric = x, - format: x => ['none', 'day', 'date'][x] - }, - Defaults: _ => {this.reset();} - }; + super(); + this.menu = { + '': {title: '* face options *'}, + '< Back': _ => {this.showMenu(); this.emit('done');}, + Ticks: { + init: _ => this.resolution, + min: 0, max: 3, + onchange: x => this.resolution = x, + format: x => ['seconds', 'seconds (up)', 'minutes', 'hours'][x] + }, + 'Display': { + init: _ => this.o24h == null ? 0 : 1 + this.o24h, + min: 0, max: 2, + onchange: x => this.o24h = [null, 0, 1][x], + format: x => ['system', '12h', '24h'][x] + }, + 'Day of Week': { + init: _ => this.dow, + onchange: x => this.dow = x + }, + Calendar: { + init: _ => this.calendric, + min: 0, max: 2, + onchange: x => this.calendric = x, + format: x => ['none', 'day', 'date'][x] + }, + Defaults: _ => {this.reset();} + }; } } @@ -196,24 +195,24 @@ class Formattable { class Fixed extends Formattable { constructor(text) { - super(); - this.text = text; + super(); + this.text = text; } squeeze() {return false;} } class Squeezable extends Formattable { constructor(named, index) { - super(); - this.named = named; - this.index = index; - this.end = index + named.forms; + super(); + this.named = named; + this.index = index; + this.end = index + named.forms; } squeeze() { - if (this.index >= this.end) return false; - this.index++; - this.w = null; - return true; + if (this.index >= this.end) return false; + this.index++; + this.w = null; + return true; } get text() {return this.named.table[this.index];} } @@ -319,82 +318,82 @@ const events = { wall: [{time: Number.POSITIVE_INFINITY}], // indexed by nominal ms + TZ ms clean: function(now, l) { - let o = now.getTimezoneOffset() * 60000; - let tf = now.getTime() + l, tw = tf - o; - // Discard stale events: - while (this.wall[0].time <= tw) this.wall.shift(); - while (this.fixed[0].time <= tf) this.fixed.shift(); + let o = now.getTimezoneOffset() * 60000; + let tf = now.getTime() + l, tw = tf - o; + // Discard stale events: + while (this.wall[0].time <= tw) this.wall.shift(); + while (this.fixed[0].time <= tf) this.fixed.shift(); }, scan: function(now, from, to, f) { - result = Infinity; - let o = now.getTimezoneOffset() * 60000; - let t = now.getTime() - o; - let c, p, i, l = from - o, h = to - o; - for (i = 0; (c = this.wall[i]).time < l; i++) ; - for (; (c = this.wall[i]).time < h; i++) { - if ((p = c.time < t) ? c.past : c.future) - result = Math.min(result, f(c, new Date(c.time + o), p)); - } - l += o; h += o; t += o; - for (i = 0; (c = this.fixed[i]).time < l; i++) ; - for (; (c = this.fixed[i]).time < h; i++) { - if ((p = c.time < t) ? c.past : c.future) - result = Math.min(f(c, new Date(c.time), p)); - } - return result; + result = Infinity; + let o = now.getTimezoneOffset() * 60000; + let t = now.getTime() - o; + let c, p, i, l = from - o, h = to - o; + for (i = 0; (c = this.wall[i]).time < l; i++) ; + for (; (c = this.wall[i]).time < h; i++) { + if ((p = c.time < t) ? c.past : c.future) + result = Math.min(result, f(c, new Date(c.time + o), p)); + } + l += o; h += o; t += o; + for (i = 0; (c = this.fixed[i]).time < l; i++) ; + for (; (c = this.fixed[i]).time < h; i++) { + if ((p = c.time < t) ? c.past : c.future) + result = Math.min(f(c, new Date(c.time), p)); + } + return result; }, span: function(now, from, to, width) { - let o = now.getTimezoneOffset() * 60000; - let t = now.getTime() - o; - let lfence = [], rfence = []; - this.scan(now, from, to, (e, d, p) => { - if (p) { - for (let j = 0; j <= e.priority; j++) { - if (d < (lfence[e.priority] || t)) lfence[e.priority] = d; - } - } else { - for (let j = 0; j <= e.priority; j++) { - if (d > (rfence[e.priority] || t)) rfence[e.priority] = d; - } - } - }); - for (let j = 0; ; j += 0.5) { - if ((rfence[Math.ceil(j)] - lfence[Math.floor(j)] || 0) <= width) { - return [lfence[Math.floor(j)] || now, rfence[Math.ceil(j)] || now]; - } - } + let o = now.getTimezoneOffset() * 60000; + let t = now.getTime() - o; + let lfence = [], rfence = []; + this.scan(now, from, to, (e, d, p) => { + if (p) { + for (let j = 0; j <= e.priority; j++) { + if (d < (lfence[e.priority] || t)) lfence[e.priority] = d; + } + } else { + for (let j = 0; j <= e.priority; j++) { + if (d > (rfence[e.priority] || t)) rfence[e.priority] = d; + } + } + }); + for (let j = 0; ; j += 0.5) { + if ((rfence[Math.ceil(j)] - lfence[Math.floor(j)] || 0) <= width) { + return [lfence[Math.floor(j)] || now, rfence[Math.ceil(j)] || now]; + } + } }, insert: function(t, wall, e) { - let v = wall ? this.wall : this.fixed; - e.time = t = t - (wall ? t.getTimezoneOffset() * 60000 : 0); - v.splice(v.findIndex(x => x.time > t), 0, e); + let v = wall ? this.wall : this.fixed; + e.time = t = t - (wall ? t.getTimezoneOffset() * 60000 : 0); + v.splice(v.findIndex(x => x.time > t), 0, e); }, loadFromSystem: function(options) { - alarms.forEach(x => { - if (x.on) { - const t = new Date(); - let h = x.hr; - let m = h % 1 * 60; - let s = m % 1 * 60; - let ms = s % 1 * 1000; - t.setHours(h - h % 1, m - m % 1, s - s % 1, ms); - // There's a race condition here, but I'm not sure what we can do about it. - if (t < Date.now() || x.last === t.getDate()) t.setDate(t.getDate() + 1); - this.insert(t, true, { - priority: 0, - past: false, // System alarms seem uninteresting if past? - future: true, - precision: x.timer ? 1000 : 60000, - colour: x.timer ? options.timerFg : options.alarmFg, - event: x - }); - } - }); - return this; + alarms.forEach(x => { + if (x.on) { + const t = new Date(); + let h = x.hr; + let m = h % 1 * 60; + let s = m % 1 * 60; + let ms = s % 1 * 1000; + t.setHours(h - h % 1, m - m % 1, s - s % 1, ms); + // There's a race condition here, but I'm not sure what we can do about it. + if (t < Date.now() || x.last === t.getDate()) t.setDate(t.getDate() + 1); + this.insert(t, true, { + priority: 0, + past: false, // System alarms seem uninteresting if past? + future: true, + precision: x.timer ? 1000 : 60000, + colour: x.timer ? options.timerFg : options.alarmFg, + event: x + }); + } + }); + return this; }, }; @@ -403,82 +402,82 @@ const events = { class Sidebar { constructor(g, x, y, w, h, options) { - this.g = g; - this.options = options; - this.x = x; - this.y = this.initY = y; - this.h = h; - this.rate = Infinity; - this.doLocked = Sidebar.status(_ => Bangle.isLocked(), lockI); - this.doHRM = Sidebar.status(_ => Bangle.isHRMOn(), HRMI); - this.doGPS = Sidebar.status(_ => Bangle.isGPSOn(), GPSI, Sidebar.gpsColour(options)); + this.g = g; + this.options = options; + this.x = x; + this.y = this.initY = y; + this.h = h; + this.rate = Infinity; + this.doLocked = Sidebar.status(_ => Bangle.isLocked(), lockI); + this.doHRM = Sidebar.status(_ => Bangle.isHRMOn(), HRMI); + this.doGPS = Sidebar.status(_ => Bangle.isGPSOn(), GPSI, Sidebar.gpsColour(options)); } reset(rate) {this.y = this.initY; this.rate = rate; return this;} print(t) { - this.y += 4 + t.print( - this.g.setColor(this.options.barFg).setFontAlign(-1, 1, 1), - this.x + 3, this.y + 4 - ); - return this; + this.y += 4 + t.print( + this.g.setColor(this.options.barFg).setFontAlign(-1, 1, 1), + this.x + 3, this.y + 4 + ); + return this; } pad(n) {this.y += n; return this;} free() {return this.h - this.y;} static status(p, i, c) { - return function() { - if (p()) { - this.g.setColor(c ? c() : this.options.barFg) - .drawImage(i, this.x + 4, this.y += 4); - this.y += imageHeight(i); - } - return this; - }; + return function() { + if (p()) { + this.g.setColor(c ? c() : this.options.barFg) + .drawImage(i, this.x + 4, this.y += 4); + this.y += imageHeight(i); + } + return this; + }; } static gpsColour(o) { - const fix = Bangle.getGPSFix(); - return fix && fix.fix ? o.active : o.barFg; + const fix = Bangle.getGPSFix(); + return fix && fix.fix ? o.active : o.barFg; } doPower() { - const c = Bangle.isCharging(); - const b = E.getBattery(); - if (c || b < 50) { - let g = this.g, x = this.x, y = this.y, options = this.options; - g.setColor(options.barFg).drawImage(batteryI, x + 4, y + 4); - g.setColor(b <= 10 ? '#f00' : b <= 30 ? '#ff0' : '#0f0'); - const h = 13 * (100 - b) / 100; - g.fillRect(x + 8, y + 7 + h, x + 17, y + 20); - // Espruino disallows blank leading rows in icons, for some reason. - if (c) g.setColor(options.barBg).drawImage(chargeI, x + 4, y + 8); - this.y = y + imageHeight(batteryI) + 4; - } - return this; + const c = Bangle.isCharging(); + const b = E.getBattery(); + if (c || b < 50) { + let g = this.g, x = this.x, y = this.y, options = this.options; + g.setColor(options.barFg).drawImage(batteryI, x + 4, y + 4); + g.setColor(b <= 10 ? '#f00' : b <= 30 ? '#ff0' : '#0f0'); + const h = 13 * (100 - b) / 100; + g.fillRect(x + 8, y + 7 + h, x + 17, y + 20); + // Espruino disallows blank leading rows in icons, for some reason. + if (c) g.setColor(options.barBg).drawImage(chargeI, x + 4, y + 8); + this.y = y + imageHeight(batteryI) + 4; + } + return this; } doCompass() { - if (Bangle.isCompassOn()) { - const c = Bangle.getCompass(); - const a = c && this.rate <= 1000; - this.g.setColor(a ? this.options.active : this.options.barFg).drawImage( - compassI, - this.x + 4 + imageWidth(compassI) / 2, - this.y + 4 + imageHeight(compassI) / 2, - a ? {rotate: c.heading / 180 * Math.PI} : undefined - ); - this.y += 4 + imageHeight(compassI); - } - return this; + if (Bangle.isCompassOn()) { + const c = Bangle.getCompass(); + const a = c && this.rate <= 1000; + this.g.setColor(a ? this.options.active : this.options.barFg).drawImage( + compassI, + this.x + 4 + imageWidth(compassI) / 2, + this.y + 4 + imageHeight(compassI) / 2, + a ? {rotate: c.heading / 180 * Math.PI} : undefined + ); + this.y += 4 + imageHeight(compassI); + } + return this; } } class Roman { constructor(g, events) { - this.g = g; - this.state = {}; - const options = this.options = new RomanOptions(); - this.events = events.loadFromSystem(this.options); - this.timescales = [1000, [1000, 60000], 60000, 3600000]; - this.sidebar = new Sidebar(g, barX, barY, barW, barH, options); - this.hours = Roman.hand(g, 3, 0.5, 12, _ => options.hourFg); - this.minutes = Roman.hand(g, 2, 0.9, 60, _ => options.minuteFg); - this.seconds = Roman.hand(g, 1, 0.9, 60, _ => options.secondFg); + this.g = g; + this.state = {}; + const options = this.options = new RomanOptions(); + this.events = events.loadFromSystem(this.options); + this.timescales = [1000, [1000, 60000], 60000, 3600000]; + this.sidebar = new Sidebar(g, barX, barY, barW, barH, options); + this.hours = Roman.hand(g, 3, 0.5, 12, _ => options.hourFg); + this.minutes = Roman.hand(g, 2, 0.9, 60, _ => options.minuteFg); + this.seconds = Roman.hand(g, 1, 0.9, 60, _ => options.secondFg); } reset() {this.state = {}; this.g.clear(true);} @@ -488,150 +487,150 @@ class Roman { // Watch hands. These could be improved, graphically. // If we restricted them to 60 positions, we could feasibly hand-draw them? static hand(g, w, l, d, c) { - return p => { - g.setColor(c()); - p = ((12 * p / d) + 1) % 12; - let h = l * rectW / 2; - let v = l * rectH / 2; - let poly = - p <= 2 ? [faceCX + w, faceCY, faceCX - w, faceCY, - faceCX + h * (p - 1), faceCY - v, - faceCX + h * (p - 1) + 1, faceCY - v] - : p < 6 ? [faceCX + 1, faceCY + w, faceCX + 1, faceCY - w, - faceCX + h, faceCY + v / 2 * (p - 4), - faceCX + h, faceCY + v / 2 * (p - 4) + 1] - : p <= 8 ? [faceCX - w, faceCY + 1, faceCX + w, faceCY + 1, - faceCX - h * (p - 7), faceCY + v, - faceCX - h * (p - 7) - 1, faceCY + v] - : [faceCX, faceCY - w, faceCX, faceCY + w, - faceCX - h, faceCY - v / 2 * (p - 10), - faceCX - h, faceCY - v / 2 * (p - 10) - 1]; - g.fillPoly(poly); - }; + return p => { + g.setColor(c()); + p = ((12 * p / d) + 1) % 12; + let h = l * rectW / 2; + let v = l * rectH / 2; + let poly = + p <= 2 ? [faceCX + w, faceCY, faceCX - w, faceCY, + faceCX + h * (p - 1), faceCY - v, + faceCX + h * (p - 1) + 1, faceCY - v] + : p < 6 ? [faceCX + 1, faceCY + w, faceCX + 1, faceCY - w, + faceCX + h, faceCY + v / 2 * (p - 4), + faceCX + h, faceCY + v / 2 * (p - 4) + 1] + : p <= 8 ? [faceCX - w, faceCY + 1, faceCX + w, faceCY + 1, + faceCX - h * (p - 7), faceCY + v, + faceCX - h * (p - 7) - 1, faceCY + v] + : [faceCX, faceCY - w, faceCX, faceCY + w, + faceCX - h, faceCY - v / 2 * (p - 10), + faceCX - h, faceCY - v / 2 * (p - 10) - 1]; + g.fillPoly(poly); + }; } static pos(p, r) { - let h = r * rectW / 2; - let v = r * rectH / 2; - p = (p + 1) % 12; - return p <= 2 ? [faceCX + h * (p - 1), faceCY - v] - : p < 6 ? [faceCX + h, faceCY + v / 2 * (p - 4)] - : p <= 8 ? [faceCX - h * (p - 7), faceCY + v] - : [faceCX - h, faceCY - v / 2 * (p - 10)]; + let h = r * rectW / 2; + let v = r * rectH / 2; + p = (p + 1) % 12; + return p <= 2 ? [faceCX + h * (p - 1), faceCY - v] + : p < 6 ? [faceCX + h, faceCY + v / 2 * (p - 4)] + : p <= 8 ? [faceCX - h * (p - 7), faceCY + v] + : [faceCX - h, faceCY - v / 2 * (p - 10)]; } alert(e, date, now, past) { - const g = this.g; - g.setColor(e.colour); - const dt = date - now; - if (e.precision < 60000 && dt >= 0 && e.future && dt <= 59000) { // Seconds away - const p = Roman.pos(date.getSeconds() / 5, 0.95); - g.drawLine(faceCX, faceCY, p[0], p[1]); - return 1000; - } else if (e.precision < 3600000 && dt >= 0 && e.future && dt <= 3540000) { // Minutes away - const p = Roman.pos(date.getMinutes() / 5 + date.getSeconds() / 300, 0.8); - g.drawLine(p[0] - 5, p[1], p[0] + 5, p[1]); - g.drawLine(p[0], p[1] - 5, p[0], p[1] + 5); - return dt < 119000 ? 1000 : 60000; // Turn on second hand two minutes up. - } else if (e.precision < 43200000 && dt >= 0 ? e.future : e.past) { // Hours away - const p = Roman.pos(date.getHours() + date.getMinutes() / 60, 0.6); - const poly = [p[0] - 4, p[1], p[0], p[1] - 4, p[0] + 4, p[1], p[0], p[1] + 4]; - if (date >= now) g.fillPoly(poly); - else g.drawPoly(poly, true); - return 3600000; - } - return Infinity; + const g = this.g; + g.setColor(e.colour); + const dt = date - now; + if (e.precision < 60000 && dt >= 0 && e.future && dt <= 59000) { // Seconds away + const p = Roman.pos(date.getSeconds() / 5, 0.95); + g.drawLine(faceCX, faceCY, p[0], p[1]); + return 1000; + } else if (e.precision < 3600000 && dt >= 0 && e.future && dt <= 3540000) { // Minutes away + const p = Roman.pos(date.getMinutes() / 5 + date.getSeconds() / 300, 0.8); + g.drawLine(p[0] - 5, p[1], p[0] + 5, p[1]); + g.drawLine(p[0], p[1] - 5, p[0], p[1] + 5); + return dt < 119000 ? 1000 : 60000; // Turn on second hand two minutes up. + } else if (e.precision < 43200000 && dt >= 0 ? e.future : e.past) { // Hours away + const p = Roman.pos(date.getHours() + date.getMinutes() / 60, 0.6); + const poly = [p[0] - 4, p[1], p[0], p[1] - 4, p[0] + 4, p[1], p[0], p[1] + 4]; + if (date >= now) g.fillPoly(poly); + else g.drawPoly(poly, true); + return 3600000; + } + return Infinity; } render(d, rate) { - const g = this.g; - const state = this.state; - const options = this.options; - const events = this.events; - events.clean(d, -39600000); // 11h + const g = this.g; + const state = this.state; + const options = this.options; + const events = this.events; + events.clean(d, -39600000); // 11h - // Sidebar: icons and date - if (d.getDate() !== state.date || !state.iconsOk) { - const sidebar = this.sidebar; - state.date = d.getDate(); - state.iconsOk = true; - g.setColor(options.barBg).fillRect(barX, barY, barX + barW, barY + barH); + // Sidebar: icons and date + if (d.getDate() !== state.date || !state.iconsOk) { + const sidebar = this.sidebar; + state.date = d.getDate(); + state.iconsOk = true; + g.setColor(options.barBg).fillRect(barX, barY, barX + barW, barY + barH); - sidebar.reset(rate).doLocked().doPower().doGPS().doHRM().doCompass(); - g.setFontCustom.apply(g, fontF); - let formatters = []; - let month, dom, dow; - if (options.calendric > 1) { - formatters.push(month = formatMonth.on(d.getMonth())); - } - if (options.calendric > 0) { - formatters.push(dom = formatDom.on(d.getDate())); - } - if (options.dow) { - formatters.push(dow = formatDow.on(d.getDay())); - } - // Obnoxiously inefficient iterative method :( - let ava = sidebar.free() - 3, use, i = 0, j = 0; - while ((use = formatters.reduce((l, f) => l + f.width(g) + 4, 0)) > ava && - j < formatters.length) - for (j = 0; - !formatters[i++ % formatters.length].squeeze() && - j < formatters.length; - j++) ; - if (dow) sidebar.print(dow); - sidebar.pad(ava - use); - if (month) sidebar.print(month); - if (dom) sidebar.print(dom); - } + sidebar.reset(rate).doLocked().doPower().doGPS().doHRM().doCompass(); + g.setFontCustom.apply(g, fontF); + let formatters = []; + let month, dom, dow; + if (options.calendric > 1) { + formatters.push(month = formatMonth.on(d.getMonth())); + } + if (options.calendric > 0) { + formatters.push(dom = formatDom.on(d.getDate())); + } + if (options.dow) { + formatters.push(dow = formatDow.on(d.getDay())); + } + // Obnoxiously inefficient iterative method :( + let ava = sidebar.free() - 3, use, i = 0, j = 0; + while ((use = formatters.reduce((l, f) => l + f.width(g) + 4, 0)) > ava && + j < formatters.length) + for (j = 0; + !formatters[i++ % formatters.length].squeeze() && + j < formatters.length; + j++) ; + if (dow) sidebar.print(dow); + sidebar.pad(ava - use); + if (month) sidebar.print(month); + if (dom) sidebar.print(dom); + } - // Hour labels and (purely aesthetic) box; clear inner face. - let keyHour = d.getHours() < 12 ? 1 : 13; - let alertSpan = events.span(d, hceil(d) - 39600000, hfloor(d) + 39600000, 39600000); - let l = alertSpan[0].getHours(), h = alertSpan[1].getHours(); - if ((l - keyHour + 24) % 24 >= 12 || (h - keyHour + 24) % 24 >= 12) keyHour = l; - if (keyHour !== state.keyHour) { - state.keyHour = keyHour; - g.setColor(options.bg) - .fillRect(faceX, faceY, faceX + faceW, faceY + faceH) - .setFontCustom.apply(g, romanPartsF) - .setFontAlign(0, 1) - .setColor(options.fg); - // In order to deal with timezone changes more logic will be required, - // since the labels may be in unusual locations (even offset when - // a non-integral zone is involved). The value of keyHour can be - // anything in [hr-12, hr] mod 24. - for (let h = keyHour; h < keyHour + 12; h++) { - g.drawString( - numeral(h % 24, options), - faceX + layout[h % 12 * 2], - faceY + layout[h % 12 * 2 + 1] - ); - } - g.setColor(options.rectFg) - .drawRect(rectX, rectY, rectX + rectW - 1, rectY + rectH - 1); - } else { - g.setColor(options.bg) - .fillRect(rectX + 1, rectY + 1, rectX + rectW - 2, rectY + rectH - 2) - .setColor(options.fg); - } + // Hour labels and (purely aesthetic) box; clear inner face. + let keyHour = d.getHours() < 12 ? 1 : 13; + let alertSpan = events.span(d, hceil(d) - 39600000, hfloor(d) + 39600000, 39600000); + let l = alertSpan[0].getHours(), h = alertSpan[1].getHours(); + if ((l - keyHour + 24) % 24 >= 12 || (h - keyHour + 24) % 24 >= 12) keyHour = l; + if (keyHour !== state.keyHour) { + state.keyHour = keyHour; + g.setColor(options.bg) + .fillRect(faceX, faceY, faceX + faceW, faceY + faceH) + .setFontCustom.apply(g, romanPartsF) + .setFontAlign(0, 1) + .setColor(options.fg); + // In order to deal with timezone changes more logic will be required, + // since the labels may be in unusual locations (even offset when + // a non-integral zone is involved). The value of keyHour can be + // anything in [hr-12, hr] mod 24. + for (let h = keyHour; h < keyHour + 12; h++) { + g.drawString( + numeral(h % 24, options), + faceX + layout[h % 12 * 2], + faceY + layout[h % 12 * 2 + 1] + ); + } + g.setColor(options.rectFg) + .drawRect(rectX, rectY, rectX + rectW - 1, rectY + rectH - 1); + } else { + g.setColor(options.bg) + .fillRect(rectX + 1, rectY + 1, rectX + rectW - 2, rectY + rectH - 2) + .setColor(options.fg); + } - // Alerts - let requestedRate = events.scan( - d, hfloor(alertSpan[0] + 0), hceil(alertSpan[1] + 0) + 1, - (e, t, p) => this.alert(e, t, d, p) - ); - if (rate > requestedRate) rate = requestedRate; - - // Hands - // Here we are using incremental hands for hours and minutes. - // If we quantised, we could use hand-crafted bitmaps, though. - this.hours(d.getHours() + d.getMinutes() / 60); - if (rate < 3600000) { - this.minutes(d.getMinutes() + d.getSeconds() / 60); - } - if (rate < 60000) this.seconds(d.getSeconds()); - g.setColor(options.hubFg).fillCircle(faceCX, faceCY, 3); - return requestedRate; + // Alerts + let requestedRate = events.scan( + d, hfloor(alertSpan[0] + 0), hceil(alertSpan[1] + 0) + 1, + (e, t, p) => this.alert(e, t, d, p) + ); + if (rate > requestedRate) rate = requestedRate; + + // Hands + // Here we are using incremental hands for hours and minutes. + // If we quantised, we could use hand-crafted bitmaps, though. + this.hours(d.getHours() + d.getMinutes() / 60); + if (rate < 3600000) { + this.minutes(d.getMinutes() + d.getSeconds() / 60); + } + if (rate < 60000) this.seconds(d.getSeconds()); + g.setColor(options.hubFg).fillCircle(faceCX, faceCY, 3); + return requestedRate; } } @@ -640,119 +639,119 @@ class Roman { class Clock { constructor(face) { - this.face = face; - this.timescales = face.timescales; - this.options = face.options; - this.rates = {}; + this.face = face; + this.timescales = face.timescales; + this.options = face.options; + this.rates = {}; - this.options.on('done', () => this.start()); - - this.listeners = { - lcdPower: on => on ? this.active() : this.inactive(), - charging: () => {face.doIcons('charging'); this.active();}, - lock: () => {face.doIcons('locked'); this.active();}, - faceUp: up => {this.conservative = !up; this.active();}, - drag: e => { - if (this.t0) { - if (e.b) { - e.x > this.xN && (this.xN = e.x) || e.x > this.xX && (this.xX = e.x); - e.y > this.yN && (this.yN = e.y) || e.y > this.yX && (this.xY = e.y); - } else if (this.xX - this.xN < 20) { - if (e.y - this.e0.y < -50) { - this.options.resolution > 0 && this.options.resolution--; - this.rates.clock = this.timescales[this.options.resolution]; - this.active(); - } else if (e.y - this.e0.y > 50) { - this.options.resolution < this.timescales.length - 1 && - this.options.resolution++; - this.rates.clock = this.timescales[this.options.resolution]; - this.active(); - } else if (this.yX - this.yN < 20 && Date.now() - this.t0 > 500) { - this.stop(); - this.options.interact(); - } - this.t0 = null; - } - } else if (e.b) { - this.t0 = Date.now(); this.e0 = e; - this.xN = this.xX = e.x; this.yN = this.yX = e.y; - } - } - }; + this.options.on('done', () => this.start()); + + this.listeners = { + lcdPower: on => on ? this.active() : this.inactive(), + charging: () => {face.doIcons('charging'); this.active();}, + lock: () => {face.doIcons('locked'); this.active();}, + faceUp: up => {this.conservative = !up; this.active();}, + drag: e => { + if (this.t0) { + if (e.b) { + e.x > this.xN && (this.xN = e.x) || e.x > this.xX && (this.xX = e.x); + e.y > this.yN && (this.yN = e.y) || e.y > this.yX && (this.xY = e.y); + } else if (this.xX - this.xN < 20) { + if (e.y - this.e0.y < -50) { + this.options.resolution > 0 && this.options.resolution--; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + } else if (e.y - this.e0.y > 50) { + this.options.resolution < this.timescales.length - 1 && + this.options.resolution++; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + } else if (this.yX - this.yN < 20 && Date.now() - this.t0 > 500) { + this.stop(); + this.options.interact(); + } + this.t0 = null; + } + } else if (e.b) { + this.t0 = Date.now(); this.e0 = e; + this.xN = this.xX = e.x; this.yN = this.yX = e.y; + } + } + }; } redraw(rate) { - const now = this.updated = new Date(); - if (this.refresh) this.face.reset(); - this.refresh = false; - rate = this.face.render(now, rate); - if (rate !== this.rates.face) { - this.rates.face = rate; - this.active(); - } - return this; + const now = this.updated = new Date(); + if (this.refresh) this.face.reset(); + this.refresh = false; + rate = this.face.render(now, rate); + if (rate !== this.rates.face) { + this.rates.face = rate; + this.active(); + } + return this; } inactive() { - this.timeout && clearTimeout(this.timeout); - this.exception && clearTimeout(this.exception); - this.interval && clearInterval(this.interval); - this.timeout = this.exception = this.interval = this.rate = null; - return this; + this.timeout && clearTimeout(this.timeout); + this.exception && clearTimeout(this.exception); + this.interval && clearInterval(this.interval); + this.timeout = this.exception = this.interval = this.rate = null; + return this; } active() { - const prev = this.rate; - const now = Date.now(); - let rate = Infinity; - for (const k in this.rates) { - let r = this.rates[k]; - r === +r || (r = r[+this.conservative]) - r < rate && (rate = r); - } - const delay = rate - now % rate + 1; - this.refresh = true; - - if (rate !== prev) { - this.inactive(); - this.redraw(rate); - if (rate < 31622400000) { // A year! - this.timeout = setTimeout( - () => { - this.inactive(); - this.interval = setInterval(() => this.redraw(rate), rate); - if (delay > 1000) this.redraw(rate); - this.rate = rate; - }, delay - ); - } - } else if (rate > 1000) { - if (!this.exception) this.exception = setTimeout(() => { - this.redraw(rate); - this.exception = null; - }, this.updated + 1000 - Date.now()); - } - return this; + const prev = this.rate; + const now = Date.now(); + let rate = Infinity; + for (const k in this.rates) { + let r = this.rates[k]; + r === +r || (r = r[+this.conservative]) + r < rate && (rate = r); + } + const delay = rate - now % rate + 1; + this.refresh = true; + + if (rate !== prev) { + this.inactive(); + this.redraw(rate); + if (rate < 31622400000) { // A year! + this.timeout = setTimeout( + () => { + this.inactive(); + this.interval = setInterval(() => this.redraw(rate), rate); + if (delay > 1000) this.redraw(rate); + this.rate = rate; + }, delay + ); + } + } else if (rate > 1000) { + if (!this.exception) this.exception = setTimeout(() => { + this.redraw(rate); + this.exception = null; + }, this.updated + 1000 - Date.now()); + } + return this; } stop() { - this.inactive(); - for (const l in this.listeners) { - Bangle.removeListener(l, this.listeners[l]); - } - return this; + this.inactive(); + for (const l in this.listeners) { + Bangle.removeListener(l, this.listeners[l]); + } + return this; } start() { - this.inactive(); // Reset to known state. - this.conservative = false; - this.rates.clock = this.timescales[this.options.resolution]; - this.active(); - for (const l in this.listeners) { - Bangle.on(l, this.listeners[l]); - } - Bangle.setUI('clock'); - return this; + this.inactive(); // Reset to known state. + this.conservative = false; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + for (const l in this.listeners) { + Bangle.on(l, this.listeners[l]); + } + Bangle.setUI('clock'); + return this; } } From 0d6dfca317804b6138cf1ec43787532e2a8a0368 Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Fri, 3 Dec 2021 00:22:17 -0800 Subject: [PATCH 0164/1839] Update resourcer.js Project configuration has weird objection to tabs. --- apps/pooqroman/resourcer.js | 56 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/pooqroman/resourcer.js b/apps/pooqroman/resourcer.js index c172812c7..69365018e 100644 --- a/apps/pooqroman/resourcer.js +++ b/apps/pooqroman/resourcer.js @@ -63,27 +63,27 @@ const prepFont = (name, data) => { if (m = /^(<*)(=)([*\d]*)(=*)(>*)$/.exec(line) || /^(<*)(-)(.)(-*)(>*)$/.exec(line)) { const h = m[2] == '='; if (m[1].length > desc || h && m[1].length != desc) - throw new Error('Invalid descender height at ' + l); - if (m[2].length + m[3].length + m[4].length != body) - throw new Error('Invalid body height at ' + l); - if (m[5].length > asc || h && m[5].length != asc) - throw new Error('Invalid ascender height at ' + l); - if (c != null) { - lengths[c] = l - o; - if (width !== null && width !== lengths[c]) - throw new Error( - `Character has width ${lengths[c]} != ${width} at ${offsets[c]}` - ); - c = null - } - if (!h) { - c = m[3].charCodeAt(0); - if (c < min) min = c; - if (c > max) max = c; - o = l + 1; - offsets[c] = l; - adjustments[c] = m[1].length - } + throw new Error('Invalid descender height at ' + l); + if (m[2].length + m[3].length + m[4].length != body) + throw new Error('Invalid body height at ' + l); + if (m[5].length > asc || h && m[5].length != asc) + throw new Error('Invalid ascender height at ' + l); + if (c != null) { + lengths[c] = l - o; + if (width !== null && width !== lengths[c]) + throw new Error( + `Character has width ${lengths[c]} != ${width} at ${offsets[c]}` + ); + c = null + } + if (!h) { + c = m[3].charCodeAt(0); + if (c < min) min = c; + if (c > max) max = c; + o = l + 1; + offsets[c] = l; + adjustments[c] = m[1].length + } } }); const xoffs = Uint8Array(lines.length); @@ -92,16 +92,16 @@ const prepFont = (name, data) => { const w0 = lengths[min]; let widths = ''; for (c = min, o = 0; c <= max; c++) { - for (i = 0, j = offsets[c]; i < lengths[c]; i++) { - xoffs[j] = asc + body + adjustments[c] - 1; - ypos[j++] = o++; - } - widths += String.fromCharCode(lengths[c]); + for (i = 0, j = offsets[c]; i < lengths[c]; i++) { + xoffs[j] = asc + body + adjustments[c] - 1; + ypos[j++] = o++; + } + widths += String.fromCharCode(lengths[c]); } const raster = Graphics.createArrayBuffer(h, o, 1, {msb: true}); const writer = Graphics.createCallback( - image.width, image.height, 1, - (x, y, col) => raster.setPixel(xoffs[y] - x, ypos[y], col) + image.width, image.height, 1, + (x, y, col) => raster.setPixel(xoffs[y] - x, ypos[y], col) ); writer.drawImage(image); if (width === null) width = `dec(${enc(widths)})`; From b5fa5fb64e60e70fc104bd60c08a7ef12b2c3146 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 3 Dec 2021 08:24:12 +0000 Subject: [PATCH 0165/1839] tweak for lint errors - still some assignment warnings --- apps/pooqroman/app.js | 835 ++++++++++++++++++------------------ apps/pooqroman/resourcer.js | 56 +-- 2 files changed, 445 insertions(+), 446 deletions(-) diff --git a/apps/pooqroman/app.js b/apps/pooqroman/app.js index 0628196a1..d25fcf1a8 100644 --- a/apps/pooqroman/app.js +++ b/apps/pooqroman/app.js @@ -51,47 +51,46 @@ class Options { // Protocol: subclasses must have static id and defaults fields. // Only fields named in the defaults will be saved. constructor() { - this.id = this.constructor.id; - this.file = `${this.id}.json`; - this.backing = storage.readJSON(this.file, true) || {}; - this.defaults = this.constructor.defaults; - Object.keys(this.defaults).forEach(k => this.bless(k)); + this.id = this.constructor.id; + this.file = `${this.id}.json`; + this.backing = storage.readJSON(this.file, true) || {}; + this.defaults = this.constructor.defaults; + Object.keys(this.defaults).forEach(k => this.bless(k)); } writeBack(delay) { - if (this.timeout) clearTimeout(this.timeout); - this.timeout = setTimeout( - () => { - this.timeout = null; - storage.writeJSON(this.file, this.backing); - }, - delay - ); + if (this.timeout) clearTimeout(this.timeout); + this.timeout = setTimeout( + () => { + this.timeout = null; + storage.writeJSON(this.file, this.backing); + }, + delay + ); } bless(k) { - Object.defineProperty(this, k, { - get: () => this.backing[k] == null ? this.defaults[k] : this.backing[k], - set: v => { - this.backing[k] = v; - // Ten second writeback delay, since the user will roll values up and down. - this.writeBack(10000); - return v; - } - }); - } + Object.defineProperty(this, k, { + get: () => this.backing[k] == null ? this.defaults[k] : this.backing[k], + set: v => { + this.backing[k] = v; + // Ten second writeback delay, since the user will roll values up and down. + this.writeBack(10000); + } + }); + } showMenu(m) { - if (m) { - for (const k in m) if ('init' in m[k]) m[k].value = m[k].init(); - m[''].selected = -1; // Workaround for self-selection bug. - } - E.showMenu(m); + if (m) { + for (const k in m) if ('init' in m[k]) m[k].value = m[k].init(); + m[''].selected = -1; // Workaround for self-selection bug. + } + E.showMenu(m); } reset() { - this.backing = {}; - this.writeBack(0); + this.backing = {}; + this.writeBack(0); } interact() {this.showMenu(this.menu);} @@ -99,34 +98,34 @@ class Options { class RomanOptions extends Options { constructor() { - super(); - this.menu = { - '': {title: '* face options *'}, - '< Back': _ => {this.showMenu(); this.emit('done');}, - Ticks: { - init: _ => this.resolution, - min: 0, max: 3, - onchange: x => this.resolution = x, - format: x => ['seconds', 'seconds (up)', 'minutes', 'hours'][x] - }, - 'Display': { - init: _ => this.o24h == null ? 0 : 1 + this.o24h, - min: 0, max: 2, - onchange: x => this.o24h = [null, 0, 1][x], - format: x => ['system', '12h', '24h'][x] - }, - 'Day of Week': { - init: _ => this.dow, - onchange: x => this.dow = x - }, - Calendar: { - init: _ => this.calendric, - min: 0, max: 2, - onchange: x => this.calendric = x, - format: x => ['none', 'day', 'date'][x] - }, - Defaults: _ => {this.reset();} - }; + super(); + this.menu = { + '': {title: '* face options *'}, + '< Back': _ => {this.showMenu(); this.emit('done');}, + Ticks: { + init: _ => this.resolution, + min: 0, max: 3, + onchange: x => this.resolution = x, + format: x => ['seconds', 'seconds (up)', 'minutes', 'hours'][x] + }, + 'Display': { + init: _ => this.o24h == null ? 0 : 1 + this.o24h, + min: 0, max: 2, + onchange: x => this.o24h = [null, 0, 1][x], + format: x => ['system', '12h', '24h'][x] + }, + 'Day of Week': { + init: _ => this.dow, + onchange: x => this.dow = x + }, + Calendar: { + init: _ => this.calendric, + min: 0, max: 2, + onchange: x => this.calendric = x, + format: x => ['none', 'day', 'date'][x] + }, + Defaults: _ => {this.reset();} + }; } } @@ -196,24 +195,24 @@ class Formattable { class Fixed extends Formattable { constructor(text) { - super(); - this.text = text; + super(); + this.text = text; } squeeze() {return false;} } class Squeezable extends Formattable { constructor(named, index) { - super(); - this.named = named; - this.index = index; - this.end = index + named.forms; + super(); + this.named = named; + this.index = index; + this.end = index + named.forms; } squeeze() { - if (this.index >= this.end) return false; - this.index++; - this.w = null; - return true; + if (this.index >= this.end) return false; + this.index++; + this.w = null; + return true; } get text() {return this.named.table[this.index];} } @@ -319,82 +318,82 @@ const events = { wall: [{time: Number.POSITIVE_INFINITY}], // indexed by nominal ms + TZ ms clean: function(now, l) { - let o = now.getTimezoneOffset() * 60000; - let tf = now.getTime() + l, tw = tf - o; - // Discard stale events: - while (this.wall[0].time <= tw) this.wall.shift(); - while (this.fixed[0].time <= tf) this.fixed.shift(); + let o = now.getTimezoneOffset() * 60000; + let tf = now.getTime() + l, tw = tf - o; + // Discard stale events: + while (this.wall[0].time <= tw) this.wall.shift(); + while (this.fixed[0].time <= tf) this.fixed.shift(); }, scan: function(now, from, to, f) { - result = Infinity; - let o = now.getTimezoneOffset() * 60000; - let t = now.getTime() - o; - let c, p, i, l = from - o, h = to - o; - for (i = 0; (c = this.wall[i]).time < l; i++) ; - for (; (c = this.wall[i]).time < h; i++) { - if ((p = c.time < t) ? c.past : c.future) - result = Math.min(result, f(c, new Date(c.time + o), p)); - } - l += o; h += o; t += o; - for (i = 0; (c = this.fixed[i]).time < l; i++) ; - for (; (c = this.fixed[i]).time < h; i++) { - if ((p = c.time < t) ? c.past : c.future) - result = Math.min(f(c, new Date(c.time), p)); - } - return result; + result = Infinity; + let o = now.getTimezoneOffset() * 60000; + let t = now.getTime() - o; + let c, p, i, l = from - o, h = to - o; + for (i = 0; (c = this.wall[i]).time < l; i++) ; + for (; (c = this.wall[i]).time < h; i++) { + if ((p = c.time < t) ? c.past : c.future) + result = Math.min(result, f(c, new Date(c.time + o), p)); + } + l += o; h += o; t += o; + for (i = 0; (c = this.fixed[i]).time < l; i++) ; + for (; (c = this.fixed[i]).time < h; i++) { + if ((p = c.time < t) ? c.past : c.future) + result = Math.min(f(c, new Date(c.time), p)); + } + return result; }, span: function(now, from, to, width) { - let o = now.getTimezoneOffset() * 60000; - let t = now.getTime() - o; - let lfence = [], rfence = []; - this.scan(now, from, to, (e, d, p) => { - if (p) { - for (let j = 0; j <= e.priority; j++) { - if (d < (lfence[e.priority] || t)) lfence[e.priority] = d; - } - } else { - for (let j = 0; j <= e.priority; j++) { - if (d > (rfence[e.priority] || t)) rfence[e.priority] = d; - } - } - }); - for (let j = 0; ; j += 0.5) { - if ((rfence[Math.ceil(j)] - lfence[Math.floor(j)] || 0) <= width) { - return [lfence[Math.floor(j)] || now, rfence[Math.ceil(j)] || now]; - } - } + let o = now.getTimezoneOffset() * 60000; + let t = now.getTime() - o; + let lfence = [], rfence = []; + this.scan(now, from, to, (e, d, p) => { + if (p) { + for (let j = 0; j <= e.priority; j++) { + if (d < (lfence[e.priority] || t)) lfence[e.priority] = d; + } + } else { + for (let j = 0; j <= e.priority; j++) { + if (d > (rfence[e.priority] || t)) rfence[e.priority] = d; + } + } + }); + for (let j = 0; ; j += 0.5) { + if ((rfence[Math.ceil(j)] - lfence[Math.floor(j)] || 0) <= width) { + return [lfence[Math.floor(j)] || now, rfence[Math.ceil(j)] || now]; + } + } }, insert: function(t, wall, e) { - let v = wall ? this.wall : this.fixed; - e.time = t = t - (wall ? t.getTimezoneOffset() * 60000 : 0); - v.splice(v.findIndex(x => x.time > t), 0, e); + let v = wall ? this.wall : this.fixed; + e.time = t = t - (wall ? t.getTimezoneOffset() * 60000 : 0); + v.splice(v.findIndex(x => x.time > t), 0, e); }, loadFromSystem: function(options) { - alarms.forEach(x => { - if (x.on) { - const t = new Date(); - let h = x.hr; - let m = h % 1 * 60; - let s = m % 1 * 60; - let ms = s % 1 * 1000; - t.setHours(h - h % 1, m - m % 1, s - s % 1, ms); - // There's a race condition here, but I'm not sure what we can do about it. - if (t < Date.now() || x.last === t.getDate()) t.setDate(t.getDate() + 1); - this.insert(t, true, { - priority: 0, - past: false, // System alarms seem uninteresting if past? - future: true, - precision: x.timer ? 1000 : 60000, - colour: x.timer ? options.timerFg : options.alarmFg, - event: x - }); - } - }); - return this; + alarms.forEach(x => { + if (x.on) { + const t = new Date(); + let h = x.hr; + let m = h % 1 * 60; + let s = m % 1 * 60; + let ms = s % 1 * 1000; + t.setHours(h - h % 1, m - m % 1, s - s % 1, ms); + // There's a race condition here, but I'm not sure what we can do about it. + if (t < Date.now() || x.last === t.getDate()) t.setDate(t.getDate() + 1); + this.insert(t, true, { + priority: 0, + past: false, // System alarms seem uninteresting if past? + future: true, + precision: x.timer ? 1000 : 60000, + colour: x.timer ? options.timerFg : options.alarmFg, + event: x + }); + } + }); + return this; }, }; @@ -403,82 +402,82 @@ const events = { class Sidebar { constructor(g, x, y, w, h, options) { - this.g = g; - this.options = options; - this.x = x; - this.y = this.initY = y; - this.h = h; - this.rate = Infinity; - this.doLocked = Sidebar.status(_ => Bangle.isLocked(), lockI); - this.doHRM = Sidebar.status(_ => Bangle.isHRMOn(), HRMI); - this.doGPS = Sidebar.status(_ => Bangle.isGPSOn(), GPSI, Sidebar.gpsColour(options)); + this.g = g; + this.options = options; + this.x = x; + this.y = this.initY = y; + this.h = h; + this.rate = Infinity; + this.doLocked = Sidebar.status(_ => Bangle.isLocked(), lockI); + this.doHRM = Sidebar.status(_ => Bangle.isHRMOn(), HRMI); + this.doGPS = Sidebar.status(_ => Bangle.isGPSOn(), GPSI, Sidebar.gpsColour(options)); } reset(rate) {this.y = this.initY; this.rate = rate; return this;} print(t) { - this.y += 4 + t.print( - this.g.setColor(this.options.barFg).setFontAlign(-1, 1, 1), - this.x + 3, this.y + 4 - ); - return this; + this.y += 4 + t.print( + this.g.setColor(this.options.barFg).setFontAlign(-1, 1, 1), + this.x + 3, this.y + 4 + ); + return this; } pad(n) {this.y += n; return this;} free() {return this.h - this.y;} static status(p, i, c) { - return function() { - if (p()) { - this.g.setColor(c ? c() : this.options.barFg) - .drawImage(i, this.x + 4, this.y += 4); - this.y += imageHeight(i); - } - return this; - }; + return function() { + if (p()) { + this.g.setColor(c ? c() : this.options.barFg) + .drawImage(i, this.x + 4, this.y += 4); + this.y += imageHeight(i); + } + return this; + }; } static gpsColour(o) { - const fix = Bangle.getGPSFix(); - return fix && fix.fix ? o.active : o.barFg; + const fix = Bangle.getGPSFix(); + return fix && fix.fix ? o.active : o.barFg; } doPower() { - const c = Bangle.isCharging(); - const b = E.getBattery(); - if (c || b < 50) { - let g = this.g, x = this.x, y = this.y, options = this.options; - g.setColor(options.barFg).drawImage(batteryI, x + 4, y + 4); - g.setColor(b <= 10 ? '#f00' : b <= 30 ? '#ff0' : '#0f0'); - const h = 13 * (100 - b) / 100; - g.fillRect(x + 8, y + 7 + h, x + 17, y + 20); - // Espruino disallows blank leading rows in icons, for some reason. - if (c) g.setColor(options.barBg).drawImage(chargeI, x + 4, y + 8); - this.y = y + imageHeight(batteryI) + 4; - } - return this; + const c = Bangle.isCharging(); + const b = E.getBattery(); + if (c || b < 50) { + let g = this.g, x = this.x, y = this.y, options = this.options; + g.setColor(options.barFg).drawImage(batteryI, x + 4, y + 4); + g.setColor(b <= 10 ? '#f00' : b <= 30 ? '#ff0' : '#0f0'); + const h = 13 * (100 - b) / 100; + g.fillRect(x + 8, y + 7 + h, x + 17, y + 20); + // Espruino disallows blank leading rows in icons, for some reason. + if (c) g.setColor(options.barBg).drawImage(chargeI, x + 4, y + 8); + this.y = y + imageHeight(batteryI) + 4; + } + return this; } doCompass() { - if (Bangle.isCompassOn()) { - const c = Bangle.getCompass(); - const a = c && this.rate <= 1000; - this.g.setColor(a ? this.options.active : this.options.barFg).drawImage( - compassI, - this.x + 4 + imageWidth(compassI) / 2, - this.y + 4 + imageHeight(compassI) / 2, - a ? {rotate: c.heading / 180 * Math.PI} : undefined - ); - this.y += 4 + imageHeight(compassI); - } - return this; + if (Bangle.isCompassOn()) { + const c = Bangle.getCompass(); + const a = c && this.rate <= 1000; + this.g.setColor(a ? this.options.active : this.options.barFg).drawImage( + compassI, + this.x + 4 + imageWidth(compassI) / 2, + this.y + 4 + imageHeight(compassI) / 2, + a ? {rotate: c.heading / 180 * Math.PI} : undefined + ); + this.y += 4 + imageHeight(compassI); + } + return this; } } class Roman { constructor(g, events) { - this.g = g; - this.state = {}; - const options = this.options = new RomanOptions(); - this.events = events.loadFromSystem(this.options); - this.timescales = [1000, [1000, 60000], 60000, 3600000]; - this.sidebar = new Sidebar(g, barX, barY, barW, barH, options); - this.hours = Roman.hand(g, 3, 0.5, 12, _ => options.hourFg); - this.minutes = Roman.hand(g, 2, 0.9, 60, _ => options.minuteFg); - this.seconds = Roman.hand(g, 1, 0.9, 60, _ => options.secondFg); + this.g = g; + this.state = {}; + const options = this.options = new RomanOptions(); + this.events = events.loadFromSystem(this.options); + this.timescales = [1000, [1000, 60000], 60000, 3600000]; + this.sidebar = new Sidebar(g, barX, barY, barW, barH, options); + this.hours = Roman.hand(g, 3, 0.5, 12, _ => options.hourFg); + this.minutes = Roman.hand(g, 2, 0.9, 60, _ => options.minuteFg); + this.seconds = Roman.hand(g, 1, 0.9, 60, _ => options.secondFg); } reset() {this.state = {}; this.g.clear(true);} @@ -488,150 +487,150 @@ class Roman { // Watch hands. These could be improved, graphically. // If we restricted them to 60 positions, we could feasibly hand-draw them? static hand(g, w, l, d, c) { - return p => { - g.setColor(c()); - p = ((12 * p / d) + 1) % 12; - let h = l * rectW / 2; - let v = l * rectH / 2; - let poly = - p <= 2 ? [faceCX + w, faceCY, faceCX - w, faceCY, - faceCX + h * (p - 1), faceCY - v, - faceCX + h * (p - 1) + 1, faceCY - v] - : p < 6 ? [faceCX + 1, faceCY + w, faceCX + 1, faceCY - w, - faceCX + h, faceCY + v / 2 * (p - 4), - faceCX + h, faceCY + v / 2 * (p - 4) + 1] - : p <= 8 ? [faceCX - w, faceCY + 1, faceCX + w, faceCY + 1, - faceCX - h * (p - 7), faceCY + v, - faceCX - h * (p - 7) - 1, faceCY + v] - : [faceCX, faceCY - w, faceCX, faceCY + w, - faceCX - h, faceCY - v / 2 * (p - 10), - faceCX - h, faceCY - v / 2 * (p - 10) - 1]; - g.fillPoly(poly); - }; + return p => { + g.setColor(c()); + p = ((12 * p / d) + 1) % 12; + let h = l * rectW / 2; + let v = l * rectH / 2; + let poly = + p <= 2 ? [faceCX + w, faceCY, faceCX - w, faceCY, + faceCX + h * (p - 1), faceCY - v, + faceCX + h * (p - 1) + 1, faceCY - v] + : p < 6 ? [faceCX + 1, faceCY + w, faceCX + 1, faceCY - w, + faceCX + h, faceCY + v / 2 * (p - 4), + faceCX + h, faceCY + v / 2 * (p - 4) + 1] + : p <= 8 ? [faceCX - w, faceCY + 1, faceCX + w, faceCY + 1, + faceCX - h * (p - 7), faceCY + v, + faceCX - h * (p - 7) - 1, faceCY + v] + : [faceCX, faceCY - w, faceCX, faceCY + w, + faceCX - h, faceCY - v / 2 * (p - 10), + faceCX - h, faceCY - v / 2 * (p - 10) - 1]; + g.fillPoly(poly); + }; } static pos(p, r) { - let h = r * rectW / 2; - let v = r * rectH / 2; - p = (p + 1) % 12; - return p <= 2 ? [faceCX + h * (p - 1), faceCY - v] - : p < 6 ? [faceCX + h, faceCY + v / 2 * (p - 4)] - : p <= 8 ? [faceCX - h * (p - 7), faceCY + v] - : [faceCX - h, faceCY - v / 2 * (p - 10)]; + let h = r * rectW / 2; + let v = r * rectH / 2; + p = (p + 1) % 12; + return p <= 2 ? [faceCX + h * (p - 1), faceCY - v] + : p < 6 ? [faceCX + h, faceCY + v / 2 * (p - 4)] + : p <= 8 ? [faceCX - h * (p - 7), faceCY + v] + : [faceCX - h, faceCY - v / 2 * (p - 10)]; } alert(e, date, now, past) { - const g = this.g; - g.setColor(e.colour); - const dt = date - now; - if (e.precision < 60000 && dt >= 0 && e.future && dt <= 59000) { // Seconds away - const p = Roman.pos(date.getSeconds() / 5, 0.95); - g.drawLine(faceCX, faceCY, p[0], p[1]); - return 1000; - } else if (e.precision < 3600000 && dt >= 0 && e.future && dt <= 3540000) { // Minutes away - const p = Roman.pos(date.getMinutes() / 5 + date.getSeconds() / 300, 0.8); - g.drawLine(p[0] - 5, p[1], p[0] + 5, p[1]); - g.drawLine(p[0], p[1] - 5, p[0], p[1] + 5); - return dt < 119000 ? 1000 : 60000; // Turn on second hand two minutes up. - } else if (e.precision < 43200000 && dt >= 0 ? e.future : e.past) { // Hours away - const p = Roman.pos(date.getHours() + date.getMinutes() / 60, 0.6); - const poly = [p[0] - 4, p[1], p[0], p[1] - 4, p[0] + 4, p[1], p[0], p[1] + 4]; - if (date >= now) g.fillPoly(poly); - else g.drawPoly(poly, true); - return 3600000; - } - return Infinity; + const g = this.g; + g.setColor(e.colour); + const dt = date - now; + if (e.precision < 60000 && dt >= 0 && e.future && dt <= 59000) { // Seconds away + const p = Roman.pos(date.getSeconds() / 5, 0.95); + g.drawLine(faceCX, faceCY, p[0], p[1]); + return 1000; + } else if (e.precision < 3600000 && dt >= 0 && e.future && dt <= 3540000) { // Minutes away + const p = Roman.pos(date.getMinutes() / 5 + date.getSeconds() / 300, 0.8); + g.drawLine(p[0] - 5, p[1], p[0] + 5, p[1]); + g.drawLine(p[0], p[1] - 5, p[0], p[1] + 5); + return dt < 119000 ? 1000 : 60000; // Turn on second hand two minutes up. + } else if (e.precision < 43200000 && dt >= 0 ? e.future : e.past) { // Hours away + const p = Roman.pos(date.getHours() + date.getMinutes() / 60, 0.6); + const poly = [p[0] - 4, p[1], p[0], p[1] - 4, p[0] + 4, p[1], p[0], p[1] + 4]; + if (date >= now) g.fillPoly(poly); + else g.drawPoly(poly, true); + return 3600000; + } + return Infinity; } render(d, rate) { - const g = this.g; - const state = this.state; - const options = this.options; - const events = this.events; - events.clean(d, -39600000); // 11h + const g = this.g; + const state = this.state; + const options = this.options; + const events = this.events; + events.clean(d, -39600000); // 11h - // Sidebar: icons and date - if (d.getDate() !== state.date || !state.iconsOk) { - const sidebar = this.sidebar; - state.date = d.getDate(); - state.iconsOk = true; - g.setColor(options.barBg).fillRect(barX, barY, barX + barW, barY + barH); + // Sidebar: icons and date + if (d.getDate() !== state.date || !state.iconsOk) { + const sidebar = this.sidebar; + state.date = d.getDate(); + state.iconsOk = true; + g.setColor(options.barBg).fillRect(barX, barY, barX + barW, barY + barH); - sidebar.reset(rate).doLocked().doPower().doGPS().doHRM().doCompass(); - g.setFontCustom.apply(g, fontF); - let formatters = []; - let month, dom, dow; - if (options.calendric > 1) { - formatters.push(month = formatMonth.on(d.getMonth())); - } - if (options.calendric > 0) { - formatters.push(dom = formatDom.on(d.getDate())); - } - if (options.dow) { - formatters.push(dow = formatDow.on(d.getDay())); - } - // Obnoxiously inefficient iterative method :( - let ava = sidebar.free() - 3, use, i = 0, j = 0; - while ((use = formatters.reduce((l, f) => l + f.width(g) + 4, 0)) > ava && - j < formatters.length) - for (j = 0; - !formatters[i++ % formatters.length].squeeze() && - j < formatters.length; - j++) ; - if (dow) sidebar.print(dow); - sidebar.pad(ava - use); - if (month) sidebar.print(month); - if (dom) sidebar.print(dom); - } + sidebar.reset(rate).doLocked().doPower().doGPS().doHRM().doCompass(); + g.setFontCustom.apply(g, fontF); + let formatters = []; + let month, dom, dow; + if (options.calendric > 1) { + formatters.push(month = formatMonth.on(d.getMonth())); + } + if (options.calendric > 0) { + formatters.push(dom = formatDom.on(d.getDate())); + } + if (options.dow) { + formatters.push(dow = formatDow.on(d.getDay())); + } + // Obnoxiously inefficient iterative method :( + let ava = sidebar.free() - 3, use, i = 0, j = 0; + while ((use = formatters.reduce((l, f) => l + f.width(g) + 4, 0)) > ava && + j < formatters.length) + for (j = 0; + !formatters[i++ % formatters.length].squeeze() && + j < formatters.length; + j++) ; + if (dow) sidebar.print(dow); + sidebar.pad(ava - use); + if (month) sidebar.print(month); + if (dom) sidebar.print(dom); + } - // Hour labels and (purely aesthetic) box; clear inner face. - let keyHour = d.getHours() < 12 ? 1 : 13; - let alertSpan = events.span(d, hceil(d) - 39600000, hfloor(d) + 39600000, 39600000); - let l = alertSpan[0].getHours(), h = alertSpan[1].getHours(); - if ((l - keyHour + 24) % 24 >= 12 || (h - keyHour + 24) % 24 >= 12) keyHour = l; - if (keyHour !== state.keyHour) { - state.keyHour = keyHour; - g.setColor(options.bg) - .fillRect(faceX, faceY, faceX + faceW, faceY + faceH) - .setFontCustom.apply(g, romanPartsF) - .setFontAlign(0, 1) - .setColor(options.fg); - // In order to deal with timezone changes more logic will be required, - // since the labels may be in unusual locations (even offset when - // a non-integral zone is involved). The value of keyHour can be - // anything in [hr-12, hr] mod 24. - for (let h = keyHour; h < keyHour + 12; h++) { - g.drawString( - numeral(h % 24, options), - faceX + layout[h % 12 * 2], - faceY + layout[h % 12 * 2 + 1] - ); - } - g.setColor(options.rectFg) - .drawRect(rectX, rectY, rectX + rectW - 1, rectY + rectH - 1); - } else { - g.setColor(options.bg) - .fillRect(rectX + 1, rectY + 1, rectX + rectW - 2, rectY + rectH - 2) - .setColor(options.fg); - } + // Hour labels and (purely aesthetic) box; clear inner face. + let keyHour = d.getHours() < 12 ? 1 : 13; + let alertSpan = events.span(d, hceil(d) - 39600000, hfloor(d) + 39600000, 39600000); + let l = alertSpan[0].getHours(), h = alertSpan[1].getHours(); + if ((l - keyHour + 24) % 24 >= 12 || (h - keyHour + 24) % 24 >= 12) keyHour = l; + if (keyHour !== state.keyHour) { + state.keyHour = keyHour; + g.setColor(options.bg) + .fillRect(faceX, faceY, faceX + faceW, faceY + faceH) + .setFontCustom.apply(g, romanPartsF) + .setFontAlign(0, 1) + .setColor(options.fg); + // In order to deal with timezone changes more logic will be required, + // since the labels may be in unusual locations (even offset when + // a non-integral zone is involved). The value of keyHour can be + // anything in [hr-12, hr] mod 24. + for (let h = keyHour; h < keyHour + 12; h++) { + g.drawString( + numeral(h % 24, options), + faceX + layout[h % 12 * 2], + faceY + layout[h % 12 * 2 + 1] + ); + } + g.setColor(options.rectFg) + .drawRect(rectX, rectY, rectX + rectW - 1, rectY + rectH - 1); + } else { + g.setColor(options.bg) + .fillRect(rectX + 1, rectY + 1, rectX + rectW - 2, rectY + rectH - 2) + .setColor(options.fg); + } - // Alerts - let requestedRate = events.scan( - d, hfloor(alertSpan[0] + 0), hceil(alertSpan[1] + 0) + 1, - (e, t, p) => this.alert(e, t, d, p) - ); - if (rate > requestedRate) rate = requestedRate; - - // Hands - // Here we are using incremental hands for hours and minutes. - // If we quantised, we could use hand-crafted bitmaps, though. - this.hours(d.getHours() + d.getMinutes() / 60); - if (rate < 3600000) { - this.minutes(d.getMinutes() + d.getSeconds() / 60); - } - if (rate < 60000) this.seconds(d.getSeconds()); - g.setColor(options.hubFg).fillCircle(faceCX, faceCY, 3); - return requestedRate; + // Alerts + let requestedRate = events.scan( + d, hfloor(alertSpan[0] + 0), hceil(alertSpan[1] + 0) + 1, + (e, t, p) => this.alert(e, t, d, p) + ); + if (rate > requestedRate) rate = requestedRate; + + // Hands + // Here we are using incremental hands for hours and minutes. + // If we quantised, we could use hand-crafted bitmaps, though. + this.hours(d.getHours() + d.getMinutes() / 60); + if (rate < 3600000) { + this.minutes(d.getMinutes() + d.getSeconds() / 60); + } + if (rate < 60000) this.seconds(d.getSeconds()); + g.setColor(options.hubFg).fillCircle(faceCX, faceCY, 3); + return requestedRate; } } @@ -640,119 +639,119 @@ class Roman { class Clock { constructor(face) { - this.face = face; - this.timescales = face.timescales; - this.options = face.options; - this.rates = {}; + this.face = face; + this.timescales = face.timescales; + this.options = face.options; + this.rates = {}; - this.options.on('done', () => this.start()); - - this.listeners = { - lcdPower: on => on ? this.active() : this.inactive(), - charging: () => {face.doIcons('charging'); this.active();}, - lock: () => {face.doIcons('locked'); this.active();}, - faceUp: up => {this.conservative = !up; this.active();}, - drag: e => { - if (this.t0) { - if (e.b) { - e.x > this.xN && (this.xN = e.x) || e.x > this.xX && (this.xX = e.x); - e.y > this.yN && (this.yN = e.y) || e.y > this.yX && (this.xY = e.y); - } else if (this.xX - this.xN < 20) { - if (e.y - this.e0.y < -50) { - this.options.resolution > 0 && this.options.resolution--; - this.rates.clock = this.timescales[this.options.resolution]; - this.active(); - } else if (e.y - this.e0.y > 50) { - this.options.resolution < this.timescales.length - 1 && - this.options.resolution++; - this.rates.clock = this.timescales[this.options.resolution]; - this.active(); - } else if (this.yX - this.yN < 20 && Date.now() - this.t0 > 500) { - this.stop(); - this.options.interact(); - } - this.t0 = null; - } - } else if (e.b) { - this.t0 = Date.now(); this.e0 = e; - this.xN = this.xX = e.x; this.yN = this.yX = e.y; - } - } - }; + this.options.on('done', () => this.start()); + + this.listeners = { + lcdPower: on => on ? this.active() : this.inactive(), + charging: () => {face.doIcons('charging'); this.active();}, + lock: () => {face.doIcons('locked'); this.active();}, + faceUp: up => {this.conservative = !up; this.active();}, + drag: e => { + if (this.t0) { + if (e.b) { + e.x > this.xN && (this.xN = e.x) || e.x > this.xX && (this.xX = e.x); + e.y > this.yN && (this.yN = e.y) || e.y > this.yX && (this.xY = e.y); + } else if (this.xX - this.xN < 20) { + if (e.y - this.e0.y < -50) { + this.options.resolution > 0 && this.options.resolution--; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + } else if (e.y - this.e0.y > 50) { + this.options.resolution < this.timescales.length - 1 && + this.options.resolution++; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + } else if (this.yX - this.yN < 20 && Date.now() - this.t0 > 500) { + this.stop(); + this.options.interact(); + } + this.t0 = null; + } + } else if (e.b) { + this.t0 = Date.now(); this.e0 = e; + this.xN = this.xX = e.x; this.yN = this.yX = e.y; + } + } + }; } redraw(rate) { - const now = this.updated = new Date(); - if (this.refresh) this.face.reset(); - this.refresh = false; - rate = this.face.render(now, rate); - if (rate !== this.rates.face) { - this.rates.face = rate; - this.active(); - } - return this; + const now = this.updated = new Date(); + if (this.refresh) this.face.reset(); + this.refresh = false; + rate = this.face.render(now, rate); + if (rate !== this.rates.face) { + this.rates.face = rate; + this.active(); + } + return this; } inactive() { - this.timeout && clearTimeout(this.timeout); - this.exception && clearTimeout(this.exception); - this.interval && clearInterval(this.interval); - this.timeout = this.exception = this.interval = this.rate = null; - return this; + this.timeout && clearTimeout(this.timeout); + this.exception && clearTimeout(this.exception); + this.interval && clearInterval(this.interval); + this.timeout = this.exception = this.interval = this.rate = null; + return this; } active() { - const prev = this.rate; - const now = Date.now(); - let rate = Infinity; - for (const k in this.rates) { - let r = this.rates[k]; - r === +r || (r = r[+this.conservative]) - r < rate && (rate = r); - } - const delay = rate - now % rate + 1; - this.refresh = true; - - if (rate !== prev) { - this.inactive(); - this.redraw(rate); - if (rate < 31622400000) { // A year! - this.timeout = setTimeout( - () => { - this.inactive(); - this.interval = setInterval(() => this.redraw(rate), rate); - if (delay > 1000) this.redraw(rate); - this.rate = rate; - }, delay - ); - } - } else if (rate > 1000) { - if (!this.exception) this.exception = setTimeout(() => { - this.redraw(rate); - this.exception = null; - }, this.updated + 1000 - Date.now()); - } - return this; + const prev = this.rate; + const now = Date.now(); + let rate = Infinity; + for (const k in this.rates) { + let r = this.rates[k]; + r === +r || (r = r[+this.conservative]) + r < rate && (rate = r); + } + const delay = rate - now % rate + 1; + this.refresh = true; + + if (rate !== prev) { + this.inactive(); + this.redraw(rate); + if (rate < 31622400000) { // A year! + this.timeout = setTimeout( + () => { + this.inactive(); + this.interval = setInterval(() => this.redraw(rate), rate); + if (delay > 1000) this.redraw(rate); + this.rate = rate; + }, delay + ); + } + } else if (rate > 1000) { + if (!this.exception) this.exception = setTimeout(() => { + this.redraw(rate); + this.exception = null; + }, this.updated + 1000 - Date.now()); + } + return this; } stop() { - this.inactive(); - for (const l in this.listeners) { - Bangle.removeListener(l, this.listeners[l]); - } - return this; + this.inactive(); + for (const l in this.listeners) { + Bangle.removeListener(l, this.listeners[l]); + } + return this; } start() { - this.inactive(); // Reset to known state. - this.conservative = false; - this.rates.clock = this.timescales[this.options.resolution]; - this.active(); - for (const l in this.listeners) { - Bangle.on(l, this.listeners[l]); - } - Bangle.setUI('clock'); - return this; + this.inactive(); // Reset to known state. + this.conservative = false; + this.rates.clock = this.timescales[this.options.resolution]; + this.active(); + for (const l in this.listeners) { + Bangle.on(l, this.listeners[l]); + } + Bangle.setUI('clock'); + return this; } } diff --git a/apps/pooqroman/resourcer.js b/apps/pooqroman/resourcer.js index c172812c7..69365018e 100644 --- a/apps/pooqroman/resourcer.js +++ b/apps/pooqroman/resourcer.js @@ -63,27 +63,27 @@ const prepFont = (name, data) => { if (m = /^(<*)(=)([*\d]*)(=*)(>*)$/.exec(line) || /^(<*)(-)(.)(-*)(>*)$/.exec(line)) { const h = m[2] == '='; if (m[1].length > desc || h && m[1].length != desc) - throw new Error('Invalid descender height at ' + l); - if (m[2].length + m[3].length + m[4].length != body) - throw new Error('Invalid body height at ' + l); - if (m[5].length > asc || h && m[5].length != asc) - throw new Error('Invalid ascender height at ' + l); - if (c != null) { - lengths[c] = l - o; - if (width !== null && width !== lengths[c]) - throw new Error( - `Character has width ${lengths[c]} != ${width} at ${offsets[c]}` - ); - c = null - } - if (!h) { - c = m[3].charCodeAt(0); - if (c < min) min = c; - if (c > max) max = c; - o = l + 1; - offsets[c] = l; - adjustments[c] = m[1].length - } + throw new Error('Invalid descender height at ' + l); + if (m[2].length + m[3].length + m[4].length != body) + throw new Error('Invalid body height at ' + l); + if (m[5].length > asc || h && m[5].length != asc) + throw new Error('Invalid ascender height at ' + l); + if (c != null) { + lengths[c] = l - o; + if (width !== null && width !== lengths[c]) + throw new Error( + `Character has width ${lengths[c]} != ${width} at ${offsets[c]}` + ); + c = null + } + if (!h) { + c = m[3].charCodeAt(0); + if (c < min) min = c; + if (c > max) max = c; + o = l + 1; + offsets[c] = l; + adjustments[c] = m[1].length + } } }); const xoffs = Uint8Array(lines.length); @@ -92,16 +92,16 @@ const prepFont = (name, data) => { const w0 = lengths[min]; let widths = ''; for (c = min, o = 0; c <= max; c++) { - for (i = 0, j = offsets[c]; i < lengths[c]; i++) { - xoffs[j] = asc + body + adjustments[c] - 1; - ypos[j++] = o++; - } - widths += String.fromCharCode(lengths[c]); + for (i = 0, j = offsets[c]; i < lengths[c]; i++) { + xoffs[j] = asc + body + adjustments[c] - 1; + ypos[j++] = o++; + } + widths += String.fromCharCode(lengths[c]); } const raster = Graphics.createArrayBuffer(h, o, 1, {msb: true}); const writer = Graphics.createCallback( - image.width, image.height, 1, - (x, y, col) => raster.setPixel(xoffs[y] - x, ypos[y], col) + image.width, image.height, 1, + (x, y, col) => raster.setPixel(xoffs[y] - x, ypos[y], col) ); writer.drawImage(image); if (width === null) width = `dec(${enc(widths)})`; From feb2b5713b90daf84fe999550c5e0fea63639e1a Mon Sep 17 00:00:00 2001 From: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Fri, 3 Dec 2021 00:36:58 -0800 Subject: [PATCH 0166/1839] Update apps.json Bump version for event time zone fix. --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 26c4303c8..606a3ed31 100644 --- a/apps.json +++ b/apps.json @@ -4645,7 +4645,7 @@ { "id": "pooqroman", "name": "pooq Roman watch face", "shortName":"pooq Roman", - "version":"0.0.0", + "version":"0.0.1", "description": "A classic watch face with a certain dynamicity. Most amusing in 24h mode. Slide up to show more hands, down for less(!). By design does not support standard widgets, sorry!", "icon": "app.png", "type": "clock", From 6baddd3b433d318d196c0f2d1c73df2572f2600e Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 3 Dec 2021 09:15:37 +0000 Subject: [PATCH 0167/1839] Add gbdebug app --- apps.json | 14 ++++++++++++++ apps/gbdebug/ChangeLog | 1 + apps/gbdebug/README.md | 26 ++++++++++++++++++++++++++ apps/gbdebug/app-icon.js | 1 + apps/gbdebug/app.js | 21 +++++++++++++++++++++ apps/gbdebug/app.png | Bin 0 -> 2914 bytes 6 files changed, 63 insertions(+) create mode 100644 apps/gbdebug/ChangeLog create mode 100644 apps/gbdebug/README.md create mode 100644 apps/gbdebug/app-icon.js create mode 100644 apps/gbdebug/app.js create mode 100644 apps/gbdebug/app.png diff --git a/apps.json b/apps.json index e6f013123..0a1fd3039 100644 --- a/apps.json +++ b/apps.json @@ -269,6 +269,20 @@ ], "data": [{"name":"gbridge.json"}] }, + { "id": "gbdebug", + "name": "Gadgetbridge Debug", + "shortName":"GB Debug", + "version":"0.01", + "description": "Debug info for Gadgetbridge. Run this app and when Gadgetbridge messages arrive they are displayed on-screen.", + "icon": "app.png", + "tags": "", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"gbdebug.app.js","url":"app.js"}, + {"name":"gbdebug.img","url":"app-icon.js","evaluate":true} + ] + }, { "id": "mclock", "name": "Morphing Clock", diff --git a/apps/gbdebug/ChangeLog b/apps/gbdebug/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/gbdebug/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/gbdebug/README.md b/apps/gbdebug/README.md new file mode 100644 index 000000000..47b1525b8 --- /dev/null +++ b/apps/gbdebug/README.md @@ -0,0 +1,26 @@ +# Gadgetbridge Debug + +This is useful if your Bangle isn't responding to the Gadgetbridge +Android app properly. + +This app disables all existing Gadgetbridge handlers and then displays the +messages that come from Gadgetbridge on the screen +of the watch. It also saves the last 10 messages in a variable +called `history`. + +More info on Gadgetbridge at http://www.espruino.com/Gadgetbridge + +## Usage + +* Run the `GB Debug` app on your Bangle +* Connect your Bangle to Gadgetbridge +* Do whatever was causing you problems (eg receiving a call) +* The Gadgetbridge message should now be displayed on-screen + +If you want to get the *actual* data rather than copying it from the screen. + +* Ensure the `GB Debug` app is kept running after the above steps +* Disconnect Gadgetbridge from the Bangle +* Connect the Web IDE on your PC +* Type `show()` on the left-hand side of the IDE and the +last 10 messages from Gadgetbridge will be shown. diff --git a/apps/gbdebug/app-icon.js b/apps/gbdebug/app-icon.js new file mode 100644 index 000000000..a701ef3a9 --- /dev/null +++ b/apps/gbdebug/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4cBzsE/4AClMywH680rlOW9N9kmSpICnyBBBgQRMkBUDgIRKoBoGGRYAFHBGARpARHT5MJKxQAFLgzELCIlIBQkSCIsEPRKBHCIYbGoIRFiQRJhJgFCISeEBwMQOQykCCIqlBpMEBIgRHOQYRIYQbPDhAbBNwgRJVwOCTIgRFMAJKDgQRGOQprBCIMSGogHBJwwbBkC2FCJNbUgMNwHYBYPJCIhODju0yFNCIUGCJGCoE2NwO24EAmw1FHgWCpMGgQOBBIMwCJGSpMmyAjDCI6eBCIWAhu2I4IRCUIYREk+Ah3brEB2CzFAAIRCl3b23btsNCJckjoRC1h2CyAREtoNC9oDC2isCCIgHBjdt5MtCJj2CowjD2uyCIOSCI83lu123tAQIRI4EB28/++39/0mwRCoARCgbfByU51/3rev+mWCIQwCPok0EYIRB/gRDpJ+EcYQRJkARQdgq/Bl5HE7IRDZAltwAREyXbCIbIFgEfCIXsBwQCDQAYRNLgvfCIXtCI44Dm3JCIUlYoYCGkrjBk9bxMkyy9CChICFA=")) diff --git a/apps/gbdebug/app.js b/apps/gbdebug/app.js new file mode 100644 index 000000000..ee5e46999 --- /dev/null +++ b/apps/gbdebug/app.js @@ -0,0 +1,21 @@ +E.showMessage("Waiting for message"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +var history = []; + +GB = function(e) { + if (history.length > 10) + history = history.slice(history.length-10); + history.push(e); + + var s = JSON.stringify(e,null,2); + + g.reset().clear(Bangle.appRect); + g.setFont("6x8").setFontAlign(-1,0); + g.drawString(s, 10, g.getHeight()/2); +}; + +function show() { + print(JSON.stringify(history,null,2)); +} diff --git a/apps/gbdebug/app.png b/apps/gbdebug/app.png new file mode 100644 index 0000000000000000000000000000000000000000..f70bce7ad2910e6f0746dca829f7a5311f0d0c8d GIT binary patch literal 2914 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 Date: Fri, 3 Dec 2021 09:20:13 +0000 Subject: [PATCH 0168/1839] Stop crypto polyfill being pulled in - fix http://forum.espruino.com/conversations/369197/#comment16294286 --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index cd3b4def8..23854083e 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit cd3b4def869cac4d7f18e7329e640e51b26758c8 +Subproject commit 23854083e0c3f83c649073a2d85e8079efc471d3 From a385c0992280070dbcbd91b8663600ea42d2749c Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 3 Dec 2021 12:04:40 +0000 Subject: [PATCH 0169/1839] openstmap .10: Improve scale factor calculation to fix scaling issues (#984) --- apps.json | 2 +- apps/openstmap/ChangeLog | 1 + apps/openstmap/custom.html | 47 +++++++++++++++++++++++++++++-------- apps/openstmap/openstmap.js | 12 +++++----- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/apps.json b/apps.json index 0a1fd3039..a312b90a3 100644 --- a/apps.json +++ b/apps.json @@ -1928,7 +1928,7 @@ "id": "openstmap", "name": "OpenStreetMap", "shortName": "OpenStMap", - "version": "0.09", + "version": "0.10", "description": "[BETA] Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are", "icon": "app.png", "tags": "outdoors,gps", diff --git a/apps/openstmap/ChangeLog b/apps/openstmap/ChangeLog index 60b9d9ae3..69c34ed4e 100644 --- a/apps/openstmap/ChangeLog +++ b/apps/openstmap/ChangeLog @@ -7,3 +7,4 @@ 0.07: Move to 96px tiles - less files (64 -> 25) and speed up rendering 0.08: Update for drag event refactor 0.09: Use current theme cols when drawing GPS info +0.10: Improve scale factor calculation to fix scaling issues (#984) diff --git a/apps/openstmap/custom.html b/apps/openstmap/custom.html index 88d94ed37..eeb148f54 100644 --- a/apps/openstmap/custom.html +++ b/apps/openstmap/custom.html @@ -63,10 +63,17 @@ TODO: /* Can see possible tiles on http://leaflet-extras.github.io/leaflet-providers/preview/ However some don't allow cross-origin use */ var TILELAYER = 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png'; // simple, high contrast - //var TILELAYER = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; + var PREVIEWTILELAYER = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; //var TILELAYER = 'http://a.tile.stamen.com/toner/{z}/{x}/{y}.png'; // black and white + var map = L.map('map').locate({setView: true, maxZoom: 16}); - var tileLayer = L.tileLayer(TILELAYER, { + // Tiles used for Bangle.js itself + var bangleTileLayer = L.tileLayer(TILELAYER, { + maxZoom: 18, + attribution: 'Map data © OpenStreetMap contributors' + }); + // Tiles used for the may the user sees (faster) + var previewTileLayer = L.tileLayer(PREVIEWTILELAYER, { maxZoom: 18, attribution: 'Map data © OpenStreetMap contributors' }); @@ -83,7 +90,7 @@ TODO: } var mapFiles = []; - tileLayer.addTo(map); + previewTileLayer.addTo(map); function tilesLoaded(ctx, width, height) { var options = { @@ -122,16 +129,35 @@ TODO: } document.getElementById("getmap").addEventListener("click", function() { - var bounds = map.getBounds(); var zoom = map.getZoom(); - var centerlatlon = bounds.getCenter(); - var center = map.project(centerlatlon, zoom).divideBy(256); + var centerlatlon = map.getBounds().getCenter(); + var center = map.project(centerlatlon, zoom).divideBy(OSMTILESIZE); var ox = Math.round((center.x - Math.floor(center.x)) * OSMTILESIZE); var oy = Math.round((center.y - Math.floor(center.y)) * OSMTILESIZE); - center = center.floor(); + center = center.floor(); // make sure we're in the middle of a tile + // JS version of Bangle.js's projection + function bproject(lat, lon) { + const degToRad = Math.PI / 180; // degree to radian conversion + const latMax = 85.0511287798; // clip latitude to sane values + const R = 6378137; // earth radius in m + if (lat > latMax) lat=latMax; + if (lat < -latMax) lat=-latMax; + var s = Math.sin(lat * degToRad); + return new L.Point( + (R * lon * degToRad), + (R * Math.log((1 + s) / (1 - s)) / 2) + ); + } + // Work out scale factors (how much from Bangle.project does one pixel equate to?) + var pc = map.unproject(center.multiplyBy(OSMTILESIZE), zoom); + var pd = map.unproject(center.multiplyBy(OSMTILESIZE).add({x:1,y:0}), zoom); + var bc = bproject(pc.lat, pc.lng) + var bd = bproject(pd.lat, pd.lng) + var scale = bc.distanceTo(bd); + var tileGetters = []; - // Render everything to a canvas - 512 x 512 px + // Render everything to a canvas... var canvas = document.getElementById("maptiles"); canvas.style.display=""; var ctx = canvas.getContext('2d'); @@ -150,7 +176,8 @@ TODO: resolve(); }; })); - img.src = tileLayer.getTileUrl(coords); + bangleTileLayer._tileZoom = previewTileLayer._tileZoom; + img.src = bangleTileLayer.getTileUrl(coords); })(i,j); } } @@ -163,7 +190,7 @@ TODO: imgx : canvas.width, imgy : canvas.height, tilesize : TILESIZE, - scale : 10000*Math.pow(2,16-zoom), // FIXME - this is probably wrong + scale : scale, // how much of Bangle.project(latlon) does one pixel equate to? lat : centerlatlon.lat, lon : centerlatlon.lng })}); diff --git a/apps/openstmap/openstmap.js b/apps/openstmap/openstmap.js index 554a71ca3..d995aca25 100644 --- a/apps/openstmap/openstmap.js +++ b/apps/openstmap/openstmap.js @@ -34,8 +34,8 @@ exports.draw = function() { var cx = g.getWidth()/2; var cy = g.getHeight()/2; var p = Bangle.project({lat:m.lat,lon:m.lon}); - var ix = (p.x-map.center.x)*4096/map.scale + (map.imgx/2) - cx; - var iy = (map.center.y-p.y)*4096/map.scale + (map.imgy/2) - cy; + var ix = (p.x-map.center.x)/map.scale + (map.imgx/2) - cx; + var iy = (map.center.y-p.y)/map.scale + (map.imgy/2) - cy; //console.log(ix,iy); var tx = 0|(ix/map.tilesize); var ty = 0|(iy/map.tilesize); @@ -57,8 +57,8 @@ exports.latLonToXY = function(lat, lon) { var cx = g.getWidth()/2; var cy = g.getHeight()/2; return { - x : (q.x-p.x)*4096/map.scale + cx, - y : cy - (q.y-p.y)*4096/map.scale + x : (q.x-p.x)/map.scale + cx, + y : cy - (q.y-p.y)/map.scale }; }; @@ -66,6 +66,6 @@ exports.latLonToXY = function(lat, lon) { exports.scroll = function(x,y) { var a = Bangle.project({lat:this.lat,lon:this.lon}); var b = Bangle.project({lat:this.lat+1,lon:this.lon+1}); - this.lon += x * this.map.scale / ((a.x-b.x) * 4096); - this.lat -= y * this.map.scale / ((a.y-b.y) * 4096); + this.lon += x * this.map.scale / (a.x-b.x); + this.lat -= y * this.map.scale / (a.y-b.y); }; From 77967c037e3793f38f2634554a4c3b616c47867f Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Fri, 3 Dec 2021 22:39:39 +0800 Subject: [PATCH 0170/1839] Update app.js --- apps/authentiwatch/app.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 2c6d09619..c0cb608c0 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -165,7 +165,7 @@ function drawToken(id, r) { } function draw() { - var timerfn = load; + var timerfn = exitApp; var timerdly = 10000; var d = new Date(); if (state.curtoken != -1) { @@ -305,12 +305,16 @@ function bangle1Btn(e) { } } +function exitApp() { + Bangle.showLauncher(); +} + Bangle.on('touch', onTouch); Bangle.on('drag' , onDrag ); Bangle.on('swipe', onSwipe); if (typeof BTN2 == 'number') { setWatch(function(){bangle1Btn(-1);}, BTN1, {edge:"rising", debounce:50, repeat:true}); - setWatch(function(){load(); }, BTN2, {edge:"rising", debounce:50, repeat:true}); + setWatch(function(){exitApp(); }, BTN2, {edge:"rising", debounce:50, repeat:true}); setWatch(function(){bangle1Btn( 1);}, BTN3, {edge:"rising", debounce:50, repeat:true}); } Bangle.loadWidgets(); From 5c1798b82483898323a1a7573524ddc47e88c13a Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Fri, 3 Dec 2021 22:42:33 +0800 Subject: [PATCH 0171/1839] Update ChangeLog --- apps/authentiwatch/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/ChangeLog b/apps/authentiwatch/ChangeLog index 294d680be..e1b8ed5bc 100644 --- a/apps/authentiwatch/ChangeLog +++ b/apps/authentiwatch/ChangeLog @@ -1,4 +1,4 @@ -0.04: Fix tapping at very bottom of list, inactivity exits to clock +0.04: Fix tapping at very bottom of list, exit on inactivity 0.03: Add "Calculating" placeholder, update JSON save format 0.02: Fix JSON save format 0.01: First release From 1271d28720d84a1321fd9bca8ecd0aa16ea4eb51 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 17:34:03 +0200 Subject: [PATCH 0172/1839] feat: use sfo as tz --- apps/a_clock_timer/app.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/a_clock_timer/app.js b/apps/a_clock_timer/app.js index 5f9a3a468..8d078ffe9 100644 --- a/apps/a_clock_timer/app.js +++ b/apps/a_clock_timer/app.js @@ -102,20 +102,19 @@ function queueNextDraw() { function draw() { g.reset().clearRect(0,24,g.getWidth(),g.getHeight()-IMAGEHEIGHT); g.drawImage(getImg(),0,g.getHeight()-IMAGEHEIGHT); - + var x_sun = 176 - (getGmt().getHours() / 24 * 176 + 4); g.setColor('#ff0').drawLine(x_sun, g.getHeight()-IMAGEHEIGHT, x_sun, g.getHeight()); g.reset(); var locale = require("locale"); - + var date = new Date(); g.setFontAlign(0,0); g.setFont("Michroma36").drawString(locale.time(date,1), g.getWidth()/2, 46); g.setFont("6x8"); g.drawString(locale.date(new Date(),1), 125, 68); - g.drawString("PAR "+locale.time(getTimeFromTimezone(1),1), 125, 80); - g.drawString("TYO "+locale.time(getTimeFromTimezone(9),1), 125, 88); + g.drawString("SFO "+locale.time(getTimeFromTimezone(-8),1), 125, 80); queueNextDraw(); } From 9b59933044083442048d50d302982497beba91a5 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:14:30 +0200 Subject: [PATCH 0173/1839] feat: new app! --- apps/hebrew_calendar/ChangeLog | 1 + apps/hebrew_calendar/LICENSE | 21 ++ apps/hebrew_calendar/README.md | 25 ++ apps/hebrew_calendar/add_to_apps.json | 15 + apps/hebrew_calendar/app-icon.js | 1 + apps/hebrew_calendar/app.js | 390 ++++++++++++++++++++++++++ apps/hebrew_calendar/app.png | Bin 0 -> 1620 bytes 7 files changed, 453 insertions(+) create mode 100644 apps/hebrew_calendar/ChangeLog create mode 100644 apps/hebrew_calendar/LICENSE create mode 100644 apps/hebrew_calendar/README.md create mode 100644 apps/hebrew_calendar/add_to_apps.json create mode 100644 apps/hebrew_calendar/app-icon.js create mode 100644 apps/hebrew_calendar/app.js create mode 100644 apps/hebrew_calendar/app.png diff --git a/apps/hebrew_calendar/ChangeLog b/apps/hebrew_calendar/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/hebrew_calendar/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/hebrew_calendar/LICENSE b/apps/hebrew_calendar/LICENSE new file mode 100644 index 000000000..cd6624ad4 --- /dev/null +++ b/apps/hebrew_calendar/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016-20 Ionică Bizău (https://ionicabizau.net) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/apps/hebrew_calendar/README.md b/apps/hebrew_calendar/README.md new file mode 100644 index 000000000..8fa6a6535 --- /dev/null +++ b/apps/hebrew_calendar/README.md @@ -0,0 +1,25 @@ +# Hebrew Calendar + +Displays the current hebrew calendar date +Add screen shots (if possible) to the app folder and link then into this file with ![](.png) + +## Usage + +Open the app, and it shows a menu with the date components + +## 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 + +Michael Salaverry +with help from https://github.com/IonicaBizau/hebrew-date (MIT license) diff --git a/apps/hebrew_calendar/add_to_apps.json b/apps/hebrew_calendar/add_to_apps.json new file mode 100644 index 000000000..5eae04cd4 --- /dev/null +++ b/apps/hebrew_calendar/add_to_apps.json @@ -0,0 +1,15 @@ +// Create an entry in apps.json as follows: +{ "id": "7chname", + "name": "Hebrew Calendar", + "shortName":"HebCal", + "version":"0.01", + "description": "lists the date according to the hebrew calendar", + "icon": "app.png", + "tags": "", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"7chname.app.js","url":"app.js"}, + {"name":"7chname.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/hebrew_calendar/app-icon.js b/apps/hebrew_calendar/app-icon.js new file mode 100644 index 000000000..49232b838 --- /dev/null +++ b/apps/hebrew_calendar/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA==")) diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js new file mode 100644 index 000000000..eac641c5d --- /dev/null +++ b/apps/hebrew_calendar/app.js @@ -0,0 +1,390 @@ +g.clear(); + +/*! + * This script was taked from this page and ported to Node.js by Ionic Bizu + * http://www.shamash.org/help/javadate.shtml + * + * This script was adapted from C sources written by + * Scott E. Lee, which contain the following copyright notice: + * + * Copyright 1993-1995, Scott E. Lee, all rights reserved. + * Permission granted to use, copy, modify, distribute and sell so long as + * the above copyright and this permission statement are retained in all + * copies. THERE IS NO WARRANTY - USE AT YOUR OWN RISK. + * + * Bill Hastings + * RBI Software Systems + * bhastings@rbi.com + */ + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var GREG_SDN_OFFSET = 32045, + DAYS_PER_5_MONTHS = 153, + DAYS_PER_4_YEARS = 1461, + DAYS_PER_400_YEARS = 146097; + +var HALAKIM_PER_HOUR = 1080, + HALAKIM_PER_DAY = 25920, + HALAKIM_PER_LUNAR_CYCLE = 29 * HALAKIM_PER_DAY + 13753, + HALAKIM_PER_METONIC_CYCLE = HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7); + +var HEB_SDN_OFFSET = 347997, + NEW_MOON_OF_CREATION = 31524, + NOON = 18 * HALAKIM_PER_HOUR, + AM3_11_20 = 9 * HALAKIM_PER_HOUR + 204, + AM9_32_43 = 15 * HALAKIM_PER_HOUR + 589; + +var SUN = 0, + MON = 1, + TUES = 2, + WED = 3, + THUR = 4, + FRI = 5, + SAT = 6; + +function weekdayarr(d0, d1, d2, d3, d4, d5, d6) { + this[0] = d0; + this[1] = d1; + this[2] = d2; + this[3] = d3; + this[4] = d4; + this[5] = d5; + this[6] = d6; +} + +function gregmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) { + this[0] = m0; + this[1] = m1; + this[2] = m2; + this[3] = m3; + this[4] = m4; + this[5] = m5; + this[6] = m6; + this[7] = m7; + this[8] = m8; + this[9] = m9; + this[10] = m10; + this[11] = m11; +} + +function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13) { + this[0] = m0; + this[1] = m1; + this[2] = m2; + this[3] = m3; + this[4] = m4; + this[5] = m5; + this[6] = m6; + this[7] = m7; + this[8] = m8; + this[9] = m9; + this[10] = m10; + this[11] = m11; + this[12] = m12; + this[13] = m13; +} + +function monthsperyeararr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18) { + this[0] = m0; + this[1] = m1; + this[2] = m2; + this[3] = m3; + this[4] = m4; + this[5] = m5; + this[6] = m6; + this[7] = m7; + this[8] = m8; + this[9] = m9; + this[10] = m10; + this[11] = m11; + this[12] = m12; + this[13] = m13; + this[14] = m14; + this[15] = m15; + this[16] = m16; + this[17] = m17; + this[18] = m18; +} + +var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur"), + gMonth = new gregmontharr("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), + hMonth = new hebrewmontharr("Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", "Elul"), + mpy = new monthsperyeararr(12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13); + +/** + * hebrewDate + * Convert the Gregorian dates into Hebrew calendar dates. + * + * @name hebrewDate + * @function + * @param {Date|Number} inputDate The date object (representing the Gregorian date) or the year. + * @param {Number?} inputMonth The Gregorian month (**one-indexed**, January being `1`!). + * @param {Number?} inputDate The Gregorian date. + * @return {Object} An object containing: + * + * - `year`: The Hebrew year. + * - `month`: The Hebrew month. + * - `month_name`: The Hebrew month name. + * - `date`: The Hebrew date. + */ +const hebrewDate = function (inputDateOrYear, inputMonth, inputDate) { + + var hebrewMonth = 0, + hebrewDate = 0, + hebrewYear = 0, + metonicCycle = 0, + metonicYear = 0, + moladDay = 0, + moladHalakim = 0; + + function GregorianToSdn(inputYear, inputMonth, inputDay) { + + var year = 0, + month = 0, + sdn = void 0; + + // Make year a positive number + if (inputYear < 0) { + year = inputYear + 4801; + } else { + year = inputYear + 4800; + } + + // Adjust the start of the year + if (inputMonth > 2) { + month = inputMonth - 3; + } else { + month = inputMonth + 9; + year--; + } + + sdn = Math.floor(Math.floor(year / 100) * DAYS_PER_400_YEARS / 4); + sdn += Math.floor(year % 100 * DAYS_PER_4_YEARS / 4); + sdn += Math.floor((month * DAYS_PER_5_MONTHS + 2) / 5); + sdn += inputDay - GREG_SDN_OFFSET; + + return sdn; + } + + function SdnToHebrew(sdn) { + var tishri1 = 0, + tishri1After = 0, + yearLength = 0, + inputDay = sdn - HEB_SDN_OFFSET; + + FindTishriMolad(inputDay); + tishri1 = Tishri1(metonicYear, moladDay, moladHalakim); + + if (inputDay >= tishri1) { + // It found Tishri 1 at the start of the year. + hebrewYear = metonicCycle * 19 + metonicYear + 1; + if (inputDay < tishri1 + 59) { + if (inputDay < tishri1 + 30) { + hebrewMonth = 1; + hebrewDate = inputDay - tishri1 + 1; + } else { + hebrewMonth = 2; + hebrewDate = inputDay - tishri1 - 29; + } + return; + } + // We need the length of the year to figure this out,so find Tishri 1 of the next year. + moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear]; + moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); + moladHalakim = moladHalakim % HALAKIM_PER_DAY; + tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim); + } else { + // It found Tishri 1 at the end of the year. + hebrewYear = metonicCycle * 19 + metonicYear; + if (inputDay >= tishri1 - 177) { + // It is one of the last 6 months of the year. + if (inputDay > tishri1 - 30) { + hebrewMonth = 13; + hebrewDate = inputDay - tishri1 + 30; + } else if (inputDay > tishri1 - 60) { + hebrewMonth = 12; + hebrewDate = inputDay - tishri1 + 60; + } else if (inputDay > tishri1 - 89) { + hebrewMonth = 11; + hebrewDate = inputDay - tishri1 + 89; + } else if (inputDay > tishri1 - 119) { + hebrewMonth = 10; + hebrewDate = inputDay - tishri1 + 119; + } else if (inputDay > tishri1 - 148) { + hebrewMonth = 9; + hebrewDate = inputDay - tishri1 + 148; + } else { + hebrewMonth = 8; + hebrewDate = inputDay - tishri1 + 178; + } + return; + } else { + if (mpy[(hebrewYear - 1) % 19] == 13) { + hebrewMonth = 7; + hebrewDate = inputDay - tishri1 + 207; + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 30; + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 30; + } else { + hebrewMonth = 6; + hebrewDate = inputDay - tishri1 + 207; + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 30; + } + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 29; + if (hebrewDate > 0) return; + // We need the length of the year to figure this out,so find Tishri 1 of this year. + tishri1After = tishri1; + FindTishriMolad(moladDay - 365); + tishri1 = Tishri1(metonicYear, moladDay, moladHalakim); + } + } + yearLength = tishri1After - tishri1; + moladDay = inputDay - tishri1 - 29; + if (yearLength == 355 || yearLength == 385) { + // Heshvan has 30 days + if (moladDay <= 30) { + hebrewMonth = 2; + hebrewDate = moladDay; + return; + } + moladDay -= 30; + } else { + // Heshvan has 29 days + if (moladDay <= 29) { + hebrewMonth = 2; + hebrewDate = moladDay; + return; + } + moladDay -= 29; + } + // It has to be Kislev. + hebrewMonth = 3; + hebrewDate = moladDay; + } + + function FindTishriMolad(inputDay) { + // Estimate the metonic cycle number. Note that this may be an under + // estimate because there are 6939.6896 days in a metonic cycle not + // 6940,but it will never be an over estimate. The loop below will + // correct for any error in this estimate. + metonicCycle = Math.floor((inputDay + 310) / 6940); + // Calculate the time of the starting molad for this metonic cycle. + MoladOfMetonicCycle(); + // If the above was an under estimate,increment the cycle number until + // the correct one is found. For modern dates this loop is about 98.6% + // likely to not execute,even once,because the above estimate is + // really quite close. + while (moladDay < inputDay - 6940 + 310) { + metonicCycle++; + moladHalakim += HALAKIM_PER_METONIC_CYCLE; + moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); + moladHalakim = moladHalakim % HALAKIM_PER_DAY; + } + // Find the molad of Tishri closest to this date. + for (metonicYear = 0; metonicYear < 18; metonicYear++) { + if (moladDay > inputDay - 74) break; + moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear]; + moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); + moladHalakim = moladHalakim % HALAKIM_PER_DAY; + } + } + + function MoladOfMetonicCycle() { + var r1 = void 0, + r2 = void 0, + d1 = void 0, + d2 = void 0; + // Start with the time of the first molad after creation. + r1 = NEW_MOON_OF_CREATION; + // Calculate gMetonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32 + // bits of the result will be in r2 and the lower 16 bits will be in r1. + r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF); + r2 = r1 >> 16; + r2 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE >> 16 & 0xFFFF); + // Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1,the + // upper 16 bits of the quotient will be in d2 and the lower 16 bits + // will be in d1. + d2 = Math.floor(r2 / HALAKIM_PER_DAY); + r2 -= d2 * HALAKIM_PER_DAY; + r1 = r2 << 16 | r1 & 0xFFFF; + d1 = Math.floor(r1 / HALAKIM_PER_DAY); + r1 -= d1 * HALAKIM_PER_DAY; + moladDay = d2 << 16 | d1; + moladHalakim = r1; + } + + function Tishri1(metonicYear, moladDay, moladHalakim) { + var tishri1 = moladDay, + dow = tishri1 % 7, + leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7 || metonicYear == 10 || metonicYear == 13 || metonicYear == 16 || metonicYear == 18, + lastWasLeapYear = metonicYear == 3 || metonicYear == 6 || metonicYear == 8 || metonicYear == 11 || metonicYear == 14 || metonicYear == 17 || metonicYear == 0; + + // Apply rules 2,3 and 4 + if (moladHalakim >= NOON || !leapYear && dow == TUES && moladHalakim >= AM3_11_20 || lastWasLeapYear && dow == MON && moladHalakim >= AM9_32_43) { + tishri1++; + dow++; + if (dow == 7) dow = 0; + } + + // Apply rule 1 after the others because it can cause an additional delay of one day. + if (dow == WED || dow == FRI || dow == SUN) { + tishri1++; + } + + return tishri1; + } + + var inputYear = inputDateOrYear; + + if ((typeof inputYear === "undefined" ? "undefined" : _typeof(inputYear)) === "object") { + inputMonth = inputDateOrYear.getMonth() + 1; + inputDate = inputDateOrYear.getDate(); + inputYear = inputDateOrYear.getFullYear(); + } + + SdnToHebrew(GregorianToSdn(inputYear, inputMonth, inputDate)); + + return { + year: hebrewYear, + month: hebrewMonth, + date: hebrewDate, + month_name: hMonth[hebrewMonth - 1] + }; +}; + + +g.setFont("Vector",10); +let now = new Date(); +let today = hebrewDate(now); + +var mainmenu = { + "" : { + "title" : "Hebrew Date" + }, + cal: { + value : now.getDay()+"/"+now.getMonth()+"/"+now.getFullYear(), + onchange : () => {} + }, + date: { + value : today.date, + onchange : () => {} + }, + month: { + value : today.month_name, + onchange : () => {} + }, + year: { + value : today.year, + onchange : () => {} + }, + "Exit" : function() { E.showMenu(); }, +}; +E.showMenu(mainmenu); diff --git a/apps/hebrew_calendar/app.png b/apps/hebrew_calendar/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: Fri, 3 Dec 2021 18:17:18 +0200 Subject: [PATCH 0174/1839] fix: metadata json --- apps/hebrew_calendar/add_to_apps.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/hebrew_calendar/add_to_apps.json b/apps/hebrew_calendar/add_to_apps.json index 5eae04cd4..49170c6ae 100644 --- a/apps/hebrew_calendar/add_to_apps.json +++ b/apps/hebrew_calendar/add_to_apps.json @@ -1,5 +1,4 @@ -// Create an entry in apps.json as follows: -{ "id": "7chname", +{ "id": "hebrewCalendar", "name": "Hebrew Calendar", "shortName":"HebCal", "version":"0.01", @@ -9,7 +8,7 @@ "supports" : ["BANGLEJS2"], "readme": "README.md", "storage": [ - {"name":"7chname.app.js","url":"app.js"}, - {"name":"7chname.img","url":"app-icon.js","evaluate":true} + {"name":"hebrewCalendar.app.js","url":"app.js"}, + {"name":"hebrewCalendar.img","url":"app-icon.js","evaluate":true} ] } From e9f2346504ad1332946444cf9b1e9ceb60b9404c Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:19:52 +0200 Subject: [PATCH 0175/1839] fix: duh --- apps.json | 24 ++++++++++++++++++++++++ apps/hebrew_calendar/add_to_apps.json | 14 -------------- 2 files changed, 24 insertions(+), 14 deletions(-) delete mode 100644 apps/hebrew_calendar/add_to_apps.json diff --git a/apps.json b/apps.json index a312b90a3..5320aaef5 100644 --- a/apps.json +++ b/apps.json @@ -29,6 +29,30 @@ ], "sortorder": -10 }, + { + "id": "hebrewCalendar", + "name": "Hebrew Calendar", + "shortName": "HebCal", + "version": "0.01", + "description": "lists the date according to the hebrew calendar", + "icon": "app.png", + "tags": "", + "supports": [ + "BANGLEJS2" + ], + "readme": "README.md", + "storage": [ + { + "name": "hebrewCalendar.app.js", + "url": "app.js" + }, + { + "name": "hebrewCalendar.img", + "url": "app-icon.js", + "evaluate": true + } + ] + }, { "id": "messages", "name": "Messages", diff --git a/apps/hebrew_calendar/add_to_apps.json b/apps/hebrew_calendar/add_to_apps.json deleted file mode 100644 index 49170c6ae..000000000 --- a/apps/hebrew_calendar/add_to_apps.json +++ /dev/null @@ -1,14 +0,0 @@ -{ "id": "hebrewCalendar", - "name": "Hebrew Calendar", - "shortName":"HebCal", - "version":"0.01", - "description": "lists the date according to the hebrew calendar", - "icon": "app.png", - "tags": "", - "supports" : ["BANGLEJS2"], - "readme": "README.md", - "storage": [ - {"name":"hebrewCalendar.app.js","url":"app.js"}, - {"name":"hebrewCalendar.img","url":"app-icon.js","evaluate":true} - ] -} From 7550dd57eb131883831886f278761b45533a159c Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:25:27 +0200 Subject: [PATCH 0176/1839] fix: path --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 5320aaef5..e3b067a11 100644 --- a/apps.json +++ b/apps.json @@ -43,11 +43,11 @@ "readme": "README.md", "storage": [ { - "name": "hebrewCalendar.app.js", + "name": "hebrew_calendar.app.js", "url": "app.js" }, { - "name": "hebrewCalendar.img", + "name": "hebrew_calendar.img", "url": "app-icon.js", "evaluate": true } From a41598a2e836c0c385aa449494c78d5cc2cf8c87 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:28:21 +0200 Subject: [PATCH 0177/1839] fix: --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index e3b067a11..992cce5d6 100644 --- a/apps.json +++ b/apps.json @@ -30,7 +30,7 @@ "sortorder": -10 }, { - "id": "hebrewCalendar", + "id": "hebrew_calendar", "name": "Hebrew Calendar", "shortName": "HebCal", "version": "0.01", From 9195e108574c79d38da16e39783a88e29baaca8f Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:33:42 +0200 Subject: [PATCH 0178/1839] feat: swifty icon --- apps/hebrew_calendar/README.md | 1 + apps/hebrew_calendar/app-icon.js | 2 +- apps/hebrew_calendar/app.png | Bin 1620 -> 32788 bytes 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/hebrew_calendar/README.md b/apps/hebrew_calendar/README.md index 8fa6a6535..3141f41b3 100644 --- a/apps/hebrew_calendar/README.md +++ b/apps/hebrew_calendar/README.md @@ -23,3 +23,4 @@ Name who should be contacted for support/update requests Michael Salaverry with help from https://github.com/IonicaBizau/hebrew-date (MIT license) +
Icons made by Smashicons from www.flaticon.com
\ No newline at end of file diff --git a/apps/hebrew_calendar/app-icon.js b/apps/hebrew_calendar/app-icon.js index 49232b838..b6b0a53ae 100644 --- a/apps/hebrew_calendar/app-icon.js +++ b/apps/hebrew_calendar/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA==")) +require("heatshrink").decompress(atob("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/4ABIn4C/AXWQX/4C/X/6/DghH/AX4C5wC/DgBH/AX4C5Xwi//AX6//gESI/4C/AW8gX4sCI/4C/AW6+FAAMJJX4C/AWtAX48BJX4C/AWq+HAAMEJX4C/AWeAX5MAgRN/AX4CxXpQADn//AH4A/AFn8Xxy//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X/4A/X/6//AH6//X7n7tu/CaH27YnRE3d/EyO3X/4AG/3btu2CZ/t23bt4mS74mRtom1/4mSX+32JQXbCZwRCtu/E34mvX+xcCAQN/CRn7OIe3E34muX+39JSQRDTH4mO2wmSt6//X5JKNX4hxNE34mhX/6Y/E36/29qY/E3NtX/6/W/yY/EyffX/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X/6//X7hKMX4xxME34mgX+RZGARBiDLIwCIE34mkX+xcOAQISB/YROtu3EyV/E34mOX+39JSFv/4RPAQIm/E0S/29pKR/xxSE0vfTCNtX6QmUX/4CJTCYm/E0C/3LiACB+xxSE0vbTCW+E0u/X/4C/AXy//AX4C/X/4C/AX6//AX4C/X/4C/AX6//AX4C/X/4C/AX6//AX4C/X/4C/AX6//AX4C/X/4C/AX6//AX4C/X/4C/AX6//AX4C/X/4C/AX6//ARX2L6PfTHO+CiXtX/6/wOKX+E3C//ABaY/E34CHTSS//TH6//X+1vOKQmm7/9TCQmmX+xKRt5xSE34miX/6Y/E36/2/5KQv///ZxP24m/E0S//TH4m/X+/2JR4TCOJ+/E34mjX/4CG75xSE0yYC/yYS9omlX+xKPTAZxPE34mkX+3/JRwSD/pxNt4m/E0i/3/ZKM24TEOJt/E34mlX+3/JRm/CQn2OJgm/E0y/39pKLCQv+OJffE3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")) \ No newline at end of file diff --git a/apps/hebrew_calendar/app.png b/apps/hebrew_calendar/app.png index 582cb2e0853a5a2899a3afbd7eb19cde2ee7f6a0..0dae731cddda69ecfca2d3de516546061c63103d 100644 GIT binary patch literal 32788 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

J`x+vYx@wLq< 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 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: Fri, 3 Dec 2021 18:35:57 +0200 Subject: [PATCH 0179/1839] docs: --- apps/hebrew_calendar/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hebrew_calendar/README.md b/apps/hebrew_calendar/README.md index 3141f41b3..3702cab57 100644 --- a/apps/hebrew_calendar/README.md +++ b/apps/hebrew_calendar/README.md @@ -9,7 +9,7 @@ Open the app, and it shows a menu with the date components ## Features -Name the function +Shows the hebrew date, month, and year; alongside the gregorian date ## Controls From 7e833088f896e60402c22549fde1c4f885b94db8 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:38:15 +0200 Subject: [PATCH 0180/1839] fix: displayed day of week, not date fix: wrong month --- apps/hebrew_calendar/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js index eac641c5d..ccf21ddde 100644 --- a/apps/hebrew_calendar/app.js +++ b/apps/hebrew_calendar/app.js @@ -370,7 +370,7 @@ var mainmenu = { "title" : "Hebrew Date" }, cal: { - value : now.getDay()+"/"+now.getMonth()+"/"+now.getFullYear(), + value: now.getDate() + "/" + Number(now.getMonth() + 1) + "/" + now.getFullYear(), onchange : () => {} }, date: { From 0a25e50e50f67ec4b60ffa111e67461f3150fc5f Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:39:06 +0200 Subject: [PATCH 0181/1839] docs: --- apps/hebrew_calendar/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hebrew_calendar/README.md b/apps/hebrew_calendar/README.md index 3702cab57..5b6feff91 100644 --- a/apps/hebrew_calendar/README.md +++ b/apps/hebrew_calendar/README.md @@ -23,4 +23,4 @@ Name who should be contacted for support/update requests Michael Salaverry with help from https://github.com/IonicaBizau/hebrew-date (MIT license) -

Icons made by Smashicons from www.flaticon.com
\ No newline at end of file + \ No newline at end of file From d8c6d55e65da9d620d5eaec9c6ac7f4b3db9285d Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:39:22 +0200 Subject: [PATCH 0182/1839] docs: --- apps/hebrew_calendar/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hebrew_calendar/README.md b/apps/hebrew_calendar/README.md index 5b6feff91..7a96a97db 100644 --- a/apps/hebrew_calendar/README.md +++ b/apps/hebrew_calendar/README.md @@ -17,7 +17,7 @@ Name the buttons and what they are used for ## Requests -Name who should be contacted for support/update requests +Michael Salaverry (github.com/barakplasma) ## Creator From 255a75d847a243fc5bcb0c225262843b051a82b1 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 18:40:10 +0200 Subject: [PATCH 0183/1839] fix: remove no-op exit --- apps/hebrew_calendar/app.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js index ccf21ddde..02b056af0 100644 --- a/apps/hebrew_calendar/app.js +++ b/apps/hebrew_calendar/app.js @@ -384,7 +384,6 @@ var mainmenu = { year: { value : today.year, onchange : () => {} - }, - "Exit" : function() { E.showMenu(); }, + } }; E.showMenu(mainmenu); From 643728af7800681daebae5f12f1e5bfd9a0037d6 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Fri, 3 Dec 2021 19:07:56 +0200 Subject: [PATCH 0184/1839] feat: use locale lib --- apps/hebrew_calendar/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js index 02b056af0..5bed9c590 100644 --- a/apps/hebrew_calendar/app.js +++ b/apps/hebrew_calendar/app.js @@ -370,7 +370,7 @@ var mainmenu = { "title" : "Hebrew Date" }, cal: { - value: now.getDate() + "/" + Number(now.getMonth() + 1) + "/" + now.getFullYear(), + value: require('locale').date(now,1), onchange : () => {} }, date: { From ec9bcf994a01bf5880611a4307b368e7fd9d4117 Mon Sep 17 00:00:00 2001 From: Lubomir Date: Fri, 3 Dec 2021 22:32:04 +0200 Subject: [PATCH 0185/1839] flow: Create app --- apps.json | 15 +++ apps/flow/README.md | 12 +++ apps/flow/app-icon.js | 1 + apps/flow/app.js | 220 ++++++++++++++++++++++++++++++++++++++ apps/flow/app.png | Bin 0 -> 323 bytes apps/flow/screenshot1.png | Bin 0 -> 992 bytes apps/flow/screenshot2.png | Bin 0 -> 2580 bytes apps/flow/screenshot3.png | Bin 0 -> 1828 bytes 8 files changed, 248 insertions(+) create mode 100644 apps/flow/README.md create mode 100644 apps/flow/app-icon.js create mode 100644 apps/flow/app.js create mode 100644 apps/flow/app.png create mode 100644 apps/flow/screenshot1.png create mode 100644 apps/flow/screenshot2.png create mode 100644 apps/flow/screenshot3.png diff --git a/apps.json b/apps.json index a312b90a3..98b8b8730 100644 --- a/apps.json +++ b/apps.json @@ -4675,5 +4675,20 @@ "data": [ {"name":"pooqroman.json"} ] + }, + { + "id": "flow", + "name": "FLOW", + "shortName": "FLOW", + "version": "0.01", + "description": "A game where you have to help a flow avoid white obstacles thing by tapping! This is a demake of an app which I forgot the name of. Press BTN(1) to restart. See if you can get to 2500 score!", + "icon": "app.png", + "tags": "game", + "supports" : ["BANGLEJS", "BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name": "flow.app.js", "url": "app.js" }, + {"name": "flow.img", "url": "app-icon.js","evaluate": true } + ] } ] diff --git a/apps/flow/README.md b/apps/flow/README.md new file mode 100644 index 000000000..caeaf92d9 --- /dev/null +++ b/apps/flow/README.md @@ -0,0 +1,12 @@ +# FLOW + +This is a game where you have to help a flow avoid white obstacles thing by tapping! +This is a demake of an app which I forgot the name of. +Press BTN(1) to restart. +See if you can get to 2500 score! + +## Screenshots + +![](screenshot1.png) +![](screenshot2.png) +![](screenshot3.png) diff --git a/apps/flow/app-icon.js b/apps/flow/app-icon.js new file mode 100644 index 000000000..969a608f4 --- /dev/null +++ b/apps/flow/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4X/AwX48EHgEC1WgCQkVqoDBBfuqBQcBqoLagEqGAguBqALaGAOoAoQuEBbEAKgIMBBQNUBbgMCyoKHBbBVBBYIKGBbEBtNVrQLfOgNaT4gLagp0CPQOABbcBFwNAgEKBgILbitVqAFClWq0ALZFwTDFGAQLZFwYwDBfg")) diff --git a/apps/flow/app.js b/apps/flow/app.js new file mode 100644 index 000000000..5f4da8f35 --- /dev/null +++ b/apps/flow/app.js @@ -0,0 +1,220 @@ +const isB2 = process.env.HWVERSION === 2; + +// Bangle.js 1 runs just too fast in direct mode??? (also no getPixel) +if (!isB2) Bangle.setLCDMode("120x120"); + +const options = Bangle.getOptions(); + +options.lockTimeout = 0; +options.lcdPowerTimeout = 0; + +Bangle.setOptions(options); + +g.reset(); +g.setBgColor(0, 0, 0); +g.setColor(255, 255, 255); +g.clear(); +const h = g.getHeight(); + +function trigToCoord(ret) { + return ((ret + 1) * h) / 2; +} + +function trigToLen(ret) { + return (ret * h) / 2; +} + +let i = 0.2; +let speedCoef = 0.014; + +let flowFile = require("Storage").readJSON("flow.json"); + +let highestI = (flowFile && flowFile.hiscore) || 0.1; + +let colorA = [255, 255, 0]; +let colorB = [0, 255, 255]; + +let x = 0; +let xt = 0; +let safeMode = false; +let lost = false; + +function offsetRect(g, x, y, w) { + g.fillRect(x, y, x + w, y + w); +} + +function getColor(num) { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1], + [1, 1, 0], + [0, 1, 1], + [1, 0, 1], + [0.5, 0.5, 1], + [1, 0.5, 0], + [0, 1, 0.5], + [0.5, 0.5, 0.5], + ][num]; +} + +function calculateColor(num) { + colorA = getColor(Math.floor((num % 1) * 10)); + colorB = getColor(Math.floor((num % 10) - (num % 1))); +} + +calculateColor(highestI); + +Bangle.on("touch", () => (safeMode = !safeMode)); + +function resetGame() { + x = xt = 0; + safeMode = lost = false; + i = 0.2; + speedCoef = 0.014; + obstaclePeriod = 150; + obstacleMode = 1; + g.clear(); + shownScore = false; + intervalId = setInterval(draw); +} + +function checkCollision() { + lost = g.getPixel(trigToCoord(+x), (h * 2) / 3 - 4) !== 0; + if (lost) { + scoringI = i; + speedCoef = Math.min(speedCoef, 0.02); + g.setFont(isB2 ? "6x15" : "4x6", 3); + g.setColor(colorA[0], colorA[1], colorA[2]) + .drawString( + "Game over", + trigToCoord(0) - g.stringWidth("Game over") / 2, + trigToCoord(0) + ) + .setColor(1, 1, 1); + } +} + +function drawPlayer() { + if (!safeMode) xt = Math.cos(i * Math.PI * 4) / 7.5; + else xt = -Math.cos(i * Math.PI * 2) / 20 + 0.35; + x = x * 0.8 + xt * 0.2; + if (highestI > 250) calculateColor(i); + g.setColor(colorA[0], colorA[1], colorA[2]); + offsetRect(g, trigToCoord(+x), (h * 2) / 3, 3); + g.setColor(colorB[0], colorB[1], colorB[2]); + offsetRect(g, trigToCoord(-x), (h * 2) / 3, 3); +} + +let obstaclePeriod = 150; +let obstacleMode = 1; + +function drawObstracle() { + g.setColor(1, 1, 1); + switch (obstacleMode) { + case 0: + offsetRect(g, trigToCoord(-0.15), 0, trigToLen(0.3)); + break; + case 1: + offsetRect(g, trigToCoord(0.2), 0, trigToLen(0.2)); + offsetRect(g, trigToCoord(-0.4), 0, trigToLen(0.2)); + break; + case 2: + break; + } + obstaclePeriod--; + if (obstaclePeriod <= 0) { + // If we are off cooldown mode, pick a random actual mode + if (obstacleMode === 2) { + obstaclePeriod = Math.random() * 50 + 50; + obstacleMode = Math.round(Math.random()); + } else if (Math.random() > 0.5) { + // Give it a chance to repeat with no cooldown + obstaclePeriod = 25 + 2.5 * speedCoef; + obstacleMode = 2; + } + } +} + +let shownScore = false; +let scoringI = 0; + +function draw() { + if (!lost) { + drawPlayer(); + checkCollision(); + speedCoef *= 1.0005; + drawObstracle(); + } else { + speedCoef /= 1.05; + if (speedCoef <= 0.005) { + clearInterval(intervalId); + i -= speedCoef; + g.setFont(isB2 ? "6x15" : "4x6", 1); + const str = "Hiscore: " + Math.round(highestI * 10); + g.setColor( + scoringI > highestI ? 0 : 255, + 0, + scoringI > highestI ? 255 : 0 + ) + .drawString( + str, + trigToCoord(0) - g.stringWidth(str) / 2, + trigToCoord(0) + ) + .setColor(255, 255, 255); + if (scoringI > highestI) { + highestI = scoringI; + require("Storage").writeJSON("flow.json", { + hiscore: highestI, + }); + calculateColor(highestI); + } + setTimeout(resetGame, 3000); + } else if (speedCoef <= 0.01 && !shownScore) { + shownScore = true; + g.setFont(isB2 ? "6x15" : "4x6", 2); + const str = "Score: " + Math.round(scoringI * 10); + g.setColor(colorB[0], colorB[1], colorB[2]) + .drawString( + str, + trigToCoord(0) - g.stringWidth(str) / 2, + trigToCoord(0) + ) + .setColor(1, 1, 1); + } + } + i += speedCoef; + g.scroll(0, speedCoef * h); + g.flip(); +} + +let intervalId; + +if (BTN.read()) { + for (let i = 0; i < 10; i++) { + color = getColor(i); + g.setColor(color[0], color[1], color[2]); + g.fillRect((i / 10) * h, 0, ((i + 1) / 10) * h, h); + } + g.setColor(0); + g.setFont("Vector", 9); + let str = "Welcome to the debug screen!"; + g.drawString( + str, + trigToCoord(0) - g.stringWidth(str) / 2, + trigToCoord(0) - 9 + ); + str = "Don't hold BTN while opening to play!"; + g.drawString(str, trigToCoord(0) - g.stringWidth(str) / 2, trigToCoord(0)); + g.flip(); + setInterval(() => { + g.scroll(0, 0.014 * h); + i += 0.014; + calculateColor(i); + g.setColor(colorA[0], colorA[1], colorA[2]); + g.fillRect(0, 0, trigToCoord(0), 0.014 * h); + g.setColor(colorB[0], colorB[1], colorB[2]); + g.fillRect(trigToCoord(0), 0, trigToCoord(1), 0.014 * h); + }, 1000 / 30); +} else intervalId = setInterval(draw, 1000 / 30); diff --git a/apps/flow/app.png b/apps/flow/app.png new file mode 100644 index 0000000000000000000000000000000000000000..b35c3ca77e8438a5c29d8f471e9ffda1fd110b45 GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC&H|6fVg?4jBOuH;Rhv&5DEQUW z#W5tK@$JlLuEPdAEK4u_j<@`~(mNyDonJfcz;DqG`N*`uH7>4CCd~U)?ov{quX%o3 z|E}XZ+;1Pq%4J^tmFIlU(xfC)snGfJKCpaX3(N~d4F!91Zm;PTZI4n3Q^ zA8|h5{h_3C?qdB9_2vIL{2B5O$S=&7Op`zMN~BU8BzvU)vTypkMuRl}#}!N!%s;hC zE-m-0j_+C3@Av8j$mC0coBXaVTE_>}t01$mKuOJ=6J(62V)45}x=CWqNBcWKs1iKMeHRxH)_moSe@jGXpM z%qY3%mzdt0xcdx$vbkC&F)du;prI+?H8`0-UsC}zeD3+hmUnv7mF*j@O8kw#zV*lP zzn5))t~?;l>g3rN5Tr0gghQ2f%$JMzF_uM}#TeJ^%-HkBuVS7tN^ozxa5Fd3ZvJ1F z*BQqpQQQ&zVo90rg8Ml$`=@WKx$szO@r##pP@KD|)$ier!}DiPJDt4v#lHCm3(uj% ziOobtA0rYv#P#lKkM_ji@j zezh%+c~Fv?u8G0v@7vFRs{QtV7P`BFjJswzq(4H_P{MWG?c&$l=CONQIlt(j`}6sx zdkXw^Mz0>8?=E0Nj?hb6Mw< G&;$S-S637O literal 0 HcmV?d00001 diff --git a/apps/flow/screenshot2.png b/apps/flow/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..e29691b69b712181e27f1a67741edd135357548a GIT binary patch literal 2580 zcmeHJ`!~~#A79I!=0m8qC*esYVT?=>Xn_HBjPxXlMluNbcQlt%O zn-U|p&$o1PiRG4_F-B>av6{8uNtAI+F9I2E6&o=%S zoQ-3J3+D6aXdJG;=v#@C9eDiu&UUo=Rp7RPu>u=XBT(GH-4sM>;nj11GKe)+Kx>^Q zBT3-yQXw7gC(cF(HD|-#ssJsAIYb~-xMirlZ)8Fm{9lkEMAjq z0HU$w1=S|fRkoIYZccYKbEfjT6?b}h;63p9>au108z`i8oQ;p?yYH`cTpI6+E$st>q@rzGa+-J+{c`C z1X=&kVXw{^tn_jmR@(Juq*?r18B~VKixGC;z2a{9Q4*Hle2=LHPy-e($Fhh**2+ju z4eMCm%>oij-}gwn@A41kWZgsA0_96@_!osC>)J#g;;WUo;@WPu=~&B{Hj2ws6R%En z^n2K-6<&@5$)w78|XKCI9e&_42h7>DCWWg;T&_xp;v?lPs1gxCja4>I8 z4!H5!w%h()DVx1Ku+%7twvXOyxscX7D4 zScZtMrvwz=xN)GN!*d+}NAmsyHcF?;y(3a&0q?)Hy82UiAlzD1GS;J%U*62P>0>Pt6Ty-E+Bg+b zT?%UvBeqIKTfBl}DK1I4@&3tBj`$-ne;hcx;)XNNpQGdQU`DIBr0qhxP)-F+-YTwsAnrqyvJJAX}> z*{;l;FFo|AxLZ8&qC4_peOS}1sm5I@E2M&iW+uq^|R7f z2$({R-m#N#Jvg$oE=ey@Pyy5rsaZ~x+vI5-^b9Jhm0hSjlqVs8ilQwmF?vCPXAS9S zxx*DgWk?G^b!0*xw6IdFel$5-{G5VZ4G7#HGO%~C;%uuS`E28!P;OpFKheu6#caxT z+06W)k32K3m7NiEBg_jtaQEn(`gc=)x(G7#Qf&+YPSsTkFq4x~qR={n|GdSs#ZPhu z9BIv6Z;Ef^GFE<-OMLip-z5?B*2E7^6#ho&8|`yPM_)n^g@3{p+d2#S*f>4O?AFG4 zO)%qPI3rirf5784hW20-qi~7&m{wXP4V4+v@X0OUi@71MQOh`K zBy!K1xyfWL2N=xxDhbSf#LNoz6ip|QVt~UzNBx~w{k`5wHu-|f9<;3n`yuBXsG ze`Z^HtX0&zr1_>~OJr;2d2|Buqq8q!=k*1SH)7f?VHp*%d>R{NO+`dppubPzY7m5- zbQYv@Wm*ti$4gs?jLjJDDd7eqrY&9rgIo569a}%<4eCvCSxsFdRQV@6eW^(Vd8qEk zRtX>H^rlzFXY6|0g zJV8x63}s`zdwFs`WHbD^ZZ3PmY(XE?St!f#`d5d(R3!wVB9lr}QD;Ea_Lx*Ox~3TF zXNDLtx~!wzcYnY31Olk34wq|Gfx%tUxV~a;PVihqc=6}$*B{ZiZp U{(juO{@KA?o!y<-4& zCmBS;LKG|{%_z)CQO1{pau(;5_8t(9&gZgW<-`vSghu3UI*A4j(Hcr%)wX2!m^V1?ea%|?SoMB%SD^#(cZfLGeE0>y^(l6 zETVf8f`&X#ER6u#h_40!6LuBRzez+CToINQGkXB-#UN&he--47FcsXmPC6k_{GZ~V z_ac!w(b2jSbP1y;`*(tW7jopI398Snvw3B68$HfGwIRNd=7_usjOlGg76ukA@iw{u z+i`Z|5TKLdq|zY(C#JULxcnEX3SdgcQ^KC9U%YqP9)8{z--AL^?Y_HiKu8Ccjk{6E zaC6u*72P%X;!B|1OUR9yoEfnSE-dKGd05O2YNhcrxv?5oi)8>plq^C%8aJ&?5Kt=% zV8?ar@uGih)Teml5LQv6!JB;EH?WV6BW)VPNom(DpzAN}ixiTV8N~&!ILTAfy5}=L zlrpm6=x*yH2AzyE1@P}^63!8UL%pL0`Cx6&knXole5sek2vf{yrz%;4SxN2!?5&UG ze}XPA^2RYoE^MeCMZ`fY0XBC;rPzU016(Ic)HSJ{MQUgFX3Le@D&?AU*wbzkLUfWf zWtP5zSRdXRnahGO zeNaD=+^o^6?xi)@XZx&}khJkOI>nRNyMEfskofytAz8vxF2xC!Q}X_xSSxSssqu9l zmuUR3Dk%dFZ`K%|nSP=3wz-jaoY}C}S)Qq70HlK^a+I{L8u!`@!chpZAJnwq@%0zi z@0HbPI6A5dQw9n>y(t&Hl!|il=G$pp!gRNk4JEtTAADr9ZgZ zI37G)7UiB+Z1ssGA_={xC8Zp!hF2~&SR2h28Y;`FWOOND^@SR;(?c)R7okvjonz!R zlmm-HSmA2FvGGyz*B>+W7u@&XmK-u;>I(aE{yd1D&^$kyP5AKaf!!6Vkd1-PF-j3; ze6ZHPK1hJEv&>29uyG1=t?2iwtqbc3;o0qe)UYPzH(pJEy4)4y+sufcClfw^$FbOr zbQ|5|53EYVOzRVR_ajGj-`eROE4KlO*-x-*FKg@&Et; literal 0 HcmV?d00001 From 685b5874c7632232d76789f943620e29d67b80bb Mon Sep 17 00:00:00 2001 From: Jay de Belle Date: Fri, 3 Dec 2021 19:27:42 -0500 Subject: [PATCH 0186/1839] A snek is born --- apps.json | 13 ++ apps/snek/snek-icon.js | 1 + apps/snek/snek.js | 463 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 477 insertions(+) create mode 100644 apps/snek/snek-icon.js create mode 100644 apps/snek/snek.js diff --git a/apps.json b/apps.json index a312b90a3..dda59cdde 100644 --- a/apps.json +++ b/apps.json @@ -2100,6 +2100,19 @@ {"name":"snake.img","url":"snake-icon.js","evaluate":true} ] }, + { "id": "snek", + "name": "The snek game", + "shortName":"Snek", + "version": "0.01", + "description": "A snek game where you control a snek to eat all the apples!", + "icon": "snek-icon.js", + "supports": ["BANGLEJS2"], + "tags": "game,fun", + "storage": [ + {"name":"snek.app.js","url":"snek.js"}, + {"name":"snek.img","url":"snek-icon.js","evaluate":true} + ] + }, { "id": "calculator", "name": "Calculator", diff --git a/apps/snek/snek-icon.js b/apps/snek/snek-icon.js new file mode 100644 index 000000000..c919c429e --- /dev/null +++ b/apps/snek/snek-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("pFIwkB+MRAEH/EUIA7i93u9xEUIABEf4AC+93/4CBETpDBv//gEHEf6MB9wkB/8HSDl3vwjCAAfnErIjiEQYdBAAXuAoSNXEYIdDAAoj4j/3DpN3v6NWAA3/fDYjgRgIjLu9xESj2BAAN/SQwLBEe4XDdwghDBQQjSCgN+C5D9FEebTDEZJEWEQSDVEdZpDZYPnETYhDAAhpeEbzREI0rTbEdXuETb4Bvz1BAYIj/EYxrg9yQDv/3JoS9WEcoaGAAQtBOwYABEaSMBWoYeFJKgjjiIUD9ySEEjwAJFogj0SQgAFBQ4jRABcfXoQj/TowjCOgIkeEf7lHvz+CEb93Ef4jHR8Rr/fY4jCuIifAAQj/EIojbeohGeEcQhHfLRFDeoIicEcQbDv3uEYiNXIgnu87SgEcf/DKnxBJEf/4ACESf/EcYA==")) \ No newline at end of file diff --git a/apps/snek/snek.js b/apps/snek/snek.js new file mode 100644 index 000000000..c97d8e030 --- /dev/null +++ b/apps/snek/snek.js @@ -0,0 +1,463 @@ +function init() { + this.titleScreen = true; + this.min = 0; + this.max = 160; + this.step = 20; + this.scoreMultiplier = 25; + this.totalGrid = this.max / this.step; + + if (g.theme.dark) { + this.textColor = 1; + } else { + this.textColor = 0; + } + + this.getNewPosistion = () => { + let newPos; + while (!newPos) { + // random bonus points for bad luck / lag + if (currentPosition.length > 10) { + this.score += 1; + } + const x = Math.floor(Math.random() * this.totalGrid + 1) * this.step; + const y = Math.floor(Math.random() * this.totalGrid + 1) * this.step; + const found = currentPosition.find(pos => { + return pos.x === x && pos.y === y; + }); + if (!found) { + newPos = {x: x, y: y}; + } + } + return newPos; + }; + + this.restart = () => { + g.clear(); + this.titleScreen = false; + this.score = 0; + this.paused = false; + this.currentPosition = [{x: 2 * step, y: 3 * step},{x: 1 * step, y: 3 * step}]; + this.death = false; + this.gameSpeed = 200; + this.directionSet = null; + this.direction = 1; + this.createApple(); + }; + + const game = () => { + if (this.death && !this.paused) { + g.clear(); + this.showDeathScreen(); + } else if (this.titleScreen && !this.paused) { + this.showTitleScreen(); + } else if (!this.paused) { + g.clear(); + this.drawApple(); + this.drawSnake(); + this.boundries(); + + } + + setTimeout(() => { + game(); + }, this.gameSpeed); + }; + + this.increaseDifficulity = () => { + if (gameSpeed > 59) { + gameSpeed -= 10; + } + }; + + this.createApple = () => { + this.applePosition = getNewPosistion(); + }; + + this.drawApple = () => { + g.setColor(0, 1, 0); + + g.drawImage(this.appleLeaf, this.applePosition.x - 15, this.applePosition.y - 10); + g.setColor(1, 0, 0); + + g.drawImage(this.apple, this.applePosition.x - 15, this.applePosition.y - 2); + }; + + this.checkmax = (x) => { + if (x > this.max) { + return this.min; + } else if (x < this.min) { + return this.max; + } + return x; + }; + + this.movement = (lastItem) => { + let newPosition; + switch(this.direction) { + case 3: + newPosition = { + x: checkmax(lastItem.x + this.step), + y: lastItem.y + }; + break; + case 1: + newPosition = { + x: checkmax(lastItem.x - this.step), + y: lastItem.y + }; + break; + case 2: + newPosition = { + x: lastItem.x, + y: checkmax(lastItem.y + this.step) + }; + break; + case 0: + newPosition = { + x: lastItem.x, + y: checkmax(lastItem.y - this.step) + }; + break; + } + this.directionSet = false; + this.checkDeath(newPosition); + this.currentPosition.push(newPosition); + + }; + + this.snakeHead = (props) => { + switch (this.direction) { + case 0: + return [this.snakeUp, props.x - 9, props.y - 12]; + case 1: + return [this.snakeLeft, props.x - 20, props.y - 10]; + case 3: + return [this.snakeRight, props.x - 12, props.y - 12]; + case 2: + return [this.snakeDown, props.x - 12, props.y - 7]; + default: + return [this.snakeDown, props.x - 12, props.y - 7]; + } + }; + + this.drawSnake = () => { + const totalItems = this.currentPosition.length - 1; + g.setColor(0, 1, 0); + this.movement(this.currentPosition[totalItems]); + this.currentPosition.forEach((props, index) => { + if (index-1 === totalItems) { + const head = this.snakeHead(props); + + g.drawImage(head[0], head[1], head[2]); + } else { + g.fillCircle(props.x,props.y,10); + } + }); + if (this.currentPosition[totalItems].x === this.applePosition.x && this.currentPosition[totalItems].y === this.applePosition.y) { + this.createApple(); + this.increaseDifficulity(); + } else { + this.currentPosition.shift(); + } + }; + + this.checkDeath = (newPos) => { + + const found = this.currentPosition.find((oldPos) => { + return newPos.x === oldPos.x && newPos.y === oldPos.y; + }); + if (found) { + Bangle.buzz(); + g.clear(); + this.death = true; + } + }; + + this.boundries = () => { + if (this.currentPosition.x >= this.maxPx) { + this.currentPosition.x = this.maxPx; + } + else if (this.currentPosition.x < 10) { + this.currentPosition.x = 10; + } + + if ( this.currentPosition.y >= this.maxPy) { + this.currentPosition.y = this.maxPy; + } else if (this.currentPosition.y < 10) { + this.currentPosition.y = 10; + } + }; + + this.creatTopScrore = () => { + require("Storage").writeJSON("snek_jd", { + topScore: this.calculateScore() + }); + }; + + this.calculateScore = () => { + return currentPosition.length * this.scoreMultiplier + this.score; + }; + + this.showDeathScreen = () => { + this.paused = true; + g.setFont('Vector', 25); + g.setColor(1, 0, 0); + g.drawString("GAME OVER",15, 50, "solid"); + g.setFont('Vector', 15); + g.setColor(this.textColor, this.textColor, this.textColor); + g.drawString("Score : " + this.calculateScore(), 50, 78, "solid"); + + let storage = require("Storage").readJSON("snek_jd"); + if (storage && storage.topScore) { + if (storage.topScore < this.calculateScore()) { + g.setColor(0, 1, 1); + g.drawString("New top score!", 20, 95, "solid"); + g.setFont('Vector', 22); + g.drawString(this.calculateScore(), 20, 115, "solid"); + + this.creatTopScrore(); + } else { + g.setColor(this.textColor, this.textColor, this.textColor); + g.drawString("Top score : " + storage.topScore, 20, 95, "solid"); + } + } else { + this.creatTopScrore(); + } + g.setFont('Vector', 25); + }; + + /* Events */ + Bangle.on('tap', (data) => { + Bangle.setLCDPower(true); + if (this.death) { + this.showTitleScreen(); + } else if (this.titleScreen || this.paused) { + this.restart(); + } + }); + + Bangle.on('accel', (xyz) => { + if (Math.abs(xyz.x) > Math.abs(xyz.y)) { + if (xyz.x < 0) { + if (!this.directionSet && this.direction !== 1) { + Bangle.setLCDPower(true); + this.direction = 3; + } + } else { + if (!this.directionSet && this.direction !== 3) { + Bangle.setLCDPower(true); + this.direction = 1; + } + } + } else { + if (xyz.y < 0) { + if (!this.directionSet && this.direction !== 0) { + Bangle.setLCDPower(true); + this.direction = 2; + } + } else { + if (!this.directionSet && this.direction !== 2) { + Bangle.setLCDPower(true); + this.direction = 0; + } + } + } + this.directionSet = true; + }); + + this.showTitleScreen = () => { + this.death = false; + g.clear(); + g.setColor(0, 1, 0); + g.setFont('Vector', 50); + g.drawString("nek", 70, 15, "solid"); + g.drawImage(this.titleScreenImg, 20, 20); + g.fillPoly([ + 15, 66, + 152, 70, + 159, 79, + 21, 71 ]); + g.setFont('Vector', 12); + g.setColor(1, 0, 1); + g.drawString("by: Jason de Belle", 30, 80, "solid"); + + + + }; + +/* Graphics */ + this.snakeUp = Graphics.createImage(` + XX XX + xx xx + xx xx + xx + xx + xx + xx + xx + xxxxxxxx + xxxx xxxx + xxxxxx xxxxxxx + xxxxxxxxxxxxxxxx + xxxxx xXXx xxxxx + xxxxx XX xxxxx + xxxxx XX xxxxx + xxxxxx xxxx xxxxx + xxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxx + `); + this.snakeDown = Graphics.createImage(` + xxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxx xxxx xxxxxx + xxxxxx xxxx xxxxxx + xxxx XX xxxxx + xxxx XX xxxxx + xxxx xXXx xxxx + xxxx xXXx xxxx + xXxxxxxxxxxxxx + xXxxxxxxxxxxxx + xxx xxx + xxxx xxxx + xxxx + xx + xx + xx + xx + x x + xx xx + xx xx + `); + + this.snakeRight = Graphics.createImage(` + xxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xXxxxxxx xxxx + xXxxxxxx xxxx + xxxxxxxX xxx + xxxxxxxX xxx xxxx +xxxxxxxxxxXX xxxxxx xxxx +xxxxxxxxxxXX xxxxxx xx +xxxxxxxxxxXXxxxxx xxxxxxxx +xxxxxxxxxxXXxxxxx xxxxxxxx +xxxxxxxxxxxx xxxxx xx +xxxxxxxxxxxx xxxxx xxx + xxxxxxxx xx xxxx + xxxxxxxx xx + xxxxxxxx xxx + xxxxxxxx xxx + xxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxx + xxxxxxxxx + `); + this.snakeLeft = Graphics.createImage(` + xxxxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xXxxxxxxxxxxxx + xX xxxxxxxxxx + x xx xXxxxxxxxx + xx xx xXxxxxxxxx + xx xx xxxx xxXXxxxxxxxx + xxxxxxx xxxxxXXxxxxxxxx + xxxxxxx xxxxxXXxxxxxxxx + xx xx xxxx xxXXxxxxxxxx + xx xxx xxxxxxxxxx + x xxx xxxxxxxxx + xxxx xxxxxxxxx + xxxx xxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxx + xxxxxxxxx + `); + + this.apple = Graphics.createImage(` + xxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxx + `); + + this.appleLeaf = Graphics.createImage(` + xxxxxx + xxxxxx + xxxx + XXxxxxxxxx + xx + xx + xx + xx + xx + `); + + +this.titleScreenImg = Graphics.createImage(` + sxxxxxxxs + xxsxxx xxxxxs + xxxxxxxxsxx xxxxsx + xxxxxxxxxxxxxxxsxxs xxxxsxx + xxxxxxxxxxxxxxxxxxxxxsxxxsssxxxxxxsxxxx + xxxxxxxxxxxxxxxxxxxsxxxxsxxs xxsxxx + xxxxxxxxxxxxxxxxxxxxxxxxxsxx xxxsxx + xxxxxxxxxxxxxxxxxxxxx sxxx ssxxsx + xxxxxxxxxxxxxxx xxxxxxs + xxxxxxxxxxxx ssss + xxxxxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxx +xxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxx +xxxxxxx +xxx +`); + + game(); +} +init(); \ No newline at end of file From d287855b9e810a44a1fda203c72e4e46f98ce7f1 Mon Sep 17 00:00:00 2001 From: Jay de Belle Date: Fri, 3 Dec 2021 19:55:52 -0500 Subject: [PATCH 0187/1839] Added the snek icon --- apps/snek/snek.png | Bin 0 -> 4967 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/snek/snek.png diff --git a/apps/snek/snek.png b/apps/snek/snek.png new file mode 100644 index 0000000000000000000000000000000000000000..8cf8d05e399d2e0bab622d1ce38b189d478bb723 GIT binary patch literal 4967 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 ZMMT}7(#MOH;Nuu+3oVc;{W$96zW^f1;dTH3 literal 0 HcmV?d00001 From 1d03a5b3aad8418d0b3468534d6a43e484e3e0a0 Mon Sep 17 00:00:00 2001 From: Jay de Belle Date: Fri, 3 Dec 2021 21:30:41 -0500 Subject: [PATCH 0188/1839] Updated name, fixed icon --- apps/snek/snek.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/snek/snek.js b/apps/snek/snek.js index c97d8e030..4c3aec73e 100644 --- a/apps/snek/snek.js +++ b/apps/snek/snek.js @@ -150,7 +150,7 @@ function init() { g.drawImage(head[0], head[1], head[2]); } else { - g.fillCircle(props.x,props.y,10); + g.fillCircle(props.x, props.y, 10); } }); if (this.currentPosition[totalItems].x === this.applePosition.x && this.currentPosition[totalItems].y === this.applePosition.y) { @@ -277,11 +277,17 @@ function init() { 152, 70, 159, 79, 21, 71 ]); - g.setFont('Vector', 12); - g.setColor(1, 0, 1); - g.drawString("by: Jason de Belle", 30, 80, "solid"); - - + g.setColor(this.textColor, this.textColor, this.textColor); + g.setFont('Vector', 15); + g.drawString("Tilt to turn", 20, 100, "solid"); + g.drawString("Tap to start", 20, 120, "solid"); + + g.setColor(0, 1, 0); + + g.setFont('4x6', 3); + g.drawString("Jason de Belle", 5, 145, "solid"); + + }; From ea8c1688dbf2c0b995e5ff6fb456ea910e0843cb Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Sat, 4 Dec 2021 10:49:50 +0200 Subject: [PATCH 0189/1839] refactor: extract lib --- apps/hebrew_calendar/app.js | 364 +---------------------------- apps/hebrew_calendar/hebrewDate.js | 359 ++++++++++++++++++++++++++++ 2 files changed, 360 insertions(+), 363 deletions(-) create mode 100644 apps/hebrew_calendar/hebrewDate.js diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js index 5bed9c590..074c22988 100644 --- a/apps/hebrew_calendar/app.js +++ b/apps/hebrew_calendar/app.js @@ -1,369 +1,7 @@ g.clear(); -/*! - * This script was taked from this page and ported to Node.js by Ionic Bizu - * http://www.shamash.org/help/javadate.shtml - * - * This script was adapted from C sources written by - * Scott E. Lee, which contain the following copyright notice: - * - * Copyright 1993-1995, Scott E. Lee, all rights reserved. - * Permission granted to use, copy, modify, distribute and sell so long as - * the above copyright and this permission statement are retained in all - * copies. THERE IS NO WARRANTY - USE AT YOUR OWN RISK. - * - * Bill Hastings - * RBI Software Systems - * bhastings@rbi.com - */ - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var GREG_SDN_OFFSET = 32045, - DAYS_PER_5_MONTHS = 153, - DAYS_PER_4_YEARS = 1461, - DAYS_PER_400_YEARS = 146097; - -var HALAKIM_PER_HOUR = 1080, - HALAKIM_PER_DAY = 25920, - HALAKIM_PER_LUNAR_CYCLE = 29 * HALAKIM_PER_DAY + 13753, - HALAKIM_PER_METONIC_CYCLE = HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7); - -var HEB_SDN_OFFSET = 347997, - NEW_MOON_OF_CREATION = 31524, - NOON = 18 * HALAKIM_PER_HOUR, - AM3_11_20 = 9 * HALAKIM_PER_HOUR + 204, - AM9_32_43 = 15 * HALAKIM_PER_HOUR + 589; - -var SUN = 0, - MON = 1, - TUES = 2, - WED = 3, - THUR = 4, - FRI = 5, - SAT = 6; - -function weekdayarr(d0, d1, d2, d3, d4, d5, d6) { - this[0] = d0; - this[1] = d1; - this[2] = d2; - this[3] = d3; - this[4] = d4; - this[5] = d5; - this[6] = d6; -} - -function gregmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) { - this[0] = m0; - this[1] = m1; - this[2] = m2; - this[3] = m3; - this[4] = m4; - this[5] = m5; - this[6] = m6; - this[7] = m7; - this[8] = m8; - this[9] = m9; - this[10] = m10; - this[11] = m11; -} - -function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13) { - this[0] = m0; - this[1] = m1; - this[2] = m2; - this[3] = m3; - this[4] = m4; - this[5] = m5; - this[6] = m6; - this[7] = m7; - this[8] = m8; - this[9] = m9; - this[10] = m10; - this[11] = m11; - this[12] = m12; - this[13] = m13; -} - -function monthsperyeararr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18) { - this[0] = m0; - this[1] = m1; - this[2] = m2; - this[3] = m3; - this[4] = m4; - this[5] = m5; - this[6] = m6; - this[7] = m7; - this[8] = m8; - this[9] = m9; - this[10] = m10; - this[11] = m11; - this[12] = m12; - this[13] = m13; - this[14] = m14; - this[15] = m15; - this[16] = m16; - this[17] = m17; - this[18] = m18; -} - -var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur"), - gMonth = new gregmontharr("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), - hMonth = new hebrewmontharr("Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", "Elul"), - mpy = new monthsperyeararr(12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13); - -/** - * hebrewDate - * Convert the Gregorian dates into Hebrew calendar dates. - * - * @name hebrewDate - * @function - * @param {Date|Number} inputDate The date object (representing the Gregorian date) or the year. - * @param {Number?} inputMonth The Gregorian month (**one-indexed**, January being `1`!). - * @param {Number?} inputDate The Gregorian date. - * @return {Object} An object containing: - * - * - `year`: The Hebrew year. - * - `month`: The Hebrew month. - * - `month_name`: The Hebrew month name. - * - `date`: The Hebrew date. - */ -const hebrewDate = function (inputDateOrYear, inputMonth, inputDate) { - - var hebrewMonth = 0, - hebrewDate = 0, - hebrewYear = 0, - metonicCycle = 0, - metonicYear = 0, - moladDay = 0, - moladHalakim = 0; - - function GregorianToSdn(inputYear, inputMonth, inputDay) { - - var year = 0, - month = 0, - sdn = void 0; - - // Make year a positive number - if (inputYear < 0) { - year = inputYear + 4801; - } else { - year = inputYear + 4800; - } - - // Adjust the start of the year - if (inputMonth > 2) { - month = inputMonth - 3; - } else { - month = inputMonth + 9; - year--; - } - - sdn = Math.floor(Math.floor(year / 100) * DAYS_PER_400_YEARS / 4); - sdn += Math.floor(year % 100 * DAYS_PER_4_YEARS / 4); - sdn += Math.floor((month * DAYS_PER_5_MONTHS + 2) / 5); - sdn += inputDay - GREG_SDN_OFFSET; - - return sdn; - } - - function SdnToHebrew(sdn) { - var tishri1 = 0, - tishri1After = 0, - yearLength = 0, - inputDay = sdn - HEB_SDN_OFFSET; - - FindTishriMolad(inputDay); - tishri1 = Tishri1(metonicYear, moladDay, moladHalakim); - - if (inputDay >= tishri1) { - // It found Tishri 1 at the start of the year. - hebrewYear = metonicCycle * 19 + metonicYear + 1; - if (inputDay < tishri1 + 59) { - if (inputDay < tishri1 + 30) { - hebrewMonth = 1; - hebrewDate = inputDay - tishri1 + 1; - } else { - hebrewMonth = 2; - hebrewDate = inputDay - tishri1 - 29; - } - return; - } - // We need the length of the year to figure this out,so find Tishri 1 of the next year. - moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear]; - moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); - moladHalakim = moladHalakim % HALAKIM_PER_DAY; - tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim); - } else { - // It found Tishri 1 at the end of the year. - hebrewYear = metonicCycle * 19 + metonicYear; - if (inputDay >= tishri1 - 177) { - // It is one of the last 6 months of the year. - if (inputDay > tishri1 - 30) { - hebrewMonth = 13; - hebrewDate = inputDay - tishri1 + 30; - } else if (inputDay > tishri1 - 60) { - hebrewMonth = 12; - hebrewDate = inputDay - tishri1 + 60; - } else if (inputDay > tishri1 - 89) { - hebrewMonth = 11; - hebrewDate = inputDay - tishri1 + 89; - } else if (inputDay > tishri1 - 119) { - hebrewMonth = 10; - hebrewDate = inputDay - tishri1 + 119; - } else if (inputDay > tishri1 - 148) { - hebrewMonth = 9; - hebrewDate = inputDay - tishri1 + 148; - } else { - hebrewMonth = 8; - hebrewDate = inputDay - tishri1 + 178; - } - return; - } else { - if (mpy[(hebrewYear - 1) % 19] == 13) { - hebrewMonth = 7; - hebrewDate = inputDay - tishri1 + 207; - if (hebrewDate > 0) return; - hebrewMonth--; - hebrewDate += 30; - if (hebrewDate > 0) return; - hebrewMonth--; - hebrewDate += 30; - } else { - hebrewMonth = 6; - hebrewDate = inputDay - tishri1 + 207; - if (hebrewDate > 0) return; - hebrewMonth--; - hebrewDate += 30; - } - if (hebrewDate > 0) return; - hebrewMonth--; - hebrewDate += 29; - if (hebrewDate > 0) return; - // We need the length of the year to figure this out,so find Tishri 1 of this year. - tishri1After = tishri1; - FindTishriMolad(moladDay - 365); - tishri1 = Tishri1(metonicYear, moladDay, moladHalakim); - } - } - yearLength = tishri1After - tishri1; - moladDay = inputDay - tishri1 - 29; - if (yearLength == 355 || yearLength == 385) { - // Heshvan has 30 days - if (moladDay <= 30) { - hebrewMonth = 2; - hebrewDate = moladDay; - return; - } - moladDay -= 30; - } else { - // Heshvan has 29 days - if (moladDay <= 29) { - hebrewMonth = 2; - hebrewDate = moladDay; - return; - } - moladDay -= 29; - } - // It has to be Kislev. - hebrewMonth = 3; - hebrewDate = moladDay; - } - - function FindTishriMolad(inputDay) { - // Estimate the metonic cycle number. Note that this may be an under - // estimate because there are 6939.6896 days in a metonic cycle not - // 6940,but it will never be an over estimate. The loop below will - // correct for any error in this estimate. - metonicCycle = Math.floor((inputDay + 310) / 6940); - // Calculate the time of the starting molad for this metonic cycle. - MoladOfMetonicCycle(); - // If the above was an under estimate,increment the cycle number until - // the correct one is found. For modern dates this loop is about 98.6% - // likely to not execute,even once,because the above estimate is - // really quite close. - while (moladDay < inputDay - 6940 + 310) { - metonicCycle++; - moladHalakim += HALAKIM_PER_METONIC_CYCLE; - moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); - moladHalakim = moladHalakim % HALAKIM_PER_DAY; - } - // Find the molad of Tishri closest to this date. - for (metonicYear = 0; metonicYear < 18; metonicYear++) { - if (moladDay > inputDay - 74) break; - moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear]; - moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); - moladHalakim = moladHalakim % HALAKIM_PER_DAY; - } - } - - function MoladOfMetonicCycle() { - var r1 = void 0, - r2 = void 0, - d1 = void 0, - d2 = void 0; - // Start with the time of the first molad after creation. - r1 = NEW_MOON_OF_CREATION; - // Calculate gMetonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32 - // bits of the result will be in r2 and the lower 16 bits will be in r1. - r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF); - r2 = r1 >> 16; - r2 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE >> 16 & 0xFFFF); - // Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1,the - // upper 16 bits of the quotient will be in d2 and the lower 16 bits - // will be in d1. - d2 = Math.floor(r2 / HALAKIM_PER_DAY); - r2 -= d2 * HALAKIM_PER_DAY; - r1 = r2 << 16 | r1 & 0xFFFF; - d1 = Math.floor(r1 / HALAKIM_PER_DAY); - r1 -= d1 * HALAKIM_PER_DAY; - moladDay = d2 << 16 | d1; - moladHalakim = r1; - } - - function Tishri1(metonicYear, moladDay, moladHalakim) { - var tishri1 = moladDay, - dow = tishri1 % 7, - leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7 || metonicYear == 10 || metonicYear == 13 || metonicYear == 16 || metonicYear == 18, - lastWasLeapYear = metonicYear == 3 || metonicYear == 6 || metonicYear == 8 || metonicYear == 11 || metonicYear == 14 || metonicYear == 17 || metonicYear == 0; - - // Apply rules 2,3 and 4 - if (moladHalakim >= NOON || !leapYear && dow == TUES && moladHalakim >= AM3_11_20 || lastWasLeapYear && dow == MON && moladHalakim >= AM9_32_43) { - tishri1++; - dow++; - if (dow == 7) dow = 0; - } - - // Apply rule 1 after the others because it can cause an additional delay of one day. - if (dow == WED || dow == FRI || dow == SUN) { - tishri1++; - } - - return tishri1; - } - - var inputYear = inputDateOrYear; - - if ((typeof inputYear === "undefined" ? "undefined" : _typeof(inputYear)) === "object") { - inputMonth = inputDateOrYear.getMonth() + 1; - inputDate = inputDateOrYear.getDate(); - inputYear = inputDateOrYear.getFullYear(); - } - - SdnToHebrew(GregorianToSdn(inputYear, inputMonth, inputDate)); - - return { - year: hebrewYear, - month: hebrewMonth, - date: hebrewDate, - month_name: hMonth[hebrewMonth - 1] - }; -}; - - -g.setFont("Vector",10); let now = new Date(); -let today = hebrewDate(now); +let today = require("hebrewDate")(now); var mainmenu = { "" : { diff --git a/apps/hebrew_calendar/hebrewDate.js b/apps/hebrew_calendar/hebrewDate.js new file mode 100644 index 000000000..bbefb4499 --- /dev/null +++ b/apps/hebrew_calendar/hebrewDate.js @@ -0,0 +1,359 @@ +/*! + * This script was taked from this page and ported to Node.js by Ionic Bizu + * http://www.shamash.org/help/javadate.shtml + * + * This script was adapted from C sources written by + * Scott E. Lee, which contain the following copyright notice: + * + * Copyright 1993-1995, Scott E. Lee, all rights reserved. + * Permission granted to use, copy, modify, distribute and sell so long as + * the above copyright and this permission statement are retained in all + * copies. THERE IS NO WARRANTY - USE AT YOUR OWN RISK. + * + * Bill Hastings + * RBI Software Systems + * bhastings@rbi.com + */ + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var GREG_SDN_OFFSET = 32045, + DAYS_PER_5_MONTHS = 153, + DAYS_PER_4_YEARS = 1461, + DAYS_PER_400_YEARS = 146097; + +var HALAKIM_PER_HOUR = 1080, + HALAKIM_PER_DAY = 25920, + HALAKIM_PER_LUNAR_CYCLE = 29 * HALAKIM_PER_DAY + 13753, + HALAKIM_PER_METONIC_CYCLE = HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7); + +var HEB_SDN_OFFSET = 347997, + NEW_MOON_OF_CREATION = 31524, + NOON = 18 * HALAKIM_PER_HOUR, + AM3_11_20 = 9 * HALAKIM_PER_HOUR + 204, + AM9_32_43 = 15 * HALAKIM_PER_HOUR + 589; + +var SUN = 0, + MON = 1, + TUES = 2, + WED = 3, + THUR = 4, + FRI = 5, + SAT = 6; + +function weekdayarr(d0, d1, d2, d3, d4, d5, d6) { + this[0] = d0; + this[1] = d1; + this[2] = d2; + this[3] = d3; + this[4] = d4; + this[5] = d5; + this[6] = d6; +} + +function gregmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) { + this[0] = m0; + this[1] = m1; + this[2] = m2; + this[3] = m3; + this[4] = m4; + this[5] = m5; + this[6] = m6; + this[7] = m7; + this[8] = m8; + this[9] = m9; + this[10] = m10; + this[11] = m11; +} + +function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13) { + this[0] = m0; + this[1] = m1; + this[2] = m2; + this[3] = m3; + this[4] = m4; + this[5] = m5; + this[6] = m6; + this[7] = m7; + this[8] = m8; + this[9] = m9; + this[10] = m10; + this[11] = m11; + this[12] = m12; + this[13] = m13; +} + +function monthsperyeararr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18) { + this[0] = m0; + this[1] = m1; + this[2] = m2; + this[3] = m3; + this[4] = m4; + this[5] = m5; + this[6] = m6; + this[7] = m7; + this[8] = m8; + this[9] = m9; + this[10] = m10; + this[11] = m11; + this[12] = m12; + this[13] = m13; + this[14] = m14; + this[15] = m15; + this[16] = m16; + this[17] = m17; + this[18] = m18; +} + +var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur"), + gMonth = new gregmontharr("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), + hMonth = new hebrewmontharr("Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", "Elul"), + mpy = new monthsperyeararr(12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13); + +/** + * hebrewDate + * Convert the Gregorian dates into Hebrew calendar dates. + * + * @name hebrewDate + * @function + * @param {Date|Number} inputDate The date object (representing the Gregorian date) or the year. + * @param {Number?} inputMonth The Gregorian month (**one-indexed**, January being `1`!). + * @param {Number?} inputDate The Gregorian date. + * @return {Object} An object containing: + * + * - `year`: The Hebrew year. + * - `month`: The Hebrew month. + * - `month_name`: The Hebrew month name. + * - `date`: The Hebrew date. + */ +const hebrewDate = function (inputDateOrYear, inputMonth, inputDate) { + + var hebrewMonth = 0, + hebrewDate = 0, + hebrewYear = 0, + metonicCycle = 0, + metonicYear = 0, + moladDay = 0, + moladHalakim = 0; + + function GregorianToSdn(inputYear, inputMonth, inputDay) { + + var year = 0, + month = 0, + sdn = void 0; + + // Make year a positive number + if (inputYear < 0) { + year = inputYear + 4801; + } else { + year = inputYear + 4800; + } + + // Adjust the start of the year + if (inputMonth > 2) { + month = inputMonth - 3; + } else { + month = inputMonth + 9; + year--; + } + + sdn = Math.floor(Math.floor(year / 100) * DAYS_PER_400_YEARS / 4); + sdn += Math.floor(year % 100 * DAYS_PER_4_YEARS / 4); + sdn += Math.floor((month * DAYS_PER_5_MONTHS + 2) / 5); + sdn += inputDay - GREG_SDN_OFFSET; + + return sdn; + } + + function SdnToHebrew(sdn) { + var tishri1 = 0, + tishri1After = 0, + yearLength = 0, + inputDay = sdn - HEB_SDN_OFFSET; + + FindTishriMolad(inputDay); + tishri1 = Tishri1(metonicYear, moladDay, moladHalakim); + + if (inputDay >= tishri1) { + // It found Tishri 1 at the start of the year. + hebrewYear = metonicCycle * 19 + metonicYear + 1; + if (inputDay < tishri1 + 59) { + if (inputDay < tishri1 + 30) { + hebrewMonth = 1; + hebrewDate = inputDay - tishri1 + 1; + } else { + hebrewMonth = 2; + hebrewDate = inputDay - tishri1 - 29; + } + return; + } + // We need the length of the year to figure this out,so find Tishri 1 of the next year. + moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear]; + moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); + moladHalakim = moladHalakim % HALAKIM_PER_DAY; + tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim); + } else { + // It found Tishri 1 at the end of the year. + hebrewYear = metonicCycle * 19 + metonicYear; + if (inputDay >= tishri1 - 177) { + // It is one of the last 6 months of the year. + if (inputDay > tishri1 - 30) { + hebrewMonth = 13; + hebrewDate = inputDay - tishri1 + 30; + } else if (inputDay > tishri1 - 60) { + hebrewMonth = 12; + hebrewDate = inputDay - tishri1 + 60; + } else if (inputDay > tishri1 - 89) { + hebrewMonth = 11; + hebrewDate = inputDay - tishri1 + 89; + } else if (inputDay > tishri1 - 119) { + hebrewMonth = 10; + hebrewDate = inputDay - tishri1 + 119; + } else if (inputDay > tishri1 - 148) { + hebrewMonth = 9; + hebrewDate = inputDay - tishri1 + 148; + } else { + hebrewMonth = 8; + hebrewDate = inputDay - tishri1 + 178; + } + return; + } else { + if (mpy[(hebrewYear - 1) % 19] == 13) { + hebrewMonth = 7; + hebrewDate = inputDay - tishri1 + 207; + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 30; + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 30; + } else { + hebrewMonth = 6; + hebrewDate = inputDay - tishri1 + 207; + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 30; + } + if (hebrewDate > 0) return; + hebrewMonth--; + hebrewDate += 29; + if (hebrewDate > 0) return; + // We need the length of the year to figure this out,so find Tishri 1 of this year. + tishri1After = tishri1; + FindTishriMolad(moladDay - 365); + tishri1 = Tishri1(metonicYear, moladDay, moladHalakim); + } + } + yearLength = tishri1After - tishri1; + moladDay = inputDay - tishri1 - 29; + if (yearLength == 355 || yearLength == 385) { + // Heshvan has 30 days + if (moladDay <= 30) { + hebrewMonth = 2; + hebrewDate = moladDay; + return; + } + moladDay -= 30; + } else { + // Heshvan has 29 days + if (moladDay <= 29) { + hebrewMonth = 2; + hebrewDate = moladDay; + return; + } + moladDay -= 29; + } + // It has to be Kislev. + hebrewMonth = 3; + hebrewDate = moladDay; + } + + function FindTishriMolad(inputDay) { + // Estimate the metonic cycle number. Note that this may be an under + // estimate because there are 6939.6896 days in a metonic cycle not + // 6940,but it will never be an over estimate. The loop below will + // correct for any error in this estimate. + metonicCycle = Math.floor((inputDay + 310) / 6940); + // Calculate the time of the starting molad for this metonic cycle. + MoladOfMetonicCycle(); + // If the above was an under estimate,increment the cycle number until + // the correct one is found. For modern dates this loop is about 98.6% + // likely to not execute,even once,because the above estimate is + // really quite close. + while (moladDay < inputDay - 6940 + 310) { + metonicCycle++; + moladHalakim += HALAKIM_PER_METONIC_CYCLE; + moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); + moladHalakim = moladHalakim % HALAKIM_PER_DAY; + } + // Find the molad of Tishri closest to this date. + for (metonicYear = 0; metonicYear < 18; metonicYear++) { + if (moladDay > inputDay - 74) break; + moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear]; + moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); + moladHalakim = moladHalakim % HALAKIM_PER_DAY; + } + } + + function MoladOfMetonicCycle() { + var r1 = void 0, + r2 = void 0, + d1 = void 0, + d2 = void 0; + // Start with the time of the first molad after creation. + r1 = NEW_MOON_OF_CREATION; + // Calculate gMetonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32 + // bits of the result will be in r2 and the lower 16 bits will be in r1. + r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF); + r2 = r1 >> 16; + r2 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE >> 16 & 0xFFFF); + // Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1,the + // upper 16 bits of the quotient will be in d2 and the lower 16 bits + // will be in d1. + d2 = Math.floor(r2 / HALAKIM_PER_DAY); + r2 -= d2 * HALAKIM_PER_DAY; + r1 = r2 << 16 | r1 & 0xFFFF; + d1 = Math.floor(r1 / HALAKIM_PER_DAY); + r1 -= d1 * HALAKIM_PER_DAY; + moladDay = d2 << 16 | d1; + moladHalakim = r1; + } + + function Tishri1(metonicYear, moladDay, moladHalakim) { + var tishri1 = moladDay, + dow = tishri1 % 7, + leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7 || metonicYear == 10 || metonicYear == 13 || metonicYear == 16 || metonicYear == 18, + lastWasLeapYear = metonicYear == 3 || metonicYear == 6 || metonicYear == 8 || metonicYear == 11 || metonicYear == 14 || metonicYear == 17 || metonicYear == 0; + + // Apply rules 2,3 and 4 + if (moladHalakim >= NOON || !leapYear && dow == TUES && moladHalakim >= AM3_11_20 || lastWasLeapYear && dow == MON && moladHalakim >= AM9_32_43) { + tishri1++; + dow++; + if (dow == 7) dow = 0; + } + + // Apply rule 1 after the others because it can cause an additional delay of one day. + if (dow == WED || dow == FRI || dow == SUN) { + tishri1++; + } + + return tishri1; + } + + var inputYear = inputDateOrYear; + + if ((typeof inputYear === "undefined" ? "undefined" : _typeof(inputYear)) === "object") { + inputMonth = inputDateOrYear.getMonth() + 1; + inputDate = inputDateOrYear.getDate(); + inputYear = inputDateOrYear.getFullYear(); + } + + SdnToHebrew(GregorianToSdn(inputYear, inputMonth, inputDate)); + + return { + year: hebrewYear, + month: hebrewMonth, + date: hebrewDate, + month_name: hMonth[hebrewMonth - 1] + }; +}; \ No newline at end of file From d5cd869b2fedadc2105f7dd1f9ce9ba0453297bf Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Sat, 4 Dec 2021 10:57:50 +0200 Subject: [PATCH 0190/1839] refactor: typescript! refactor: rollup! --- apps/hebrew_calendar/app.js | 28 +---------------- apps/hebrew_calendar/package.json | 23 ++++++++++++++ apps/hebrew_calendar/rollup.config.js | 15 +++++++++ apps/hebrew_calendar/src/app.ts | 32 ++++++++++++++++++++ apps/hebrew_calendar/{ => src}/hebrewDate.js | 0 apps/hebrew_calendar/tsconfig.json | 10 ++++++ 6 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 apps/hebrew_calendar/package.json create mode 100644 apps/hebrew_calendar/rollup.config.js create mode 100644 apps/hebrew_calendar/src/app.ts rename apps/hebrew_calendar/{ => src}/hebrewDate.js (100%) create mode 100644 apps/hebrew_calendar/tsconfig.json diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js index 074c22988..ff30920e7 100644 --- a/apps/hebrew_calendar/app.js +++ b/apps/hebrew_calendar/app.js @@ -1,27 +1 @@ -g.clear(); - -let now = new Date(); -let today = require("hebrewDate")(now); - -var mainmenu = { - "" : { - "title" : "Hebrew Date" - }, - cal: { - value: require('locale').date(now,1), - onchange : () => {} - }, - date: { - value : today.date, - onchange : () => {} - }, - month: { - value : today.month_name, - onchange : () => {} - }, - year: { - value : today.year, - onchange : () => {} - } -}; -E.showMenu(mainmenu); +!function(){"use strict";g.clear();let e=new Date,a=require("hebrewDate")(e);var n={"":{title:"Hebrew Date"},cal:{value:require("locale").date(e,1),onchange:()=>{}},date:{value:a.date,onchange:()=>{}},month:{value:a.month_name,onchange:()=>{}},year:{value:a.year,onchange:()=>{}}};E.showMenu(n)}(); diff --git a/apps/hebrew_calendar/package.json b/apps/hebrew_calendar/package.json new file mode 100644 index 000000000..c509b70bb --- /dev/null +++ b/apps/hebrew_calendar/package.json @@ -0,0 +1,23 @@ +{ + "name": "hebrew_calendar", + "version": "0.0.1", + "description": "Bangle.js app for seeing hebrew calendar", + "main": "app.js", + "types": "app.d.ts", + "scripts": { + "build": "rollup -c" + }, + "author": { + "name": "Michael Salaverry", + "url": "https://github.com/barakplasma" + }, + "license": "MIT", + "devDependencies": { + "@rollup/plugin-typescript": "^4.1.1", + "rollup": "^2.10.2", + "rollup-plugin-terser": "^5.3.0", + "terser": "^4.7.0", + "tslib": "^2.0.0", + "typescript": "^3.9.2" + } +} diff --git a/apps/hebrew_calendar/rollup.config.js b/apps/hebrew_calendar/rollup.config.js new file mode 100644 index 000000000..5f7f0746f --- /dev/null +++ b/apps/hebrew_calendar/rollup.config.js @@ -0,0 +1,15 @@ +import typescript from '@rollup/plugin-typescript'; +import { terser } from 'rollup-plugin-terser'; + +export default { + input: './src/app.ts', + output: { + dir: '.', + format: 'iife', + name: 'hebrew_calendar' + }, + plugins: [ + typescript(), + terser(), + ] +}; diff --git a/apps/hebrew_calendar/src/app.ts b/apps/hebrew_calendar/src/app.ts new file mode 100644 index 000000000..111f47184 --- /dev/null +++ b/apps/hebrew_calendar/src/app.ts @@ -0,0 +1,32 @@ +declare var Bangle: any; +declare var g: any; +declare var E: any; +declare var require: any; + +g.clear(); + +let now = new Date(); +let today = require("hebrewDate")(now); + +var mainmenu = { + "" : { + "title" : "Hebrew Date" + }, + cal: { + value: require('locale').date(now,1), + onchange : () => {} + }, + date: { + value : today.date, + onchange : () => {} + }, + month: { + value : today.month_name, + onchange : () => {} + }, + year: { + value : today.year, + onchange : () => {} + } +}; +E.showMenu(mainmenu); diff --git a/apps/hebrew_calendar/hebrewDate.js b/apps/hebrew_calendar/src/hebrewDate.js similarity index 100% rename from apps/hebrew_calendar/hebrewDate.js rename to apps/hebrew_calendar/src/hebrewDate.js diff --git a/apps/hebrew_calendar/tsconfig.json b/apps/hebrew_calendar/tsconfig.json new file mode 100644 index 000000000..a341a5a5e --- /dev/null +++ b/apps/hebrew_calendar/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "es2015", + "noImplicitAny": true, + "target": "es2015" + }, + "include": [ + "src" + ] +} From 4c5134ff423ef12718641f815c6103985e416bda Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Sat, 4 Dec 2021 11:17:58 +0200 Subject: [PATCH 0191/1839] bump: version --- apps.json | 2 +- apps/hebrew_calendar/ChangeLog | 1 + apps/hebrew_calendar/package.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 992cce5d6..d7218d428 100644 --- a/apps.json +++ b/apps.json @@ -33,7 +33,7 @@ "id": "hebrew_calendar", "name": "Hebrew Calendar", "shortName": "HebCal", - "version": "0.01", + "version": "0.02", "description": "lists the date according to the hebrew calendar", "icon": "app.png", "tags": "", diff --git a/apps/hebrew_calendar/ChangeLog b/apps/hebrew_calendar/ChangeLog index 5560f00bc..b2ac114ef 100644 --- a/apps/hebrew_calendar/ChangeLog +++ b/apps/hebrew_calendar/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: using TS and rollup to bundle \ No newline at end of file diff --git a/apps/hebrew_calendar/package.json b/apps/hebrew_calendar/package.json index c509b70bb..d43cc6ad9 100644 --- a/apps/hebrew_calendar/package.json +++ b/apps/hebrew_calendar/package.json @@ -1,6 +1,6 @@ { "name": "hebrew_calendar", - "version": "0.0.1", + "version": "0.0.2", "description": "Bangle.js app for seeing hebrew calendar", "main": "app.js", "types": "app.d.ts", From 355c2ba37e0c4ca667d068cfd527f4234d17b15b Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Sat, 4 Dec 2021 11:34:50 +0200 Subject: [PATCH 0192/1839] refactor: js to ts --- apps/hebrew_calendar/app.js | 18 +++++++++++++++++- apps/hebrew_calendar/src/app.ts | 4 +++- .../src/{hebrewDate.js => hebrewDate.ts} | 9 ++++----- apps/hebrew_calendar/tsconfig.json | 2 +- 4 files changed, 25 insertions(+), 8 deletions(-) rename apps/hebrew_calendar/src/{hebrewDate.js => hebrewDate.ts} (97%) diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js index ff30920e7..9c21fa89b 100644 --- a/apps/hebrew_calendar/app.js +++ b/apps/hebrew_calendar/app.js @@ -1 +1,17 @@ -!function(){"use strict";g.clear();let e=new Date,a=require("hebrewDate")(e);var n={"":{title:"Hebrew Date"},cal:{value:require("locale").date(e,1),onchange:()=>{}},date:{value:a.date,onchange:()=>{}},month:{value:a.month_name,onchange:()=>{}},year:{value:a.year,onchange:()=>{}}};E.showMenu(n)}(); +!function(){"use strict"; +/*! + * This script was taked from this page and ported to Node.js by Ionic Bizu + * http://www.shamash.org/help/javadate.shtml + * + * This script was adapted from C sources written by + * Scott E. Lee, which contain the following copyright notice: + * + * Copyright 1993-1995, Scott E. Lee, all rights reserved. + * Permission granted to use, copy, modify, distribute and sell so long as + * the above copyright and this permission statement are retained in all + * copies. THERE IS NO WARRANTY - USE AT YOUR OWN RISK. + * + * Bill Hastings + * RBI Software Systems + * bhastings@rbi.com + */var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};var i=new function(t,i,e,o,r,n,h,a,s,f,u,l,v,c){this[0]=t,this[1]=i,this[2]=e,this[3]=o,this[4]=r,this[5]=n,this[6]=h,this[7]=a,this[8]=s,this[9]=f,this[10]=u,this[11]=l,this[12]=v,this[13]=c}("Tishri","Heshvan","Kislev","Tevet","Shevat","AdarI","AdarII","Nisan","Iyyar","Sivan","Tammuz","Av","Elul"),e=new function(t,i,e,o,r,n,h,a,s,f,u,l,v,c,y,d,m,M,b){this[0]=t,this[1]=i,this[2]=e,this[3]=o,this[4]=r,this[5]=n,this[6]=h,this[7]=a,this[8]=s,this[9]=f,this[10]=u,this[11]=l,this[12]=v,this[13]=c,this[14]=y,this[15]=d,this[16]=m,this[17]=M,this[18]=b}(12,12,13,12,12,13,12,13,12,12,13,12,12,13,12,12,13,12,13);g.clear();let o=new Date,r=function(o){var r,n,h=0,a=0,s=0,f=0,u=0,l=0,v=0;function c(t){var i,o,r,n;for(f=Math.floor((t+310)/6940),r=void 0,n=void 0,r=31524,n=(r+=45971*f)>>16,n+=2744*f,o=Math.floor(n/25920),r=(n-=25920*o)<<16|65535&r,i=Math.floor(r/25920),l=o<<16|i,v=r-=25920*i;lt-74);u++)v+=765433*e[u],l+=Math.floor(v/25920),v%=25920}function y(t,i,e){var o=i,r=o%7;return(e>=19440||!(2==t||5==t||7==t||10==t||13==t||16==t||18==t)&&2==r&&e>=9924||(3==t||6==t||8==t||11==t||14==t||17==t||0==t)&&1==r&&e>=16789)&&(o++,7==++r&&(r=0)),3!=r&&5!=r&&0!=r||o++,o}var d=o;return"object"===(void 0===d?"undefined":t(d))&&(r=o.getMonth()+1,n=o.getDate(),d=o.getFullYear()),function(t){var i,o=0,r=0,n=t-347997;if(c(n),n>=(o=y(u,l,v))){if(s=19*f+u+1,n=o-177)return void(n>o-30?(h=13,a=n-o+30):n>o-60?(h=12,a=n-o+60):n>o-89?(h=11,a=n-o+89):n>o-119?(h=10,a=n-o+119):n>o-148?(h=9,a=n-o+148):(h=8,a=n-o+178));if(13==e[(s-1)%19]){if(h=7,(a=n-o+207)>0)return;if(h--,(a+=30)>0)return;h--,a+=30}else{if(h=6,(a=n-o+207)>0)return;h--,a+=30}if(a>0)return;if(h--,(a+=29)>0)return;r=o,c(l-365),o=y(u,l,v)}if(l=n-o-29,355==(i=r-o)||385==i){if(l<=30)return h=2,void(a=l);l-=30}else{if(l<=29)return h=2,void(a=l);l-=29}h=3,a=l}(function(t,i,e){var o=0,r=0,n=void 0;return o=t<0?t+4801:t+4800,i>2?r=i-3:(r=i+9,o--),n=Math.floor(146097*Math.floor(o/100)/4),n+=Math.floor(o%100*1461/4),n+=Math.floor((153*r+2)/5),n+=e-32045}(d,r,n)),{year:s,month:h,date:a,month_name:i[h-1]}}(o);var n={"":{title:"Hebrew Date"},cal:{value:require("locale").date(o,1),onchange:()=>{}},date:{value:r.date,onchange:()=>{}},month:{value:r.month_name,onchange:()=>{}},year:{value:r.year,onchange:()=>{}}};E.showMenu(n)}(); diff --git a/apps/hebrew_calendar/src/app.ts b/apps/hebrew_calendar/src/app.ts index 111f47184..51314e337 100644 --- a/apps/hebrew_calendar/src/app.ts +++ b/apps/hebrew_calendar/src/app.ts @@ -6,7 +6,9 @@ declare var require: any; g.clear(); let now = new Date(); -let today = require("hebrewDate")(now); +import { hebrewDate } from "./hebrewDate"; + +let today = hebrewDate(now); var mainmenu = { "" : { diff --git a/apps/hebrew_calendar/src/hebrewDate.js b/apps/hebrew_calendar/src/hebrewDate.ts similarity index 97% rename from apps/hebrew_calendar/src/hebrewDate.js rename to apps/hebrew_calendar/src/hebrewDate.ts index bbefb4499..cc3a5ed78 100644 --- a/apps/hebrew_calendar/src/hebrewDate.js +++ b/apps/hebrew_calendar/src/hebrewDate.ts @@ -66,7 +66,7 @@ function gregmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) { this[11] = m11; } -function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13) { +function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13?: any) { this[0] = m0; this[1] = m1; this[2] = m2; @@ -117,8 +117,6 @@ var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "S * @name hebrewDate * @function * @param {Date|Number} inputDate The date object (representing the Gregorian date) or the year. - * @param {Number?} inputMonth The Gregorian month (**one-indexed**, January being `1`!). - * @param {Number?} inputDate The Gregorian date. * @return {Object} An object containing: * * - `year`: The Hebrew year. @@ -126,7 +124,8 @@ var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "S * - `month_name`: The Hebrew month name. * - `date`: The Hebrew date. */ -const hebrewDate = function (inputDateOrYear, inputMonth, inputDate) { +export const hebrewDate = function (inputDateOrYear: Date) { + var inputMonth, inputDate; var hebrewMonth = 0, hebrewDate = 0, @@ -340,7 +339,7 @@ const hebrewDate = function (inputDateOrYear, inputMonth, inputDate) { return tishri1; } - var inputYear = inputDateOrYear; + var inputYear: Date | number = inputDateOrYear; if ((typeof inputYear === "undefined" ? "undefined" : _typeof(inputYear)) === "object") { inputMonth = inputDateOrYear.getMonth() + 1; diff --git a/apps/hebrew_calendar/tsconfig.json b/apps/hebrew_calendar/tsconfig.json index a341a5a5e..30a9e35f4 100644 --- a/apps/hebrew_calendar/tsconfig.json +++ b/apps/hebrew_calendar/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "es2015", - "noImplicitAny": true, + "noImplicitAny": false, "target": "es2015" }, "include": [ From 60ba4ed3f181a4ab13705a2409d9a9d908d61847 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Sat, 4 Dec 2021 11:42:08 +0200 Subject: [PATCH 0193/1839] Revert "feat: use sfo as tz" This reverts commit 1271d28720d84a1321fd9bca8ecd0aa16ea4eb51. --- apps/a_clock_timer/app.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/a_clock_timer/app.js b/apps/a_clock_timer/app.js index 8d078ffe9..5f9a3a468 100644 --- a/apps/a_clock_timer/app.js +++ b/apps/a_clock_timer/app.js @@ -102,19 +102,20 @@ function queueNextDraw() { function draw() { g.reset().clearRect(0,24,g.getWidth(),g.getHeight()-IMAGEHEIGHT); g.drawImage(getImg(),0,g.getHeight()-IMAGEHEIGHT); - + var x_sun = 176 - (getGmt().getHours() / 24 * 176 + 4); g.setColor('#ff0').drawLine(x_sun, g.getHeight()-IMAGEHEIGHT, x_sun, g.getHeight()); g.reset(); var locale = require("locale"); - + var date = new Date(); g.setFontAlign(0,0); g.setFont("Michroma36").drawString(locale.time(date,1), g.getWidth()/2, 46); g.setFont("6x8"); g.drawString(locale.date(new Date(),1), 125, 68); - g.drawString("SFO "+locale.time(getTimeFromTimezone(-8),1), 125, 80); + g.drawString("PAR "+locale.time(getTimeFromTimezone(1),1), 125, 80); + g.drawString("TYO "+locale.time(getTimeFromTimezone(9),1), 125, 88); queueNextDraw(); } From a8f69af1535024dd852fc490e20abfdd48421450 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Sat, 4 Dec 2021 11:49:52 +0200 Subject: [PATCH 0194/1839] fix: travis by making it mjs --- apps/hebrew_calendar/{rollup.config.js => rollup.config.mjs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/hebrew_calendar/{rollup.config.js => rollup.config.mjs} (100%) diff --git a/apps/hebrew_calendar/rollup.config.js b/apps/hebrew_calendar/rollup.config.mjs similarity index 100% rename from apps/hebrew_calendar/rollup.config.js rename to apps/hebrew_calendar/rollup.config.mjs From 00e05c2f2187e2d6f5b7a267026396a36a3a4b68 Mon Sep 17 00:00:00 2001 From: Michael Salaverry Date: Sat, 4 Dec 2021 11:55:07 +0200 Subject: [PATCH 0195/1839] feat: support bangle 1 by changing apps.json --- apps.json | 3 ++- apps/hebrew_calendar/ChangeLog | 3 ++- apps/hebrew_calendar/package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index d7218d428..5b6eac06d 100644 --- a/apps.json +++ b/apps.json @@ -33,11 +33,12 @@ "id": "hebrew_calendar", "name": "Hebrew Calendar", "shortName": "HebCal", - "version": "0.02", + "version": "0.03", "description": "lists the date according to the hebrew calendar", "icon": "app.png", "tags": "", "supports": [ + "BANGLEJS", "BANGLEJS2" ], "readme": "README.md", diff --git a/apps/hebrew_calendar/ChangeLog b/apps/hebrew_calendar/ChangeLog index b2ac114ef..d7dbc19e3 100644 --- a/apps/hebrew_calendar/ChangeLog +++ b/apps/hebrew_calendar/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! -0.02: using TS and rollup to bundle \ No newline at end of file +0.02: using TS and rollup to bundle +0.03: bug fixes and support bangle 1 \ No newline at end of file diff --git a/apps/hebrew_calendar/package.json b/apps/hebrew_calendar/package.json index d43cc6ad9..85e9ebbf0 100644 --- a/apps/hebrew_calendar/package.json +++ b/apps/hebrew_calendar/package.json @@ -1,6 +1,6 @@ { "name": "hebrew_calendar", - "version": "0.0.2", + "version": "0.0.3", "description": "Bangle.js app for seeing hebrew calendar", "main": "app.js", "types": "app.d.ts", From 0518b77d680e45c215b3aa963cb43528b5bb2f2f Mon Sep 17 00:00:00 2001 From: James Date: Sat, 4 Dec 2021 10:13:45 +0000 Subject: [PATCH 0196/1839] Fix spelling of mandelbrot for mandelbrotclock --- apps/mandlebrotclock/README.md | 4 ++-- apps/mandlebrotclock/mandlebrotclock.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/mandlebrotclock/README.md b/apps/mandlebrotclock/README.md index 8628a61d0..387343a9e 100644 --- a/apps/mandlebrotclock/README.md +++ b/apps/mandlebrotclock/README.md @@ -1,6 +1,6 @@ -# Mandlebrot Clock +# Mandelbrot Clock -A simple clock themed on the mandlebrot set. +A simple clock themed on the mandelbrot set. Written by [James Milner](https://www.github.com/jameslmilner) diff --git a/apps/mandlebrotclock/mandlebrotclock.js b/apps/mandlebrotclock/mandlebrotclock.js index 16cc8dfb8..94636056e 100644 --- a/apps/mandlebrotclock/mandlebrotclock.js +++ b/apps/mandlebrotclock/mandlebrotclock.js @@ -1,6 +1,6 @@ // MIT License - James Milner 2021 -const mandlebrotBmp = { +const mandelbrotBmp = { width: 176, height: 176, bpp: 8, @@ -13,7 +13,7 @@ const mandlebrotBmp = { }; function draw() { - g.drawImage(mandlebrotBmp); + g.drawImage(mandelbrotBmp); // work out how to display the current time const d = new Date(); const h = d.getHours(), From 72265234bbd908c5527a7a5c00f3a215ce54eb66 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 4 Dec 2021 10:20:49 +0000 Subject: [PATCH 0197/1839] Rename files --- apps.json | 16 ++++++++-------- .../ChangeLog | 0 .../README.md | 0 .../app.png | Bin .../mandelbrotclock-icon.js} | 0 .../mandelbrotclock.js} | 0 .../mandelbrotclock.png} | Bin .../screenshot_mandelbrotclock.png} | Bin 8 files changed, 8 insertions(+), 8 deletions(-) rename apps/{mandlebrotclock => mandelbrotclock}/ChangeLog (100%) rename apps/{mandlebrotclock => mandelbrotclock}/README.md (100%) rename apps/{mandlebrotclock => mandelbrotclock}/app.png (100%) rename apps/{mandlebrotclock/mandlebrotclock-icon.js => mandelbrotclock/mandelbrotclock-icon.js} (100%) rename apps/{mandlebrotclock/mandlebrotclock.js => mandelbrotclock/mandelbrotclock.js} (100%) rename apps/{mandlebrotclock/mandlebrotclock.png => mandelbrotclock/mandelbrotclock.png} (100%) rename apps/{mandlebrotclock/screenshot_mandlebrotclock.png => mandelbrotclock/screenshot_mandelbrotclock.png} (100%) diff --git a/apps.json b/apps.json index a312b90a3..5eaa26362 100644 --- a/apps.json +++ b/apps.json @@ -463,22 +463,22 @@ ] }, { - "id": "mandlebrotclock", - "name": "Mandlebrot Clock", + "id": "mandelbrotclock", + "name": "Mandelbrot Clock", "version": "0.01", - "description": "A mandlebrot set themed clock cool", - "icon": "mandlebrotclock.png", - "screenshots": [{ "url": "screenshot_mandlebrotclock.png" }], + "description": "A mandelbrot set themed clock cool", + "icon": "mandelbrotclock.png", + "screenshots": [{ "url": "screenshot_mandelbrotclock.png" }], "type": "clock", "tags": "clock", "supports": ["BANGLEJS2"], "readme": "README.md", "allow_emulator": true, "storage": [ - { "name": "mandlebrotclock.app.js", "url": "mandlebrotclock.js" }, + { "name": "mandelbrotclock.app.js", "url": "mandelbrotclock.js" }, { - "name": "mandlebrotclock.img", - "url": "mandlebrotclock-icon.js", + "name": "mandelbrotclock.img", + "url": "mandelbrotclock-icon.js", "evaluate": true } ] diff --git a/apps/mandlebrotclock/ChangeLog b/apps/mandelbrotclock/ChangeLog similarity index 100% rename from apps/mandlebrotclock/ChangeLog rename to apps/mandelbrotclock/ChangeLog diff --git a/apps/mandlebrotclock/README.md b/apps/mandelbrotclock/README.md similarity index 100% rename from apps/mandlebrotclock/README.md rename to apps/mandelbrotclock/README.md diff --git a/apps/mandlebrotclock/app.png b/apps/mandelbrotclock/app.png similarity index 100% rename from apps/mandlebrotclock/app.png rename to apps/mandelbrotclock/app.png diff --git a/apps/mandlebrotclock/mandlebrotclock-icon.js b/apps/mandelbrotclock/mandelbrotclock-icon.js similarity index 100% rename from apps/mandlebrotclock/mandlebrotclock-icon.js rename to apps/mandelbrotclock/mandelbrotclock-icon.js diff --git a/apps/mandlebrotclock/mandlebrotclock.js b/apps/mandelbrotclock/mandelbrotclock.js similarity index 100% rename from apps/mandlebrotclock/mandlebrotclock.js rename to apps/mandelbrotclock/mandelbrotclock.js diff --git a/apps/mandlebrotclock/mandlebrotclock.png b/apps/mandelbrotclock/mandelbrotclock.png similarity index 100% rename from apps/mandlebrotclock/mandlebrotclock.png rename to apps/mandelbrotclock/mandelbrotclock.png diff --git a/apps/mandlebrotclock/screenshot_mandlebrotclock.png b/apps/mandelbrotclock/screenshot_mandelbrotclock.png similarity index 100% rename from apps/mandlebrotclock/screenshot_mandlebrotclock.png rename to apps/mandelbrotclock/screenshot_mandelbrotclock.png From 03d18c61f4b6518645d1cad89bb0ff48ee5bb4f1 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 19:25:50 +0100 Subject: [PATCH 0198/1839] create first draft --- apps.json | 13 +++++++++++++ apps/chargingStatus/ChangeLog | 1 + apps/chargingStatus/widget.js | 23 +++++++++++++++++++++++ apps/chargingStatus/widget.png | Bin 0 -> 3724 bytes 4 files changed, 37 insertions(+) create mode 100644 apps/chargingStatus/ChangeLog create mode 100644 apps/chargingStatus/widget.js create mode 100644 apps/chargingStatus/widget.png diff --git a/apps.json b/apps.json index a312b90a3..af5921669 100644 --- a/apps.json +++ b/apps.json @@ -4675,5 +4675,18 @@ "data": [ {"name":"pooqroman.json"} ] + }, + { "id": "chargingStatus", + "name": "Charging Status", + "shortName":"Charging", + "icon": "widget.png", + "version":"0.1", + "type": "widget", + "description": "A simple widget that shows up whenever the watch starts charging.", + "tags": "widget,battery", + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"chargingStatus.wid.js","url":"widget.js"} + ] } ] diff --git a/apps/chargingStatus/ChangeLog b/apps/chargingStatus/ChangeLog new file mode 100644 index 000000000..d3175e1ab --- /dev/null +++ b/apps/chargingStatus/ChangeLog @@ -0,0 +1 @@ +0.1: First release. \ No newline at end of file diff --git a/apps/chargingStatus/widget.js b/apps/chargingStatus/widget.js new file mode 100644 index 000000000..72e8bdb26 --- /dev/null +++ b/apps/chargingStatus/widget.js @@ -0,0 +1,23 @@ +(() => { + Bangle.on('charging', (charging) => { + if (charging) { + Bangle.buzz(); + } + Bangle.drawWidgets(); // re-layout widgets + g.flip(); + }); + WIDGETS.chargingStatus = { + area: 'tr', + width: 16, + draw() { + const { + x, + y + } = this; + g.reset(); + if (Bangle.isCharging()) { + g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), x, y); + } + }, + }; +})(); \ No newline at end of file diff --git a/apps/chargingStatus/widget.png b/apps/chargingStatus/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..0097d45efb9d2eaed58999990cf36808f0a7f718 GIT binary patch literal 3724 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 literal 0 HcmV?d00001 From af42aa02b321ece5585534e3ca21b6ec81969d15 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 19:42:34 +0100 Subject: [PATCH 0199/1839] Update widget.js --- apps/chargingStatus/widget.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/chargingStatus/widget.js b/apps/chargingStatus/widget.js index 72e8bdb26..20925bfc7 100644 --- a/apps/chargingStatus/widget.js +++ b/apps/chargingStatus/widget.js @@ -10,13 +10,9 @@ area: 'tr', width: 16, draw() { - const { - x, - y - } = this; g.reset(); if (Bangle.isCharging()) { - g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), x, y); + g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); } }, }; From 86626ce80531b1557f6b05a6e5664fa5250cc148 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 19:53:43 +0100 Subject: [PATCH 0200/1839] test: activate widget always --- apps/chargingStatus/widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/chargingStatus/widget.js b/apps/chargingStatus/widget.js index 20925bfc7..a43c0411b 100644 --- a/apps/chargingStatus/widget.js +++ b/apps/chargingStatus/widget.js @@ -11,9 +11,9 @@ width: 16, draw() { g.reset(); - if (Bangle.isCharging()) { + //if (Bangle.isCharging()) { g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); - } + //} }, }; })(); \ No newline at end of file From 78800e63d0fa688006d9e6a8f472fca96497e000 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 19:56:41 +0100 Subject: [PATCH 0201/1839] Update widget.js --- apps/chargingStatus/widget.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/chargingStatus/widget.js b/apps/chargingStatus/widget.js index a43c0411b..90d048fa4 100644 --- a/apps/chargingStatus/widget.js +++ b/apps/chargingStatus/widget.js @@ -12,7 +12,8 @@ draw() { g.reset(); //if (Bangle.isCharging()) { - g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); + g.drawString("X", this.x, this.y); + //g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); //} }, }; From d908f888e409a90a4dc94f46093505c639fd5099 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Sun, 5 Dec 2021 03:58:57 +0900 Subject: [PATCH 0202/1839] Update apps.json --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index a312b90a3..c47539c27 100644 --- a/apps.json +++ b/apps.json @@ -4591,9 +4591,9 @@ }, { "id":"a_speech_timer", - "name":"A Speech Timer", + "name":"Speech Timer", "icon": "app.png", - "version":"1.00", + "version":"1.01", "description": "A timer designed to help keeping your speeches and presentations to time.", "tags": "tool,timer", "readme":"README.md", From c892b155f8b57ebc46f0d264f5d2628cde259aa2 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:00:35 +0100 Subject: [PATCH 0203/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index af5921669..8680dfc97 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"Charging", "icon": "widget.png", - "version":"0.1", + "version":"0.1.1", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", From d2f8615a773a06ad821e7cb79652e1cfcf827dc9 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Sun, 5 Dec 2021 04:01:17 +0900 Subject: [PATCH 0204/1839] Update ChangeLog --- apps/a_speech_timer/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/a_speech_timer/ChangeLog b/apps/a_speech_timer/ChangeLog index 4a8e3fbe7..b3aa9e0dd 100644 --- a/apps/a_speech_timer/ChangeLog +++ b/apps/a_speech_timer/ChangeLog @@ -1 +1,2 @@ 1.00: Release (2021/12/01) +1.01: Grey font when timer is frozen (2021/12/04) From dc358e2202333775b174a79077eb8a2f129696e1 Mon Sep 17 00:00:00 2001 From: Alain Saas Date: Sun, 5 Dec 2021 04:01:52 +0900 Subject: [PATCH 0205/1839] Update app.js --- apps/a_speech_timer/app.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/a_speech_timer/app.js b/apps/a_speech_timer/app.js index dae2545b2..440cd92c6 100644 --- a/apps/a_speech_timer/app.js +++ b/apps/a_speech_timer/app.js @@ -63,7 +63,7 @@ function countDown() { Bangle.on('touch',(touchside, touchdata)=>{ if (!islocked && istimeron && touchdata.y > (100+10)) { - Bangle.buzz(40); + Bangle.buzz(40); istimeron = false; clearInterval(timerinterval); } else if (touchdata.y > 24 && touchdata.y < (100-10)) { @@ -134,20 +134,20 @@ function draw() { else if (current_value >= current_from) { g.setBgColor("#8F8"); } g.clearRect(0,24,176,176); - g.reset(); - g.setFontAlign(0, 0); - + g.reset().setFontAlign(0, 0).setColor(istimeron ? "#000" : "#444"); g.setFont("Michroma36").drawString(timeToString(current_value), 88, 62); + g.reset().setFontAlign(0, 0); + g.setFont("HaxorNarrow7x17"); g.drawString(timeToString(current_from), 44, 62+26); g.drawString(timeToString(current_mid), 88, 62+26); g.drawString(timeToString(current_to), 132, 62+26); - + if (current_value >= current_from) { g.drawRect(44-1,62+26+9,44+1,62+26+9+1); } if (current_value >= current_mid) { g.drawRect(88-1,62+26+9,88+1,62+26+9+1); } if (current_value >= current_to) { g.drawRect(132-1,62+26+9,132+1,62+26+9+1); } - + if (showInstructions) { g.setFont("6x8").drawString("Tapping timer locks buttons", 88, 100+5); g.setFont("6x8").drawString("<= Swipe to change time =>", 88, 168); @@ -159,7 +159,7 @@ function draw() { g.drawString(timeToString(newtimer_left_to), 44, 138+9); g.drawString(timeToString(newtimer_right_from), 132, 138-9); g.drawString(timeToString(newtimer_right_to), 132, 138+9); - + g.drawRect(0+8,138-24, 88-9+1, 138+22+1); g.drawRect(0+8,138-24, 88-9, 138+22); g.drawRect(88+8,138-24, 176-10+1, 138+22+1); From 107f862723a6fb3000ba4720f32c4e1d6412c39c Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:07:54 +0100 Subject: [PATCH 0206/1839] update version for another test --- apps.json | 2 +- apps/chargingStatus/widget.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index 8680dfc97..146e3a1a0 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"Charging", "icon": "widget.png", - "version":"0.1.1", + "version":"0.1.2", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/chargingStatus/widget.js b/apps/chargingStatus/widget.js index 90d048fa4..1352c2b11 100644 --- a/apps/chargingStatus/widget.js +++ b/apps/chargingStatus/widget.js @@ -6,13 +6,13 @@ Bangle.drawWidgets(); // re-layout widgets g.flip(); }); - WIDGETS.chargingStatus = { + WIDGETS["chargingStatus"] = { area: 'tr', - width: 16, + width: 32, draw() { g.reset(); //if (Bangle.isCharging()) { - g.drawString("X", this.x, this.y); + g.drawString("X", this.x, this.y); //g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); //} }, From 168515a2efe4242503494e076f52b6a6a05cd601 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:18:24 +0100 Subject: [PATCH 0207/1839] Update widget.js --- apps/chargingStatus/widget.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/chargingStatus/widget.js b/apps/chargingStatus/widget.js index 1352c2b11..6a3837ace 100644 --- a/apps/chargingStatus/widget.js +++ b/apps/chargingStatus/widget.js @@ -10,10 +10,13 @@ area: 'tr', width: 32, draw() { - g.reset(); + g.reset(); + g.setColor("#FD0"); // on = amber + //if (Bangle.isCharging()) { - g.drawString("X", this.x, this.y); - //g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); + g.drawImage(atob("GBiBAAAAAAAAAAAAAA//8B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+A//8AAAAAAAAAAAAA=="), this.x, 2+this.y); + + //g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); //} }, }; From a0e61f0d4bdf2024b4ecd4d07d66c36ad016970d Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:19:07 +0100 Subject: [PATCH 0208/1839] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 146e3a1a0..23a5344e7 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"Charging", "icon": "widget.png", - "version":"0.1.2", + "version":"0.1.3", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", From c320902fc6729b643438ee17582dc69f224da32f Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:30:13 +0100 Subject: [PATCH 0209/1839] move to another folder, add gps draw logic --- apps.json | 6 +-- apps/chargingStatus/widget.js | 23 ----------- .../ChangeLog | 0 apps/widChargingStatus/widget.js | 38 ++++++++++++++++++ .../widget.png | Bin 5 files changed, 41 insertions(+), 26 deletions(-) delete mode 100644 apps/chargingStatus/widget.js rename apps/{chargingStatus => widChargingStatus}/ChangeLog (100%) create mode 100644 apps/widChargingStatus/widget.js rename apps/{chargingStatus => widChargingStatus}/widget.png (100%) diff --git a/apps.json b/apps.json index 23a5344e7..7576d584a 100644 --- a/apps.json +++ b/apps.json @@ -4676,11 +4676,11 @@ {"name":"pooqroman.json"} ] }, - { "id": "chargingStatus", + { "id": "widChargingStatus", "name": "Charging Status", - "shortName":"Charging", + "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.3", + "version":"0.1.4", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/chargingStatus/widget.js b/apps/chargingStatus/widget.js deleted file mode 100644 index 6a3837ace..000000000 --- a/apps/chargingStatus/widget.js +++ /dev/null @@ -1,23 +0,0 @@ -(() => { - Bangle.on('charging', (charging) => { - if (charging) { - Bangle.buzz(); - } - Bangle.drawWidgets(); // re-layout widgets - g.flip(); - }); - WIDGETS["chargingStatus"] = { - area: 'tr', - width: 32, - draw() { - g.reset(); - g.setColor("#FD0"); // on = amber - - //if (Bangle.isCharging()) { - g.drawImage(atob("GBiBAAAAAAAAAAAAAA//8B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+A//8AAAAAAAAAAAAA=="), this.x, 2+this.y); - - //g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); - //} - }, - }; -})(); \ No newline at end of file diff --git a/apps/chargingStatus/ChangeLog b/apps/widChargingStatus/ChangeLog similarity index 100% rename from apps/chargingStatus/ChangeLog rename to apps/widChargingStatus/ChangeLog diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js new file mode 100644 index 000000000..3c953ce17 --- /dev/null +++ b/apps/widChargingStatus/widget.js @@ -0,0 +1,38 @@ +(() => { + Bangle.on('charging', (charging) => { + if (charging) { + Bangle.buzz(); + } + Bangle.drawWidgets(); // re-layout widgets + g.flip(); + }); + + function draw() { + g.reset(); + g.setColor("#FD0"); // on = amber + //if (Bangle.isCharging()) { + g.drawImage(atob("GBiBAAAAAAAAAAAAAA//8B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+A//8AAAAAAAAAAAAA=="), this.x, 2 + this.y); + //g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); + //} + } + + WIDGETS.chargingStatus = { + area: 'tr', + width: 32, + draw: draw, + }; + + function gpsDraw() { + g.reset(); + g.setColor("#FD0"); // on = amber + + g.drawImage(atob("GBiBAAAAAAAAAAAAAA//8B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+A//8AAAAAAAAAAAAA=="), this.x, 2 + this.y); + + } + WIDGETS.gpsT = { + area: "tr", + width: 24, + draw: gpsDraw + }; + +})(); \ No newline at end of file diff --git a/apps/chargingStatus/widget.png b/apps/widChargingStatus/widget.png similarity index 100% rename from apps/chargingStatus/widget.png rename to apps/widChargingStatus/widget.png From c2b731a972699307063fdf106af66bdab43f3c13 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:34:45 +0100 Subject: [PATCH 0210/1839] attempt to draw what we want to see --- apps.json | 2 +- apps/widChargingStatus/widget.js | 14 +------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/apps.json b/apps.json index 7576d584a..a0616c635 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.4", + "version":"0.1.5", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 3c953ce17..4f77351e1 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -11,8 +11,7 @@ g.reset(); g.setColor("#FD0"); // on = amber //if (Bangle.isCharging()) { - g.drawImage(atob("GBiBAAAAAAAAAAAAAA//8B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+A//8AAAAAAAAAAAAA=="), this.x, 2 + this.y); - //g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); + g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); //} } @@ -22,17 +21,6 @@ draw: draw, }; - function gpsDraw() { - g.reset(); - g.setColor("#FD0"); // on = amber - g.drawImage(atob("GBiBAAAAAAAAAAAAAA//8B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+A//8AAAAAAAAAAAAA=="), this.x, 2 + this.y); - - } - WIDGETS.gpsT = { - area: "tr", - width: 24, - draw: gpsDraw - }; })(); \ No newline at end of file From 67c72d337e7f7e70c67d0c3627eb5257192f3cfd Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:44:17 +0100 Subject: [PATCH 0211/1839] attempt to use correct image for rendering --- apps.json | 2 +- apps/widChargingStatus/widget.js | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index a0616c635..9eba02710 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.5", + "version":"0.1.6", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 4f77351e1..b75335c45 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -7,17 +7,25 @@ g.flip(); }); + const chargingSymbol = { + width: 16, + height: 16, + bpp: 1, + transparent: 1, + buffer: require("heatshrink").decompress(atob("/9/AIP+v/8AIP//ABBg/wh4BB8Ef/4BBn/+AIIXB/4BB")) + }; + function draw() { g.reset(); - g.setColor("#FD0"); // on = amber + g.setColor("#FD0"); //if (Bangle.isCharging()) { - g.setColor('#0f0').drawImage(atob("EBCBAf9//3/+f/x//P/4//gH8A/wD+Af/x//P/4//n/+//7/"), this.x, this.y); + g.drawImage(chargingSymbol, this.x + 2, this.y); //} } WIDGETS.chargingStatus = { area: 'tr', - width: 32, + width: 20, draw: draw, }; From 772d0a8724999dc25c5aa76ad618d20e89b5b402 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:47:31 +0100 Subject: [PATCH 0212/1839] draw X --- apps.json | 2 +- apps/widChargingStatus/widget.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 9eba02710..87750ad2c 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.6", + "version":"0.1.7", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index b75335c45..bd46b0847 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -19,7 +19,8 @@ g.reset(); g.setColor("#FD0"); //if (Bangle.isCharging()) { - g.drawImage(chargingSymbol, this.x + 2, this.y); + // g.drawImage(chargingSymbol, this.x + 2, this.y); + g.drawString('X',this.x,this.y) //} } From 4e4cc3e93085061e497c93050f133774c75cf5dc Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:50:24 +0100 Subject: [PATCH 0213/1839] attempt to draw icon again --- apps.json | 2 +- apps/widChargingStatus/widget.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index 87750ad2c..6c223e7d2 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.7", + "version":"0.1.8", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index bd46b0847..120741b27 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -17,10 +17,10 @@ function draw() { g.reset(); - g.setColor("#FD0"); + //g.setColor("#FD0"); //if (Bangle.isCharging()) { - // g.drawImage(chargingSymbol, this.x + 2, this.y); - g.drawString('X',this.x,this.y) + g.drawImage(chargingSymbol, this.x /* + 2 */ , this.y); + //g.drawString('X',this.x,this.y) //} } From 5efc380b83dbf8481c0482139c77c9a442fa16df Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:54:29 +0100 Subject: [PATCH 0214/1839] use inverted icon --- apps.json | 2 +- apps/widChargingStatus/widget.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps.json b/apps.json index 6c223e7d2..9bb299bec 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.8", + "version":"0.1.9", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 120741b27..9fd9bdc01 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -7,17 +7,17 @@ g.flip(); }); - const chargingSymbol = { + const chargingIcon = { width: 16, height: 16, bpp: 1, - transparent: 1, - buffer: require("heatshrink").decompress(atob("/9/AIP+v/8AIP//ABBg/wh4BB8Ef/4BBn/+AIIXB/4BB")) - }; + transparent: 0, + buffer: require("heatshrink").decompress(atob("gGAAIMBwEDAIMAg4BB/EP+ABBj/ggABB4EBAIIXBgABB")) + } function draw() { g.reset(); - //g.setColor("#FD0"); + g.setColor("#FD0"); //if (Bangle.isCharging()) { g.drawImage(chargingSymbol, this.x /* + 2 */ , this.y); //g.drawString('X',this.x,this.y) From 4814120de63d81c1e7840e71dac70d29d56a565e Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 20:56:59 +0100 Subject: [PATCH 0215/1839] draw string --- apps.json | 2 +- apps/widChargingStatus/widget.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 9bb299bec..b29b2717a 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.9", + "version":"0.1.10", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 9fd9bdc01..723a10374 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -18,9 +18,10 @@ function draw() { g.reset(); g.setColor("#FD0"); + g.setFontVector(16); //if (Bangle.isCharging()) { - g.drawImage(chargingSymbol, this.x /* + 2 */ , this.y); - //g.drawString('X',this.x,this.y) + // g.drawImage(chargingIcon, this.x /* + 2 */ , this.y); + g.drawString('X',this.x,this.y) //} } From d3b586635cc380ab9f12d797579c893c80fa7919 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 21:02:14 +0100 Subject: [PATCH 0216/1839] use larger icon --- apps.json | 2 +- apps/widChargingStatus/widget.js | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/apps.json b/apps.json index b29b2717a..8ac5a1de5 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.10", + "version":"0.1.11", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 723a10374..974e08aa7 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -8,26 +8,25 @@ }); const chargingIcon = { - width: 16, - height: 16, + width: 32, + height: 32, bpp: 1, - transparent: 0, - buffer: require("heatshrink").decompress(atob("gGAAIMBwEDAIMAg4BB/EP+ABBj/ggABB4EBAIIXBgABB")) + transparent: 1, + buffer: require("heatshrink").decompress(atob("///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBHwYDC/0AgIyBAYkDIYQDDg4DGh4DCj4DGL45DCAYhyC/oCBA=")) } function draw() { g.reset(); g.setColor("#FD0"); - g.setFontVector(16); //if (Bangle.isCharging()) { - // g.drawImage(chargingIcon, this.x /* + 2 */ , this.y); - g.drawString('X',this.x,this.y) + g.drawImage(chargingIcon, this.x /* + 2 */ , this.y); + //g.drawString('X',this.x,this.y) //} } WIDGETS.chargingStatus = { area: 'tr', - width: 20, + width: 32, draw: draw, }; From 6b8c201ff22bf37c85b07ae060dc53aeb248add4 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 21:08:40 +0100 Subject: [PATCH 0217/1839] use different export technique --- apps.json | 2 +- apps/widChargingStatus/widget.js | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/apps.json b/apps.json index 8ac5a1de5..fc02b21a7 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.11", + "version":"0.1.12", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 974e08aa7..15a9b53f3 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -7,19 +7,11 @@ g.flip(); }); - const chargingIcon = { - width: 32, - height: 32, - bpp: 1, - transparent: 1, - buffer: require("heatshrink").decompress(atob("///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBHwYDC/0AgIyBAYkDIYQDDg4DGh4DCj4DGL45DCAYhyC/oCBA=")) - } - function draw() { g.reset(); - g.setColor("#FD0"); + //g.setColor("#FD0"); //if (Bangle.isCharging()) { - g.drawImage(chargingIcon, this.x /* + 2 */ , this.y); + g.drawImage(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI="), this.x /* + 2 */ , this.y); //g.drawString('X',this.x,this.y) //} } From 9ee26a66efc6827502b9a9b89efbeb6006995c0d Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 21:19:29 +0100 Subject: [PATCH 0218/1839] use 8bit image --- apps.json | 2 +- apps/widChargingStatus/widget.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index fc02b21a7..413f7edef 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.12", + "version":"0.1.13", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 15a9b53f3..0fc1e48d9 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -9,9 +9,9 @@ function draw() { g.reset(); - //g.setColor("#FD0"); + g.setColor("#FD0"); //if (Bangle.isCharging()) { - g.drawImage(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI="), this.x /* + 2 */ , this.y); + g.drawImage(atob("kEgxH+ACEACSIeMD/p1CDzwffH3wfbDwYf6DwgfZDwofgABAeeD74etH3yc+FCAfeDzAflDzIfEDzQfjDzYffH3wfCDzgfBCKAA="), this.x, this.y); //g.drawString('X',this.x,this.y) //} } From 70bb045be059d63ea5ed99e28150973d88c57e45 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:00:07 +0100 Subject: [PATCH 0219/1839] use image with 1bit and without specified color --- apps.json | 2 +- apps/widChargingStatus/widget.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 413f7edef..02c1044fc 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.13", + "version":"0.1.14", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget,battery", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 0fc1e48d9..b0e503b3a 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -9,9 +9,9 @@ function draw() { g.reset(); - g.setColor("#FD0"); + //g.setColor("#FD0"); //if (Bangle.isCharging()) { - g.drawImage(atob("kEgxH+ACEACSIeMD/p1CDzwffH3wfbDwYf6DwgfZDwofgABAeeD74etH3yc+FCAfeDzAflDzIfEDzQfjDzYffH3wfCDzgfBCKAA="), this.x, this.y); + g.drawImage(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI="), this.x, this.y); //g.drawString('X',this.x,this.y) //} } From c7aea28a47f564d79f5e22a5516a36c5d7418546 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:08:07 +0100 Subject: [PATCH 0220/1839] display text --- apps.json | 4 ++-- apps/widChargingStatus/widget.js | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index 02c1044fc..aa57b01c7 100644 --- a/apps.json +++ b/apps.json @@ -4680,10 +4680,10 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.14", + "version":"0.1.15", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", - "tags": "widget,battery", + "tags": "widget", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"chargingStatus.wid.js","url":"widget.js"} diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index b0e503b3a..ed674263e 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -9,10 +9,11 @@ function draw() { g.reset(); - //g.setColor("#FD0"); + g.setColor("#FD0"); + g.setFont("Vector", 26); //if (Bangle.isCharging()) { - g.drawImage(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI="), this.x, this.y); - //g.drawString('X',this.x,this.y) + // g.drawImage(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI="), this.x, this.y); + g.drawString('PWR',this.x,this.y) //} } From 1d7a69ce0ab7a74d923154cd8c05262d8ce6bec5 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:22:22 +0100 Subject: [PATCH 0221/1839] another attempt to use icon correctly --- apps.json | 2 +- apps/widChargingStatus/widget.js | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index aa57b01c7..69fc98957 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.15", + "version":"0.1.16", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index ed674263e..c90a6adb6 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -7,13 +7,15 @@ g.flip(); }); + const icon = require("heatshrink").decompress(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI=")) + function draw() { g.reset(); - g.setColor("#FD0"); - g.setFont("Vector", 26); + g.setColor("#FD0"); + //g.setFont("Vector", 26); //if (Bangle.isCharging()) { - // g.drawImage(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI="), this.x, this.y); - g.drawString('PWR',this.x,this.y) + g.drawImage(icon, this.x, this.y); + //g.drawString('PWR', this.x, this.y) //} } From 6989466aba8fc7ed38f40c3a1af73942a3a178a1 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:26:55 +0100 Subject: [PATCH 0222/1839] export image differently --- apps.json | 2 +- apps/widChargingStatus/widget.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 69fc98957..1c22a48d7 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.16", + "version":"0.1.17", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index c90a6adb6..deff019ae 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -7,7 +7,7 @@ g.flip(); }); - const icon = require("heatshrink").decompress(atob("kEgwMB///34CB/8/AYv+AYX8AYd/AYP4AY3wAY3gAYXAAYcAEAOAAYgMBIQIPBAYX+gBGB/gDEgZDCAYcHAY0PAYUfAYxfHIYQDEOQX9AQI=")) + const icon = require("heatshrink").decompress(atob("kEggIEBoAIC4ADFgIDCgYDDwADBg4DGh4DGj4DCn4DD/4gBv4DEBgP//4PBAYUB//+GQIDE/hDCAYf4AY3wAYXgAYxfHIYQDEOQUCAQI")); function draw() { g.reset(); From 1a320a56c752b75e5ad63265270ae70ec6434c40 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:30:02 +0100 Subject: [PATCH 0223/1839] scale icon --- apps.json | 2 +- apps/widChargingStatus/widget.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index 1c22a48d7..736e010c4 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.17", + "version":"0.1.18", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index deff019ae..9978d0ef9 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -12,16 +12,16 @@ function draw() { g.reset(); g.setColor("#FD0"); - //g.setFont("Vector", 26); //if (Bangle.isCharging()) { - g.drawImage(icon, this.x, this.y); - //g.drawString('PWR', this.x, this.y) + g.drawImage(icon, this.x, this.y + 2, { + scale: 0.8125 + }); //} } WIDGETS.chargingStatus = { area: 'tr', - width: 32, + width: 26, draw: draw, }; From cf36400faa5f05e4a10a5546cbcc247a68c48edf Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:37:16 +0100 Subject: [PATCH 0224/1839] prepare first release --- apps.json | 2 +- apps/widChargingStatus/ChangeLog | 2 +- apps/widChargingStatus/widget.js | 34 ++++++++++++++++---------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/apps.json b/apps.json index 736e010c4..880c17660 100644 --- a/apps.json +++ b/apps.json @@ -4680,7 +4680,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.18", + "version":"0.1.0", "type": "widget", "description": "A simple widget that shows up whenever the watch starts charging.", "tags": "widget", diff --git a/apps/widChargingStatus/ChangeLog b/apps/widChargingStatus/ChangeLog index d3175e1ab..16675015d 100644 --- a/apps/widChargingStatus/ChangeLog +++ b/apps/widChargingStatus/ChangeLog @@ -1 +1 @@ -0.1: First release. \ No newline at end of file +0.1.0: First release. \ No newline at end of file diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 9978d0ef9..686a120db 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -1,30 +1,30 @@ (() => { - Bangle.on('charging', (charging) => { - if (charging) { - Bangle.buzz(); - } - Bangle.drawWidgets(); // re-layout widgets - g.flip(); - }); - const icon = require("heatshrink").decompress(atob("kEggIEBoAIC4ADFgIDCgYDDwADBg4DGh4DGj4DCn4DD/4gBv4DEBgP//4PBAYUB//+GQIDE/hDCAYf4AY3wAYXgAYxfHIYQDEOQUCAQI")); function draw() { g.reset(); - g.setColor("#FD0"); - //if (Bangle.isCharging()) { - g.drawImage(icon, this.x, this.y + 2, { - scale: 0.8125 - }); - //} + if (Bangle.isCharging()) { + g.setColor("#FD0"); + g.drawImage(icon, this.x, this.y + 1, { + scale: 0.6875 + }); + } } WIDGETS.chargingStatus = { area: 'tr', - width: 26, + width: 22, draw: draw, }; - - + Bangle.on('charging', (charging) => { + if (charging) { + Bangle.buzz(); + WIDGETS.chargingStatus.width = 22; + } else { + WIDGETS.chargingStatus.width = 0; + } + Bangle.drawWidgets(); // re-layout widgets + g.flip(); + }); })(); \ No newline at end of file From 9ad0ccd1bfbc03b8ae9a7a235e2ea7679c43f6f6 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:47:27 +0100 Subject: [PATCH 0225/1839] make width smaller, default to not having width --- apps.json | 2 +- apps/widChargingStatus/widget.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index 880c17660..fd788f8d3 100644 --- a/apps.json +++ b/apps.json @@ -4682,7 +4682,7 @@ "icon": "widget.png", "version":"0.1.0", "type": "widget", - "description": "A simple widget that shows up whenever the watch starts charging.", + "description": "A simple widget that shows a yellow lightning icon to indicate whenever the watch is charging. This way one can see if the watch is charging at a glance, no matter which battery widget is being used.", "tags": "widget", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 686a120db..a4c862101 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -1,5 +1,5 @@ (() => { - const icon = require("heatshrink").decompress(atob("kEggIEBoAIC4ADFgIDCgYDDwADBg4DGh4DGj4DCn4DD/4gBv4DEBgP//4PBAYUB//+GQIDE/hDCAYf4AY3wAYXgAYxfHIYQDEOQUCAQI")); + const icon = require("heatshrink").decompress(atob("ikggMAiEAgYIBmEAg4EB+EAh0AgPggEeCAIEBnwQBAgP+gEP//x///j//8f//k///H//4BYOP/4lBv4bDvwEB4EAvAEBwEAuA7DCAI7BgAQBhEAA")); function draw() { g.reset(); @@ -13,14 +13,14 @@ WIDGETS.chargingStatus = { area: 'tr', - width: 22, + width: Bangle.isCharging() ? 20 : 0, draw: draw, }; Bangle.on('charging', (charging) => { if (charging) { Bangle.buzz(); - WIDGETS.chargingStatus.width = 22; + WIDGETS.chargingStatus.width = 20; } else { WIDGETS.chargingStatus.width = 0; } From 14d1b23bd49184e8920558975bba28e9ac3425ce Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 22:51:40 +0100 Subject: [PATCH 0226/1839] give some breathing space to icons on the left --- apps.json | 2 +- apps/widChargingStatus/widget.js | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index fd788f8d3..1432eee96 100644 --- a/apps.json +++ b/apps.json @@ -4682,7 +4682,7 @@ "icon": "widget.png", "version":"0.1.0", "type": "widget", - "description": "A simple widget that shows a yellow lightning icon to indicate whenever the watch is charging. This way one can see if the watch is charging at a glance, no matter which battery widget is being used.", + "description": "A simple widget that shows a yellow lightning icon to indicate whenever the watch is charging. This way one can see the charging status at a glance, no matter which battery widget is being used.", "tags": "widget", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index a4c862101..90f9199fa 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -1,11 +1,12 @@ (() => { const icon = require("heatshrink").decompress(atob("ikggMAiEAgYIBmEAg4EB+EAh0AgPggEeCAIEBnwQBAgP+gEP//x///j//8f//k///H//4BYOP/4lBv4bDvwEB4EAvAEBwEAuA7DCAI7BgAQBhEAA")); + const iconWidth = 18; function draw() { g.reset(); if (Bangle.isCharging()) { g.setColor("#FD0"); - g.drawImage(icon, this.x, this.y + 1, { + g.drawImage(icon, this.x + 1, this.y + 1, { scale: 0.6875 }); } @@ -13,14 +14,14 @@ WIDGETS.chargingStatus = { area: 'tr', - width: Bangle.isCharging() ? 20 : 0, + width: Bangle.isCharging() ? iconWidth : 0, draw: draw, }; Bangle.on('charging', (charging) => { if (charging) { Bangle.buzz(); - WIDGETS.chargingStatus.width = 20; + WIDGETS.chargingStatus.width = iconWidth; } else { WIDGETS.chargingStatus.width = 0; } From 4fd2ab6d6a05ff160fb63731e1e72d02718417a0 Mon Sep 17 00:00:00 2001 From: Sebastian Di Luzio Date: Sat, 4 Dec 2021 23:07:43 +0100 Subject: [PATCH 0227/1839] fix id and versioning --- apps.json | 4 ++-- apps/widChargingStatus/ChangeLog | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 1432eee96..59b3892a5 100644 --- a/apps.json +++ b/apps.json @@ -4680,13 +4680,13 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.1.0", + "version":"0.1", "type": "widget", "description": "A simple widget that shows a yellow lightning icon to indicate whenever the watch is charging. This way one can see the charging status at a glance, no matter which battery widget is being used.", "tags": "widget", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ - {"name":"chargingStatus.wid.js","url":"widget.js"} + {"name":"widChargingStatus.wid.js","url":"widget.js"} ] } ] diff --git a/apps/widChargingStatus/ChangeLog b/apps/widChargingStatus/ChangeLog index 16675015d..d3175e1ab 100644 --- a/apps/widChargingStatus/ChangeLog +++ b/apps/widChargingStatus/ChangeLog @@ -1 +1 @@ -0.1.0: First release. \ No newline at end of file +0.1: First release. \ No newline at end of file From 45a292bc5d6b08096d819eb8261ae43de7cb00f0 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sat, 4 Dec 2021 22:13:44 +0100 Subject: [PATCH 0228/1839] new custom menu: menuwheel --- apps.json | 18 +++ apps/menuwheel/ChangeLog | 1 + apps/menuwheel/README.md | 25 +++ apps/menuwheel/boot.js | 213 +++++++++++++++++++++++++ apps/menuwheel/icon.png | Bin 0 -> 880 bytes apps/menuwheel/screenshot_b1_dark.png | Bin 0 -> 4610 bytes apps/menuwheel/screenshot_b1_edit.png | Bin 0 -> 4203 bytes apps/menuwheel/screenshot_b1_light.png | Bin 0 -> 4183 bytes apps/menuwheel/screenshot_b2_dark.png | Bin 0 -> 2905 bytes apps/menuwheel/screenshot_b2_edit.png | Bin 0 -> 2636 bytes apps/menuwheel/screenshot_b2_light.png | Bin 0 -> 2567 bytes 11 files changed, 257 insertions(+) create mode 100644 apps/menuwheel/ChangeLog create mode 100644 apps/menuwheel/README.md create mode 100644 apps/menuwheel/boot.js create mode 100644 apps/menuwheel/icon.png create mode 100644 apps/menuwheel/screenshot_b1_dark.png create mode 100644 apps/menuwheel/screenshot_b1_edit.png create mode 100644 apps/menuwheel/screenshot_b1_light.png create mode 100644 apps/menuwheel/screenshot_b2_dark.png create mode 100644 apps/menuwheel/screenshot_b2_edit.png create mode 100644 apps/menuwheel/screenshot_b2_light.png diff --git a/apps.json b/apps.json index a312b90a3..d5e84f9dd 100644 --- a/apps.json +++ b/apps.json @@ -4675,5 +4675,23 @@ "data": [ {"name":"pooqroman.json"} ] + }, + { + "id": "menuwheel", + "name": "Wheel Menus", + "version": "0.01", + "description": "Replace Bangle.js 2's menus with a version that contains variable-size text and a back button", + "readme": "README.md", + "icon": "icon.png", + "screenshots": [ + {"url":"screenshot_b1_dark.png"},{"url":"screenshot_b1_edit.png"},{"url":"screenshot_b1_light.png"}, + {"url":"screenshot_b2_dark.png"},{"url":"screenshot_b2_edit.png"},{"url":"screenshot_b2_light.png"} + ], + "type": "boot", + "tags": "system", + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"menuwheel.boot.js","url":"boot.js"} + ] } ] diff --git a/apps/menuwheel/ChangeLog b/apps/menuwheel/ChangeLog new file mode 100644 index 000000000..defdb5049 --- /dev/null +++ b/apps/menuwheel/ChangeLog @@ -0,0 +1 @@ +0.01: New menu! diff --git a/apps/menuwheel/README.md b/apps/menuwheel/README.md new file mode 100644 index 000000000..22cb49466 --- /dev/null +++ b/apps/menuwheel/README.md @@ -0,0 +1,25 @@ +# Wheel Menu + +Replace Bangle.js 2's menus with a version that contains variable-size text and a back button. + +Bangle.js 1: +![Dark Mode Screenshot](screenshot_b1_dark.png) +![Light Mode Screenshot](screenshot_b1_light.png) + +Bangle.js 2: +![Dark Mode Screenshot](screenshot_b2_dark.png) +![Editing Screenshot](screenshot_b2_edit.png) +![Light Mode Screenshot](screenshot_b2_light.png) + + +## Features + +If the menu contains "Back" or "Exit", it is shown as a button instead. +The menu wraps around, with a divider between the last and first items. + +## Controls + +Bangle.js 1: Use BTN1/BTN3 to scroll through items, BTN2 to open/edit the selected item. +Bangle.js 2: Swipe up/down to scroll through items, tap/BTN to open/edit the selected item. + +Press the back button (if present) to go back. \ No newline at end of file diff --git a/apps/menuwheel/boot.js b/apps/menuwheel/boot.js new file mode 100644 index 000000000..3e708e9a8 --- /dev/null +++ b/apps/menuwheel/boot.js @@ -0,0 +1,213 @@ +E.showMenu = function(items) { + g.clearRect(Bangle.appRect); // clear screen if no menu supplied + // clean up back button listener + if (Bangle.backHandler) Bangle.removeListener('touch', Bangle.backHandler) + delete Bangle.backHandler; + if (!items) { + Bangle.setUI(); + return; + } + + var B2 = process.env.HWVERSION===2, + loc = require("locale"), + menuItems = Object.keys(items), + options = items[""]; + if (options) menuItems.splice(menuItems.indexOf(""),1); + if (!(options instanceof Object)) options = {}; + + // show "< Back" item (or similar) as button instead (i.e. remove from the menu) + var back,backLbl; + for (var b of ['Back', 'Exit', 'Cancel']) { + if (!items[b] && items['< '+b]) b = '< '+b; + back = items[b]; + if (typeof back === "function") { + backLbl = loc.translate(b); + menuItems.splice(menuItems.indexOf(b),1); + break; + } + else back = undefined; + } + // font sizes + var small = B2?15:22, + large = B2?30:45; + if (options.selected === undefined) options.selected = 0; + var ar = Bangle.appRect, + x = ar.x, + x2 = ar.x2, + w = ar.w, + y = ar.y, + y2 = ar.y2; + if (options.title) y += 22; + var wrap = menuItems.length>3; // don't wrap if all items are always in view anyway + + var vc=Math.round((y+y2)/2), // vertical center + hc = Math.round((x+x2)/2), // horizontal center + ih = large+small*2; // active item height + + var getItem = idx => { + // we wrap out-of-range indexes + while (idx<0) idx+=menuItems.length; + idx = idx%menuItems.length; + var name = menuItems[idx]; + var item = items[name]; + var v; + if ("object"== typeof item) { + v = item.value; + if (item.format) v = item.format(v); + v = loc.translate(""+v); + } + return {lbl: loc.translate(name), v: v}; + }; + var l = { + lastIdx : null, // we want a complete redraw on first run + draw : function() { + var idx = options.selected, + edit = l.selectEdit; + g.reset(); + + // don't highlight whole item when editing + g.setColor(edit?g.theme.fg:g.theme.fgH) + .setBgColor(edit?g.theme.bg:g.theme.bgH) + .setFont('Vector', large); + var item = getItem(idx), + lw = g.stringWidth(item.lbl)+2; + if (lw+2 >= w) { // label width doesn't fit at large size: scale it down + g.setFont('Vector', Math.floor(large*ar.w/lw)); + } + g.clearRect(x,vc-ih/2,x2,vc+ih/2) + .setFontAlign(0,0,0).drawString(item.lbl,hc,vc); + + if (item.v !== undefined) { + g.setColor(g.theme.fgH).setBgColor(g.theme.bgH) // always highlighted: either as part of item, or while editing + .setFontAlign(0,1,0) + .setFont('Vector', small) + .clearRect(x,vc+ih/2-small-2,x2,vc+ih/2) + .drawString(item.v,hc,vc+ih/2-1); + if (edit) { + g.drawImage("\x0c\x05\x81\x00 \x07\x00\xF9\xF0\x0E\x00@",x2-23,vc+ih/2-small+(B2?1:5),{scale:2}); + } + } + if (l.lastIdx !== idx) { + // we scrolled: redraw all + l.lastIdx=idx; + g.reset(); + + if (options.title) { + if (B2) g.setFont('12x20'); + else g.setFont('6x8',2); + g.drawLine(x, y-2, x2, y-2) + .setFontAlign(0,1,0) + .drawString(options.title, (x+x2)/2, y-2); + } + + // clear prev/next items area + g.clearRect(x,y,x2,vc-ih/2-1) + .clearRect(x,vc+ih/2+1,x2,y2); + + // get display label by index + var lbl = idx => { + var item = getItem(idx); + if (item.v !== undefined) item.lbl+=': '+item.v; + return item.lbl; + } + // previous two items + g.setFontAlign(0, 1) + if (wrap||idx>0) g.setFont('Vector', small).drawString(lbl(idx-1), hc, vc-ih/2-5); + if (wrap||idx>1) g.setFont('Vector', small/2).drawString(lbl(idx-2), hc, vc-ih/2-small-10); + // next two items + g.setFontAlign(0, -1); + if (wrap||idx g.drawLine(x, y, x2, y); + if (idx===0) div(vc-ih/2-1); + if (idx===1) div(vc-ih/2-small-8); + // if (s === 2) div(vc-ih/2-small*1.5-13); + if (idx===menuItems.length-1) div(vc+ih/2+1); + if (idx===menuItems.length-2) div(vc+ih/2+small+6); + // if (s === 2) div(vc+ih/2+small*1.5+13); + } + + if (back) { + g.setBgColor(g.theme.bg2) + .setFont('Vector', small); + var bw=g.stringWidth(backLbl); + g.clearRect(x,y, x+bw+2, y+small+2); + var bx1=x, by1=y, bx2=x+bw+2, by2=y+small+2; + // g.drawRect(x,y, x+bw+2, y+small+2); + var poly = [ // button outline + bx1+2,by1, + bx2-2,by1, + bx2, by1+2, + bx2, by2-2, + bx2-2,by2, + bx1+2,by2, + bx1, by2-2, + bx1, by1+2, + ] + g.setColor(g.theme.bg2).fillPoly(poly, true) + .setColor(g.theme.fg2).drawPoly(poly, true) + .setFontAlign(-1,-1,0).drawString(backLbl, x+2,y+2); + } + } + g.flip(); + }, + select : function() { // same as default menu + var item = items[menuItems[options.selected]]; + if ("function" == typeof item) {l.lastIdx=null; item(l);} // force a redraw after callback + else if ("object" == typeof item) { + // if a number, go into 'edit mode' + if ("number" == typeof item.value) + l.selectEdit = l.selectEdit?undefined:item; + else { // else just toggle bools + if ("boolean" == typeof item.value) item.value=!item.value; + if (item.onchange) {l.lastIdx=null; item.onchange(item.value);} // force a redraw after callback + } + l.draw(); + } + }, + move : function(dir) { + if (l.selectEdit) { // same as default menu + var item = l.selectEdit; + item.value -= (dir||1)*(item.step||1); + if (item.min!==undefined && item.valueitem.max) item.value = item.wrap ? item.min : item.max; + if (item.onchange) {l.lastIdx=null; item.onchange(item.value);} // force a redraw after callback + } else { + if (B2) dir=-dir; // swipe vs button scrolling + if (!wrap && (options.selected+dir<0 || options.selected+dir>=menuItems.length)) { + return; + } + options.selected = (options.selected+dir+menuItems.length)%menuItems.length; + } + l.draw(); + } + }; + l.draw(); + Bangle.setUI("updown",dir => { + if (dir) l.move(dir); + else l.select(); + }); + if (back) { + // we have a back button: check touches before passing them to setUI's touchHandler + if (B2) { + Bangle.removeListener('touch', Bangle.touchHandler); + Bangle.backHandler = (b, xy) => { + // anywhere top-left (but above the active item) = back button + if (xy.x { + // left side = back button + if (b===1) back(); + } + } + // note: backHandler is cleaned up at the top of this file + Bangle.on('touch', Bangle.backHandler); + } + return l; +}; diff --git a/apps/menuwheel/icon.png b/apps/menuwheel/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..61f94a035078db81a386a8a42af3c00f16e91614 GIT binary patch literal 880 zcmW-fJ!lnC5QWdvC?+9-l@csO!Ad1C+K3Pn67vEk#Ag~)Jqe6$F#eIoAo4&`*aUGv zBq;iQ)9r~4_eg#A z?dIM6*1yHocWrEDOnUWj@ZZ%v#I5Dd)OhRb#}ju6jx4r2Gt$a&Y4yJJmrtudq?@4p z>`G@JO9z*pY+pJj?OL0=I6wJb%6dv>WO}A$sz#+`i7cMQvZyAbWJHE%ScYn?m-I;Y zbW2xlwUQQTo@QwRDOFOD@|2|rzy=yDnyFTuQ%{uQrC2GdV~HY4cnK?^%7UavaW8Jg zRY_56QOt{3F~O16qA2nrD`G0F0fRIwp+%0tU;_;n&8mWG%<%||P}Rp+BKL3$SCtD3 zlICF+Ce%ZU+K`7VggpF!Cf(S9en_AY)__48mXyMS!C(Uoma20#P0TTORU^^ISRykw z;VW`sLDFR|e8g!CfEVQ$jasb44`|Yj9dJT03SkWxr0IkfJQxf%(5fq{)uf3zVq+MI zKE@Ime^2u_RJqN9*=XHov!qI@@x89Mv9fY(+^O4c1Xs$9hPwQQR#nhU0var~gn4LU z)QjamYh0}xo!QGe|NRS})xXrfvMilCR-e|LXQQ|HcxHNHY`*(hNZ?VW|A@1FM#JUZRG{b^+3_5RNb>ldV7hezM8|K1t|K+}`66EDZR G_x=N44umcM literal 0 HcmV?d00001 diff --git a/apps/menuwheel/screenshot_b1_dark.png b/apps/menuwheel/screenshot_b1_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c6dfb802b1bc3cc46ff9710f07c20ba6758a7c0d GIT binary patch literal 4610 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 Jr5W!2zX4`DYqS6W literal 0 HcmV?d00001 diff --git a/apps/menuwheel/screenshot_b1_light.png b/apps/menuwheel/screenshot_b1_light.png new file mode 100644 index 0000000000000000000000000000000000000000..35ac01fe972f46b7c9cd4f51e891210ef3220810 GIT binary patch literal 4183 zcmds5`8(8Y)E{3XgD^v@WlYv&7f%>tDK$x`QH7;{8?@m21BB(tt>A@c`W3PP?$%gU?ZqF?oRxI z>Dk-%l{gcs-nsqSHx+r8oe;0fj|dTB7Dx(D70f-igaPCb1v&;FEf0Zr^zQwKKbp?y)c?#b(i&_)- zZkb`l78ZT8mpB|yg!K!!A(Ohoa_}LTNn*?{S;OP<`Ux$rB{k%X+f|=;V7=b|?mojh zVr6Zl{+J<8#5Nm{=YAtFq2|;dSx90^5(o(JgHE0jDg6D=m7!Fzha-q^UQUJq<~^bm zBx9~OYWDfVi{FLQ%6!0ojWU$b(Yaw(D*avHOgwD1%tnzbNaKk{-*Kt;)Hnc`pIfoy zn=qwk#lVC7o7?5fNPsW^%cEql+cNB^7969S3Bz)|ptF)-I=qQ)W**0ZSa@ye;Kgp% zI+y1Qe=~P?c5C077RSjUB(r5JtvTut_r^-$+A)w+GT3fE8D9CG$74B9)uy^)deR{` zFsOZ{z_+$NKT!z8Rv&V>E>ft(eGHyLld7vWkx}rA({g9Ma3D*>{E!|X8Df~PU+ZAZqPB19Z) zxr{)=c+NWcfG6E$_S@N8nSAh-l;kLu)RY2N=DVCc__HmRJ7{P|V`9Rsj z=_wk2y!fS%cD?oj`R6>8@8Qjb0YR~M>{5qmxsDZBC2m5*pB)2;55UZ*Cmmbn_&P`q zC}HTdRvZwZLy_rt(O}&1j5x)>EVbBF?XCG%RCHO0nXX&|q?P7k_7{y)Pcy1CSF%

P8u>Ns5%r~m0zRXO?^ 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 NHkS4lRc7Sd{|4C5NoW87 literal 0 HcmV?d00001 diff --git a/apps/menuwheel/screenshot_b2_edit.png b/apps/menuwheel/screenshot_b2_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..bca98a9a5401dfc21ad5bac060a1ff5aaa82c989 GIT binary patch literal 2636 zcmbuBYc$mR8pnS#V`emi3ArQ|8RGTZ-eXv(C%2)>-Ggc%JWz?^@5BXFZ?q^M|W5K^mii z0RTv!JYnayt#$t_Nz`_)ZTR4`EwGDj1RGHEO7$ZE7}QBS>(ex!`Qq0xEOn{lW?NgY zpL7@YkGrX(TVJ=27Ss?W#{>85n|V1oJ3G7ar`oQ_2M~f$Y%kNm!~lJDE)g)iQ*k1g zGU}`@fNI)OKLaU5jRNo+9B+#SS7Cz~P&X?cHwSHuP$YQw+gc=^;SX`(V9u0of`jyh zBp8UbZRMGt2~@J5WMC*D(DW!JRvo;lI~I6kQ&p0bU`F);l2~4;%N-T2c__BWb8=4gskc zdQcQpgnYSBWC>57#QvgVlvhNo{DUA0;j}C*lHt5)w6*l712B9s(==80F~Uzn2Sd-_ z{jB4GloUiX)VnkSZySzryC0Cj?m_`wht0A5b|`$~+DxlSK*(vz)DJh2?}pt@)0K+{ zhvsboE4)mL?XDg=(U3nzV&;^Sjz&?)48F4i?rY9^vGjysu?_G%z}NNdWhQhktOyX| zd0FvK0BmHA%|E$JU#Ld%*2e^^ z?)x(fne0&gX|GsB9cpD(wWdH}U2i|gLYGTN`p6yJ{RqjYl<0xT!l;XpH`2*i`6FTz zUT?ctw6BI0q(Jixo$0>9OTf((wNys*ruGNVM+}Ipdq_hMSK2+h?(6gcbLDjAbOd8H z`IhhZ26~0{DEwWM^2?+P#fE4Y&m|ykZzaUu&CM^Y{-rukQv1zdSMGpTch1bYcv8}2 zs8Axx3;)PLT0v;IZ15f~Hr#bbO0^lw)jQ z;Fr19?pn@w=>?(#{J(VMzAG;O1c(LuyEN!FjT7r{M4k%PwSj z$BxK2(;s1lmPESk z0cFSvj4w{EyTcp$o-un-Y2WiKWWjGdiQYXB^~!2tI#^q{5$}ciQZq-0(O}J0evl32 zJB8ja-9v&LB)-yz1( zJOUT`uTFW)uVF0B%T!f_M8(HeACafmxtFom?qu*H))mn>fh3a-P!&eb|%(+$Djn`S#}L0 zWZ7u=`R^4bPShUYDOKoZ?`frN6isEBMe%79Z_gSdgh^s;KyuYKy6y%GL7?_^y(IE3Zo z6%*>^5z4p7_EMtMALumYSVsIIH}SU=R~W}YjJJx{vNh$`VJaV zL-$y$TUbd*t?lDyL=W5?u_hSGgqky8Q2dRUJ{P13T7yaaNweV1t3wkc$M2GXPnt#_ z3@yYQCP?4DQ07H_8mB~2Ea5MbPP%sEz_%8iaac^<3E@Nv9GGk1y?Z?Xqc;nN|7Dvl z@)NI@=}55lO<3Mzl33g}>n-MK0fDv5su42?SBH9?cc*-B*dRuCvSn?O7Xqw;bq96U_%B vpayI#YX>5dMH7S@0eW+GXOaHDtj{>R!WL)!MS{-udk9V*cebms@k{;(%;URD literal 0 HcmV?d00001 diff --git a/apps/menuwheel/screenshot_b2_light.png b/apps/menuwheel/screenshot_b2_light.png new file mode 100644 index 0000000000000000000000000000000000000000..4ffe08fe35f376e8eecd9c5fedbde53df07669de GIT binary patch literal 2567 zcmcIm`#Y5D8h&Rq#*AZFvMmj=P?)faB*&a$oEnFQk@aCw873m9k|7mIv$PmHEgi|3 zVa$&ge$?@@WmB(w~ z0RZxDC!EMgWdCQ$NF#fF^Hc~DQ1N8f-_TOFT1 z8^k>A4L@n$x5-`an9%;%f5+jSmlkhE{N<&cD#b4Y3rvcScI^ZJ1}gL%1|-j}?zRTq zFdq*@{8`;(a6O~!J0L6@auoqNDUuO@N##r-N?n?T+$i$W>Xb5-Gp+@|q{KE83#n6r zP$0xAZI>c!%I2U!TY^M}zzBu@2jW;wnAzK1z#iQSIY^!S8g?f-doT{n7>;UVggPG2 z^)bREXI7OlXr*X`$-%&SS6hV}Y7E4>eGYo_y0^3`NNaNL2>xc_HejP5+NG0GM_1}c zcTB#pC8u$16%^F7-NI97GMjUyC2}5P<=Jj=UUmQP5)=gP7kc^z136gVC(;}(gcw{W zl0dtGqomeRJaGGgRIDk?S{h#?%q8w>xaf(TtNrX@roccY}=eSYchj+E&RPE@}-(7+BaP=;Mqyb>jRGf;N@c< zpY;>2ZJBS^PPr_rTZEttMVp#R4mZ%udO>T6g30f4X?CRK(m(I~!s}g@5*^IzxwIE- zr^H6y{jj{YcA5SL^Q|U3{l zwPV42Xz1~;wxgHH8C1X1i5`Cwa`f1Ke<@Q&na(2YI9wjwUPMR#fcjxrs=OHAj$zn_MaPh#gk!FV zI$O4$McC9#t!`F2X(PhKO%e)%8VgPnK~9D zA3JN)#%i8PZhR-ceu8$3HCngc^C57_qlx;>GGf7*pRcsR2+wO+t=<&$UfrnV8r;77 zaJ8p#O_4KN6;Pbagzm&BTC)C-TylQU*1Zq&?JVO#epy9PmT)=g#an9);Zn7@H=X+u z9qTRE*(jK!&kJ(IAb8%nj91!`GDyZfF*F5&=jRvi*06>-UFXs&6900aSIYsNYQ-sDF=gMs>4H`ug#V)vM{g&kzj8m$7 zObxACgUS8_M;>x?M(s`X|IkIP@925ZWC!DAL*M?)n&+q+k1RKu!}FyXC#Z;^1E$rF zTtfqEXAPOh{wP5Aza8hhAHcq)8QMYr4Hj+O@G6(d)%Jm(0`M-OD~gQx1;0m$<%t4K zvsrISkpeHx(J{V<2GK*fYBz+(O~sL7fdOMrRRVrB1n{r=*V)l{!1gq#(f0=o15dfo zx2gcT=SA_X0>Haiy{qv6fGtYc#eOJo|FBtBgfC#kScRHbB2PURCe#1a-WpzN&i>{l z5WBwHm*$r0Bw?=l_n)@)9vG>5p_iCDV8j}JZPk(IKZs}e2Bz+6)__c>ZrmN&;l#ca1-&`$*RA=smGQELA-lZmr zaM?QiJu`9%L!nWv#{;5g=sKBdfeB9#IK8x9hEaBdE9P~cGdn`hFY^LA;z=Pgc(yCCdD>z%&9d;sbz=I zxxVoSJa|t|t(c*q>O?gmO%g&A)3;rI*coOD>^R>~iFh^<-Ydp#?5=lG?8EE){vXqs z(!}pNE~*r+j)11A12^l-QXx-uS?k$Ms*z~g5k08fZ3v1a5TL)m62hRBhtV)}n?PEF zg}dm?-y^y?oa6Tm+(T3sgId{jE%k#@T@rx0W zY1%g5$5Um&J~Gekd7h;*)E}=c_%Nc9)L-aL>>LC|Bh!OUt##tf#xA3^ffQ5)YB8sB zXkARqGO%Ab7NG`5iJdn`wKo&OUfc_y<-4bzn-^K*tmQ0YMzNG*M@N;ovAtr)n@Wt*>cVfnrFH+2N;_)$_>ay8j%LhH6))aJ6eWECT<+r#n^65r+yC3ht{t zQv2x#`zL8Jm{|F+N<*rG7uU6ZZTG Date: Sat, 4 Dec 2021 20:33:43 -0500 Subject: [PATCH 0229/1839] Add new Weather Clock clock face. --- apps.json | 16 +++ apps/weatherClock/ChangeLog | 1 + apps/weatherClock/README.md | 19 +++ apps/weatherClock/app-icon.js | 1 + apps/weatherClock/app.js | 136 ++++++++++++++++++ apps/weatherClock/app.png | Bin 0 -> 3259 bytes .../icons/icons8-cloud-lightning-48.png | Bin 0 -> 1166 bytes apps/weatherClock/icons/icons8-clouds-48.png | Bin 0 -> 654 bytes apps/weatherClock/icons/icons8-error-48.png | Bin 0 -> 683 bytes .../icons/icons8-partly-cloudy-day-48.png | Bin 0 -> 950 bytes apps/weatherClock/icons/icons8-rain-48.png | Bin 0 -> 863 bytes .../icons/icons8-snow-storm-48.png | Bin 0 -> 1153 bytes apps/weatherClock/icons/icons8-sun-48.png | Bin 0 -> 725 bytes apps/weatherClock/screens/screenshot1.png | Bin 0 -> 3182 bytes apps/weatherClock/screens/screenshot2.png | Bin 0 -> 3145 bytes 15 files changed, 173 insertions(+) create mode 100644 apps/weatherClock/ChangeLog create mode 100644 apps/weatherClock/README.md create mode 100644 apps/weatherClock/app-icon.js create mode 100644 apps/weatherClock/app.js create mode 100644 apps/weatherClock/app.png create mode 100644 apps/weatherClock/icons/icons8-cloud-lightning-48.png create mode 100644 apps/weatherClock/icons/icons8-clouds-48.png create mode 100644 apps/weatherClock/icons/icons8-error-48.png create mode 100644 apps/weatherClock/icons/icons8-partly-cloudy-day-48.png create mode 100644 apps/weatherClock/icons/icons8-rain-48.png create mode 100644 apps/weatherClock/icons/icons8-snow-storm-48.png create mode 100644 apps/weatherClock/icons/icons8-sun-48.png create mode 100644 apps/weatherClock/screens/screenshot1.png create mode 100644 apps/weatherClock/screens/screenshot2.png diff --git a/apps.json b/apps.json index a312b90a3..84967e350 100644 --- a/apps.json +++ b/apps.json @@ -4675,5 +4675,21 @@ "data": [ {"name":"pooqroman.json"} ] + }, + { + "id": "weatherclk", + "name": "Weather Clock", + "version": "0.01", + "description": "A clock which displays current weather conditions.", + "icon": "app.png", + "screenshots": [{"url":"screens/screenshot1.png"}], + "type": "clock", + "tags": "clock, weather", + "supports": ["BANGLEJS","BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"weatherclk.app.js","url":"app.js"}, + {"name":"weatherclk.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/weatherClock/ChangeLog b/apps/weatherClock/ChangeLog new file mode 100644 index 000000000..2286a7f70 --- /dev/null +++ b/apps/weatherClock/ChangeLog @@ -0,0 +1 @@ +0.01: New App! \ No newline at end of file diff --git a/apps/weatherClock/README.md b/apps/weatherClock/README.md new file mode 100644 index 000000000..904909f6d --- /dev/null +++ b/apps/weatherClock/README.md @@ -0,0 +1,19 @@ +# Weather Clock + +A clock which displays the current weather conditions. Temperature, wind speed, and an icon indicating the weather conditions are displayed. + +Standard widgets are displayed. + +## Requirements + +**This clock requires Gadgetbridge and the weather app in order to get weather data!** + +See the [Bangle.js Gadgetbridge documentation](https://www.espruino.com/Gadgetbridge) for instructions on setting up Gadgetbridge and weather. + +![Screenshot](screens/screenshot1.png) + +![Screenshot2](screens/screenshot2.png) + +## Creator + +James Gough diff --git a/apps/weatherClock/app-icon.js b/apps/weatherClock/app-icon.js new file mode 100644 index 000000000..e289f6c8b --- /dev/null +++ b/apps/weatherClock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkE/4A/AH4A/ADEzAgk/AogACn/zAgYLBmMACAQEBgMvAwUQgAABj8wAgUD//yAgIQFBQIXFl4XFmETC4QcBn8xgQXDGgYACmAXBmQMBC4UB//zAQJoBC4JmE/8gj4kDC48Qn8QJAIxEBIIXFCgM/+IXELIIGBBwYcEAYcBCARHCiczNIINB+JrDC4inBFAjKCLQZ2CC4zRCHYgXFkBkFKAUSPQYABkJEBVQZ2DmUigEikfzgESiA7BkU/mEBkJfCOwjdFL4QnBEwL8CHIJ2F+ciAAI6CmUjAYRmCAwQSBbgoA/AG3zXoMvkMv+Uj+U/mcxBYP/kciTQMimKRCBYPyj/xXIMydYMvmKqBUYIWBkcyC4bmBmMT+P/C4Uzn/xEYXziYXBkYnBbAczmfyC4MT+bWBkMiiQKBiUyAoMhj6RzMgYASn3dmazIAYYmG/ve93dC48iCYMzAYQXF93u9oXIl4uBAQIAFCwIAB74XKkYvGIwIXJYQIDCC43+I4QKFAoh6Cn4IEO4RfF+QtDGQcTMQn97oABC4si+cRkcikIUBAQQAE6a8GiXzkUykUiZgMjj7gNEwMzXoLWCL4oANCSQAl")) \ No newline at end of file diff --git a/apps/weatherClock/app.js b/apps/weatherClock/app.js new file mode 100644 index 000000000..340d5d723 --- /dev/null +++ b/apps/weatherClock/app.js @@ -0,0 +1,136 @@ +const Layout = require("Layout"); +const storage = require('Storage'); +const locale = require("locale"); + +// weather icons from https://icons8.com/icon/set/weather/color +var sunIcon = require("heatshrink").decompress(atob("mEwwhC/AH4AbhvQC6vd7ouVC4IwUCwIwUFwQwQCYgAHDZQXc9wACC6QWDDAgXN7wXF9oXPCwowDC5guGGAYXMCw4wCC5RGJJAZGTJBiNISIylQVJrLCC5owGF65fXR7AwBC5jvhC7JIILxapDFxAXOGAy9KC4owGBAQXODAgHDC54AHC8T0FAAQSOGg4qPGA4WUGAIuVC7AA/AH4AEA=")); + +var partSunIcon = require("heatshrink").decompress(atob("mEwwhC/AH4AY6AWVhvdC6vd7owUFwIABFiYAFGR4Xa93u9oXTCwIYDC6HeC4fuC56MBC4ySOIwpIQXYQXHmYABRpwXECwQYKF5HjC4kwL5gQCAYYwO7wqFAAowK7wWKJBgXLJBPd6YX/AAoVMAAM/Cw0DC5yRHCx5JGFyAwGCyIwFC/4XyR4inXa64wRFwowQCw4A/AH4AkA")); + +var cloudIcon = require("heatshrink").decompress(atob("mEwwhC/AH4A/AH4AtgczmYWWDCgWDmcwIKAuEGBoSGGCAWKC7BIKIxYX6CpgABn4tUSJIWPJIwuQGAwWRGAoX/C+SPEU67XXGCIuFGCAWHAH4A/AH4A/ADg=")); + +var snowIcon = require("heatshrink").decompress(atob("mEwwhC/AH4AhxGAC9YUBC4QZRhAVBAIWIC6QAEI6IYEI5cIBgwWOC64NCKohHPNox3RBgqnQEo7XPHpKONR5AXYAH4ASLa4XWXILiBC6r5LDBgWWDBRrKC5hsCEacIHawvMCIwvQC5QvQFAROEfZ5ADLJ4YGCywvVI7CPGC9IA/AH4AF")); + +var rainIcon = require("heatshrink").decompress(atob("mEwwhC/AH4AFgczmYWWDCgWDmcwIKAuEGBoSGGCAWKC7BIKIxYX6CpgABn4tUSJIWPJIwuQGAwWRGAoX/C+SPEU67XXGCIuFGCAWHAGeIBJEIwAVJhGIC5AJBC5QMJEJQMEC44JBC6QSCC54FHLxgNBBgYSEDgKpPMhQXneSwuUAH4A/AA4=")); + +var stormIcon = require("heatshrink").decompress(atob("mEwwhC/AFEzmcwCyoYUgYXDmYuVGAY0OFwocHC6pNLCxYXYJBQXuCxhhJRpgYKCyBKFFyIXFCyJIFC/4XaO66nU3eza6k7C4IWFGBwXBCwwwO3ewC5AZMC6RaCIxZiI3e7AYYwRCQIIBC4QwPIQIpDC5owDhYREIxgAEFIouNC4orDFyBGBGAcLC6BaFhYWRLSRIFISQXcCyqhRAH4Az")); + +// err icon - https://icons8.com/icons/set/error +var errIcon = require("heatshrink").decompress(atob("mEwwkBiIA/AH4AZUAIWUiAXBWqgXXdIYuVGCgXBgICCIyYXCJCQTDC6QrEMCQSEJCQRFC6ApGJCCiDDQSpQFAYXEJBqNGJCA/EC4ZIOEwgXFJBgNEAhKlNAgxIKBgoXEJBjsLC5TsIeRycMBhRrMMBKzQEozjOBxAgHGww+IA6wfSH4hnIC47OMSJqlRIJAXCACIXaGoQARPwwuTAH4A/ABw")); + +/** +Choose weather icon to display based on condition. +Based on function from the Bangle weather app so it should handle all of the conditions +sent from gadget bridge. +*/ +function chooseIcon(condition) { + condition = condition.toLowerCase(); + if (condition.includes("thunderstorm")) return stormIcon; + if (condition.includes("freezing")||condition.includes("snow")|| + condition.includes("sleet")) { + return snowIcon; + } + if (condition.includes("drizzle")|| + condition.includes("shower")) { + return rainIcon; + } + if (condition.includes("rain")) return rainIcon; + if (condition.includes("clear")) return sunIcon; + if (condition.includes("few clouds")) return partSunIcon; + if (condition.includes("scattered clouds")) return cloudIcon; + if (condition.includes("clouds")) return cloudIcon; + if (condition.includes("mist") || + condition.includes("smoke") || + condition.includes("haze") || + condition.includes("sand") || + condition.includes("dust") || + condition.includes("fog") || + condition.includes("ash") || + condition.includes("squalls") || + condition.includes("tornado")) { + return cloudIcon; + } + return cloudIcon; +} + +/** +Get weather stored in json file by weather app. +*/ +function getWeather() { + let jsonWeather = storage.readJSON('weather.json'); + return jsonWeather; +} + +var clockLayout = new Layout( { + type:"v", c: [ + {type:"txt", font:"35%", halign: 0, fillx:1, pad: 8, label:"00:00", id:"time" }, + {type: "h", fillx: 1, c: [ + {type:"txt", font:"10%", label:"THU", id:"dow" }, + {type:"txt", font:"10%", label:"01/01/1970", id:"date" } + ] + }, + {type: "v", fillx: 1, c: [ + {type: "h", valign : 1, fillx:1, c: [ + {type: "img", filly: 1, id: "weatherIcon", src: sunIcon}, + {type: "v", fillx:1, c: [ + {type: "h", c: [ + {type: "txt", font: "10%", id: "temp", label: "000"}, + {type: "txt", font: "10%", id: "tempUnit", label: "°C"}, + ]}, + {type: "h", c: [ + {type: "txt", font: "10%", id: "wind", label: "00"}, + {type: "txt", font: "10%", id: "windUnit", label: "km/h"}, + ]} + ] + }, + ]}, + ]}] +}); + +// timeout used to update every minute +var drawTimeout; + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function draw() { + var date = new Date(); + clockLayout.time.label = locale.time(date, 1); + clockLayout.date.label = locale.date(date, 1).toUpperCase(); + clockLayout.dow.label = locale.dow(date, 1).toUpperCase(); + var weatherJson = getWeather(); + if(weatherJson){ + var currentWeather = weatherJson.weather; + const temp = locale.temp(currentWeather.temp-273.15).match(/^(\D*\d*)(.*)$/); + clockLayout.temp.label = temp[1]; + clockLayout.tempUnit.label = temp[2]; + clockLayout.weatherIcon.src = chooseIcon(currentWeather.txt); + const wind = locale.speed(currentWeather.wind).match(/^(\D*\d*)(.*)$/); + clockLayout.wind.label = wind[1] + " "; + clockLayout.windUnit.label = wind[2] + " " + (currentWeather.wrose||'').toUpperCase(); + } + else{ + clockLayout.temp.label = "Err"; + clockLayout.tempUnit.label = ""; + clockLayout.wind.label = "No Data"; + clockLayout.windUnit.label = ""; + clockLayout.weatherIcon.src = errIcon; + } + clockLayout.clear(); + clockLayout.render(); + // queue draw in one minute + queueDraw(); +} + +g.clear(); +Bangle.setUI("clock"); // Show launcher when middle button pressed +Bangle.loadWidgets(); +Bangle.drawWidgets(); +clockLayout.render(); +draw(); \ No newline at end of file diff --git a/apps/weatherClock/app.png b/apps/weatherClock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..434811541f217787965236c1f05c875089be3099 GIT binary patch literal 3259 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 literal 0 HcmV?d00001 diff --git a/apps/weatherClock/icons/icons8-cloud-lightning-48.png b/apps/weatherClock/icons/icons8-cloud-lightning-48.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae0cd4a912c0131c62ac1c86d9ba045e1b4a823 GIT binary patch literal 1166 zcmV;91abR`P)Io|u_#_&UtIJ2VG&~6y{mt2^mm7?L2uNmgU>WzBw@d-s>i5I9-tNU z_~?22C2!QKgV7tvt^6^=I0f0$9kvEX6ZUpR4}ok4no%w)`kf#jbZ-otHe#Mb)kIFk z^cJVli36=3@=S}$kcz%ofy#&0@BV>kR2-9ut!f=JYwQE4cp(qaQkgt}9(3-=030%z z*q{ewx5>obpa)0d_5&snRSQsMi#Z{4h+k{<23T*%#T&BnkcqpAfPW0Bc!SVv=3W6O zybA3+dWWHK#u&U<;HIi#_WvM>3$PMJ#aFvExDCnN#p^x1^jle+gKzZSMw{OY)U}( zxh+Kk1a{Sj%v{4Nnl%WCxD7=|35AVIVr2kP@ac-^?^65ArBso3*RK{AAxO# zVM(B|+@Ndq6Ke=Y?nGv*nb`PR1;bq`_`R|roNdfE=K9|Mx0V%$hT(Zz79FUTJa`ab zx=XElhr%s``f;utmN5$D$eE^oJu3?|`H-O)DUFdz$FLtV596fTeK0}Eh19+X4eu|;#q*K5ie2j8*3Rr-{^`O2?2jbD_WO|QrJQ4= z-v&Jlpm4l{(B5izEa}Yu<*$0X<#+l-=|R}cT=riChHrZ^doDQ1iM+3(Pj%2RRBo;q zsY#$6m~aSo-iusY3b!R=lJu!uEo+R_*Oh$7x!#uZyF5;+-6W5fU1(8^lk8HoYk_HJ zUd#lu9~G0ZdH_|}zm?FGNv@g*@Z*2A%+OD_66!BD>*E4%brAa8G*?XoY#|tp5E4N* zFEGz!(5KswL+6dud{&4TVLbv($B4rj4@qnO=F*99?BU*&4Q zTuH55{E0TkNL`DO9#OPrH+nTIq06MYfQuG^7o-L!*gR_30}}Ni&)kh%s$Gs6Vha1= g8_i)AtGF5PABDJuG1+mF&j0`b07*qoM6N<$f=L1@egFUf literal 0 HcmV?d00001 diff --git a/apps/weatherClock/icons/icons8-clouds-48.png b/apps/weatherClock/icons/icons8-clouds-48.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7533c51380c17a80b35807fa693b05a9e63ab3 GIT binary patch literal 654 zcmV;90&)F`P)2a3?`rhzKri^XF3e~~l>SzOZL#-Mu%WJ;C8Kn_?J;iIa)ayGM%CXUKRlD_*Mp!UV9 zsOnuH-$C{bWTsqno|*QaNp7t>^L6)@s?O5cJirL(liG@V({zl)D^RPuUjIMs)%0g(Cq`zv%rXH|G?VLrZYNrNPfl< z8*icR<^l8y$;<=fHwWB{am7Xf=IZXT?&f=eOvP0i1<0V&=4KLcB(BhK3(1(NlZ5Pv zD>OX=IYWIy;3W|X zpMtfh0B=(8k_ZuA25X@JzVB3lSa0!^`8xE=3Ecys0F$G#Cdg$#Q?V6~rV5p)kDSOu ze4^;Q5ahf-qCW+_MOW45_{l={T~uqwr^4IMy4T5gw==>8gx#vCJS}`+Ly!-M|9l78 o#}fr~rp7`+CL(`IBzrd+xpevHi)DKtn@A!~e)Z;34oa z9uMMc{{$`I74S!lm+@TfnL>x}k82g?%ETey3-$)S0f#F~mw^S+fq%y%d2OMxbRJFs zUD9Fi0r$nVE^w-%j8M3q3yIj87J9LSyeUqjAN9OvP1XhgZi(6+(GS2<7y;gk18m|Z z$>GR|6jkG;jUDTGvj5n19ci*;F7Pyt3)4;{Tc-BkNr5)6<_#(dQ)d{*KTmR!v>UA*&8ndqmc-Ga*j>$C%nK{)L?+XV z>AY%TH;OO^UMc3Me1M4R&? zIp;JKN&&fSY(b zxfBd$s_Qgyo$xfUVzyZ(*xAxT~tyjc2iMhqlYph8V!&BI5F-60u;F z6U(J%Q=c(0aE@ZU51^xb0i;w(f$T9m%`?ADnJ0#`#`nQGaT`JrM!;nyEtG;)E|}cQ zoML>(rHc4kYy`c0GhaF#tP_uw*mW4~99W(v%PcGna=&~#-h_| zvFD>q>^Ha8np=e*|I{~)h(-O;HrbKkGX4gG?!7=0P-bXXID$&Ws|LL_E?HU)C^|k-gA}*S8>j{_wIe>%t77Hm<>|}jPN?ctN{a_*1ijw>CU@L+j>s#}pUt%^+6B@M z)T4Y-^syjkGc8qvg)e{Aat;OQuvrOf0|Nu<_5$cupwYHIFg$b8X>D5~ zqbAALEmU4SfbJohcz}lQ)w!Lf$yNp)W^-%Gi;n}@W}0bbAcc0>i;2WC(?rV_k~Ui< z5t(b6XuAjME%PHHpN%t14L*FW4XITAAg~!&1Ud^Ok<%L(LFAr?dun5I&5L45MaA@G z^V6T^p0L4C0|oInijDsjRQF|Cs?Yhu0fB|KdClMd@_xoqXK|)Q z-u)g7Y~n)C|7+p_YLWZ_e=uM`U`sN3>``HpKNc{ckWNO9J)$)EW7B$_jvIkVe=N+v zn*_8(LgA%97G~gn0$L&=!X1AsV8HX79>C}>o-iM3C!D}J5HPT@RfYxG4QL{=%$QW6 zBkYkAx{24Po!f%!5Qy|oLA>ZY^;ox|x$05aXvwR>gI7AwN##$bgieGxs)<}JJYY zWu?F`>o+3kjkTtcf#%+?M-e?8GW5h|vgxR4bQcoQLt$~xbt9kJan&?h0fpM20G_=) zFlVUPZ_4#`l$v1}?g6eL?EfRAaweFk($qV;Q$!BCE-Om*wQ0>V7#WywW*@6@#}w!Q z{U(~~&UVed;?Mip*J9MyrZvkE>&cq#9euAb-yio}H*MP*ro{T7iL0+|i1$UNTnmIE p^tBCUo7j-J`np1e3KjkzegM>LDqZJ4qd))v002ovPDHLkV1gF!oP7WQ literal 0 HcmV?d00001 diff --git a/apps/weatherClock/icons/icons8-snow-storm-48.png b/apps/weatherClock/icons/icons8-snow-storm-48.png new file mode 100644 index 0000000000000000000000000000000000000000..e5ff7dd113bdc2c5a10c199404de19c02c477528 GIT binary patch literal 1153 zcmV-{1b+L8P)TDV0F>{wN?#FI ze(~RXuG?xg1ud)ZwGOU|q-uVt_%QDXcHCfMdK&}6vFt)N#_r&B8 znP2O#>?xFNmxbo3x+fLw1r{^rnl;UQ@hgJ#QB$`wNIaBi2K*i5c6JYdEs4|)&(mQ< zb_OW>NyKO$KNPu;&qu*C&^nOXYsY7|ueCQ1r8l<@ruT&L;i(vcyDShuK`HdmiMb}vbWf=8T)=A&;p~#DZ(ciGKNHlyvHyCcHWE3n=qJf3 ztDl&7|0yL@#ZEY{0bLt5Ed0&1OdllLUH z2b~x3^dwLZtF;co(PW2}D2uuf1O`xStrMD2HTfB}8&Z8BM?v41=&;^jRVJY}jldMr zYIjM6-5_Z}`h2@6$AD#&7YsEw79}3Ar=6(X;9L-q2Qni+XeXR+TLzuy!}Rez^V$aOHNi1|p)~Q2H6u z^*&Y6U4AwToU1nV+0br^7P5xW7yOtSc7t;X*ovU&zqEWg5w)HUGhRvlRw?Mvi;1Ty z0}5ZE^6{!sKU5e~7i#w1q4m`4w&uia(9GPu+|8Gt3Kc3;C_VoG>mB3A TQR6AP00000NkvXXu0mjf8E+*K literal 0 HcmV?d00001 diff --git a/apps/weatherClock/icons/icons8-sun-48.png b/apps/weatherClock/icons/icons8-sun-48.png new file mode 100644 index 0000000000000000000000000000000000000000..4933d6721a44c1f902e835caa8d964ff8e775296 GIT binary patch literal 725 zcmV;`0xJE9P)kAq`^HR+SK}%L?%_tg~#VKSFWQ<0$Gf*nR%~dGmAa9HF9S44OpxK628=Stelx7U1Q?OowjWT4@ z^WPV8;wTlNH-NoEIB3FPsGVBhz>*F3w_s&i?)q#R?%al3H{kUybpB|i*Lw$YHaxs1 zFaA8&uE2x4B8CR)2GS{U=XC_+Y}np{l)4P{k?U)4UE$8pva&4RA4Q}MxOHmd4|WDN z)|8XZu~`-|N4X-@PErQuR@hR}d$v&}n-){=gsQBGPy?Rj!E`b+%*T{65oo}-wz-;* zq)iI%n4u|@Uz}LjjPBd{cc*P764-&JGr-{~aG;uPt+B1p6#e?KJFlVCqT~w8(==G-! zNQxJiMqsKV+boN!(gYtq!`{(E)IvJ4gC-oGC=VagK7sv~@^EzngCV@xg|5bo)OAFR zp?YJZ*AH|Zc=1;4N&NT?FW+fT$@(4HsROUx2e*{x>Gj3$eZQ%7=SP_7i3daYcnF`q zilVHv3WfZnJm@-No^Q29W8b@IP5lU`4`05CV?q4)`$A^778_I{q=t{MNXcM+b2rF@ zVeukl40xJ|L42&Z4XWcmIG%^@SYJ%sI<=|YjD&=QgiFU?`U=pEQ8oi=00000NkvXX Hu0mjfd1O_) literal 0 HcmV?d00001 diff --git a/apps/weatherClock/screens/screenshot1.png b/apps/weatherClock/screens/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..31e1e1361fa83944f2e76734568889f1f0548e3f GIT binary patch literal 3182 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 Djh4}I literal 0 HcmV?d00001 From 566a11a9d4b1dbdddb569949cdfc1ffaafea29ac Mon Sep 17 00:00:00 2001 From: James G Date: Sat, 4 Dec 2021 20:36:07 -0500 Subject: [PATCH 0230/1839] fix weatherClock id in apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 84967e350..a4d61f7f9 100644 --- a/apps.json +++ b/apps.json @@ -4677,7 +4677,7 @@ ] }, { - "id": "weatherclk", + "id": "weatherClock", "name": "Weather Clock", "version": "0.01", "description": "A clock which displays current weather conditions.", From df83c635274c9e8205c62dc045bfeb30ddad869a Mon Sep 17 00:00:00 2001 From: James G Date: Sat, 4 Dec 2021 20:39:09 -0500 Subject: [PATCH 0231/1839] Update descriptions and readme for weatherClock in apps.json --- apps.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index a4d61f7f9..a876c2daa 100644 --- a/apps.json +++ b/apps.json @@ -4680,13 +4680,14 @@ "id": "weatherClock", "name": "Weather Clock", "version": "0.01", - "description": "A clock which displays current weather conditions.", + "description": "A clock which displays current weather conditions (requires Gadgetbridge and Weather apps).", "icon": "app.png", "screenshots": [{"url":"screens/screenshot1.png"}], "type": "clock", "tags": "clock, weather", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "readme": "README.md", "storage": [ {"name":"weatherclk.app.js","url":"app.js"}, {"name":"weatherclk.img","url":"app-icon.js","evaluate":true} From 7dc6cf6aa29ae5c632c82ba490ba72018f210056 Mon Sep 17 00:00:00 2001 From: James G Date: Sat, 4 Dec 2021 21:01:25 -0500 Subject: [PATCH 0232/1839] fix weatherClock storage params. --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index a876c2daa..3b4a45bdb 100644 --- a/apps.json +++ b/apps.json @@ -4689,8 +4689,8 @@ "allow_emulator": true, "readme": "README.md", "storage": [ - {"name":"weatherclk.app.js","url":"app.js"}, - {"name":"weatherclk.img","url":"app-icon.js","evaluate":true} + {"name":"weatherClock.app.js","url":"app.js"}, + {"name":"weatherClock.img","url":"app-icon.js","evaluate":true} ] } ] From 34f73b85da043908ee0bcd45287311ccd9436990 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sun, 5 Dec 2021 11:39:21 +0000 Subject: [PATCH 0233/1839] Widbata: battery level status using clocks colour theme --- apps/widbata/ChangeLog | 1 + apps/widbata/README.md | 13 +++++++++++++ apps/widbata/screenshot_widbata_1.png | Bin 0 -> 2431 bytes apps/widbata/screenshot_widbata_2.png | Bin 0 -> 5911 bytes apps/widbata/screenshot_widbata_3.png | Bin 0 -> 2499 bytes apps/widbata/widbata.png | Bin 0 -> 1629 bytes apps/widbata/widbata.wid.js | 16 ++++++++++++++++ 7 files changed, 30 insertions(+) create mode 100644 apps/widbata/ChangeLog create mode 100644 apps/widbata/README.md create mode 100644 apps/widbata/screenshot_widbata_1.png create mode 100644 apps/widbata/screenshot_widbata_2.png create mode 100644 apps/widbata/screenshot_widbata_3.png create mode 100644 apps/widbata/widbata.png create mode 100644 apps/widbata/widbata.wid.js diff --git a/apps/widbata/ChangeLog b/apps/widbata/ChangeLog new file mode 100644 index 000000000..51575d3b4 --- /dev/null +++ b/apps/widbata/ChangeLog @@ -0,0 +1 @@ +0.01: Created diff --git a/apps/widbata/README.md b/apps/widbata/README.md new file mode 100644 index 000000000..3f49f555b --- /dev/null +++ b/apps/widbata/README.md @@ -0,0 +1,13 @@ +# Battery Level Widget (Again) + +Show the current battery level status in the top right using the clocks colour theme + +* Works with Bangle 2 +* Simple design, no settings +* 27 pixels wide + +![](screenshot_widbata_1.png) +![](screenshot_widbata_2.png) +![](screenshot_widbata_3.png) + +Written by: [Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/) diff --git a/apps/widbata/screenshot_widbata_1.png b/apps/widbata/screenshot_widbata_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5fdc3ac3d172142d27662f162454c08348fbb67b GIT binary patch literal 2431 zcmcgui#OD37k+;;7`Ze|?)M}eGpFLz7lovhW2R)>FVSQW9mEkakr`2(l61&j3Lyp) zLo)J97;>3P#!M-bONuj?L>l6o^FMs+d)M0UUTd#s@4eo4J$pSn&B@VTQBF$^0HEmb zyPdPd*Z*s>GLpNldD2hfpeSei!=QFh=L-Ov_B+_wy2knmi-h^_EM$+Fe@}eX!0GRP z@46)qO*0+*($2+{b4B`v-_&xX4`2k`M8uYrj~vIX_LS#l|Ps-t=+PvF4OS7g$tm5 zEM+3{fPM!{tt&+So-nX1^7SH@Z@6+=4wyPMx|isXszi4v-eH{40|Y4>H$bIH5^^BV zCt_C!+6LfcPWOvbftx3{^Wx&)}nxTm%B;*Yd418h)6QBU-!8mX?{-8SY&+Hp!i zzn>3rmhq`?rnwAJmwHY)AVMc4$gG%Q|94viTlHbvM-+Go1Mnt%0 zM`Rvf3$FV(_m%9ByEo=yf8Kf-lX5(6#Kbn<5JYu2Q;=_oDH(kU}`?e?? z(QYV5*t7ph*QV}}urv0|ON5S)E#J|4WjIu*X?AHsMgWlrs<$a^4Qhsc8R}AsaGoUE z)D)5pSLloz$(CXl9Bn@2(tDT0X{=+5O}}xO_#Z=7D8WFplCyIys8^ZbFTPhoO6a&C zj+t{zg*2$opUg0aw|t+Q zUA0{`SFT2E>L0x=z*YeUYXq8RC{78v;1YCQ$wTE7WvArX3>19$j@5lVV<>jloMo7m zx1=>8B}P1o9OZvn<{?SosRBHA$assj_V~N3sezERyd$Fn=twnt16O%2?NnO<7ljH#pVN!=4l8Iu`Xlzdg934qPl z49Ff+BJn*$-J8gX(H^6smYd%unA?}K$ZLK!AT&85FgD;eSV@%b9vC0aQ%h1C&p@~e zHp=Q}N_O7T8Mo++OdXoLLoWP29Q3|7^D?WcCYwEbO^=8F*s;=M^a?pYOS?EVkfgR# zYG?A36dh8;OmsRlwFTd#YO)yB+C!sCYpx{&x9EN z9Q}~CJJXqFbv#On#fzIqQ9@4&DG*(wdLepL?pLCIKuztL!t-ruj1?3KG%bv4$-}!J zd3C1N1l9KMH$K|U^6yg?U-)bLS@(8VfwqTWzTE9d;ih?x*rKy-hlS6ISGgCoYbNm% z!~I!8L&?qH#B-NX1x|` z5r^bO(9TXqr?1j{QjXgA5%1K+(&7;3L|oy0~E zAa3f5+yl~s)LNNk4@*}fZPxk9bgPNepYoCB%3ddn5a3jWbum%}2!OH~u>ydRkc?>{ z{TdV(1$ZQqoK{^>)fIulVdp#g)sDmo_DP}ph&ueaY7;2#LBbjOfd};jUR`h2S3_5I zsSerf0?@mDE->?-49?jJc6vRhHKFkcx6lp^BS(-T6M<81B-e&F{I51ao6OAV_fEC-oIws?gOWCIMsKs-FHtKRbMX(B(#J`tZ|eR#t^CXUInu z6uaJ>wrYMYJIf?L(7cR3Puv9a6`dZ1yU%L-o}2snd@tHWbzq}dSP zC%U4`eFSax4Wlnl!k6MMCPBOv`aYZ~C~Q3%j;fc+T|%btFDjK?@~-m#VD*bMW7cO_n=ZyO*dChtI_nRZ|t1}7`ME&yhDM=m0aQXUW*YncH z#kXJcygh|JV+P#fgX$GOxlk+v!J#fb6+^tHO_FZRakumwY|FA=zFf^unU*keR(dVs zH6<4z(69^lptaSJgs9CQ6n}ewtM0&yx=2yFIIz|)4Njx*1fynYo*{y~iUn{&l>MYz zJ5FX5m~o+CX&5^5Wo(}LI9m|qZqt|L>PXgRyhFnCTT?&iKN=a6dsezJQ43- oVF!U-nYtB3iRS)4Q)!7%Fy7=^sfp5l$wmbnjyl@a9wsII7pysJEdT%j literal 0 HcmV?d00001 diff --git a/apps/widbata/screenshot_widbata_2.png b/apps/widbata/screenshot_widbata_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6a6ec8581d1f349632b2ed74b36d1b5c5c9a2e06 GIT binary patch literal 5911 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 BYKs5> literal 0 HcmV?d00001 diff --git a/apps/widbata/widbata.png b/apps/widbata/widbata.png new file mode 100644 index 0000000000000000000000000000000000000000..3a1f8281abad68e4dfd8cd3ca245dcff5d85ffc3 GIT binary patch literal 1629 zcmV-j2BP_iP)000F^dQ@0+Qek%> zaB^>EX>4U6ba`-PAZ2)IW&i+q+U;0bcH=k<{KqNg2n4|OI9%VG8_e;iKuNZfbP{*F zzxuTli!w-JD;7wH=70Y#`UjU3b>u_JvBcC-2VydSimDBR+Vmrce zvE=j^LO;i^vwx=nAF_wnBr!xz9#1bWrC9Ku#rcH14Rch}wtqA9{ySYm1wP4CR)=Rc z57j=b6(7OVX}}oX64?^bcz6o5gj~XVx$^q;^_Ayzxqd?a2GZLbev@gXI`+mfy&ssJ@B$Ld`yFjl9-8qN_e4kg|go;u35JBtcW|| z6I`}r+g)&H*y(_CV39T4oeK+KTWGAgc)EI>1yD5yLm~{ zqC+zv?pO{AsoZ?wZMJN4oihv%&V<#&P{w<0yl~SqgVr)aF}r-r75oxg+3>=UVBDnN?hL4Y%$if0#D z14njAgc36nnE_CR>!My7VBrvCz)A6{5#WFYu#Gv1_fQFPh*1auM9@f@fKAZ~u)Ggg zKgnmTp&B&!5JC(obaL*hYTIy@rWahJj$q(CzjIm zGt4;C%(Kk8u+)|=zrupx}gSXN|y?@auN(PASRvx zcrpZ7NyIR7nY|Z7&MzN2T0okK_KPTJU$Czq1etZ~}6UgMTVqpH%HTw_CTu${7E;EJ{C8?j9)+wR$Q z*SEES+>yq+p7)lXHALT8de#uV8q#HmUJdCoM6ZT)8KT3|@($=@r%_B~Y%CBaYUNmIA`3~^IGo)ohg&USGS<}`GsHd$^o|z$ zObK1S&cpv0$X>AD*sP)OuHp1<=OG{P=bmrrn*pg~w>?5>ejq$-R%>rTTM}>Up6rJd zh*3&F=EfO)9#D~8*y`NJHX+#AJDxc2ZYnj}LB(qHGc#l36l2*IlQ$j?%uRFXW}gbO zHp~fd52tRm1i=xyrw5+kV6q+}fW(xa5g79~-=)ouCh4#lmK}M1KE?Nzel4{hGfTgg z+K-u~pG)mE(@LHZ1m`8>&@7ROG;~CT)om=XUjU8UY60Ak&AhP2mAI$r^?-fbuXPMo$*1@9+-H$9fC~_y#k%2pv0A{s+B3R}Bx~2TY zz?BcM@b+nyqE9N$r&a2GDY}Xq-OA`EmYy|4-&uOr5WO1GWr$u4=`uvGhIARC??amI zsOx?lbv=(;U6%|JZhARNyR^imED}*WC)7IJMp9DC=vLv zP~Y;cqIx~@tupG#jcwKTlg+kKI_yQ71#Fx7g_8E%F7j8=UqyeGqP>06|FUhuJ``Ce zKL7v#32;bRa{vGf6951U69E94oEQKA00(qQO+^Rg3F z1gto3FJz1#(3o?Mlk<$j0{{R30000000000000000I-y-433C;1;v-OyE{;v!j=YR z%QSo~rSU=5Db&%u%39I^05|dO6pz&WLlK(+Ef?y&dmwzX0ssI2000000000000000 b0GyZ?WnUGDU!+md00000NkvXXu0mjf-eL3? literal 0 HcmV?d00001 diff --git a/apps/widbata/widbata.wid.js b/apps/widbata/widbata.wid.js new file mode 100644 index 000000000..0567cc581 --- /dev/null +++ b/apps/widbata/widbata.wid.js @@ -0,0 +1,16 @@ +setInterval(()=>WIDGETS["bat"].draw(), 60000); +Bangle.on('lcdPower', function(on) { + if (on) WIDGETS["bat"].draw(); +}); +WIDGETS["bat"]={area:"tr",width:27,draw:function() { + var s = 26; + var t = 13; // thickness + var x = this.x, y = this.y; + g.reset(); + g.setColor(g.theme.fg); + g.fillRect(x,y+2,x+s-4,y+2+t); // outer + g.clearRect(x+2,y+2+2,x+s-4-2,y+2+t-2); // centre + g.setColor(g.theme.fg); + g.fillRect(x+s-3,y+2+(((t - 1)/2)-1),x+s-2,y+2+(((t - 1)/2)-1)+4); // contact + g.fillRect(x+3, y+5, x +4 + E.getBattery()*(s-12)/100, y+t-1); // the level +}}; From ffc1b0926491646c91c8e675742c3c5f0e295dc7 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sun, 5 Dec 2021 11:46:47 +0000 Subject: [PATCH 0234/1839] Widbata: battery level status using clocks colour theme --- apps.json | 16 ++++++++++++++++ apps/widbata/README.md | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index a312b90a3..f6bda645e 100644 --- a/apps.json +++ b/apps.json @@ -4675,5 +4675,21 @@ "data": [ {"name":"pooqroman.json"} ] + }, + { + "id": "widbata", + "name": "Battery Level Widget (Themed)", + "shortName":"Battery Theme", + "icon": "widbata.png", + "screenshots": [{"url":"screenshot_widbat_1.png"}], + "version":"0.01", + "type": "widget", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "description": "Show the current battery level status in the top right using the clocks colour theme", + "tags": "widget,battery", + "storage": [ + {"name":"widbat.wid.js","url":"widbata.wid.js"} + ] } ] diff --git a/apps/widbata/README.md b/apps/widbata/README.md index 3f49f555b..1567df930 100644 --- a/apps/widbata/README.md +++ b/apps/widbata/README.md @@ -1,10 +1,11 @@ -# Battery Level Widget (Again) +# Battery Level Widget (Themed) Show the current battery level status in the top right using the clocks colour theme * Works with Bangle 2 * Simple design, no settings * 27 pixels wide +* Uses current colour theme to match clock ![](screenshot_widbata_1.png) ![](screenshot_widbata_2.png) From 11a598e024bb6da7257d28d9887afc8a4c766b7c Mon Sep 17 00:00:00 2001 From: hughbarney Date: Sun, 5 Dec 2021 12:22:14 +0000 Subject: [PATCH 0235/1839] Widbata: documentation tweaks --- apps.json | 4 ++-- apps/widbata/README.md | 2 +- apps/widbata/widbata.png | Bin 1629 -> 1635 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index f6bda645e..f8ee44dfd 100644 --- a/apps.json +++ b/apps.json @@ -4681,12 +4681,12 @@ "name": "Battery Level Widget (Themed)", "shortName":"Battery Theme", "icon": "widbata.png", - "screenshots": [{"url":"screenshot_widbat_1.png"}], + "screenshots": [{"url":"screenshot_widbata_1.png"}], "version":"0.01", "type": "widget", "supports": ["BANGLEJS2"], "readme": "README.md", - "description": "Show the current battery level status in the top right using the clocks colour theme", + "description": "Shows the current battery level status in the top right using the clocks colour theme", "tags": "widget,battery", "storage": [ {"name":"widbat.wid.js","url":"widbata.wid.js"} diff --git a/apps/widbata/README.md b/apps/widbata/README.md index 1567df930..6c3012793 100644 --- a/apps/widbata/README.md +++ b/apps/widbata/README.md @@ -1,6 +1,6 @@ # Battery Level Widget (Themed) -Show the current battery level status in the top right using the clocks colour theme +Shows the current battery level status in the top right using the clocks colour theme * Works with Bangle 2 * Simple design, no settings diff --git a/apps/widbata/widbata.png b/apps/widbata/widbata.png index 3a1f8281abad68e4dfd8cd3ca245dcff5d85ffc3..877af17077cd4a3237e044f33dfc2337c188398d 100644 GIT binary patch delta 1526 zcmVN?Ec* z38b(+K9FrU|ND2je{gV-?1H8oON<^zD4}r0L-xl}_nmy$_kD!33-3>Ick5t?1g#ve zIiB(fIb%GZ@_y>6kn4k@GS80o+)+ggq8M{LA94{sJOx_pe8O|N^7{Glndk0u{e=7p(%TcgkUt>pc0#WX`G8QowLg`U z-sSEQ(v91L; zXHs=1_&PrxhN}QU-D%DUu=-{i0Dn`uPcGR&3kE9MgGZFcsQ@X02MT9MfPjxAN|AhG zc8Lgy%mApub(X*lu#hSbILSdI0vxaaw((7(J(QIXF$y7oP>D_wuqjdjRtSpulS0NE zswx^(HEPnVMQeYQXbg)nMXRVaNeW3*Oey75QgvB!$eLqLIp>mVK>fAh6UaG(?hDBMh}+Ll z8+9*qvJo;GT2j4$eHc_Z;}0w5=dJT!9Qdv1ThZUGNM>4V?afuSww92rbzIfRR|y_v}TRd-g=E&8jY&r)}$I6dev6Sih(QEDomn5rFkf{RcVyDM#L0xGC8hpn<-2(O|pN+;p|p9{AvjwV_wZMHTF@UceL1N zO6Ur89{xvl_JH-qz8V7W8g}ot9}0>;|Mk}WVnFIxZI4h|7zhuG)!IwYmc-k=@amPM)Q>g7&Vl_q8)Q^o%jAdI&!T2`<_9)>}Ls$@v zZ$p1J3x$!rVa}M0suRnUd2~w?Ji-QLJwyVD89O7f3b1+4ZQfmQ&pxPm;D0~WLEU>P zzGv9Im*RVd-Fqp%G@(L{%@}N;kW4deRZ+AfI?Q%sjr}5M)K*h)g*Ow&HXQw8e5#}M zF&08IJYvh(9)U#-P8{}jEbzgixyMqGoPK|n-EC_fyh34H>ycL5gFCT~jNGY(n5+F$ z!B&Fj*5wx+pS3F=pyBCOOx(w^^`Zj3tXfxTaxcs3i~9J=ko%RTuNrdihIDCj?}l`B zxpzal47uMAY5JqihjG;TJgm;|noXR+%FQ>QcBx;2J^mWDgp7>e1QJ0Xy_fnQE4@I? zBfr_8g4sK9-wN^Lp+57iqKZB8trF_WjcwK00<+mRN{7KX3)nXEA74ej6@4rEyA|!_ z)cp@Vf5#?{IEOTob_F2^3>72fyHlW(o&_j>gGod|RA}Dq*-Hw*APfaSQ*!?++bfhN z#ftOxLdN(3jXCGoIoH@c000000000000000000000I!mj!4Xlfp!l+Ob_a@6*wVmk znT98&eDnzG6zb?+Wi9CdfSY)AipOjIp@_wRmJ9XVJrKTG0RR9100000000000000P c004H(4T(Dyh#sUj4*&oF07*qoM6N<$g1UCj=Kufz delta 1520 zcmVH+?PMQ@coUPZXE)VqSfPT zj;DM=E*LMTyq|h1v@gXI`+mfwHKp{Txz`9jS;YmL0tJff>UBII}mb%nCuFs@m)_N<6I;S*f8 zWZPYEXV~e0b6}A*+?@*xU|j5ZaOK5wx1Bp&^fD!(73l!C6NDLH6zOW*ZTwMozN3FrUF(lP8yw)~s>bw_f9xMx(0Inp|T;Z?K)RV&ICk>Kn05D%-71G$Enza&)f_X#J__`X z7W+&IUB1r4{}{+#u;19Mq42KZ^ls-NAMod%Z|R!>sbjZ2LTP>=JZx5LZ$VoUZ|k1y zhZKlWNA81pyZrOl5f>984=9eI8}#rKweEwvvr zOTU)dkC~;POYJq&N}dq}=OyIOERl&cbVP;KZ7i{00FB#f0o;(yys-^Mw*+&;Xnl;; zHVm<4oQ6P}M&9vZZ~G1(%=^3V6-nu5ncaW3*1@9+-H$9fC~_y#k%2pv0A{s+B3R}B zx~2TYz?BcM@b+nyqE9N$r&a2GDY}Xq-OA`EmYy|4-&uOr5WO1GWr$u4=`uvGhIARC z??amIsOx?lbv=(;U6%|JZhARNyR^imED}*WC)7IJMlZC z<|q;Pu~6Ugt)hB8@~txJ$&GE*_LI%FQ9A5Jngwi|`Gu19+%EE0(O*S>mZH6V(*Lq; z!afvPCqI*W1tA9u7ARc{&u){W1t@=lNklmEIBzdx zj33aLbB>eqjKc!}00000000000000000026l&lPnh4Nd@ZH% zLDnhM(Y?xA(g6TB@$M9l)civcn*l8s>b-j)e6s=o000000000000000000;OoR}A7 WUloX7q*2iT0000 Date: Sun, 5 Dec 2021 12:30:29 +0000 Subject: [PATCH 0236/1839] Widbata: documentation tweaks --- apps.json | 2 +- apps/widbata/widbata.wid.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps.json b/apps.json index f8ee44dfd..d3c5abcfc 100644 --- a/apps.json +++ b/apps.json @@ -4689,7 +4689,7 @@ "description": "Shows the current battery level status in the top right using the clocks colour theme", "tags": "widget,battery", "storage": [ - {"name":"widbat.wid.js","url":"widbata.wid.js"} + {"name":"widbata.wid.js","url":"widbata.wid.js"} ] } ] diff --git a/apps/widbata/widbata.wid.js b/apps/widbata/widbata.wid.js index 0567cc581..1c04bf8ae 100644 --- a/apps/widbata/widbata.wid.js +++ b/apps/widbata/widbata.wid.js @@ -1,8 +1,8 @@ -setInterval(()=>WIDGETS["bat"].draw(), 60000); +setInterval(()=>WIDGETS["bata"].draw(), 60000); Bangle.on('lcdPower', function(on) { - if (on) WIDGETS["bat"].draw(); + if (on) WIDGETS["bata"].draw(); }); -WIDGETS["bat"]={area:"tr",width:27,draw:function() { +WIDGETS["bata"]={area:"tr",width:27,draw:function() { var s = 26; var t = 13; // thickness var x = this.x, y = this.y; From 69a54194a9eb41d0722fc061bec5c900b724e8cf Mon Sep 17 00:00:00 2001 From: t0m1o1 <94725994+t0m1o1@users.noreply.github.com> Date: Sun, 5 Dec 2021 17:11:14 +0000 Subject: [PATCH 0237/1839] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a385c0992280070dbcbd91b8663600ea42d2749c Author: Gordon Williams Date: Fri Dec 3 12:04:40 2021 +0000 openstmap .10: Improve scale factor calculation to fix scaling issues (#984) commit 052eb41ebc248ab874f7b188318db48638957a7f Author: Gordon Williams Date: Fri Dec 3 09:20:13 2021 +0000 Stop crypto polyfill being pulled in - fix http://forum.espruino.com/conversations/369197/#comment16294286 commit 6baddd3b433d318d196c0f2d1c73df2572f2600e Author: Gordon Williams Date: Fri Dec 3 09:15:37 2021 +0000 Add gbdebug app commit b5fa5fb64e60e70fc104bd60c08a7ef12b2c3146 Author: Gordon Williams Date: Fri Dec 3 08:24:12 2021 +0000 tweak for lint errors - still some assignment warnings commit d504017782a5ecf7b80da27a1c855f95865c86ea Merge: e2ae57fa 633cad5c Author: Gordon Williams Date: Fri Dec 3 08:18:47 2021 +0000 Merge pull request #986 from stephenPspackman/master pooq Roman - a watch face commit e2ae57faa4bb2c338f74daa538971c67c02b687a Merge: 79f37b2b 3595fab0 Author: Gordon Williams Date: Fri Dec 3 08:13:52 2021 +0000 Merge pull request #951 from rigrig/qmsched-clean Move Quiet Mode LCD options from global settings to the Quiet Mode Schedule app commit 79f37b2bfa208a6b831d1240c90d3c019ee4d6a5 Merge: 56b9e04f b595e603 Author: Gordon Williams Date: Fri Dec 3 08:12:21 2021 +0000 Merge pull request #987 from hughbarney/master Pebble: use LECO1976 font, update boot icon, redo screenshots commit 633cad5cd3f312bc9db84623dfe4e9b6d7199e57 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Fri Dec 3 00:11:07 2021 -0800 Update app.js Fix (hopefully) time zone issues and boundaries in the event scanner. commit b595e603334f701cc5feb7e29a2eae804e4b250c Author: hughbarney Date: Thu Dec 2 22:17:00 2021 +0000 Pebble: switched to LECO1976 font and slanting boot icon commit 3595fab079eb6a91596bc994c7d744109ed5c4fc Author: Richard de Boer Date: Fri Nov 26 20:05:40 2021 +0100 qmsched: manage LCD options Also migrates old settings file: we now store options in qmsched.json, instead of in the global setting.json. commit d743b2266abf069297de59248cb366d6b04ec63c Author: Richard de Boer Date: Tue Nov 23 21:27:37 2021 +0100 boot: remove Quiet Mode options Updating these will be handled by the Quiet Mode Schedule app (qmsched) commit c24f67b06bbb5417355398149b8e4ad12f8d0c19 Author: Richard de Boer Date: Tue Nov 23 21:25:26 2021 +0100 settings: remove Quiet Mode LCD options Updating these will be handled by the Quiet Mode Schedule app (qmsched) commit 32980bf3befaf7a047cfc808df2d9cbd547813ce Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 13:04:29 2021 -0800 Update apps.json Declare pooqroman.json, our private config file. commit ade94521b7da3217c6210d0d5e8873012719a792 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 12:57:25 2021 -0800 Update README.md Github flubs UTF-8? Really? commit 2906e228bad106b86c176ccf8e1639f3c67dd556 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 12:54:03 2021 -0800 Update apps.json commit 9c8fd937839ab2fd784abd28e2e991b5d010cd26 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 12:53:18 2021 -0800 Create README.md commit 6ed4565ee1feb936fc341207cff4e058eeb37150 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 12:16:53 2021 -0800 Add files via upload Upload the right file this time :-}. commit 98bb9c28b3aac54a7a65e2eefd28dccba5a8dbef Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 12:02:15 2021 -0800 Add files via upload commit 4803365ab3f8a6b3e2f9a6f650b642326a952010 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 11:49:28 2021 -0800 Update app.js Conform to filename conventions for our settings file—it is json. commit 8ff08cbaab00ce915eac1cf66ac2af4aaee220d9 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 11:35:39 2021 -0800 Create resourcer.js commit ad96a97ae9fc12d8d93dceb60d1c861ce60ad630 Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 11:34:25 2021 -0800 Create app-icon.js commit 2fc3cee13926258243f86a791c2e175cc9ceb07b Author: stephenPspackman <93166870+stephenPspackman@users.noreply.github.com> Date: Thu Dec 2 11:27:53 2021 -0800 Create app.js commit 43a68fb908f7eca0adf27079b5be3cbfa2236fac Author: hughbarney Date: Thu Dec 2 19:01:40 2021 +0000 Pebble: 0.03 changed font to Leco1976, updated screenshots commit 56b9e04ff0575334c07849bf83f829fc98c08472 Author: Gordon Williams Date: Thu Dec 2 10:37:08 2021 +0000 new core commit 9d26a6448ef93694da643b6152439bc4db516e96 Author: Gordon Williams Date: Thu Dec 2 10:28:38 2021 +0000 launcher 0.09: Bangle.js 2 - pressing the button goes back to clock (fix #971) After 10s of being locked, the launcher goes back to the clock screen commit 5b967184b671315b2d474e1f5eefeff9073c1bb0 Author: Gordon Williams Date: Thu Dec 2 10:07:45 2021 +0000 0.03: Fix unfreed memory, and clearInterval that disabled all clocks at midnight (fix #946) Fix app icon Change menu order so 'back' is at the top commit ce2d1822477e9bc1468fc77f5ce31f4dc850a8cf Author: Gordon Williams Date: Thu Dec 2 09:43:03 2021 +0000 tweak 2v11 firmware mentions commit 829ee9129a8bcacd443c493e9111166bfaaa4b0e Merge: 0cb1dfbb 7a1bb02b Author: Gordon Williams Date: Thu Dec 2 09:06:21 2021 +0000 Merge pull request #983 from hughbarney/master Pebble: deploy settings file, updated README commit 0cb1dfbb82afe9a1d3adc96489b8883c70775469 Merge: e0018a49 3baa465f Author: Gordon Williams Date: Thu Dec 2 09:06:07 2021 +0000 Merge pull request #982 from rigrig/delete-settings-library remove Settings module commit e0018a495c3ea51cce4e3834db0ed899c2fc3872 Merge: 7218acf0 cb8ee706 Author: Gordon Williams Date: Thu Dec 2 08:12:16 2021 +0000 Merge pull request #981 from andrewgoz/master New icon, improved UI commit cb8ee706252666bbfd215af26ecd87acc39d077c Author: Andrew Gregory Date: Thu Dec 2 16:05:36 2021 +0800 Update app.js commit 012982e910436c5abe2ad6f28f68a96762343a18 Author: Andrew Gregory Date: Thu Dec 2 16:03:22 2021 +0800 Update README.md commit 7a1bb02bced4f0080d838bbe7ca3923b1e8d665f Author: hughbarney Date: Wed Dec 1 21:07:41 2021 +0000 Pebble: updated README commit bd8bb638d434df8a8cbfab84272f39d1a86b0755 Author: hughbarney Date: Wed Dec 1 20:29:34 2021 +0000 Pebble: deploy pebble.settings.js in apps.json commit 3baa465f01e5df16ff15311ec91c7896eabd345d Author: Richard de Boer Date: Wed Dec 1 19:34:52 2021 +0100 remove Settings module Better not to have this at all than to have a library that you can't actually use in widgets/boot/settings code commit b848c45ce4618e7d9d737437a30812bf14c1cea0 Author: Andrew Gregory Date: Wed Dec 1 23:42:17 2021 +0800 Improve token display Limit label length. Reduce digits font size until it fits. commit 86ea0554b37139afc295437d45b2d85c9b4aee3c Author: Andrew Gregory Date: Wed Dec 1 23:26:45 2021 +0800 Colour icon commit 3305a5db6ab4e40ef45ea54513c656b503195450 Author: Andrew Gregory Date: Wed Dec 1 23:23:44 2021 +0800 Colour icon commit 26cc978a40ffcf415db086025cc63910f7e8e943 Author: Andrew Gregory Date: Wed Dec 1 22:29:37 2021 +0800 Update README.md commit 21961edf42856a2b82f45a8bbbb6751247fa658d Author: Andrew Gregory Date: Wed Dec 1 22:26:01 2021 +0800 Update ChangeLog commit 4d239bf71e5cc8312e3a5c762088c27ad9f20491 Author: Andrew Gregory Date: Wed Dec 1 22:24:43 2021 +0800 Version 0.03 commit 16f20970d9294d144347cfb02605d1ddc4472be2 Author: Andrew Gregory Date: Wed Dec 1 22:21:21 2021 +0800 Limit scanned label length Fixed #5 commit d4ddf22399667a2cb98f73c375a98f11869512a3 Author: Andrew Gregory Date: Wed Dec 1 22:15:55 2021 +0800 Try new JSON settings format commit 60a8c487ad9035780ffbaf0a9a5db88d9743fe99 Author: Andrew Gregory Date: Wed Dec 1 22:05:53 2021 +0800 Support updated settings file commit 7a9b64a7fd9667181294406de59975ef240a010d Merge: dfd7a02e 7218acf0 Author: Andrew Gregory Date: Wed Dec 1 21:28:07 2021 +0800 Merge branch 'espruino:master' into master commit 7218acf0b470bb6ba2300ed7cc4791ceefe0bcfc Merge: adca628e a789e0be Author: Gordon Williams Date: Wed Dec 1 13:26:44 2021 +0000 Merge pull request #980 from myxor/poweroff-icon-color-fix Poweroff: icon color fix & README improvement commit dfd7a02e12f977e45699b6a1bbbd49c22a385633 Author: Andrew Gregory Date: Wed Dec 1 21:26:41 2021 +0800 Show placeholder "Calculating" Fixes #2 commit a789e0bea4945dd4461469b26f25744a9a3dc46d Author: Marco H Date: Wed Dec 1 13:55:25 2021 +0100 Icon white with 1px black border commit ca6b73e3e48c2a2b1ee157a6d02d166a0195324c Author: Marco H Date: Wed Dec 1 13:54:49 2021 +0100 Icon white with 1px black border commit 871c345cea41816a167170ef019fd6f041f0ccb0 Author: Marco H Date: Wed Dec 1 13:49:25 2021 +0100 Update README.md commit e2a4428be2a8369d51c30b4b34d367983f35c672 Author: Marco H Date: Wed Dec 1 13:48:03 2021 +0100 Fix gramar and link in README commit 2d190278f224253b969b8a0c742166d4fe193147 Author: Marco H Date: Wed Dec 1 13:45:24 2021 +0100 Change app icon color to white commit f3dffdb3e1d43cce05fde4a1bd31d043c758eedb Author: Marco H Date: Wed Dec 1 13:44:12 2021 +0100 Change app icon to white commit adca628e2ceff835b4fabdd2798b1b7b99ae0d33 Merge: 38c6e160 edec2442 Author: Gordon Williams Date: Wed Dec 1 12:06:47 2021 +0000 Merge branch 'master' of github.com:espruino/BangleApps commit edec24429acc747b80c0be6736a5919559bc3f91 Merge: 013d7704 43312a78 Author: Gordon Williams Date: Wed Dec 1 09:37:09 2021 +0000 Merge pull request #978 from myxor/mylocation-spelling Spelling issue in mylocation README commit 43312a782a58cbbe6cf2f8c4d49ae1d898bc82d5 Author: Marco H Date: Wed Dec 1 10:23:07 2021 +0100 Update README.md Fix spelling of the Scottish capital city in the README :) commit 013d7704a9997079de9f4ef0eee61745504d9e37 Merge: 527bbf8e a9530f64 Author: Gordon Williams Date: Wed Dec 1 09:00:19 2021 +0000 Merge pull request #973 from rigrig/widbars New widget: Widbars commit a9530f64ea9b0ed1e96dd1ddf6eac897943ec223 Merge: 8580952e 527bbf8e Author: Gordon Williams Date: Wed Dec 1 09:00:08 2021 +0000 Merge branch 'master' into widbars commit 527bbf8e59798bb73f0a7859c3f7f290dc31c111 Merge: 68b73d2e a44d5420 Author: Gordon Williams Date: Wed Dec 1 08:59:27 2021 +0000 Merge pull request #974 from rigrig/widbatpc-fix widbatpc: Fix drawing the bar when charging commit 68b73d2e17df1375fd0f6fc5b4172ea484b95444 Merge: 097a3153 1108983c Author: Gordon Williams Date: Wed Dec 1 08:58:35 2021 +0000 Merge pull request #977 from alainsaas/master New app: A Speech Timer commit 1108983cbad1f5a8cf2862bb5b03d8592e770303 Merge: 3c7d6b79 097a3153 Author: Gordon Williams Date: Wed Dec 1 08:58:30 2021 +0000 Merge branch 'master' into master commit 097a3153952073b468bd1fdab0029e66cb747fe6 Merge: 3ddd1696 24e2b01e Author: Gordon Williams Date: Wed Dec 1 08:51:48 2021 +0000 Merge pull request #975 from hughbarney/master Mylocation (APP), Pastel sunrise, sunset, A Pebble Clock to keep the revolution going commit 3c7d6b795d50aac5d6c3945a4a9af1ee013154ad Author: Alain Saas Date: Wed Dec 1 15:28:23 2021 +0900 Update apps.json commit 3507dcde457b78beede4ee033af1f38090a1a71d Author: Alain Saas Date: Wed Dec 1 15:26:52 2021 +0900 Update apps.json commit 541adf4c16c7bf2e522c3343b7675831b9e13343 Author: Alain Saas Date: Wed Dec 1 15:22:44 2021 +0900 Update README.md commit 8f0856d8716af6e1058a9923e0e5850734303d72 Author: Alain Saas Date: Wed Dec 1 15:21:21 2021 +0900 Update README.md commit 13b01fe82955ca3ba595ed115fd1bfc6acd7a4fc Author: Alain Saas Date: Wed Dec 1 15:20:52 2021 +0900 Add files via upload commit 18c3461e6e4191433897f3b1e10a9f68f7b97fa8 Author: Alain Saas Date: Wed Dec 1 15:20:41 2021 +0900 Create README.md commit da133e2ccd7ee837d078430095733180929fff4b Author: Alain Saas Date: Wed Dec 1 15:09:06 2021 +0900 Create ChangeLog commit 9033db08bf1a56d1f852a60795eb75d2bdee0f70 Author: Alain Saas Date: Wed Dec 1 15:03:45 2021 +0900 Create app-icon.js commit 673fa8820f779a79bcfa46819990e5717a4d49ba Author: Alain Saas Date: Wed Dec 1 15:01:48 2021 +0900 Add files via upload commit 312bed6491d7a9341c7f9de4d1f309e2f85b3fe5 Author: Alain Saas Date: Wed Dec 1 15:00:58 2021 +0900 Create app.js commit 24e2b01e22e8534029bcf8195c8f4e5eba209208 Merge: 7785c7ea 3ddd1696 Author: hughbarney Date: Tue Nov 30 23:45:24 2021 +0000 Merge remote-tracking branch 'upstream/master' commit 7785c7ea56867250df5985d0a27a7fd35478e501 Author: hughbarney Date: Tue Nov 30 23:38:29 2021 +0000 Mylocation: make into an app commit 848ccd2be996e5127d09e36960775e5cb45a4143 Author: hughbarney Date: Tue Nov 30 23:16:56 2021 +0000 Mylocation: make into an app commit 8ad8ed15dc8e9fe4091d2f3a5b1faf7b828bb0c5 Author: hughbarney Date: Tue Nov 30 23:15:45 2021 +0000 Mylocation: make into an app commit 8e56dce22c49a1a80b4dc9142092ea5238ab34ad Author: hughbarney Date: Tue Nov 30 23:10:36 2021 +0000 Mylocation: make into an app commit 4cbd7e8ea63c5aef83f72ceedcad7a2cc811917d Author: hughbarney Date: Tue Nov 30 22:46:37 2021 +0000 Mylocation: make into an app commit e3745f94fc0fd7bf367727a1fa2f43c26bde89b5 Author: hughbarney Date: Tue Nov 30 22:43:45 2021 +0000 Mylocation: make into an app commit a44d542053941c7bb588e3d444aeb02ad6aba676 Author: Richard de Boer Date: Tue Nov 30 22:30:28 2021 +0100 widbatpc: Fix drawing the bar when charging commit 8580952e69609f53736089e72e1028117fd5c09f Author: Richard de Boer Date: Tue Nov 30 21:06:23 2021 +0100 widbars: comment out HRM/temperature They didn't seem very useful commit 7caac64a8653f06f95650228abc98018de8df9b8 Author: Richard de Boer Date: Tue Nov 30 20:40:33 2021 +0100 widbars: new widget commit 4669099645a46062a63a9e77771b7ab1cf531ef2 Author: hughbarney Date: Tue Nov 30 18:11:08 2021 +0000 MyLocation added mylocation.app.js commit 3ddd169612095949d6e10a0c11f8f283bdd1fc29 Merge: a20a2e42 31eaeade Author: Gordon Williams Date: Tue Nov 30 17:14:26 2021 +0000 Merge pull request #972 from andrewgoz/master Fix JSON save format commit 31eaeadee2929e93fdee2ee01974cf2779e5ed13 Author: Andrew Gregory Date: Wed Dec 1 00:26:39 2021 +0800 Update Authentiwatch version commit f094cc6e354ada59d50719bd8af60bfe1f258cb3 Author: Andrew Gregory Date: Wed Dec 1 00:25:00 2021 +0800 Update ChangeLog commit e1c67cf345cf0b1093caa7c41c8e8981de8f24cb Author: Andrew Gregory Date: Wed Dec 1 00:22:23 2021 +0800 Save in new JSON format too commit 989dc5ccd4ede2fcc8f9bc82d9d5c4ad84981360 Author: Andrew Gregory Date: Wed Dec 1 00:18:44 2021 +0800 Use new JSON format. commit 51c91bf9eede044c0093bf265855d149547697d2 Author: Andrew Gregory Date: Wed Dec 1 00:17:26 2021 +0800 Rename variable commit f127bef66b9c4c88e8094594a90ac4aad53b26e9 Author: Andrew Gregory Date: Wed Dec 1 00:14:47 2021 +0800 Load new JSON format commit 0e3b17be6757527c1f372fa8b9d5bbc8f3985035 Author: hughbarney Date: Tue Nov 30 16:12:47 2021 +0000 Added icon for mylocation commit c1a48e7b48ddb4087b63171bde681ea1e79ca76f Author: Andrew Gregory Date: Wed Dec 1 00:09:52 2021 +0800 Try different JSON format commit 78c3791c1e6af33dc127418a172a22b0b9c96df9 Author: hughbarney Date: Tue Nov 30 13:48:20 2021 +0000 Pebble screenshot updated commit 5b7bbd83db31769a8b255821729d1cad5d5a81c8 Author: hughbarney Date: Tue Nov 30 13:30:13 2021 +0000 Pebble: added README, battery warning if below 30% commit 4cf5d860834aed17316a9b02b38539c2f6295bf1 Merge: ac1425ca a20a2e42 Author: hughbarney Date: Tue Nov 30 13:18:27 2021 +0000 merged upstream commit ac1425ca7cfaf46041790a3223e1f3383f7a2ae2 Author: hughbarney Date: Tue Nov 30 13:07:56 2021 +0000 set mylocation to an app commit a20a2e4292cef623f15d5408061ebd8463672dd1 Merge: dec4ec8c c30ee355 Author: Gordon Williams Date: Tue Nov 30 08:28:19 2021 +0000 Merge pull request #967 from myxor/poweroff-app Poweroff app commit c30ee355bb1f857e42d82c99d8805095e68b88b5 Merge: bd1fa974 dec4ec8c Author: Gordon Williams Date: Tue Nov 30 08:28:14 2021 +0000 Merge branch 'master' into poweroff-app commit dec4ec8c19d070e9d980a83d564f9ad22425c89a Merge: c1dd7c6c d2cb4be4 Author: Gordon Williams Date: Tue Nov 30 08:27:16 2021 +0000 Merge pull request #966 from reelyactive/master Added SensiBLE app commit bd1fa974d18bc8840cdfc8bf61091790a2825df1 Author: Marco H Date: Tue Nov 30 09:04:43 2021 +0100 Update ChangeLog commit 31dba4df497d464374237b9617f576d3cda54f15 Author: Marco H Date: Tue Nov 30 08:59:37 2021 +0100 Change icon to black commit ffd7eebf258636c52f07e82b5fe8fe787c77cb36 Author: Marco H Date: Tue Nov 30 08:59:20 2021 +0100 Change icon to black commit 4a852e713834b4163acff86a1a9edba5cab2f91c Author: Marco H Date: Tue Nov 30 08:52:47 2021 +0100 Rename Readme.md to README.md commit a08a8d8a24139b29d091f0c6847d80612066eef4 Author: Marco H Date: Tue Nov 30 08:52:29 2021 +0100 Update apps.json commit 166994311e6bfacbd6b1327a41800a489bf05852 Author: Marco H Date: Tue Nov 30 08:46:04 2021 +0100 Add app to apps.json commit ea10cea706d638de3827202fde9400317412e142 Author: Marco H Date: Tue Nov 30 08:44:45 2021 +0100 Update Readme.md commit f73055253e76284dd520080ad03cefac225b9d18 Author: Marco H Date: Tue Nov 30 08:42:30 2021 +0100 Add files via upload commit eef1569c9900cce4eb7c779aa6b51a7bc60682dc Author: Marco H Date: Tue Nov 30 08:41:49 2021 +0100 Create app-icon.js commit eeb3206a095f0a9db31c0a95b917b2b2d506f5e0 Author: Marco H Date: Tue Nov 30 08:39:36 2021 +0100 Create Readme.md commit c822b62789b269d9f1732e3e664a4670dd4d233a Author: Marco H Date: Tue Nov 30 08:36:28 2021 +0100 Create app.js commit 8775a6f3392fedbb2385dde7558254ae5ba559ec Author: Marco H Date: Tue Nov 30 08:24:43 2021 +0100 Create ChangeLog commit d2cb4be4b4dc7e1a0ee50dfd0331815e5469ddc8 Author: jeffyactive Date: Mon Nov 29 21:48:30 2021 -0500 Corrected variable initialisation commit 4d107148c78d5a7211e2e08664052014059b5371 Author: jeffyactive Date: Mon Nov 29 21:31:53 2021 -0500 Added SensiBLE app commit 6642b216066519d90e1bb0b46c1c8b731ff270b8 Author: hughbarney Date: Mon Nov 29 20:27:25 2021 +0000 added pebble icon commit b50faa919a9f8c50687a16435d7db946771b674b Author: hughbarney Date: Mon Nov 29 20:12:25 2021 +0000 Pebble - long live the rebellion commit 3fa435e57ddde56b59c75074adc0831f9ae2ba67 Author: hughbarney Date: Mon Nov 29 19:58:19 2021 +0000 Pastel, MyLocation updated README files commit 6510e4b7d2965f34404f8973c5d802adfa933d6c Author: hughbarney Date: Mon Nov 29 19:02:01 2021 +0000 Pastel added dependancy on widpedom commit 784f7f84924b2b5bf670086b237c537bc6eac0d7 Merge: 22d06c8c c1dd7c6c Author: hughbarney Date: Mon Nov 29 18:57:56 2021 +0000 resolved apps.json conflict commit 22d06c8cf6f6fb7a1e0c899480cb8c40785d81f0 Author: hughbarney Date: Mon Nov 29 18:45:44 2021 +0000 Pastel changed dependancy on MyLocation to type app commit 38c6e16010837c73e32022bb7ce999402f1a44b4 Author: Gordon Williams Date: Mon Nov 29 16:29:34 2021 +0000 new about pixels commit c1dd7c6cabbfcae7a68ecbead3a9a8a3a7ac7686 Merge: c2b70103 616afad0 Author: Gordon Williams Date: Mon Nov 29 11:37:02 2021 +0000 Merge pull request #957 from JamesLMilner/minor-style-updates Tweak styling to give a more aligned and spaced out layout commit c2b70103a6347d4f41b34c0dcbf20e45cc4bbd47 Merge: cd0de091 3e1c90e4 Author: Gordon Williams Date: Mon Nov 29 10:54:30 2021 +0000 Merge pull request #955 from alainsaas/master New app: A Clock with Timer, v0.01 commit 3e1c90e48582f548740f2e5c38b10c72e23a62a6 Merge: 17e13a63 cd0de091 Author: Gordon Williams Date: Mon Nov 29 10:54:23 2021 +0000 Merge branch 'master' into master commit cd0de091f3d590ac9eb32008a4a84506dc020807 Merge: 0dd00635 6fc1e738 Author: Gordon Williams Date: Mon Nov 29 10:52:43 2021 +0000 Merge pull request #956 from JamesLMilner/mandlebrotclock Add Mandlebrot Clock app commit 0dd00635b8f7da9a37c4e5318198c0af1d180c81 Merge: 72d3c44f ba506741 Author: Gordon Williams Date: Mon Nov 29 10:50:28 2021 +0000 Merge pull request #959 from dratini0/recorder-fixes Assorted bugfixes to the recorder apps commit 72d3c44ffd4896b00a187f926604e4717742ac7c Merge: 33ce71f2 0d45f2c2 Author: Gordon Williams Date: Mon Nov 29 10:09:47 2021 +0000 Merge branch 'master' of github.com:espruino/BangleApps commit 0d45f2c2e8d57fa50413e0477888159aaa05c4b3 Merge: c4238eba 075d7a84 Author: Gordon Williams Date: Mon Nov 29 10:08:07 2021 +0000 Merge pull request #962 from myxor/myxor-temperature-app Update degree Celsius temperature app commit 33ce71f279162e61bf1be8247ed87c1f12331e89 Author: Gordon Williams Date: Mon Nov 29 10:06:21 2021 +0000 fix for sanity test errors commit c4238ebae7b5e25baced884730d03787f932e497 Merge: d4f1e7d3 10d170d3 Author: Gordon Williams Date: Mon Nov 29 10:01:40 2021 +0000 Merge pull request #950 from jg76379/master Add new Interval Timer App commit 10d170d31ebdf744a7eaabada4d0f9f918a05646 Merge: 4f5ec608 d4f1e7d3 Author: Gordon Williams Date: Mon Nov 29 10:00:29 2021 +0000 Merge branch 'master' into master commit d4f1e7d3cb2d79bb69405e46300afcf2eedaf4c7 Author: Gordon Williams Date: Mon Nov 29 09:52:47 2021 +0000 minor fixes for #952 commit 795d2b83ec1b6bd5bcc26239beda7b56fa3be7b7 Merge: d1534bdc 99ec40cd Author: Gordon Williams Date: Mon Nov 29 09:51:51 2021 +0000 Merge branch 'master' of github.com:espruino/BangleApps commit 99ec40cd8ead828bc2572914234a06c554410089 Merge: 30e421e2 6220a88d Author: Gordon Williams Date: Mon Nov 29 09:48:20 2021 +0000 Merge pull request #952 from rigrig/locale-12h locale: Apply 12hour setting to time commit 075d7a840ca46181a72da0dc6ba667e64787b950 Author: Marco H Date: Mon Nov 29 10:43:42 2021 +0100 Update apps.json commit c9d0a199477bf6c6b39a852c73d71fca666adda2 Author: Marco H Date: Mon Nov 29 10:40:32 2021 +0100 Add space after temperature value Add space after temperature value commit baba42ae25a9a90cc53aae0d99ad634d7e57df6c Author: Marco H Date: Mon Nov 29 10:36:31 2021 +0100 Fix changelog syntax commit cd674865479142016b7cb51844b75fbb7f91305f Author: Marco H Date: Mon Nov 29 10:25:14 2021 +0100 Update ChangeLog commit 765a683c894b1e09e1aae1c450b48a53db5b54a6 Author: Marco H Date: Mon Nov 29 10:23:54 2021 +0100 Update app.js Improving messages and added Celsius sign commit 30e421e225c329423d77f5dae7e1d69a6ba7df73 Merge: 94f8b4bc 918dcba6 Author: Gordon Williams Date: Mon Nov 29 08:38:52 2021 +0000 Merge pull request #960 from leer10/master Add 93 Dub Watchface commit 918dcba633d7e9cdb6aa6017f0961006afcb0a88 Merge: bb537b17 050b9c2b Author: leer10 Date: Sun Nov 28 14:58:18 2021 -0800 Merge pull request #1 from leer10/style-cleanup style cleanup commit 050b9c2b807c5e66405a8549bbfa47e4a1421f33 Author: leer10 Date: Sun Nov 28 14:56:18 2021 -0800 Update apps.json commit ada93e894d76497dd48956020cd3dc3649441dbf Author: leer10 Date: Sun Nov 28 14:55:46 2021 -0800 Update ChangeLog commit 590f022a91c430a832df0d9c64d9cde837b82cdf Author: leer10 Date: Sun Nov 28 14:55:32 2021 -0800 Update ChangeLog commit f423a6b91bbd698e72fa6a7cc002b068f506e291 Author: leer10 Date: Sun Nov 28 14:54:17 2021 -0800 Update app.js commit bb537b1738573c756207cb883c4ed8fd95256bb0 Author: leer10 Date: Sun Nov 28 14:27:14 2021 -0800 Update ChangeLog commit 656ca2ecaa8288bfc69c9f3a1ebbbdf2b1c56f36 Author: leer10 Date: Sun Nov 28 14:25:23 2021 -0800 Update apps.json added new version in json commit 438885ae922f25a3927bc5b785f2bba64d6272ee Author: leer10 Date: Sun Nov 28 14:24:18 2021 -0800 Add files via upload commit b9b7cfb50cfc62401a768653d9b4fd910256840c Author: leer10 Date: Sun Nov 28 14:23:49 2021 -0800 Delete screenshot.png commit 36aead94e7683da9aaf46601e28267ccf386a8aa Author: leer10 Date: Sun Nov 28 14:23:24 2021 -0800 Create ChangeLog commit b2cb4e7c0a84a49abfa0e04d16e2471b829d5b40 Author: leer10 Date: Sun Nov 28 14:22:04 2021 -0800 Add files via upload commit b25ad7573e19ccf6f617381e5ac78260ddeef36a Author: leer10 Date: Sun Nov 28 14:21:57 2021 -0800 Delete screenshot.png commit c3fac095b83c9936dedef8dad70578b4593923db Author: leer10 Date: Sun Nov 28 14:19:21 2021 -0800 Update app.js add discominotaur's adjustments (cause a battery on the watchface isn't useful when the widget does the work anyways) maybe i'll do it as a setting later commit 426ec0350fff5ce87dd2e8a6096c80f2f0e1b448 Author: leer10 Date: Sun Nov 28 14:10:47 2021 -0800 Update README.md added credits commit ba50674173c0fae02948c69fb8eaa0098ae4efe3 Author: Balint Kovacs Date: Sun Nov 28 18:58:26 2021 +0000 Update app versions and changelog commit 1a118a60374099538f65f24b347907b1ac12ea25 Author: Balint Kovacs Date: Sun Nov 28 18:44:47 2021 +0000 Recorded: Slightly improve plot altitude if data has NaNs commit 22fa78ff8d82e3a0512a3538278cc8e0ff735b28 Author: Balint Kovacs Date: Sun Nov 28 18:43:44 2021 +0000 Even out x axis grid points commit 466fd2155c81f44cfd30c7e3f15f460f5a8662c0 Author: Balint Kovacs Date: Sun Nov 28 18:18:18 2021 +0000 Remove superfluous semicolon commit a622781628c35eca58831c36e658e36b9a752712 Author: Balint Kovacs Date: Sun Nov 28 16:46:01 2021 +0000 Make the recorder handle missing coordinates in plot speed commit 69c6a34ead08410eee37000d7405f287aa416548 Author: Balint Kovacs Date: Sun Nov 28 15:46:02 2021 +0000 Fix some text overflowing the screen in recorder and gpsrec On Bangle.js 2 commit 616afad05616b13ca1d3618b5c899add6ab9624b Author: James Date: Sun Nov 28 14:10:29 2021 +0000 Title indent again commit 41c80ae76793e7bce50cd51f09a92cad48551c3b Author: James Date: Sun Nov 28 14:08:30 2021 +0000 Indent logo slightly to line up more accurately commit 617ed688c532f77bac0e09f3a5d10fcb796d2f77 Author: James Date: Sun Nov 28 14:05:49 2021 +0000 Use rem commit a28b3b78e407091fb5880be2c6801686b4f0bec2 Author: James Date: Sun Nov 28 13:58:41 2021 +0000 Add spacing to layout, small css tweaks commit 6fc1e738f1e1bdaaa45bb2ea34b33d97be3f37ee Author: James Date: Sun Nov 28 13:22:42 2021 +0000 Add mandlebrot clock app commit 89e88e717211d8c80b0e258114be7498722aa783 Author: leer10 Date: Sat Nov 27 23:39:51 2021 -0800 Update app-icon.js hopefully fix launcher icon commit 40d19aad2e4d672171b4feeee6b9c6f4cdbb11a1 Author: leer10 Date: Sat Nov 27 22:29:57 2021 -0800 Update apps.json added screenshot to app store listing commit d87930e4d37ea5248b7de93825735967e75030b3 Author: leer10 Date: Sat Nov 27 22:27:51 2021 -0800 Update apps.json commit 6eb7a844d6839456c13a4402c5212b9bb9dbd3ad Author: leer10 Date: Sat Nov 27 22:26:36 2021 -0800 Update app.js fix battery graphics commit da41d04d2681afd5bafe9f39660ca6c8a15a787a Author: leer10 Date: Sat Nov 27 22:20:21 2021 -0800 Update apps.json commit 47c8edba4f040716d5860b56588a98687914ac36 Author: leer10 Date: Sat Nov 27 22:19:25 2021 -0800 Add files via upload commit b28986c249a952edaac1b5e4b624ab357dcb81c3 Author: leer10 Date: Sat Nov 27 22:19:09 2021 -0800 Delete app.png commit 9e897dfd50c2ff4cc6c012724305e5e079b02dab Author: leer10 Date: Sat Nov 27 22:13:21 2021 -0800 Update app.js removed other nonfunctional comment block commit 6fd7a0eb633ac47eea07c2befe8f0a96bda19a02 Author: leer10 Date: Sat Nov 27 22:11:06 2021 -0800 Update app.js battery icon actually works now commit 4a3e1bbe28e3180ab04685646a4e41de07993cf4 Author: leer10 Date: Sat Nov 27 21:52:13 2021 -0800 Update app.js 12 hr/24 hr specific behavior now from settings instead of hardcoded commit 3d03895b9dc97c6f7bb20f68e64619612b89cf85 Author: leer10 Date: Sat Nov 27 21:44:49 2021 -0800 Update README.md commit 0d5892769d6862ed8a56dcfcf3fd960893cec688 Author: leer10 Date: Sat Nov 27 21:42:19 2021 -0800 Add files via upload add screenshot for 93dub commit 82e515e0e5c05cd89f871f33fb24654e1e26d5b0 Author: leer10 Date: Sat Nov 27 21:39:55 2021 -0800 Create README.md added dub93's readme commit 8a3f9f848a4dc98f0f1108c46e406ba8007aa45b Author: leer10 Date: Sat Nov 27 21:36:48 2021 -0800 Update app.js stripped license and info block of text since it's already enclosed in an MIT-licensed repo commit 4294a27279f7482cb9abe10fe22d254f2a9a7073 Author: leer10 Date: Sat Nov 27 21:31:41 2021 -0800 Update apps.json apps.json updates commit 251ceb9dd1ee7064f86c4056a280169f299311d9 Author: leer10 Date: Sat Nov 27 21:27:35 2021 -0800 Update apps.json oops comma commit b49223d5b95c3802ca5b9a7e2478a227ad888652 Author: leer10 Date: Sat Nov 27 21:24:09 2021 -0800 Update apps.json commit 2d21ce74459871c238dc12d2ed04c212bd1d814e Author: leer10 Date: Sat Nov 27 21:21:29 2021 -0800 Add files via upload commit c0e5d4432eb48ae7c83d1c62f28a8b8abdc1438b Author: leer10 Date: Sat Nov 27 21:19:34 2021 -0800 Create app-icon.js added icon commit 0d6bfc7c13f024f36e9703dbb4b88289756621f5 Author: leer10 Date: Sat Nov 27 20:59:32 2021 -0800 Update app.js redid background, adjusted graphics to look nice on bangle 2 commit 17e13a63253c868ffc16ad6f11a62ac3e2973c9e Author: Alain Saas Date: Sun Nov 28 13:43:31 2021 +0900 Update apps.json commit a19da85de7e3c880030397b1d89f3f086a0a4e27 Author: Alain Saas Date: Sun Nov 28 13:41:56 2021 +0900 Update README.md commit 9d4c251b730c655dec6fd709a29ca4a4d4c861ff Author: Alain Saas Date: Sun Nov 28 13:39:41 2021 +0900 Update apps.json commit f9fa4a7df132b5a2bf8c804c4164f5c4afb5798c Author: Alain Saas Date: Sun Nov 28 13:32:58 2021 +0900 Update apps.json commit ff95dd3b2c9a74d0173227a88cb1d171639996d1 Author: Alain Saas Date: Sun Nov 28 13:29:06 2021 +0900 Create README.md commit c23960c12c0460cfb015082799f218d8d7e86859 Author: Alain Saas Date: Sun Nov 28 13:20:48 2021 +0900 Add files via upload commit d9d6133559f55421e8b38b2d63eef3e2c549bfd8 Author: Alain Saas Date: Sun Nov 28 13:20:15 2021 +0900 Create ChangeLog commit de4d744e266a47aa072cd1f07c6f2362d62efd10 Author: Alain Saas Date: Sun Nov 28 13:19:15 2021 +0900 Create app-icon.js commit de9a526517577136b2060e0d5138b943cc0951fe Author: Alain Saas Date: Sun Nov 28 13:14:06 2021 +0900 Add files via upload commit 662963b2089e0e8bc6f0d1548202462833143d46 Author: Alain Saas Date: Sun Nov 28 13:06:47 2021 +0900 Create app.js commit 56f3044e5e5fedbbddffc9810e24135cca7acfbf Author: leer10 Date: Sat Nov 27 12:02:34 2021 -0800 Update app.js background needed redraw after notification background redraw broke widgets, so temp fix commit 228a3664c7ab9774a8dad99f05fc1bf3c5570e61 Author: leer10 Date: Sat Nov 27 11:41:39 2021 -0800 Update apps.json commit 33b3e918693959e9828cafa1354b6df3a5a5c90d Author: leer10 Date: Sat Nov 27 11:40:13 2021 -0800 Update apps.json commit 7d646945df493e7c95a51c7ce6e7224662150090 Author: leer10 Date: Sat Nov 27 11:37:56 2021 -0800 Update apps.json commit dabaa06efbe3698e11afad390bb06d3e48c93f12 Author: leer10 Date: Sat Nov 27 11:33:19 2021 -0800 Create app.js commit 3fbb46b046c65d8d9f1a37b600bddc0ee1e16e03 Author: hughbarney Date: Sat Nov 27 11:23:03 2021 +0000 Pastel, recalc sunrise,sunset every hour commit 21fe6e7ea486ee553bd1bac8399d153c50171380 Author: hughbarney Date: Fri Nov 26 21:52:05 2021 +0000 Pastel added dependancy on MyLocation app, display sunrise,sunset times commit b426c479a32595b592acc1eb68a202e3ed5f0c17 Author: hughbarney Date: Fri Nov 26 21:29:46 2021 +0000 Pastel added dependancy on MyLocation app, display sunrise,sunset times commit 070558a0a62027fc67e9d54b45ef81e2166d6fab Author: hughbarney Date: Fri Nov 26 20:48:27 2021 +0000 MyLocation - adds menu to set preferred city or setup from GPS commit 6220a88d29ace89e386ae3d7630c112bc8905b73 Author: Richard de Boer Date: Fri Nov 26 21:29:58 2021 +0100 locale: Apply 12hour setting to time Fixes #892 commit ce0e50ed949eeffc97bd2ec3db1fdb38830c3e4e Author: hughbarney Date: Fri Nov 26 20:25:28 2021 +0000 MyLocation - adds menu to set preferred city or setup from GPS commit 4f5ec608de77dd4febf68db0b6d3aa9703b73b16 Author: James G Date: Fri Nov 26 12:48:20 2021 -0500 fix formatting in README for interval timer app commit 2ae9585193c1394bca43a9160dcfbcdd29f14803 Author: James G Date: Fri Nov 26 12:43:36 2021 -0500 rename intervalTimer.app.js to app.js commit bff43e662da03dfd1648ef656062195689448236 Author: James G Date: Fri Nov 26 12:42:13 2021 -0500 Fix url for intervalTimer.app.js in app.json commit fc6ecaccce783eb5bf6d3571b885bdfcf78912be Author: James G Date: Fri Nov 26 12:35:35 2021 -0500 Add new Interval Timer app. commit d1534bdcbf2281343f023d4c8aada9169283ac84 Author: Gordon Williams Date: Fri Nov 26 15:05:05 2021 +0000 comment commit 94f8b4bca79a0b79ad0e3635ad56786722bfa802 Merge: dc8edba0 4cfbe11e Author: Gordon Williams Date: Fri Nov 26 12:01:01 2021 +0000 Merge pull request #947 from peerdavid/master [LCARS clock] Alarm works also if clock is closed and opened again. commit dc8edba00ddf236c79279313f36a05795bf9e3ac Merge: db1c5b74 fa4fd118 Author: Gordon Williams Date: Fri Nov 26 11:59:41 2021 +0000 Merge pull request #948 from Smooklu/master Updated fd6fdetect commit db1c5b74817a3be17f923104138e6f46c03bb514 Merge: a4299586 045251f5 Author: Gordon Williams Date: Fri Nov 26 11:59:15 2021 +0000 Merge pull request #949 from johan-m-o/master Update Spirit Level to work on Bangle.js 2 commit 045251f55f9a71f755ffdcdb120e032dc437096a Author: johan-m-o <85756863+johan-m-o@users.noreply.github.com> Date: Fri Nov 26 11:50:19 2021 +0100 Update spiritlevel.js commit b6e5175675890222b1f23318a2b466dcf6302238 Author: johan-m-o <85756863+johan-m-o@users.noreply.github.com> Date: Fri Nov 26 11:44:21 2021 +0100 Update spiritlevel.js commit 6f300299b55f60098d262c02e0c7ed1a5576fc38 Author: johan-m-o <85756863+johan-m-o@users.noreply.github.com> Date: Fri Nov 26 11:34:52 2021 +0100 Update apps.json commit fe5ca8bc76b9c1a1d28159af6dba92af14fd4e57 Author: johan-m-o <85756863+johan-m-o@users.noreply.github.com> Date: Fri Nov 26 11:33:49 2021 +0100 Update spiritlevel.js commit a89dd4d544b306acb94edeb63de6a90e1e946565 Author: johan-m-o <85756863+johan-m-o@users.noreply.github.com> Date: Fri Nov 26 11:23:43 2021 +0100 Update ChangeLog commit a4299586e8055425f1ea638090ac267081845a76 Author: Gordon Williams Date: Fri Nov 26 10:04:02 2021 +0000 cscsensor 0.06: Now read wheel rev as well as cadence sensor Improve connection code commit fa4fd118e28787458623159617600b4d42432e98 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:20:52 2021 -0600 Update apps.json commit 43b447f81c3f40b1c042a9551ec71a1f29aa4d91 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:17:35 2021 -0600 Update apps.json commit 1ea1706e61149214a3d423b2a9eeba7ae1ca1eaf Merge: 08fd95ab 095165c5 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:04:40 2021 -0600 Merge branch 'espruino:master' into master commit 08fd95ab9a3cb50f26605cebb4ae7411c1823c48 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:04:09 2021 -0600 Update README.md commit bc27677f5ef33bf85d67df951edae6dce437248e Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:02:43 2021 -0600 Update apps.json commit f9286cbee97efeb9c63f2672b520e8976e59e45a Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:00:48 2021 -0600 Update README.md commit a1a56601c0579d4a9e9756eb83bfcd8a802a9510 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:00:38 2021 -0600 Update README.md commit 4cfbe11e45690f31e3010b7234a26e3ec3695dff Author: David Peer Date: Thu Nov 25 20:00:36 2021 +0100 Show text for each icon. commit 4fb4d12ba48dee2869338cf1d4e4675e18a0d86a Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 13:00:28 2021 -0600 Update README.md commit 6508ed8b3fc99d0a39fb460a47f7d989c6f3eb7b Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 12:57:25 2021 -0600 Update apps.json commit 85b7115c731479ede76db6c659a071f9390dd352 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 12:54:33 2021 -0600 Update README.md commit 6482297881ddfeef3202ae235e1e4a38f1826f9b Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 12:53:16 2021 -0600 Update ChangeLog commit f5940b5bdbc0fc3118544821b6508f78f10a59f1 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 12:52:27 2021 -0600 Update README.md commit 9f002934015e4bacc43a652703418d9c8ad7c29e Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 12:50:35 2021 -0600 Update README.md commit 2818a63e2c6d3116001eca6e0ddf852825dfdd55 Author: Smooklu <37220586+Smooklu@users.noreply.github.com> Date: Thu Nov 25 12:48:36 2021 -0600 Create README.md commit 95f845ad4e9408081b9ecf882ad85012bbb4bc7d Author: David Peer Date: Thu Nov 25 19:10:05 2021 +0100 New icon for alarm commit ca3453440c8171ffb53a9d0a69cdfc516f454e56 Merge: dcee49cd 4a530371 Author: David Peer Date: Thu Nov 25 19:01:24 2021 +0100 Merge branch 'master' of https://github.com/peerdavid/BangleApps commit dcee49cdc89867584d140d3cc318b7dabbf930b9 Author: David Peer Date: Thu Nov 25 19:01:22 2021 +0100 New GPS Icon commit 4a5303714d952d0d63df60a9d9f64af9e79a97e0 Merge: 93e2a88a 095165c5 Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Thu Nov 25 18:52:23 2021 +0100 Merge branch 'espruino:master' into master commit 93e2a88a4c42968ab7260a3b56ef0e3a477cf47f Author: David Peer Date: Thu Nov 25 18:51:20 2021 +0100 Updated screenshot commit d99cea9ae0c280c2d765dd0d9b53d7ad82b5a2ad Merge: 232dcc4b 7e1b0422 Author: David Peer Date: Thu Nov 25 18:49:46 2021 +0100 Merge branch 'master' of https://github.com/peerdavid/BangleApps commit 232dcc4b9df3a85b09f1b296a769fead4ea634cb Author: David Peer Date: Thu Nov 25 18:49:44 2021 +0100 Real icons - its an image of the real planet :) commit 095165c5c9673c3322f2a271528a112d1749878b Author: Gordon Williams Date: Thu Nov 25 16:33:45 2021 +0000 oops - fix uncommitted file! commit bf964ce3e4ecdea91718f9dc50052c47f7ac97f2 Author: Gordon Williams Date: Thu Nov 25 16:06:26 2021 +0000 The 'update all' button shouldn't update apps that require 'custom.html' (fix #748) commit 7e1b04225511997c8e4557b5c3f0e58cef2986d1 Merge: ccce57ae 944b24e6 Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Thu Nov 25 16:56:53 2021 +0100 Merge branch 'espruino:master' into master commit ccce57ae89a8d2a19d9d171a50bc39c94a673cc6 Merge: a99d9d5e c381e7ef Author: David Peer Date: Thu Nov 25 16:56:35 2021 +0100 Merge branch 'master' of https://github.com/peerdavid/BangleApps commit a99d9d5e7c649ab498c1ef5b459c2647f52c5703 Author: David Peer Date: Thu Nov 25 16:56:32 2021 +0100 Store alarm in settings commit 944b24e6c34068432786b44343f20c73c56ebf53 Merge: e8264cc8 1b9477be Author: Gordon Williams Date: Thu Nov 25 15:52:25 2021 +0000 Merge branch 'master' of github.com:espruino/BangleApps commit e8264cc8f8c7cde0e88cef06347c9ca67f8dae9e Author: Gordon Williams Date: Thu Nov 25 15:50:07 2021 +0000 messages 0.07: Added settings menu with option to choose vibrate pattern and frequency (fix #909) commit 5f5ca64cb4d305094907e368d8f0e344b694e304 Author: Gordon Williams Date: Thu Nov 25 15:21:59 2021 +0000 android 0.04: Android icon now goes to settings page with 'find phone' commit 6aa6bcf17977e127ef1879cfdb11ce3b972b1772 Author: Gordon Williams Date: Thu Nov 25 15:12:04 2021 +0000 messages 0.06: New messages now go at the start (fix #898) Answering true/false now exits the messages app if no new messages Back now marks a message as read Clicking top-left opens a menu which allows you to delete a message or mark unread commit 1b9477be5d4c5af923b7ef435ae08b721171b7bf Merge: e28f9c15 2b7091bd Author: Gordon Williams Date: Thu Nov 25 12:19:48 2021 +0000 Merge pull request #945 from nlisgo/improve-ux-add-timer Cube Scramble: Improved UX and display solve time commit 2b7091bd6b8c12e3c5bc75244e0eba38f9b223e9 Author: nlisgo Date: Thu Nov 25 11:40:37 2021 +0000 Set default title for showPrompt commit c381e7ef2196963dcc5414fdf583e179122e0362 Merge: 1ab98707 e28f9c15 Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Thu Nov 25 11:41:01 2021 +0100 Merge branch 'espruino:master' into master commit e28f9c157b2540a87387041f54a35ea50572e8c9 Merge: e040cc4e cb9866ff Author: Gordon Williams Date: Thu Nov 25 08:55:39 2021 +0000 Merge pull request #932 from hughbarney/master Pastel: created font modules commit 1ab98707eda9543a4792627c1c91884059345bc0 Author: David Peer Date: Thu Nov 25 09:17:25 2021 +0100 Minor changes commit 9940b38bbd0f53640b4a4ea2e0d70691bae04cea Author: nlisgo Date: Thu Nov 25 00:13:06 2021 +0000 Force LCD on commit f175f4c48c149b7b4b6a317db8105790b97a0f6a Author: nlisgo Date: Thu Nov 25 00:06:02 2021 +0000 Update screenshots commit f6c689eeedfa4d349e2f73cdfabbd0a641502735 Author: nlisgo Date: Wed Nov 24 23:56:47 2021 +0000 Amend app description commit 3c984f1fee70a8af17476a2b751a5c8b128aec36 Author: nlisgo Date: Wed Nov 24 23:52:28 2021 +0000 Cube Scramble: Improved UX and display solve time commit cb9866ffe23bbbff7e6c44edc4ef437a27bdee29 Author: hughbarney Date: Wed Nov 24 21:11:47 2021 +0000 Pastel: updated screenshots and README commit 8b46634c9bb7ea17e4824abbdf7c1cb21859e62d Author: hughbarney Date: Wed Nov 24 21:05:45 2021 +0000 Pastel: updated screenshots and README commit cbb38ec1ceb54db23826c476e0efdbd496b048a6 Author: hughbarney Date: Wed Nov 24 20:18:29 2021 +0000 Pastel: added cycle through info items to bottom of screen commit 469c3296404703ca27ce52a55c4a67fc416ca520 Merge: 37ca6251 e040cc4e Author: hughbarney Date: Wed Nov 24 19:59:57 2021 +0000 Merge remote-tracking branch 'upstream/master' commit 37ca6251742ddce653e5d04819fa16a8efdce29f Author: hughbarney Date: Wed Nov 24 19:59:46 2021 +0000 Pastel: added cycle through info items to bottom of screen commit c6096675fb65d43ef2a037a1325ef160b812fec5 Author: hughbarney Date: Wed Nov 24 19:06:06 2021 +0000 Pastel: added cycle through info items to bottom of screen commit a537e98116a932422a10c043b001a96911c65d3d Author: David Peer Date: Wed Nov 24 18:04:59 2021 +0100 Font improvements commit 59692c8ca175c17c6ea81f203855cb029baa0ee6 Merge: 657e64b0 e040cc4e Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Wed Nov 24 17:52:48 2021 +0100 Merge branch 'espruino:master' into master commit 657e64b078eda64cd6817959cbdc8a3bc71bb580 Author: David Peer Date: Wed Nov 24 17:52:25 2021 +0100 Added readme also to app.json commit e040cc4e245a8fb4c55bfeb99cab12c62af5e7b5 Author: Gordon Williams Date: Wed Nov 24 15:22:16 2021 +0000 replace tabs! commit 60c2fa710c4904827bfba868507a9f6d10d524a3 Merge: 38b2e417 f3cb7e9a Author: Gordon Williams Date: Wed Nov 24 13:29:46 2021 +0000 Merge pull request #942 from madman2021/master Add new TimeCal app commit 38b2e417bf8e63be394a96ed24b9e3d174d5f45b Merge: 94bd895b 43b38cc8 Author: Gordon Williams Date: Wed Nov 24 13:26:43 2021 +0000 Merge pull request #943 from peerdavid/master [LCARS Clock] Shows icons for charging and out of battery commit 94bd895bafeb37250b64373692c9cceb3e9ece97 Author: Gordon Williams Date: Wed Nov 24 12:56:56 2021 +0000 welcome 0.14: Turn off and run later to use softOff to time is set right plus other minor tweaks commit 43b38cc8ab5796e25f65ace531be68a6a4134f98 Author: David Peer Date: Wed Nov 24 13:40:47 2021 +0100 New screenshot. Updated version. commit 34c6589f06a1a8ba0f7fe2e126b41d03dff7f45b Author: David Peer Date: Wed Nov 24 13:37:07 2021 +0100 Minor improvement commit c403a5af671cf70b18776fad83126adf66122f0f Author: David Peer Date: Wed Nov 24 13:36:21 2021 +0100 New design. Removed png icon files - only converted icons are needed. commit 19655ea3279daf32ebfd4453db398915a8229946 Merge: 274b705c b1fb0e6b Author: David Peer Date: Wed Nov 24 13:22:44 2021 +0100 Merge branch 'master' of https://github.com/peerdavid/BangleApps commit 274b705c1e7313cf646412ec01bf17de9b1dabcf Author: David Peer Date: Wed Nov 24 13:22:37 2021 +0100 More lcars style commit f3cb7e9a0b8f0ba3624b639415c9168c240905e8 Author: Jordan Coulam Date: Wed Nov 24 10:53:14 2021 +0000 Remove Icon as it renders massive commit 1a9f5375557fc232acfe3f42d1198da827db5ab8 Author: Jordan Coulam Date: Wed Nov 24 10:46:03 2021 +0000 Add missing supports tag for TimeCal commit 3738bde22a0d4cef2bd5c956a1a370e9a145689a Author: Jordan Coulam Date: Wed Nov 24 10:43:38 2021 +0000 Add TimeCal to the app library Add TimeCal to the app library commit b1fb0e6b7d88f53cff85f6a8d3eb416bebd35e92 Merge: 559e8208 dabc22c2 Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Wed Nov 24 11:10:36 2021 +0100 Merge branch 'espruino:master' into master commit dabc22c2d725ccddad8b08c0fa0b14af94d38e28 Author: Gordon Williams Date: Wed Nov 24 09:54:11 2021 +0000 custom code works on bangle2 commit 2e83a511d2032736a63bda38406b4f744a4130f1 Author: Gordon Williams Date: Wed Nov 24 08:51:20 2021 +0000 metronome supports bangle 2 now commit cea51d06d07f09923d590357c33782861c342817 Merge: cd1daba0 4eee3f05 Author: Gordon Williams Date: Wed Nov 24 08:50:24 2021 +0000 Merge pull request #938 from bengwalker/master Add Bangle.js 2 support for metronome app commit cd1daba0c55e99f5a477407f47b932d050c0b6f2 Author: Gordon Williams Date: Wed Nov 24 08:46:13 2021 +0000 0.25: Fix issue where if Bangle.js 2 got a GPS fix but no reported time, errors could be caused by the widget (fix #935) commit c03ab08687bbc7ed893ed2ef8c3be21f1e61e74f Merge: 1750c72e f10bf240 Author: Gordon Williams Date: Wed Nov 24 08:40:53 2021 +0000 Merge pull request #939 from Ronin0000/master Add Screenshots to Many Apps commit 1750c72e94eab6ee22650d993ea31efa17e79c46 Merge: 5eeb1181 1def233d Author: Gordon Williams Date: Wed Nov 24 08:38:06 2021 +0000 Merge pull request #936 from Vingelar/master Binwatch: re-format background images commit 559e82088077ba79675c0012c921eae3ef32b16d Author: David Peer Date: Wed Nov 24 07:14:04 2021 +0100 Minor design change commit d24b8c80da7afd75a6f121a22e3694252aa3c57a Author: David Peer Date: Wed Nov 24 07:12:25 2021 +0100 Minor design chnges commit f10bf24018add2df61a5fc422aee941b07c70082 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 17:04:07 2021 -0800 Update apps.json commit c66b0982368a5e1ee74da598945df12d88cba679 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:53:48 2021 -0800 Update apps.json commit 638fea73c791b4f11b6119c02ca2090c31b6bc83 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:24:10 2021 -0800 Add files via upload commit 4e79c896c65b2edc7dfcb7b4b2eb6ae1c96f60ce Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:23:33 2021 -0800 Add files via upload commit 33809d8cdfa7ea3f02941c820b4836f20a9eb869 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:22:58 2021 -0800 Add files via upload commit 6cb83284a7e7b9d2f8935835702e713f0f9b7b51 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:22:45 2021 -0800 Add files via upload commit 7e521d0d29262227a32244d2929eb99fcb36fb98 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:22:17 2021 -0800 Add files via upload commit 9985ff03f20469897ceb3dd1acb4f90ac850ebb8 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:22:00 2021 -0800 Add files via upload commit 6f437c39866562e05d8821bdb5150cd553f3a6cf Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:21:15 2021 -0800 Add files via upload commit ffe218a0046d65464e96cdc59d1c10fbb708b791 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:20:56 2021 -0800 Add files via upload commit 9400133dd49762a7bfcff38e5a6249cbfd5753f7 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:20:39 2021 -0800 Add files via upload commit 76463d927940f590ed45cc51558723375217a34a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:19:37 2021 -0800 Add files via upload commit 4011accb47eb53954acc3e27cce5b6f6cb025c57 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:19:19 2021 -0800 Add files via upload commit bc5960d61a40c08566a8e1977fa53c6528f04a85 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:19:07 2021 -0800 Add files via upload commit da5634beda72243f5ee6e4fc0e376c6c5f9c6ccc Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:18:51 2021 -0800 Add files via upload commit b9c4640f853d4992e57cd5d6b2e3f4d75db32d1f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:18:25 2021 -0800 Add files via upload commit d27a605a24cc06903084b6a796c9c93b7724150f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:18:07 2021 -0800 Add files via upload commit 52baa42e69b1a7a8ef6bc2cae548298af4dcbf7c Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:17:48 2021 -0800 Add files via upload commit db3b6a58e49a3d5ce9b528011f3e0607474e4fa8 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:17:16 2021 -0800 Add files via upload commit f0de0d8a9d542fd960f13b36a2bb2a3548f06033 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:16:52 2021 -0800 Add files via upload commit 6d4cb98ba83d0ab62406c00ed9fa8dcd139d2f8c Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:16:34 2021 -0800 Add files via upload commit 5f434d9d327fff8cebf41a45cf73ea9c96cb42db Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:16:23 2021 -0800 Add files via upload commit 6e72349f05e3773b0ae60217df8b6f266447f1ce Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:15:37 2021 -0800 Add files via upload commit 03e4d0d7c01cdc214526891933f3c155f63ff2b5 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:15:21 2021 -0800 Add files via upload commit ead12a1c11e3937637e8af8b1d54218e0138e908 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:14:54 2021 -0800 Add files via upload commit a1ed32c91380e03146dc4003a3ee6e400d0dd35f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:14:30 2021 -0800 Add files via upload commit fae08d7a739b1a28faacb0105d5ad417171dddcb Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:13:57 2021 -0800 Add files via upload commit b889e431edf72d64867c576135bc1470c4590db2 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:13:32 2021 -0800 Add files via upload commit f177480160184722b935623ebed05ad630a5a6a2 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:13:02 2021 -0800 Add files via upload commit a2fe8c3722f56c59957642cad2bb0a6454dc6f5b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:11:42 2021 -0800 Add files via upload commit c1cdf15bf5413167692e9c7bd4f5fee31fe4d4c1 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:10:49 2021 -0800 Add files via upload commit fb1c5529f037cc701e30d9da036a54236ea1ba1d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:10:11 2021 -0800 Add files via upload commit 530089e0830473574b38c172a964f9cfb49436a3 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:09:35 2021 -0800 Add files via upload commit 3556e668560587c074ad435b977283e19367f69e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:09:12 2021 -0800 Add files via upload commit e1e32772e4dd1943af6ed37407425998b0819e48 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:08:56 2021 -0800 Add files via upload commit 8084bb92b7cfb12740129c57e1bb5c05ce13994c Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:08:37 2021 -0800 Add files via upload commit 2c997d2964d4ade4ba0aa5ef89a1b646c15a9751 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:08:18 2021 -0800 Add files via upload commit 747626b66c880293481bd0a97cda8e32e0239d04 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:07:24 2021 -0800 Add files via upload commit ed36fae0ac6def24ca20ab6229affbcf7502582e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:06:59 2021 -0800 Add files via upload commit e8baad3c3775e26f8a88457ff8f361a18572e484 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:06:33 2021 -0800 Add files via upload commit 1efcebe84aa2b2b00d6920a84d4e486b834c1083 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:06:16 2021 -0800 Add files via upload commit 082d3d1e95e9bb98e10bb1679ae0dfba11bf44e0 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:05:21 2021 -0800 Add files via upload commit b10f62a6c55dd89bb15a97430b74269486a72807 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:04:58 2021 -0800 Add files via upload commit 24b41c2c6fe40d18ffd9dfc0404f215cc9b847ff Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:04:42 2021 -0800 Add files via upload commit 19a2ef1a44c78fe9b1922574f0a1eda20f2fbd43 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:04:01 2021 -0800 Add files via upload commit 7089d6e74c438d3577ebf03857b0c1b6f73aaa2a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 16:03:38 2021 -0800 Add files via upload commit 431824f828f0ea900c9d206e492cc7a6d1830f2e Merge: 15aa41c7 5eeb1181 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 15:15:57 2021 -0800 Merge branch 'espruino:master' into master commit 5eeb1181d049f1580f75657b9a9ac664041b26b9 Merge: 546a0b16 6b05d928 Author: Gordon Williams Date: Tue Nov 23 20:29:18 2021 +0000 Merge pull request #937 from rigrig/barclock-b2 Barclock works fine on the Bangle.js 2 :-) commit 15aa41c766b2a25c7a83a1a6744706a7b2852aa3 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 12:23:03 2021 -0800 Add files via upload commit 6a93494e3fe516ccbc7755027f613bd9bd529021 Merge: 12443640 546a0b16 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 12:22:27 2021 -0800 Merge branch 'espruino:master' into master commit 546a0b16cc32841b38a0d39b07ec6d18f58d21c5 Merge: cb6e14f6 18fbd289 Author: Gordon Williams Date: Tue Nov 23 20:20:55 2021 +0000 Merge branch 'master' of github.com:espruino/BangleApps commit cb6e14f6c12816224bbc3dc127e9817d0df7ae78 Author: Gordon Williams Date: Tue Nov 23 20:20:37 2021 +0000 messages, start of call handling and message responses, fix for scroll issue when only 2 menu items commit 12443640c95efbe9f25ed0ffe73280c84d90cd13 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:54:22 2021 -0800 Update apps.json commit 9bdc07f8617e457439522d5b4c84a65d1eba4ed9 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:47:36 2021 -0800 Update apps.json commit 4eee3f05e92e26aa5c70c1d2cefcc97ff4935b0d Merge: aafc93f0 18fbd289 Author: bengwalker <63957296+bengwalker@users.noreply.github.com> Date: Tue Nov 23 20:46:32 2021 +0100 Merge branch 'master' into master commit 298fa47cd87e37b19cd142f47867843e24d08b57 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:42:50 2021 -0800 Update apps.json commit 52c07f6dc80e8eabd017fc324332c0594c173399 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:40:42 2021 -0800 Update apps.json commit fe340d75bbb6c7814241becacddaca50435c5fe3 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:39:31 2021 -0800 Update apps.json commit aafc93f09a818f5bb6e4b6988246e4f8d049df87 Author: bengwalker <63957296+bengwalker@users.noreply.github.com> Date: Tue Nov 23 20:35:35 2021 +0100 Update README.md update README commit bd80ea5ca03b2e9d5f2eb562adc7305b3952d2e5 Author: bengwalker <63957296+bengwalker@users.noreply.github.com> Date: Tue Nov 23 20:31:33 2021 +0100 Update metronome.js print instructuions for banglejs2 commit 51afd5ef049c67f331931ee18b53e9d4e835342a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:29:27 2021 -0800 Add files via upload commit ff62b603a27d6acea382af80496b6a35787a73ce Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:28:51 2021 -0800 Add files via upload commit ffbd331c1376c5f393dafe62eaa62a9991949a3e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:28:29 2021 -0800 Add files via upload commit 93c113a95a21dccfde6bb171d15b0f93e6d0f58a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:27:25 2021 -0800 Add files via upload commit b2be26fccedfa52f00f275db8050c0c3e532859b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:27:07 2021 -0800 Add files via upload commit 899e78539c3bb0e41e4d56aa854c4806715ccce0 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:26:06 2021 -0800 Add files via upload commit 50a88d41cd63e51a876e4fca58fe13c5af2088fc Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:25:35 2021 -0800 Add files via upload commit b1d636bac2148007dd72becff0daddf24b80f0a4 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 11:25:10 2021 -0800 Add files via upload commit 6b05d928751b49d4910ddd3a6867e2d4cad6c93f Author: Richard de Boer Date: Tue Nov 23 19:42:12 2021 +0100 barclock: Fix time/date disappearing after fullscreen notification By forcing a complete redraw at lcdPower-on commit 32e3d326aa143eed99d26c81c9fbf870730591f4 Author: Richard de Boer Date: Sat Nov 20 17:13:36 2021 +0100 barclock works fine on the Bangle.js 2 :-) commit 1def233de2434d272c6f712c9c213b7caff3ae92 Author: Vingelar Date: Tue Nov 23 19:09:16 2021 +0100 changed format of bg images to binary raw format (export from emulator commit e021aa2c9d5c44f9130e4bf67cb4b066d02cbd6d Author: Vingelar Date: Tue Nov 23 17:59:49 2021 +0100 Update app.js binwatch: adapted names of bg images commit 3dd723d10bd3195257205a48dc79872668bd53cb Author: Vingelar Date: Tue Nov 23 17:58:48 2021 +0100 Update apps.json binwatch: shorten names of background images commit 275402344ee927a51d0c100d4387c739d7a49968 Merge: cf027b37 18fbd289 Author: Vingelar Date: Tue Nov 23 17:36:45 2021 +0100 Merge branch 'espruino:master' into master commit 18fbd2898da9fc2bfb16d0adf9cf2b97f5ce0f3d Merge: 5be6981a df364bab Author: Gordon Williams Date: Tue Nov 23 16:34:15 2021 +0000 Merge pull request #933 from peerdavid/master [LCARS Clock] Added lcars icon to watch face. commit cf027b3783cbbf8deca98fb3e1ee1922557686bf Author: Vingelar Date: Tue Nov 23 17:34:13 2021 +0100 Update app.js changed names of background images commit 5be6981acdf3935b936bb85caf37780537518b66 Author: Gordon Williams Date: Tue Nov 23 16:31:42 2021 +0000 oops - named stub wrong commit d328d94d34ea86dd99f958098c7f0a000b1e395f Author: Vingelar Date: Tue Nov 23 17:30:20 2021 +0100 Add files via upload added background files exported from Emulator commit c36fb16a684085c2eb6ada2c50021d3776f5e215 Author: Vingelar Date: Tue Nov 23 17:28:54 2021 +0100 Delete Background240_center.js removed background240_center.js (wrong format) commit 4719fada2843f1c8d6ae36d8d59d0fb95318d9b5 Author: Gordon Williams Date: Tue Nov 23 16:28:34 2021 +0000 Android Remove messages on disconnect, Fix music control (ref #909) commit f431bd8a2c823e877ee6e78576aa4f39a0b5701f Author: Vingelar Date: Tue Nov 23 17:28:25 2021 +0100 Delete Background176_center.js remove backgounrd176_center.js (wrong format) commit 1b548c9bbb5a10769498b4ad1be04397fb889bce Author: Vingelar Date: Tue Nov 23 17:27:33 2021 +0100 Update apps.json adapted naming for image files commit df364babab19550f75a01d707f0684d8547e8664 Merge: d28517b2 a1eeadfc Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Tue Nov 23 17:16:00 2021 +0100 Merge branch 'espruino:master' into master commit d28517b2a5b5e7eaa6a8d9832d9352062addb3ee Merge: cd93a201 465c93d8 Author: David Peer Date: Tue Nov 23 17:15:18 2021 +0100 Merge branch 'master' of https://github.com/peerdavid/BangleApps commit cd93a201f846e2c51a1ff9cc447dbbbdc2c5e2cc Author: David Peer Date: Tue Nov 23 17:15:15 2021 +0100 Moved logo commit dd2bb22f076abff1aac2f32734b50fdcc5423861 Author: Vingelar Date: Tue Nov 23 17:08:57 2021 +0100 Update apps.json use .js files as background images commit 03c5f996f4998ebc1e6bfea7e77d3a61743c0c69 Author: Vingelar Date: Tue Nov 23 17:07:21 2021 +0100 Add files via upload added background files as js commit 7d81bfe2bbdf5095ac7550247eddbe6827cec4c0 Author: Vingelar Date: Tue Nov 23 16:53:40 2021 +0100 Update apps.json added missing "url" to background storage commit 51b73894e461af6312b6fca28e0b5888e9f98da6 Author: Vingelar Date: Tue Nov 23 16:51:40 2021 +0100 Update app.js use background images from storage commit dab36d05a77563e9a839f38807bfd7cfe09a1f69 Author: Vingelar Date: Tue Nov 23 16:48:50 2021 +0100 Update apps.json added background images to stroage commit 31f28093411e4f501dd49f98359af43e71e8b27e Author: Gordon Williams Date: Tue Nov 23 15:44:49 2021 +0000 Fix https://github.com/espruino/BangleApps/issues/927 - App loader offers to update unknown apps commit a1eeadfc224a976e3fca6a00ca47d1c1389fa70f Merge: 68429483 0a695e51 Author: Gordon Williams Date: Tue Nov 23 15:40:09 2021 +0000 Merge pull request #934 from Ronin0000/master Fix School Calendar Bug commit 0a695e5143fbff3935e80b9df85720f065b1e185 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 07:09:14 2021 -0800 Update custom.html fix bug that was for testing commit cfecc24f42d257d565f21571a50b825cffb2f1c3 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 23 07:05:47 2021 -0800 Delete boot.js commit 684294830d75459982845920cb30815236dc0917 Author: Gordon Williams Date: Tue Nov 23 13:57:46 2021 +0000 app manager works in bjs2 commit 465c93d830300054722f10f483a9023c6ec315e7 Merge: d20f5e59 3ba779ee Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Tue Nov 23 14:53:47 2021 +0100 Merge branch 'espruino:master' into master commit d20f5e597e72d8392af3e9b745a4dfab36e8797f Author: David Peer Date: Tue Nov 23 14:53:27 2021 +0100 Updated screenshot commit a283cf58fb90b1852d8e414fb01010632a65ba46 Author: David Peer Date: Tue Nov 23 14:51:55 2021 +0100 Included lcars logo commit be3345d1433f3fcd4fd2e5f477c53c0e1d92fe22 Merge: e3310ffc 3ba779ee Author: hughbarney Date: Tue Nov 23 13:22:30 2021 +0000 Merge remote-tracking branch 'upstream/master' commit e3310ffc32e9fab87bcafe96b43894dcecc60cc5 Author: hughbarney Date: Tue Nov 23 13:13:17 2021 +0000 Pastel: architect font module commit 3ba779ee5826a60f127ed12f0eeaa2a848f53b4c Author: Gordon Williams Date: Tue Nov 23 11:48:34 2021 +0000 Fix bangleapps after recent PRs commit aaf06b113c72e1487651d30602ba79c95a41d6ff Merge: a0351381 06a6b72d Author: Gordon Williams Date: Tue Nov 23 11:42:26 2021 +0000 Merge branch 'master' of github.com:espruino/BangleApps commit 9600f16671ab5a9fc772a959a7110622baa5e606 Author: David Peer Date: Tue Nov 23 11:19:48 2021 +0100 Updated changelog commit 98577b626960bd971af483ef709655dfe0ac1f00 Merge: 1ccabca0 d3cd47f9 Author: David Peer Date: Tue Nov 23 11:18:52 2021 +0100 Merge branch 'master' of https://github.com/peerdavid/BangleApps commit 1ccabca0c6f1cf79c1b5d6a56749ab752a4d1850 Author: David Peer Date: Tue Nov 23 11:18:50 2021 +0100 No hrm icon - its shown too much. commit d3cd47f95704e7c508e1e311d3224826f3fd73ce Merge: 2e18795c 06a6b72d Author: Peer David <4281901+peerdavid@users.noreply.github.com> Date: Tue Nov 23 11:12:43 2021 +0100 Merge branch 'espruino:master' into master commit 2e18795c5780148c6f52d50cd69849b5893b1cdb Author: David Peer Date: Tue Nov 23 11:11:33 2021 +0100 Fixed string commit 36edd449c5398147536d20c2b4f11040cb3105b9 Author: David Peer Date: Tue Nov 23 11:10:33 2021 +0100 Minor change commit 06a6b72d42fc55a224bb5d133640670c21d6cae0 Merge: a39d4102 be083113 Author: Gordon Williams Date: Tue Nov 23 10:03:45 2021 +0000 Merge pull request #925 from Ronin0000/master Add School Calendar commit a39d4102963fc1593e1f2f8ea3f4372a3da4da6f Merge: ab2cb243 930cfa13 Author: Gordon Williams Date: Tue Nov 23 10:02:41 2021 +0000 Merge pull request #928 from peerdavid/master [LCARS Clock] Icons for different states such as GPS or HRM. commit 5c3b0468d4ce9a51249f6f098c3e6ba84ba1cf41 Author: Vingelar Date: Tue Nov 23 10:59:26 2021 +0100 Update apps.json corrected format commit 336501059da7bceddba9e300c5b6d5bd1aba6a3a Author: Vingelar Date: Tue Nov 23 10:56:25 2021 +0100 Update apps.json removed background image commit 3f4c49a8aef6ba79419f00d86fc4f02435b72e21 Author: Vingelar Date: Tue Nov 23 10:55:07 2021 +0100 Update app.js integrated BG image into app commit ff3223e1b906957811cad815df88ad495e70a95f Author: Vingelar Date: Tue Nov 23 10:51:02 2021 +0100 Update app.js added "require" for bg image commit ab2cb243857e50e7bb80ee163e4bc153302446a7 Merge: adadf7ef 162dc1f2 Author: Gordon Williams Date: Tue Nov 23 09:51:01 2021 +0000 Merge pull request #929 from weeurey/master Update app commit adadf7efd39b01466cfd348e13c5a02deaa6bf4d Merge: b7f403e7 0f9d938f Author: Gordon Williams Date: Tue Nov 23 09:49:26 2021 +0000 Merge pull request #931 from reelyactive/master emojuino@0.02 commit b7f403e79bf5fae387c5f6d0522f49ce917362a6 Merge: f4e997d4 46383d4d Author: Gordon Williams Date: Tue Nov 23 09:49:12 2021 +0000 Merge pull request #930 from rigrig/gbmusic-fix gbmusic: fix "previous" button image commit a03513812956c629f003824b46bb6763734eead8 Author: Gordon Williams Date: Tue Nov 23 09:44:24 2021 +0000 fix download icon on android commit b128f5c15569de9e2be0717f270cfd90e006d5ab Author: Vingelar Date: Tue Nov 23 10:38:02 2021 +0100 Update apps.json added background image to upload commit 930cfa13315046c621a5444632f7b12bbd956fae Author: David Peer Date: Tue Nov 23 09:43:24 2021 +0100 New HRM Icon commit 7f3f7b9eee3c23c922645274dd8d7947def8158d Author: David Peer Date: Tue Nov 23 08:26:37 2021 +0100 Currently, no confidence > 80 is reached... commit 1fb861b82c4cc75b94dc6875280fbd411390bc71 Author: David Peer Date: Tue Nov 23 08:25:11 2021 +0100 HRM confidence of 80 to display commit 7d95221e166770be91bf76374f926fe996356009 Author: David Peer Date: Tue Nov 23 08:24:15 2021 +0100 Minor change commit 6d8d98fb03e7bed42c3feeee771ddfcd78b60ea8 Author: David Peer Date: Tue Nov 23 08:21:41 2021 +0100 Show HRM commit a0cc4c633e0e6853a0f170a5358b7e1f11e310af Author: David Peer Date: Tue Nov 23 08:10:00 2021 +0100 Minor changes commit be083113316ec7ba07d780b6593cb9adfd748298 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 19:11:40 2021 -0800 Update custom.html commit 0664a44c454107d4e3ff039d12baffea3e90cf5f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 18:52:43 2021 -0800 Update apps.json commit b032ca0fc1936e650a459f766799e197daf2a4dd Merge: 7fd37f7e f1f063fd Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 18:49:27 2021 -0800 Merge branch 'espruino-master' commit f1f063fd1adb553c548a3aa54156bce00b4ca48d Merge: 7fd37f7e f4e997d4 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 18:49:09 2021 -0800 merge3 commit 0f9d938fa6970df18fbe99f3c707b94aa26d15c1 Author: jeffyactive Date: Mon Nov 22 20:23:17 2021 -0500 Version bump commit 5a01047cd0b30e4b7b253d784bd0b5755fc0c2e2 Author: jeffyactive Date: Mon Nov 22 20:21:29 2021 -0500 Added screenshots commit ae55c2d39fc936cfa1954d44b7f76dc91c21ced3 Author: jeffyactive Date: Mon Nov 22 20:09:26 2021 -0500 Allow emulator, specify type as app commit 58f9e7cd5b59904651fb878a89844ee4ccfb23df Author: jeffyactive Date: Mon Nov 22 20:03:18 2021 -0500 Upgrade to emoji images and supporting text commit 1a75f0813b5bae3f2b6b7b14dd563a18fa00225f Author: hughbarney Date: Mon Nov 22 22:50:27 2021 +0000 Pastel: font modules commit d450758f1ad9aa833f47873cd45c87f15ef151b4 Author: hughbarney Date: Mon Nov 22 22:09:52 2021 +0000 Pastel: font modules commit cf66db35a95aabf22dd3be5d77b9264148db1956 Author: hughbarney Date: Mon Nov 22 22:08:47 2021 +0000 Pastel: font modules commit 29ecb8daa20219d1657f2ac8d2c76885d5056753 Author: hughbarney Date: Mon Nov 22 22:08:19 2021 +0000 Pastel: font modules commit a29bba62cba6037a64286d89304e3f92051cbf2a Author: hughbarney Date: Mon Nov 22 21:29:26 2021 +0000 Pastel: f_orbitron font module commit 8576d90e50c6c1099b78b1fb82808f788aeabba6 Author: hughbarney Date: Mon Nov 22 21:24:27 2021 +0000 Pastel: f_orbitron font module commit 723e1a6cb2752d12e1a1d1eed45a39000f50208f Author: hughbarney Date: Mon Nov 22 21:17:50 2021 +0000 Pastel: f_orbitron font module commit ec7f9ac69d012a64c1dd383bd688ab8815fb49ad Author: hughbarney Date: Mon Nov 22 21:13:48 2021 +0000 Pastel: f_orbitron font module commit d68bcf1ff18893e5e7fda5cda55db7ed69502f78 Author: hughbarney Date: Mon Nov 22 21:05:28 2021 +0000 Pastel: f_orbitron font module commit ff1d5f2d76ddf8a9cfc4ffea2ea5dcd636851a25 Author: hughbarney Date: Mon Nov 22 21:03:53 2021 +0000 Pastel: f_orbitron font module commit 7fd37f7e4e669c0aea7b5324b85f9d85ca394dcb Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 12:18:44 2021 -0800 Update custom.html commit 84d9ca4b337e36c4f62ffce4b3059f8f2909d482 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 10:57:14 2021 -0800 Update boot.js commit 740f4a95665fd92ad87e83dd381da7e55c2e4b18 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 10:52:27 2021 -0800 Create boot.js not part of the current merge commit d3538a03f10f6323afc8656cef397a561cf35bf0 Author: David Peer Date: Mon Nov 22 19:12:50 2021 +0100 Added raster commit 20310fdb75b11fe8b3ea38dc7810732910537169 Author: David Peer Date: Mon Nov 22 19:02:27 2021 +0100 Smaller icons commit 3863be18301cec9fec480db7fe28a19439c708d2 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Nov 22 09:06:52 2021 -0800 Delete apps/schoolCalendar/fullcalendar/interaction/src directory commit 5d8c13a7e6a934e8b750f0ab4871e3dcc67c09bf Author: David Peer Date: Mon Nov 22 17:56:29 2021 +0100 Updated screenshot accordingly commit 21134a1dcdc102755171af26e99ae86f3559996f Author: David Peer Date: Mon Nov 22 17:55:21 2021 +0100 Better background commit cab3d43085b2edf4dc97ebf05785bb5b446a88da Author: David Peer Date: Mon Nov 22 17:39:48 2021 +0100 Better alarm - shown only in icon so we can display more data. commit db22bac0ecd48633d6acf0874127a1b28821d8ea Author: David Peer Date: Mon Nov 22 17:11:15 2021 +0100 Use correct alarm icon commit 162dc1f29346ab0f6ff4b7cd4128826292ca766e Author: weeurey Date: Mon Nov 22 16:11:07 2021 +0000 Update apps.json commit dc24ae9bfba1786d4d8a3e22871c4da7bda9fb92 Author: David Peer Date: Mon Nov 22 17:10:58 2021 +0100 Better HRM Icon commit 8e688d144ab30ff87f31b51ab457688ce03c4c23 Merge: 741f7aab f4e997d4 Author: weeurey Date: Mon Nov 22 16:09:43 2021 +0000 Merge branch 'espruino:master' into master commit 741f7aab5239e6fa6ae48e1a5351216dfcfc4177 Author: weeurey Date: Mon Nov 22 16:08:38 2021 +0000 Update apps.json commit 247ed9faa2e8b8463374fea05d4bb04ddda2cfc1 Author: weeurey Date: Mon Nov 22 16:07:39 2021 +0000 Create ChangeLog commit d878d46d4ccc5128643034c535cff69984ab7853 Author: weeurey Date: Mon Nov 22 16:05:57 2021 +0000 Update app.js commit c720fc314b516e1007452ad18ce51bc4fefefec1 Author: David Peer Date: Mon Nov 22 17:03:21 2021 +0100 New alarm icon commit 75fbd6882d1368c73db1b96fac79f4202d6a5e53 Author: David Peer Date: Mon Nov 22 16:37:48 2021 +0100 Added icon for alarm commit eb20f15537d8b6be7226b2ae49fc6e6dd0474124 Author: David Peer Date: Mon Nov 22 16:33:42 2021 +0100 Compeletely new design with icons for GPS, HRM and Compass. All Icons are open source and mentioned in the Readme.md file. commit 46383d4d5547bca38a2a07ea01d67afa0166bedc Author: Richard de Boer Date: Mon Nov 22 13:18:01 2021 +0100 gbmusic: fix "previous" button image commit 1bf5132a5caf41398125e0c7f2bad72ffa300df2 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 21:07:49 2021 -0800 Update custom.html commit 618c5b7a10ebe610205ab463c395f65948e5a763 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 21:02:29 2021 -0800 Update custom.html commit adfeb5e535564f8851fcdc080e2fa10d9acced9a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 21:00:21 2021 -0800 Update custom.html commit f950fd2ee88486e3355efd30823d50de799e8418 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:57:52 2021 -0800 Update custom.html commit 3ee0e9bae6ee137c6e36672c9aa6a20d1c072caf Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:49:48 2021 -0800 Update apps.json commit 387bd30236b5d765b396eba24ad43120ceb6c384 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:48:14 2021 -0800 Rename ChangeLog.md to ChangeLog commit 6e07f282b8918ac3b8f333c7c4156980a44ff1d6 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:41:26 2021 -0800 Add files via upload commit fea37b4992e65a5ca54648f88281ce2623f6a55f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:37:40 2021 -0800 Update apps.json commit 939d8f6a9ae71b49c13f7dbf1455bb2fec60462a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:37:21 2021 -0800 Add files via upload commit 854ae5361d1b2400f6b6d1b2c2239f46d1e16bc9 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:34:28 2021 -0800 Update README.md commit 426768eb11e34ea7a04010e6fe7da1a5a5187f40 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 20:32:14 2021 -0800 Update custom.html commit bf994d9acc8b79ebda1e47dc5ebc5158210d6205 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 18:24:29 2021 -0800 Update apps.json commit 7c74c5d43f9f66b6374cabd4e247d1560e5f29a1 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 18:15:40 2021 -0800 Update apps.json commit 8981aa3f614c388c74d73ccd25e16f5e6eabde9f Merge: e878e547 100384f2 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 18:12:19 2021 -0800 Merge branch 'espruino:master' into master commit e878e5478713b0b3cae0bb86e28f998cbfeb9b10 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 18:11:43 2021 -0800 merge commit 3bde4d2e48711186ae26036baea8f880c2aac7c4 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 16:12:16 2021 -0800 Update custom.html commit 5f3c93df8cc8b73c432ea31b15e84e4b106256de Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:37:41 2021 -0800 Update custom.html commit 26bd9e35be993aae4deece775ac85f53f877b122 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:35:47 2021 -0800 Update custom.html commit 8f2cc6e2137cf29e03435123e96d9c6c550864d1 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:34:09 2021 -0800 Update custom.html commit 66f061112301898b011412e91982dbefc7cc2d1e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:32:48 2021 -0800 Update custom.html commit 87a9504912b8753dc63700207ee89acacbb34726 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:30:44 2021 -0800 Update custom.html commit 626498da9d296fecf6776b836def4eda87027d85 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:24:01 2021 -0800 Update custom.html commit 3472ca355a1a71d3fa3f464ece2b81dce7f4eeaa Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:21:57 2021 -0800 Update custom.html commit 529b0cb4637652dfc0a3ba6688b863b5f47437ca Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:19:53 2021 -0800 Update custom.html commit e77d9980023f041a87743ac1fd3c48a3f0652a8e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:18:21 2021 -0800 Update custom.html update commit a712c37c7652f7bc46c4d7761df93b3d28e17229 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:17:58 2021 -0800 Update custom.html commit 4d9d6abb9ef466e4058510efe9eec295f60127e9 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:14:02 2021 -0800 Update custom.html commit f35b24844810a90f08f731cc9e63535be217e4cf Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:09:44 2021 -0800 Update custom.html commit d0336b2854d7e0892c440ef8c5f83bcbe1374a9b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:06:56 2021 -0800 Update custom.html commit 640c8e491e489e9ea88282cf0bfe14004838b3db Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:03:42 2021 -0800 Update custom.html commit 604153cb2408399ce1420b43ef87f41c09d3daa6 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 08:01:45 2021 -0800 Update custom.html commit 0f8f1e38e85a8c1c49057f4b891209bdfad67aef Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:58:44 2021 -0800 Update custom.html commit 7f7dcb0bcf89b1d66f60481efaa09f5956ee4ecc Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:58:22 2021 -0800 Update custom.html commit d42fe03dc8fcbc0f68857dd9f887c8cc4eff1c06 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:55:08 2021 -0800 Update custom.html commit 98f172fad442e89f53c45ac47f2388a08049855a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:53:01 2021 -0800 Update custom.html commit daf8dde32bc81b8f04402c4728eac41784751cd5 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:49:25 2021 -0800 Update custom.html commit 408bd24080a2f7dcf1e6d0c33dab65da4dff82cf Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:48:38 2021 -0800 Update custom.html commit 68db21acbb837b12d84d9930d451d2ba90e251dd Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:44:30 2021 -0800 Update custom.html commit 45feb1b2ffb17b8835c505bc4a4f825ddc17bf4f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:39:42 2021 -0800 Update custom.html commit 3bc5fd87b61cbb9b867009d933342fe627da982d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:39:12 2021 -0800 Update custom.html commit c3eede9868ee342bc4248e71a874c2e6b332dcdd Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:37:42 2021 -0800 Update custom.html commit 8426356c01a23ae769c79f726b95ea64f4428574 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:35:55 2021 -0800 Update custom.html commit 93f09c216a1eb9aa876c88a1f806ccb709e971b7 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:27:39 2021 -0800 Update apps.json commit cb748a251dbd11e87615d82081522953607b3a27 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Nov 21 07:27:20 2021 -0800 Update custom.html commit a994ed66301040f60d5f99b672a6081152a20d6c Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 19:53:38 2021 -0800 Update custom.html commit b76bb48973dbabfaf56bdec4aee44a483f94d129 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 19:50:08 2021 -0800 Update custom.html commit f99ce683e9ce42431321fc711e061955bc0220fb Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 19:46:32 2021 -0800 Update custom.html commit ddfdd94ff845d3d8560158cde184a9a19a3d2142 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 19:42:51 2021 -0800 Update custom.html commit 52675f7eff140426532f81da9c84c5d7803d0cda Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:48:03 2021 -0800 Update custom.html commit d4911034145e3d98b99d649be55c75671e2f5c5c Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:44:23 2021 -0800 Update custom.html commit 71ff5959aec6a5f8302bda513d2c1371bbed0743 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:42:58 2021 -0800 Update custom.html commit daba705b37b9952cba2910c3c0bed23e58aaf2fc Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:42:16 2021 -0800 Update custom.html commit 19cb5fc749abeefe378205531d18b97562ddfc47 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:39:15 2021 -0800 Update apps.json commit 6c20945898b84a02d6b440923a5afd994c7d97aa Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:37:41 2021 -0800 Update custom.html commit ff519bdc0d9bca530284d98cad9fd023ad37d50d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:15:29 2021 -0800 Update custom.html commit 34843d703aae0b6a33be352ad0f8408d8d17d07b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:11:54 2021 -0800 Update custom.html commit 4da82197f32b280e4192d5bc9a5ba174fbad4ace Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 18:01:20 2021 -0800 Update custom.html commit a9c5a32bc1359d8288f4fd6b6da50eaf40910c9a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:56:54 2021 -0800 Update custom.html commit 352fea34791ccf06450a516ab2a2daf22353c641 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:53:38 2021 -0800 Update apps.json commit ab6f56c381a54e4ab3466625a9eb794eef5dd2a0 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:52:34 2021 -0800 Update custom.html commit a65742ce346039ef901e70157620aabd95bbca35 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:48:25 2021 -0800 Update apps.json commit a1a387dd600f7e5c3879d74cd5a516d7566fb7bb Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:47:52 2021 -0800 Update custom.html commit 180e88e0e44dc3ca09291a7d37b6fa4df637fa78 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:46:50 2021 -0800 Update custom.html commit 0099736b8c64e8f1afefd4d52b526151e3ac700a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:46:14 2021 -0800 Update apps.json commit 1fdf4e954e23fe0514b8d795224c2edafd5941c1 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:44:43 2021 -0800 Update apps.json commit faa5b6b21aa8b7062dc62499e8361b8233cf9408 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 17:44:10 2021 -0800 Update custom.html commit d617803c13ec381f35a9d30f99a267dca02c9cf1 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 16:37:44 2021 -0800 Update apps.json commit dc669254bcccad425153d209d6dcdf002f64a30d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 16:37:10 2021 -0800 Update custom.html commit 303247fb4e66802ed7f5c2ee404ce0a28221ec2d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 16:25:00 2021 -0800 Update custom.html commit d836cbd2ba256adfffa55f1d12fda02ae8ac760c Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 16:15:16 2021 -0800 Update custom.html commit e206bd4e1cad4aab266fd376fa525500941878a8 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 16:08:00 2021 -0800 Update custom.html commit 1a6c1acce50fe2fe2e49bfc26b3ac98c1db5aa13 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 16:04:06 2021 -0800 Update custom.html commit aa20fac50ed19adfb9248fd9cda1ebb7c31f95b1 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 16:02:52 2021 -0800 Update apps.json commit 5625414e90c78677040420f342f29e96f088469b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:34:30 2021 -0800 Update apps.json commit ebc2d8096144e6150920efc4b63e8f1e3f52eb00 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:33:27 2021 -0800 Update custom.html commit 6c43de3766433c1f9fa1d01fd24cbfe0839e19c0 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:21:11 2021 -0800 Update apps.json commit 37da3c68aeeb5fec1ef3d8965fa3d8170074d791 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:19:46 2021 -0800 Update custom.html commit 92707b9d13ed269a41684ce45111376694cb6e58 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:12:50 2021 -0800 Update ChangeLog.md commit d3ca682cff08be0bb2a64ab057f6efdf36b4e094 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:09:56 2021 -0800 Update apps.json commit dfd9e59993944f6323120f8af660d880c63c6793 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:08:52 2021 -0800 Update custom.html commit 5d24a09ffa2d9cad10a5fae3c7b4d5fafc944aa9 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:04:41 2021 -0800 Update apps.json commit e965bd7d962108a2944824eb6579fce435876966 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:02:43 2021 -0800 Update custom.html commit 345d9c155135fc4d0a2b8d00b3528b363a584ced Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:02:12 2021 -0800 Delete schoolCalendar.js commit dc9db8a4767d4c16d92645131d977263e2468521 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:01:58 2021 -0800 Update schoolCalendar.js commit 58df0a5ca26684b4da84929c8c388ca5c37acabd Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 15:01:03 2021 -0800 Update apps.json commit 65ad4979e8d58b51f11f3bcc86f31ab303a5d7b6 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 13:27:10 2021 -0800 Update custom.html commit 9c07800c5ef948a1b9b2071e7bdfe46809fefa1d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 13:07:38 2021 -0800 Update custom.html commit b108bc45fb8bfa266e4d4ad3e66a9f65cec96c92 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:58:24 2021 -0800 Update custom.html commit d871855f8e217b27ea73ed28b389bbc8aea59d62 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:55:58 2021 -0800 Update apps.json commit 99112920b287568db32c5e43b47cfc2ee0cf71a3 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:47:34 2021 -0800 Update apps.json commit 37f4329ec57bc4a96a1b2a0847406f6a05cad520 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:39:49 2021 -0800 Update apps.json commit ba2aee642bf90307757bb85fda6aa0db01bed5e5 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:39:06 2021 -0800 Update custom.html commit 98048dc23cb1caf3aafbf1d1ecfa461ba5943925 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:37:23 2021 -0800 Update apps.json commit 1a53e8d34af89f0e6c889653961350a898deea81 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:33:43 2021 -0800 Update custom.html commit 993bb7298c8fbc9348e6668b70a555c51dc54a09 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:31:41 2021 -0800 Rename interface.html to custom.html commit 3a3962bfdc0365e75f8804b61293ec91084f6698 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:30:12 2021 -0800 Rename custom.html to interface.html commit c8ad92a3dcb7b8a0df83f2e720b6730dd785e829 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:20:33 2021 -0800 Update apps.json commit ae85c1cee709457b10233205c057f946ea15fe83 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Nov 20 12:14:33 2021 -0800 Update custom.html commit c1b467ba8e96f58b27eb3b9b2dc2b859fa89e227 Author: weeurey Date: Sat Nov 20 18:14:50 2021 +0000 Update app.js commit 438537ace2358f5b798bdfde92ebf78db81abc49 Author: weeurey Date: Sat Nov 20 18:10:03 2021 +0000 Update app.js commit e6d736860d7d7511f08474a4d8f6446ebe97e634 Author: weeurey Date: Sat Nov 20 17:57:57 2021 +0000 Update app.js commit e1add5e2b2a068873d0102324d61f9ff5532924d Author: weeurey Date: Sat Nov 20 17:45:02 2021 +0000 Update app.js commit 09be008dfaf764b542a80f4dbbde6ab26314713e Author: weeurey Date: Sat Nov 20 17:39:48 2021 +0000 Update app.js commit 9f26994f5c66a5ee88a702c7a73d8bcc0c8236c3 Author: weeurey Date: Sat Nov 20 17:33:47 2021 +0000 Update app.js commit 0cf4c5d70a97480185296b32137fcdc179fddcc4 Author: weeurey Date: Sat Nov 20 17:10:31 2021 +0000 Update app.js commit cfdb94439526722ca757b8ee748d298f6a76d9e7 Author: weeurey Date: Sat Nov 20 16:32:34 2021 +0000 Update app.js Add Media controls commit e3cd8f5607f912002d3ec0adf833834058a492cb Author: weeurey Date: Sat Nov 20 16:16:37 2021 +0000 Update app.js Removed extra unneeded code commit ceed8a123836f5da6fb8c5d6741e2224a3e4a0af Author: weeurey Date: Sat Nov 20 15:05:28 2021 +0000 Update app.js commit 721a3f2608ee0012767cfacd5c69aa91a7bba5f6 Author: weeurey Date: Sat Nov 20 14:39:30 2021 +0000 Update app.js commit a16bfe4d7350b34c694050448f2aefc990d19dcb Author: weeurey Date: Sat Nov 20 14:32:57 2021 +0000 Update app.js commit e72bf84a7a05c4208e8c1d5f60815a9f57ca11c4 Author: bengwalker <63957296+bengwalker@users.noreply.github.com> Date: Wed Nov 17 21:29:57 2021 +0100 use dark theme for metronome commit 071a7a7e683a649b9f75fdc92b9f56804cd0af87 Author: bengwalker <63957296+bengwalker@users.noreply.github.com> Date: Wed Nov 17 20:46:18 2021 +0100 add support for Bangle.js 2 commit 7a7175fa483e4e9fcd5912d83e9519274d67b4f0 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Nov 4 16:00:41 2021 -0700 Update custom.html commit e2928498690565ba7d0454aaa4265bc8adfda712 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Wed Nov 3 08:22:32 2021 -0700 Rename interface.html to custom.html commit cd7579269efe8d54a5a5680b8126ea38f9ce54be Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Wed Nov 3 08:22:04 2021 -0700 Update apps.json commit df7f9cc530194025708b712565a410aed1d73e95 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Wed Nov 3 08:20:09 2021 -0700 Update interface.html commit ada94b11cfbebfeaa010cee1b39d0f92591d4e13 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Wed Nov 3 08:06:50 2021 -0700 Update interface.html commit 08fc58deb57847cca7d81bf84a54df16ce97528f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 20:20:57 2021 -0700 Update interface.html commit 04b9e74a4d2cd84dd9b64b0ba6fba1167fc400e7 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 20:10:58 2021 -0700 Update interface.html commit be7af68455ff4b5034c0baab9d8c138b9b024707 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 20:08:24 2021 -0700 Update interface.html commit aaee5f3c0610de7a48bdda7fe9c6064dff97780e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 19:13:08 2021 -0700 Update interface.html commit 73819933eeb57f32935e6ad93a146bdbee6d8be6 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 18:52:09 2021 -0700 Update schoolCalendar.js commit fa5cbd71c618a2053ec3217048c74a723c46f03f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 18:49:22 2021 -0700 Update README.md commit fa392008d1e30a6df05245eac969badf4188fb74 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 18:45:24 2021 -0700 Update README.md commit c280e41560a3812ee83ca461e098bc35b80ef439 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Nov 2 18:42:39 2021 -0700 Update README.md commit 6b84a8eb3007cca6abd31cc1d3d0552cc79cb492 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 18 19:43:26 2021 -0700 Update schoolCalendar.js commit 5bbfb1109910856575cc348012dbc44d489a8005 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 18 19:43:11 2021 -0700 Update interface.html update interface commit 6660dad4c01c66c20670cfd415b6ad063d9b5b74 Merge: 8c003cf6 1e0f6cd6 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 18 07:35:54 2021 -0700 Merge branch 'espruino:master' into master commit 8c003cf6ffb5a8b3437897a1e57a6a020b5e02a4 Merge: 5c11881f f1ce196a Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Fri Oct 15 07:33:21 2021 -0700 Merge branch 'espruino:master' into master commit 5c11881f752edbdef3031f0a48109a196eced80a Merge: 8c149dbe be34e2b0 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Oct 14 17:14:45 2021 -0700 Merge branch 'espruino:master' into master commit 8c149dbea1cfd34e815b64ca354840b811a82222 Merge: 7888cc6c 300ed35b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Wed Oct 13 07:46:16 2021 -0700 Merge branch 'espruino:master' into master commit 7888cc6ce0bbabf99c7dd39f002810d262af07fd Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 11 17:43:59 2021 -0700 Create README.md commit 36a52b8b001a4515d715950db56e411a6c4842b2 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 11 17:43:52 2021 -0700 Update README.md commit 4f5558c41e75f6e91a34842f7b42fa85970dce5e Merge: 5db16d19 68cc9fbd Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 11 16:43:12 2021 -0700 Merge branch 'espruino:master' into master commit 5db16d190b1439293d9f0af16d37fea29db8830c Merge: e7995505 54d98db6 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 11 07:03:23 2021 -0700 Merge branch 'espruino:master' into master commit e799550544e55ef94ef48f905283625e50f73e97 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Oct 7 17:02:57 2021 -0700 Update schoolCalendar.js commit 89f82a50436d4eab82574d310077d19154a8ab59 Merge: 7107d510 f3712e66 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Oct 7 17:02:38 2021 -0700 Merge branch 'espruino:master' into master commit 7107d510a5301f50ca5dc1bf9d4463ad99a33af8 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 4 20:06:28 2021 -0700 Update schoolCalendar.js commit a61879753285b4469772f51474c29fe86a5aa942 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 4 19:55:30 2021 -0700 Update schoolCalendar.js commit 3c9e46c2160f4ff58708afc0d08ce2e5d27df097 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 4 15:59:03 2021 -0700 Update apps.json commit 941bc852c1ab4472dc74a7f84e12e92ab891432e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 4 15:57:53 2021 -0700 Add files via upload commit 4cbfac212e6999887cfafd37d9c809919a014e27 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 4 15:57:26 2021 -0700 Delete apps/schoolCalender directory commit c7b723f87e5e6fb0858c09ee2910510267d73fd6 Merge: 8d2f4ccc ba08863b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Oct 4 07:31:25 2021 -0700 Merge branch 'espruino:master' into master commit 8d2f4ccca761e1695620b072e116b94272850427 Merge: 7846b48c 44aa03e4 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Fri Oct 1 07:31:42 2021 -0700 Merge branch 'espruino:master' into master commit 7846b48cf67ab024970b90948096f9258e1c184c Merge: 59aa9909 d0fd2f01 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 30 17:22:33 2021 -0700 Merge branch 'espruino:master' into master commit 59aa99092dac99b9a13bbc2a7153dd2b44a6fb67 Merge: 9061acee 03bbe1d2 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Wed Sep 29 08:06:54 2021 -0700 Merge branch 'espruino:master' into master commit 9061acee5db851bd58295785cc7542a7c066b4c8 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Sep 28 17:44:12 2021 -0700 Update interface.html commit 79bacc45932ce8842cbf12d23c36a41e992b438e Merge: bb5fcdaa 48bb819b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Sep 28 07:12:44 2021 -0700 Merge branch 'espruino:master' into master commit bb5fcdaafc1e344bf2d717c3eb238f763f255215 Merge: 814fbdd6 28bd9e83 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Sep 27 16:15:07 2021 -0700 Merge branch 'espruino:master' into master commit 814fbdd61ef41676d07719b5b1b297fbbc03ec6f Merge: 83d88a1e f3fd0f25 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Sep 25 08:01:44 2021 -0700 Merge branch 'espruino:master' into master commit 83d88a1ea191e2e6b669d284d94b4180b9ea54aa Merge: c9bed74e 71471d37 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Fri Sep 24 19:35:52 2021 -0700 Merge branch 'espruino:master' into master commit c9bed74ec2e240e2daf26bf9ec9432df91ac18aa Merge: 1f130c53 16fe8470 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 23 15:21:18 2021 -0700 Merge branch 'espruino:master' into master commit 1f130c53b46546328260a6b94ad182be5d55ff18 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Wed Sep 22 07:25:41 2021 -0700 Update interface.html commit 3d8ebe82c289156581799134b3c56fd02ade1fad Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Sep 21 21:07:20 2021 -0700 Update interface.html commit 2ca58d2cc436b72beb87d347b8d8c217b461e805 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Sep 21 21:02:14 2021 -0700 Update custom.html commit d8c149073fb6bca8f5f78ba4a031004adeab1a6b Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Sep 21 21:01:31 2021 -0700 Update apps.json commit ceab5d46a23f913faf96be90e644458ac5546157 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Sep 21 20:58:01 2021 -0700 Rename schoolCalender.js to app.js commit 9b344eb1ecc577e96196d2a3d3fc8962198e90de Merge: ec453c0e 3b15a7f9 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Tue Sep 21 07:24:54 2021 -0700 Merge branch 'espruino:master' into master commit ec453c0e100f7fd140305fe8ed4a62d3987e68f1 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Sep 20 19:45:50 2021 -0700 Update README.md commit a8f7fe72923e1fe38042cb4752dac1429c6be426 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Sep 20 07:31:41 2021 -0700 Update interface.html commit 51c41d5c48a72b7a373e6f979c95bab9fa9ddb7a Merge: b7a4ecb5 50ec8d97 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon Sep 20 07:25:50 2021 -0700 Merge branch 'espruino:master' into master commit b7a4ecb57857016c131ba72e101b3a11eb3cb06c Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 16:48:24 2021 -0700 Update interface.html commit 82320ab073c0b106f5260e26c0fb147d7c8fcd02 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 16:40:43 2021 -0700 Update interface.html commit 27d025bf82cc5882dc39110c5c7799f657f2c57d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 14:01:04 2021 -0700 Update interface.html commit bd92c0e67fce373f11aae3bbcf8f5a4c06f2e161 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 13:51:31 2021 -0700 Update interface.html commit f0c596d14f6119bbe52e2f0d3912216785257536 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 13:40:29 2021 -0700 Update interface.html commit d6542bac6d666af7c8fe1f67434611e6ccacc6a6 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 07:29:46 2021 -0700 Update interface.html commit 7a2ee0f7111209afa859761a62f80e93ca71a879 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 07:15:29 2021 -0700 Update interface.html commit c65ddbfc522c54da540080a16d171edd42ce592e Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sun Sep 19 07:05:32 2021 -0700 Update interface.html commit 43c684f389d97dd12815edbd93d0750f923f17b3 Merge: ddd1a83c 5f5b5c0d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Sep 18 19:45:25 2021 -0700 Merge branch 'espruino-master' commit 5f5b5c0dc2485f7e454acb9f364d240e3972d955 Merge: ddd1a83c cc2e1bbd Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Sat Sep 18 19:42:47 2021 -0700 Merge branch 'master' of git://github.com/espruino/BangleApps into espruino-master commit ddd1a83c613a9f21ec8e37ba1151e1ca255a77af Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Fri Sep 17 18:27:57 2021 -0700 Update interface.html commit 632c98f8be2ad6e2290e5eb98025559a42a47c34 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Fri Sep 17 15:13:46 2021 -0700 Update interface.html commit c252f74e16edc5a1a1fcfe4ce72c9594f12a9624 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Fri Sep 17 07:31:16 2021 -0700 Update interface.html commit b9b0a43e99db0c2d13c28bf6d65540925709d866 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 19:28:35 2021 -0700 Update interface.html commit afafd449fb06abd3930d0eb40989dc12787c96d9 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 19:22:01 2021 -0700 Update interface.html commit 45a0d50b011ee50e9b1b4c6ce5a84e1290331b1f Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 19:15:25 2021 -0700 Update interface.html commit eb146fe07bd5d71f49c5e267424d7b8206eee952 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 19:07:51 2021 -0700 Update interface.html commit 34baf995e7f5288266b5da08bcac6d76202a92fc Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 19:04:33 2021 -0700 Update interface.html commit 751fbdda43ea542db4887bed7b4d4e2ad7628a23 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 19:00:47 2021 -0700 Update interface.html commit bc71f317311509e8f3fd5054e6c3efaa05bc0416 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 18:47:13 2021 -0700 Update interface.html commit cfde9e14a87466a8dc7cb92934c3af373f6a43d0 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 18:41:40 2021 -0700 Update interface.html commit 135165c983beca48190d091e355436100beee41d Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 18:37:52 2021 -0700 Add files via upload commit d50ba356d68ebeffd028a924450d4a6ad4fddd74 Author: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Thu Sep 16 18:36:59 2021 -0700 Update apps.json --- .eslintignore | 2 + README.md | 12 +- apps.json | 431 +- apps/93dub/93dub.png | Bin 0 -> 650 bytes apps/93dub/ChangeLog | 3 + apps/93dub/README.md | 11 + apps/93dub/app-icon.js | 1 + apps/93dub/app.js | 137 + apps/93dub/screenshot.png | Bin 0 -> 3297 bytes apps/a_clock_timer/ChangeLog | 1 + apps/a_clock_timer/README.md | 15 + apps/a_clock_timer/app-icon.js | 1 + apps/a_clock_timer/app.js | 129 + apps/a_clock_timer/app.png | Bin 0 -> 3751 bytes apps/a_clock_timer/screenshot.png | Bin 0 -> 4174 bytes apps/a_speech_timer/ChangeLog | 1 + apps/a_speech_timer/README.md | 16 + apps/a_speech_timer/app-icon.js | 1 + apps/a_speech_timer/app.js | 173 + apps/a_speech_timer/app.png | Bin 0 -> 3036 bytes apps/a_speech_timer/screenshot0.png | Bin 0 -> 3276 bytes apps/a_speech_timer/screenshot1.png | Bin 0 -> 3457 bytes apps/a_speech_timer/screenshot2.png | Bin 0 -> 3401 bytes apps/a_speech_timer/screenshot3.png | Bin 0 -> 3374 bytes apps/about/ChangeLog | 1 + apps/about/app-bangle2.js | 2 +- apps/about/bangle1-about-screenshot.png | Bin 0 -> 14911 bytes apps/android/ChangeLog | 4 + apps/android/app.js | 5 +- apps/android/boot.js | 24 +- apps/android/settings.js | 18 + apps/authentiwatch/ChangeLog | 2 + apps/authentiwatch/README.md | 3 + apps/authentiwatch/app-icon.js | 2 +- apps/authentiwatch/app.js | 57 +- apps/authentiwatch/app.png | Bin 964 -> 1630 bytes apps/authentiwatch/interface.html | 22 +- apps/barclock/ChangeLog | 3 +- apps/barclock/clock-bar.js | 10 +- .../bangle1-battle-ship-screenshot.png | Bin 0 -> 2817 bytes .../bangle1-binary-clock-screenshot.png | Bin 0 -> 4673 bytes .../bangle1-beeb-clock-screenshot.png | Bin 0 -> 4466 bytes apps/berlinc/berlin-clock-screenshot.png | Bin 0 -> 1846 bytes apps/binwatch/Background176_center.img | Bin 0 -> 11686 bytes apps/binwatch/Background240_center.img | Bin 0 -> 21694 bytes apps/binwatch/Background240_center.png | Bin 6492 -> 6350 bytes apps/binwatch/ChangeLog | 1 + apps/binwatch/app.js | 10 +- .../bangle1-black-jack-game-screenshot.png | Bin 0 -> 4165 bytes ...gle1-large-digit-blob-clock-screenshot.png | Bin 0 -> 2879 bytes ...gle2-large-digit-blob-clock-screenshot.png | Bin 0 -> 1972 bytes apps/boot/ChangeLog | 1 + apps/boot/bootupdate.js | 8 +- .../bangle-charge-animation-screenshot.png | Bin 0 -> 3401 bytes .../bangle2-charge-animation-screenshot.png | Bin 0 -> 2031 bytes apps/choozi/bangle1-choozi-screenshot1.png | Bin 0 -> 3893 bytes apps/choozi/bangle1-choozi-screenshot2.png | Bin 0 -> 3822 bytes apps/cliclockJS2Enhanced/ChangeLog | 2 + apps/cliclockJS2Enhanced/app.js | 235 +- .../clotris/bangle1-clock-tris-screenshot.png | Bin 0 -> 3196 bytes apps/counter/bangle1-counter-screenshot.png | Bin 0 -> 3588 bytes .../bangle1-CPR-assist-screenshot.png | Bin 0 -> 2960 bytes apps/cscsensor/ChangeLog | 2 + apps/cscsensor/README.md | 8 +- apps/cscsensor/cscsensor.app.js | 148 +- .../bangle1-center-clock-screenshot.png | Bin 0 -> 3736 bytes apps/cubescramble/ChangeLog | 1 + apps/cubescramble/README.md | 3 +- .../bangle1-cube-scramble-screenshot.png | Bin 0 -> 3848 bytes .../bangle2-cube-scramble-screenshot.png | Bin 0 -> 2923 bytes apps/cubescramble/cube-scramble.js | 33 +- apps/dclock/bangle1-dev-clock-screenshot.png | Bin 0 -> 4058 bytes apps/dclock/bangle2-dev-clock-screenshot.png | Bin 0 -> 2461 bytes .../demoapp/bangle1-demo-loop-screenshot1.png | Bin 0 -> 9662 bytes .../demoapp/bangle1-demo-loop-screenshot2.png | Bin 0 -> 2889 bytes .../demoapp/bangle1-demo-loop-screenshot3.png | Bin 0 -> 3679 bytes .../demoapp/bangle1-demo-loop-screenshot4.png | Bin 0 -> 5754 bytes .../bangle1-dev-stopwatch-screenshot.png | Bin 0 -> 3825 bytes .../dotclock/bangle1-dot-clock-screenshot.png | Bin 0 -> 3610 bytes .../dotclock/bangle2-dot-clcok-screenshot.png | Bin 0 -> 3107 bytes apps/emojuino/ChangeLog | 1 + apps/emojuino/emojuino.js | 54 +- apps/emojuino/screenshot-swipe.png | Bin 0 -> 2097 bytes apps/emojuino/screenshot-tx.png | Bin 0 -> 1812 bytes apps/emojuino/screenshot-welcome.png | Bin 0 -> 2697 bytes apps/fd6fdetect/ChangeLog | 1 + apps/fd6fdetect/README.md | 3 + apps/files/files-icon.js | 2 +- apps/gbdebug/ChangeLog | 1 + apps/gbdebug/README.md | 26 + apps/gbdebug/app-icon.js | 1 + apps/gbdebug/app.js | 21 + apps/gbdebug/app.png | Bin 0 -> 2914 bytes apps/gbmusic/ChangeLog | 1 + apps/gbmusic/app.js | 2 +- apps/gbridge/settings.js | 4 +- apps/getup/bangle1-get-up-screenshot.png | Bin 0 -> 2367 bytes apps/gpsrec/ChangeLog | 2 + apps/gpsrec/app.js | 8 +- apps/gpsrec/widget.js | 1 + ...bangle1-high-contrast-clock-screenshot.png | Bin 0 -> 3312 bytes .../hrings/bangle1-hypno-rings-screenshot.png | Bin 0 -> 5168 bytes ...angle1-impercise-word-clock-screenshot.png | Bin 0 -> 5292 bytes apps/intervalTimer/ChangeLog | 1 + apps/intervalTimer/README.md | 34 + apps/intervalTimer/app-icon.js | 1 + apps/intervalTimer/app.js | 306 + apps/intervalTimer/app.png | Bin 0 -> 1823 bytes apps/intervalTimer/images/done.png | Bin 0 -> 2356 bytes apps/intervalTimer/images/pause.png | Bin 0 -> 1231 bytes apps/intervalTimer/images/set-active.png | Bin 0 -> 2226 bytes apps/intervalTimer/images/set-rest.png | Bin 0 -> 2364 bytes apps/intervalTimer/images/set-sets.png | Bin 0 -> 2212 bytes apps/intervalTimer/images/timer1.png | Bin 0 -> 1717 bytes apps/intervalTimer/images/timer2.png | Bin 0 -> 1646 bytes apps/ios/ChangeLog | 2 + apps/ios/boot.js | 9 +- ...ngle1-magic-8-ball-italiano-screenshot.png | Bin 0 -> 3517 bytes .../bangle1-large-clock-screenshot.png | Bin 0 -> 5060 bytes apps/launch/ChangeLog | 3 +- apps/launch/app-bangle1.js | 9 + apps/launch/app-bangle2.js | 13 + .../bangle1-lazy-clock-screenshot.png | Bin 0 -> 2976 bytes apps/lcars/ChangeLog | 6 +- apps/lcars/README.md | 3 + apps/lcars/background.png | Bin 1497 -> 0 bytes apps/lcars/bg_large.png | Bin 0 -> 12390 bytes apps/lcars/bg_small.png | Bin 0 -> 9939 bytes apps/lcars/lcars.app.js | 236 +- apps/lcars/screenshot.png | Bin 2434 -> 26993 bytes apps/life/bangle1-game-of-life-screenshot.png | Bin 0 -> 3847 bytes apps/locale/ChangeLog | 1 + apps/locale/locale.html | 9 +- apps/mandlebrotclock/ChangeLog | 2 + apps/mandlebrotclock/README.md | 9 + apps/mandlebrotclock/app.png | Bin 0 -> 136198 bytes apps/mandlebrotclock/mandlebrotclock-icon.js | 1 + apps/mandlebrotclock/mandlebrotclock.js | 34 + apps/mandlebrotclock/mandlebrotclock.png | Bin 0 -> 19497 bytes .../screenshot_mandlebrotclock.png | Bin 0 -> 40229 bytes .../bangle1-mario-clock-screenshot.png | Bin 0 -> 3658 bytes .../bangle1-morphing-clock-screenshot.png | Bin 0 -> 3175 bytes apps/messages/ChangeLog | 7 + apps/messages/app.js | 106 +- apps/messages/lib.js | 24 +- apps/messages/settings.js | 35 + apps/messages/widget.js | 24 +- apps/metronome/ChangeLog | 1 + apps/metronome/README.md | 7 +- .../bangle1-metronome-screenshot.png | Bin 0 -> 3706 bytes apps/metronome/metronome.js | 99 +- .../bangle1-mixed-clock-screenshot.png | Bin 0 -> 4047 bytes .../bangle1-mixed-clock-2-screenshot.png | Bin 0 -> 4011 bytes .../bangle1-minion-clock-screenshot.png | Bin 0 -> 10005 bytes .../bangle1-moon-phase-screenshot.png | Bin 0 -> 4809 bytes apps/mylocation/ChangeLog | 1 + apps/mylocation/README.md | 41 + apps/mylocation/mylocation.app.js | 75 + apps/mylocation/mylocation.icon.js | 1 + apps/mylocation/mylocation.png | Bin 0 -> 1909 bytes apps/mylocation/screenshot_1.png | Bin 0 -> 2847 bytes apps/mylocation/screenshot_2.png | Bin 0 -> 2642 bytes apps/mylocation/screenshot_3.png | Bin 0 -> 15562 bytes apps/mylocation/screenshot_4.png | Bin 0 -> 2818 bytes .../bangle1-mystic-clock-screenshot.png | Bin 0 -> 3454 bytes .../bangle1-customized-welcome-screenshot.png | Bin 0 -> 7082 bytes apps/mywelcome/custom.html | 7 - .../nato/bangle1-NATO-alphabet-screenshot.png | Bin 0 -> 1725 bytes .../bangle1-NATO-alphabet-screenshot2.png | Bin 0 -> 1843 bytes apps/numerals/bangle1-numerals-screenshot.png | Bin 0 -> 3916 bytes apps/openstmap/ChangeLog | 1 + apps/openstmap/custom.html | 47 +- apps/openstmap/openstmap.js | 12 +- apps/pastel/ChangeLog | 3 + apps/pastel/README.md | 45 +- apps/pastel/f_architect.js | 9 + apps/pastel/f_cabin.js | 9 + apps/pastel/f_elite.js | 7 + apps/pastel/f_gochihand.js | 10 + apps/pastel/f_lato.js | 10 + apps/pastel/f_latosmall.js | 10 + apps/pastel/f_monoton.js | 7 + apps/pastel/f_orbitron.js | 11 + apps/pastel/pastel.app.js | 175 +- apps/pastel/pastel.settings.js | 9 - apps/pastel/screenshot_architech.jpg | Bin 38320 -> 0 bytes apps/pastel/screenshot_architect.png | Bin 0 -> 2796 bytes apps/pastel/screenshot_b2_dark.jpg | Bin 52318 -> 0 bytes apps/pastel/screenshot_cabinsketch.png | Bin 0 -> 3472 bytes apps/pastel/screenshot_elite.jpg | Bin 9486 -> 0 bytes apps/pastel/screenshot_elite.png | Bin 0 -> 2643 bytes apps/pastel/screenshot_gochi.jpg | Bin 40511 -> 0 bytes apps/pastel/screenshot_gochihand.png | Bin 0 -> 2794 bytes apps/pastel/screenshot_lato.jpg | Bin 46058 -> 0 bytes apps/pastel/screenshot_lato.png | Bin 0 -> 2626 bytes apps/pastel/screenshot_monoton.jpg | Bin 11281 -> 0 bytes apps/pastel/screenshot_monoton.png | Bin 0 -> 3012 bytes apps/pastel/screenshot_orbitron.png | Bin 0 -> 2668 bytes apps/pebble/ChangeLog | 3 + apps/pebble/LECO 1976-Regular.otf | Bin 0 -> 26432 bytes apps/pebble/README.md | 17 + apps/pebble/pebble.app.js | 120 + apps/pebble/pebble.icon.js | 1 + apps/pebble/pebble.png | Bin 0 -> 1213 bytes apps/pebble/pebble.settings.js | 38 + apps/pebble/pebble_screenshot.png | Bin 0 -> 2426 bytes apps/pebble/pebble_screenshot2.png | Bin 0 -> 2549 bytes apps/pebble/pebble_screenshot3.png | Bin 0 -> 2335 bytes ...bangle1-pipboy-themed-clock-screenshot.png | Bin 0 -> 7709 bytes apps/pomodo/ChangeLog | 2 +- apps/pomodo/bangle2-pomodoro-screenshot.png | Bin 0 -> 1839 bytes apps/pong/bangle1-pong-screenshot.png | Bin 0 -> 2243 bytes apps/pooqroman/README.md | 42 + apps/pooqroman/app-icon.js | 1 + apps/pooqroman/app.js | 761 + apps/pooqroman/app.png | Bin 0 -> 3969 bytes apps/pooqroman/resourcer.js | 721 + apps/poweroff/ChangeLog | 1 + apps/poweroff/README.md | 13 + apps/poweroff/app-icon.js | 1 + apps/poweroff/app.js | 13 + apps/poweroff/app.png | Bin 0 -> 620 bytes .../bangle1-party-parrot-screenshot.png | Bin 0 -> 3963 bytes apps/qalarm/ChangeLog | 5 +- apps/qalarm/app-icon.js | 2 +- apps/qalarm/app.js | 10 +- apps/qalarm/boot.js | 2 +- apps/qalarm/qalarmcheck.js | 9 +- apps/qmsched/ChangeLog | 1 + apps/qmsched/README.md | 15 +- apps/qmsched/app.js | 188 +- apps/qmsched/boot.js | 10 +- apps/qmsched/lib.js | 31 +- apps/qmsched/screenshot_b1_edit.png | Bin 0 -> 3610 bytes apps/qmsched/screenshot_b1_lcd.png | Bin 0 -> 4167 bytes apps/qmsched/screenshot_b1_main.png | Bin 0 -> 4050 bytes apps/qmsched/screenshot_b2_edit.png | Bin 0 -> 2946 bytes apps/qmsched/screenshot_b2_lcd.png | Bin 0 -> 3352 bytes apps/qmsched/screenshot_b2_main.png | Bin 0 -> 3226 bytes apps/qmsched/screenshot_edit.png | Bin 3644 -> 0 bytes apps/qmsched/screenshot_main.png | Bin 3661 -> 0 bytes apps/qmsched/screenshot_widget_alarms.png | Bin 3965 -> 0 bytes apps/qmsched/screenshot_widget_silent.png | Bin 3890 -> 0 bytes apps/qmsched/widget.js | 4 +- apps/recorder/ChangeLog | 1 + apps/recorder/app.js | 15 +- apps/rpgdice/bangle1-rpg-dice-screenshot.png | Bin 0 -> 2728 bytes apps/schoolCalendar/CalenderLogo.png | Bin 0 -> 1162 bytes apps/schoolCalendar/ChangeLog | 1 + apps/schoolCalendar/README.md | 27 + apps/schoolCalendar/app-icon.js | 1 + apps/schoolCalendar/custom.html | 416 + .../fullcalendar/interaction/LICENSE.txt | 22 + .../fullcalendar/interaction/README.md | 8 + .../fullcalendar/interaction/package.json | 32 + .../fullcalendar/interaction/tsconfig.json | 13 + .../fullcalendar/locales-all.js | 1622 ++ apps/schoolCalendar/fullcalendar/main.css | 1446 ++ apps/schoolCalendar/fullcalendar/main.js | 14738 ++++++++++++++++ apps/schoolCalendar/screenshot_basic.png | Bin 0 -> 6464 bytes apps/schoolCalendar/screenshot_info.png | Bin 0 -> 4021 bytes apps/scolor/bangle1-view-color-screenshot.png | Bin 0 -> 2796 bytes apps/sensible/ChangeLog | 2 + apps/sensible/README.md | 35 + apps/sensible/sensible-icon.js | 1 + apps/sensible/sensible.js | 162 + apps/sensible/sensible.png | Bin 0 -> 1716 bytes apps/setting/ChangeLog | 1 + apps/setting/README.md | 2 - apps/setting/settings.js | 129 +- apps/simpletimer/bangle1-timer-screenshot.png | Bin 0 -> 2721 bytes apps/slevel/ChangeLog | 1 + apps/slevel/spiritlevel.js | 16 +- .../bangle1-slow-mo-clock-screenshot.png | Bin 0 -> 3923 bytes .../bangle2-simple-v-clock-screenshot.png | Bin 0 -> 2253 bytes apps/swatch/bangle1-stopwatch-screenshot.png | Bin 0 -> 3415 bytes .../bangle1-sweep-clock-screenshot.png | Bin 0 -> 3040 bytes apps/swlclk/bangle1-SWL-clock-screenshot.png | Bin 0 -> 5343 bytes apps/thermom/ChangeLog | 1 + apps/thermom/app.js | 8 +- apps/timecal/icon.png | Bin 0 -> 3833 bytes apps/timecal/timecal.app.js | 94 + .../bangle1-vector-clock-screenshot.png | Bin 0 -> 5074 bytes ...bangle1-vertical-watch-face-screenshot.png | Bin 0 -> 3656 bytes .../bangle1-vibrate-clock-screenshot.png | Bin 0 -> 3110 bytes apps/welcome/ChangeLog | 1 + apps/welcome/settings.js | 3 +- apps/widbars/ChangeLog | 1 + apps/widbars/README.md | 15 + apps/widbars/icon.png | Bin 0 -> 2085 bytes apps/widbars/screenshot.png | Bin 0 -> 9787 bytes apps/widbars/widget.js | 67 + apps/widbatpc/ChangeLog | 1 + apps/widbatpc/README.md | 4 +- apps/widbatpc/widget.js | 16 +- apps/wohrm/bangle1-workout-HRM-screenshot.png | Bin 0 -> 3483 bytes core | 2 +- css/main.css | 52 +- index.html | 7 +- loader.js | 6 +- modules/Settings.js | 101 - 301 files changed, 23270 insertions(+), 950 deletions(-) create mode 100644 apps/93dub/93dub.png create mode 100644 apps/93dub/ChangeLog create mode 100644 apps/93dub/README.md create mode 100644 apps/93dub/app-icon.js create mode 100644 apps/93dub/app.js create mode 100644 apps/93dub/screenshot.png create mode 100644 apps/a_clock_timer/ChangeLog create mode 100644 apps/a_clock_timer/README.md create mode 100644 apps/a_clock_timer/app-icon.js create mode 100644 apps/a_clock_timer/app.js create mode 100644 apps/a_clock_timer/app.png create mode 100644 apps/a_clock_timer/screenshot.png create mode 100644 apps/a_speech_timer/ChangeLog create mode 100644 apps/a_speech_timer/README.md create mode 100644 apps/a_speech_timer/app-icon.js create mode 100644 apps/a_speech_timer/app.js create mode 100644 apps/a_speech_timer/app.png create mode 100644 apps/a_speech_timer/screenshot0.png create mode 100644 apps/a_speech_timer/screenshot1.png create mode 100644 apps/a_speech_timer/screenshot2.png create mode 100644 apps/a_speech_timer/screenshot3.png create mode 100644 apps/about/bangle1-about-screenshot.png create mode 100644 apps/android/settings.js create mode 100644 apps/battleship/bangle1-battle-ship-screenshot.png create mode 100644 apps/bclock/bangle1-binary-clock-screenshot.png create mode 100644 apps/beebclock/bangle1-beeb-clock-screenshot.png create mode 100644 apps/berlinc/berlin-clock-screenshot.png create mode 100644 apps/binwatch/Background176_center.img create mode 100644 apps/binwatch/Background240_center.img create mode 100644 apps/blackjack/bangle1-black-jack-game-screenshot.png create mode 100644 apps/blobclk/bangle1-large-digit-blob-clock-screenshot.png create mode 100644 apps/blobclk/bangle2-large-digit-blob-clock-screenshot.png create mode 100644 apps/chargeanim/bangle-charge-animation-screenshot.png create mode 100644 apps/chargeanim/bangle2-charge-animation-screenshot.png create mode 100644 apps/choozi/bangle1-choozi-screenshot1.png create mode 100644 apps/choozi/bangle1-choozi-screenshot2.png create mode 100644 apps/cliclockJS2Enhanced/ChangeLog create mode 100644 apps/clotris/bangle1-clock-tris-screenshot.png create mode 100644 apps/counter/bangle1-counter-screenshot.png create mode 100644 apps/cprassist/bangle1-CPR-assist-screenshot.png create mode 100644 apps/ctrclk/bangle1-center-clock-screenshot.png create mode 100644 apps/cubescramble/bangle1-cube-scramble-screenshot.png create mode 100644 apps/cubescramble/bangle2-cube-scramble-screenshot.png create mode 100644 apps/dclock/bangle1-dev-clock-screenshot.png create mode 100644 apps/dclock/bangle2-dev-clock-screenshot.png create mode 100644 apps/demoapp/bangle1-demo-loop-screenshot1.png create mode 100644 apps/demoapp/bangle1-demo-loop-screenshot2.png create mode 100644 apps/demoapp/bangle1-demo-loop-screenshot3.png create mode 100644 apps/demoapp/bangle1-demo-loop-screenshot4.png create mode 100644 apps/devstopwatch/bangle1-dev-stopwatch-screenshot.png create mode 100644 apps/dotclock/bangle1-dot-clock-screenshot.png create mode 100644 apps/dotclock/bangle2-dot-clcok-screenshot.png create mode 100644 apps/emojuino/screenshot-swipe.png create mode 100644 apps/emojuino/screenshot-tx.png create mode 100644 apps/emojuino/screenshot-welcome.png create mode 100644 apps/fd6fdetect/README.md create mode 100644 apps/gbdebug/ChangeLog create mode 100644 apps/gbdebug/README.md create mode 100644 apps/gbdebug/app-icon.js create mode 100644 apps/gbdebug/app.js create mode 100644 apps/gbdebug/app.png create mode 100644 apps/getup/bangle1-get-up-screenshot.png create mode 100644 apps/hcclock/bangle1-high-contrast-clock-screenshot.png create mode 100644 apps/hrings/bangle1-hypno-rings-screenshot.png create mode 100644 apps/impwclock/bangle1-impercise-word-clock-screenshot.png create mode 100644 apps/intervalTimer/ChangeLog create mode 100644 apps/intervalTimer/README.md create mode 100644 apps/intervalTimer/app-icon.js create mode 100644 apps/intervalTimer/app.js create mode 100644 apps/intervalTimer/app.png create mode 100644 apps/intervalTimer/images/done.png create mode 100644 apps/intervalTimer/images/pause.png create mode 100644 apps/intervalTimer/images/set-active.png create mode 100644 apps/intervalTimer/images/set-rest.png create mode 100644 apps/intervalTimer/images/set-sets.png create mode 100644 apps/intervalTimer/images/timer1.png create mode 100644 apps/intervalTimer/images/timer2.png create mode 100644 apps/jbm8b_IT/bangle1-magic-8-ball-italiano-screenshot.png create mode 100644 apps/largeclock/bangle1-large-clock-screenshot.png create mode 100644 apps/lazyclock/bangle1-lazy-clock-screenshot.png delete mode 100644 apps/lcars/background.png create mode 100644 apps/lcars/bg_large.png create mode 100644 apps/lcars/bg_small.png create mode 100644 apps/life/bangle1-game-of-life-screenshot.png create mode 100644 apps/mandlebrotclock/ChangeLog create mode 100644 apps/mandlebrotclock/README.md create mode 100644 apps/mandlebrotclock/app.png create mode 100644 apps/mandlebrotclock/mandlebrotclock-icon.js create mode 100644 apps/mandlebrotclock/mandlebrotclock.js create mode 100644 apps/mandlebrotclock/mandlebrotclock.png create mode 100644 apps/mandlebrotclock/screenshot_mandlebrotclock.png create mode 100644 apps/marioclock/bangle1-mario-clock-screenshot.png create mode 100644 apps/mclock/bangle1-morphing-clock-screenshot.png create mode 100644 apps/messages/settings.js create mode 100644 apps/metronome/bangle1-metronome-screenshot.png create mode 100644 apps/miclock/bangle1-mixed-clock-screenshot.png create mode 100644 apps/miclock2/bangle1-mixed-clock-2-screenshot.png create mode 100644 apps/minionclk/bangle1-minion-clock-screenshot.png create mode 100644 apps/moonphase/bangle1-moon-phase-screenshot.png create mode 100644 apps/mylocation/ChangeLog create mode 100644 apps/mylocation/README.md create mode 100644 apps/mylocation/mylocation.app.js create mode 100644 apps/mylocation/mylocation.icon.js create mode 100644 apps/mylocation/mylocation.png create mode 100644 apps/mylocation/screenshot_1.png create mode 100644 apps/mylocation/screenshot_2.png create mode 100644 apps/mylocation/screenshot_3.png create mode 100644 apps/mylocation/screenshot_4.png create mode 100644 apps/mysticclock/bangle1-mystic-clock-screenshot.png create mode 100644 apps/mywelcome/bangle1-customized-welcome-screenshot.png create mode 100644 apps/nato/bangle1-NATO-alphabet-screenshot.png create mode 100644 apps/nato/bangle1-NATO-alphabet-screenshot2.png create mode 100644 apps/numerals/bangle1-numerals-screenshot.png create mode 100644 apps/pastel/f_architect.js create mode 100644 apps/pastel/f_cabin.js create mode 100644 apps/pastel/f_elite.js create mode 100644 apps/pastel/f_gochihand.js create mode 100644 apps/pastel/f_lato.js create mode 100644 apps/pastel/f_latosmall.js create mode 100644 apps/pastel/f_monoton.js create mode 100644 apps/pastel/f_orbitron.js delete mode 100644 apps/pastel/screenshot_architech.jpg create mode 100644 apps/pastel/screenshot_architect.png delete mode 100644 apps/pastel/screenshot_b2_dark.jpg create mode 100644 apps/pastel/screenshot_cabinsketch.png delete mode 100644 apps/pastel/screenshot_elite.jpg create mode 100644 apps/pastel/screenshot_elite.png delete mode 100644 apps/pastel/screenshot_gochi.jpg create mode 100644 apps/pastel/screenshot_gochihand.png delete mode 100644 apps/pastel/screenshot_lato.jpg create mode 100644 apps/pastel/screenshot_lato.png delete mode 100644 apps/pastel/screenshot_monoton.jpg create mode 100644 apps/pastel/screenshot_monoton.png create mode 100644 apps/pastel/screenshot_orbitron.png create mode 100644 apps/pebble/ChangeLog create mode 100644 apps/pebble/LECO 1976-Regular.otf create mode 100644 apps/pebble/README.md create mode 100644 apps/pebble/pebble.app.js create mode 100644 apps/pebble/pebble.icon.js create mode 100644 apps/pebble/pebble.png create mode 100644 apps/pebble/pebble.settings.js create mode 100644 apps/pebble/pebble_screenshot.png create mode 100644 apps/pebble/pebble_screenshot2.png create mode 100644 apps/pebble/pebble_screenshot3.png create mode 100644 apps/pipboy/bangle1-pipboy-themed-clock-screenshot.png create mode 100644 apps/pomodo/bangle2-pomodoro-screenshot.png create mode 100644 apps/pong/bangle1-pong-screenshot.png create mode 100644 apps/pooqroman/README.md create mode 100644 apps/pooqroman/app-icon.js create mode 100644 apps/pooqroman/app.js create mode 100644 apps/pooqroman/app.png create mode 100644 apps/pooqroman/resourcer.js create mode 100644 apps/poweroff/ChangeLog create mode 100644 apps/poweroff/README.md create mode 100644 apps/poweroff/app-icon.js create mode 100644 apps/poweroff/app.js create mode 100644 apps/poweroff/app.png create mode 100644 apps/pparrot/bangle1-party-parrot-screenshot.png create mode 100644 apps/qmsched/screenshot_b1_edit.png create mode 100644 apps/qmsched/screenshot_b1_lcd.png create mode 100644 apps/qmsched/screenshot_b1_main.png create mode 100644 apps/qmsched/screenshot_b2_edit.png create mode 100644 apps/qmsched/screenshot_b2_lcd.png create mode 100644 apps/qmsched/screenshot_b2_main.png delete mode 100644 apps/qmsched/screenshot_edit.png delete mode 100644 apps/qmsched/screenshot_main.png delete mode 100644 apps/qmsched/screenshot_widget_alarms.png delete mode 100644 apps/qmsched/screenshot_widget_silent.png create mode 100644 apps/rpgdice/bangle1-rpg-dice-screenshot.png create mode 100644 apps/schoolCalendar/CalenderLogo.png create mode 100644 apps/schoolCalendar/ChangeLog create mode 100644 apps/schoolCalendar/README.md create mode 100644 apps/schoolCalendar/app-icon.js create mode 100644 apps/schoolCalendar/custom.html create mode 100644 apps/schoolCalendar/fullcalendar/interaction/LICENSE.txt create mode 100644 apps/schoolCalendar/fullcalendar/interaction/README.md create mode 100644 apps/schoolCalendar/fullcalendar/interaction/package.json create mode 100644 apps/schoolCalendar/fullcalendar/interaction/tsconfig.json create mode 100644 apps/schoolCalendar/fullcalendar/locales-all.js create mode 100644 apps/schoolCalendar/fullcalendar/main.css create mode 100644 apps/schoolCalendar/fullcalendar/main.js create mode 100644 apps/schoolCalendar/screenshot_basic.png create mode 100644 apps/schoolCalendar/screenshot_info.png create mode 100644 apps/scolor/bangle1-view-color-screenshot.png create mode 100644 apps/sensible/ChangeLog create mode 100644 apps/sensible/README.md create mode 100644 apps/sensible/sensible-icon.js create mode 100644 apps/sensible/sensible.js create mode 100644 apps/sensible/sensible.png create mode 100644 apps/simpletimer/bangle1-timer-screenshot.png create mode 100644 apps/slomoclock/bangle1-slow-mo-clock-screenshot.png create mode 100644 apps/svclock/bangle2-simple-v-clock-screenshot.png create mode 100644 apps/swatch/bangle1-stopwatch-screenshot.png create mode 100644 apps/sweepclock/bangle1-sweep-clock-screenshot.png create mode 100644 apps/swlclk/bangle1-SWL-clock-screenshot.png create mode 100644 apps/timecal/icon.png create mode 100644 apps/timecal/timecal.app.js create mode 100644 apps/vectorclock/bangle1-vector-clock-screenshot.png create mode 100644 apps/verticalface/bangle1-vertical-watch-face-screenshot.png create mode 100644 apps/vibrclock/bangle1-vibrate-clock-screenshot.png create mode 100644 apps/widbars/ChangeLog create mode 100644 apps/widbars/README.md create mode 100644 apps/widbars/icon.png create mode 100644 apps/widbars/screenshot.png create mode 100644 apps/widbars/widget.js create mode 100644 apps/wohrm/bangle1-workout-HRM-screenshot.png delete mode 100644 modules/Settings.js diff --git a/.eslintignore b/.eslintignore index 57fedb0da..e657b6260 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,4 @@ apps/animclk/V29.LBM.js apps/banglerun/rollup.config.js +apps/schoolCalendar/fullcalendar/main.js +apps/authentiwatch/qr_packed.js diff --git a/README.md b/README.md index 20ae8afb2..8e186cf79 100644 --- a/README.md +++ b/README.md @@ -384,14 +384,18 @@ Example `settings.js` ```js // make sure to enclose the function in parentheses (function(back) { - function get(key, def) { return require('Settings').get('myappid', key, def); } - function set(key, value) { require('Settings').set('myappid', key, value); } + let settings = require('Storage').readJSON('myappid.json',1)||{}; + if (typeof settings.monkeys !== "number") settings.monkeys = 12; // default value + function save(key, value) { + settings[key] = value; + require('Storage').write('myappid.json', settings); + } const appMenu = { '': {'title': 'App Settings'}, '< Back': back, 'Monkeys': { - value: get('monkeys', 12), - onchange: (m) => set('monkeys', m) + value: settings.monkeys, + onchange: (m) => {save('monkeys', m)} } }; E.showMenu(appMenu) diff --git a/apps.json b/apps.json index ea42a1c68..a312b90a3 100644 --- a/apps.json +++ b/apps.json @@ -16,7 +16,7 @@ { "id": "boot", "name": "Bootloader", - "version": "0.36", + "version": "0.37", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "icon": "bootloader.png", "type": "bootloader", @@ -32,7 +32,7 @@ { "id": "messages", "name": "Messages", - "version": "0.03", + "version": "0.07", "description": "App to display notifications from iOS and Gadgetbridge", "icon": "app.png", "type": "app", @@ -41,16 +41,19 @@ "readme": "README.md", "storage": [ {"name":"messages.app.js","url":"app.js"}, + {"name":"messages.settings.js","url":"settings.js"}, {"name":"messages.img","url":"app-icon.js","evaluate":true}, {"name":"messages.wid.js","url":"widget.js"}, {"name":"messages","url":"lib.js"} ], + "data": [{"name":"messages.json"},{"name":"messages.settings.json"}], "sortorder": -9 }, { "id": "android", "name": "Android Integration", - "version": "0.01", + "shortName": "Android", + "version": "0.04", "description": "(BETA) App to display notifications from Gadgetbridge on Android. This will eventually replace the Gadgetbridge widget.", "icon": "app.png", "tags": "tool,system,messages,notifications", @@ -58,15 +61,16 @@ "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"android.app.js","url":"app.js"}, + {"name":"android.settings.js","url":"settings.js"}, {"name":"android.img","url":"app-icon.js","evaluate":true}, {"name":"android.boot.js","url":"boot.js"} ], - "sortorder": -9 + "sortorder": -8 }, { "id": "ios", "name": "iOS Integration", - "version": "0.01", + "version": "0.03", "description": "(BETA) App to display notifications from iOS devices", "icon": "app.png", "tags": "tool,system,ios,apple,messages,notifications", @@ -77,13 +81,13 @@ {"name":"ios.img","url":"app-icon.js","evaluate":true}, {"name":"ios.boot.js","url":"boot.js"} ], - "sortorder": -9 + "sortorder": -8 }, { "id": "health", "name": "Health Tracking", "version": "0.08", - "description": "Logs health data and provides an app to view it (BETA - requires firmware 2v11)", + "description": "Logs health data and provides an app to view it (requires firmware 2v10.100 or later)", "icon": "app.png", "tags": "tool,system,health", "supports": ["BANGLEJS","BANGLEJS2"], @@ -108,19 +112,14 @@ "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"launch.app.js","url":"app-bangle1.js","supports":["BANGLEJS"]}, - {"name":"launch.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]}, - {"name":"launch.settings.js","url":"settings.js","supports":["BANGLEJS2"]} + {"name":"launch.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]} ], - "data": [ - {"name":"launch.json"} - ] - , "sortorder": -10 }, { "id": "setting", "name": "Settings", - "version": "0.33", + "version": "0.34", "description": "A menu for setting up Bangle.js", "icon": "settings.png", "tags": "tool,system", @@ -136,11 +135,12 @@ { "id": "about", "name": "About", - "version": "0.11", + "version": "0.12", "description": "Bangle.js About page - showing software version, stats, and a collaborative mural from the Bangle.js KickStarter backers", "icon": "app.png", "tags": "tool,system", "supports": ["BANGLEJS","BANGLEJS2"], + "screenshots": [{"url":"bangle1-about-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"about.app.js","url":"app-bangle1.js","supports": ["BANGLEJS"]}, @@ -170,7 +170,7 @@ { "id": "locale", "name": "Languages", - "version": "0.09", + "version": "0.10", "description": "Translations for different countries", "icon": "locale.png", "type": "locale", @@ -216,7 +216,7 @@ "id": "welcome", "name": "Welcome", "shortName": "Welcome", - "version": "0.13", + "version": "0.14", "description": "Appears at first boot and explains how to use Bangle.js", "icon": "app.png", "screenshots": [{"url":"screenshot_welcome.png"}], @@ -242,6 +242,7 @@ "tags": "start,welcome", "supports": ["BANGLEJS"], "custom": "custom.html", + "screenshots": [{"url":"bangle1-customized-welcome-screenshot.png"}], "storage": [ {"name":"mywelcome.boot.js","url":"boot.js"}, {"name":"mywelcome.app.js","url":"app.js"}, @@ -268,6 +269,20 @@ ], "data": [{"name":"gbridge.json"}] }, + { "id": "gbdebug", + "name": "Gadgetbridge Debug", + "shortName":"GB Debug", + "version":"0.01", + "description": "Debug info for Gadgetbridge. Run this app and when Gadgetbridge messages arrive they are displayed on-screen.", + "icon": "app.png", + "tags": "", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"gbdebug.app.js","url":"app.js"}, + {"name":"gbdebug.img","url":"app-icon.js","evaluate":true} + ] + }, { "id": "mclock", "name": "Morphing Clock", @@ -278,6 +293,7 @@ "tags": "clock", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-morphing-clock-screenshot.png"}], "storage": [ {"name":"mclock.app.js","url":"clock-morphing.js"}, {"name":"mclock.img","url":"clock-morphing-icon.js","evaluate":true} @@ -292,6 +308,7 @@ "icon": "app.png", "tags": "", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-moon-phase-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"moonphase.app.js","url":"app.js"}, @@ -422,6 +439,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-sweep-clock-screenshot.png"}], "storage": [ {"name":"sweepclock.app.js","url":"sweepclock.js"}, {"name":"sweepclock.img","url":"sweepclock-icon.js","evaluate":true} @@ -444,6 +462,27 @@ {"name":"matrixclock.img","url":"matrixclock-icon.js","evaluate":true} ] }, + { + "id": "mandlebrotclock", + "name": "Mandlebrot Clock", + "version": "0.01", + "description": "A mandlebrot set themed clock cool", + "icon": "mandlebrotclock.png", + "screenshots": [{ "url": "screenshot_mandlebrotclock.png" }], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + { "name": "mandlebrotclock.app.js", "url": "mandlebrotclock.js" }, + { + "name": "mandlebrotclock.img", + "url": "mandlebrotclock-icon.js", + "evaluate": true + } + ] + }, { "id": "imgclock", "name": "Image background clock", @@ -472,6 +511,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-impercise-word-clock-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"impwclock.app.js","url":"clock-impword.js"}, @@ -548,13 +588,14 @@ { "id": "cubescramble", "name": "Cube Scramble", - "version":"0.03", - "description": "A random scramble generator for the 3x3 Rubik's cube", + "version":"0.04", + "description": "A random scramble generator for the 3x3 Rubik's cube with a basic timer", "icon": "cube-scramble.png", "tags": "", "supports" : ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle2-cube-scramble-screenshot.png"},{"url":"bangle1-cube-scramble-screenshot.png"}], "storage": [ {"name":"cubescramble.app.js","url":"cube-scramble.js"}, {"name":"cubescramble.img","url":"cube-scramble-icon.js","evaluate":true} @@ -658,7 +699,7 @@ { "id": "gpsrec", "name": "GPS Recorder", - "version": "0.24", + "version": "0.26", "description": "Application that allows you to record a GPS track. Can run in background", "icon": "app.png", "tags": "tool,outdoors,gps,widget", @@ -677,7 +718,7 @@ "id": "recorder", "name": "Recorder (BETA)", "shortName": "Recorder", - "version": "0.03", + "version": "0.04", "description": "Record GPS position, heart rate and more in the background, then download to your PC.", "icon": "app.png", "tags": "tool,outdoors,gps,widget", @@ -728,11 +769,11 @@ { "id": "slevel", "name": "Spirit Level", - "version": "0.01", + "version": "0.02", "description": "Show the current angle of the watch, so you can use it to make sure something is absolutely flat", "icon": "spiritlevel.png", "tags": "tool", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"slevel.app.js","url":"spiritlevel.js"}, {"name":"slevel.img","url":"spiritlevel-icon.js","evaluate":true} @@ -745,7 +786,7 @@ "description": "Show currently installed apps, free space, and allow their deletion from the watch", "icon": "files.png", "tags": "tool,system,files", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"files.app.js","url":"files.js"}, {"name":"files.img","url":"files-icon.js","evaluate":true} @@ -779,6 +820,7 @@ "tags": "battery", "supports": ["BANGLEJS", "BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"bangle2-charge-animation-screenshot.png"},{"url":"bangle-charge-animation-screenshot.png"}], "storage": [ {"name":"chargeanim.app.js","url":"app.js"}, {"name":"chargeanim.boot.js","url":"boot.js"}, @@ -844,7 +886,7 @@ "id": "widbatpc", "name": "Battery Level Widget (with percentage)", "shortName": "Battery Widget", - "version": "0.13", + "version": "0.14", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage", "icon": "widget.png", "type": "widget", @@ -984,6 +1026,7 @@ "readme": "README.md", "interface": "interface.html", "allow_emulator": true, + "screenshots": [{"url":"bangle1-stopwatch-screenshot.png"}], "storage": [ {"name":"swatch.app.js","url":"stopwatch.js"}, {"name":"swatch.img","url":"stopwatch-icon.js","evaluate":true} @@ -1185,6 +1228,7 @@ "tags": "clock", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-vibrate-clock-screenshot.png"}], "storage": [ {"name":"vibrclock.app.js","url":"app.js"}, {"name":"vibrclock.img","url":"app-icon.js","evaluate":true} @@ -1200,6 +1244,7 @@ "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"bangle2-simple-v-clock-screenshot.png"}], "storage": [ {"name":"svclock.app.js","url":"vclock-simple.js"}, {"name":"svclock.img","url":"vclock-simple-icon.js","evaluate":true} @@ -1215,6 +1260,7 @@ "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"bangle2-dev-clock-screenshot.png"},{"url":"bangle1-dev-clock-screenshot.png"}], "storage": [ {"name":"dclock.app.js","url":"clock-dev.js"}, {"name":"dclock.img","url":"clock-dev-icon.js","evaluate":true} @@ -1246,6 +1292,7 @@ "tags": "party,parrot,lol", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-party-parrot-screenshot.png"}], "storage": [ {"name":"pparrot.app.js","url":"party-parrot.js"}, {"name":"pparrot.img","url":"party-parrot-icon.js","evaluate":true} @@ -1261,6 +1308,7 @@ "tags": "rings,hypnosis,psychadelic", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-hypno-rings-screenshot.png"}], "storage": [ {"name":"hrings.app.js","url":"hypno-rings.js"}, {"name":"hrings.img","url":"hypno-rings-icon.js","evaluate":true} @@ -1328,6 +1376,7 @@ "icon": "show-color.png", "type": "app", "tags": "tool", + "screenshots": [{"url":"bangle1-view-color-screenshot.png"}], "supports": ["BANGLEJS"], "allow_emulator": true, "storage": [ @@ -1343,6 +1392,7 @@ "icon": "clock-mixed.png", "type": "clock", "tags": "clock", + "screenshots": [{"url":"bangle1-mixed-clock-screenshot.png"}], "supports": ["BANGLEJS"], "allow_emulator": true, "storage": [ @@ -1360,6 +1410,7 @@ "tags": "clock", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-binary-clock-screenshot.png"}], "storage": [ {"name":"bclock.app.js","url":"clock-binary.js"}, {"name":"bclock.img","url":"clock-binary-icon.js","evaluate":true} @@ -1373,6 +1424,7 @@ "icon": "clock-tris.png", "tags": "game", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-clock-tris-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"clotris.app.js","url":"clock-tris.js"}, @@ -1432,6 +1484,7 @@ "tags": "pomodoro,cooking,tools", "supports": ["BANGLEJS", "BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"bangle2-pomodoro-screenshot.png"}], "storage": [ {"name":"pomodo.app.js","url":"pomodoro.js"}, {"name":"pomodo.img","url":"pomodoro-icon.js","evaluate":true} @@ -1448,6 +1501,7 @@ "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"bangle2-large-digit-blob-clock-screenshot.png"},{"url":"bangle1-large-digit-blob-clock-screenshot.png"}], "storage": [ {"name":"blobclk.app.js","url":"clock-blob.js"}, {"name":"blobclk.img","url":"clock-blob-icon.js","evaluate":true} @@ -1507,6 +1561,7 @@ "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"berlin-clock-screenshot.png"}], "storage": [ {"name":"berlinc.app.js","url":"berlin-clock.js"}, {"name":"berlinc.img","url":"berlin-clock-icon.js","evaluate":true} @@ -1521,6 +1576,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-center-clock-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"ctrclk.app.js","url":"app.js"}, @@ -1535,6 +1591,7 @@ "icon": "app.png", "type": "app", "tags": "", + "screenshots": [{"url":"bangle1-demo-loop-screenshot1.png"},{"url":"bangle1-demo-loop-screenshot2.png"},{"url":"bangle1-demo-loop-screenshot3.png"},{"url":"bangle1-demo-loop-screenshot4.png"}], "supports": ["BANGLEJS"], "allow_emulator": true, "storage": [ @@ -1567,6 +1624,7 @@ "tags": "clock", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-pipboy-themed-clock-screenshot.png"}], "storage": [ {"name":"pipboy.app.js","url":"app.js"}, {"name":"pipboy.img","url":"app-icon.js","evaluate":true} @@ -1613,6 +1671,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-workout-HRM-screenshot.png"}], "storage": [ {"name":"wohrm.app.js","url":"app.js"}, {"name":"wohrm.img","url":"app-icon.js","evaluate":true} @@ -1657,6 +1716,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": false, + "screenshots": [{"url":"bangle1-mario-clock-screenshot.png"}], "storage": [ {"name":"marioclock.app.js","url":"marioclock-app.js"}, {"name":"marioclock.img","url":"marioclock-icon.js","evaluate":true} @@ -1695,13 +1755,13 @@ { "id": "barclock", "name": "Bar Clock", - "version": "0.08", + "version": "0.09", "description": "A simple digital clock showing seconds as a bar", "icon": "clock-bar.png", "screenshots": [{"url":"screenshot.png"},{"url":"screenshot_pm.png"}], "type": "clock", "tags": "clock", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "allow_emulator": true, "storage": [ @@ -1719,6 +1779,7 @@ "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"bangle2-dot-clcok-screenshot.png"},{"url":"bangle1-dot-clock-screenshot.png"}], "storage": [ {"name":"dotclock.app.js","url":"clock-dot.js"}, {"name":"dotclock.img","url":"clock-dot-icon.js","evaluate":true} @@ -1828,6 +1889,7 @@ "tags": "game,fun", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-rpg-dice-screenshot.png"}], "storage": [ {"name":"rpgdice.app.js","url":"app.js"}, {"name":"rpgdice.img","url":"app-icon.js","evaluate":true} @@ -1856,6 +1918,7 @@ "tags": "clock,minion", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-minion-clock-screenshot.png"}], "storage": [ {"name":"minionclk.app.js","url":"app.js"}, {"name":"minionclk.img","url":"app-icon.js","evaluate":true} @@ -1865,7 +1928,7 @@ "id": "openstmap", "name": "OpenStreetMap", "shortName": "OpenStMap", - "version": "0.09", + "version": "0.10", "description": "[BETA] Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are", "icon": "app.png", "tags": "outdoors,gps", @@ -1933,7 +1996,7 @@ "icon": "custom.png", "type": "bootloader", "tags": "tool,system", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "custom": "custom.html", "storage": [ {"name":"custom"} @@ -1948,6 +2011,7 @@ "icon": "app.png", "tags": "stopwatch,chrono,timer,chronometer", "supports": ["BANGLEJS","BANGLEJS2"], + "screenshots": [{"url":"bangle1-dev-stopwatch-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"devstopwatch.app.js","url":"app.js"}, @@ -1981,6 +2045,7 @@ "tags": "app,learn,visual", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-NATO-alphabet-screenshot.png"},{"url":"bangle1-NATO-alphabet-screenshot2.png"}], "storage": [ {"name":"nato.app.js","url":"nato.js"}, {"name":"nato.img","url":"nato-icon.js","evaluate":true} @@ -1997,6 +2062,7 @@ "tags": "numerals,clock", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-numerals-screenshot.png"}], "storage": [ {"name":"numerals.app.js","url":"numerals.app.js"}, {"name":"numerals.img","url":"numerals-icon.js","evaluate":true}, @@ -2123,13 +2189,14 @@ { "id": "metronome", "name": "Metronome", - "version": "0.06", + "version": "0.07", + "readme": "README.md", "description": "Makes the watch blinking and vibrating with a given rate", "icon": "metronome_icon.png", "tags": "tool", - "supports": ["BANGLEJS"], - "readme": "README.md", + "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-metronome-screenshot.png"}], "storage": [ {"name":"metronome.app.js","url":"metronome.js"}, {"name":"metronome.img","url":"metronome-icon.js","evaluate":true}, @@ -2145,6 +2212,7 @@ "icon": "blackjack.png", "tags": "game", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-black-jack-game-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"blackjack.app.js","url":"blackjack.app.js"}, @@ -2178,6 +2246,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-SWL-clock-screenshot.png"}], "storage": [ {"name":"swlclk.app.js","url":"app.js"}, {"name":"swlclk.img","url":"app-icon.js","evaluate":true} @@ -2255,6 +2324,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-pong-screenshot.png"}], "storage": [ {"name":"pong.app.js","url":"app.js"}, {"name":"pong.img","url":"app-icon.js","evaluate":true} @@ -2317,6 +2387,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-large-clock-screenshot.png"}], "storage": [ {"name":"largeclock.app.js","url":"largeclock.js"}, {"name":"largeclock.img","url":"largeclock-icon.js","evaluate":true}, @@ -2368,6 +2439,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-timer-screenshot.png"}], "storage": [ {"name":"simpletimer.app.js","url":"app.js"}, {"name":".tfnames","url":"gesture-tfnames.js","evaluate":true}, @@ -2384,6 +2456,7 @@ "icon": "beebclock.png", "type": "clock", "tags": "clock", + "screenshots": [{"url":"bangle1-beeb-clock-screenshot.png"}], "supports": ["BANGLEJS"], "allow_emulator": true, "storage": [ @@ -2417,6 +2490,7 @@ "tags": "tools,health", "supports": ["BANGLEJS"], "readme": "README.md", + "screenshots": [{"url":"bangle1-get-up-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"getup.app.js","url":"app.js"}, @@ -2495,6 +2569,7 @@ "version": "0.01", "description": "La palla predice il futuro", "icon": "app.png", + "screenshots": [{"url":"bangle1-magic-8-ball-italiano-screenshot.png"}], "tags": "game", "supports": ["BANGLEJS"], "allow_emulator": true, @@ -2608,6 +2683,7 @@ "tags": "clock", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-vertical-watch-face-screenshot.png"}], "storage": [ {"name":"verticalface.app.js","url":"app.js"}, {"name":"verticalface.img","url":"app-icon.js","evaluate":true} @@ -2635,6 +2711,7 @@ "icon": "life.png", "tags": "game", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-game-of-life-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"life.app.js","url":"life.min.js"}, @@ -2682,6 +2759,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-mixed-clock-2-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"miclock2.app.js","url":"clock-mixed.js"}, @@ -2817,6 +2895,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-CPR-assist-screenshot.png"}], "storage": [ {"name":"cprassist.app.js","url":"cprassist.js"}, {"name":"cprassist.img","url":"cprassist-icon.js","evaluate":true}, @@ -2860,6 +2939,7 @@ "icon": "counter_icon.png", "tags": "tool", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-counter-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"counter.app.js","url":"counter.js"}, @@ -2903,7 +2983,7 @@ "id": "cscsensor", "name": "Cycling speed sensor", "shortName": "CSCSensor", - "version": "0.05", + "version": "0.06", "description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch", "icon": "icons8-cycling-48.png", "tags": "outdoors,exercise,ble,bluetooth", @@ -3239,6 +3319,7 @@ "tags": "clock", "supports": ["BANGLEJS"], "readme": "README.md", + "screenshots": [{"url":"bangle1-lazy-clock-screenshot.png"}], "allow_emulator": true, "storage": [ {"name":"lazyclock.app.js","url":"lazyclock-app.js"}, @@ -3340,6 +3421,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-slow-mo-clock-screenshot.png"}], "storage": [ {"name":"slomoclock.app.js","url":"app.js"}, {"name":"slomoclock.img","url":"app-icon.js","evaluate":true}, @@ -3654,7 +3736,7 @@ "id": "gbmusic", "name": "Gadgetbridge Music Controls", "shortName": "Music Controls", - "version": "0.06", + "version": "0.07", "description": "Control the music on your Gadgetbridge-connected phone", "icon": "icon.png", "screenshots": [{"url":"screenshot_v1.png"},{"url":"screenshot_v2.png"}], @@ -3679,6 +3761,7 @@ "icon": "battleship-icon.png", "tags": "game", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-battle-ship-screenshot.png"}], "readme": "README.md", "allow_emulator": true, "storage": [ @@ -3728,10 +3811,11 @@ "id": "qmsched", "name": "Quiet Mode Schedule and Widget", "shortName": "Quiet Mode", - "version": "0.03", - "description": "Automatically turn Quiet Mode on or off at set times", + "version": "0.04", + "description": "Automatically turn Quiet Mode on or off at set times, and change LCD options while Quiet Mode is active.", "icon": "app.png", - "screenshots": [{"url":"screenshot_edit.png"},{"url":"screenshot_main.png"},{"url":"screenshot_widget_alarms.png"},{"url":"screenshot_widget_silent.png"}], + "screenshots": [{"url":"screenshot_b1_main.png"},{"url":"screenshot_b1_edit.png"},{"url":"screenshot_b1_lcd.png"}, + {"url":"screenshot_b2_main.png"},{"url":"screenshot_b2_edit.png"},{"url":"screenshot_b2_lcd.png"}], "tags": "tool,widget", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", @@ -3845,8 +3929,8 @@ { "id": "thermom", "name": "Thermometer", - "version": "0.02", - "description": "Displays the current temperature, updated every 20 seconds", + "version": "0.03", + "description": "Displays the current temperature in degree Celsius, updated every 20 seconds", "icon": "app.png", "tags": "tool", "supports": ["BANGLEJS"], @@ -3882,6 +3966,7 @@ "type": "clock", "tags": "clock", "supports": ["BANGLEJS"], + "screenshots": [{"url":"bangle1-mystic-clock-screenshot.png"}], "readme": "README.md", "allow_emulator": true, "storage": [ @@ -3898,6 +3983,7 @@ "icon": "hcclock-icon.png", "type": "clock", "tags": "clock", + "screenshots": [{"url":"bangle1-high-contrast-clock-screenshot.png"}], "supports": ["BANGLEJS"], "allow_emulator": true, "storage": [ @@ -3979,6 +4065,7 @@ "tags": "clock", "supports": ["BANGLEJS"], "allow_emulator": true, + "screenshots": [{"url":"bangle1-vector-clock-screenshot.png"}], "storage": [ {"name":"vectorclock.app.js","url":"app.js"}, {"name":"vectorclock.img","url":"app-icon.js","evaluate":true} @@ -3988,10 +4075,11 @@ "id": "fd6fdetect", "name": "fd6fdetect", "shortName": "fd6fdetect", - "version": "0.1", + "version": "0.2", "description": "Allows you to see 0xFD6F beacons near you.", "icon": "app.png", "tags": "tool", + "readme": "README.md", "supports": ["BANGLEJS"], "storage": [ {"name":"fd6fdetect.app.js","url":"app.js"}, @@ -4008,6 +4096,7 @@ "supports": ["BANGLEJS"], "readme": "README.md", "allow_emulator": true, + "screenshots": [{"url":"bangle1-choozi-screenshot1.png"},{"url":"bangle1-choozi-screenshot2.png"}], "storage": [ {"name":"choozi.app.js","url":"app.js"}, {"name":"choozi.img","url":"app-icon.js","evaluate":true} @@ -4032,15 +4121,24 @@ "id": "pastel", "name": "Pastel Clock", "shortName": "Pastel", - "version": "0.05", - "description": "A Configurable clock with custom fonts and background", + "version": "0.08", + "description": "A Configurable clock with custom fonts and background. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", "icon": "pastel.png", + "dependencies": {"mylocation":"app"}, "screenshots": [{"url":"screenshot_pastel.png"}], "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "storage": [ + {"name":"f_architect","url":"f_architect.js"}, + {"name":"f_gochihand","url":"f_gochihand.js"}, + {"name":"f_cabin","url":"f_cabin.js"}, + {"name":"f_orbitron","url":"f_orbitron.js"}, + {"name":"f_monoton","url":"f_monoton.js"}, + {"name":"f_elite","url":"f_elite.js"}, + {"name":"f_lato","url":"f_lato.js"}, + {"name":"f_latosmall","url":"f_latosmall.js"}, {"name":"pastel.app.js","url":"pastel.app.js"}, {"name":"pastel.img","url":"pastel.icon.js","evaluate":true}, {"name":"pastel.settings.js","url":"pastel.settings.js"} @@ -4067,7 +4165,7 @@ "id": "waveclk", "name": "Wave Clock", "version": "0.02", - "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**", + "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: Works on any Bangle.js 2, but requires firmware 2v11 or later on Bangle.js 1**", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], "type": "clock", @@ -4083,7 +4181,7 @@ "id": "floralclk", "name": "Floral Clock", "version": "0.01", - "description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**", + "description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: Works on any Bangle.js 2 but requires firmware 2v11 or later on Bangle.js 1**", "icon": "app.png", "screenshots": [{"url":"screenshot_floral.png"}], "type": "clock", @@ -4227,7 +4325,7 @@ "name": "Q Alarm and Timer", "shortName": "Q Alarm", "icon": "app.png", - "version": "0.02", + "version": "0.03", "description": "Alarm and timer app with days of week and 'hard' option.", "tags": "tool,alarm,widget", "supports": ["BANGLEJS", "BANGLEJS2"], @@ -4245,11 +4343,18 @@ "id": "emojuino", "name": "Emojuino", "shortName": "Emojuino", - "version": "0.01", + "version": "0.02", "description": "Emojis & Espruino: broadcast Unicode emojis via Bluetooth Low Energy.", "icon": "emojuino.png", + "screenshots": [ + { "url": "screenshot-tx.png" }, + { "url": "screenshot-swipe.png" }, + { "url": "screenshot-welcome.png" } + ], + "type": "app", "tags": "emoji", "supports" : [ "BANGLEJS2" ], + "allow_emulator": true, "readme": "README.md", "storage": [ { "name": "emojuino.app.js", "url": "emojuino.js" }, @@ -4260,8 +4365,8 @@ "id": "cliclockJS2Enhanced", "name": "Commandline-Clock JS2 Enhanced", "shortName": "CLI-Clock JS2", - "version": "0.1", - "description": "Simple CLI-Styled Clock with enhancements. Modes that are hard to use and unneded are removed (BPM, battery info, memory ect) credit to hughbarney for the original code and design", + "version": "0.02", + "description": "Simple CLI-Styled Clock with enhancements. Modes that are hard to use and unneded are removed (BPM, battery info, memory ect) credit to hughbarney for the original code and design. Also added HID media controlls, just swipe on the clock face to controll the media! Gadgetbride support coming soon(hopefully) Thanks to t0m1o1 for media controls!", "icon": "app.png", "screenshots": [{"url":"screengrab.png"}], "type": "clock", @@ -4293,7 +4398,8 @@ "name": "LCARS Clock", "shortName":"LCARS", "icon": "lcars.png", - "version":"0.02", + "version":"0.06", + "readme": "README.md", "supports": ["BANGLEJS2"], "description": "Library Computer Access Retrieval System (LCARS) clock.", "type": "clock", @@ -4309,21 +4415,21 @@ "shortName":"BinWatch", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], - "version":"0.03", + "version":"0.04", "supports": ["BANGLEJS2"], "readme": "README.md", "allow_emulator":true, "description": "Famous binary watch", "tags": "clock", "type": "clock", - "storage": [ + "storage": [ {"name":"binwatch.app.js","url":"app.js"}, + {"name":"binwatch.bg176.img","url":"Background176_center.img"}, + {"name":"binwatch.bg240.img","url":"Background240_center.img"}, {"name":"binwatch.img","url":"app-icon.js","evaluate":true} ] }, - { - "id": "hidmsicswipe", "name": "Bluetooth Music Swipe Controls", "shortName": "Swipe Control", @@ -4336,7 +4442,6 @@ {"name":"hidmsicswipe.app.js","url":"hidmsicswipe.js"}, {"name":"hidmsicswipe.img","url":"hidmsicswipe-icon.js","evaluate":true} ] - }, { "id": "authentiwatch", @@ -4344,7 +4449,7 @@ "shortName": "AuthWatch", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], - "version": "0.01", + "version": "0.03", "description": "Google Authenticator compatible tool.", "tags": "tool", "interface": "interface.html", @@ -4356,7 +4461,219 @@ {"name":"authentiwatch.img","url":"app-icon.js","evaluate":true} ], "data": [{"name":"authentiwatch.json"}] - - + }, + { "id": "schoolCalendar", + "name": "School Calendar", + "shortName":"SCalendar", + "icon": "CalenderLogo.png", + "version": "0.01", + "description": "A simple calendar that you can see your upcoming events that you create in the customizer. Keep in note that your events reapeat weekly.(Beta)", + "tags": "tool", + "readme":"README.md", + "custom":"custom.html", + "supports": ["BANGLEJS"], + "screenshots": [{"url":"screenshot_basic.png"},{"url":"screenshot_info.png"}], + "storage": [ + {"name":"schoolCalendar.app.js"}, + {"name":"schoolCalendar.img","url":"app-icon.js","evaluate":true} + ], + "data": [ + {"name":"app.json"} + ] + }, + { "id": "timecal", + "name": "TimeCal", + "shortName":"TimeCal", + "icon": "icon.png", + "version":"0.01", + "description": "TimeCal shows the Time along with a 3 week calendar", + "tags": "clock", + "type": "clock", + "supports":["BANGLEJS2"], + "storage": [ + {"name":"timecal.app.js","url":"timecal.app.js"} + ] + }, + { + "id": "a_clock_timer", + "name": "A Clock with Timer", + "version": "0.01", + "description": "A Clock with Timer, Map and Time Zones", + "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + {"name":"a_clock_timer.app.js","url":"app.js"}, + {"name":"a_clock_timer.img","url":"app-icon.js","evaluate":true} + ] + }, + { + "id":"intervalTimer", + "name":"Interval Timer", + "shortName":"Interval Timer", + "icon": "app.png", + "version":"0.01", + "description": "Interval Timer for workouts, HIIT, or whatever else.", + "tags": "timer, interval, hiit, workout", + "readme":"README.md", + "supports":["BANGLEJS2"], + "storage": [ + {"name":"intervalTimer.app.js","url":"app.js"}, + {"name":"intervalTimer.img","url":"app-icon.js","evaluate":true} + ] + }, + { "id": "93dub", + "name": "93 Dub", + "shortName":"93 Dub", + "icon": "93dub.png", + "screenshots": [{"url":"screenshot.png"}], + "version":"0.03", + "description": "Fan recreation of orviwan's 91 Dub app for the Pebble smartwatch. Uses assets from his 91-Dub-v2.0 repo", + "tags": "clock", + "type": "clock", + "supports":["BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + {"name":"93dub.app.js","url":"app.js"}, + {"name":"93dub.img","url":"app-icon.js","evaluate":true} + ] + }, + { "id": "poweroff", + "name": "Poweroff", + "shortName":"Poweroff", + "version":"0.01", + "description": "Simple app to power off your Bangle.js", + "icon": "app.png", + "tags": "poweroff, shutdown", + "supports" : ["BANGLEJS", "BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"poweroff.app.js","url":"app.js"}, + {"name":"poweroff.img","url":"app-icon.js","evaluate":true} + ] +}, +{ + "id": "sensible", + "name": "SensiBLE", + "shortName": "SensiBLE", + "version": "0.02", + "description": "Collect, display and advertise real-time sensor data.", + "icon": "sensible.png", + "type": "app", + "tags": "tool,sensors", + "supports" : [ "BANGLEJS2" ], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + { "name": "sensible.app.js", "url": "sensible.js" }, + { "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true } + ] +}, + { + "id": "widbars", + "name": "Bars Widget", + "version": "0.01", + "description": "Display several measurements as vertical bars.", + "icon": "icon.png", + "screenshots": [{"url":"screenshot.png"}], + "readme": "README.md", + "type": "widget", + "tags": "widget", + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"widbars.wid.js","url":"widget.js"} + ] +}, +{ + "id":"a_speech_timer", + "name":"A Speech Timer", + "icon": "app.png", + "version":"1.00", + "description": "A timer designed to help keeping your speeches and presentations to time.", + "tags": "tool,timer", + "readme":"README.md", + "supports":["BANGLEJS2"], + "storage": [ + {"name":"a_speech_timer.app.js","url":"app.js"}, + {"name":"a_speech_timer.img","url":"app-icon.js","evaluate":true} + ] +}, + { + "id": "sensible", + "name": "SensiBLE", + "shortName": "SensiBLE", + "version": "0.02", + "description": "Collect, display and advertise real-time sensor data.", + "icon": "sensible.png", + "type": "app", + "tags": "tool,sensors", + "supports" : [ "BANGLEJS2" ], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + { "name": "sensible.app.js", "url": "sensible.js" }, + { "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true } + ] + }, + { "id": "mylocation", + "name": "My Location", + "shortName":"My Location", + "icon": "mylocation.png", + "type": "app", + "screenshots": [{"url":"screenshot_1.png"}], + "version":"0.01", + "description": "Sets and stores the lat and long of your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", + "readme": "README.md", + "tags": "tool,utility", + "supports": ["BANGLEJS", "BANGLEJS2"], + "storage": [ + {"name":"mylocation.app.js","url":"mylocation.app.js"}, + {"name":"mylocation.img","url":"mylocation.icon.js","evaluate": true } + ], + "data": [ + {"name":"mylocation.json"} + ] + }, + { + "id": "pebble", + "name": "Pebble Clock", + "shortName": "Pebble", + "version": "0.03", + "description": "A pebble style clock to keep the rebellion going", + "readme": "README.md", + "icon": "pebble.png", + "screenshots": [{"url":"pebble_screenshot.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"pebble.app.js","url":"pebble.app.js"}, + {"name":"pebble.settings.js","url":"pebble.settings.js"}, + {"name":"pebble.img","url":"pebble.icon.js","evaluate":true} + ] + }, + { "id": "pooqroman", + "name": "pooq Roman watch face", + "shortName":"pooq Roman", + "version":"0.0.0", + "description": "A classic watch face with a certain dynamicity. Most amusing in 24h mode. Slide up to show more hands, down for less(!). By design does not support standard widgets, sorry!", + "icon": "app.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "allow_emulator":true, + "readme": "README.md", + "storage": [ + {"name":"pooqroman.app.js","url":"app.js"}, + {"name":"pooqroman.img","url":"app-icon.js","evaluate":true} + ], + "data": [ + {"name":"pooqroman.json"} + ] } ] diff --git a/apps/93dub/93dub.png b/apps/93dub/93dub.png new file mode 100644 index 0000000000000000000000000000000000000000..59950c8959c296dabb9cf98ef9721cba82763012 GIT binary patch literal 650 zcmV;50(Jd~P)EX>4Tx04R~2kiAO7U=)U*RIB38q&P^246X$iJGoSaAXJF4g3&2WQYDTsSyeb*-@o*)?BzGs=+MTZ z9fW1xcijPv@%gGb#Y@*{HP8JSOHo{gs&i!)=0ye8fw(uTa>GitZin8H_(5z(X%>l} z#Jf=%88*9KnoPqVO>@n9oL!uozOsYE38%Q&jF>VZp`xprsdG$^eN~5ofO|?p)r45R znPw_(M5UA*4n;$eu4(Ywsr_8JjHEG_CX>@2HM@dak zSAh-}0002hNkl$iJIG%Fl*5j zDS+@7MS=c1sV?Qg^i@b&5CuviM0ahgE7k9O^tN0Q9;dm__+B9>ceyJHhFdsrx^j@TOI0j9t!}DR= kje2Q0^&!ql94NdZKiy|bRt}#=Pyhe`07*qoM6N<$f{COZCjbBd literal 0 HcmV?d00001 diff --git a/apps/93dub/ChangeLog b/apps/93dub/ChangeLog new file mode 100644 index 000000000..5fbfe4fa3 --- /dev/null +++ b/apps/93dub/ChangeLog @@ -0,0 +1,3 @@ +0.01: Initial version for upload +0.02: DiscoMinotaur's adjustments (removed battery and adjusted spacing) +0.03: Code style cleanup diff --git a/apps/93dub/README.md b/apps/93dub/README.md new file mode 100644 index 000000000..fd24d54d8 --- /dev/null +++ b/apps/93dub/README.md @@ -0,0 +1,11 @@ +# 93 Dub + +![](screenshot.png) + +Uses many portions from Espruino documentation, example watchfaces, and the waveclk app. It also sourced from Jon Barlow's 91 Dub v2.0 source code and resources and adapted for Bangle.js 2's screen. Time, date and the battery display works. It is not pixel perfect to the original. + +Contributors: +Leer10 +Orviwan (original watchface and assets) +Gordon Williams (Bangle.js, watchapps for reference code and documentation) +DiscoMinotaur (adjustments) diff --git a/apps/93dub/app-icon.js b/apps/93dub/app-icon.js new file mode 100644 index 000000000..39d11fd6a --- /dev/null +++ b/apps/93dub/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkBG2XwAgcPC6P/h//AAIDBA4Pwh/w+AGBAgIDBC4oVDAAITBCAIIBAYIBBAgIvHh4YCFgQPBAoIvCCwoAWIQYAQGLgAWI6bQVdQiiDOyAX/C/7+IAIYvSh4RBAYIXLAwJAHC6ZFCF5yn/C7wDBBAJ3EVAKBDC5QLBYAoLFC5nwCgoXlL44vSL653sL4QXBL6DvXC9YCBACIXCZ4YAQFaYAgPAhqCa4SDFLoZpICYIXDQKLyCDIQXVAAKI0AAYA==")) diff --git a/apps/93dub/app.js b/apps/93dub/app.js new file mode 100644 index 000000000..92544304c --- /dev/null +++ b/apps/93dub/app.js @@ -0,0 +1,137 @@ +// get 12 hour status, code from barclock +const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; + +// define background +var imgBg = require("heatshrink").decompress(atob("2GwgJC/AH4A/AH4A/AH4A/AH4A/ACcGAhAV/Cp3gvdug+Gj0AgeABYMBAQMIggVEg/w/9/h/Gn8As3ACpk559zznmseAs0B13nq/Rie+uodCIIUZw9hzFmv+AgcCmco7MRilow1ACpN8gFhwMilFRCoMowgVEIIVhIINhwFg4GiCpfw/dhx/mn4uBCoXRhWktAVFTIVhw9mj8YseDkUnqPEoeuugVEAAlgSgICBACAVC8AUQCQQVSAEsD/4ASeYgA/ACkHNiK5Cj4VR/AVBng+RCQVwCqMOAQPhIKOHgEB44VR8YVBx4VR+eAgOfCqPxwEDCqX5CoKvS/PAgc/YqQVU/gV/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/Cv4V/CsMfCqP4CoOfCqP54EBx4VR+OAgPPCqPzwEA44VR4cAgHhCqMHCoNwAQIAPjwCBngVRvgCBV6XwCoMHCqPAHyIA/AEigEf4IAOkAEDoAPJWAtA+PHv+Al6uPCofAGAgALoHz51/8AVT+IVS+4VPpMR73woH27n/8Eh8+ZmadIqsoyGICofAkMUktJFZAVBzgVBv34YgMhi8RkIVJnGQIIN8/H34FB8kJiIVIkVEyGQkF8/Pj4GBkhBKCoOexEQvHx8fBgMXzMxTJkICoXCVx8AggDGABsD/4AB/AVQAH4APA")); + +// define fonts +// reg number first char 48 28 by 41 +var fontNum = atob("AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//w//j4//A/+P4/8A/4/4AAAAD/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/4AAAAP/wAAAAf/gAAAA//AAAAB/+AAAAD/8AAAAH/wAAAAH/H/gH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wB/4AP/4H/4A//4f/4D//5//4P//h//4//+B//4AAAAAAAAAAAAAAAAAf/+AAAB//4gAAD//jgAAD/+PgABj/4/gAHj/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f88AAfx/8wAAfH/8AAAcf/8AAAR//4AAAH//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA4AAAAAD4AAYAAP4AD8AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAHgAH/H/GH/H8f/gf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAP//AAAAP//AAAAP//AAAAP/8AAAAP/2AAAAP/eAAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAB/7x/4AH/7H/4Af/4f/4B//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wAAAD//wAAAj//gAADj/+AAAPj/5gAA/j/ngAD/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8AA8f8fwAAx/8fAAAH/8cAAAf/8QAAA//8AAAA//8AAAAAAAAAAAAAA//8D//g//8P/+I//8//44//0//j4//Y/+P4/94/4/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/AAPH/H8AAMf/HwAAB//HAAAH//EAAAH//AAAAH//AAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAGAAAAAAOAAAAAAeAAAAAA+AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB+AAAAAD8AAAAAH4AAAAAPwAAAAAfgAAAAA/AAAAAB8AAAAADx/4B/4HH/4H/4Mf/4f/4R//5//4H//h//4f/+B//4AAAAAAAAAAAAAD//wP/+D//w//4j//z//jj//T/+Pj/9j/4/j/3j/j/gAfgAP/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/AA/AAf8f+8f8fx/+x/8fH/+H/8cf/+f/8R//4f/8H//gf/8AAAAAAAAAAAAAA//8AAAA//8AAAI//8AAA4//0AAD4//YAAP4/94AA/4AH4AD/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/4APwAP/wAfgAf/gA/AA//AB+AB/+AD8AD/8AH4AH/wAPwAH/H/vH/H8f/sf/Hx//h//HH//n//Ef/+H//B//4H//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); +// tiny font for percentage first char 48 6 by 8 +var fontTiny = atob("AH6BgYF+ACFB/wEBAGGDhYlxAEKBkZFuAAx0hP8EAPqRkZGOAH6RkZFOAICHmKDAAG6RkZFuAHKJiYl+AAAAAAAAAAAAAAAA"); +// date font first char 48 12 by 15 +var fontDate = atob("AAAAAfv149wAeADwAeADwAeADvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAPHn9/AAAAAAP0A9wweGDwweGDwweGDvAL8AAAAAAAAAAAgwOGDwweGDwweGDvHp98AAAAA/gB6AAwAGAAwAGAAwAGAPHj9/AAAAAfgF6BwweGDwweGDwweGDgHoB+AAAAAfv169wweGDwweGDwweGDgHoB+AAAAAAAAAAgAGAAwAGAAwAGAAvHh9/AAAAAfv169wweGDwweGDwweGDvHr9+AAAAAfgF6BwweGDwweGDwweGDvHr9+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + +// define days of the week images +var imgMon = E.toArrayBuffer(atob("Ig8BgHwfD5AvB8HD8z8wMPzPzMQzM/M/DMz8z8c7f7f7z////3Oz+3+PzPzPw/M/M/D8z8z8PzPzPw/vB8/n/8H3/A==")); +var imgTue = E.toArrayBuffer(atob("Ig8BwDv9wDAOfmgf/5+Z///n5n/5+fmf/n5+Z//fv9oH////Af37/b/+fn5n/5+fmf/n5+Z/+fn5n/5/g+gfn+D8AA==")); +var imgWed = E.toArrayBuffer(atob("Ig8Bf7gHgM/NA9Az8z/z8PzP/Pw/M/8/D8z/z8c7QPf7z+A//3O3/3+MzP/PwzM/8/D8z/z8PzP/PxAtA9A4B4B4DA==")); +var imgThu = E.toArrayBuffer(atob("Ig8BgHf7f6Ac/M/P/z8z8//PzPzz8/M/PPz8z8+/QLf7/+A///v3+3+8/PzPzz8/M/PPz8z88/PzPzz8/vB/P3/8HA==")); +var imgFri = E.toArrayBuffer(atob("Ig8B/wDwP7+geg/P5/5+c/n/n5z+f+fnP5/5+c/oHoF7/AfAf/7/7/+/n/k/z+f+R/P5/5j8/n/nHz+/++PP7//8+A==")); +var imgSat = E.toArrayBuffer(atob("Ig8B4DwDwDgOgXAJ/5+f/n/n5/+f+fn55/5+fnoHoF/fAfAf//+b/f3/5n5+f/mfn5/+Z+fn//n5+eAef358B7//nA==")); +var imgSun = E.toArrayBuffer(atob("Ig8BwHf7D7Ac/MHD/z8wMP/PzMQ/8/M/D/z8z8QPf7f6A/////83+3+/zPzPz/M/M/P8z8z8//PzPwA/B8/oD8H3/A==")); + + + +// define icons +var imgSep = E.toArrayBuffer(atob("BhsBAAAAAA///////////////AAAAAAA")); +var imgPercent = E.toArrayBuffer(atob("BwcBuq7ffbqugA==")); +var img24hr = E.toArrayBuffer(atob("EwgBj7vO53na73tcDtu9uDev7vA93g==")); +var imgPM = E.toArrayBuffer(atob("EwgB+HOfdnPu1X3ar4dV9+q+/bfftg==")); + +//vars +var separator = true; +var is24hr = !is12Hour; +var leadingZero = true; + +//the following 2 sections are used from waveclk to schedule minutely updates +// timeout used to update every minute +var drawTimeout; + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function drawBackground() { + g.setBgColor(0,0,0); + g.setColor(1,1,1); + g.clear(); + g.drawImage(imgBg,0,0); + g.reset(); +} + +function draw(){ + drawBackground(); + var date = new Date(); + var h = date.getHours(), m = date.getMinutes(); + var d = date.getDate(), w = date.getDay(); + g.reset(); + g.setBgColor(0,0,0); + g.setColor(1,1,1); + + //draw 24 hr indicator and 12 hr specific behavior + if (is24hr){ + g.drawImage(img24hr,32, 65); + if (leadingZero){ + h = ("0"+h).substr(-2); + } + } else if (h > 12) { + g.drawImage(imgPM,40, 70); + h = h - 12; + if (leadingZero){ + h = ("0"+h).substr(-2); + } else { + h = " " + h; + } + } + + //draw separator + if (separator){ + g.drawImage(imgSep, 85,98);} + + //draw day of week + var imgW = null; + if (w == 0) {imgW = imgSun;} + if (w == 1) {imgW = imgMon;} + if (w == 2) {imgW = imgTue;} + if (w == 3) {imgW = imgWed;} + if (w == 4) {imgW = imgThr;} + if (w == 5) {imgW = imgFri;} + if (w == 6) {imgW = imgSat;} + g.drawImage(imgW, 85, 63); + + + // draw nums + // draw time + g.setColor(0,0,0); + g.setBgColor(1,1,1); + g.setFontCustom(fontNum, 48, 28, 41); + if (h<10) { + if (leadingZero) { + h = ("0"+h).substr(-2); + } else { + h = " " + h; + } + } + g.drawString(h, 25, 90, true); + g.drawString(("0"+m).substr(-2), 92, 90, true); + // draw date + g.setFontCustom(fontDate, 48, 12, 15); + g.drawString(("0"+d).substr(-2), 123,63, true); + + // widget redraw + Bangle.drawWidgets(); + queueDraw(); +} + + +draw(); + +//the following section is also from waveclk +Bangle.on('lcdPower',on=>{ + if (on) { + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); + +Bangle.setUI("clock"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); diff --git a/apps/93dub/screenshot.png b/apps/93dub/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..197c52c018739e13eb44b17b4273cc21d7e1d9f3 GIT binary patch literal 3297 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 + if (t == 1) { + Bangle.buzz(30); + if (timervalue < 5*60) { timervalue = 1 ; } + else { timervalue -= 5*60; } + } + else if (t == 2) { + Bangle.buzz(30); + if (!istimeron) { + istimeron = true; + timertick = setInterval(countDown, 1000); + } + timervalue += 60*10; + } +}); + +function timeToString(duration) { + var hrs = ~~(duration / 3600); + var mins = ~~((duration % 3600) / 60); + var secs = ~~duration % 60; + var ret = ""; + if (hrs > 0) { + ret += "" + hrs + ":" + (mins < 10 ? "0" : ""); + } + ret += "" + mins + ":" + (secs < 10 ? "0" : ""); + ret += "" + secs; + return ret; +} + +function countDown() { + timervalue--; + + g.reset().clearRect(0, 76, 44+44, g.getHeight()/2+6); + + g.setFontAlign(0, -1, 0); + g.setFont("6x8").drawString("Timer", 44, g.getHeight()/2-20); + g.setFont("Michroma16").drawString(timeToString(timervalue), 44, g.getHeight()/2-10); + + if (timervalue <= 0) { + istimeron = false; + clearInterval(timertick); + + Bangle.buzz().then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 500)); + }).then(()=>{ + return Bangle.buzz(1000); + }); + } + else + if ((timervalue <= 30) && (timervalue % 10 == 0)) { Bangle.buzz(); } +} + +function showWelcomeMessage() { + g.reset().clearRect(0, 76, 44+44, g.getHeight()/2+6); + g.setFontAlign(0, 0).setFont("6x8"); + g.drawString("Touch right to", 44, 80); + g.drawString("start timer", 44, 88); + setTimeout(function(){ g.reset().clearRect(0, 76, 44+44, g.getHeight()/2+6); }, 8000); +} + +// time +var drawTimeout; + +function getGmt() { + var d = new Date(); + var gmt = new Date(d.getTime() + d.getTimezoneOffset() * 60 * 1000); + return gmt; +} + +function getTimeFromTimezone(offset) { + return new Date(getGmt().getTime() + offset * 60 * 60 * 1000); +} + +function queueNextDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function draw() { + g.reset().clearRect(0,24,g.getWidth(),g.getHeight()-IMAGEHEIGHT); + g.drawImage(getImg(),0,g.getHeight()-IMAGEHEIGHT); + + var x_sun = 176 - (getGmt().getHours() / 24 * 176 + 4); + g.setColor('#ff0').drawLine(x_sun, g.getHeight()-IMAGEHEIGHT, x_sun, g.getHeight()); + g.reset(); + + var locale = require("locale"); + + var date = new Date(); + g.setFontAlign(0,0); + g.setFont("Michroma36").drawString(locale.time(date,1), g.getWidth()/2, 46); + g.setFont("6x8"); + g.drawString(locale.date(new Date(),1), 125, 68); + g.drawString("PAR "+locale.time(getTimeFromTimezone(1),1), 125, 80); + g.drawString("TYO "+locale.time(getTimeFromTimezone(9),1), 125, 88); + + queueNextDraw(); +} + +// init +g.setTheme({bg:"#fff",fg:"#000",dark:false}).clear(); +draw(); +Bangle.setUI("clock"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +showWelcomeMessage(); diff --git a/apps/a_clock_timer/app.png b/apps/a_clock_timer/app.png new file mode 100644 index 0000000000000000000000000000000000000000..b91bc3f185f3a43476a7b72aec64607cd80a11a9 GIT binary patch literal 3751 zcmaJ^2Ut_t629~fN`eIiLg)&Fgs2b#8ahY`MP86*3_*gB#3V>iEc6ZnQe^1}Sh1p@ z1Vlg(6qO<>C{?fk(wl{MgYN3?bKgzQJ#){@|DTyTGxtkk@pcvxqOzg@07zI_nmU5B z4tEIig7+8us87L(hv{fx43xKReh)r0kO@{kwzj|)P!cj40=28zP&pHREf|n zU6}wN26`k0;Q_L9HUI!$ImMa4BG}qsNVEWLqBm_nS(_a|=Q06UHU<;}$Sfj^9pF!8 zV%Uc8RSOI#bC(ft*s2NZpdp-Ki-(!e7-ZOXZ5?eLxREFf2E#JEeK3xu=0D)zlOf!f z#iC;nh@hY#?I2xk8sh*0sjsh(&_N+kC@s)Jiy2I15!qT)rqXwkKY2{aOcH}aXHjTW z7?+p0pBBh6gu}TT{dIl!lST3Qxf7N7BP=jL1XqJVYU?0=2P3m7{{rJ`{uKu1=&!K; zwi%m9{|;JB#&;jFTn{j=j$|gyKad-X(GHXjcp;G7J9gE?3|IlC6|AhWT z?x9jxMyMaV{bTu`D0>El44%lUugD*eU)O%I=cWm>TFS1blmIf7$&C-KheiBW@mnC_ z-+;d;egT5H$Jm0E=uKo1O^GbB5x4xckVq|*o-6GhBJ-kZ}h)C{oRLE^beaKa4dpb(Z5vq_x4#`1^dTH6h!{ni$Fh&&t9TYjp4@^KXU=z04@yhgQ(l zYe$Bfk`H#5zpgoU*X-)6ii1*e7&Ht9gppe_a`l-b<2|=kZ6ifxqQo~kmb>el-J*1u z6UCm^o>)0|PF*bZefGA4w*q=xO03hZ(o~UwqG)Pw<dn^3zD5|KC2ku7- zNp99VGOOMWbN%@I^2g5e#ryz7)#k=3>~h1x!sb8q(WVz71j?RY za@952HDvGWd+rhNf^^CIq(AiCm03ldJG1mnfghi9n4?Jy_R=(Y?nBp;Jj0`3m*+CH z+_uQyqoBH$+HwtchAaXj_anu|M%}6yZ+QhoH9hV)&kM^FT!sb*Cv{8xhvPFRZLO_e z-8dk1Qj*nsS2N9kq4HQwQo$A7GqJ&}zG^h<%8oz~>rm3DQ=c?3+#V7qvOg$kdb zID2tYk-sTfVZ9$(lRw1l$!%KStrzzX$Audwduh8~KZ`Fk4i}Qz{xBkaA9itQbX3SJ z-{=@@ZhCrf3>!Qh69c#SJU{NmIa1-*wdKT#mFnOb(e~<`tm6HRaRUPb7ifxUpBiEz z$Tfvd=N(nDq9Y@TdsNs{g9189p&B`=yKQaBVHY-9D+6%GqfCUC@V(i zDjk8$sY-o|P^36!U+wZ%*KKtng@wZ5@QJ=!npLb|Y<+4@|KXtr5{&ch(5)_)aN&ZD z@$3JSAb^h#4_ZD&UaHN-%;2>pC#?MxyRG1`*4A+xLsVa2h5UYI^vTncp#XuA7(w0RQuVi@LK0JQj_xIJWQY{0zA9zp6YYTs;VQ;iY*#B7TvXx^SW4F7QZdgJ&Le zbfn!_u~g{1D{pv&&TLQt6pfB8vp7fQA_}{rCoQVkeKp6xj!;p6H-P?eI2?SF`Qlb8%7%--?yO z+3uiEZ@_A_H4t(cFy1aDB7)15!?0o!5^k!;UN>v64g9!neh_OTW$xSGBJClO0hc-P zby+5VW@;)ls#gpBhEGTmJVFHsHi{*`X;Zv|KBK$bBgS~yYWHqPnUa`p9yS;iJnj8% zz_R7gdf}CG4#k4EO5qg;yX|)Kzt8ieft~4Zit42-O~2iIXtKY~JW)0l9m3K3^kr#= zZR9S@BO1x_V+mKT?eXP}g~rL9k!V?-`^eP7X5QJ|u$|Iw8mzIak$iQ1?eUdwoEtE` z&8%Qx%&bC0L?lbPw)E!O9eXai%+1ZEkH0x5L{p1V�@bixAPV)Q;e6KqsOr7y03B zXLJv|sSb9BdS+Dy^xWDK!TYu~b7l5Dq??5J;Ee5(ZF+H?+&Vc>k5un2mQE`H-y~*$ zpVq=I$CoDF47CJaB~cVPy-wPN1XH+ZncyN!BET|SC+GG7Ief(@R=(vP=c~683U$1u z6q%F3gHUBS$TMJ^&B~jx>i#Y9=y07vDJ35IYmii2gXWF=}dc$ zdliGcF!9?Bxccn9``{+Bi4?Sx>&=P@wltVK% z>iQIT-%(*i2S2jk_qfwIe7C8Eh2olry7frSKk^NaM)4gIXBPo9Sa5U4{nH{@C~=7* zF`=_+yG0UW_+KHcH!3K69?gHyV?ubBIcW~788&P&awt9TB5=Q5PqS>$Bz~RN-YSMl z4^qK{Iog&R`p~`si_+*B12CszVoo(T)5+BFXiKRG!I#O)#(V2MCmsEGo@!0hQaV%} z9}Lt-m)YmrZI4bJ6p)tngLgMiinRKW;?B_PA|e{@-P4I9J&3zImi6!jna>fnO`bw6 zurL${f~Y&2`g7~*Y6=UFmy^zwj@5nfhHWh0W*~e5UiMPn#1gD7r^;tLkrgUV%2xUK zxrLy~C)?E9@RvL}*?MLBE7y&|S{gY=7fu%&>=M|cT(wpn>J#e{l7q266nV0sP$4cU zDe7KRQ;I90Be_AbIaK#Rn{p<;eY}A_z<>&?y`^pro*uTMA`F%Wgv1lqcW8UuS);9& zGk*!2-r?0+?u3Hn+0BaE48Lyc=IqCd+2`mLVwxpS<>$@v@0C>#Y{AV!3FbO^d6M5= zO2uuZno1CNdIg^+SQ6D3c=UBhbBI~<;qo#m{_BD@niIJAx=nrT5jQ)gUiJ^djeamnuUTH$rXAFXsHEtG962Prt+a7u z!0e)xRLm}@$mBUSHwm29!boV!(8av!lQiq8rP$4PI&V^(md*2u!(4Au`cpz_l5lzQtS}8 literal 0 HcmV?d00001 diff --git a/apps/a_clock_timer/screenshot.png b/apps/a_clock_timer/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..4fb3dd9f2f572b1d7bc2423fa31032b762e0585e GIT binary patch literal 4174 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 0) { + ret += "" + hrs + ":" + (mins < 10 ? "0" : ""); + } + ret += "" + mins + ":" + (secs < 10 ? "0" : ""); + ret += "" + secs; + return ret; +} + +var newtimer_left_from = 60; +var newtimer_left_to = 2*60; + +var newtimer_right_from = 5*60; +var newtimer_right_to = 7*60; + +var current_from = 5*60; +var current_mid = 6*60; +var current_to = 7*60; +var current_value = 0; + +var timerinterval; +var istimeron = false; + +var islocked = false; + +function countDown() { + current_value++; + draw(); + + if (current_value == current_from) { + Bangle.buzz(500); + } else if (current_value == current_mid) { + Bangle.buzz(400).then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 800)); + }).then(()=>{ + return Bangle.buzz(500); + }); + } else if (current_value == current_to) { + Bangle.buzz(300).then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 600)); + }).then(()=>{ + Bangle.buzz(300).then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 600)); + }).then(()=>{ + return Bangle.buzz(500); + }); + }); + } + +} + +Bangle.on('touch',(touchside, touchdata)=>{ + if (!islocked && istimeron && touchdata.y > (100+10)) { + Bangle.buzz(40); + istimeron = false; + clearInterval(timerinterval); + } else if (touchdata.y > 24 && touchdata.y < (100-10)) { + Bangle.buzz(40); + islocked = !islocked; + } else if (!islocked && touchdata.y > (100+10) && touchdata.x > 88 + 10) { + Bangle.buzz(40); + current_from = newtimer_right_from; + current_to = newtimer_right_to; + current_mid = (current_from + current_to) / 2; + current_value = 0; + if (timerinterval) clearInterval(timerinterval); + timerinterval = setInterval(countDown, 1000); + istimeron = true; + } else if (!islocked && touchdata.y > (100+10) && touchdata.x < 88 - 10) { + Bangle.buzz(40); + current_from = newtimer_left_from; + current_to = newtimer_left_to; + current_mid = (current_from + current_to) / 2; + current_value = 0; + if (timerinterval) clearInterval(timerinterval); + timerinterval = setInterval(countDown, 1000); + istimeron = true; + } + showInstructions = false; + draw(); +}); + +Bangle.on('swipe',(swiperight, swipedown)=>{ + console.log(swiperight); + console.log(swipedown); + + if (swiperight == -1) { + if (newtimer_left_from >= 60) { + newtimer_left_from += 60; + newtimer_left_to += 60; + } else { // special case for 0:30 to 1:00 + newtimer_left_from = 60; + newtimer_left_to = 120; + } + newtimer_right_from += 60; + newtimer_right_to += 60; + draw(); + } else if (swiperight == 1) { + if (newtimer_left_from > 60) { + newtimer_left_from -= 60; + newtimer_left_to -= 60; + } else { // special case for 0:30 to 1:00 + newtimer_left_from = 30; + newtimer_left_to = 60; + } + + if (newtimer_right_from > 120) { + newtimer_right_from -= 60; + newtimer_right_to -= 60; + } + draw(); + } +}); + +var drawTimeout; +var showInstructions = true; + +function draw() { + g.reset(); + if (current_value >= current_to) { g.setBgColor("#F00"); } + else if (current_value >= current_mid) { g.setBgColor("#FF0"); } + else if (current_value >= current_from) { g.setBgColor("#8F8"); } + g.clearRect(0,24,176,176); + + g.reset(); + g.setFontAlign(0, 0); + + g.setFont("Michroma36").drawString(timeToString(current_value), 88, 62); + + g.setFont("HaxorNarrow7x17"); + g.drawString(timeToString(current_from), 44, 62+26); + g.drawString(timeToString(current_mid), 88, 62+26); + g.drawString(timeToString(current_to), 132, 62+26); + + if (current_value >= current_from) { g.drawRect(44-1,62+26+9,44+1,62+26+9+1); } + if (current_value >= current_mid) { g.drawRect(88-1,62+26+9,88+1,62+26+9+1); } + if (current_value >= current_to) { g.drawRect(132-1,62+26+9,132+1,62+26+9+1); } + + if (showInstructions) { + g.setFont("6x8").drawString("Tapping timer locks buttons", 88, 100+5); + g.setFont("6x8").drawString("<= Swipe to change time =>", 88, 168); + } + + g.setColor(islocked ? "#444" : "#000"); + g.setFont("Michroma16"); + g.drawString(timeToString(newtimer_left_from), 44, 138-9); + g.drawString(timeToString(newtimer_left_to), 44, 138+9); + g.drawString(timeToString(newtimer_right_from), 132, 138-9); + g.drawString(timeToString(newtimer_right_to), 132, 138+9); + + g.drawRect(0+8,138-24, 88-9+1, 138+22+1); + g.drawRect(0+8,138-24, 88-9, 138+22); + g.drawRect(88+8,138-24, 176-10+1, 138+22+1); + g.drawRect(88+8,138-24, 176-10, 138+22); +} + +require("FontHaxorNarrow7x17").add(Graphics); +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +draw(); diff --git a/apps/a_speech_timer/app.png b/apps/a_speech_timer/app.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb777fa7988b5d0a44e31d7238925f0ca47027a GIT binary patch literal 3036 zcmaJ@3p`Z$7r!HUj7_!?B{4>i$zz^u&6t_Q$XoJCMH*&gm7T#^Y#jC4Ec1rSneYmM!f8k4B7!W3=T`g;)ob59BV=ZWegs`71mpW zD&=6Cy*vO=0XH2|=zlRJNH2(<$bM!H+ ze;g*D1uuZ+ld<3E051S(=FRrM#EQWHUHCS$rnjNa!yrz6kXE zFW?fz5+Im+q9a&|bQ+&VrSTaQS@|1damE;|8(97(cp}Es5JMo!Qu{C4&v-0D86d+K zSmv8(Da#VeFL7`~-MCy9<=;KM;KMw6(Pj}&Ldz<8Nrf-8&-^afKNKj4{JR$^(23~i zJ^)adwx#ZH^HjcdR%o+lzgnYYD!(Q1uAQq?6ESlhF}fq!qhPi4bsWnFSrnj`506*+ zdQ?>81vNOTu7ZQ+2Z)e{2Kxf=sT!w~>?Bj+;}bzo%x>4c?~Q1?MG;JkM&_P3pPeA% zdH&D6*1aDb-C|_K8hEz1%s+K&RGNz;siY&|&kygrud_$GE5>W0X1xaRc>GEo(i$Bd z)n|z3lmX@TWKDD~Nr>YQwLhy%xLGvPbA#vZ-dUHh(wm-QnG57GYGWWOnkfFBts#B& z7k8bjy1&M{E_D?G6VNWcV4qc`vU%gijhi;fwp(Iy$q^oV_cGlI3IxRVHky$@psxTRdE~h>`Z{(6U104+r9Bn$P0T?@V=(rtq0lZ^;fx(Itn|4G+>k%)R41zRD{|5NaB%~Lw>w$Qt!dRL9I5}S`y>w?Qahq_sNRbS1)o_Yw!Cd z`D|CgiSsR|r2UN|kq&uA^mL`w^vI)2fkU@pv4dAye((Iz-rk;Ed{gkMZ*t_(_NbYM z)k2=?!$y&=9;wwdX}J;A;R^7g2bo$c(%t@H?tM9@H@x`_);`mS*;#zrVQ%gno_QyE zmFC(X){@vqxX}?lr@}`_h419UUF%85y>@399R*HBk}q zA~}0SKbvQ2`HcISm6q5mzD`c6zs%L2fWbC7Y>Rx0dHnk2fnz;4#2c#p zTXU58rVqCMY)2iuOslI38&~ZGQ~6{d59M8De%JC8OIp4KfrwK*?M{n+_j+*PUd8}< zXnOqVAv&FEZCwT-_PSnlQa+dWs=slz#WEIR{)@uB}_@7b(;2x8vredha zJe7jC+4mH?NlbbDdYiYTsr}}knPhBgQ2cP0=A9KM9gezN?s^ zEf>_9L#T9r1hX@fvv9N9q~iROs`j?uI7fDh)|>5==4}7AX3Xb#6VpoX!tqjL^`osJ z^7V2BX4Eb2;G5ZK=wjmaRod!%=fFO)x3Ov0tbOFGLqimbj(4QRbX{PTTP16-g6^Kw zGxR7y8W=!FqhngFVxF9(UpYMD5heW9QYY=DG5?)&nm#;pcWlp3`zy{{iy9gl`qIE} zOmAg~rLnoXRzzXj~B%aEQKeqLAH00wSCC`!wh8i%#MVt_U|M>}vK{Q@Gu{N<&}W+cQ9m7-o`4 zsLFJ(p_8KLwz*x>R8`@Pf!xQ=f0xx3SlM;2%WH^)AmVN_YFmR#N%*#S32VjC~%Lglw6 z#l^)r{Xks1QpxqLw(IWQu>NpWGqqmnqH+6nH*gYU# yJ4%fcGfsA|u23h2XeHGe^>e7deLFk-@M$Mu_WQQ7zPGYpR9h=2YN^G+xW54KKFVwW literal 0 HcmV?d00001 diff --git a/apps/a_speech_timer/screenshot0.png b/apps/a_speech_timer/screenshot0.png new file mode 100644 index 0000000000000000000000000000000000000000..ee3ababc1abf849d688e97c5ceb8d3ae8180f05c GIT binary patch literal 3276 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 literal 0 HcmV?d00001 diff --git a/apps/a_speech_timer/screenshot1.png b/apps/a_speech_timer/screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..69ea91e95332e8b97e6de3205f72319215bd6195 GIT binary patch literal 3457 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 literal 0 HcmV?d00001 diff --git a/apps/a_speech_timer/screenshot3.png b/apps/a_speech_timer/screenshot3.png new file mode 100644 index 0000000000000000000000000000000000000000..7b67b6f0156354dc839f5194e1a1fbc1c54ed9a1 GIT binary patch literal 3374 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 bvNGFCP4eAd222Y+K)?liN4u7DzS;i;FilcV literal 0 HcmV?d00001 diff --git a/apps/about/ChangeLog b/apps/about/ChangeLog index 03e920a9a..f5638fdd2 100644 --- a/apps/about/ChangeLog +++ b/apps/about/ChangeLog @@ -9,3 +9,4 @@ 0.09: Actual Bangle.js 1 pixels as of 13 Oct 2021 0.10: Added separate Bangle.js 2 file with Bangle.js 2 kickstarter pixels (as of 28 Oct 2021) 0.11: Bangle.js2: New pixels, btn1 to exit +0.12: Actual pixels as of 29th Nov 2021 diff --git a/apps/about/app-bangle2.js b/apps/about/app-bangle2.js index 32e5bafae..978d36193 100644 --- a/apps/about/app-bangle2.js +++ b/apps/about/app-bangle2.js @@ -6,7 +6,7 @@ var ENV = process.env; var MEM = process.memory(); var s = require("Storage"); -var img = atob("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"); +var img = atob("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n/2wAAABBCQAEGEmBJFoAABIoooxwgPoAddoCEkFFFAEwwAGwAHJIIJBAAAG2AjDAG/n+AABBBBAggXi3/xI13/////4AAABICQDEk0mBAFqABIHCSH2wkgw4FDCCHnAooAoGAAAAAwFttGAAAAGGAkkkkn/ttrADAAAAAX6nPhStv////+mmbYBBCQZY2AGAAACABIoqSookEAAADFCSEnbbbAFigAAAMEAFA2wAAA/q6gEkAA4AAFBBEAkgEHghJiR13////880cYBAIDLLAAAAAkCABAHCSHCAkBBHAJKCDbFArAAEEgkIMkAFAGAAAAvq6DE8AYGPOFAAEAggEUiOOIJbf////+mmbYAAABZZA2wEggiQQQAowoAQCBIHBICIDAFFYA2GEEENMEAFAGAQQYtqSw0kDDAHAFCCEYggcHgJxIAfb////840BJA9FALIAAAggkACCkEnAHACopB/JJJJDbFrDSww0AEAIwAFAkgSTZJmBwwgjbGIOFBJEYkgcAAH/BpbbAAADAAmIQHFoABHMkkEAggAAgkgggEgEDbG222PvvFdCAwwwBJJIAAAAAAQQZBgB2wgjbAAAADAAbADYAUg4FFkjAAHDgE0IQA9FAABMkgAAgEAAkEEABJJJDr2GG2PvvFAoSDADBJJAAGWAAAoABJgBwwAAAAAARP8gYYYYAWg4FIijbDDbkEmQSQAAAAEkkgAAAAgAAAAggAAgjb2222PvvbDbADYbBJJAACiAAAooBhk5YDH/CACCBP8gbADYAUg4BFkjDADDgk0gQQkgAAGAAAGABJg2AAHEHAAEAF2AA1PvvDbAYDDDYBAYAGWAAAoEkA/ADY//6CCARP8gSQAAAbbYAAtrADDDwAmgSQAkkkAYDAFGSIkGAAASkkAggA+228N//AYDDDAAbBAYAbYAAAov/gA/DY446HCCAJJFQFAEkAYAMgSrDDDDSQMEkB4AAwGADAouWIIGAAAW0kA44AFotBJASbaQYDAAGxYYYYYAAos//8HAYD446A6AQABFQFAEAgbYIESrDDAbQBIoQYEgGAAYAYFCWJBwAAASkkAIIkQDAADbabaAA2AAABbbYbYgAtt778AAAA//6/6CAABFQFAEAgYYIEtobAAgSIIGABAAAAGADDDH/JBAAAA4A4ABAigFAASTiaahABgdoBAAAAFtAAAn/gAAtoH/CQSAQIBFSVAEkAbJMgJIBJEgRAIqSA4gAAAYDYYfnAAAHHAAH/AIIkQBQAATjTThABgYqBAAA2ttoAAd8YJAAoA+2SWywBIFtFtEAgYYAA54BAggAAECABkgAAGADADH/AAAHHAAAAAAAigoDAATcccZhhgdqCH/AwssoAAbzYIAFAAGACGAQ4w4w4w4w4bYAAJIBBkkAAACSP/4AAAYAdvQQAAAAAGAAAA/AH+AEAATbjjYgggaCSJJA2ttoAAYYYIAAAA+GAGAwbbgEJMMAAAAAA2wBJAgAg5//J/4AAGAAF/CAAAAGWWWWLI/GH4AoAQQbbbAEAkiSA//AwllgAAYRYJAA3AH2AAGwbbAAG2wAG2wAAOIAAAAEEPJJJP8kkAEUlvCJIAAAwwwwLIAGJJGAACJASQYAAAACAIAA2EkAAAaIYBAA/AHFAAAADAAAwAG2wnOAAEAAAAX4E5/JJJ8nkFEigAC/4AAAwxwwLIAGJB4AAAIIAQb7AwASQYAAAgAkgARIEBAAA/4AAAAHHHEn8gA2AIgAAggAQAH4gAAAJJM/8tEkSAAtqSJAGAGAAAgAIhIEAAIOCG4GAAGFzbYuAgAgACIBtJAAA44EAA5IggEn8gGAwgIM3EACQAAEkAAbe20nkFEAQQ1wAQIIwxwwkgkkkACYAAIIQAYAwwwAQYGAIgAkgRABoAAAAAomgoxgkgEn8gADY5hg+EAAAFtAAH4YGSkkkAICCCGuCQIIAAAAoA222AAAAAJASQ4AG2AAozAGAgAAgIJItAAAAAAECA8gEAAAAAAoFQDPcggAQFFAQAADEkkngBxAQQA1wAJA23gJFAkkkAFwQAQAGAD7AwAQUEAoAkgkgFEkoGDtoooAWSACAQAAAAAHAQYAxggGwFtDbbAAYAE//AIACAAAAAJIOk/JAoAAgAHIUkQAAABJAAAGEgGMIAAAArsJtwztFFFFSSQSQQAkQ/9AoEAGGVQk1AAFroAbYAEngBxFtAA/HABBG4kISQ4EAAAAQQQCCFFotAFFsEtAAAAAFdEMAwDdoooAQSCCCQAmgJIbAkkG2qoG2wADrtoqSJEACAIFkoAAHABGOE4IAAAkkAAAiSgCCAIAIAAAAAAAAH//FoFFAGbbYAAAACACAQAUgSQSX4AGGqsE2ASDbvooABEATQbdkoI/HQAAACQAkkgAAAAAkEgAAFJANGG2GAYAAYHAQQFFAAwZJAAEgkBIAA444QQQX6SSSVUkxwXUgttqSBEAQQYdtBI/AAAAAQCw/X4w84AAgggAQFIINGGAGADADknAEAYAYwwZAH/EEEIAAABJASQSABAiBqsE2ISU8oooBBECACbdAOxICSAAAWyA6S4AigAAgAgAQFIBNGAGGADDD2nGEGD7AGAZBHPEEEIAAAAgAQAQQBkEBVUExwQUgooqSJMgFAYFFhJJSSQAAQCAkkgA84AAgAgCCFIAN2G2GwAYY03A2wXAH/6ZJH/EAEBIAAHHAQASABgkB"); var imgHeight = g.imageMetrics(img).height; var imgScroll = Math.floor(Math.random()*imgHeight); diff --git a/apps/about/bangle1-about-screenshot.png b/apps/about/bangle1-about-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..092f93dae470d0fa00488b9fec727eec5c9241a8 GIT binary patch literal 14911 zcmc(Gb*pBktGed&^h|%4bAEl!7p+$?d|YZ=004lmqO73v)E@tLVq-pCrQhtv zJ~coO9he-TY?yWz0AK{DD7@75F*`7YCeqfAJ7-!}@X0(omiqwc0)s$kAUu2scgqUK zKO9U7lLi!Ol#%hj1BK#yy2}+Ya^kQ0S10l3p4y^R^NT%di=(ebobi8)c;o+!ShZ#J=x^&vZv=&rbO?knM9-vDiEJ!<3M(QsDckQ*p+4@O`>Pefua z8x{$Q1Fa9qwIvI>4yWK%(Ij9&yvB@0(;q~lACvQ%#b(ed0}Ak1u*#C2uv}&>EK*N{ zy`oYkFyVi~>bLl)__;Fz(*&L#ZSjOH_c@6@-;f1~zGD<~?RmnQpRBR&_B~CcU-th! z5sGK`=bL|ontg*N?(y3vj!N3?%&+lWqSMdZR{f<3>hc0lj!MK-&t-41)2SDUGt6{S z(T`b6d#P-xfb8T!1X|!i6Ark{_*Fpo%n|#K8ehZZ9Fms^*p5V3EbZJo(6yGAnVC%j zMgpp<{R{x9L_xH6&QcWP8>ru~=bSaRkk@di0?g;b@yDBgvF0a)gOE*)+Kk%MbMCXX zUMZWGZPR3t%J%1y)o2 zW$-zPni%3YWqFXV(EY>hQA~cG21s=9=bmF>pv_7%~ju?Cmi{<961g}#dPiV&^+RslbN4x!|PMyGn7OM_K z`COo?H6C)kmLQGehx_!oWkTN!iUoY9ooNcqWj*G8o{#bHT#=hC@YU1WjPxz;ONhBz z6SVk0I)~gZlxBWK*1Pj$su9qlkWweScrrSJF+Ar$aDpid7CY7@$cKeA@C0yauh+U< zu2_@NFIg74yq)dgawn1U+t2I9{YI7T#aeJ?1dd6nqGt7e7Hm8vu{T2M>~<;xgE8_C z8AA_)O4N_0zgJi71)cq7AdLcBhrGMl5r(D_Ehqgk>9 z^9HJCj52?M4}f3M6g^%F4M3cZdOp#oQ_G63*BPw*u58vu_#M;(42%PQo@7#gX23+QNJwJ}W>< zs0v85jR`gYVb_LMDnq5r2e8m8CY_u|C?-)Z`yj|$_J+5~v5N1)GsaPVELGmX&Dd9j&Zj)RLRbz*($p&HG3t zl-lN((;4*R9buewWwHvB(bjF2dO6F6O*-Xu<&03wZg$ySQDcZ>v8&b%w`(@J9G`Ma zO-Yo#oHFqD?(u?mfL?YcnglL9;FS)oUR@&E@7Iz`O_2@5wEE{q389xJFUg!Wu%Vxf zAS7SLaGyzLO-o{c;c1PYj;}^y?tMH?Ab|r%eEBw}S?2h;*R5<7OVkd6D;^|(MxpJq z`jRXwq#F;tj9>~pK&|L&3E?Qc+brt`R*;X?v7^5f?PpL@ND^)X>tKrO2}=fsf*qI@ zR}i=GGX{NnL~czK;5g&E&H`NOuk^8{LGB)Mi9aq1KnZ+_;l1ID!$>^pv--6M$BFPw z73xpmWkYc&83hh}=>Ft+>BJ)MPUn5NpWVmK(ZgCs0$(182bY3ks|VClCJDnbgH~8kmHczjR#P@ zG*tH+qLblXe=qtKOTTCYy&WySvS*9(>DQ6?@iGpgAwRW1#jW<*AqYU`6S!6Akp6uZ z^QX?W3*vcYb~M{SX4Iyc$voB;Jik^?`WWlgr0# zN!wdfl|Ir3%xs36PO2}!Jf)Kp-8}jm%$s_6a`Rb^py_f+k2(*=y)kNHJ0cY52rl6_ zs&>s;_K0LNbn1&ZUho)N^AD-MxGKbuz7mdo_m72|IlK$>9et(H;<&eWIVW8EtXEXD zRn)+J+4vcj*K;S}520A@WGt%yrN7I!8YvCvEPZe4ZlY=mJQ7++hAht9#Et}|9We^8 zOwdso#yj`JzWh~@R=zk8t(H_i7QjU9$z>kY)&6w76eE$jDSe}H!YHQigA=nNTjD{~ zCL-51msoOod|=HlFD?f%bBZ{w_lVa~;@+d@`l=KS=|d&aN3(1OvmoO zYox6i7+I!l&i}p%0w9_KMH9S|Ugj|C%*eV-Z&<3bs4@c`%#{_00=N$L6MdX