diff --git a/apps/activityreminder/ChangeLog b/apps/activityreminder/ChangeLog index 76f0945c8..df6bcaf6b 100644 --- a/apps/activityreminder/ChangeLog +++ b/apps/activityreminder/ChangeLog @@ -9,3 +9,4 @@ 0.09: New app screen (instead of showing settings or the alert) and some optimisations 0.10: Add software back button via setUI 0.11: Add setting to unlock screen +0.12: Fix handling that dates can be given as ms since epoch. diff --git a/apps/activityreminder/metadata.json b/apps/activityreminder/metadata.json index a5df15a26..7be6fe911 100644 --- a/apps/activityreminder/metadata.json +++ b/apps/activityreminder/metadata.json @@ -3,7 +3,7 @@ "name": "Activity Reminder", "shortName":"Activity Reminder", "description": "A reminder to take short walks for the ones with a sedentary lifestyle", - "version":"0.11", + "version":"0.12", "icon": "app.png", "type": "app", "tags": "tool,activity", diff --git a/apps/clockcal/ChangeLog b/apps/clockcal/ChangeLog index 5657bf26d..0f501f1fb 100644 --- a/apps/clockcal/ChangeLog +++ b/apps/clockcal/ChangeLog @@ -5,4 +5,5 @@ 0.05: Improved colors (connected vs disconnected) 0.06: Tell clock widgets to hide. 0.07: Convert Yes/No On/Off in settings to checkboxes -0.08: Fixed typo in settings.js for DRAGDOWN to make option work \ No newline at end of file +0.08: Fixed typo in settings.js for DRAGDOWN to make option work +0.09: You can now back out of the calendar using the button \ No newline at end of file diff --git a/apps/clockcal/README.md b/apps/clockcal/README.md index d30205be0..bc05081ad 100644 --- a/apps/clockcal/README.md +++ b/apps/clockcal/README.md @@ -7,23 +7,24 @@ I know that it seems redundant because there already **is** a *time&cal*-app, bu |:--:|:-| |![locked screen](screenshot.png)|locked: triggers only one minimal update/min| |![unlocked screen](screenshot2.png)|unlocked: smaller clock, but with seconds| -|![big calendar](screenshot3.png)|swipe up for big calendar, (up down to scroll, left/right to exit)| +|![big calendar](screenshot3.png)|swipe up for big calendar
⬆️/⬇️ to scroll
⬅️/➡️ to exit| ## Configurable Features - Number of calendar rows (weeks) -- Buzz on connect/disconnect (I know, this should be an extra widget, but for now, it is included) +- Buzz on connect/disconnect (feel free to disable and use a widget) - Clock Mode (24h/12h). (No am/pm indicator) - First day of the week - Red Saturday/Sunday - Swipe/Drag gestures to launch features or apps. -## Auto detects your message/music apps: -- swiping down will search your files for an app with the string "message" in its filename and launch it. (configurable) -- swiping right will search your files for an app with the string "music" in its filename and launch it. (configurable) +## Integrated swipe launcher: (Configure in Settings) +- ⬇️ (down) will search your files for an app with the string "**message**" +- ➡️ (right) will search your files for an app with the string "**music**" +- ⬅️ (left) will search your files for an app with the string "**agenda**" +- ⬆️ (up) will show the **internal full calendar** ## Feedback -The clock works for me in a 24h/MondayFirst/WeekendFree environment but is not well-tested with other settings. -So if something isn't working, please tell me: https://github.com/foostuff/BangleApps/issues +If something isn't working, please tell me: https://github.com/Stuff-etc/BangleApps/issues (I moved my github repo) ## Planned features: - Internal lightweight music control, because switching apps has a loading time. diff --git a/apps/clockcal/app.js b/apps/clockcal/app.js index 58ddd7ef5..3a0025096 100644 --- a/apps/clockcal/app.js +++ b/apps/clockcal/app.js @@ -28,11 +28,11 @@ var monthOffset = 0; * Calendar features */ function drawFullCalendar(monthOffset) { - addMonths = function (_d, _am) { - var ay = 0, m = _d.getMonth(), y = _d.getFullYear(); + const addMonths = function (_d, _am) { + let ay = 0, m = _d.getMonth(), y = _d.getFullYear(); while ((m + _am) > 11) { ay++; _am -= 12; } while ((m + _am) < 0) { ay--; _am += 12; } - n = new Date(_d.getTime()); + let n = new Date(_d.getTime()); n.setMonth(m + _am); n.setFullYear(y + ay); return n; @@ -45,7 +45,7 @@ function drawFullCalendar(monthOffset) { if (typeof dayInterval !== "undefined") clearTimeout(dayInterval); if (typeof secondInterval !== "undefined") clearTimeout(secondInterval); if (typeof minuteInterval !== "undefined") clearTimeout(minuteInterval); - d = addMonths(Date(), monthOffset); + var d = addMonths(Date(), monthOffset); tdy = Date().getDate() + "." + Date().getMonth(); newmonth = false; c_y = 0; @@ -124,7 +124,7 @@ function drawMinutes() { var d = new Date(); var hours = s.MODE24 ? d.getHours().toString().padStart(2, ' ') : ((d.getHours() + 24) % 12 || 12).toString().padStart(2, ' '); var minutes = d.getMinutes().toString().padStart(2, '0'); - var textColor = NRF.getSecurityStatus().connected ? '#99f' : '#fff'; + var textColor = NRF.getSecurityStatus().connected ? '#fff' : '#f00'; var size = 50; var clock_x = (w - 20) / 2; if (dimSeconds) { @@ -156,7 +156,7 @@ function drawSeconds() { } function drawWatch() { - if (DEBUG) console.log("CALENDAR"); + if (DEBUG) console.log("DRAWWATCH"); monthOffset = 0; state = "watch"; var d = new Date(); @@ -197,6 +197,7 @@ function drawWatch() { if (DEBUG) console.log("Next Day:" + (nextday / 3600)); if (typeof dayInterval !== "undefined") clearTimeout(dayInterval); dayInterval = setTimeout(drawWatch, nextday * 1000); + if (DEBUG) console.log("ended DRAWWATCH. next refresh in " + nextday + "s"); } function BTevent() { @@ -211,8 +212,11 @@ function action(a) { g.reset(); if (typeof secondInterval !== "undefined") clearTimeout(secondInterval); if (DEBUG) console.log("action:" + a); + state = "unknown"; + console.log("state -> unknown"); switch (a) { case "[ignore]": + drawWatch(); break; case "[calend.]": drawFullCalendar(); @@ -229,6 +233,12 @@ function action(a) { load(l[0]); } else E.showAlert("Message app not found", "Not found").then(drawWatch); break; + case "[AI:agenda]": + l = require("Storage").list(RegExp("agenda.*app.js")); + if (l.length > 0) { + load(l[0]); + } else E.showAlert("Agenda app not found", "Not found").then(drawWatch); + break; default: l = require("Storage").list(RegExp(a + ".app.js")); if (l.length > 0) { @@ -276,7 +286,6 @@ function input(dir) { drawWatch(); } break; - } } @@ -309,3 +318,10 @@ NRF.on('disconnect', BTevent); dimSeconds = Bangle.isLocked(); drawWatch(); +setWatch(function() { + if (state == "watch") { + Bangle.showLauncher() + } else if (state == "calendar") { + drawWatch(); + } +}, BTN1, {repeat:true, edge:"falling"}); diff --git a/apps/clockcal/metadata.json b/apps/clockcal/metadata.json index 998115827..60e55ceb7 100644 --- a/apps/clockcal/metadata.json +++ b/apps/clockcal/metadata.json @@ -1,7 +1,7 @@ { "id": "clockcal", "name": "Clock & Calendar", - "version": "0.08", + "version": "0.09", "description": "Clock with Calendar", "readme":"README.md", "icon": "app.png", diff --git a/apps/clockcal/settings.js b/apps/clockcal/settings.js index a406f3cf7..19059861a 100644 --- a/apps/clockcal/settings.js +++ b/apps/clockcal/settings.js @@ -9,12 +9,12 @@ REDSAT: true, // Use red color for saturday? DRAGDOWN: "[AI:messg]", DRAGRIGHT: "[AI:music]", - DRAGLEFT: "[ignore]", + DRAGLEFT: "[AI:agenda]", DRAGUP: "[calend.]" }; settings = Object.assign(defaults, require('Storage').readJSON(FILE, true) || {}); - actions = ["[ignore]","[calend.]","[AI:music]","[AI:messg]"]; + actions = ["[ignore]","[calend.]","[AI:music]","[AI:messg]","[AI:agenda]"]; require("Storage").list(RegExp(".app.js")).forEach(element => actions.push(element.replace(".app.js",""))); function writeSettings() { diff --git a/apps/counter2/ChangeLog b/apps/counter2/ChangeLog new file mode 100644 index 000000000..d7b228c2c --- /dev/null +++ b/apps/counter2/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App! +0.02: Added Settings & readme \ No newline at end of file diff --git a/apps/counter2/README.md b/apps/counter2/README.md new file mode 100644 index 000000000..d57844aae --- /dev/null +++ b/apps/counter2/README.md @@ -0,0 +1,24 @@ +# Counter2 by Michael + +I needed an HP/XP-Tracker for a game, so i made one. +The counter state gets saved. Best to use this with pattern launcher or ClockCal + +- Colored Background Mode +- ![color bg](https://stuff-etc.github.io/BangleApps/apps/counter2/counter2-screenshot.png) +- Colored Text Mode +- ![color text](https://stuff-etc.github.io/BangleApps/apps/counter2/counter2dark-screenshot.png) + +## Howto + - Tap top side or swipe up to increase counter + - Tap bottom side or swipe down to decrease counter + - Hold (600ms) to reset to default value (configurable) + - Press button to exit + +## Configurable Features +- Default value Counter 1 +- Default value Counter 2 +- Buzz on interact +- Colored Text/Background + +## Feedback +If something isn't working, please tell me: https://github.com/Stuff-etc/BangleApps/issues diff --git a/apps/counter2/app-icon.js b/apps/counter2/app-icon.js new file mode 100644 index 000000000..fda8d1e21 --- /dev/null +++ b/apps/counter2/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwcAyVJkgCFAwwCBAgd5CI+eCI2T/IRH/wR7n//AAPyCIdPBAX8CKpr/CLTpSCOipB8gRFXoPJCIknCJAIBOoYRCagLNCa4f8Q4gREI4tP8mT/41HCKJHFGoQRG+QKBLI4RHLIx9CCJ7zBGpxZCPoyhQYpIIBYor7kCP4R8YoX/WY69DAIM/BAT+BdIYICeYQRTGqKP/CNIA==")) \ No newline at end of file diff --git a/apps/counter2/app.js b/apps/counter2/app.js new file mode 100644 index 000000000..79eabb985 --- /dev/null +++ b/apps/counter2/app.js @@ -0,0 +1,96 @@ +Bangle.loadWidgets(); + +var s = Object.assign({ + counter0:10, + counter1:20, + max0:15, + max1:25, + buzz: true, + colortext: true, +}, require('Storage').readJSON("counter2.json", true) || {}); + +f1 = (s.colortext) ? "#f00" : "#fff"; +f2 = (s.colortext) ? "#00f" : "#fff"; +b1 = (s.colortext) ? g.theme.bg : "#f00"; +b2 = (s.colortext) ? g.theme.bg : "#00f"; + +var counter = 0; +var drag; + +screenwidth = g.getWidth(); +screenheight = g.getHeight(); +halfwidth = screenwidth / 2; +halfheight = screenheight / 2; + +counter = []; +counter[0] = s.counter0; +counter[1] = s.counter1; +defaults = []; +defaults[0] = s.max0; +defaults[1] = s.max1; + +function saveSettings() { + s.counter0 = counter[0]; + s.counter1 = counter[1]; + s.max0 = defaults[0]; + s.max1 = defaults[1]; + require('Storage').writeJSON("counter2.json", s); +} + +ignoreonce = false; +var dragtimeout; + +function updateScreen() { + g.setBgColor(b1); + g.clearRect(0, 0, halfwidth, screenheight); + g.setBgColor(b2); + g.clearRect(halfwidth, 0, screenwidth, screenheight); + g.setFont("Vector", 60).setFontAlign(0, 0); + g.setColor(f1); + g.drawString(Math.floor(counter[0]), halfwidth * 0.5, halfheight); + g.setColor(f2); + g.drawString(Math.floor(counter[1]), halfwidth * 1.5, halfheight); + saveSettings(); + if (s.buzz) Bangle.buzz(50,.5); + Bangle.drawWidgets(); +} + +Bangle.on("drag", e => { + c = (e.x < halfwidth) ? 0 : 1; + if (!drag) { + if (ignoreonce) { + ignoreonce = false; + return; + } + drag = { x: e.x, y: e.y }; + dragtimeout = setTimeout(function () { resetcounter(c); }, 600); //if dragging for 500ms, reset counter + } + else if (drag && !e.b) { // released + adjust = 0; + const dx = e.x - drag.x, dy = e.y - drag.y; + if (Math.abs(dy) > Math.abs(dx) + 30) { + adjust = (dy > 0) ? -1 : 1; + } else { + adjust = (e.y > halfwidth) ? -1 : 1; + } + counter[c] += adjust; + updateScreen(); + drag = undefined; + clearTimeout(dragtimeout); + } +}); + +function resetcounter(which) { + counter[which] = defaults[which]; + console.log("resetting counter ", which); + updateScreen(); + drag = undefined; + ignoreonce = true; +} + + +updateScreen(); + +setWatch(function() { + load(); +}, BTN1, {repeat:true, edge:"falling"}); \ No newline at end of file diff --git a/apps/counter2/counter2-icon.png b/apps/counter2/counter2-icon.png new file mode 100644 index 000000000..c16e9c0c7 Binary files /dev/null and b/apps/counter2/counter2-icon.png differ diff --git a/apps/counter2/counter2-screenshot.png b/apps/counter2/counter2-screenshot.png new file mode 100644 index 000000000..0864acb64 Binary files /dev/null and b/apps/counter2/counter2-screenshot.png differ diff --git a/apps/counter2/counter2dark-screenshot.png b/apps/counter2/counter2dark-screenshot.png new file mode 100644 index 000000000..2f0fd07c1 Binary files /dev/null and b/apps/counter2/counter2dark-screenshot.png differ diff --git a/apps/counter2/metadata.json b/apps/counter2/metadata.json new file mode 100644 index 000000000..265dadcd4 --- /dev/null +++ b/apps/counter2/metadata.json @@ -0,0 +1,18 @@ +{ + "id": "counter2", + "name": "Counter2", + "version": "0.02", + "description": "Dual Counter", + "readme":"README.md", + "icon": "counter2-icon.png", + "tags": "tool", + "supports": ["BANGLEJS2"], + "screenshots": [{"url":"counter2-screenshot.png"},{"url":"counter2dark-screenshot.png"}], + "allow_emulator": true, + "storage": [ + {"name":"counter2.app.js","url":"app.js"}, + {"name":"counter2.settings.js","url":"settings.js"}, + {"name":"counter2.img","url":"app-icon.js","evaluate":true} + ], + "data": [{"name":"counter2.json"}] +} diff --git a/apps/counter2/settings.js b/apps/counter2/settings.js new file mode 100644 index 000000000..36bfc240b --- /dev/null +++ b/apps/counter2/settings.js @@ -0,0 +1,55 @@ +(function (back) { + var FILE = "counter2.json"; + defaults={ + counter0:12, + counter1:0, + max0:12, + max1:0, + buzz: true, + colortext: true, + }; + settings = Object.assign(defaults, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + + menu = { + "": { "title": "Counter2" }, + "< Back": () => back(), + 'Default C1': { + value: settings[0], + min: -99, max: 99, + onchange: v => { + settings.max0 = v; + writeSettings(); + } + }, + 'Default C2': { + value: settings[2], + min: -99, max: 99, + onchange: v => { + settings.max1 = v; + writeSettings(); + } + }, + 'Color': { + value: settings.colortext, + format: v => v?"Text":"Backg", + onchange: v => { + settings.colortext = v; + console.log("Color",v); + writeSettings(); + } + }, + 'Vibrate': { + value: settings.buzz, + onchange: v => { + settings.buzz = v; + writeSettings(); + } + } + }; + // Show the menu + E.showMenu(menu); +}); diff --git a/apps/fastload/README.md b/apps/fastload/README.md index f2ff71e93..f7fab4933 100644 --- a/apps/fastload/README.md +++ b/apps/fastload/README.md @@ -1,11 +1,17 @@ +#### ⚠️EXPERIMENTAL⚠️ + # Fastload Utils -*EXPERIMENTAL* Use this with caution. When you find something misbehaving please check if the problem actually persists when removing this app. +Use this with caution. When you find something misbehaving please check if the problem actually persists when removing this app. This allows fast loading of all apps with two conditions: * Loaded app contains `Bangle.loadWidgets`. This is needed to prevent problems with apps not expecting widgets to be already loaded. * Current app can be removed completely from RAM. +#### ⚠️ KNOWN ISSUES ⚠️ + +* Fastload currently does not play nice with the automatic reload option of the apploader. App installs and upgrades are unreliable since the fastload causes code to run after reset and interfere with the upload process. + ## Settings * Activate app history and navigate back through recent apps instead of immediately loading the clock face diff --git a/apps/lint_exemptions.js b/apps/lint_exemptions.js index 28377e6a7..d88e0d9f3 100644 --- a/apps/lint_exemptions.js +++ b/apps/lint_exemptions.js @@ -59,13 +59,6 @@ module.exports = { "no-unused-vars" ] }, - "sleeplog/settings.js": { - "hash": "bd5e3e1382321df6682ef1cb718b0e15ab355422bef77278eb086f213f643021", - "rules": [ - "no-unused-vars", - "no-undef" - ] - }, "showimg/app.js": { "hash": "71cbbaa488e2d08c5bf28f7d56178d5e7694eb9761cd4752bbc9733e825d4bcf", "rules": [ @@ -276,13 +269,6 @@ module.exports = { "no-undef" ] }, - "sleeplog/app.js": { - "hash": "336da552e4b04677447cf76a253b40bc259a597ea11d455121933f93afe99794", - "rules": [ - "no-unused-vars", - "no-undef" - ] - }, "qmsched/app.js": { "hash": "4b7dbabed6c252021531d6b0449c16a3adc2e405f2ddda33ca0a65f5fa42c663", "rules": [ @@ -562,13 +548,6 @@ module.exports = { "no-undef" ] }, - "sleeplog/lib.js": { - "hash": "755e0d4c02b92181281fd6990df39c9446c73ff896b50b64d7e14cb1c0188556", - "rules": [ - "no-unused-vars", - "no-undef" - ] - }, "doztime/app-bangle1.js": { "hash": "1e9598c201175180ae77d1c3bc47e8138b339b72eb58782b5057fb7aefdc88a1", "rules": [ @@ -666,12 +645,6 @@ module.exports = { "no-undef" ] }, - "taglaunch/app.js": { - "hash": "944689f0600e59bbe4d9e5e2684baeefabe4457a6edd938aae451dc4cd659ad3", - "rules": [ - "no-undef" - ] - }, "tabanchi/app.js": { "hash": "6ad6dc1d6b0f539f9f659d5773b5a26d19eb6dacafe7b4682469e6f3c412647e", "rules": [ @@ -762,12 +735,6 @@ module.exports = { "no-undef" ] }, - "sleeplog/boot.js": { - "hash": "b4c9d8e3c3e7cdf44ea10e29a9e3b53f958b86c21ca91d88e4efb85901c3bde9", - "rules": [ - "no-undef" - ] - }, "scicalc/app.js": { "hash": "416c7b2eb12a5d10bcc3a99d89d8f6f54ecd2b47cce2d1f4d55c3e3bc602b31a", "rules": [ @@ -798,12 +765,6 @@ module.exports = { "no-undef" ] }, - "ratchet_launch/app.js": { - "hash": "592d432301d7836aa54e288d465ae8952ecb891d628f824ea9f62479a2a01631", - "rules": [ - "no-undef" - ] - }, "rclock/rclock.app.js": { "hash": "8e698787730601a1bba71aff03204c2adfaf7eeb77b35dc706534755f63f613b", "rules": [ diff --git a/apps/messagegui/ChangeLog b/apps/messagegui/ChangeLog index a2d8dbc35..5e0353782 100644 --- a/apps/messagegui/ChangeLog +++ b/apps/messagegui/ChangeLog @@ -104,3 +104,4 @@ 0.75: Handle text with images in messages list by just displaying the first line 0.76: Swipe up/down on a shown message to show the next newer/older message. 0.77: Messages can now use international fonts if they are installed +0.78: Fix: When user taps on a new message, clear the unread timeout diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js index 1d1a144c7..133cb0906 100644 --- a/apps/messagegui/app.js +++ b/apps/messagegui/app.js @@ -233,6 +233,7 @@ function showMusicMessage(msg) { } function showMessageScroller(msg) { + cancelReloadTimeout(); active = "scroller"; var bodyFont = fontBig; g.setFont(bodyFont); diff --git a/apps/messagegui/metadata.json b/apps/messagegui/metadata.json index 53836a9c4..5e064c9b3 100644 --- a/apps/messagegui/metadata.json +++ b/apps/messagegui/metadata.json @@ -2,7 +2,7 @@ "id": "messagegui", "name": "Message UI", "shortName": "Messages", - "version": "0.77", + "version": "0.78", "description": "Default app to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", diff --git a/apps/ratchet_launch/ChangeLog b/apps/ratchet_launch/ChangeLog index e60ca42d2..2731ec2ec 100644 --- a/apps/ratchet_launch/ChangeLog +++ b/apps/ratchet_launch/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial release 0.02: Cache the app-launch info +0.03: Fix bugs that would make the launcher unusable on most watches diff --git a/apps/ratchet_launch/app.js b/apps/ratchet_launch/app.js index 156106894..748cf0a82 100644 --- a/apps/ratchet_launch/app.js +++ b/apps/ratchet_launch/app.js @@ -5,13 +5,13 @@ var font = g.getFonts().includes("6x15") ? "6x15" : "6x8:2"; var largeFont = g.getFonts().includes("12x20") ? "12x20" : "6x8:3"; var currentApp = 0; var overscroll = 0; -var blankImage = Graphics.createImage(` `); +var blankImage = Graphics.createImage(`\n \n`); var rowHeight = g.getHeight()/3; // Load apps list var apps; -var launchCache = s.readJSON("launch.cache.json", true)||{}; +var launchCache = Storage.readJSON("launch.cache.json", true)||{}; var launchHash = require("Storage").hash(/\.info/); if (launchCache.hash==launchHash) { apps = launchCache.apps; @@ -39,7 +39,7 @@ if (launchCache.hash==launchHash) { }); launchCache = { apps, hash: launchHash }; - s.writeJSON("launch.cache.json", launchCache); + Storage.writeJSON("launch.cache.json", launchCache); } // Uncomment for testing in the emulator without apps: diff --git a/apps/ratchet_launch/metadata.json b/apps/ratchet_launch/metadata.json index 7ebe0c4cd..2e6db9741 100644 --- a/apps/ratchet_launch/metadata.json +++ b/apps/ratchet_launch/metadata.json @@ -2,7 +2,7 @@ "id": "ratchet_launch", "name": "Ratchet Launcher", "shortName": "Ratchet", - "version": "0.02", + "version": "0.03", "description": "Launcher with discrete scrolling for quicker app selection", "icon": "app.png", "type": "launch", diff --git a/apps/sleeplog/ChangeLog b/apps/sleeplog/ChangeLog index 7d2f147db..9f48750d0 100644 --- a/apps/sleeplog/ChangeLog +++ b/apps/sleeplog/ChangeLog @@ -12,3 +12,4 @@ 0.14: Add "Delete all logfiles before" to interface.html, display all logfiles in the interface 0.15: Issue newline before GB commands (solves issue with console.log and ignored commands) 0.16: Only write logs if we have a non-empty log to write +0.17: Minor code improvements diff --git a/apps/sleeplog/app.js b/apps/sleeplog/app.js index c75bf1e4c..9055f1e0c 100644 --- a/apps/sleeplog/app.js +++ b/apps/sleeplog/app.js @@ -245,13 +245,13 @@ function draw() { g.reset(); var imgStr = ""; // check which icon to set - if (!global.sleeplog || sleeplog.conf.enabled !== true) { + if (!global.sleeplog || global.sleeplog.conf.enabled !== true) { // set color and disabled service icon g.setColor(1, 0, 0); imgStr = "FBSBAOAAfwAP+AH3wD4+B8Hw+A+fAH/gA/wAH4AB+AA/wAf+APnwHw+D4Hx8A++AH/AA/gAH"; - } else if (sleeplog.debug) { + } else if (global.sleeplog.debug) { // set debugging icon - imgStr = typeof sleeplog.debug === "object" ? + imgStr = typeof global.sleeplog.debug === "object" ? "FBSBAB/4AQDAF+4BfvAX74F+CBf+gX/oFJKBf+gUkoF/6BSSgX/oFJ6Bf+gX/oF/6BAAgf/4" : // file "FBSBAP//+f/V///4AAGAABkAAZgAGcABjgAYcAGDgBhwAY4AGcABmH+ZB/mAABgAAYAAH///"; // console } @@ -297,7 +297,7 @@ var ATID; // analysis timeout ID var drawingID = 0; // drawing ID for ongoing process // get screen width and center (zero based) var width = g.getWidth() - 1; -var center = width / 2 - 1; +//var center = width / 2 - 1; // set areas and actions array var aaa = [ diff --git a/apps/sleeplog/boot.js b/apps/sleeplog/boot.js index dc0cd5ae1..d74db7357 100644 --- a/apps/sleeplog/boot.js +++ b/apps/sleeplog/boot.js @@ -18,14 +18,14 @@ global.sleeplog = { }; // check if service is enabled -if (sleeplog.conf.enabled) { +if (global.sleeplog.conf.enabled) { // assign functions to global object global.sleeplog = Object.assign({ // define function to initialy start or restart the service start: function() { // add kill and health listener - E.on('kill', sleeplog.saveStatus); - Bangle.on('health', sleeplog.health); + E.on('kill', global.sleeplog.saveStatus); + Bangle.on('health', global.sleeplog.health); // restore saved status this.restoreStatus(); @@ -34,8 +34,8 @@ if (sleeplog.conf.enabled) { // define function to stop the service, it will be restarted on reload if enabled stop: function() { // remove all listeners - Bangle.removeListener('health', sleeplog.health); - E.removeListener('kill', sleeplog.saveStatus); + Bangle.removeListener('health', global.sleeplog.health); + E.removeListener('kill', global.sleeplog.saveStatus); // save active values this.saveStatus(); @@ -122,11 +122,11 @@ if (sleeplog.conf.enabled) { if (!global.sleeplog) return new Error("sleeplog: Can't save status, global object missing!"); // check saveUpToDate is not set or forced - if (!sleeplog.info.saveUpToDate || force) { + if (!global.sleeplog.info.saveUpToDate || force) { // save status, consecutive status and info timestamps to restore on reload - var save = [sleeplog.info.lastCheck, sleeplog.info.awakeSince, sleeplog.info.asleepSince]; + var save = [global.sleeplog.info.lastCheck, global.sleeplog.info.awakeSince, global.sleeplog.info.asleepSince]; // add debuging status if active - if (sleeplog.debug) save.push(sleeplog.debug.writeUntil, sleeplog.debug.fileid); + if (global.sleeplog.debug) save.push(global.sleeplog.debug.writeUntil, global.sleeplog.debug.fileid); // stringify entries save = "," + save.map((entry, index) => { @@ -135,8 +135,8 @@ if (sleeplog.conf.enabled) { }).join(",") + "\n"; // add present status if forced - if (force) save = (sleeplog.info.lastChange / 6E5) + "," + - sleeplog.status + "," + sleeplog.consecutive + "\n" + save; + if (force) save = (global.sleeplog.info.lastChange / 6E5) + "," + + global.sleeplog.status + "," + global.sleeplog.consecutive + "\n" + save; // append saved data to StorageFile require("Storage").open("sleeplog.log", "a").write(save); @@ -161,20 +161,20 @@ if (sleeplog.conf.enabled) { // add preliminary status depending on charging and movement thresholds // 1 = not worn, 2 = awake, 3 = light sleep, 4 = deep sleep data.status = Bangle.isCharging() ? 1 : - data.movement <= sleeplog.conf.deepTh ? 4 : - data.movement <= sleeplog.conf.lightTh ? 3 : 2; + data.movement <= global.sleeplog.conf.deepTh ? 4 : + data.movement <= global.sleeplog.conf.lightTh ? 3 : 2; // check if changing to deep sleep from non sleeping - if (data.status === 4 && sleeplog.status <= 2) { - sleeplog.checkIsWearing((isWearing, data) => { + if (data.status === 4 && global.sleeplog.status <= 2) { + global.sleeplog.checkIsWearing((isWearing, data) => { // correct status if (!isWearing) data.status = 1; // set status - sleeplog.setStatus(data); + global.sleeplog.setStatus(data); }, data); } else { // set status - sleeplog.setStatus(data); + global.sleeplog.setStatus(data); } }, @@ -185,7 +185,7 @@ if (sleeplog.conf.enabled) { } // create a temporary object to store data and functions - global.tmpWearingCheck = { + const tmpWearingCheck = { // define temporary hrm listener function to read the wearing status hrmListener: hrm => tmpWearingCheck.isWearing = hrm.isWearing, // set default wearing status @@ -195,22 +195,18 @@ if (sleeplog.conf.enabled) { // enable HRM Bangle.setHRMPower(true, "wearingCheck"); // wait until HRM is initialised - setTimeout((returnFn, data) => { + setTimeout((returnFn, data, tmpWearingCheck) => { // add HRM listener Bangle.on('HRM-raw', tmpWearingCheck.hrmListener); // wait for two cycles (HRM working on 60Hz) - setTimeout((returnFn, data) => { + setTimeout((returnFn, data, tmpWearingCheck) => { // remove listener and disable HRM Bangle.removeListener('HRM-raw', tmpWearingCheck.hrmListener); Bangle.setHRMPower(false, "wearingCheck"); - // cache wearing status - var isWearing = tmpWearingCheck.isWearing; - // clear temporary object - delete global.tmpWearingCheck; // call return function with status - returnFn(isWearing, data); - }, 34, returnFn, data); - }, 2500, returnFn, data); + returnFn(tmpWearingCheck.isWearing, data); + }, 34, returnFn, data, tmpWearingCheck); + }, 2500, returnFn, data, tmpWearingCheck); }, // define function to set the status @@ -361,7 +357,7 @@ if (sleeplog.conf.enabled) { // define trigger object trigger: {} - }, sleeplog); + }, global.sleeplog); // initial starting global.sleeplog.start(); diff --git a/apps/sleeplog/lib.js b/apps/sleeplog/lib.js index 79d7db0d5..d3f3dddbe 100644 --- a/apps/sleeplog/lib.js +++ b/apps/sleeplog/lib.js @@ -3,7 +3,7 @@ exports = { // define en-/disable function, restarts the service to make changes take effect setEnabled: function(enable) { // stop if enabled - if (global.sleeplog && sleeplog.enabled) sleeplog.stop(); + if (global.sleeplog && global.sleeplog.enabled) global.sleeplog.stop(); // define settings filename var settings = "sleeplog.json"; @@ -138,7 +138,7 @@ exports = { } // define last index - var lastIndex = log.length - 1; + //var lastIndex = log.length - 1; // set timestamp of first entry to since if first entry before since if (log[0] && log[0][0] < since) log[0][0] = since; // add timestamp at now with unknown status if until after now @@ -251,7 +251,7 @@ exports = { // set default date or correct date type if needed if (!date || !date.getDay) date = date ? new Date(date) : new Date(); // set default ToD as set in sleeplog.conf or settings if available - if (ToD === undefined) ToD = (global.sleeplog && sleeplog.conf ? sleeplog.conf.breakToD : + if (ToD === undefined) ToD = (global.sleeplog && global.sleeplog.conf ? global.sleeplog.conf.breakToD : (require("Storage").readJSON("sleeplog.json", true) || {}).breakToD) || 12; // calculate last break time and return return new Date(date.getFullYear(), date.getMonth(), date.getDate(), ToD); @@ -274,24 +274,24 @@ exports = { // check if nothing has to be changed if (!duration && - (enable && sleeplog.debug === true) || - (!enable && !sleeplog.debug)) return; + (enable && global.sleeplog.debug === true) || + (!enable && !global.sleeplog.debug)) return; // check if en- or disable debugging if (enable) { // define debug object - sleeplog.debug = {}; + global.sleeplog.debug = {}; // check if a file should be generated if (typeof duration === "number") { // check duration boundaries, 0 => 8 duration = duration > 96 ? 96 : duration || 12; // calculate and set writeUntil in 10min steps - sleeplog.debug.writeUntil = ((Date.now() / 6E5 | 0) + duration * 6) * 6E5; + global.sleeplog.debug.writeUntil = ((Date.now() / 6E5 | 0) + duration * 6) * 6E5; // set fileid to "{hours since 1970}" - sleeplog.debug.fileid = Date.now() / 36E5 | 0; + global.sleeplog.debug.fileid = Date.now() / 36E5 | 0; // write csv header on empty file - var file = require("Storage").open("sleeplog_" + sleeplog.debug.fileid + ".csv", "a"); + var file = require("Storage").open("sleeplog_" + global.sleeplog.debug.fileid + ".csv", "a"); if (!file.getLength()) file.write( "timestamp,movement,status,consecutive,asleepSince,awakeSince,bpm,bpmConfidence\n" ); @@ -299,21 +299,21 @@ exports = { file = undefined; } else { // set debug as active - sleeplog.debug = true; + global.sleeplog.debug = true; } } else { // disable debugging - delete sleeplog.debug; + delete global.sleeplog.debug; } // save status forced - sleeplog.saveStatus(true); + global.sleeplog.saveStatus(true); }, // define debugging function, called after logging if debug is set debug: function(data) { // check if global variable accessable and debug active - if (!global.sleeplog || !sleeplog.debug) return; + if (!global.sleeplog || !global.sleeplog.debug) return; // set functions to convert timestamps function localTime(timestamp) { @@ -328,10 +328,10 @@ exports = { var console = "sleeplog: " + localTime(data.timestamp) + " > " + "movement: " + ("" + data.movement).padStart(4) + ", " + - "unknown ,non consec.,consecutive".split(",")[sleeplog.consecutive] + " " + + "unknown ,non consec.,consecutive".split(",")[global.sleeplog.consecutive] + " " + "unknown,not worn,awake,light sleep,deep sleep".split(",")[data.status].padEnd(12) + ", " + - "asleep since: " + localTime(sleeplog.info.asleepSince) + ", " + - "awake since: " + localTime(sleeplog.info.awakeSince); + "asleep since: " + localTime(global.sleeplog.info.asleepSince) + ", " + + "awake since: " + localTime(global.sleeplog.info.awakeSince); // add bpm if set if (data.bpm) console += ", " + "bpm: " + ("" + data.bpm).padStart(3) + ", " + @@ -340,24 +340,24 @@ exports = { print(console); // check if debug is set as object with a file id and it is not past writeUntil - if (typeof sleeplog.debug === "object" && sleeplog.debug.fileid && - Date.now() < sleeplog.debug.writeUntil) { + if (typeof global.sleeplog.debug === "object" && global.sleeplog.debug.fileid && + Date.now() < global.sleeplog.debug.writeUntil) { // generate next csv line var csv = [ officeTime(data.timestamp), data.movement, data.status, - sleeplog.consecutive, - sleeplog.info.asleepSince ? officeTime(sleeplog.info.asleepSince) : "", - sleeplog.info.awakeSince ? officeTime(sleeplog.info.awakeSince) : "", + global.sleeplog.consecutive, + global.sleeplog.info.asleepSince ? officeTime(global.sleeplog.info.asleepSince) : "", + global.sleeplog.info.awakeSince ? officeTime(global.sleeplog.info.awakeSince) : "", data.bpm || "", data.bpmConfidence || "" ].join(","); // write next line to log if set - require("Storage").open("sleeplog_" + sleeplog.debug.fileid + ".csv", "a").write(csv + "\n"); + require("Storage").open("sleeplog_" + global.sleeplog.debug.fileid + ".csv", "a").write(csv + "\n"); } else { // clear file setting in debug - sleeplog.debug = true; + global.sleeplog.debug = true; } }, diff --git a/apps/sleeplog/metadata.json b/apps/sleeplog/metadata.json index 212c47ff3..0c3d73a96 100644 --- a/apps/sleeplog/metadata.json +++ b/apps/sleeplog/metadata.json @@ -2,7 +2,7 @@ "id":"sleeplog", "name":"Sleep Log", "shortName": "SleepLog", - "version": "0.16", + "version": "0.17", "description": "Log and view your sleeping habits. This app is using the built in movement calculation.", "icon": "app.png", "type": "app", diff --git a/apps/sleeplog/settings.js b/apps/sleeplog/settings.js index 2c967cd2e..7bac69857 100644 --- a/apps/sleeplog/settings.js +++ b/apps/sleeplog/settings.js @@ -174,8 +174,8 @@ } // get thresholds - var deepTh = global.sleeplog ? sleeplog.conf.deepTh : defaults.deepTh; - var lightTh = global.sleeplog ? sleeplog.conf.lightTh : defaults.lightTh; + var deepTh = global.sleeplog ? global.sleeplog.conf.deepTh : defaults.deepTh; + var lightTh = global.sleeplog ? global.sleeplog.conf.lightTh : defaults.lightTh; // set lowest movement displayed var minMove = deepTh - 20; // set start point @@ -240,8 +240,8 @@ // check if sleeplog is available if (global.sleeplog) { // get debug status, file and duration - var enabled = !!sleeplog.debug; - var file = typeof sleeplog.debug === "object"; + var enabled = !!global.sleeplog.debug; + var file = typeof global.sleeplog.debug === "object"; var duration = 0; // setup debugging menu var debugMenu = { @@ -250,7 +250,7 @@ }, /*LANG*/"< Back": () => { // check if some value has changed - if (enabled !== !!sleeplog.debug || file !== (typeof sleeplog.debug === "object") || duration) + if (enabled !== !!global.sleeplog.debug || file !== (typeof global.sleeplog.debug === "object") || duration) require("sleeplog").setDebug(enabled, file ? duration || 12 : undefined); // redraw main menu showMain(7); @@ -265,7 +265,7 @@ onchange: v => file = v }, /*LANG*/"Duration": { - value: file ? (sleeplog.debug.writeUntil - Date.now()) / 36E5 | 0 : 12, + value: file ? (global.sleeplog.debug.writeUntil - Date.now()) / 36E5 | 0 : 12, min: 1, max: 96, wrap: true, @@ -275,7 +275,7 @@ /*LANG*/"Cancel": () => showMain(7), }; // show menu - var menu = E.showMenu(debugMenu); + /*var menu =*/ E.showMenu(debugMenu); } else { // show error prompt E.showPrompt("Sleeplog" + /*LANG*/"not enabled!", { @@ -290,7 +290,7 @@ // show menu to change thresholds function showThresholds() { // setup logging menu - var menu; + //var menu; var thresholdsMenu = { "": { title: /*LANG*/"Thresholds" @@ -377,9 +377,9 @@ buttons: { /*LANG*/"Ok": 0 } - }).then(() => menu = E.showMenu(thresholdsMenu)); + }).then(() => /*menu =*/ E.showMenu(thresholdsMenu)); } else { - menu = E.showMenu(thresholdsMenu); + /*menu =*/ E.showMenu(thresholdsMenu); } } @@ -388,9 +388,9 @@ // set debug image var debugImg = !global.sleeplog ? "FBSBAOAAfwAP+AH3wD4+B8Hw+A+fAH/gA/wAH4AB+AA/wAf+APnwHw+D4Hx8A++AH/AA/gAH" : // X - typeof sleeplog.debug === "object" ? + typeof global.sleeplog.debug === "object" ? "FBSBAB/4AQDAF+4BfvAX74F+CBf+gX/oFJKBf+gUkoF/6BSSgX/oFJ6Bf+gX/oF/6BAAgf/4" : // file - sleeplog.debug ? + global.sleeplog.debug ? "FBSBAP//+f/V///4AAGAABkAAZgAGcABjgAYcAGDgBhwAY4AGcABmH+ZB/mAABgAAYAAH///" : // console 0; // off debugImg = debugImg ? "\0" + atob(debugImg) : false; @@ -440,7 +440,7 @@ onchange: () => setTimeout(showDebug, 10) } }; - var menu = E.showMenu(mainMenu); + /*var menu =*/ E.showMenu(mainMenu); } // draw main menu diff --git a/apps/taglaunch/ChangeLog b/apps/taglaunch/ChangeLog index 6c36d39d5..ed415e847 100644 --- a/apps/taglaunch/ChangeLog +++ b/apps/taglaunch/ChangeLog @@ -3,3 +3,4 @@ 0.03: Remove app from 'tool' when it has at least one other known tag Add tag 'health' for apps like Heart Rate Monitor 0.04: Fix remove handler +0.05: Make the "App source not found" warning less buggy diff --git a/apps/taglaunch/app.js b/apps/taglaunch/app.js index 9569cc7bd..a3481e159 100644 --- a/apps/taglaunch/app.js +++ b/apps/taglaunch/app.js @@ -106,8 +106,9 @@ let showTagMenu = (tag) => { let app = appsByTag[tag][i]; if (!app) return; if (!app.src || require("Storage").read(app.src)===undefined) { + Bangle.setUI(); E.showMessage(/*LANG*/"App Source\nNot found"); - setTimeout(drawMenu, 2000); + setTimeout(showMainMenu, 2000); } else { load(app.src); } diff --git a/apps/taglaunch/metadata.json b/apps/taglaunch/metadata.json index a4fb4ef6c..1eb56e0a8 100644 --- a/apps/taglaunch/metadata.json +++ b/apps/taglaunch/metadata.json @@ -2,7 +2,7 @@ "id": "taglaunch", "name": "Tag Launcher", "shortName": "Taglauncher", - "version": "0.04", + "version": "0.05", "description": "Launcher that puts all applications into submenus based on their tag. With many applications installed this can result in a faster application selection than the linear access of the default launcher.", "readme": "README.md", "icon": "app.png",