From bdf9e3e9535acdc387b38a7f1baa9c16b7f19ee1 Mon Sep 17 00:00:00 2001 From: James Taylor Date: Sat, 6 Apr 2024 13:16:20 +0100 Subject: [PATCH] Add new thunder app Signed-off-by: James Taylor --- apps/thunder/ChangeLog | 1 + apps/thunder/README.md | 20 +++++++ apps/thunder/app-icon.js | 1 + apps/thunder/app.js | 110 ++++++++++++++++++++++++++++++++++++ apps/thunder/app.png | Bin 0 -> 982 bytes apps/thunder/metadata.json | 17 ++++++ apps/thunder/screenshot.png | Bin 0 -> 2528 bytes apps/thunder/settings.js | 40 +++++++++++++ 8 files changed, 189 insertions(+) create mode 100644 apps/thunder/ChangeLog create mode 100644 apps/thunder/README.md create mode 100644 apps/thunder/app-icon.js create mode 100644 apps/thunder/app.js create mode 100644 apps/thunder/app.png create mode 100644 apps/thunder/metadata.json create mode 100644 apps/thunder/screenshot.png create mode 100644 apps/thunder/settings.js diff --git a/apps/thunder/ChangeLog b/apps/thunder/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/thunder/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/thunder/README.md b/apps/thunder/README.md new file mode 100644 index 000000000..86607107e --- /dev/null +++ b/apps/thunder/README.md @@ -0,0 +1,20 @@ +# Come on Thunder + +Simple timer to calculate how far away lightning is. + +A tribute to [Flash Boom](https://archive.org/details/tucows_33513_Flash_Boom), the greatest app of all time! + +![](screenshot.png) + +## Usage + +Use the "Flash" button when you see the flash of lightning, and press the "Boom" button when you hear the rumble of thunder! + +## Creator + +James Taylor ([jt-nti](https://github.com/jt-nti)) + +## Icons + +- [Cloud Lightning](https://icons8.com/icon/41144/cloud-lightning) +- [Lightning](https://icons8.com/icon/60998/lightning-bolt") diff --git a/apps/thunder/app-icon.js b/apps/thunder/app-icon.js new file mode 100644 index 000000000..7a95e1390 --- /dev/null +++ b/apps/thunder/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgn/AH4AO/uEkETxoWR/1QN4deC6HBgN89/suMB54WO/gqFsEcC53hg4GE/ECC51Qr4HFsF/RhsB94IF+MPC5n4IwoAB+8HscRk2vC5Hzhh/IAAUC34XH+UOBI8Dzv/7MwHo//+BWIYAf6gB9F/tziBuN4ELTgpSBI5AAE/TGE+kBvv/NJAAFmAPDsEtchwAByFvaYffC6HQl7KDKo5mBx6fHj7TChokHgEIW5AXC+KjHkAuII4gXH+ouJO4hHHwAuJU4h3G/YuKa4inG8IuK4ELAodwa4kwUoMAz6qCLIX5gF/CIf0gN8AgP2CwUKVQUGBQPZmDRGuASBp4FB2EB56qCt/0BgMCOoQAD/tziAXCkEdVQQuBHoMmCwwAF+0C96qCLoQAO4E+//8LoYAPmiqDFyP4r6qFUIgAK66qFhIvPUYJjDgGvMCLzDjYWU/EB74XU6EuCyn/oYWV/NPC6vnCyqqFAH4A//4A==")) diff --git a/apps/thunder/app.js b/apps/thunder/app.js new file mode 100644 index 000000000..d180bb720 --- /dev/null +++ b/apps/thunder/app.js @@ -0,0 +1,110 @@ +Bangle.loadWidgets(); +g.clear(true); +Bangle.drawWidgets(); + +Bangle.setLCDTimeout(undefined); + +let renderIntervalId; +let startTime; + +const DEFAULTS = { + units: 0, +}; + +const settings = require("Storage").readJSON("thunder.json", 1) || DEFAULTS; + +var Layout = require("Layout"); +var layout = new Layout( { + type:"v", c: [ + {type:"txt", font:"6x8:2", label:"", id:"time", fillx:1}, + {type:"txt", pad:8, font:"20%", label:"", id:"distance", fillx:1}, + {type:"h", c: [ + {type:"btn", font:"6x8:2", label:"Flash", cb: l=>flash() }, + {type:"img", pad:4, src:require("heatshrink").decompress(atob("h0awkBiMQBAQFBAxwdDAoIGKCYQGGFBQTCAyIAPgIGGIAoFCAxITDAxIFDAxATEJwIMEAw4TEAwo")) }, + {type:"btn", font:"6x8:2", label:"Boom", cb: l=>boom() } + ]}, + ] +}, { + lazy: true, + back: load, +}); + +const getTime = function(milliseconds) { + let hrs = Math.floor(milliseconds/3600000); + let mins = Math.floor(milliseconds/60000)%60; + let secs = Math.floor(milliseconds/1000)%60; + let tnth = Math.floor(milliseconds/100)%10; + let text; + + if (hrs === 0) { + text = ("0"+mins).slice(-2) + ":" + ("0"+secs).slice(-2) + "." + tnth; + } else { + text = ("0"+hrs) + ":" + ("0"+mins).slice(-2) + ":" + ("0"+secs).slice(-2); + } + + return text; +}; + +// Convert milliseconds to distance based on one km in 2.91 s or +// one mile in 4.69 s +// See https://en.wikipedia.org/wiki/Speed_of_sound +const getDistance = function(milliseconds) { + let secs = milliseconds/1000; + let distance; + + if (settings.units === 0) { + let kms = Math.round((secs / 2.91) * 10) / 10; + distance = kms.toFixed(1) + "km"; + } else { + let miles = Math.round((secs / 4.69) * 10) / 10; + distance = miles.toFixed(1) + "mi"; + } + + return distance; +}; + +const renderIntervalCallback = function() { + if (startTime === undefined) { + return; + } + + updateTimeAndDistance(); +}; + +const flash = function() { + Bangle.buzz(50, 0.5); + + startTime = startTime = Date.now(); + updateTimeAndDistance(); + renderIntervalId = setInterval(renderIntervalCallback, 100); +}; + +const boom = function() { + Bangle.buzz(50, 0.5); + + if (renderIntervalId !== undefined) { + clearInterval(renderIntervalId); + renderIntervalId = undefined; + } + + updateTimeAndDistance(); + startTime = undefined; +}; + +const updateTimeAndDistance = function() { + let t; + + if (startTime === undefined) { + t = 0; + } else { + t = Date.now() - startTime; + } + + layout.time.label = getTime(t); + layout.distance.label = getDistance(t); + + layout.render(); + // layout.debug(); +}; + +updateTimeAndDistance(); diff --git a/apps/thunder/app.png b/apps/thunder/app.png new file mode 100644 index 0000000000000000000000000000000000000000..5767e9275b78270f02c60d242056adb462a9c527 GIT binary patch literal 982 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 unitOptions[v], + onchange: v => { + settings.units = 0 | v; + saveSettings(settings); + } + }, + }; + + E.showMenu(menu); + }; + + loadSettings(); + showMenu(); +});