Merge branch 'espruino:master' into master

pull/3374/head
Elfreda Kwawu 2024-04-04 17:35:36 -04:00 committed by GitHub
commit ecf73cd843
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 318 additions and 134 deletions

View File

@ -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.

View File

@ -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",

View File

@ -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
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

View File

@ -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<br>⬆️/⬇️ to scroll<br> ⬅️/➡️ 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.

View File

@ -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"});

View File

@ -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",

View File

@ -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() {

2
apps/counter2/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.01: New App!
0.02: Added Settings & readme

24
apps/counter2/README.md Normal file
View File

@ -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

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwcAyVJkgCFAwwCBAgd5CI+eCI2T/IRH/wR7n//AAPyCIdPBAX8CKpr/CLTpSCOipB8gRFXoPJCIknCJAIBOoYRCagLNCa4f8Q4gREI4tP8mT/41HCKJHFGoQRG+QKBLI4RHLIx9CCJ7zBGpxZCPoyhQYpIIBYor7kCP4R8YoX/WY69DAIM/BAT+BdIYICeYQRTGqKP/CNIA=="))

96
apps/counter2/app.js Normal file
View File

@ -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"});

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -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"}]
}

55
apps/counter2/settings.js Normal file
View File

@ -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);
});

View File

@ -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

View File

@ -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": [

View File

@ -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

View File

@ -233,6 +233,7 @@ function showMusicMessage(msg) {
}
function showMessageScroller(msg) {
cancelReloadTimeout();
active = "scroller";
var bodyFont = fontBig;
g.setFont(bodyFont);

View File

@ -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",

View File

@ -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

View File

@ -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:

View File

@ -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",

View File

@ -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

View File

@ -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 = [

View File

@ -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();

View File

@ -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;
}
},

View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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",