diff --git a/apps.json b/apps.json index 412b4be10..f16b4b27d 100644 --- a/apps.json +++ b/apps.json @@ -456,6 +456,23 @@ {"name":"widbatpc.json"} ] }, + { "id": "widbatwarn", + "name": "Battery Warning", + "shortName": "Battery Warning", + "icon": "widget.png", + "version":"0.01", + "description": "Show a warning when the battery runs low.", + "tags": "tool,battery", + "type":"widget", + "dependencies": { "notify":"type" }, + "storage": [ + {"name":"widbatwarn.wid.js","url":"widget.js"}, + {"name":"widbatwarn.settings.js","url":"settings.js"} + ], + "data": [ + {"name":"widbatwarn.json"} + ] + }, { "id": "widbt", "name": "Bluetooth Widget", "icon": "widget.png", diff --git a/apps/widbatwarn/ChangeLog b/apps/widbatwarn/ChangeLog new file mode 100644 index 000000000..c51b06842 --- /dev/null +++ b/apps/widbatwarn/ChangeLog @@ -0,0 +1 @@ +0.01: New Battery Warning! \ No newline at end of file diff --git a/apps/widbatwarn/battery-low.png b/apps/widbatwarn/battery-low.png new file mode 100644 index 000000000..0955a0578 Binary files /dev/null and b/apps/widbatwarn/battery-low.png differ diff --git a/apps/widbatwarn/icons.txt b/apps/widbatwarn/icons.txt new file mode 100644 index 000000000..2e8dba984 --- /dev/null +++ b/apps/widbatwarn/icons.txt @@ -0,0 +1,2 @@ +widget.png: https://icons8.com/icon/vga9edYpuB7a/warning-battery +battery-low.png: https://icons8.com/icon/96282/low-battery (recolored) \ No newline at end of file diff --git a/apps/widbatwarn/settings.js b/apps/widbatwarn/settings.js new file mode 100644 index 000000000..8d15c8458 --- /dev/null +++ b/apps/widbatwarn/settings.js @@ -0,0 +1,47 @@ +/** + * @param {function} back Use back() to return to settings menu + */ +(function(back) { + const SETTINGS_FILE = "widbatwarn.json", + storage = require("Storage"), + translate = require("locale").translate; + + // initialize with default settings... + let s = { + buzz: true, + percentage: 10, + }; + // ...and overwrite them with any saved values + // This way saved values are preserved if a new version adds more settings + const saved = storage.readJSON(SETTINGS_FILE, 1) || {}; + for(const key in saved) { + s[key] = saved[key]; + } + + // creates a function to safe a specific setting, e.g. save('buzz')(true) + function save(key) { + return function(value) { + s[key] = value; + storage.write(SETTINGS_FILE, s); + WIDGETS["batwarn"].reload(); + }; + } + + const menu = { + "": {"title": "Battery Warning"}, + "< Back": back, + "Percentage": { + value: s.percentage, + min: 5, + max: 100, + step: 5, + onchange: save("percentage"), + }, + "Buzz": { + value: s.buzz, + format: b => translate(b?"Yes":"No"), + onchange: save("buzz"), + }, + }; + E.showMenu(menu); +}); \ No newline at end of file diff --git a/apps/widbatwarn/widget.js b/apps/widbatwarn/widget.js new file mode 100644 index 000000000..c5c2f2bf0 --- /dev/null +++ b/apps/widbatwarn/widget.js @@ -0,0 +1,59 @@ +(function() { + const SETTINGS_FILE = "widbatwarn.json"; + let settings; + + function loadSettings() { + settings = require("Storage").readJSON(SETTINGS_FILE, 1) || {}; + const DEFAULTS = { + buzz: true, + percentage: 10, + }; + Object.keys(DEFAULTS).forEach(k => { + if (settings[k]===undefined) settings[k] = DEFAULTS[k]; + }); + } + + function setting(key) { + if (!settings) { loadSettings(); } + return settings[key]; + } + + let warning = false; // did we show the warning already? + function check() { + if (Bangle.isCharging() + || E.getBattery()>setting("percentage")) { + require("notify").hide({id: "widbatwarn"}); + warning = false; + return; + } + if (warning) return; // already warned + warning = true; // only show once (until we recharge) + require("notify").show({ + size: 56, id: "widbatwarn", + // battery-low.png + icon: require("heatshrink").decompress(atob("jEYwgfchnM5nABaQJCBoQLSAhAL/Bf6bHAAYLpACgA==")), + title: "Low Battery", + render: a => { + g.setFont("6x8", 2).setFontAlign(-1, 0) + .setColor(-1).drawString("Battery: ", a.x+8, a.y+a.h/2) + .setColor(0xF800).drawString(`${E.getBattery()}%`, a.x+8+100, a.y+a.h/2); + }, + }); + if (setting("buzz")) Bangle.buzz(); + } + + Bangle.on("charging", check); + + function reload() { + loadSettings(); + // check right away, so user sees it work when fiddling with settings + check(); + } + + // we never draw anything, but 'area' and 'draw' are required + WIDGETS["batwarn"] = {width: 0, reload: reload, area: "tl", draw: () => {}}; + + // check every minute + // deliberately not right away, to prevent instant notifications in settings + setTimeout(check, 60000); +})(); \ No newline at end of file diff --git a/apps/widbatwarn/widget.png b/apps/widbatwarn/widget.png new file mode 100644 index 000000000..8a3031ee1 Binary files /dev/null and b/apps/widbatwarn/widget.png differ