From 595fc18ea65e0b8c4d4084b3b22040a823ade781 Mon Sep 17 00:00:00 2001 From: Dimitri Gigot Date: Thu, 26 Mar 2020 17:03:53 +0000 Subject: [PATCH 01/54] Groceries app --- apps.json | 14 +++ apps/groceries/groceries.html | 158 ++++++++++++++++++++++++++++++++++ apps/groceries/groceries.png | Bin 0 -> 1800 bytes 3 files changed, 172 insertions(+) create mode 100644 apps/groceries/groceries.html create mode 100644 apps/groceries/groceries.png diff --git a/apps.json b/apps.json index cb0a1bf79..3e3c89bba 100644 --- a/apps.json +++ b/apps.json @@ -823,5 +823,19 @@ "storage": [ {"name":"widid.wid.js","url":"widget.js"} ] + }, + { + "id": "groceries", + "name": "Groceries", + "icon": "groceries.png", + "version":"0.01", + "description": "Simple grocery list - Display a list of product and track if you already put them in your cart.", + "tags": "tool,outdoors", + "type": "app", + "custom":"groceries.html", + "storage": [ + {"name":"groceries.json"}, + {"name":"groceries.app.js"} + ] } ] diff --git a/apps/groceries/groceries.html b/apps/groceries/groceries.html new file mode 100644 index 000000000..9da8b0e6b --- /dev/null +++ b/apps/groceries/groceries.html @@ -0,0 +1,158 @@ + + + + + + +

List of products

+ + + + + + + + + + + +
namequantityactions
+

+

Add a new product

+
+
+
+ +
+
+ +
+
+ +
+
+
+

+ + + + + + + diff --git a/apps/groceries/groceries.png b/apps/groceries/groceries.png new file mode 100644 index 0000000000000000000000000000000000000000..93a29a4a686f172e5e6dbd2ecb2a1d3edf4751c0 GIT binary patch literal 1800 zcmV+j2lx1iP)tlxqC9)f@Omu&Na^VuQ3o*OkLX&0x0b91a zC7LC3CR;|G&UwKyoC)@U)%oe$2-|YHkk(v4M!t35mBz$@a#wDU>?rxOl>4iDU0;K~&^NeJ~rZV1qG0 z2VEWRN{fW6B-AV=vyLG{LNQb2i6*D;)z1+>HV9oV)YY-AYv;CEAGyt1BxHeIB6`O1 zgNbCKvH5&(h}tjTY&oMqX-z=6c>c(BKect-eBUPt!g0uGg&+h40X>Fzw5_e#pVR#$ zXoP~+BFSrtk0nGN171%U%*9ZeH|HLjvY%#M?bNRbI9pq_zjAQwp^ph~HbFcpN~ZRz z(p@Mo-ho770lfp=4bOss8*F%I4msLmKr#xaD)J*)`yvYx`ky+nJwKX`iBeY-qKGqH z?QS=3P!M$53s7Hu5JniTm@SU>rp6YK0dui1iN|DU+@DO!eyGs{ttdh(`FAE0vla{o z?WidZt%?gW#AR7;<X-pbXX@H zNxpMYdq4RMO4a}WV;wc05JSkxHD~SsCa-dTj zNTxVqQheR_7dUJ%8VslVKYYW7jWB?j;7(;1x|h0^D=>+_|8G8A);PQcVdy~=1vqUM z=Bmmm)pMW?ZosIy0KK;IbR&uXN!$f_n-$fCGwJquLBgH9YRnj{JTt}EHBxNEeXlt^ z=25u`mrr_dyKd3t92OJZd{9ZwAii{~WsvTQjEnfS8xO2y_@!_U?;}HwP2R(Ijz)}m zit&g9Oe?63KH;Lj-FATAd+p`e9q7aT9cJ8VbS}; zQ^kGnzzKFl@TSGDoSS-YQ$q_XStXt~30!=tPYtT;z`;H5V0>y6M#+fsq8;frcBVm9 z*_*JM9oV^KK>zTcC~y_yt(v2JXX>jDabwn+OJjC>_p^QzY!*8o^Zl)_Rq0Y~0Idq0 zS2Ejbz57Z043707FgeP1%EK<&HQJ?2qjG*1bTS%v z%ubCHDDjk|*z-F39AIq&YmVQ|gsn7eCKBY&B;IDWBhQ|XP-F^P(QUxw%mhX!9y3?4 za|0-g(DPbUZ?Ai9XPitl89;gYdW9(B>6do0 z&{d=<|EJJx0R4iRi$%B)8xs*{tC-D)*IL!li9sItRi$t8xdUT=@j7sD@4L`~ZUg#< z@9|7Teoy(EeEDwwZ_kbU;PA;c-%(!VWd_vn&m{hDmP)mv+W`74ORG=SmA{Aypl2;4 z5^=uzMCz^;-3HXM(oa{4%%IK%Ex`EHFzC+|RLpt@yWwJmOe>of#Mu@=51VEH#S6s{ z9o#%D1JN_>#7hfe`U6y8YJ?wyDGkFo zERDt!OF!~i5Yltbc`JfdVhJF1ywFnv_&cBz%HNa*=^#c>zCWO1`&}!lb?WRyb7@D_ zoMJQ4ZGbZ)W6%m}S;fo+s9pL&qm@ky;%p0`2i^anc~wxo1C;V!MN}J*?VR%}kkbG~ qkv|qi@hCO{S(a~Li!HWTm;V6Sm{)4DoNDL*0000 Date: Thu, 26 Mar 2020 17:20:23 +0000 Subject: [PATCH 02/54] Change product list style --- apps/groceries/groceries.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/groceries/groceries.html b/apps/groceries/groceries.html index 9da8b0e6b..0f29817ab 100644 --- a/apps/groceries/groceries.html +++ b/apps/groceries/groceries.html @@ -126,8 +126,12 @@ function updateSettings() { require("Storage").writeJSON(filename, settings); Bangle.buzz(); } +function twoChat(n){ + if(n<10) return '0'+n; + return ''+n; +} const mainMenu = settings.products.reduce(function(m, p, i){ - const name = '( '+p.quantity+' ) '+p.name; + const name = twoChat(p.quantity)+' '+p.name; m[name] = { value: p.ok, format: v => v?'[x]':'[ ]', From d0dd4b13af93296dfd66240fe361c076baf2c87a Mon Sep 17 00:00:00 2001 From: Dimitri Gigot Date: Thu, 26 Mar 2020 19:35:17 +0000 Subject: [PATCH 03/54] save on remove item --- apps/groceries/groceries.html | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/groceries/groceries.html b/apps/groceries/groceries.html index 0f29817ab..79acb4b59 100644 --- a/apps/groceries/groceries.html +++ b/apps/groceries/groceries.html @@ -87,6 +87,7 @@ function removeProduct(index){ products = products.filter((p,i) => i!==index) + save() renderProducts() } From b47b5f5a4f7184b662b6d1d4b187cf065720c7e7 Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 01:00:49 +0800 Subject: [PATCH 04/54] Update stopwatch.js --- apps/swatch/stopwatch.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/swatch/stopwatch.js b/apps/swatch/stopwatch.js index 6886bc697..dc79b34da 100644 --- a/apps/swatch/stopwatch.js +++ b/apps/swatch/stopwatch.js @@ -22,7 +22,12 @@ function updateLabels() { g.setFont("6x8",1); g.setFontAlign(-1,-1); for (var i in lapTimes) { - g.drawString(i+": "+timeToText(lapTimes[i]),10,timeY + 30 + i*8); + if (i<18) + {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),8,timeY + 30 + i*8);} + else if (i<36) + {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),80,timeY + 30 + (i-18)*8);} + else + {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),152,timeY + 30 + (i-36)*8);} } drawsecs(); } From ad67db1a4abbcf51f1dd18c0c2e317e03cfb113c Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 01:07:24 +0800 Subject: [PATCH 05/54] Update stopwatch.js Made lap entries count up from 1 Made lap entries scroll to 2nd column after 18th entry to allow for 36 lap entries before scrolling off-screen --- apps/swatch/stopwatch.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/swatch/stopwatch.js b/apps/swatch/stopwatch.js index dc79b34da..ed087e66f 100644 --- a/apps/swatch/stopwatch.js +++ b/apps/swatch/stopwatch.js @@ -23,11 +23,9 @@ function updateLabels() { g.setFontAlign(-1,-1); for (var i in lapTimes) { if (i<18) - {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),8,timeY + 30 + i*8);} - else if (i<36) - {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),80,timeY + 30 + (i-18)*8);} - else - {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),152,timeY + 30 + (i-36)*8);} + {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),35,timeY + 30 + i*8);} + else + {g.drawString(lapTimes.length-i+": "+timeToText(lapTimes[i]),125,timeY + 30 + (i-18)*8);} } drawsecs(); } From 4696f7e4ecb557281727ec3569e9c0a3d8566cad Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 01:10:45 +0800 Subject: [PATCH 06/54] Create ChangeLog Changelog for updated Lap logging feature --- apps/swatch/ChangeLog | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 apps/swatch/ChangeLog diff --git a/apps/swatch/ChangeLog b/apps/swatch/ChangeLog new file mode 100644 index 000000000..86f584836 --- /dev/null +++ b/apps/swatch/ChangeLog @@ -0,0 +1,3 @@ +0.01 Original App +0.02 Lap log now counts up from 1 + Lap log now scrolls into 2nd column after 18th entry, able to display 36 entries before going off screen From 30912d6825d9efe1f800cd1a00c8eedc5a040e07 Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 01:13:27 +0800 Subject: [PATCH 07/54] Update apps.json Updated Stopwatch app version --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 15acb3b20..44a30c1f9 100644 --- a/apps.json +++ b/apps.json @@ -355,7 +355,7 @@ { "id": "swatch", "name": "Stopwatch", "icon": "stopwatch.png", - "version":"0.01", + "version":"0.02", "description": "Simple stopwatch with Lap Time recording", "tags": "health", "allow_emulator":true, From 82feb3b7c102c068c211ae4de9ac9a377fa6b3b9 Mon Sep 17 00:00:00 2001 From: Dimitri Gigot Date: Fri, 27 Mar 2020 20:00:37 +0000 Subject: [PATCH 08/54] rename the app to have a 7character name & fix issue with saving --- apps.json | 12 ++++++------ .../groceries.html => grocery/grocery.html} | 8 ++++---- .../groceries.png => grocery/grocery.png} | Bin 3 files changed, 10 insertions(+), 10 deletions(-) rename apps/{groceries/groceries.html => grocery/grocery.html} (96%) rename apps/{groceries/groceries.png => grocery/grocery.png} (100%) diff --git a/apps.json b/apps.json index 3e3c89bba..c06cd49a8 100644 --- a/apps.json +++ b/apps.json @@ -825,17 +825,17 @@ ] }, { - "id": "groceries", - "name": "Groceries", - "icon": "groceries.png", + "id": "grocery", + "name": "Grocery", + "icon": "grocery.png", "version":"0.01", "description": "Simple grocery list - Display a list of product and track if you already put them in your cart.", "tags": "tool,outdoors", "type": "app", - "custom":"groceries.html", + "custom":"grocery.html", "storage": [ - {"name":"groceries.json"}, - {"name":"groceries.app.js"} + {"name":"grocery"}, + {"name":"grocery.app.js"} ] } ] diff --git a/apps/groceries/groceries.html b/apps/grocery/grocery.html similarity index 96% rename from apps/groceries/groceries.html rename to apps/grocery/grocery.html index 79acb4b59..12711375d 100644 --- a/apps/groceries/groceries.html +++ b/apps/grocery/grocery.html @@ -111,7 +111,7 @@ var newTime = ${Date.now()} var products = ${JSON.stringify(products)} var newTime = newTime; -var filename = 'groceries.json'; +var filename = 'grocery'; var settings = require("Storage").readJSON(filename,1)|| null; function getSettings(){ return { @@ -152,9 +152,9 @@ E.showMenu(mainMenu); var icon = `require("heatshrink").decompress(atob("mEwxH+AH4A/AH4AQ0QACF1nGAAIxpFoYwqFwwwnRggwGB4eFAggACLzwHCMAeF1WGAgOGw2x2IGCLzYGEF4YpBwotCFwJfWFwo1GSAYtBAIIABRq4vFMhAwBzoAFdzIuKAAOc4IAGGC4qEMZOiF44wXFxovleBYvIGCwmB0WjE4V/AgfG1IvCzujFQOjwoECF6WFwovBDYOFEwN/AgIwCAgOFBwYrBBAQEBzodCF6AAHww1CBpIODAAYvRDAWG2IEBAYYJFBxICCF6Ox1WxAAQfBAYQlCAAIOJAQIvUADQvn1WGR4RfbP4gAFBwgFCF7a5EdwQADF46/cL9wAQF94AGF85bB1TvmF47vdJ4bvFF8qPRFgLv/L7jPCaQq/fYYrvgJgoAGd/7v/F/4v/F5oAdF54weFyAA/AH4A3A="))`; sendCustomizedApp({ storage:[ - {name:"groceries.app.js", content:app}, - {name:"groceries.img", content:icon, evaluate:true}, - {name:"groceries.json"} + {name:"grocery.app.js", content:app}, + {name:"grocery.img", content:icon, evaluate:true}, + {name:"grocery"} ] }); }); diff --git a/apps/groceries/groceries.png b/apps/grocery/grocery.png similarity index 100% rename from apps/groceries/groceries.png rename to apps/grocery/grocery.png From 8aabcf28e8df1a8dcd8ac72635a5968c5f4f5ef7 Mon Sep 17 00:00:00 2001 From: Oli Sanders <35221386+oli-sanders@users.noreply.github.com> Date: Fri, 27 Mar 2020 23:53:38 +0000 Subject: [PATCH 09/54] dev clock (#13) --- apps.json | 13 ++++ apps/dclock/ChangeLog | 8 +++ apps/dclock/clock-dev-icon.js | 1 + apps/dclock/clock-dev.js | 111 ++++++++++++++++++++++++++++++++++ apps/dclock/clock-dev.png | Bin 0 -> 2603 bytes 5 files changed, 133 insertions(+) create mode 100644 apps/dclock/ChangeLog create mode 100644 apps/dclock/clock-dev-icon.js create mode 100644 apps/dclock/clock-dev.js create mode 100644 apps/dclock/clock-dev.png diff --git a/apps.json b/apps.json index 15acb3b20..4f29159cb 100644 --- a/apps.json +++ b/apps.json @@ -508,6 +508,19 @@ {"name":"sclock.img","url":"clock-simple-icon.js","evaluate":true} ] }, + { "id": "dclock", + "name": "Dev Clock", + "icon": "clock-dev.png", + "version":"0.08", + "description": "A Digital Clock including timestamp (tst), beats(@), days in current month (dm) and days since new moon (l)", + "tags": "clock", + "type":"clock", + "allow_emulator":true, + "storage": [ + {"name":"dclock.app.js","url":"clock-dev.js"}, + {"name":"dclock.img","url":"clock-dev-icon.js","evaluate":true} + ] + }, { "id": "gesture", "name": "Gesture Test", "icon": "gesture.png", diff --git a/apps/dclock/ChangeLog b/apps/dclock/ChangeLog new file mode 100644 index 000000000..6582ec16e --- /dev/null +++ b/apps/dclock/ChangeLog @@ -0,0 +1,8 @@ +0.01: branched from simple clock and added seconds +0.02: add timestamp (tst) +0.03: fix timestamp round to whole number +0.04: add iso datetime and move day of the week (d) / month names (m) +0.05: add beats (@) +0.06: tidy up +0.07: add days in current month (md) and days since new moon (l) +0.08: update icon \ No newline at end of file diff --git a/apps/dclock/clock-dev-icon.js b/apps/dclock/clock-dev-icon.js new file mode 100644 index 000000000..f36dcaee3 --- /dev/null +++ b/apps/dclock/clock-dev-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkEIf4A5/8wgf/AwUB/8gh/zA4QMCl/xA4cAichgIaBiEDgMgmECDQMAkMA+EgiYvDkQJBkcQgMQDwMggUiiECG4MikEBmQWCgURiEREQIXBCIMxkIIBAoMSiQ4BGoIABKgPykRSBI4JfC+c/iARBl8zmBfEAAUvIgIAUkbAtgalB+ADDBIKSBHgUgmYJCAAa6BmCoBAYMiBIMRC4UQmEAAoQvFmUDAYUSmcxWIKMBEQKrBOw0yh8wmcyj4nBIYQDB+cwBAQA/ABUxgUDkBqBgchkMiiUikMRgSOBkR3BkEhC4MgiQHBiADBC4UQAYMRiUxkECAAITBC4MSiUQF4MTiQTBBAIDBkcCiMxkUTAYIvCAH4A/AH4AKiIPPgMxiESgUQgECgMBdAMiiUgC48ikUBiEBiIXDGQURiIbBF48RkAvCEwIvCkERgQMBRHpDBOoRhBNoJOBJIkiKYMjgcTOoMhLQMQmMDDIMjQQInEC4MhiUSkQHCC4MAkAXCiUjiZ5UiR5jLwLaBAQJ1BAgIAMCgMxMwMgkciAoMjC5pqBRwPxCoMiiUyGBsgiBBBiESVAKzBf+YACA==")) \ No newline at end of file diff --git a/apps/dclock/clock-dev.js b/apps/dclock/clock-dev.js new file mode 100644 index 000000000..39f031fcc --- /dev/null +++ b/apps/dclock/clock-dev.js @@ -0,0 +1,111 @@ +/* jshint esversion: 6 */ +const timeFontSize = 4; +const dateFontSize = 3; +const smallFontSize = 2; +const font = "6x8"; + +const xyCenter = g.getWidth() / 2; +const yposTime = 50; +const yposDate = 85; +const yposTst = 115; +const yposDml = 170; +const yposDayMonth = 195; +const yposGMT = 220; + +// Check settings for what type our clock should be +var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]; + +function getUTCTime(d) { + return d.toUTCString().split(' ')[4].split(':').map(function(d){return Number(d)}); +} + +function drawSimpleClock() { + // get date + var d = new Date(); + var da = d.toString().split(" "); + var dutc = getUTCTime(d); + + g.reset(); // default draw styles + // drawSting centered + g.setFontAlign(0, 0); + + // draw time + var time = da[4].split(":"); + var hours = time[0], + minutes = time[1], + seconds = time[2]; + + var meridian = ""; + if (is12Hour) { + hours = parseInt(hours,10); + meridian = "AM"; + if (hours == 0) { + hours = 12; + meridian = "AM"; + } else if (hours >= 12) { + meridian = "PM"; + if (hours>12) hours -= 12; + } + hours = (" "+hours).substr(-2); + } + + // Time + g.setFont(font, timeFontSize); + g.drawString(`${hours}:${minutes}:${seconds}`, xyCenter, yposTime, true); + g.setFont(font, smallFontSize); + g.drawString(meridian, xyCenter + 102, yposTime + 10, true); + + // Date String + g.setFont(font, dateFontSize); + g.drawString(`${d.getFullYear()}-${d.getMonth()+1}-${d.getDate()}`, xyCenter, yposDate, true); + + // Timestamp + var tst = Math.round(d.getTime()); + g.setFont(font, smallFontSize); + g.drawString(`tst:${tst}`, xyCenter, yposTst, true); + + //Days in month + var dom = new Date(d.getFullYear(), d.getMonth()+1, 0).getDate(); + + //Days since full moon + var knownnew = new Date(2020,02,24,09,28,0); + + // Get millisecond difference and divide down to cycles + var cycles = (d.getTime()-knownnew.getTime())/1000/60/60/24/29.53; + + // Multiply decimal component back into days since new moon + var sincenew = (cycles % 1)*29.53; + + // Draw days in month and sime since new moon + g.setFont(font, smallFontSize); + g.drawString(`md:${dom} l:${sincenew.toFixed(2)}`, xyCenter, yposDml, true); + + // draw Month name, Day of the week and beats + var beats = Math.floor((((dutc[0] + 1) % 24) + dutc[1] / 60 + dutc[2] / 3600) * 1000 / 24); + g.setFont(font, smallFontSize); + g.drawString(`m:${da[1]} d:${da[0]} @${beats}`, xyCenter, yposDayMonth, true); + + // draw gmt + var gmt = da[5]; + g.setFont(font, smallFontSize); + g.drawString(gmt, xyCenter, yposGMT, true); +} + +// handle switch display on by pressing BTN1 +Bangle.on('lcdPower', function(on) { + if (on) drawSimpleClock(); +}); + +// clean app screen +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +// refesh every 100 milliseconds +setInterval(drawSimpleClock, 100); + +// draw now +drawSimpleClock(); + +// Show launcher when middle button pressed +setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); \ No newline at end of file diff --git a/apps/dclock/clock-dev.png b/apps/dclock/clock-dev.png new file mode 100644 index 0000000000000000000000000000000000000000..0cfbff44c1e6ff1dad206c266e64f43787c846df GIT binary patch literal 2603 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 N002ovPDHLkV1gky Date: Sat, 28 Mar 2020 11:07:14 +0800 Subject: [PATCH 10/54] Update stopwatch.js - Remove ability to lap while stopped - Added ability to save log of laps as dated json array while stopped --- apps/swatch/stopwatch.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/swatch/stopwatch.js b/apps/swatch/stopwatch.js index ed087e66f..ac1cc0d5b 100644 --- a/apps/swatch/stopwatch.js +++ b/apps/swatch/stopwatch.js @@ -4,6 +4,7 @@ var started = false; var timeY = 60; var hsXPos = 0; var lapTimes = []; +var saveTimes = []; var displayInterval; function timeToText(t) { @@ -18,7 +19,7 @@ function updateLabels() { g.setFontAlign(0,0,3); g.drawString(started?"STOP":"GO",230,120); if (!started) g.drawString("RESET",230,50); - g.drawString("LAP",230,190); + g.drawString(started?"LAP":"SAVE",230,190); g.setFont("6x8",1); g.setFontAlign(-1,-1); for (var i in lapTimes) { @@ -50,6 +51,11 @@ function drawms() { g.clearRect(hsXPos,timeY,220,timeY+20); g.drawString("."+("0"+hs).substr(-2),hsXPos,timeY+10); } +function saveconvert() { + for (var v in lapTimes){ + saveTimes[v]=v+1+"-"+timeToText(lapTimes[(lapTimes.length-1)-v]); + } +} setWatch(function() { // Start/stop started = !started; @@ -85,6 +91,12 @@ setWatch(function() { // Lap if (started) tCurrent = Date.now(); lapTimes.unshift(tCurrent-tStart); tStart = tCurrent; + if (!started) + { + var timenow= Date(); + saveconvert(); + require("Storage").writeJSON("StpWch-"+timenow.toString(), saveTimes); + } updateLabels(); }, BTN3, {repeat:true}); From 661eaa7c3a02127a8fd46ada3b058c2db4970a30 Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 11:57:32 +0800 Subject: [PATCH 11/54] Update ChangeLog --- apps/swatch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/swatch/ChangeLog b/apps/swatch/ChangeLog index 86f584836..119333d94 100644 --- a/apps/swatch/ChangeLog +++ b/apps/swatch/ChangeLog @@ -1,3 +1,4 @@ 0.01 Original App 0.02 Lap log now counts up from 1 Lap log now scrolls into 2nd column after 18th entry, able to display 36 entries before going off screen +0.03 Added ability to save Lap log as a date named JSON file into memory From 72d0de30a52fe7490010d1e02de493eb0e96edc5 Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 11:58:14 +0800 Subject: [PATCH 12/54] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 44a30c1f9..a8083c619 100644 --- a/apps.json +++ b/apps.json @@ -355,7 +355,7 @@ { "id": "swatch", "name": "Stopwatch", "icon": "stopwatch.png", - "version":"0.02", + "version":"0.03", "description": "Simple stopwatch with Lap Time recording", "tags": "health", "allow_emulator":true, From be539e59932c7627cf91e3709082fbc709ce8a7d Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 12:12:22 +0800 Subject: [PATCH 13/54] Update stopwatch.js -Swapped functions of BN1 and BN3 --- apps/swatch/stopwatch.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/swatch/stopwatch.js b/apps/swatch/stopwatch.js index ac1cc0d5b..73cf0adfc 100644 --- a/apps/swatch/stopwatch.js +++ b/apps/swatch/stopwatch.js @@ -18,8 +18,8 @@ function updateLabels() { g.setFont("6x8",2); g.setFontAlign(0,0,3); g.drawString(started?"STOP":"GO",230,120); - if (!started) g.drawString("RESET",230,50); - g.drawString(started?"LAP":"SAVE",230,190); + if (!started) g.drawString("RESET",230,190); + g.drawString(started?"LAP":"SAVE",230,50); g.setFont("6x8",1); g.setFontAlign(-1,-1); for (var i in lapTimes) { @@ -78,14 +78,6 @@ setWatch(function() { // Start/stop drawms(); }, 20); }, BTN2, {repeat:true}); -setWatch(function() { // Reset - Bangle.beep(); - if (!started) { - tStart = tCurrent = Date.now(); - } - lapTimes = []; - updateLabels(); -}, BTN1, {repeat:true}); setWatch(function() { // Lap Bangle.beep(); if (started) tCurrent = Date.now(); @@ -98,6 +90,14 @@ setWatch(function() { // Lap require("Storage").writeJSON("StpWch-"+timenow.toString(), saveTimes); } updateLabels(); +}, BTN1, {repeat:true}); +setWatch(function() { // Reset + Bangle.beep(); + if (!started) { + tStart = tCurrent = Date.now(); + } + lapTimes = []; + updateLabels(); }, BTN3, {repeat:true}); updateLabels(); From 06b98f0043e99446c5c77b82b3d974ff38fa2c56 Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 12:14:40 +0800 Subject: [PATCH 14/54] Update stopwatch.js Fixed bug where one could reset lap log even though timer is running --- apps/swatch/stopwatch.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/swatch/stopwatch.js b/apps/swatch/stopwatch.js index 73cf0adfc..d4136d8ed 100644 --- a/apps/swatch/stopwatch.js +++ b/apps/swatch/stopwatch.js @@ -92,11 +92,11 @@ setWatch(function() { // Lap updateLabels(); }, BTN1, {repeat:true}); setWatch(function() { // Reset - Bangle.beep(); if (!started) { - tStart = tCurrent = Date.now(); - } + Bangle.beep(); + tStart = tCurrent = Date.now(); lapTimes = []; + } updateLabels(); }, BTN3, {repeat:true}); From 7bbc2e7eb14b4101d3b2f67b765f3eebd6c98959 Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 12:21:58 +0800 Subject: [PATCH 15/54] Update ChangeLog --- apps/swatch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/swatch/ChangeLog b/apps/swatch/ChangeLog index 119333d94..d907766c1 100644 --- a/apps/swatch/ChangeLog +++ b/apps/swatch/ChangeLog @@ -2,3 +2,4 @@ 0.02 Lap log now counts up from 1 Lap log now scrolls into 2nd column after 18th entry, able to display 36 entries before going off screen 0.03 Added ability to save Lap log as a date named JSON file into memory + Fixed bug from 0.01 where BN1 (reset) could clear the lap log when timer is running From 11bf84f583bf8b4a00dfdb9d74d46b3067786fc3 Mon Sep 17 00:00:00 2001 From: Red-The-Hunter <62763030+Red-The-Hunter@users.noreply.github.com> Date: Sat, 28 Mar 2020 16:03:37 +0800 Subject: [PATCH 16/54] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index a8083c619..0cdd8fd3b 100644 --- a/apps.json +++ b/apps.json @@ -356,7 +356,7 @@ "name": "Stopwatch", "icon": "stopwatch.png", "version":"0.03", - "description": "Simple stopwatch with Lap Time recording", + "description": "Simple stopwatch with Lap Time logging to a JSON file", "tags": "health", "allow_emulator":true, "storage": [ From a6fab96de9e8bdf34bbff9d28fcaab4202d0f7e2 Mon Sep 17 00:00:00 2001 From: Oliver Sanders Date: Sat, 28 Mar 2020 22:13:51 +0000 Subject: [PATCH 17/54] Use localised month and day of the week from locale --- apps.json | 2 +- apps/dclock/ChangeLog | 3 ++- apps/dclock/clock-dev.js | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index 4f29159cb..923ebfecd 100644 --- a/apps.json +++ b/apps.json @@ -511,7 +511,7 @@ { "id": "dclock", "name": "Dev Clock", "icon": "clock-dev.png", - "version":"0.08", + "version":"0.09", "description": "A Digital Clock including timestamp (tst), beats(@), days in current month (dm) and days since new moon (l)", "tags": "clock", "type":"clock", diff --git a/apps/dclock/ChangeLog b/apps/dclock/ChangeLog index 6582ec16e..edf7da4c2 100644 --- a/apps/dclock/ChangeLog +++ b/apps/dclock/ChangeLog @@ -5,4 +5,5 @@ 0.05: add beats (@) 0.06: tidy up 0.07: add days in current month (md) and days since new moon (l) -0.08: update icon \ No newline at end of file +0.08: update icon +0.09: Use localised month and day of the week from locale diff --git a/apps/dclock/clock-dev.js b/apps/dclock/clock-dev.js index 39f031fcc..d2c08726a 100644 --- a/apps/dclock/clock-dev.js +++ b/apps/dclock/clock-dev.js @@ -1,3 +1,4 @@ +var locale = require("locale"); /* jshint esversion: 6 */ const timeFontSize = 4; const dateFontSize = 3; @@ -83,7 +84,7 @@ function drawSimpleClock() { // draw Month name, Day of the week and beats var beats = Math.floor((((dutc[0] + 1) % 24) + dutc[1] / 60 + dutc[2] / 3600) * 1000 / 24); g.setFont(font, smallFontSize); - g.drawString(`m:${da[1]} d:${da[0]} @${beats}`, xyCenter, yposDayMonth, true); + g.drawString(`m:${locale.month(d,true)} d:${locale.dow(d,true)} @${beats}`, xyCenter, yposDayMonth, true); // draw gmt var gmt = da[5]; From e97852cae41f7b28fd9a7b1d86443b31ec900770 Mon Sep 17 00:00:00 2001 From: Dimitri Gigot Date: Sun, 29 Mar 2020 02:48:21 +0000 Subject: [PATCH 18/54] Fixing issue #147 - No way to open launcher when no clock --- apps/boot/bootloader.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/boot/bootloader.js b/apps/boot/bootloader.js index febc4fc19..76d655671 100644 --- a/apps/boot/bootloader.js +++ b/apps/boot/bootloader.js @@ -12,7 +12,11 @@ if (!settings.welcomed && require("Storage").read("welcome.js")!==undefined) { clockApp = require("Storage").read(clockApps[0].src); delete clockApps; } - if (!clockApp) clockApp='E.showMessage("No Clock Found")'; + if (!clockApp) clockApp=`E.showMessage("No Clock Found"); + setWatch(() => { + Bangle.showLauncher(); + }, BTN2, {repeat:false,edge:"falling"});) + `; delete settings; // check to see if our clock is wrong - if it is use GPS time if ((new Date()).getFullYear()==1970) { From f746b0c67cc3729542a4bbc42c026e6de16ea3ce Mon Sep 17 00:00:00 2001 From: MaBecker Date: Sun, 29 Mar 2020 18:52:10 +0200 Subject: [PATCH 19/54] add widget version --- apps.json | 11 +++++++++++ apps/widver/ChangeLog | 1 + apps/widver/widget.js | 11 +++++++++++ apps/widver/widget.png | Bin 0 -> 344 bytes 4 files changed, 23 insertions(+) create mode 100644 apps/widver/ChangeLog create mode 100644 apps/widver/widget.js create mode 100644 apps/widver/widget.png diff --git a/apps.json b/apps.json index 15acb3b20..12903f95d 100644 --- a/apps.json +++ b/apps.json @@ -836,5 +836,16 @@ {"name":"marioclock.app.js","url":"marioclock-app.js"}, {"name":"marioclock.img","url":"marioclock-icon.js","evaluate":true} ] + }, + { "id": "widver", + "name": "Firmware Version Widget", + "icon": "widget.png", + "version":"0.01", + "description": "Display the version of the installed firmware in the top widget section.", + "tags": "widget,tool,system", + "type":"widget", + "storage": [ + {"name":"widver.wid.js","url":"widget.js"} + ] } ] diff --git a/apps/widver/ChangeLog b/apps/widver/ChangeLog new file mode 100644 index 000000000..adb5b038a --- /dev/null +++ b/apps/widver/ChangeLog @@ -0,0 +1 @@ +0.01: New Widget diff --git a/apps/widver/widget.js b/apps/widver/widget.js new file mode 100644 index 000000000..b5edfc08c --- /dev/null +++ b/apps/widver/widget.js @@ -0,0 +1,11 @@ +/* jshint esversion: 6 */ +(() => { + var width = 28, + ver = process.env.VERSION.split('.'); + function draw() { + g.reset().setColor(0, 0.5, 1).setFont("6x8", 1); + g.drawString(ver[0], this.x + 2, this.y + 4, true); + g.setFontAlign(0, -1, 0).drawString(ver[1], this.x + width / 2, this.y + 14, true); + } + WIDGETS["version"] = { area: "tr", width: width, draw: draw }; +})(); diff --git a/apps/widver/widget.png b/apps/widver/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..72e646a30471367725c001956df1274def0dafdc GIT binary patch literal 344 zcmV-e0jK_nP)Jw!7z!$$Z#QY4ycoKvLXQhXuA$3 z8cA3q0O(0%=HA=f%x)9|Qi;zv`9T<=Xq>D{AVnn!D+Pf6C9D+yekHQb=-+)MvOmY# zwN@wa4-}Aw0@6@G8VX250cj{84F#m3fHV}4Ci9>8y6$GK90vufMJXzuK;;FL)+&dk qm%GiLn?7)8QuzcbFF*((vb+J73rQEfJXV?z* literal 0 HcmV?d00001 From 441d5d1882c304b5fbfba430fac92a23d3891267 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 30 Mar 2020 08:39:59 +0100 Subject: [PATCH 20/54] bump version --- apps.json | 2 +- apps/boot/ChangeLog | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 15acb3b20..27dc2b2e0 100644 --- a/apps.json +++ b/apps.json @@ -2,7 +2,7 @@ { "id": "boot", "name": "Bootloader", "icon": "bootloader.png", - "version":"0.11", + "version":"0.12", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "tags": "tool,system", "type":"bootloader", diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 3bd9ec71c..93f03b8ad 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -9,3 +9,4 @@ 0.10: Stop users calling save() (fix #125) If Debug info is set to 'show' don't move to Terminal if connected! 0.11: Added vibrate as beep workaround +0.12: Add an event on BTN2 to open launcher when no clock detected (fix #147) From c776cc9222154264dc31b7dee77105f52455ec9a Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 15:25:40 +0200 Subject: [PATCH 21/54] Update app.js --- apps/pipboy/app.js | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/apps/pipboy/app.js b/apps/pipboy/app.js index 050fd366b..48a87fc5d 100644 --- a/apps/pipboy/app.js +++ b/apps/pipboy/app.js @@ -29,17 +29,23 @@ function topLine() { function bottomLine() { - g.setColor(darkGreen); - g.fillRect(5, 175, 60, 185); - g.fillRect(67, 175, 140, 185); + //first line + g.setColor(darkerGreen); + g.fillRect(5, 175, 100, 185); //DATE + g.fillRect(105, 175, 160, 185);//STIM + g.fillRect(166, 175, 239, 185); // RADAWAY + g.setColor(green); + g.setFont("6x8", tinyFont); + g.drawString("DATE", 20, 177); + g.drawString("STIM (3)", 135, 177); + g.drawString("RADAWAY (8)", 205, 177); + + //second line g.setColor(darkerGreen); g.fillRect(5, 190, 70, 200); g.fillRect(75, 190, 239, 200); - g.setFont("6x8", tinyFont); - g.drawString("STIM (0)", 32, 177); - g.drawString("RADAWAY (0)", 105, 177); g.setColor(green); g.drawString("HP 115/115", 38, 192); g.drawString("LEVEL 6", 100, 192); @@ -55,7 +61,15 @@ function drawClock() { var t = new Date(); var h = t.getHours(); var m = t.getMinutes(); + var dd = t.getDate(); + var mm = t.getMonth()+1; //month is zero-based + var yy = t.getFullYear(); var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2); + + //create date string + if (dd.toString().length < 2) dd = '0' + dd; + if (mm.toString().length < 2) mm = '0' + mm; + var date = dd + "." + mm + "." + yy; g.setFont("6x8",bigFont); g.setColor(green); @@ -63,6 +77,10 @@ function drawClock() { g.clearRect(0, 110, 150, 140); g.drawString(time, 70, 110); + + //draw date + g.setFont("6x8", tinyFont); + g.drawString(date, 67, 177); } function drawAll() { @@ -83,4 +101,3 @@ setInterval(drawClock, 1E4); drawAll(); setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); - From 5399f1577023e420ac5d9718d8e281b9add83d5c Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 15:28:28 +0200 Subject: [PATCH 22/54] Create app.js --- apps/pipboydate/app.js | 103 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 apps/pipboydate/app.js diff --git a/apps/pipboydate/app.js b/apps/pipboydate/app.js new file mode 100644 index 000000000..48a87fc5d --- /dev/null +++ b/apps/pipboydate/app.js @@ -0,0 +1,103 @@ +const bigFont = 4; +const smallFont = 2; +const tinyFont = 1; +const green = 0x0661; +const darkGreen = 0x0461; +const darkerGreen = 0x0261; +const pip = require("heatshrink").decompress(atob("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")); + +function topLine() { + + g.setColor(green); + g.setFontAlign(0, -1, 0); + + g.moveTo(0, 50).lineTo(30, 50); + g.lineTo(30, 40); + g.lineTo(35, 40).moveTo(90, 40).lineTo(95, 40); + g.lineTo(95, 50); + g.lineTo(239, 50); + + g.setFont("6x8", smallFont); + g.drawString("STAT", 65, 34); + g.drawString("INV", 130, 34); + g.drawString("DATA", 190, 34); + g.setColor(darkGreen); + g.drawString("STATUS", 45, 55); + g.drawString("SPEC", 122, 55); + g.drawString("PERKS", 195, 55); +} + +function bottomLine() { + + //first line + g.setColor(darkerGreen); + g.fillRect(5, 175, 100, 185); //DATE + g.fillRect(105, 175, 160, 185);//STIM + g.fillRect(166, 175, 239, 185); // RADAWAY + + g.setColor(green); + g.setFont("6x8", tinyFont); + g.drawString("DATE", 20, 177); + g.drawString("STIM (3)", 135, 177); + g.drawString("RADAWAY (8)", 205, 177); + + //second line + g.setColor(darkerGreen); + g.fillRect(5, 190, 70, 200); + g.fillRect(75, 190, 239, 200); + + g.setColor(green); + g.drawString("HP 115/115", 38, 192); + g.drawString("LEVEL 6", 100, 192); + g.drawRect(127, 192, 235, 198); +} + +function boy() { + g.drawImage(pip, 165, 85); +} + +function drawClock() { + + var t = new Date(); + var h = t.getHours(); + var m = t.getMinutes(); + var dd = t.getDate(); + var mm = t.getMonth()+1; //month is zero-based + var yy = t.getFullYear(); + var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2); + + //create date string + if (dd.toString().length < 2) dd = '0' + dd; + if (mm.toString().length < 2) mm = '0' + mm; + var date = dd + "." + mm + "." + yy; + + g.setFont("6x8",bigFont); + g.setColor(green); + g.setFontAlign(0, -1, 0); + + g.clearRect(0, 110, 150, 140); + g.drawString(time, 70, 110); + + //draw date + g.setFont("6x8", tinyFont); + g.drawString(date, 67, 177); +} + +function drawAll() { + topLine(); + boy(); + bottomLine(); + drawClock(); +} + +Bangle.on('lcdPower', function(on) { + if (on) drawAll(); +}); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +setInterval(drawClock, 1E4); +drawAll(); + +setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); From 0c6c6eb61ede29c151cec25bbae69f64a062a7d6 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 15:34:58 +0200 Subject: [PATCH 23/54] Create app-icon.js --- apps/pipboydate/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/pipboydate/app-icon.js diff --git a/apps/pipboydate/app-icon.js b/apps/pipboydate/app-icon.js new file mode 100644 index 000000000..935210156 --- /dev/null +++ b/apps/pipboydate/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AC4fDDjAuSgwACGFIuBhgACGAJjmLoQvDGAJkhbAguGGYwxbRAoAMGDZZMGBAvSbIpdSGCxYCW5jpDHhKSRDYQgGAwY8ETZYvPDZBXEAAwUFNAowOF44bFNJI2ENISRQdIqzLYhAxDAoRgScZgwFdow1DF54tQdpRMDF5jjHLiDxWF44wJBZIJFF5qPGF5blDLxIvPeAjsOF7RgCc6QvId6AvUd5QACF5pyEKAwlGF5qORcIwoFBgIwHFwwvTU4gvILxYuOXwouKA5AwGFxzuIDYYvkDQ6GIABKqEL6ryGF8QbHF6QXFX6wvuYIQvnFJgMBAAQva/wgMBQT4CF5QPCeB65CABgwCHxYuOF6L5JHYYuPSAyDFBRS6TMA4AME4RdHFyhgCLRLoJLzBgDExa7JFywwVFzQwTFwIADGDC5NRohDBSTQdCGCARCGDRNCGRQuFSobAYGAYxIFwoTDGKpMGWggADA4Q1FYipNGGA7NHYawVBD44qDGIbEHIwwlEA=")) From 6570eb499ea201877c8b0a0510432e569e7d9610 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 15:35:47 +0200 Subject: [PATCH 24/54] Add files via upload --- apps/pipboydate/app.png | Bin 0 -> 12431 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/pipboydate/app.png diff --git a/apps/pipboydate/app.png b/apps/pipboydate/app.png new file mode 100644 index 0000000000000000000000000000000000000000..018b5c7bb8dd8a8a0dcba32fa0450695d92bd67f GIT binary patch literal 12431 zcmV;AFmTU_P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3;ua&#+lhX1n)FM)Yj4kQra9eDYEUaF)!bldKZ zu+*QVTXpIjAT!?~q22kf|Ge%$_^Lf;mrLt))av=lBab-wqx;X-ct3;B@8|nU-?#Yh zzr5~#--x`F{%jknLi^)pMUfHp1fXk zT}too>^?7jZ^nZBWqLoqz5nw9{biAV{&Ig`{olX-w)k;=Ur&Eq%lcg-{`jYFgz~r7 z)9+*A-_qebqWIT0dI{qnrt|%G@9y`W&+KNdtZ4ma)LZQEa~m#PEO~k#t9&>975;AT zd+^=;^hU_HH^2C{FhV3M*M%H*nBj)=ep@hxnB$3!-!WQD@3o#<9MOmv5z=?Kv89oA z>O{`safC0Y_&b*Ho;%+2EOef{1DD3Y%>p0!AHUuI_U6Cy?d~-#QSkkDtr%BSUNa0u zPCvPdfQ0*vTX_ro^ZgCK|5N^uszk87W$sLH`t`ZRD&ddZN-xfd>k7X=B@|rS-y5(* zJi9QMkcfbSeHr zK$KKdBQ_&Vf|YY2e_HP3&@8FsQc5kYbXP{1HPu{8t+iEw+-#}kR$6VX^)}kf-F(Zfx7~inoxf50M)e=Q|Ba}HZ`9(8l&)*P zQR7wD+RrV5;G`&KL@ee&#G4{OLPy2S_mFc`{EqWQ=h0l-amc1VkLAg%8)=_ z85$t7xm~WTZ-&ekYq2sDrix}9E$AJ;dkUXRR<^l{xePU0(JREV&yWu@>?hP(jIv@1 zxy~?_Z#%Ahm{S1*V;=Rcz2^$Uj@3|HY=mra)oe{jN;>9q^1Zzv1Zuwxc0SjNmPD_% zoa(JDOybsSWhqu64;&b7O}9F&7{R_Z^;&u-S7PP^z%7#{aJ*3%OsXaIi1Z-E#wmOdyKC`{Ah!_v zM#a>3+am43hYr+7Ks#{8!jyhIf4D~cM%a+gyeHOqNc53eH7j`~mgKY^m`yt*XJZsY)imX+Co7Nz50R)hwDU#cbmqI z`$=Rwc}7O9T^ix8P`8l6dd;fLy2=>d)wFhMMhPrZg9KSI~v zVkLWbom=*mHtE4dN*^*Qc9M!e!>&DL^W*~W4P#b_r}DDt^IO#pl62HawA}-^!Eivc zK^al?Yip*h%*?FNR7#3-D{}|(Vy6OFw)Dv+(r&hjU>{^&uuH`l0tP7QyH^kL5iO>P zK)RG((MPx?&}6BVSM?c$iIo+dKrJ;B!D`ki%~Hj7@)1BhF(GY;=a{4JX*H6jU8|Y2 znzmH|Razbf5^<*s|7O94KwV{n;!n4^RMLjKm^j*a1dX z)UH;I#RGt{xt2=R^ct5_kE{>N5Gl?XpvgpG9<947cDy+5K5o`!0FZe;iQ**SuEE>T zZlKzLXWpvEuBYPaITnF^689C$egNLUdpPJ=!GHy^04YCf>y8@={Q<#+wK@%uf|xtm zCVVD$RsdhPymk=Whx))61B2+;6x@5y*XhpaqCi)B;k#x~Pj~rvgw;Opp~%?gLvqy8{7W z4a_l?$VwF|jTp#==BY8l%m6#$2Awi4WYeH)fS^E>%Ndbp{&9II5bcZxjkeAVh!7j4 zeWMUPR7q~_J<^RqC?Nr~(JE!4#Q#$;4K~lah`U2r60yXfva0# z6#4*XKrbi;9HEvMB?7;DA#~PM=V6fo86_=D8V_4UXGm|5#G}0OzdRE#CC~^ZE`}wS zL)Z7vjscV7u9Lt#h@bL}#`JGq145Kf#l&*$RaUzNeJq<;|dDuw~167=XhMj8C$U_Ao+nwMnM~cW))?JG@Gni zmg*<*$2wJ%R$g1f*$u)7rmEnJh>^)Kh-xgChxf?BN?vCm7Ml_YDrGc10Y(I3jM+|-VO!eJ^RizGpp0XF~@`R7*7r-GIzNL0;DvG52@A*!k^_Lix;gWqM%cP z>>IVo)a15tT!}h781t$=izXBKxZ%)YF>Hm~vOtw|X%lM;@Q(Y$Ro}2r~VR4b56mMm;nzcY05N`?!xm;zrz2Tw;f z1T;4&F&h-fA|QT>DpDN|yat65n>am3Ot-S{cI#68}R`@c@798UJAgLP!iBiS7d2#c_PKiNq{gwF? zR2FtvRa!DgkfLffL30#fLZ;>D4hg$O?gL+4fjLbMZ;a*6BFH2Bqg)NBC765+;xC_f zU^rrfUIz=@GZY{SVTLXOIKO;B#*nw%V__x&*aekW6gD&|Q${YB-PbUH|7C*vBq4*+ z=%~Yyl}wcI5O#W1RTMePUdvmkchHdhR#3r+a&7|?AQ{2Y?oflIFyOz?JZ)eSF%{&R z6m24atS-y~EV3--hfMNrmGuBlm^2o!R==R5sIJ(>IUo+fr{G}+gu$dt?|>G75;Znd zN9f!`iYl>?krb==>PWg%^p2{BlE+@HkwlTQm;ss^e?kRBuK{Xg7Da#L%{_Bq$XHEs z;B|1S!@`jW%=kz|hx}ww(E@(k2gp{Q>B5+U-@-+yLut<+)`S!m@dA#JtXrO?U?I{2OIRla0rw&)(L4Z#sSk(NJkTbr z!e<5L$RH+#5D(~8>JxKuXXQpwt(Wk6ji0B1xE|Cxs4;}jXzF1;d5Hl4!6tmdO2D9f z>-%siqM*5t2+vD>A1u=9mwZ$Cp%qgvWLQH5ZW;cCoEZ)M2Y}=`$dFRhbMq=OjI`T?Kde{it*;fsE>DT

1C}EjuiQ{0X5=O(KG|og0RysElDc~s4(SYrSm4` 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 N002ovPDHLkV1jo{v#J09 literal 0 HcmV?d00001 From 0aa9374ecb0e018f7d3cd10f4db7722c196253cd Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 15:45:27 +0200 Subject: [PATCH 25/54] Delete app-icon.js --- apps/pipboydate/app-icon.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 apps/pipboydate/app-icon.js diff --git a/apps/pipboydate/app-icon.js b/apps/pipboydate/app-icon.js deleted file mode 100644 index 935210156..000000000 --- a/apps/pipboydate/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -require("heatshrink").decompress(atob("mEwxH+AC4fDDjAuSgwACGFIuBhgACGAJjmLoQvDGAJkhbAguGGYwxbRAoAMGDZZMGBAvSbIpdSGCxYCW5jpDHhKSRDYQgGAwY8ETZYvPDZBXEAAwUFNAowOF44bFNJI2ENISRQdIqzLYhAxDAoRgScZgwFdow1DF54tQdpRMDF5jjHLiDxWF44wJBZIJFF5qPGF5blDLxIvPeAjsOF7RgCc6QvId6AvUd5QACF5pyEKAwlGF5qORcIwoFBgIwHFwwvTU4gvILxYuOXwouKA5AwGFxzuIDYYvkDQ6GIABKqEL6ryGF8QbHF6QXFX6wvuYIQvnFJgMBAAQva/wgMBQT4CF5QPCeB65CABgwCHxYuOF6L5JHYYuPSAyDFBRS6TMA4AME4RdHFyhgCLRLoJLzBgDExa7JFywwVFzQwTFwIADGDC5NRohDBSTQdCGCARCGDRNCGRQuFSobAYGAYxIFwoTDGKpMGWggADA4Q1FYipNGGA7NHYawVBD44qDGIbEHIwwlEA=")) From 0f73a3aa0f8a3d6b05d3b301b69e86567c49fa41 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 15:45:35 +0200 Subject: [PATCH 26/54] Delete app.js --- apps/pipboydate/app.js | 103 ----------------------------------------- 1 file changed, 103 deletions(-) delete mode 100644 apps/pipboydate/app.js diff --git a/apps/pipboydate/app.js b/apps/pipboydate/app.js deleted file mode 100644 index 48a87fc5d..000000000 --- a/apps/pipboydate/app.js +++ /dev/null @@ -1,103 +0,0 @@ -const bigFont = 4; -const smallFont = 2; -const tinyFont = 1; -const green = 0x0661; -const darkGreen = 0x0461; -const darkerGreen = 0x0261; -const pip = require("heatshrink").decompress(atob("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")); - -function topLine() { - - g.setColor(green); - g.setFontAlign(0, -1, 0); - - g.moveTo(0, 50).lineTo(30, 50); - g.lineTo(30, 40); - g.lineTo(35, 40).moveTo(90, 40).lineTo(95, 40); - g.lineTo(95, 50); - g.lineTo(239, 50); - - g.setFont("6x8", smallFont); - g.drawString("STAT", 65, 34); - g.drawString("INV", 130, 34); - g.drawString("DATA", 190, 34); - g.setColor(darkGreen); - g.drawString("STATUS", 45, 55); - g.drawString("SPEC", 122, 55); - g.drawString("PERKS", 195, 55); -} - -function bottomLine() { - - //first line - g.setColor(darkerGreen); - g.fillRect(5, 175, 100, 185); //DATE - g.fillRect(105, 175, 160, 185);//STIM - g.fillRect(166, 175, 239, 185); // RADAWAY - - g.setColor(green); - g.setFont("6x8", tinyFont); - g.drawString("DATE", 20, 177); - g.drawString("STIM (3)", 135, 177); - g.drawString("RADAWAY (8)", 205, 177); - - //second line - g.setColor(darkerGreen); - g.fillRect(5, 190, 70, 200); - g.fillRect(75, 190, 239, 200); - - g.setColor(green); - g.drawString("HP 115/115", 38, 192); - g.drawString("LEVEL 6", 100, 192); - g.drawRect(127, 192, 235, 198); -} - -function boy() { - g.drawImage(pip, 165, 85); -} - -function drawClock() { - - var t = new Date(); - var h = t.getHours(); - var m = t.getMinutes(); - var dd = t.getDate(); - var mm = t.getMonth()+1; //month is zero-based - var yy = t.getFullYear(); - var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2); - - //create date string - if (dd.toString().length < 2) dd = '0' + dd; - if (mm.toString().length < 2) mm = '0' + mm; - var date = dd + "." + mm + "." + yy; - - g.setFont("6x8",bigFont); - g.setColor(green); - g.setFontAlign(0, -1, 0); - - g.clearRect(0, 110, 150, 140); - g.drawString(time, 70, 110); - - //draw date - g.setFont("6x8", tinyFont); - g.drawString(date, 67, 177); -} - -function drawAll() { - topLine(); - boy(); - bottomLine(); - drawClock(); -} - -Bangle.on('lcdPower', function(on) { - if (on) drawAll(); -}); - -g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -setInterval(drawClock, 1E4); -drawAll(); - -setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); From a03280c9cf58ee6ad8744cf8ec02988c577557d5 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 15:45:44 +0200 Subject: [PATCH 27/54] Delete app.png --- apps/pipboydate/app.png | Bin 12431 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/pipboydate/app.png diff --git a/apps/pipboydate/app.png b/apps/pipboydate/app.png deleted file mode 100644 index 018b5c7bb8dd8a8a0dcba32fa0450695d92bd67f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12431 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

1C}EjuiQ{0X5=O(KG|og0RysElDc~s4(SYrSm4` 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 N002ovPDHLkV1jo{v#J09 From e7282f87769413ad44a953126c2e45fc48c14c19 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 16:46:58 +0200 Subject: [PATCH 28/54] Create ChangeLog --- apps/pipboy/ChangeLog | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 apps/pipboy/ChangeLog diff --git a/apps/pipboy/ChangeLog b/apps/pipboy/ChangeLog new file mode 100644 index 000000000..134ba4e18 --- /dev/null +++ b/apps/pipboy/ChangeLog @@ -0,0 +1,2 @@ +0.01: New Watch! +0.02: Changed colors for better readability and added current date From 02e9f6b285cb53809702ff04a0ae2326d750a2d4 Mon Sep 17 00:00:00 2001 From: Purple-Tentacle <59914607+Purple-Tentacle@users.noreply.github.com> Date: Mon, 30 Mar 2020 16:52:22 +0200 Subject: [PATCH 29/54] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 1d1c911ca..8e1679ebd 100644 --- a/apps.json +++ b/apps.json @@ -803,7 +803,7 @@ "id": "pipboy", "name": "Pipboy", "icon": "app.png", - "version": "0.01", + "version": "0.02", "description": "Pipboy themed clock", "tags": "clock", "type":"clock", From 7ff958ad2cc35d620eeb2a6a9191854d0b657f66 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 30 Mar 2020 16:23:45 +0100 Subject: [PATCH 30/54] Fixing sanitycheck errors from recent PRs --- apps.json | 7 ++++--- apps/grocery/grocery-icon.js | 1 + apps/swatch/ChangeLog | 10 +++++----- bin/sanitycheck.js | 4 +++- 4 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 apps/grocery/grocery-icon.js diff --git a/apps.json b/apps.json index 8e1679ebd..2110078f6 100644 --- a/apps.json +++ b/apps.json @@ -837,7 +837,7 @@ {"name":"widid.wid.js","url":"widget.js"} ] }, - { + { "id": "grocery", "name": "Grocery", "icon": "grocery.png", @@ -848,13 +848,14 @@ "custom":"grocery.html", "storage": [ {"name":"grocery"}, - {"name":"grocery.app.js"} + {"name":"grocery.app.js"}, + {"name":"grocery.img","url":"grocery-icon.js","evaluate":true} ] }, { "id": "marioclock", "name": "Mario Clock", "icon": "marioclock.png", - "version":"0.01", + "version":"0.02", "description": "Animated Mario clock, jumps to change the time!", "tags": "clock,mario,retro", "type": "clock", diff --git a/apps/grocery/grocery-icon.js b/apps/grocery/grocery-icon.js new file mode 100644 index 000000000..949b0e45b --- /dev/null +++ b/apps/grocery/grocery-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwhC/AFEEolAC6lN7vdDCcECwPd6guVGCYuDC4cCBQMikQXQJAMjkECmcyIx4XDmUjmYvLC4XUDARHBIoIWLgATCGQdA7tEonQC5ouDDYg0BOxgSEAggwKRwgUCC6ZIDSwoXNogWDDgNCAgIWIkUEoUk6kiCgMkokipsiBIQXIki2CAgNCAoYADC5Eic4Mic4ICCAIIJCC5MzAAcykYGEAAIXOABAXTmUzGoIXVAIIXLB4SICDIovjO76PZbYR3PDI4XiI6530MIh3SC6R33C/oAOC48CCxsgC44A/ADY=")) diff --git a/apps/swatch/ChangeLog b/apps/swatch/ChangeLog index d907766c1..86a782585 100644 --- a/apps/swatch/ChangeLog +++ b/apps/swatch/ChangeLog @@ -1,5 +1,5 @@ -0.01 Original App -0.02 Lap log now counts up from 1 - Lap log now scrolls into 2nd column after 18th entry, able to display 36 entries before going off screen -0.03 Added ability to save Lap log as a date named JSON file into memory - Fixed bug from 0.01 where BN1 (reset) could clear the lap log when timer is running +0.01: Original App +0.02: Lap log now counts up from 1 + Lap log now scrolls into 2nd column after 18th entry, able to display 36 entries before going off screen +0.03: Added ability to save Lap log as a date named JSON file into memory + Fixed bug from 0.01 where BN1 (reset) could clear the lap log when timer is running diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index d911a20d6..d55bba4c8 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -51,7 +51,9 @@ apps.forEach((app,addIdx) => { if (app.version != "0.01") WARN(`App ${app.id} has no ChangeLog`); } else { - var versions = fs.readFileSync(appDir+"ChangeLog").toString().match(/\d+\.\d+:/g); + var changeLog = fs.readFileSync(appDir+"ChangeLog").toString(); + var versions = changeLog.match(/\d+\.\d+:/g); + if (!versions) ERROR(`No versions found in ${app.id} ChangeLog (${appDir}ChangeLog)`); var lastChangeLog = versions.pop().slice(0,-1); if (lastChangeLog != app.version) WARN(`App ${app.id} app version (${app.version}) and ChangeLog (${lastChangeLog}) don't agree`); From 83b5b9b8aa80519d6f7ffa985f759cc1f2d72a96 Mon Sep 17 00:00:00 2001 From: Nik Martin Date: Mon, 30 Mar 2020 10:37:59 -0500 Subject: [PATCH 31/54] aclock refactor and updates To get my feet wet with Espruino and my new Bangle.js, I dove into the analog clock code and enhanced and refactored a few things to simplify the interface, fix a few bugs, and improve readability: added date added distinct hour markers refactor timers down to a single timer add elapsed seconds display add date --- apps/aclock/clock-analog.js | 188 +++++++++++++++++++++++------------- 1 file changed, 120 insertions(+), 68 deletions(-) diff --git a/apps/aclock/clock-analog.js b/apps/aclock/clock-analog.js index 67061af52..af8f88064 100644 --- a/apps/aclock/clock-analog.js +++ b/apps/aclock/clock-analog.js @@ -1,94 +1,146 @@ -const p = Math.PI/2; -const PRad = Math.PI/180; +let g; +let Bangle; -let intervalRefMin = null; -let intervalRefSec = null; +const p = Math.PI / 2; +const pRad = Math.PI / 180; +const faceWidth = 100; // watch face radius +let timer = null; +let currentDate = new Date(); +const centerPx = g.getWidth() / 2; -let minuteDate = new Date(); -let secondDate = new Date(); +const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat']; -function seconds(angle, r) { - const a = angle*PRad; - const x = 120+Math.sin(a)*r; - const y = 120-Math.cos(a)*r; - g.fillRect(x-1,y-1,x+1,y+1); -} -function hand(angle, r1,r2) { - const a = angle*PRad; +const seconds = (angle) => { + const a = angle * pRad; + const x = centerPx + Math.sin(a) * faceWidth; + const y = centerPx - Math.cos(a) * faceWidth; + + // if 15 degrees, make hour marker larger + const radius = (angle % 15) ? 2 : 4; + g.fillCircle(x, y, radius); +}; + +const hand = (angle, r1, r2) => { + const a = angle * pRad; const r3 = 3; - g.fillPoly([ - 120+Math.sin(a)*r1, - 120-Math.cos(a)*r1, - 120+Math.sin(a+p)*r3, - 120-Math.cos(a+p)*r3, - 120+Math.sin(a)*r2, - 120-Math.cos(a)*r2, - 120+Math.sin(a-p)*r3, - 120-Math.cos(a-p)*r3]); -} -function drawAll() { + g.fillPoly([ + Math.round(centerPx + Math.sin(a) * r1), + Math.round(centerPx - Math.cos(a) * r1), + Math.round(centerPx + Math.sin(a + p) * r3), + Math.round(centerPx - Math.cos(a + p) * r3), + Math.round(centerPx + Math.sin(a) * r2), + Math.round(centerPx - Math.cos(a) * r2), + Math.round(centerPx + Math.sin(a - p) * r3), + Math.round(centerPx - Math.cos(a - p) * r3) + ]); +}; + +const drawAll = () => { g.clear(); - secondDate = minuteDate = new Date(); + currentDate = new Date(); // draw hands first onMinute(); // draw seconds - g.setColor(0,0,0.6); - for (let i=0;i<60;i++) - seconds(360*i/60, 90); + const currentSec = currentDate.getSeconds(); + // draw all secs + + for (let i = 0; i < 60; i++) { + if (i > currentSec) { + g.setColor(0, 0, 0.6); + } else { + g.setColor(0.3, 0.3, 1); + } + seconds((360 * i) / 60); + } onSecond(); -} +}; -function onSecond() { - g.setColor(0,0,0.6); - seconds(360*secondDate.getSeconds()/60, 90); - g.setColor(1,0,0); - secondDate = new Date(); - seconds(360*secondDate.getSeconds()/60, 90); - g.setColor(1,1,1); +const resetSeconds = () => { + g.setColor(0, 0, 0.6); + for (let i = 0; i < 60; i++) { + seconds((360 * i) / 60); + } +}; -} +const onSecond = () => { + g.setColor(0.3, 0.3, 1); + seconds((360 * currentDate.getSeconds()) / 60); + if (currentDate.getSeconds() === 59) { + resetSeconds(); + onMinute(); + } + g.setColor(1, 0.7, 0.2); + currentDate = new Date(); + seconds((360 * currentDate.getSeconds()) / 60); + g.setColor(1, 1, 1); +}; -function onMinute() { - g.setColor(0,0,0); - hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -10, 50); - hand(360*minuteDate.getMinutes()/60, -10, 82); - minuteDate = new Date(); - g.setColor(1,1,1); - hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -10, 50); - hand(360*minuteDate.getMinutes()/60, -10, 82); - if(minuteDate.getHours() >= 0 && minuteDate.getMinutes() === 0) { +const drawDate = () => { + g.reset(); + g.setColor(1, 0, 0); + g.setFont('6x8', 2); + + const dayString = days[currentDate.getDay()]; + // pad left date + const dateString = (currentDate.getDate() < 10) ? '0' : '' + currentDate.getDate().toString(); + const dateDisplay = `${dayString}-${dateString}`; + // console.log(`${dayString}|${dateString}`); + // center date + const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2; + const t = centerPx + 37; + g.drawString(dateDisplay, l, t); + // console.log(l, t); +}; +const onMinute = () => { + if (currentDate.getHours() === 0 && currentDate.getMinutes() === 0) { + g.clear(); + resetSeconds(); + } + // clear existing hands + g.setColor(0, 0, 0); + // Hour + hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35); + // Minute + hand((360 * currentDate.getMinutes()) / 60, -8, faceWidth - 10); + + // get new date, then draw new hands + currentDate = new Date(); + g.setColor(1, 0.9, 0.9); + // Hour + hand((360 * (currentDate.getHours() + currentDate.getMinutes() / 60)) / 12, -8, faceWidth - 35); + g.setColor(1, 1, 0.9); + // Minute + hand((360 * currentDate.getMinutes()) / 60, -8, faceWidth - 10); + if (currentDate.getHours() >= 0 && currentDate.getMinutes() === 0) { Bangle.buzz(); } -} + drawDate(); +}; -function clearTimers() { - if(intervalRefMin) {clearInterval(intervalRefMin);} - if(intervalRefSec) {clearInterval(intervalRefSec);} -} +const startTimers = () => { + timer = setInterval(onSecond, 1000); +}; -function startTimers() { - minuteDate = new Date(); - secondDate = new Date(); - intervalRefSec = setInterval(onSecond,1000); - intervalRefMin = setInterval(onMinute,60*1000); - drawAll(); -} - -Bangle.on('lcdPower',function(on) { +Bangle.on('lcdPower', (on) => { if (on) { - g.clear(); - Bangle.drawWidgets(); + // g.clear(); + drawAll(); startTimers(); - }else { - clearTimers(); + Bangle.drawWidgets(); + } else { + if (timer) { + clearInterval(timer); + } } }); g.clear(); +resetSeconds(); +startTimers(); +drawAll(); Bangle.loadWidgets(); Bangle.drawWidgets(); -drawAll(); -startTimers(); + // Show launcher when middle button pressed -setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); +setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); From 655488dc35a156a93e0d11e598fadd5c37400289 Mon Sep 17 00:00:00 2001 From: Nik Martin Date: Mon, 30 Mar 2020 10:48:22 -0500 Subject: [PATCH 32/54] update apps.json vBump aclock to 0.10 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 2110078f6..1d9b82a04 100644 --- a/apps.json +++ b/apps.json @@ -133,7 +133,7 @@ { "id": "aclock", "name": "Analog Clock", "icon": "clock-analog.png", - "version":"0.02", + "version":"0.10", "description": "An Analog Clock", "tags": "clock", "type":"clock", From 7070536dff46aaa3468484fa5a1190a9411d11f9 Mon Sep 17 00:00:00 2001 From: Nik Martin Date: Mon, 30 Mar 2020 12:09:46 -0500 Subject: [PATCH 33/54] add locales to Date display --- apps/aclock/clock-analog.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/aclock/clock-analog.js b/apps/aclock/clock-analog.js index af8f88064..419ed0933 100644 --- a/apps/aclock/clock-analog.js +++ b/apps/aclock/clock-analog.js @@ -1,6 +1,8 @@ let g; let Bangle; +// http://forum.espruino.com/conversations/345155/#comment15172813 +const locale = require('locale'); const p = Math.PI / 2; const pRad = Math.PI / 180; const faceWidth = 100; // watch face radius @@ -8,8 +10,6 @@ let timer = null; let currentDate = new Date(); const centerPx = g.getWidth() / 2; -const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat']; - const seconds = (angle) => { const a = angle * pRad; const x = centerPx + Math.sin(a) * faceWidth; @@ -81,7 +81,7 @@ const drawDate = () => { g.setColor(1, 0, 0); g.setFont('6x8', 2); - const dayString = days[currentDate.getDay()]; + const dayString = locale.dow(currentDate, true); // pad left date const dateString = (currentDate.getDate() < 10) ? '0' : '' + currentDate.getDate().toString(); const dateDisplay = `${dayString}-${dateString}`; From 277132e2a497383863a8ac33aa49400f32bd57cf Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Mon, 30 Mar 2020 21:34:44 +0200 Subject: [PATCH 34/54] Create Bar Clock --- apps.json | 13 +++++ apps/barclock/ChangeLog | 1 + apps/barclock/clock-bar-icon.js | 1 + apps/barclock/clock-bar.js | 99 ++++++++++++++++++++++++++++++++ apps/barclock/clock-bar.png | Bin 0 -> 159 bytes 5 files changed, 114 insertions(+) create mode 100644 apps/barclock/ChangeLog create mode 100644 apps/barclock/clock-bar-icon.js create mode 100644 apps/barclock/clock-bar.js create mode 100644 apps/barclock/clock-bar.png diff --git a/apps.json b/apps.json index 2110078f6..d42bc2c11 100644 --- a/apps.json +++ b/apps.json @@ -875,5 +875,18 @@ "storage": [ {"name":"widver.wid.js","url":"widget.js"} ] + }, + { "id": "barclock", + "name": "Bar Clock", + "icon": "clock-bar.png", + "version":"0.01", + "description": "A simple 24h digital clock showing seconds as a bar", + "tags": "clock", + "type":"clock", + "allow_emulator":true, + "storage": [ + {"name":"barclock.app.js","url":"clock-bar.js"}, + {"name":"barclock.img","url":"clock-bar-icon.js","evaluate":true} + ] } ] diff --git a/apps/barclock/ChangeLog b/apps/barclock/ChangeLog new file mode 100644 index 000000000..83b3133da --- /dev/null +++ b/apps/barclock/ChangeLog @@ -0,0 +1 @@ +0.01: Created Bar Clock diff --git a/apps/barclock/clock-bar-icon.js b/apps/barclock/clock-bar-icon.js new file mode 100644 index 000000000..29bf0f481 --- /dev/null +++ b/apps/barclock/clock-bar-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgJC/AD8Mgfwh/AhgFFngHBOIM8AovMDIXA5gFFDoUAmYjDAocMSoMz/4FF//P/g1CAopTLDAIABwAFGAH4AfA")) diff --git a/apps/barclock/clock-bar.js b/apps/barclock/clock-bar.js new file mode 100644 index 000000000..100f66db1 --- /dev/null +++ b/apps/barclock/clock-bar.js @@ -0,0 +1,99 @@ +/* jshint esversion: 6 */ +/** + * A simple 24h digital clock showing seconds as a bar + **/ +{ + const timeFont = '6x8' + const timeFontSize = 8 // 'hh:mm' fits exactly + const dateFont = 'Vector' + const dateFontSize = 20 + + const screenSize = g.getWidth() + const screenCenter = screenSize / 2 + + const timeY = screenCenter + const barY = 155 // just below time + const barThickness = 6 // matches time digit size + const dateY = screenSize - dateFontSize // at bottom of screen + + const SECONDS_PER_MINUTE = 60 + + function timeText(date) { + const d = date.toString().split(' ') + const time = d[4].substr(0, 5) + const t = time.split(':') + const hours = t[0], + minutes = t[1] + return `${hours}:${minutes}` + } + + function dateText(date) { + const d = date.toString().split(' ') + const dayName = d[0], + month = d[1], + day = d[2] + return `${dayName} ${day} ${month}` + } + + function drawDateTime(date) { + g.setFontAlign(0, 0) // centered + + g.setFont(timeFont, timeFontSize) + g.drawString(timeText(date), screenCenter, timeY, true) + + g.setFont(dateFont, dateFontSize) + g.drawString(dateText(date), screenCenter, dateY, true) + } + + function drawBar(date) { + const seconds = date.getSeconds() + const fraction = seconds / SECONDS_PER_MINUTE + g.fillRect(0, barY, fraction * screenSize, barY + barThickness) + } + function eraseBar() { + const color = g.getColor() + g.setColor(g.getBgColor()) + g.fillRect(0, barY, screenSize, barY + barThickness) + g.setColor(color) + } + + let lastSeconds + function tick() { + g.reset() + const date = new Date() + const seconds = date.getSeconds() + if (lastSeconds > seconds) { + // new minute + eraseBar() + drawDateTime(date) + } + drawBar(date) + + lastSeconds = seconds + } + + let iTick + function start() { + lastSeconds = 99 // force redraw + tick() + iTick = setInterval(tick, 1000) + } + function stop() { + if (iTick) { + clearInterval(iTick) + iTick = undefined + } + } + + // clean app screen + g.clear() + Bangle.loadWidgets() + Bangle.drawWidgets() + // Show launcher when middle button pressed + setWatch(Bangle.showLauncher, BTN2, {repeat: false, edge: 'falling'}) + + Bangle.on('lcdPower', function (on) { + on ? start() : stop() + }) + start() +} diff --git a/apps/barclock/clock-bar.png b/apps/barclock/clock-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..a580cae69c0b08824b0a0540a691bb636ace9045 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDH3?y^UWFG-iYymzYu0Z<#|Nl#G&c6#}aTa() z7BevDDT6R$#Zvn+prE~{i(`ny<>Z6~#t#zz9jI?$cf0xFgM`G511pRj9x|sVhy-vp z8}iS2lxSe^kALyM`TvAoWE-G$nj`63{3HPgg&ebxsLQ0OcVv A;{X5v literal 0 HcmV?d00001 From 6176c16712136a9ca5d09830bb12a0b4ae88d5bb Mon Sep 17 00:00:00 2001 From: DerGuteWolf Date: Mon, 30 Mar 2020 23:52:41 +0200 Subject: [PATCH 35/54] marioclock: use short date format from locale, take timeout from settings --- apps/marioclock/marioclock-app.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/marioclock/marioclock-app.js b/apps/marioclock/marioclock-app.js index 248b15387..c0ada5e59 100644 --- a/apps/marioclock/marioclock-app.js +++ b/apps/marioclock/marioclock-app.js @@ -6,6 +6,9 @@ **********************************/ var locale = require("locale"); +const storage = require('Storage'); +const settings = (storage.readJSON('setting.json',1)||{}); +const timeout = settings.timeout||10; // Screen dimensions let W, H; @@ -280,14 +283,10 @@ function drawTime() { } function drawDate() { - const date = new Date(); - const day = locale.dow(date).substr(0, 3); - const dayNum = ("0" + date.getDate()).substr(-2); - const month = locale.month(date).substr(0, 3); - g.setFont("6x8"); g.setColor(LIGHTEST); - g.drawString(`${day} ${dayNum} ${month}`, 10, 0, true); + const dateStr = locale.date(new Date(), true); + g.drawString(dateStr, (W - g.stringWidth(dateStr))/2, 0, true); } function redraw() { @@ -322,7 +321,7 @@ function resetDisplayTimeout() { displayTimeoutRef = setInterval(() => { if (Bangle.isLCDOn()) Bangle.setLCDPower(false); clearTimers(); - }, ONE_SECOND * 10); + }, ONE_SECOND * timeout); } function startTimers(){ From 249eead69baf85ff8561a63b916c35178b451fd4 Mon Sep 17 00:00:00 2001 From: DerGuteWolf Date: Mon, 30 Mar 2020 23:54:37 +0200 Subject: [PATCH 36/54] Update ChangeLog --- apps/marioclock/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/marioclock/ChangeLog b/apps/marioclock/ChangeLog index e81e2f78c..79f103c48 100644 --- a/apps/marioclock/ChangeLog +++ b/apps/marioclock/ChangeLog @@ -1,2 +1,3 @@ 0.01: Create mario app 0.02: Fix day of the week and add padding +0.03: use short date format from locale, take timeout from settings From 0e8f9405d38c1211b864daf4c2581d428e9ca108 Mon Sep 17 00:00:00 2001 From: DerGuteWolf Date: Mon, 30 Mar 2020 23:55:56 +0200 Subject: [PATCH 37/54] Update apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 2110078f6..a24d3babd 100644 --- a/apps.json +++ b/apps.json @@ -855,7 +855,7 @@ { "id": "marioclock", "name": "Mario Clock", "icon": "marioclock.png", - "version":"0.02", + "version":"0.03", "description": "Animated Mario clock, jumps to change the time!", "tags": "clock,mario,retro", "type": "clock", From 54346977c4d5f5265084042b4a95fd4cef6cff10 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 31 Mar 2020 00:05:00 +0200 Subject: [PATCH 38/54] Bar clock 0.02: Apply locale, 12-hour setting Plus minor bar drawing improvement --- apps.json | 4 +-- apps/barclock/ChangeLog | 1 + apps/barclock/clock-bar.js | 58 ++++++++++++++++++++++++++++---------- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/apps.json b/apps.json index d42bc2c11..4958d039b 100644 --- a/apps.json +++ b/apps.json @@ -879,8 +879,8 @@ { "id": "barclock", "name": "Bar Clock", "icon": "clock-bar.png", - "version":"0.01", - "description": "A simple 24h digital clock showing seconds as a bar", + "version":"0.02", + "description": "A simple digital clock showing seconds as a bar", "tags": "clock", "type":"clock", "allow_emulator":true, diff --git a/apps/barclock/ChangeLog b/apps/barclock/ChangeLog index 83b3133da..a8d2f5485 100644 --- a/apps/barclock/ChangeLog +++ b/apps/barclock/ChangeLog @@ -1 +1,2 @@ 0.01: Created Bar Clock +0.02: Apply locale, 12-hour setting diff --git a/apps/barclock/clock-bar.js b/apps/barclock/clock-bar.js index 100f66db1..5ab9c433e 100644 --- a/apps/barclock/clock-bar.js +++ b/apps/barclock/clock-bar.js @@ -1,10 +1,23 @@ /* jshint esversion: 6 */ /** - * A simple 24h digital clock showing seconds as a bar + * A simple digital clock showing seconds as a bar **/ { + // Check settings for what type our clock should be + const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour'] + const locale = require('locale') + { // add some more info to locale + let date = new Date() + date.setFullYear(1111) + date.setMonth(1, 3) // februari: months are zero-indexed + const localized = locale.date(date, true) + locale.dayFirst = /3.*2/.test(localized) + locale.hasMeridian = (locale.meridian(date) !== '') + } + const timeFont = '6x8' - const timeFontSize = 8 // 'hh:mm' fits exactly + const timeFontSize = (is12Hour && locale.hasMeridian) ? 6 : 8 + const ampmFontSize = 2 const dateFont = 'Vector' const dateFontSize = 20 @@ -18,35 +31,50 @@ const SECONDS_PER_MINUTE = 60 + function timeText(date) { - const d = date.toString().split(' ') - const time = d[4].substr(0, 5) - const t = time.split(':') - const hours = t[0], - minutes = t[1] - return `${hours}:${minutes}` + if (!is12Hour) { + return {time: locale.time(date, true), ampm: ''} + } + const meridian = locale.meridian(date) + const hours = date.getHours() + if (hours === 0) { + date.setHours(12) + } else if (hours > 12) { + date.setHours(hours - 12) + } + return {time: locale.time(date, true), ampm: meridian} } function dateText(date) { - const d = date.toString().split(' ') - const dayName = d[0], - month = d[1], - day = d[2] - return `${dayName} ${day} ${month}` + const dayName = locale.dow(date, true), + month = locale.month(date, true), + day = date.getDate() + return `${dayName} ` + (locale.dayFirst ? `${day} ${month}` : `${month} ${day}`) } function drawDateTime(date) { + const timeTexts = timeText(date) g.setFontAlign(0, 0) // centered - g.setFont(timeFont, timeFontSize) - g.drawString(timeText(date), screenCenter, timeY, true) + g.drawString(timeTexts.time, screenCenter, timeY, true) + if (timeTexts.ampm !== '') { + g.setFontAlign(1, -1) + g.setFont(timeFont, ampmFontSize) + g.drawString(timeTexts.ampm, + // at right edge of screen , aligned with time bottom + (screenSize - ampmFontSize * 2), (timeY + timeFontSize - ampmFontSize), + true) + } + g.setFontAlign(0, 0) // centered g.setFont(dateFont, dateFontSize) g.drawString(dateText(date), screenCenter, dateY, true) } function drawBar(date) { const seconds = date.getSeconds() + if (seconds === 0) return; // zero-size rect stills draws one line of pixels const fraction = seconds / SECONDS_PER_MINUTE g.fillRect(0, barY, fraction * screenSize, barY + barThickness) } From e56035c7c9a3be5dbd626f1ebe544dd3aefa6cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Luk=C3=A1cs?= Date: Tue, 31 Mar 2020 13:17:59 +0200 Subject: [PATCH 39/54] Wrong long date pattern for HU locale ooops :) --- apps/locale/locales.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/locale/locales.js b/apps/locale/locales.js index e28d285da..a326d72a8 100644 --- a/apps/locale/locales.js +++ b/apps/locale/locales.js @@ -348,7 +348,7 @@ var locales = { temperature: '°C', ampm: {0:"de",1:"du"}, timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" }, - datePattern: { 0: "%Y %d %b", 1: "%Y.%m.%d" }, // 2020 Feb 28" // "2020.03.01."(short) + datePattern: { 0: "%Y %b %d, %A", 1: "%Y.%m.%d" }, // 2020 Feb 28, Péntek" // "2020.03.01."(short) abmonth: "Jan,Feb,Már,Ápr,Máj,Jún,Júl,Aug,Szep,Okt,Nov,Dec", month: "Január,Február,Március,Április,Május,Június,Július,Augusztus,Szeptember,Október,November,December", abday: "Vas,Hét,Ke,Szer,Csüt,Pén,Szom", From b40c9031e13d206f751442e5eb410a9fb90a1b95 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 31 Mar 2020 13:18:31 +0100 Subject: [PATCH 40/54] refactor - move JS into its own directory --- index.html | 8 ++++---- appinfo.js => js/appinfo.js | 0 comms.js => js/comms.js | 0 index.js => js/index.js | 0 utils.js => js/utils.js | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename appinfo.js => js/appinfo.js (100%) rename comms.js => js/comms.js (100%) rename index.js => js/index.js (100%) rename utils.js => js/utils.js (100%) diff --git a/index.html b/index.html index c256360e7..5ad76064d 100644 --- a/index.html +++ b/index.html @@ -128,10 +128,10 @@ - - - - + + + + diff --git a/appinfo.js b/js/appinfo.js similarity index 100% rename from appinfo.js rename to js/appinfo.js diff --git a/comms.js b/js/comms.js similarity index 100% rename from comms.js rename to js/comms.js diff --git a/index.js b/js/index.js similarity index 100% rename from index.js rename to js/index.js diff --git a/utils.js b/js/utils.js similarity index 100% rename from utils.js rename to js/utils.js From 91e78238bbe418b2efa5d8d3c216eeaf62865adc Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 31 Mar 2020 13:18:50 +0100 Subject: [PATCH 41/54] Remove un-needed dependency --- index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/index.html b/index.html index 5ad76064d..efaf84a61 100644 --- a/index.html +++ b/index.html @@ -132,6 +132,5 @@ - From 174cc6d7cfdc5de5877d60e9c042620c2ab5cc52 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 31 Mar 2020 13:19:40 +0100 Subject: [PATCH 42/54] Remove firmware js - basically guaranteed to be out of date --- firmware.js | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 firmware.js diff --git a/firmware.js b/firmware.js deleted file mode 100644 index 2a3a697a3..000000000 --- a/firmware.js +++ /dev/null @@ -1,32 +0,0 @@ -// Generated by BangleApps/bin/firmwaremaker.js -reset(1) -var FAIL=0; -require('Storage').write(".boot0","// This ALWAYS runs at boot\nE.setFlags({pretokenise:1});\n// Load settings...\nvar s = require('Storage').readJSON('setting.json',1)||{};\nif (s.ble!==false) {\n if (s.HID) { // Human interface device\n Bangle.HID = E.toUint8Array(atob(\"BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA==\"));\n NRF.setServices({}, {uart:true, hid:Bangle.HID});\n }\n}\nif (s.blerepl===false) { // If not programmable, force terminal off Bluetooth\n if (s.log) Terminal.setConsole(true); // if showing debug, force REPL onto terminal\n else E.setConsole(null,{force:true}); // on new (2v05+) firmware we have E.setConsole which allows a 'null' console\n} else {\n if (s.log) Terminal.setConsole(); // if showing debug, put REPL on terminal (until connection)\n else Bluetooth.setConsole(true); // else if no debug, force REPL to Bluetooth\n}\n// we just reset, so BLE should be on.\n// Don't disconnect if something is already connected to us\nif (s.ble===false && !NRF.getSecurityStatus().connected) NRF.sleep();\n// Set time, vibrate, beep, etc\nif (!s.vibrate) Bangle.buzz=Promise.resolve;\nif (!s.beep) Bangle.beep=Promise.resolve;\nBangle.setLCDTimeout(s.timeout);\nif (!s.timeout) Bangle.setLCDPower(1);\nE.setTimeZone(s.timezone);\ndelete s;\n// check for alarms\nvar alarms = require('Storage').readJSON('alarm.json',1)||[];\nvar time = new Date();\nvar active = alarms.filter(a=>a.on&&(a.last!=time.getDate()));\nif (active.length) {\n active = active.sort((a,b)=>a.hr-b.hr);\n var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);\n if (!require('Storage').read(\"alarm.js\")) {\n console.log(\"No alarm app!\");\n require('Storage').write('alarm.json',\"[]\")\n } else {\n var t = 3600000*(active[0].hr-hr);\n if (t<1000) t=1000;\n /* execute alarm at the correct time. We avoid execing immediately\n since this code will get called AGAIN when alarm.js is loaded. alarm.js\n will then clearInterval() to get rid of this call so it can proceed\n normally. */\n setTimeout(function() {\n load(\"alarm.js\");\n },t);\n }\n}\n"); -require('Storage').write(".bootcde","// This runs after a 'fresh' boot\nvar settings=require(\"Storage\").readJSON('setting.json',1)||{};\nif (!settings.welcomed && require(\"Storage\").read(\"welcome.js\")!==undefined) {\n setTimeout(()=>load(\"welcome.js\"));\n} else {\n // load clock if specified\n var clockApp = settings.clock;\n if (clockApp) clockApp = require(\"Storage\").read(clockApp)\n if (!clockApp) {\n var clockApps = require(\"Storage\").list(/\\.info$/).map(app=>require(\"Storage\").readJSON(app,1)||{}).filter(app=>app.type==\"clock\").sort((a, b) => a.sortorder - b.sortorder);\n if (clockApps && clockApps.length > 0)\n clockApp = require(\"Storage\").read(clockApps[0].src);\n delete clockApps;\n }\n if (!clockApp) clockApp='E.showMessage(\"No Clock Found\")';\n delete settings;\n // check to see if our clock is wrong - if it is use GPS time\n if ((new Date()).getFullYear()==1970) {\n E.showMessage(\"Searching for\\nGPS time\");\n Bangle.on('GPS',function cb(g) {\n Bangle.setGPSPower(0);\n Bangle.removeListener(\"GPS\",cb);\n if (!g.time || (g.time.getFullYear()<2000) ||\n (g.time.getFullYear()==2250)) {\n // GPS receiver's time not set - just boot clock anyway\n eval(clockApp);delete clockApp;\n return;\n }\n // We have a GPS time. Set time and reboot (to load alarms properly)\n setTime(g.time.getTime()/1000);\n load();\n });\n Bangle.setGPSPower(1);\n } else {\n eval(clockApp);\n delete clockApp;\n }\n}\n"); -require('Storage').write("boot.info","{\"id\":\"boot\",\"name\":\"Bootloader\",\"type\":\"bootloader\",\"sortorder\":-10,\"version\":\"0.09\",\"files\":\"boot.info,.boot0,.bootcde\"}"); -require('Storage').write("launch.app.js","var s = require(\"Storage\");\nvar apps = s.list(/\\.info$/).map(app=>s.readJSON(app,1)||{name:\"DEAD: \"+app.substr(1)}).filter(app=>app.type==\"app\" || app.type==\"clock\" || !app.type);\napps.sort((a,b)=>{\n var n=(0|a.sortorder)-(0|b.sortorder);\n if (n) return n; // do sortorder first\n if (a.nameb.name) return 1;\n return 0;\n});\nvar selected = 0;\nvar menuScroll = 0;\nvar menuShowing = false;\n\nfunction drawMenu() {\n g.setFont(\"6x8\",2);\n g.setFontAlign(-1,0);\n var n = 3;\n if (selected>=n+menuScroll) menuScroll = 1+selected-n;\n if (selectedn+menuScroll) g.fillPoly([120,239,100,219,140,219]);\n else g.clearRect(100,219,140,239);\n for (var i=0;i0) {\n selected--;\n drawMenu();\n }\n}, BTN1, {repeat:true});\nsetWatch(function() {\n if (selected+1[],\n\"0\":n=>[\n[n,0,1,0],\n[1,0,1,1],\n[1,1,1,2],\n[n,2,1,2],\n[n,1,n,2],\n[n,0,n,1]],\n\"1\":n=>[\n[1-n,0,1,0],\n[1,0,1,1],\n[1-n,1,1,1],\n[1-n,1,1-n,2],\n[1-n,2,1,2]],\n\"2\":n=>[\n[0,0,1,0],\n[1,0,1,1],\n[0,1,1,1],\n[0,1+n,0,2],\n[1,2-n,1,2],\n[0,2,1,2]],\n\"3\":n=>[\n[0,0,1-n,0],\n[0,0,0,n],\n[1,0,1,1],\n[0,1,1,1],\n[1,1,1,2],\n[n,2,1,2]],\n\"4\":n=>[\n[0,0,0,1],\n[1,0,1-n,0],\n[1,0,1,1-n],\n[0,1,1,1],\n[1,1,1,2],\n[1-n,2,1,2]],\n\"5\": (n,maxFive)=>maxFive ? [ // 5 -> 0\n[0,0,0,1],\n[0,0,1,0],\n[n,1,1,1],\n[1,1,1,2],\n[0,2,1,2],\n[0,2,0,2],\n[1,1-n,1,1],\n[0,1,0,1+n]] : [ // 5 -> 6\n[0,0,0,1],\n[0,0,1,0],\n[0,1,1,1],\n[1,1,1,2],\n[0,2,1,2],\n[0,2-n,0,2]],\n\"6\":n=>[\n[0,0,0,1-n],\n[0,0,1,0],\n[n,1,1,1],\n[1,1-n,1,1],\n[1,1,1,2],\n[n,2,1,2],\n[0,1-n,0,2-2*n]],\n\"7\":n=>[\n[0,0,0,n],\n[0,0,1,0],\n[1,0,1,1],\n[1-n,1,1,1],\n[1,1,1,2],\n[1-n,2,1,2],\n[1-n,1,1-n,2]],\n\"8\":n=>[\n[0,0,0,1],\n[0,0,1,0],\n[1,0,1,1],\n[0,1,1,1],\n[1,1,1,2],\n[0,2,1,2],\n[0,1,0,2-n]],\n\"9\":n=>[\n[0,0,0,1],\n[0,0,1,0],\n[1,0,1,1],\n[0,1,1-n,1],\n[0,1,0,1+n],\n[1,1,1,2],\n[0,2,1,2]],\n\":\":n=>[\n[0.4,0.4,0.6,0.4],\n[0.6,0.4,0.6,0.6],\n[0.6,0.6,0.4,0.6],\n[0.4,0.4,0.4,0.6],\n[0.4,1.4,0.6,1.4],\n[0.6,1.4,0.6,1.6],\n[0.6,1.6,0.4,1.6],\n[0.4,1.4,0.4,1.6]]\n};\n\n/* Draw a transition between lastText and thisText.\n 'n' is the amount - 0..1 */\nfunction draw(lastText,thisText,n) {\n buf.clear();\n var x = 1; // x offset\n const p = 2; // padding around digits\n var y = p; // y offset\n const s = 34; // character size\n for (var i=0;i{\n if (c[0]!=c[2]) // horiz\n buf.fillRect(x+c[0]*s,y+c[1]*s-p,x+c[2]*s,y+c[3]*s+p);\n else if (c[1]!=c[3]) // vert\n buf.fillRect(x+c[0]*s-p,y+c[1]*s,x+c[2]*s+p,y+c[3]*s);\n });\n if (thisCh==\":\") x-=4;\n x+=s+p+7;\n }\n y += 2*s;\n var d = new Date();\n buf.setFont(\"6x8\");\n buf.setFontAlign(-1,-1);\n buf.drawString((\"0\"+d.getSeconds()).substr(-2), x, y-8);\n // date\n buf.setFontAlign(0,-1);\n var date = d.toString().substr(0,15);\n buf.drawString(date, buf.getWidth()/2, y+8);\n flip();\n}\n\n/* Show the current time, and animate if needed */\nfunction showTime() {\n if (!Bangle.isLCDOn()) return;\n if (animInterval) return; // in animation - quit\n var d = new Date();\n var t = (\" \"+d.getHours()).substr(-2)+\":\"+\n (\"0\"+d.getMinutes()).substr(-2);\n var l = lastTime;\n // same - don't animate\n if (t==l) {\n draw(t,l,0);\n return;\n }\n var n = 0;\n animInterval = setInterval(function() {\n n += 1/10;\n if (n>=1) {\n n=1;\n clearInterval(animInterval);\n animInterval=0;\n }\n draw(l,t,n);\n }, 20);\n lastTime = t;\n}\n\nBangle.on('lcdPower',function(on) {\n if (on)\n showTime();\n});\n\ng.clear();\nBangle.loadWidgets();\nBangle.drawWidgets();\n// Update time once a second\nsetInterval(showTime, 1000);\nshowTime();\n\n// Show launcher when middle button pressed\nsetWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:\"falling\"});\n"); -require('Storage').write("mclock.img",require("heatshrink").decompress(atob("mEwghC/AE8IxAAEwAWVDB4WIDBwWJAAIWPmf//8zDBpFDwYVBAAc4JJYWJDAoXKn4SC+EPAgXzC5JGCx4qDC4n//BIIEIRCEC4v/GBBdHC4xhCIw5dDC5BhCJAgXCRQoXGJAQXEUhAXHJAyNGC5KRCC7p2FC5B4CC5kggQXOBwvyBQMvSA4XL+EIwCoIC8ZHCgYXNO44LBBIiPPCAIwFC5DXGAAMwGAjvPGA4XIwYXHGALBDnAXFhCQHGAaOFwAXGPA4bFC4xIMIxIXDJBJGEC4xICSJCNEIwowEMJBdCFwwXEMJBdCC5BICDA4WDIw4wEAAMzCoMzBAgWIDAwAGCxRJEAAxFJDBgWNDBAWPAH4AYA=="))); -require('Storage').write("mclock.info","{\"id\":\"mclock\",\"name\":\"Morphing Clock\",\"type\":\"clock\",\"src\":\"mclock.app.js\",\"icon\":\"mclock.img\",\"sortorder\":-9,\"version\":\"0.02\",\"files\":\"mclock.info,mclock.app.js,mclock.img\"}"); -require('Storage').write("setting.app.js","Bangle.loadWidgets();\nBangle.drawWidgets();\n\nconst storage = require('Storage');\nlet settings;\n\nfunction updateSettings() {\n //storage.erase('setting.json'); // - not needed, just causes extra writes if settings were the same\n storage.write('setting.json', settings);\n}\n\nfunction resetSettings() {\n settings = {\n ble: true, // Bluetooth enabled by default\n blerepl: true, // Is REPL on Bluetooth - can Espruino IDE be used?\n log: false, // Do log messages appear on screen?\n timeout: 10, // Default LCD timeout in seconds\n vibrate: true, // Vibration enabled by default. App must support\n beep: true, // Beep enabled by default. App must support\n timezone: 0, // Set the timezone for the device\n HID : false, // BLE HID mode, off by default\n clock: null, // a string for the default clock's name\n \"12hour\" : false, // 12 or 24 hour clock?\n // welcomed : undefined/true (whether welcome app should show)\n };\n updateSettings();\n}\n\nsettings = storage.readJSON('setting.json',1);\nif (!settings) resetSettings();\n\nconst boolFormat = v => v ? \"On\" : \"Off\";\n\nfunction showMainMenu() {\n const mainmenu = {\n '': { 'title': 'Settings' },\n 'Make Connectable': makeConnectable,\n 'BLE': {\n value: settings.ble,\n format: boolFormat,\n onchange: () => {\n settings.ble = !settings.ble;\n updateSettings();\n }\n },\n 'Programmable': {\n value: settings.blerepl,\n format: boolFormat,\n onchange: () => {\n settings.blerepl = !settings.blerepl;\n updateSettings();\n }\n },\n 'Debug info': {\n value: settings.log,\n format: v => v ? \"Show\" : \"Hide\",\n onchange: () => {\n settings.log = !settings.log;\n updateSettings();\n }\n },\n 'LCD Timeout': {\n value: settings.timeout,\n min: 0,\n max: 60,\n step: 5,\n onchange: v => {\n settings.timeout = 0 | v;\n updateSettings();\n Bangle.setLCDTimeout(settings.timeout);\n }\n },\n 'Beep': {\n value: settings.beep,\n format: boolFormat,\n onchange: () => {\n settings.beep = !settings.beep;\n updateSettings();\n if (settings.beep) {\n Bangle.beep(1);\n }\n }\n },\n 'Vibration': {\n value: settings.vibrate,\n format: boolFormat,\n onchange: () => {\n settings.vibrate = !settings.vibrate;\n updateSettings();\n if (settings.vibrate) {\n VIBRATE.write(1);\n setTimeout(()=>VIBRATE.write(0), 10);\n }\n }\n },\n 'Welcome App': {\n value: !settings.welcomed,\n format: boolFormat,\n onchange: v => {\n settings.welcomed = v?undefined:true;\n updateSettings();\n }\n },\n 'Locale': showLocaleMenu,\n 'Select Clock': showClockMenu,\n 'HID': {\n value: settings.HID,\n format: boolFormat,\n onchange: () => {\n settings.HID = !settings.HID;\n updateSettings();\n }\n },\n 'Set Time': showSetTimeMenu,\n 'Reset Settings': showResetMenu,\n 'Turn Off': Bangle.off,\n '< Back': ()=> {load();}\n };\n return E.showMenu(mainmenu);\n}\n\nfunction showLocaleMenu() {\n const localemenu = {\n '': { 'title': 'Locale' },\n '< Back': showMainMenu,\n 'Time Zone': {\n value: settings.timezone,\n min: -11,\n max: 12,\n step: 0.5,\n onchange: v => {\n settings.timezone = v || 0;\n updateSettings();\n }\n },\n 'Clock Style': {\n value: !!settings[\"12hour\"],\n format : v => v?\"12hr\":\"24hr\",\n onchange: v => {\n settings[\"12hour\"] = v;\n updateSettings();\n }\n }\n };\n return E.showMenu(localemenu);\n}\n\nfunction showResetMenu() {\n const resetmenu = {\n '': { 'title': 'Reset' },\n '< Back': showMainMenu,\n 'Reset Settings': () => {\n E.showPrompt('Reset Settings?').then((v) => {\n if (v) {\n E.showMessage('Resetting');\n resetSettings();\n }\n setTimeout(showMainMenu, 50);\n });\n }\n };\n return E.showMenu(resetmenu);\n}\n\nfunction makeConnectable() {\n try { NRF.wake(); } catch(e) {}\n Bluetooth.setConsole(1);\n var name=\"Bangle.js \"+NRF.getAddress().substr(-5).replace(\":\",\"\");\n E.showPrompt(name+\"\\nStay Connectable?\",{title:\"Connectable\"}).then(r=>{\n if (settings.ble!=r) {\n settings.ble = r;\n updateSettings();\n }\n if (!r) try { NRF.sleep(); } catch(e) {}\n showMainMenu();\n });\n}\nfunction showClockMenu() {\n var clockApps = require(\"Storage\").list(/\\.info$/).map(app=>{\n try { return require(\"Storage\").readJSON(app); }\n catch (e) {}\n }).filter(app=>app.type==\"clock\").sort((a, b) => a.sortorder - b.sortorder);\n const clockMenu = {\n '': {\n 'title': 'Select Clock',\n },\n '< Back': showMainMenu,\n };\n clockApps.forEach((app,index) => {\n var label = app.name;\n if ((!settings.clock && index === 0) || (settings.clock === app.src)) {\n label = \"* \"+label;\n }\n clockMenu[label] = () => {\n if (settings.clock !== app.src) {\n settings.clock = app.src;\n updateSettings();\n showMainMenu();\n }\n };\n });\n if (clockApps.length === 0) {\n clockMenu[\"No Clocks Found\"] = () => {};\n }\n return E.showMenu(clockMenu);\n}\n\n\n\nfunction showSetTimeMenu() {\n d = new Date();\n const timemenu = {\n '': {\n 'title': 'Set Time',\n 'predraw': function() {\n d = new Date();\n timemenu.Hour.value = d.getHours();\n timemenu.Minute.value = d.getMinutes();\n timemenu.Second.value = d.getSeconds();\n timemenu.Date.value = d.getDate();\n timemenu.Month.value = d.getMonth() + 1;\n timemenu.Year.value = d.getFullYear();\n }\n },\n '< Back': showMainMenu,\n 'Hour': {\n value: d.getHours(),\n min: 0,\n max: 23,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setHours(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Minute': {\n value: d.getMinutes(),\n min: 0,\n max: 59,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setMinutes(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Second': {\n value: d.getSeconds(),\n min: 0,\n max: 59,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setSeconds(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Date': {\n value: d.getDate(),\n min: 1,\n max: 31,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setDate(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Month': {\n value: d.getMonth() + 1,\n min: 1,\n max: 12,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setMonth(v - 1);\n setTime(d.getTime()/1000);\n }\n },\n 'Year': {\n value: d.getFullYear(),\n min: 2019,\n max: 2100,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setFullYear(v);\n setTime(d.getTime()/1000);\n }\n }\n };\n return E.showMenu(timemenu);\n}\n\nshowMainMenu();\n"); -require('Storage').write("setting.json",{"ble":true,"blerepl":true,"log":false,"timeout":10,"vibrate":true,"beep":true,"timezone":0,"HID":false,"clock":null,"12hour":false}); -require('Storage').write("setting.img",require("heatshrink").decompress(atob("mEwghC/AFEiAAgX/C/4SFkADBgQXFBIgECAAYSCkAWGBIoXGyQTHABBZLkUhiMRiQXLIQwVBAAZlIC44tCAAYxGIxIWFGA4XIFwwwHXBAWHGAwXHFxAwGPAYXTX44XDiAJBgIXGyDAHFAYKDMAq+EGAgXNCwwX/C453XU6IWHa6ZFCC6JJCC4hgEAAoOEC5AwIFwhgEBAgwIBoqmGGBIuFVAgXFGAwLFYAoLFGIYtFeA4MGABMpC4pICkBMGBIpGFC4SuIBIoWFAAxZLC/4X/AFQ"))); -require('Storage').write("setting.info","{\"id\":\"setting\",\"name\":\"Settings\",\"src\":\"setting.app.js\",\"icon\":\"setting.img\",\"sortorder\":-2,\"version\":\"0.06\",\"files\":\"setting.info,setting.app.js,setting.json,setting.img\"}"); -require('Storage').write("about.app.js","var ENV = process.env;\nvar MEM = process.memory();\nvar s = require(\"Storage\");\n\ng.clear(1);\ng.setFont(\"6x8\");\nvar y = 24, h=8;\ng.drawImage(require(\"heatshrink\").decompress(atob(\"vE4gQZWg//AAI3Zh4dCoAd6wAd64Ad2j4d6l4dcn4dC6Adc+AdYv4dUggHG//kgN//AGB1WkDpkOAwsH/gDBgJ4CTRwdGl6RDl/0gHQgJeMDo2/AgcDIAIkBnAdRgJyCAAQdDlgdRgZPDgbWBDoUcDqMPRYcJgEfoA7Uh9AAgQ1BEgIdBngdRKQIACmBbB6AdB2gdRnoEDyB+C8tbbQVpgNAqOkAwMGyEQDoMB1AIBvgdDPYMC+H//7zBg//+fAA4OAgH//twDoMv/4WB3iyEAAPwHINvTYMAv/A/sC6BmBh/wDoP4gIuBdwayBAAP/DoMH4F4ToQSB+EPJQUOgKmDBgIABhAdFB4L7BgfAAYNwjpKChwJBTIQdDiAdFgHgAYIdDmDaCO4MD9Wq14dM+CdCDoU0nDjChyhBAAIdFsgdTZgaVDmPYLJk0LIodDaIcxcILRDSo80jiVECgUAvgDCmG0YQTRHDoTRBgLRCMwJDBnodDeAMDKoUvAIU/DocD6ELDoKRCAIM/LIcGG4PQUIKCBU4PzDoaEB/p3BFQKKCh9ADoXsKIVVqonCtVBoFQcAUKyFwghdB3IPBCwJZCAQMfEgQAL2AGFgZJBDoZgDABEMWYQJFgLwCkACB/gdLWYMCfoQAE35BEDpkH8EfdgYADl4mDl68BABazBFBA2CgK8CABcBUZP/8kBv58CAC1//4ABUQwASn4dgOxoALl4dC4AdYj4d6h4d+wAd6oAd2g4dCAwQA=\")),120,y);\ng.drawString(\"BANGLEJS.COM\",120,y-4);\ng.drawString(\"Powered by Espruino\",0,y+=4+h);\ng.drawString(\"Version \"+ENV.VERSION,0,y+=h);\ng.drawString(\"Commit \"+ENV.GIT_COMMIT,0,y+=h);\nfunction getVersion(name,file) {\n var j = s.readJSON(file,1);\n var v = (\"object\"==typeof j)?j.version:false;\n g.drawString(v?(name+\" \"+(v?\"v\"+v:\"Unknown\")):\"NO \"+name,0,y+=h);\n}\ngetVersion(\"Bootloader\",\"boot.info\");\ngetVersion(\"Launcher\",\"launch.info\");\ngetVersion(\"Settings\",\"setting.info\");\n\ny+=h;\ng.drawString(MEM.total+\" JS Variables available\",0,y+=h);\ng.drawString(\"Storage: \"+(require(\"Storage\").getFree()>>10)+\"k free\",0,y+=h);\nif (ENV.STORAGE) g.drawString(\" \"+(ENV.STORAGE>>10)+\"k total\",0,y+=h);\nif (ENV.SPIFLASH) g.drawString(\"SPI Flash: \"+(ENV.SPIFLASH>>10)+\"k\",0,y+=h);\ng.setFontAlign(0,-1);\ng.drawString(NRF.getAddress(),120,232);\ng.flip();\n\n// Pixel chooser image\ng.drawImage(require(\"heatshrink\").decompress(atob(\"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\")),0,135);\ng.flip();\n"); -require('Storage').write("about.img",require("heatshrink").decompress(atob("mEwxH+AH4A/AH4AQqoAHFtovlFxQzOiEQF0QwJFwIwSFyIwIF6YuTGBQule7IvuEp150d5GBS+DSBwtO5wABGA4vUFxvIFwXO44wJF7hcEAAejYJQvYFpAwJF7ejRQgAHF7BcH44tLF47xGF6QtNF8l5vIqFA4gv/R/4vZABwv25ovudYwAHvIvfp+dFxlPFy4wHp9PvPHFo/HFwIvEFqYxHEINP43G4/H5vNAYIHBBgQuaGAgvEAA4vEFzIxDq0zh5YCAAvHh8zqwud/1lssPh+AF4+ABYIPBFroABnUPnPNFwvNnMPnQRDFzgvCh/OdgKMC5vOBIIvEGC4bESAeB5wAErqODGDIbGMAekFwekLw4wWDY9liAoBrpdEiASIFzdloIpBAAkQoITJF7aSERhQvUDhYATF/4v/F74A/AH4A5A="))); -require('Storage').write("about.info","{\"id\":\"about\",\"name\":\"About\",\"src\":\"about.app.js\",\"icon\":\"about.img\",\"version\":\"0.04\",\"files\":\"about.info,about.app.js,about.img\"}"); -require('Storage').write("alarm.app.js","Bangle.loadWidgets();\nBangle.drawWidgets();\n\nvar alarms = require(\"Storage\").readJSON(\"alarm.json\",1)||[];\n/*alarms = [\n { on : true,\n hr : 6.5, // hours + minutes/60\n msg : \"Eat chocolate\",\n last : 0, // last day of the month we alarmed on - so we don't alarm twice in one day!\n rp : true, // repeat\n }\n];*/\n\nfunction formatTime(t) {\n var hrs = 0|t;\n var mins = Math.round((t-hrs)*60);\n return hrs+\":\"+(\"0\"+mins).substr(-2);\n}\n\nfunction getCurrentHr() {\n var time = new Date();\n return time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);\n}\n\nfunction showMainMenu() {\n const menu = {\n '': { 'title': 'Alarms' },\n 'New Alarm': ()=>editAlarm(-1)\n };\n alarms.forEach((alarm,idx)=>{\n txt = (alarm.on?\"on \":\"off \")+formatTime(alarm.hr);\n if (alarm.rp) txt += \" (repeat)\";\n menu[txt] = function() {\n editAlarm(idx);\n };\n });\n menu['< Back'] = ()=>{load();};\n return E.showMenu(menu);\n}\n\nfunction editAlarm(alarmIndex) {\n var newAlarm = alarmIndex<0;\n var hrs = 12;\n var mins = 0;\n var en = true;\n var repeat = true;\n if (!newAlarm) {\n var a = alarms[alarmIndex];\n hrs = 0|a.hr;\n mins = Math.round((a.hr-hrs)*60);\n en = a.on;\n repeat = a.rp;\n }\n const menu = {\n '': { 'title': 'Alarms' },\n 'Hours': {\n value: hrs,\n onchange: function(v){if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} // no arrow fn -> preserve 'this'\n },\n 'Minutes': {\n value: mins,\n onchange: function(v){if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} // no arrow fn -> preserve 'this'\n },\n 'Enabled': {\n value: en,\n format: v=>v?\"On\":\"Off\",\n onchange: v=>en=v\n },\n 'Repeat': {\n value: en,\n format: v=>v?\"Yes\":\"No\",\n onchange: v=>repeat=v\n }\n };\n function getAlarm() {\n var hr = hrs+(mins/60);\n var day = 0;\n // If alarm is for tomorrow not today (eg, in the past), set day\n if (hr < getCurrentHr())\n day = (new Date()).getDate();\n // Save alarm\n return {\n on : en, hr : hr,\n last : day, rp : repeat\n };\n }\n if (newAlarm) {\n menu[\"> New Alarm\"] = function() {\n alarms.push(getAlarm());\n require(\"Storage\").write(\"alarm.json\",JSON.stringify(alarms));\n showMainMenu();\n };\n } else {\n menu[\"> Save\"] = function() {\n alarms[alarmIndex] = getAlarm();\n require(\"Storage\").write(\"alarm.json\",JSON.stringify(alarms));\n showMainMenu();\n };\n }\n menu['< Back'] = showMainMenu;\n return E.showMenu(menu);\n}\n\nshowMainMenu();\n"); -require('Storage').write("alarm.js","// Chances are boot0.js got run already and scheduled *another*\n// 'load(alarm.js)' - so let's remove it first!\nclearInterval();\n\nfunction formatTime(t) {\n var hrs = 0|t;\n var mins = Math.round((t-hrs)*60);\n return hrs+\":\"+(\"0\"+mins).substr(-2);\n}\n\nfunction getCurrentHr() {\n var time = new Date();\n return time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);\n}\n\nfunction showAlarm(alarm) {\n var msg = formatTime(alarm.hr);\n var buzzCount = 10;\n if (alarm.msg)\n msg += \"\\n\"+alarm.msg;\n E.showPrompt(msg,{\n title:\"ALARM!\",\n buttons : {\"Sleep\":true,\"Ok\":false} // default is sleep so it'll come back in 10 mins\n }).then(function(sleep) {\n buzzCount = 0;\n if (sleep) {\n alarm.hr += 10/60; // 10 minutes\n } else {\n alarm.last = (new Date()).getDate();\n if (!alarm.rp) alarm.on = false;\n }\n require(\"Storage\").write(\"alarm.json\",JSON.stringify(alarms));\n load();\n });\n function buzz() {\n Bangle.buzz(100).then(()=>{\n setTimeout(()=>{\n Bangle.buzz(100).then(function() {\n if (buzzCount--)\n setTimeout(buzz, 3000);\n });\n },100);\n });\n }\n buzz();\n}\n\n// Check for alarms\nvar day = (new Date()).getDate();\nvar hr = getCurrentHr()+10000; // get current time - 10s in future to ensure we alarm if we've started the app a tad early\nvar alarms = require(\"Storage\").readJSON(\"alarm.json\",1)||[];\nvar active = alarms.filter(a=>a.on&&(a.hra.hr-b.hr);\n showAlarm(active[0]);\n} else {\n // otherwise just go back to default app\n setTimeout(load, 100);\n}\n"); -require('Storage').write("alarm.json","[]"); -require('Storage').write("alarm.img",require("heatshrink").decompress(atob("mEwwkGswAhiMRCCAREAo4eHBIQLEAgwYHsIJDiwHB5gACBpIhHCoYZEGA4gFCw4ABGA4HEjgXJ4IXGAwcUB4VEmf//8zogICoJIFAodMBoNDCoIADmgJB4gXIFwXDCwoABngwFC4guB4k/CQXwh4EC+YMCC44iBp4qDC4n/+gNBC41sEIJCEC4v/GAPGC4dhXYRdFC4xhCCYIXCdQRdDC5HzegQXCsxGHC45IDCwQXCUgwXHJAIXGRogXJSIIXcOw4XIPAYXcBwv/mEDBAwXOgtQC65QGC5vzoEAJAx3Nmk/mEABIiPN+dDAQIwFC4zXGFwKRCGAjvMFwQECGAgXI4YuGGAUvAgU8C4/EFwwGCAgdMC4p4EFwobFOwoXDJAIoEAApGBC4xIEABJGHGAapEAAqNBFwwXD4heI+YuBC5BIBVQhdHIw4wD5inFS4IKCCxFmigNCokzCoMzogICoIWIsMRjgPCAA3BiMWC48RBQIXJEgMRFxAJCCw4lEC44IECooOIBAaBJKwhgIAH4ACA=="))); -require('Storage').write("alarm.wid.js","(() => {\n var alarms = require('Storage').readJSON('alarm.json',1)||[];\n alarms = alarms.filter(alarm=>alarm.on);\n if (!alarms.length) return; // no alarms, no widget!\n delete alarms;\n // add the widget\n WIDGETS[\"alarm\"]={area:\"tl\",width:24,draw:function() {\n g.setColor(-1);\n g.drawImage(atob(\"GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA\"),this.x,this.y);\n }};\n})()\n"); -require('Storage').write("alarm.info","{\"id\":\"alarm\",\"name\":\"Alarms\",\"src\":\"alarm.app.js\",\"icon\":\"alarm.img\",\"version\":\"0.04\",\"files\":\"alarm.info,alarm.app.js,alarm.js,alarm.json,alarm.img,alarm.wid.js\"}"); -require('Storage').write("widbat.wid.js","(function(){\nvar CHARGING = 0x07E0;\n\nfunction setWidth() {\n WIDGETS[\"bat\"].width = 40 + (Bangle.isCharging()?16:0);\n}\nfunction draw() {\n var s = 39;\n var x = this.x, y = this.y;\n if (Bangle.isCharging()) {\n g.setColor(CHARGING).drawImage(atob(\"DhgBHOBzgc4HOP////////////////////3/4HgB4AeAHgB4AeAHgB4AeAHg\"),x,y);\n x+=16;\n }\n g.setColor(-1);\n g.fillRect(x,y+2,x+s-4,y+21);\n g.clearRect(x+2,y+4,x+s-6,y+19);\n g.fillRect(x+s-3,y+10,x+s,y+14);\n g.setColor(CHARGING).fillRect(x+4,y+6,x+4+E.getBattery()*(s-12)/100,y+17);\n g.setColor(-1);\n}\nBangle.on('charging',function(charging) {\n if(charging) Bangle.buzz();\n setWidth();\n Bangle.drawWidgets(); // relayout widgets\n g.flip();\n});\nvar batteryInterval;\nBangle.on('lcdPower', function(on) {\n if (on) {\n WIDGETS[\"bat\"].draw();\n // refresh once a minute if LCD on\n if (!batteryInterval)\n batteryInterval = setInterval(draw, 60000);\n } else {\n if (batteryInterval) {\n clearInterval(batteryInterval);\n batteryInterval = undefined;\n }\n }\n});\nWIDGETS[\"bat\"]={area:\"tr\",width:40,draw:draw};\nsetWidth();\n})()\n"); -require('Storage').write("widbat.info","{\"id\":\"widbat\",\"name\":\"Battery Level Widget\",\"type\":\"widget\",\"version\":\"0.04\",\"files\":\"widbat.info,widbat.wid.js\"}"); -require('Storage').write("widbt.wid.js","(function(){\nvar img_bt = E.toArrayBuffer(atob(\"CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA==\"));\n\nfunction draw() {\n g.reset();\n if (NRF.getSecurityStatus().connected)\n g.setColor(0,0.5,1);\n else\n g.setColor(0.3,0.3,0.3);\n g.drawImage(img_bt,10+this.x,2+this.y);\n}\nfunction changed() {\n WIDGETS[\"bluetooth\"].draw();\n g.flip();// turns screen on\n}\nNRF.on('connected',changed);\nNRF.on('disconnected',changed);\nWIDGETS[\"bluetooth\"]={area:\"tr\",width:24,draw:draw};\n})()\n"); -require('Storage').write("widbt.info","{\"id\":\"widbt\",\"name\":\"Bluetooth Widget\",\"type\":\"widget\",\"version\":\"0.03\",\"files\":\"widbt.info,widbt.wid.js\"}"); -require('Storage').write("welcome.js","eval(require(\"Storage\").read(\"welcome.app.js\"))\n"); -require('Storage').write("welcome.app.js","// exec each function from seq one after the other\nfunction animate(seq,period) {\n var i = setInterval(function() {\n if (seq.length) {\n var f = seq.shift();\n if (f) f();\n } else clearInterval(i);\n },period);\n}\n\n// Fade in to FG color with angled lines\nfunction fade(callback) {\n var n = 0;\n function f() {\n for (var i=n;i<240;i+=10) {\n g.drawLine(i,0,0,i);\n g.drawLine(i,240,240,i);\n }\n g.flip();\n n++;\n if (n<10) setTimeout(f,0);\n else callback();\n }\n f();\n}\n\n\nvar scenes = [\n function() {\n g.clear(1);\n g.setFont(\"4x6\",2);\n var n=0;\n var i = setInterval(function() {\n n+=0.04;\n g.setColor(n,n,n);\n g.drawImage(Bangle.getLogo(),(240-222)/2,(240-100)/2);\n if (n>=1) {\n clearInterval(i);\n setTimeout(()=>g.drawString(\"Open\",34,144), 500);\n setTimeout(()=>g.drawString(\"Hackable\",34,156), 1000);\n setTimeout(()=>g.drawString(\"Smart Watch\",34,168), 1500);\n }\n },50);\n },function() {\n var img = require(\"heatshrink\").decompress(atob(\"ptRxH+qYAfvl70mj5gAC0ekvd8FkAAdz3HJAYAH4+eJXWkJJYAF0hK2vfNJaIAB5t7S3fN5/V6wAD6vOTg9SumXy2W3QAB3eXul2JdnO63XAApPEVYvAJQIACJoRQDzBLoJQ3W5/NIwr4GJohMFAAROgJYvVJQiPGABZNN3bsdvYyESwnWJSIAC3RNM3V1JjZAES4nVJSYAB4xMNJrbkE56WD5xLVdB5NbFofNJbgABJh26qREPrFXrlbAAWjFgfWJgRLaTQhMLy5KNJINhsJLDrYrD5xLC6pLa5nGTR7oLq9bJQJMKTAXWJbbnR3RLJSoRMHv4pC5rkec6SaIrBLGw2r2XW1epcoqYeJiOXJYziEsOH2RBBw7lF56Yg5nGc6FScZOGJQPX2TmDFIfVTEBMSc4hLEw5KB6+rsJMH63X6pMf5hMQzBLCq5LD1ZLEJhTlfJiWXTA2GJYpMIcwPNc2O6TAuGRIPX1igDJg/PJmyYDcgXWwxMH1ApC53XcsHAJiVYcg2HJYZME0YpC5vWJkhLNJgLlDTAeFJhF/FQfVJkG6JiGXcomyJgOrJYhMErYqD53NJj7lRzBMDcoeGJhzoBJb3GJiN1qZBCJgWyJYpNF1LigAAXAJiNSJgzlGJgt/JkZLRy9TJgeHJhznFcuSZGw5MHJomjcuhLBqdcJiSaiTChMV1CYxy5LCqdXIAWy6+rJhCalTCN2JgdYH4WHJiGpTF7kDc43W2RMJTUZLQzBLFc4mr6+GJh2jTFmXJYyaEwuyc5Sag4xLZTQmG2WFJhxNaJYZMLJZSaEJoOHTR9/Ja+6JbdTqRNETRRNF1JLV4BLcAANYI5ToK1BLYJhWYJZwABq5NoJZ91JaAABdAZNS0ZLey9SJaRNYv5KM426JZmXuxKUJrKcL0lTzBLKzBKYJrVXvfGSol7EYWXJI27zF1JLQADq5NUrgYB4wAEEIV0comXI7wAFrCcPJgYWBTIIAETIN2JYmWuhMkdSdYCgOeJgueqRLFyzhfTi9bq4TC45MF49TuuXJlpONcogAC0hKB0gHDvZMEqRMpAANSq9crlbJAYADqwRDxGk0mIA4eCTQOeveXJdYAHqxNFdAeIAAQGCrOI0oHEAGVXTRJMGvgGCwRM7TAZMHwQGCvhM1rBMERIhMGAwdZJmtSqVTwNcwJEDJg19cvIADa4d9JhANDJnSLHJgrl6AAhFFAwpZDegjn7vhMGcvwABrJAFJgjl/TQpBBI4jl/AAN8TQhHDcv4ADcJBMDvpM+IYaeDAAhL+qd9SgycEJn7iEAA18Jf7nEcv4AIrJLIcv6aMcv4ADvhMHrJJ/AAbl/c6ZM/AAt9cv7nSIv7nLcv4AHrLl/TRpJBvgnjA==\"));\n g.reset();\n g.setColor(\"#6633ff\");\n g.setBgColor(\"#6633ff\");\n var y = 240, speed = 5;\n function balloon(callback) {\n y-=speed;\n var x = (240-77)/2;\n g.drawImage(img,x,y);\n g.clearRect(x,y+81,x+77,y+81+speed);\n if (y>60) setTimeout(balloon,0,callback);\n else callback();\n }\n fade(function() {\n balloon(function() {\n g.setColor(-1);\n g.setFont(\"6x8\",3);\n g.setFontAlign(0,0);\n g.drawString(\"Welcome.\",120,160);\n });\n });\n setTimeout(function() {\n var n=0;\n var i = setInterval(function() {\n n+=5;\n g.scroll(0,-5);\n if (n>170)\n clearInterval(i);\n },20);\n },3500);\n\n },function() {\n g.reset();\n g.setBgColor(\"#ffa800\");g.clear();\n g.setFont(\"6x8\",2);\n g.setFontAlign(0,0);\n var x = 80, y = 35, h=35;\n animate([\n ()=>g.drawString(\"Your\",x,y+=h),\n ()=>g.drawString(\"Bangle.js\",x,y+=h),\n ()=>g.drawString(\"has\",x,y+=h),\n ()=>g.drawString(\"3 buttons\",x,y+=h),\n ()=>{g.setFont(\"Vector\",36);g.drawString(\"1\",200,40);},\n ()=>g.drawString(\"2\",200,120),\n ()=>g.drawString(\"3\",200,200)\n ],200);\n },\n function() {\n g.reset();\n g.setBgColor(\"#00a8ff\");g.clear();\n g.setFontAlign(0,0);\n g.setFont(\"Vector\",48);\n g.drawString(\"1\",200,40);\n g.setFontAlign(-1,-1);\n g.setFont(\"6x8\",2);\n g.drawString(\"Move up\\nin menus\\n\\nTurn Bangle.js on\\nif it was off\", 20,40);\n },\n function() {\n g.reset();\n g.setBgColor(\"#00a8ff\");g.clear();\n g.setFontAlign(0,0);\n g.setFont(\"Vector\",48);\n g.drawString(\"2\",200,120);\n g.setFontAlign(-1,-1);\n g.setFont(\"6x8\",2);\n g.drawString(\"Select menu\\nitem\\n\\nLaunch app\\nwhen watch\\nis showing\", 20,70);\n },\n function() {\n g.reset();\n g.setBgColor(\"#00a8ff\");g.clear();\n g.setFontAlign(0,0);\n g.setFont(\"Vector\",48);\n g.drawString(\"3\",200,200);\n g.setFontAlign(-1,-1);\n g.setFont(\"6x8\",2);\n g.drawString(\"Move down\\nin menus\\n\\nLong press\\nto exit app\\nand go back\\nto clock\", 20,100);\n },\n function() {\n g.reset();\n g.setBgColor(\"#ff3300\");g.clear();\n g.setFontAlign(0,0);\n g.setFont(\"Vector\",48);\n g.drawString(\"1\",200,40);\n g.drawString(\"2\",200,120);\n g.setFontAlign(-1,-1);\n g.setFont(\"6x8\",2);\n g.drawString(\"If Bangle.js\\never stops,\\nhold buttons\\n1 and 2 for\\naround six\\nseconds.\\n\\n\\n\\nBangle.js will\\nthen reboot.\", 20,20);\n },\n function() {\n g.reset();\n g.setBgColor(\"#00a8ff\");g.clear();\n g.setFont(\"6x8\",2);\n g.setFontAlign(0,0);\n var x = 120, y = 10, h=21;\n animate([\n ()=>{g.drawString(\"Bangle.js has a\",x,y+=h);\n g.drawString(\"simple touchscreen\",x,y+=h);},\n 0,0,\n ()=>{g.drawString(\"It'll detect touch\",x,y+=h*2);\n g.drawString(\"on left and right\",x,y+=h);},\n 0,0,\n ()=>{g.drawString(\"Horizontal swipes\",x,y+=h*2);\n g.drawString(\"work too. Try now\",x,y+=h);\n g.drawString(\"to change page.\",x,y+=h);}\n ],300);\n },\n function() {\n g.reset();\n g.setBgColor(\"#339900\");g.clear();\n g.setFont(\"6x8\",2);\n g.setFontAlign(0,0);\n var x = 120, y = 10, h=21;\n animate([\n ()=>{g.drawString(\"Bangle.js\",x,y+=h);\n g.drawString(\"comes with\",x,y+=h);\n g.drawString(\"a few simple\",x,y+=h);\n g.drawString(\"apps installed\",x,y+=h);},\n 0,0,\n ()=>{g.drawString(\"To add more, visit\",x,y+=h*2);\n g.drawString(\"banglejs.com/apps\",x,y+=h);\n g.drawString(\"with a Bluetooth\",x,y+=h);\n g.drawString(\"capable device\",x,y+=h);},\n ],400);\n },\n function() {\n g.reset();\n g.setBgColor(\"#990066\");g.clear();\n g.setFont(\"6x8\",2);\n g.setFontAlign(0,0);\n var x = 120, y = 10, h=21;\n g.drawString(\"You can also make\",x,y+=h);\n g.drawString(\"your own apps!\",x,y+=h);\n y=160;\n g.drawString(\"Check out\",x,y+=h);\n g.drawString(\"banglejs.com\",x,y+=h);\n\n var rx = 0, ry = 0;\n var h = Graphics.createArrayBuffer(96,96,1,{msb:true});\n // draw a cube\n function draw() {\n // rotate\n rx += 0.1;\n ry += 0.11;\n var rcx=Math.cos(rx),\n rsx=Math.sin(rx),\n rcy=Math.cos(ry),\n rsy=Math.sin(ry);\n // Project 3D coordinates into 2D\n function p(x,y,z) {\n var t;\n t = x*rcy + z*rsy;\n z = z*rcy - x*rsy;\n x=t;\n t = y*rcx + z*rsx;\n z = z*rcx - y*rsx;\n y=t;\n z += 4;\n return [96*(0.5+x/z), 96*(0.5+y/z)];\n }\n\n var a;\n // draw a series of lines to make up our cube\n h.clear();\n a = p(-1,-1,-1); h.moveTo(a[0],a[1]);\n a = p(1,-1,-1); h.lineTo(a[0],a[1]);\n a = p(1,1,-1); h.lineTo(a[0],a[1]);\n a = p(-1,1,-1); h.lineTo(a[0],a[1]);\n a = p(-1,-1,-1); h.lineTo(a[0],a[1]);\n a = p(-1,-1,1); h.moveTo(a[0],a[1]);\n a = p(1,-1,1); h.lineTo(a[0],a[1]);\n a = p(1,1,1); h.lineTo(a[0],a[1]);\n a = p(-1,1,1); h.lineTo(a[0],a[1]);\n a = p(-1,-1,1); h.lineTo(a[0],a[1]);\n a = p(-1,-1,-1); h.moveTo(a[0],a[1]);\n a = p(-1,-1,1); h.lineTo(a[0],a[1]);\n a = p(1,-1,-1); h.moveTo(a[0],a[1]);\n a = p(1,-1,1); h.lineTo(a[0],a[1]);\n a = p(1,1,-1); h.moveTo(a[0],a[1]);\n a = p(1,1,1); h.lineTo(a[0],a[1]);\n a = p(-1,1,-1); h.moveTo(a[0],a[1]);\n a = p(-1,1,1); h.lineTo(a[0],a[1]);\n g.drawImage({width:96,height:96,buffer:h.buffer},(240-96)/2,68);\n }\n\n setInterval(draw,50);\n },\n function() {\n g.reset();\n g.setBgColor(\"#660099\");g.clear();\n g.setFontAlign(0,0);\n g.setFont(\"Vector\",36);\n g.drawString(\"2\",200,120);\n g.setFont(\"6x8\",2);\n\n var x = 90, y = 30, h=21;\n animate([\n ()=>g.drawString(\"That's it!\",x,y+=h),\n ()=>{g.drawString(\"Press\",x,y+=h*3);\n g.drawString(\"Button 2\",x,y+=h);\n g.drawString(\"to start\",x,y+=h);\n g.drawString(\"Bangle.js\",x,y+=h);}\n ],400);\n }\n];\n\nvar sceneNumber = 0;\n\nfunction move(dir) {\n if (dir>0 && sceneNumber+1 == scenes.length) return; // at the end\n sceneNumber = (sceneNumber+dir)%scenes.length;\n if (sceneNumber<0) sceneNumber=0;\n clearInterval();\n scenes[sceneNumber]();\n if (sceneNumber>1) {\n var l = scenes.length;\n for (var i=0;imove(1), BTN3, {repeat:true});\nsetWatch(()=>{\n // If we're on the last page\n if (sceneNumber == scenes.length-1) {\n var settings = require(\"Storage\").readJSON('setting.json',1)||{};\n settings.welcomed = true;\n require(\"Storage\").write('setting.json',settings);\n load();\n }\n}, BTN2, {repeat:true,edge:\"rising\"});\nsetWatch(()=>move(-1), BTN1, {repeat:true});\n\n\n\nBangle.setLCDTimeout(0);\nBangle.setLCDPower(1);\nmove(0);\n"); -require('Storage').write("welcome.img",require("heatshrink").decompress(atob("mEwxH+AH4A/AH4AU5gAEFtoxnEwXN53WAAXO5oJB42Wy26AAIueFoPXFggAD4AwEGTQiB6otBFgwAD3QvFGC5dCFxiRGGClhrdbv67BXAIuLMBIwPsIABF4OpLwXOFxjBCF6gtBw2r1mHXoXWFxqQWFwOH62rL4IeB6xeOAAIvHGBYuC6+rR4QvCXpovXw3X1i/DR4QuPR5AvKFQOs6+GF4eod4IvPd5AvLwvWLwQvCv4fBR54vURwOHF4iQCX0yOCF4aQBX0QvHSAoAN3SOSd4WyF4yQPLyhgD1YvDMCJeIFxhgCF47BN4BeHFxpgDSAiRORpAuPMIYAFGBYuaF5aSHFwQvEFqQwOeggSBLa4xNF4X+4wAC/xeCFjIADrYwGBIIvlMQiPDBAOk0gDBz2XF8BlEF4eIxADFF8lcF9n+wIrFF05bHF9AsGF9wupGAYv/F8QupGAov/F/4wOF1gA/AH4Ap"))); -require('Storage').write("welcome.info","{\"id\":\"welcome\",\"name\":\"Welcome\",\"src\":\"welcome.app.js\",\"icon\":\"welcome.img\",\"version\":\"0.04\",\"files\":\"welcome.info,welcome.js,welcome.app.js,welcome.img\"}"); From 04f8cbcd139409b5ca1b4e6b19d85061abeaf024 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 31 Mar 2020 13:37:03 +0100 Subject: [PATCH 43/54] write code in chunks, in case it is too big to fit in RAM (fix #157) --- js/appinfo.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/js/appinfo.js b/js/appinfo.js index 151227f45..613d15379 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -27,14 +27,19 @@ var AppInfo = { // then map each file to a command to load into storage fileContents.forEach(storageFile => { // format ready for Espruino - var js; if (storageFile.evaluate) { - js = storageFile.content.trim(); + let js = storageFile.content.trim(); if (js.endsWith(";")) js = js.slice(0,-1); - } else - js = toJS(storageFile.content); - storageFile.cmd = `\x10require('Storage').write(${toJS(storageFile.name)},${js});`; + storageFile.cmd = `\x10require('Storage').write(${toJS(storageFile.name)},${js});`; + } else { + let code = storageFile.content; + // write code in chunks, in case it is too big to fit in RAM (fix #157) + var CHUNKSIZE = 4096; + storageFile.cmd = `\x10require('Storage').write(${toJS(storageFile.name)},${toJS(code.substr(0,CHUNKSIZE))},0,${code.length});`; + for (var i=CHUNKSIZE;i reject(err)); From 8fce6d7f37609f5f179965f8c3e42840f6dc6d17 Mon Sep 17 00:00:00 2001 From: Nik Martin Date: Tue, 31 Mar 2020 08:36:18 -0500 Subject: [PATCH 44/54] bring changelog from dev branch --- apps/aclock/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/aclock/ChangeLog b/apps/aclock/ChangeLog index 7819dbe2a..a179800be 100644 --- a/apps/aclock/ChangeLog +++ b/apps/aclock/ChangeLog @@ -1 +1,7 @@ 0.02: Modified for use with new bootloader and firmware +0.03: add hour ticks, remove timers +0.04: add day-date display +0.07: make date and face bigger +0.08: make dots bigger and date more readable +0.09: center date, remove box around it, internal refactor to remove redundant code. +0.10: remove debug, refactor seconds to show elapsed secs each time app is displayed From dd0e3c89d1b5f3bc57e60f5654acb962f56f4162 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 31 Mar 2020 14:39:59 +0100 Subject: [PATCH 45/54] Added showModal/hideModal utility functions Added readStorageFile/eraseStorageFile to handle efficiently downloading large files (fix #119) --- apps/gpsrec/interface.html | 45 ++++++------------------------ apps/heart/interface.html | 45 ++++++------------------------ js/comms.js | 45 ++++++++++++++++++++++++++++++ js/index.js | 8 ++++++ lib/interface.js | 56 +++++++++++++++++++++++++++++++++++--- 5 files changed, 123 insertions(+), 76 deletions(-) diff --git a/apps/gpsrec/interface.html b/apps/gpsrec/interface.html index b87d75b3c..bc8dc48e1 100644 --- a/apps/gpsrec/interface.html +++ b/apps/gpsrec/interface.html @@ -5,32 +5,9 @@

- -