diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog index bb8a292a0..398396c96 100644 --- a/apps/alarm/ChangeLog +++ b/apps/alarm/ChangeLog @@ -38,3 +38,6 @@ 0.35: Add automatic translation of more strings 0.36: alarm widget moved out of app 0.37: add message input and dated Events +0.38: Display date in locale + When switching 'repeat' from 'Workdays', 'Weekends' to 'Custom' preset Custom menu with previous selection + Display alarm label in delete prompt diff --git a/apps/alarm/app.js b/apps/alarm/app.js index 74007d04b..e97b61917 100644 --- a/apps/alarm/app.js +++ b/apps/alarm/app.js @@ -40,6 +40,14 @@ function handleFirstDayOfWeek(dow) { // Check the first day of week and update the dow field accordingly (alarms only!) alarms.filter(e => e.timer === undefined).forEach(a => a.dow = handleFirstDayOfWeek(a.dow)); +function getLabel(e) { + const dateStr = e.date && require("locale").date(new Date(e.date), 1); + return (e.timer + ? require("time_utils").formatDuration(e.timer) + : (dateStr ? `${dateStr} ${require("time_utils").formatTime(e.t)}` : require("time_utils").formatTime(e.t) + (e.rp ? ` ${decodeDOW(e)}` : "")) + ) + (e.msg ? " " + e.msg : ""); +} + function showMainMenu() { const menu = { "": { "title": /*LANG*/"Alarms & Timers" }, @@ -48,11 +56,7 @@ function showMainMenu() { }; alarms.forEach((e, index) => { - var label = (e.timer - ? require("time_utils").formatDuration(e.timer) - : (e.date ? `${e.date.substring(5,10)} ${require("time_utils").formatTime(e.t)}` : require("time_utils").formatTime(e.t) + (e.rp ? ` ${decodeDOW(e)}` : "")) - ) + (e.msg ? " " + e.msg : ""); - menu[label] = { + menu[getLabel(e)] = { value: e.on ? (e.timer ? iconTimerOn : iconAlarmOn) : (e.timer ? iconTimerOff : iconAlarmOff), onchange: () => setTimeout(e.timer ? showEditTimerMenu : showEditAlarmMenu, 10, e, index) }; @@ -184,7 +188,7 @@ function showEditAlarmMenu(selectedAlarm, alarmIndex, withDate) { if (!isNew) { menu[/*LANG*/"Delete"] = () => { - E.showPrompt(/*LANG*/"Are you sure?", { title: /*LANG*/"Delete Alarm" }).then((confirm) => { + E.showPrompt(getLabel(alarm) + "\n" + /*LANG*/"Are you sure?", { title: /*LANG*/"Delete Alarm" }).then((confirm) => { if (confirm) { alarms.splice(alarmIndex, 1); saveAndReload(); @@ -264,7 +268,7 @@ function showEditRepeatMenu(repeat, dow, dowChangeCallback) { }, /*LANG*/"Custom": { value: isCustom ? decodeDOW({ rp: true, dow: dow }) : false, - onchange: () => setTimeout(showCustomDaysMenu, 10, isCustom ? dow : EVERY_DAY, dowChangeCallback, originalRepeat, originalDow) + onchange: () => setTimeout(showCustomDaysMenu, 10, dow, dowChangeCallback, originalRepeat, originalDow) } }; @@ -372,7 +376,7 @@ function showEditTimerMenu(selectedTimer, timerIndex) { if (!keyboard) delete menu[/*LANG*/"Message"]; if (!isNew) { menu[/*LANG*/"Delete"] = () => { - E.showPrompt(/*LANG*/"Are you sure?", { title: /*LANG*/"Delete Timer" }).then((confirm) => { + E.showPrompt(getLabel(timer) + "\n" + /*LANG*/"Are you sure?", { title: /*LANG*/"Delete Timer" }).then((confirm) => { if (confirm) { alarms.splice(timerIndex, 1); saveAndReload(); diff --git a/apps/alarm/metadata.json b/apps/alarm/metadata.json index 29e71b3d9..28d48daab 100644 --- a/apps/alarm/metadata.json +++ b/apps/alarm/metadata.json @@ -2,7 +2,7 @@ "id": "alarm", "name": "Alarms & Timers", "shortName": "Alarms", - "version": "0.37", + "version": "0.38", "description": "Set alarms and timers on your Bangle", "icon": "app.png", "tags": "tool,alarm", diff --git a/apps/bwclk/README.md b/apps/bwclk/README.md index 5e2a7b55f..882d525f6 100644 --- a/apps/bwclk/README.md +++ b/apps/bwclk/README.md @@ -11,6 +11,7 @@ sub-items simply swipe up/down. To run an action (e.g. trigger home assistant), ![](screenshot_3.png) +Note: Check out the settings to change different themes. ## Settings - Screen: Normal (widgets shown), Dynamic (widgets shown if unlocked) or Full (widgets are hidden). diff --git a/apps/chargent/ChangeLog b/apps/chargent/ChangeLog index ae4aa0e36..3003cd07d 100644 --- a/apps/chargent/ChangeLog +++ b/apps/chargent/ChangeLog @@ -1,2 +1,3 @@ 0.01: First version 0.02: Support BangleJS2 +0.03: Added threshold diff --git a/apps/chargent/README.md b/apps/chargent/README.md index 56bc763b4..db93615a6 100644 --- a/apps/chargent/README.md +++ b/apps/chargent/README.md @@ -6,6 +6,8 @@ The first stage of charging Li-ion ends at ~80% capacity when the charge voltage This app has no UI and no configuration. To disable the app, you have to uninstall it. +New in v0.03: before the very first buzz, the average value after the peak is written to chargent.json and used as threshold for future charges. This reduces the time spent in the second charge stage. + Side notes - Full capacity is reached after charge current drops to an insignificant level. This is quite some time after charge voltage reached its peak / `E.getBattery()` returns 100. - This app starts buzzing some time after `E.getBattery()` returns 100 (~15min on my watch), and at least 5min after the peak to account for noise. diff --git a/apps/chargent/boot.js b/apps/chargent/boot.js index b02d00a8e..c62003a21 100644 --- a/apps/chargent/boot.js +++ b/apps/chargent/boot.js @@ -6,19 +6,27 @@ if (charging) { if (!id) { var max = 0; - var count = 0; + var cnt = 0; + var sum = 0; + var lim = (require('Storage').readJSON('chargent.json', true) || {}).limit || 0; id = setInterval(() => { - var battlvl = analogRead(pin); - if (max < battlvl) { - max = battlvl; - count = 0; + var val = analogRead(pin); + if (max < val) { + max = val; + cnt = 1; + sum = val; } else { - count++; - if (10 <= count) { // 10 * 30s == 5 min // TODO ? customizable - // TODO ? customizable - Bangle.buzz(500); - setTimeout(() => Bangle.buzz(500), 1000); + cnt++; + sum += val; + } + if (10 < cnt || (lim && lim <= max)) { // 10 * 30s == 5 min // TODO ? customizable + if (!lim) { + lim = sum / cnt; + require('Storage').writeJSON('chargent.json', {limit: lim}); } + // TODO ? customizable + Bangle.buzz(500); + setTimeout(() => Bangle.buzz(500), 1000); } }, 30*1000); } diff --git a/apps/chargent/metadata.json b/apps/chargent/metadata.json index e2e6f5a61..653cb7d74 100644 --- a/apps/chargent/metadata.json +++ b/apps/chargent/metadata.json @@ -1,6 +1,6 @@ { "id": "chargent", "name": "Charge Gently", - "version": "0.02", + "version": "0.03", "description": "When charging, reminds you to disconnect the watch to prolong battery life.", "icon": "icon.png", "type": "bootloader", @@ -9,5 +9,8 @@ "readme": "README.md", "storage": [ {"name": "chargent.boot.js", "url": "boot.js"} + ], + "data": [ + {"name": "chargent.json"} ] } diff --git a/apps/fuzzyw/ChangeLog b/apps/fuzzyw/ChangeLog index 206efb10f..dd73475f9 100644 --- a/apps/fuzzyw/ChangeLog +++ b/apps/fuzzyw/ChangeLog @@ -1,3 +1,4 @@ 0.01: First release 0.02: Move translations to locale module (removed watch settings, now pick language in Bangle App Loader, More..., Settings) -0.03: Change for fast loading, use widget_utils to hide widgets \ No newline at end of file +0.03: Change for fast loading, use widget_utils to hide widgets +0.04: Add animation when display changes \ No newline at end of file diff --git a/apps/fuzzyw/README.md b/apps/fuzzyw/README.md index 49d0fe0d5..062c9ac25 100644 --- a/apps/fuzzyw/README.md +++ b/apps/fuzzyw/README.md @@ -16,7 +16,6 @@ Most translations are taken from the original Fuzzy Text International code. ## TODO * Bold hour word (as the pebble version has) -* Animation when changing time? ## References Based on Pebble app Fuzzy Text International: https://github.com/hallettj/Fuzzy-Text-International diff --git a/apps/fuzzyw/fuzzyw.app.js b/apps/fuzzyw/fuzzyw.app.js index e185e2ccf..8bc51710f 100644 --- a/apps/fuzzyw/fuzzyw.app.js +++ b/apps/fuzzyw/fuzzyw.app.js @@ -33,13 +33,17 @@ ] }; -let text_scale = 3.5; +let text_scale = 4; let timeout = 2.5*60; let drawTimeout; +let animInterval; +let time_string = ""; +let time_string_old = ""; +let time_string_old_wrapped = ""; let loadSettings = function() { settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'showWidgets': false}; -} +}; let queueDraw = function(seconds) { let millisecs = seconds * 1000; @@ -48,10 +52,7 @@ let queueDraw = function(seconds) { drawTimeout = undefined; draw(); }, millisecs - (Date.now() % millisecs)); -} - -const h = g.getHeight(); -const w = g.getWidth(); +}; let getTimeString = function(date) { let segment = Math.round((date.getMinutes()*60 + date.getSeconds() + 1)/300); @@ -63,18 +64,47 @@ let getTimeString = function(date) { f_string = f_string.replace('$2', fuzzy_string.hours[(hour + 1) % 12]); } return f_string; -} +}; let draw = function() { - let time_string = getTimeString(new Date()).replace('*', ''); - // print(time_string); - g.setFont('Vector', (h-24*2)/text_scale); - g.setFontAlign(0, 0); - g.clearRect(0, 24, w, h-24); - g.setColor(g.theme.fg); - g.drawString(g.wrapString(time_string, w).join("\n"), w/2, h/2); + time_string = getTimeString(new Date()).replace('*', ''); + //print(time_string); + if (time_string != time_string_old) { + g.setFont('Vector', R.h/text_scale).setFontAlign(0, 0); + animate(3); + } queueDraw(timeout); -} +}; + +let animate = function(step) { + if (animInterval) clearInterval(animInterval); + let time_string_new_wrapped = g.wrapString(time_string, R.w).join("\n"); + slideX = 0; + animInterval = setInterval(function() { + let time_start = getTime() + //blank old time + g.setColor(g.theme.bg); + g.drawString(time_string_old_wrapped, R.x + R.w/2 + slideX, R.y + R.h/2); + g.drawString(time_string_new_wrapped, R.x - R.w/2 + slideX, R.y + R.h/2); + g.setColor(g.theme.fg); + slideX += step; + let stop = false; + if (slideX>=R.w) { + slideX=R.w; + stop = true; + } + //draw shifted new time + g.drawString(time_string_old_wrapped, R.x + R.w/2 + slideX, R.y + R.h/2); + g.drawString(time_string_new_wrapped, R.x - R.w/2 + slideX, R.y + R.h/2); + if (stop) { + time_string_old = time_string; + clearInterval(animInterval); + animInterval=undefined; + time_string_old_wrapped = time_string_new_wrapped; + } + print(Math.round((getTime() - time_start)*1000)) + }, 30); +}; g.clear(); loadSettings(); @@ -95,6 +125,8 @@ Bangle.setUI({ // Called to unload all of the clock app if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = undefined; + if (animInterval) clearInterval(animInterval); + animInterval = undefined; require('widget_utils').show(); // re-show widgets } }); @@ -106,5 +138,6 @@ if (settings.showWidgets) { require("widget_utils").swipeOn(); // hide widgets, make them visible with a swipe } +R = Bangle.appRect; draw(); } \ No newline at end of file diff --git a/apps/fuzzyw/metadata.json b/apps/fuzzyw/metadata.json index d1040fda3..97f060866 100644 --- a/apps/fuzzyw/metadata.json +++ b/apps/fuzzyw/metadata.json @@ -2,7 +2,7 @@ "id":"fuzzyw", "name":"Fuzzy Text Clock", "shortName": "Fuzzy Text", - "version": "0.03", + "version": "0.04", "description": "An imprecise clock for when you're not in a rush", "readme": "README.md", "icon":"fuzzyw.png", diff --git a/apps/happyclk/ChangeLog b/apps/happyclk/ChangeLog index 759f68777..e87114779 100644 --- a/apps/happyclk/ChangeLog +++ b/apps/happyclk/ChangeLog @@ -1 +1,2 @@ -0.01: New app! \ No newline at end of file +0.01: New app! +0.02: Added settings to show/hide widgets and settings for different styles. \ No newline at end of file diff --git a/apps/happyclk/README.md b/apps/happyclk/README.md index 3540b5aca..d5b8752fb 100644 --- a/apps/happyclk/README.md +++ b/apps/happyclk/README.md @@ -14,6 +14,10 @@ Here you can see an example of a locked bangle with a low battery: ![](screenshot_3.png) +## Settings +- Screen: Normal (widgets shown), Dynamic (widgets shown if unlocked) or Full (widgets are hidden). +- Theme: Select your custom theme, independent of system settings. + ## Creator - [David Peer](https://github.com/peerdavid). diff --git a/apps/happyclk/happyclk.app.js b/apps/happyclk/happyclk.app.js index ad8f80cbf..8e22b6e1e 100644 --- a/apps/happyclk/happyclk.app.js +++ b/apps/happyclk/happyclk.app.js @@ -1,6 +1,82 @@ /************************************************ * Happy Clock */ + + +const storage = require('Storage'); +const widget_utils = require("widget_utils"); + + +/************************************************ + * Settings + */ +const SETTINGS_FILE = "happyclk.setting.json"; + +let settings = { + color: "Dark", + screen: "Dynamic" +}; + +let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings; +for (const key in saved_settings) { + settings[key] = saved_settings[key]; +} + +var color_map = { + "Dark":{ + fg: "#fff", + bg: "#000", + eye: "#fff", + eyePupils: "#000" + }, + "Black":{ + fg: "#fff", + bg: "#000", + eye: "#000", + eyePupils: "#fff" + }, + "White":{ + fg: "#000", + bg: "#fff", + eye: "#fff", + eyePupils: "#000" + }, + "Blue":{ + fg: "#fff", + bg: "#00f", + eye: "#fff", + eyePupils: "#000" + }, + "Green":{ + fg: "#000", + bg: "#0f0", + eye: "#fff", + eyePupils: "#000" + }, + "Red":{ + fg: "#fff", + bg: "#f00", + eye: "#fff", + eyePupils: "#000" + }, + "Purple":{ + fg: "#fff", + bg: "#f0f", + eye: "#fff", + eyePupils: "#000" + }, + "Yellow":{ + fg: "#000", + bg: "#ff0", + eye: "#fff", + eyePupils: "#000" + } +}; +var colors = color_map[settings.color]; + +/************************************************ + * Globals + */ var W = g.getWidth(),R=W/2; var H = g.getHeight(); var drawTimeout; @@ -10,6 +86,16 @@ var drawTimeout; * HELPER */ +let isFullscreen = function() { + var s = settings.screen.toLowerCase(); + if(s == "dynamic"){ + return Bangle.isLocked(); + } else { + return s == "full"; + } + }; + + // Based on the great multi clock from https://github.com/jeffmer/BangleApps/ Graphics.prototype.drawPupils = function(cx, cy, r1, dx, dy, angle) { angle = angle % 360; @@ -19,11 +105,12 @@ Graphics.prototype.drawPupils = function(cx, cy, r1, dx, dy, angle) { g.setColor(g.theme.fg); g.fillCircle(cx, cy, 32); - g.setColor(g.theme.bg); + + g.setColor(colors.eye); g.fillCircle(cx, cy, 27); g.fillCircle(cx+dx, cy+dy, 28); - g.setColor(g.theme.fg); + g.setColor(colors.eyePupils); g.fillCircle(x, y, 8); g.fillCircle(x+1, y, 8); }; @@ -85,6 +172,7 @@ let drawEyes = function(){ let drawSmile = function(isLocked){ + g.setColor(colors.fg); var y = 120; var o = parseInt(E.getBattery()*0.8); @@ -100,6 +188,9 @@ let drawSmile = function(isLocked){ } let drawEyeBrow = function(){ + if(!isFullscreen()) return; + + g.setColor(colors.fg); var w = 6; for(var i = 0; i < w; i++){ g.drawLine(25, 25+i, 70, 15+i%3); @@ -108,6 +199,15 @@ let drawEyeBrow = function(){ } +let drawWidgets = function(){ + if (isFullscreen()) { + widget_utils.hide(); + } else { + Bangle.drawWidgets(); + } +} + + let draw = function(){ // Queue draw in one minute @@ -118,12 +218,16 @@ let draw = function(){ } let drawHelper = function(isLocked){ + g.setColor(g.theme.bg); + + g.fillRect(0, isFullscreen() ? 0 : 24, W, H); g.setColor(g.theme.fg); - g.reset().clear(); drawEyes(); drawEyeBrow(); drawSmile(isLocked); + + drawWidgets(); } @@ -140,6 +244,15 @@ Bangle.on('lcdPower',on=>{ }); Bangle.on('lock', function(isLocked) { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + + if(!isLocked && settings.screen.toLowerCase() == "dynamic"){ + // If we have to show the widgets again, we load it from our + // cache and not through Bangle.loadWidgets as its much faster! + widget_utils.show(); + } + draw(isLocked); }); @@ -162,15 +275,9 @@ let queueDraw = function() { // Show launcher when middle button pressed Bangle.setUI("clock"); Bangle.loadWidgets(); -/* - * we are not drawing the widgets as we are taking over the whole screen - * so we will blank out the draw() functions of each widget and change the - * area to the top bar doesn't get cleared. - */ -require('widget_utils').hide(); // Clear the screen once, at startup and draw clock -// g.setTheme({bg:"#fff",fg:"#000",dark:false}); +g.setTheme({bg:colors.bg,fg:colors.fg,dark:false}); draw(); // After drawing the watch face, we can draw the widgets diff --git a/apps/happyclk/happyclk.settings.js b/apps/happyclk/happyclk.settings.js new file mode 100644 index 000000000..dd9f2f675 --- /dev/null +++ b/apps/happyclk/happyclk.settings.js @@ -0,0 +1,43 @@ +(function(back) { + const SETTINGS_FILE = "happyclk.setting.json"; + + // initialize with default settings... + const storage = require('Storage') + let settings = { + color: "Dark", + screen: "Dynamic" + }; + let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings; + for (const key in saved_settings) { + settings[key] = saved_settings[key] + } + + function save() { + storage.write(SETTINGS_FILE, settings) + } + + var colorOptions = ["Dark", "Black", "White", "Blue", "Green", "Red", "Purple", "Yellow"]; + var screenOptions = ["Normal", "Dynamic", "Full"]; + E.showMenu({ + '': { 'title': 'Happy Clock' }, + '< Back': back, + 'Screen': { + value: 0 | screenOptions.indexOf(settings.screen), + min: 0, max: screenOptions.length-1, + format: v => screenOptions[v], + onchange: v => { + settings.screen = screenOptions[v]; + save(); + }, + }, + 'Theme': { + value: 0 | colorOptions.indexOf(settings.color), + min: 0, max: colorOptions.length-1, + format: v => colorOptions[v], + onchange: v => { + settings.color = colorOptions[v]; + save(); + }, + }, + }); +}) diff --git a/apps/happyclk/metadata.json b/apps/happyclk/metadata.json index 2388db667..e5129b0f0 100644 --- a/apps/happyclk/metadata.json +++ b/apps/happyclk/metadata.json @@ -3,7 +3,7 @@ "name": "Happy Clock", "shortName":"Happy Clock", "icon": "happyclk.png", - "version":"0.01", + "version":"0.02", "readme": "README.md", "supports": ["BANGLEJS2"], "description": "A happy clock :)", @@ -12,10 +12,13 @@ "screenshots": [ {"url":"screenshot_1.png"}, {"url":"screenshot_2.png"}, - {"url":"screenshot_3.png"} + {"url":"screenshot_3.png"}, + {"url":"screenshot_4.png"}, + {"url":"screenshot_5.png"} ], "storage": [ {"name":"happyclk.app.js","url":"happyclk.app.js"}, - {"name":"happyclk.img","url":"happyclk.icon.js","evaluate":true} + {"name":"happyclk.img","url":"happyclk.icon.js","evaluate":true}, + {"name":"happyclk.settings.js","url":"happyclk.settings.js"} ] } diff --git a/apps/happyclk/screenshot_2.png b/apps/happyclk/screenshot_2.png index 5bb00bc38..49c09ee31 100644 Binary files a/apps/happyclk/screenshot_2.png and b/apps/happyclk/screenshot_2.png differ diff --git a/apps/happyclk/screenshot_4.png b/apps/happyclk/screenshot_4.png new file mode 100644 index 000000000..b84e41ab1 Binary files /dev/null and b/apps/happyclk/screenshot_4.png differ diff --git a/apps/happyclk/screenshot_5.png b/apps/happyclk/screenshot_5.png new file mode 100644 index 000000000..401bb0c51 Binary files /dev/null and b/apps/happyclk/screenshot_5.png differ diff --git a/apps/iconlaunch/ChangeLog b/apps/iconlaunch/ChangeLog index 0c33a4871..6f0e8194c 100644 --- a/apps/iconlaunch/ChangeLog +++ b/apps/iconlaunch/ChangeLog @@ -20,3 +20,4 @@ still be loaded when they weren't supposed to. 0.15: Ensure that we hide widgets if in fullscreen mode (So that widgets are still hidden if launcher is fast-loaded) +0.16: Use firmware provided E.showScroller method diff --git a/apps/iconlaunch/metadata.json b/apps/iconlaunch/metadata.json index 27f6386d3..435a29b39 100644 --- a/apps/iconlaunch/metadata.json +++ b/apps/iconlaunch/metadata.json @@ -2,7 +2,7 @@ "id": "iconlaunch", "name": "Icon Launcher", "shortName" : "Icon launcher", - "version": "0.15", + "version": "0.16", "icon": "app.png", "description": "A launcher inspired by smartphones, with an icon-only scrollable menu.", "tags": "tool,system,launcher", diff --git a/apps/inspire/ChangeLog b/apps/inspire/ChangeLog index 267ee22c2..e8e154f2f 100644 --- a/apps/inspire/ChangeLog +++ b/apps/inspire/ChangeLog @@ -1 +1,2 @@ 0.01: First public version +0.02: Disable screen lock when breathing diff --git a/apps/inspire/README.md b/apps/inspire/README.md index f5f8e3aa9..43df1b760 100644 --- a/apps/inspire/README.md +++ b/apps/inspire/README.md @@ -2,7 +2,7 @@ A minimalistic app that will help you practive breathing. -Author: Written by pancake in 2022, powered by insomnia +Author: Written by pancake in 2022, updated in 2023, powered by insomnia ## Features @@ -10,6 +10,7 @@ Author: Written by pancake in 2022, powered by insomnia * [x] Tap to start * [x] Subtle vibrations * [x] Drag to pause breathing +* [x] Dont lock screen while breathing * [ ] Automatic buzz every hour during day ## Screenshots diff --git a/apps/inspire/app.js b/apps/inspire/app.js index 92b2c4ef2..818a6af76 100644 --- a/apps/inspire/app.js +++ b/apps/inspire/app.js @@ -14,6 +14,7 @@ var mode = 0; var sin = 0; var dragged = 0; var lastTime = Date.now(); + function breath(t) { var r = Math.abs(Math.sin(t / 100)) * w2; g.fillCircle(w/2,h/2, r); @@ -26,7 +27,7 @@ setTimeout(()=>{Bangle.buzz(60);}, 500); function showTouchScreen() { g.setColor(1,1,1); - g.fillCircle (w2, h2, h2-5); + g.fillCircle(w2, h2, h2-5); g.setColor(0,0,0); g.setFont("Vector", 32); g.drawString("Tap to", w/6, h2-fs); @@ -40,7 +41,7 @@ g.clear(); function animateCircle() { g.clear(); g.setColor(1,1,1); - g.fillCircle (w2, h2, radius); + g.fillCircle(w2, h2, radius); radius-=2; if (radius < 40) { breathing = true; @@ -68,6 +69,9 @@ function main() { return; } started = true; + Bangle.setLCDPower(1); + Bangle.setLocked(0); + Bangle.setLCDTimeout(0); animateCircle(); Bangle.buzz(40); } @@ -78,48 +82,48 @@ function main() { main(); function startBreathing() { -var cicles = 3; -g.setFont("Vector", fs); - -var interval = setInterval(function() { -if (lastTime + 10 > Date.now()) { - return; -} - lastTime = Date.now(); - g.setColor(0, 0, 0); - g.clear(); - - g.setColor(0, 0.5, 1); - var b = breath(count); - g.setColor(0.5, 0.5, 1); - var c = breath(count + 50); - count++; - g.setColor(1, 1, 1); - if (b < c) { - g.drawString("inspire",8,ty); - if (mode) { - mode = 0; - Bangle.buzz(20); - if (!dragged ) { - cicles--; + var cicles = 3; + g.setFont("Vector", fs); + + function breathTime() { + if (lastTime + 10 > Date.now()) { + return; + } + lastTime = Date.now(); + g.setColor(0, 0, 0); + g.clear(); + + g.setColor(0, 0.5, 1); + var b = breath(count); + g.setColor(0.5, 0.5, 1); + var c = breath(count + 50); + count++; + g.setColor(1, 1, 1); + if (b < c) { + g.drawString("inspire",8,ty); + if (mode) { + mode = 0; + Bangle.buzz(20); + if (!dragged ) { + cicles--; + } + } + } else { + g.drawString("expire",8,ty); + if (!mode) { + mode = 1; + Bangle.buzz(20); } } - } else { - g.drawString("expire",8,ty); - if (!mode) { - mode = 1; - Bangle.buzz(20); + g.drawString(cicles, w-fs, ty); + if (cicles < 1) { + clearInterval(interval); + g.clear(); + g.drawString("Thanks for",20,h/3); + g.drawString(" breathing!",20,(h/3) + 16); + Bangle.showClock(); } - } - g.drawString(cicles, w-fs, ty); - if (cicles < 1) { - clearInterval(interval); - g.clear(); - g.drawString("Thanks for",20,h/3); - g.drawString(" breathing!",20,(h/3) + 16); - Bangle.showClock(); - } dragged = 0; - -}, 4); + } + var interval = setInterval(breathTime, 4); } diff --git a/apps/inspire/metadata.json b/apps/inspire/metadata.json index 85b7365be..3ffbc40e7 100644 --- a/apps/inspire/metadata.json +++ b/apps/inspire/metadata.json @@ -2,7 +2,7 @@ "id": "inspire", "name": "Inspire Breathing", "shortName": "Inspire", - "version": "0.01", + "version": "0.02", "description": "exercise breathing every now and then", "icon": "app-icon.png", "tags": "tools,health", diff --git a/apps/mtnclock/README.md b/apps/mtnclock/README.md index 58538509d..441754b83 100644 --- a/apps/mtnclock/README.md +++ b/apps/mtnclock/README.md @@ -4,7 +4,7 @@ Based on the Pebble watchface Weather Land. Mountain Pass Clock changes depending on time (day/night) and weather conditions. -This clock requires Gadgetbridge and an app that Gadgetbridge can use to get the current weather from OpenWeatherMap (e.g. Weather Notification). To set up Gadgetbridge and weather, see https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Weather. +This clock requires Gadgetbridge and an app that Gadgetbridge can use to get the current weather from OpenWeatherMap (e.g. Weather Notification), or a Bangle app that will update weather.json such as OWM Weather. To set up Gadgetbridge and weather, see https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Weather. The scene will change according to the following OpenWeatherMap conditions: clear, cloudy, overcast, lightning, drizzle, rain, fog and snow. Each weather condition has night/day scenes. diff --git a/apps/mtnclock/app.js b/apps/mtnclock/app.js index 28ba25882..c6adc7706 100644 --- a/apps/mtnclock/app.js +++ b/apps/mtnclock/app.js @@ -323,11 +323,28 @@ function setWeather() { draw(a); } +function readWeather() { + var weatherJson = require("Storage").readJSON('weather.json', 1); + // save updated weather data if available and it has been an hour since last updated + if (weatherJson !== undefined && (data.time === undefined || (data.time + 3600000) < weatherJson.weather.time)) { + data = { + time: weatherJson.weather.time, + temp: weatherJson.weather.temp, + code: weatherJson.weather.code + }; + require("Storage").writeJSON('mtnclock.json', data); + } +} + const _GB = global.GB; global.GB = (event) => { if (event.t==="weather") { - data = event; - require("Storage").write('mtnclock.json', event); + data = { + temp: event.temp, + code: event.code, + time: Date.now() + }; + require("Storage").writeJSON('mtnclock.json', data); setWeather(); } if (_GB) setTimeout(_GB, 0, event); @@ -340,11 +357,13 @@ function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function() { drawTimeout = undefined; + readWeather(); setWeather(); queueDraw(); }, 60000 - (Date.now() % 60000)); } queueDraw(); +readWeather(); setWeather(); Bangle.setUI("clock"); diff --git a/apps/mtnclock/metadata.json b/apps/mtnclock/metadata.json index a3a173069..82a0cccab 100644 --- a/apps/mtnclock/metadata.json +++ b/apps/mtnclock/metadata.json @@ -2,7 +2,7 @@ "id": "mtnclock", "name": "Mountain Pass Clock", "shortName": "Mtn Clock", - "version": "0.01", + "version": "0.02", "description": "A clock that changes scenery based on time and weather.", "readme":"README.md", "icon": "app.png", diff --git a/apps/powermanager/ChangeLog b/apps/powermanager/ChangeLog index a83e8c676..06f38d399 100644 --- a/apps/powermanager/ChangeLog +++ b/apps/powermanager/ChangeLog @@ -3,3 +3,4 @@ 0.03: Use default Bangle formatter for booleans 0.04: Remove calibration with current voltage (Calibrate->Auto) as it is now handled by settings app Allow automatic calibration on every charge longer than 3 hours +0.05: Add back button to settings menu. diff --git a/apps/powermanager/metadata.json b/apps/powermanager/metadata.json index 0777feee3..456831aa9 100644 --- a/apps/powermanager/metadata.json +++ b/apps/powermanager/metadata.json @@ -2,7 +2,7 @@ "id": "powermanager", "name": "Power Manager", "shortName": "Power Manager", - "version": "0.04", + "version": "0.05", "description": "Allow configuration of warnings and thresholds for battery charging and display.", "icon": "app.png", "type": "bootloader", diff --git a/apps/powermanager/settings.js b/apps/powermanager/settings.js index 9eeb29e00..fe4719275 100644 --- a/apps/powermanager/settings.js +++ b/apps/powermanager/settings.js @@ -23,6 +23,7 @@ '': { 'title': 'Power Manager' }, + "< Back" : back, 'Monotonic percentage': { value: !!settings.forceMonoPercentage, onchange: v => { diff --git a/apps/qcenter/ChangeLog b/apps/qcenter/ChangeLog index 900b9017c..436949dc9 100644 --- a/apps/qcenter/ChangeLog +++ b/apps/qcenter/ChangeLog @@ -1,2 +1,4 @@ 0.01: New App! 0.02: Fix fast loading on swipe to clock +0.03: Adds a setting for going back to clock on a timeout +0.04: Fix timeouts closing fast loaded apps \ No newline at end of file diff --git a/apps/qcenter/app.js b/apps/qcenter/app.js index be28db3b6..bd22c87e1 100644 --- a/apps/qcenter/app.js +++ b/apps/qcenter/app.js @@ -110,6 +110,8 @@ let layout = new Layout({ }, { remove: ()=>{ Bangle.removeListener("swipe", onSwipe); + Bangle.removeListener("touch", updateTimeout); + if (timeout) clearTimeout(timeout); delete Graphics.prototype.setFont8x12; } }); @@ -117,6 +119,16 @@ g.clear(); layout.render(); Bangle.drawWidgets(); +let timeout; +const updateTimeout = function(){ +if (settings.timeout){ + if (timeout) clearTimeout(timeout); + timeout = setTimeout(Bangle.showClock,settings.timeout*1000); + } +}; + +updateTimeout(); + // swipe event listener for exit gesture let onSwipe = function (lr, ud) { if(exitGesture == "swipeup" && ud == -1) Bangle.showClock(); @@ -126,4 +138,5 @@ let onSwipe = function (lr, ud) { } Bangle.on("swipe", onSwipe); +Bangle.on("touch", updateTimeout); } diff --git a/apps/qcenter/metadata.json b/apps/qcenter/metadata.json index a325de10f..cd3e350a4 100644 --- a/apps/qcenter/metadata.json +++ b/apps/qcenter/metadata.json @@ -2,7 +2,7 @@ "id": "qcenter", "name": "Quick Center", "shortName": "QCenter", - "version": "0.02", + "version": "0.04", "description": "An app for quickly launching your favourite apps, inspired by the control centres of other watches.", "icon": "app.png", "tags": "", diff --git a/apps/qcenter/settings.js b/apps/qcenter/settings.js index 2c97f8a5f..5d38b079e 100644 --- a/apps/qcenter/settings.js +++ b/apps/qcenter/settings.js @@ -49,6 +49,11 @@ E.showMenu(exitGestureMenu); }; + // Set Timeout + mainmenu["Timeout: " + (settings.timeout ? (settings.timeout+"s") : "Off")] = function () { + E.showMenu(timeoutMenu); + }; + //List all pinned apps, redirecting to menu with options to unpin and reorder pinnedApps.forEach((app, i) => { mainmenu[app.name] = function () { @@ -129,5 +134,22 @@ showMainMenu(); }; + // menu for setting timeout + var timeoutMenu = { + "": { title: "Timeout", back: showMainMenu } + }; + timeoutMenu["Off"] = function () { + save("timeout", 0); + showMainMenu(); + }; + let timeoutvalues = [10,20,30,60]; + for (c in timeoutvalues){ + let v = timeoutvalues[c]; + timeoutMenu[v+"s"] = function () { + save("timeout", v); + showMainMenu(); + }; + } + showMainMenu(); }); diff --git a/apps/sched/interface.html b/apps/sched/interface.html new file mode 100644 index 000000000..366e597a2 --- /dev/null +++ b/apps/sched/interface.html @@ -0,0 +1,223 @@ + + + + + + + + + +

Manage dated events

+ +
+ +
+ + + + + + + + + + + +
DateSummary
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + diff --git a/apps/sched/metadata.json b/apps/sched/metadata.json index 2a1b0f8ca..42c3aaa12 100644 --- a/apps/sched/metadata.json +++ b/apps/sched/metadata.json @@ -10,6 +10,7 @@ "provides_modules" : ["sched"], "default" : true, "readme": "README.md", + "interface": "interface.html", "storage": [ {"name":"sched.boot.js","url":"boot.js"}, {"name":"sched.js","url":"sched.js"}, diff --git a/apps/tempgraph/ChangeLog b/apps/tempgraph/ChangeLog new file mode 100644 index 000000000..58dd75a19 --- /dev/null +++ b/apps/tempgraph/ChangeLog @@ -0,0 +1,2 @@ +0.01: 3/Feb/2023 Added 'Temperature Graph' app to depository. + diff --git a/apps/tempgraph/README.md b/apps/tempgraph/README.md new file mode 100644 index 000000000..919c20267 --- /dev/null +++ b/apps/tempgraph/README.md @@ -0,0 +1,36 @@ +# Temperature Graph + +**Temperature Graph** (tempgraph) is a Bangle.js 2 app for recording graphs of the temperature for various time periods from 10 minutes to 7 days long. It samples the watch's temperature sensor 150 times while creating a graph, regardless of the time period selected. + +### Menu Options +* **Widgets** Toggles the watch's widgets on and off. With them off gives you a bigger graph when viewing it. + +* **Duration** Select the time period for drawing the graph, from 10 minutes to 7 days long. + +* **Draw Graph** Draws the graph. + * Tapping the screen toggles the graph between Celsius (red) and Fahrenheit (blue). + * Pressing the watch button takes you back to the menu. **Note:** While the graph can still be viewed after returning to the menu, you can't continue recording it if you had returned to the menu before the time period was up. The graph is saved in the watch though so it's still there the next time you start the app. + +* **Show Graph** Shows the last drawn graph. + * Tapping the screen toggles the graph between Celsius (red) and Fahrenheit (blue). + * Pressing the watch button takes you back to the menu. + +* **Save Graph** Sends a screengrab of the graph to the Espruino Web IDE from where you can save it as you would any image on a webpage. + +* **Save Data** Sends a CSV file of the graph's temperature data to the Espruino Web IDE where you can save it for further use. I suggest you use the Espruino Web IDE's Terminal Logger (selected in the IDE's Settings/General) to record the data as it's sent. This is the easiest way to save it as a text file. + +* **Show Temp** Shows the current temperature. + +### Note +Using the watch in a normal fashion can raise the temperature it's sensing to quite a few degrees above the surrounding temperature and it may take half an hour or so to drop to close to the surrounding temperature. After that it seems to give quite accurate readings, assuming the thermometer I've been comparing it to is itself reasonably accurate. So best to load the app then not touch the watch for half an hour before starting a recording. This is assuming you're not wearing the app and are just using it to record the temperature where you've put the watch. You could of course wear it and it'll still draw a graph, which might also be useful. + +### Screenshots +![](screenshot_1.png) +![](screenshot_2.png) +![](screenshot_3.png) + +### Creator +Carl Read ([mail](mailto:cread98@orcon.net.nz), [github](https://github.com/CarlR9)) + +#### License +[MIT License](LICENSE) diff --git a/apps/tempgraph/app-icon.js b/apps/tempgraph/app-icon.js new file mode 100644 index 000000000..50aae4c01 --- /dev/null +++ b/apps/tempgraph/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+goA/AH4AgrHXABFYF0XXkYAK64utGENYFxoABSTxeHXYJglF+UAAIQvEBApfhE4UAF4IDBFwZf/X7hfsR4K/tL96/vRwpf/X/5fJGYK/tL9u02i/tF4KOFL/6/XF4ZftR4K/tL96/vRwpf/X/5fJGYK/tL96/vRwpf/X7gADF8ouBGA4v/F/6/urAmGABFYF7pgIL0owPF0KSC64AIRj4A/AH4ACA=")) \ No newline at end of file diff --git a/apps/tempgraph/app.js b/apps/tempgraph/app.js new file mode 100644 index 000000000..a0bb3016b --- /dev/null +++ b/apps/tempgraph/app.js @@ -0,0 +1,395 @@ +// Temperature Graph +// BangleJS Script + +Bangle.setBarometerPower(true,"tempgraph"); +Bangle.loadWidgets(); +var wids=WIDGETS; +var widsOn=true; +var rm=null; +var gt=null; +var dg=null; +var Layout=require("Layout"); +var C=true; +var temp,tempMode,readErrCnt,watchButton2; + +var graph=require("Storage").readJSON("tempgraph.json",true); +if(graph==undefined) { + graph=[]; +} + +var timesData=[ + // dur=duration, u=time units, d=divisions on graph, s=seconds per unit. + {dur:10,u:"Mins",d:5,s:60}, + {dur:20,u:"Mins",d:4,s:60}, + {dur:30,u:"Mins",d:3,s:60}, + {dur:40,u:"Mins",d:4,s:60}, + {dur:1,u:"Hr",d:4,s:3600}, + {dur:2,u:"Hrs",d:4,s:3600}, + {dur:3,u:"Hrs",d:3,s:3600}, + {dur:4,u:"Hrs",d:4,s:3600}, + {dur:6,u:"Hrs",d:6,s:3600}, + {dur:8,u:"Hrs",d:4,s:3600}, + {dur:12,u:"Hrs",d:6,s:3600}, + {dur:16,u:"Hrs",d:4,s:3600}, + {dur:20,u:"Hrs",d:5,s:3600}, + {dur:1,u:"Day",d:4,s:3600}, + {dur:2,u:"Days",d:4,s:86400}, + {dur:3,u:"Days",d:3,s:86400}, + {dur:4,u:"Days",d:4,s:86400}, + {dur:5,u:"Days",d:5,s:86400}, + {dur:6,u:"Days",d:6,s:86400}, + {dur:7,u:"Days",d:7,s:86400} +]; +var times=[]; +for(n=0;n{ + temp=p.temperature; + if(tempMode=="drawGraph"&&graph.length>0&&Math.abs(graph[graph.length-1].temp-temp)>10&&readErrCnt<2){ + // A large change in temperature may be a reading error. ie. A 0C or less reading after + // a 20C reading. So if this happens, the reading is repeated up to 2 times to hopefully + // skip such errors. + readErrCnt++; + print("readErrCnt "+readErrCnt); + return; + } + clearInterval(gt); + readErrCnt=0; + switch (tempMode){ + case "showTemp": + showT(); + break; + case "drawGraph": + var date=new Date(); + var dateStr=require("locale").date(date).trim(); + var hrs=date.getHours(); + var mins=date.getMinutes(); + var secs=date.getSeconds(); + graph.push({ + temp:temp, + date:dateStr, + hrs:hrs, + mins:mins, + secs:secs + }); + if(graph.length==1){ + graph[0].dur=durInd; + } + require("Storage").writeJSON("tempgraph.json", graph); + if(graph.length==150){ + clearInterval(dg); + } + drawG(); + } + }); +} + +function getTemp(){ + readErrCnt=0; + gt = setInterval(getT,800); +} + +function setButton(){ + var watchButton=setWatch(function(){ + clearInterval(gt); + clearInterval(dg); + clearWatch(watchButton); + Bangle.removeListener("touch",screenTouch); + openMenu(); + },BTN); + Bangle.on('touch',screenTouch); +} + +function setButton2(){ + watchButton2=setWatch(function(){ + clearWatch(watchButton2); + openMenu(); + },BTN); +} + +function zPad(n){ + return n.toString().padStart(2,0); +} + +function screenTouch(n,ev){ + if(ev.y>23&&ev.y<152){ + C=C==false; + drawG(false); + } +} + +function drawG(){ + function cf(t){ + if(C){ + return t; + } + return getF(t); + } + drawWids(); + var top=1; + var bar=21; + var barBot=175-22; + if(widsOn){ + top=25; + bar=bar+24; + barBot=barBot-24; + } + var low=graph[0].temp; + var hi=low; + for(n=0;nt){ + low=t; + } + if(hi10){ + div=5; + } + if(C){ + g.setColor(1,0,0); + }else{ + g.setColor(0,0,1); + } + var step=(barBot-bar)/((tempHi-tempLow)/div); + for(n=0;nexit()}, + ],lazy:true + }); + drawWids(); + messageLO.render(); +} + +function showT(){ + tempLO.lab1.label=tempLO.lab3.label; + tempLO.lab2.label=tempLO.lab4.label; + tempLO.lab3.label=tempLO.lab5.label; + tempLO.lab4.label=tempLO.lab6.label; + tempLO.lab5.label=temp.toFixed(2)+"C"; + tempLO.lab6.label=getF(temp).toFixed(2)+"F"; + tempLO.render(); +} + +function exit(){ + clearWatch(watchButton2); + openMenu(); +} + +function showTemp(){ + tempMode="showTemp"; + setButton2(); + tempLO=new Layout({ + type:"v",c:[ + {type:"h",c:[ + {type:"txt",pad:5,col:"#f77",font:"6x8:2",label:" ",id:"lab1"}, + {type:"txt",pad:5,col:"#77f",font:"6x8:2",label:" ",id:"lab2"} + ]}, + {type:"h",c:[ + {type:"txt",pad:5,col:"#f77",font:"6x8:2",label:" ",id:"lab3"}, + {type:"txt",pad:5,col:"#77f",font:"6x8:2",label:" ",id:"lab4"} + ]}, + {type:"h",c:[ + {type:"txt",pad:5,col:"#f00",font:"6x8:2",label:" ",id:"lab5"}, + {type:"txt",pad:5,col:"#00f",font:"6x8:2",label:" ",id:"lab6"} + ]}, + {type:"h",c:[ + {type:"btn",pad:2,font:"6x8:2",label:"Temp",cb:l=>getTemp()}, + {type:"btn",pad:2,font:"6x8:2",label:"Exit",cb:l=>exit()} + ]} + ] + },{lazy:true}); + tempLO.render(); + getTemp(); +} + +var menu={ + "":{ + "title":" Temp. Graph" + }, + + "Widgets":{ + value:widsOn, + format:vis=>vis?"Hide":"Show", + onchange:vis=>{ + widsOn=vis; + refreshMenu(); + } + }, + + "Duration":{ + value:times.indexOf(duration), + min:0,max:times.length-1,step:1,wrap:true, + format:tim=>times[tim], + onchange:(dur)=>{ + duration=times[dur]; + } + }, + + "Draw Graph":function(){ + E.showMenu(); + drawGraph(); + }, + + "Show Graph" : function(){ + E.showMenu(); + if(graph.length>0){ + showGraph(); + }else{ + message("No graph to\nshow as no\ngraph has been\ndrawn yet."); + } + }, + + "Save Graph" : function(){ + E.showMenu(); + if(graph.length>0){ + saveGraph(); + }else{ + message("No graph to\nsave as no\ngraph has been\ndrawn yet."); + } + }, + + "Save Data" : function(){ + E.showMenu(); + if(graph.length>0){ + saveData(); + }else{ + message("No data to\nsave as no\ngraph has been\ndrawn yet."); + } + }, + + "Show Temp":function(){ + E.showMenu(); + showTemp(); + } +}; + +openMenu(); diff --git a/apps/tempgraph/app.png b/apps/tempgraph/app.png new file mode 100644 index 000000000..1ae347ac8 Binary files /dev/null and b/apps/tempgraph/app.png differ diff --git a/apps/tempgraph/metadata.json b/apps/tempgraph/metadata.json new file mode 100644 index 000000000..6772429a5 --- /dev/null +++ b/apps/tempgraph/metadata.json @@ -0,0 +1,19 @@ +{ "id": "tempgraph", + "name": "Temperature Graph", + "shortName":"Temp Graph", + "version":"0.01", + "description": "An app for recording the temperature for time periods ranging from 10 minutes to 7 days.", + "icon": "app.png", + "type": "app", + "tags": "temperature,tempgraph,graph", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"tempgraph.app.js","url":"app.js"}, + {"name":"tempgraph.img","url":"app-icon.js","evaluate":true} + ], + "data": [ + {"name":"tempgraph.json"} + ], + "screenshots": [{"url":"screenshot_1.png"},{"url":"screenshot_2.png"},{"url":"screenshot_3.png"}] +} diff --git a/apps/tempgraph/screenshot_1.png b/apps/tempgraph/screenshot_1.png new file mode 100644 index 000000000..7395f2896 Binary files /dev/null and b/apps/tempgraph/screenshot_1.png differ diff --git a/apps/tempgraph/screenshot_2.png b/apps/tempgraph/screenshot_2.png new file mode 100644 index 000000000..68d0ea236 Binary files /dev/null and b/apps/tempgraph/screenshot_2.png differ diff --git a/apps/tempgraph/screenshot_3.png b/apps/tempgraph/screenshot_3.png new file mode 100644 index 000000000..33f3d612e Binary files /dev/null and b/apps/tempgraph/screenshot_3.png differ diff --git a/apps/widalarmeta/ChangeLog b/apps/widalarmeta/ChangeLog index 8bdf1156f..1012ee386 100644 --- a/apps/widalarmeta/ChangeLog +++ b/apps/widalarmeta/ChangeLog @@ -4,3 +4,4 @@ Add option to show seconds 0.03: Fix Bell not appearing on alarms > 24h and redrawing interval Update to match the default alarm widget, and not show itself when an alarm is hidden. +0.04: Fix check for active alarm diff --git a/apps/widalarmeta/metadata.json b/apps/widalarmeta/metadata.json index 89e35c090..aad3c4321 100644 --- a/apps/widalarmeta/metadata.json +++ b/apps/widalarmeta/metadata.json @@ -2,7 +2,7 @@ "id": "widalarmeta", "name": "Alarm & Timer ETA", "shortName": "Alarm ETA", - "version": "0.03", + "version": "0.04", "description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h (configurable).", "icon": "widget.png", "type": "widget", diff --git a/apps/widalarmeta/widget.js b/apps/widalarmeta/widget.js index 8615aa1d2..3ad2e6ad2 100644 --- a/apps/widalarmeta/widget.js +++ b/apps/widalarmeta/widget.js @@ -9,10 +9,10 @@ function draw() { const times = alarms - .map(alarm => { + .map(alarm => alarm.hidden !== true && require("sched").getTimeToAlarm(alarm) - }) + ) .filter(a => a !== undefined); const next = times.length > 0 ? Math.min.apply(null, times) : 0; let calcWidth = 0;