From c28d85ad1fc18f2a326858ddc5dfc0842d7b13e5 Mon Sep 17 00:00:00 2001
From: Erik Andresen
Date: Sat, 11 Jun 2022 09:00:47 +0200
Subject: [PATCH 01/14] sleepphasealarm: add settings file
- Vibrate with configured pattern
- Add setting to defer start of algorithm
---
apps/sleepphasealarm/ChangeLog | 2 +
apps/sleepphasealarm/README.md | 17 +++-
apps/sleepphasealarm/app.js | 130 +++++++++++++++++-----------
apps/sleepphasealarm/interface.html | 1 -
apps/sleepphasealarm/metadata.json | 3 +-
apps/sleepphasealarm/settings.js | 37 ++++++++
6 files changed, 135 insertions(+), 55 deletions(-)
create mode 100644 apps/sleepphasealarm/settings.js
diff --git a/apps/sleepphasealarm/ChangeLog b/apps/sleepphasealarm/ChangeLog
index 208058472..4ca4fb723 100644
--- a/apps/sleepphasealarm/ChangeLog
+++ b/apps/sleepphasealarm/ChangeLog
@@ -7,3 +7,5 @@
use Layout library and display ETA
0.07: Add check for day of week
0.08: Update to new time_utils module
+0.09: Vibrate with configured pattern
+ Add setting to defer start of algorithm
diff --git a/apps/sleepphasealarm/README.md b/apps/sleepphasealarm/README.md
index c33c9c807..218ce5363 100644
--- a/apps/sleepphasealarm/README.md
+++ b/apps/sleepphasealarm/README.md
@@ -4,10 +4,19 @@ The alarm must be in the next 24h.
The display shows:
-- the current time
-- time of the next alarm or timer
-- time difference between current time and alarm time (ETA)
-- current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging
+- The current time.
+- Time of the next alarm or timer.
+- Time difference between current time and alarm time (ETA).
+- Current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging. State can also be "Deferred", see the "Run before alarm"-option.
+
+## Settings
+
+* **Keep alarm enabled**
+ - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at 6:45 (the calculated time from the ESS algorithm) and again at 7:00.
+ - No: No action at configured alarm time from scheduler.
+* **Run before alarm**
+ - disabled: (default) The ESS algorithm starts immediately when the application starts.
+ - 1..23: The ESS algorithm starts the configured time before the alarm. E.g. when set to 1h for an alarm at 7:00 the ESS algorithm will start at 6:00. This improves battery life.
## Logging
diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js
index febc8a259..23df53b22 100644
--- a/apps/sleepphasealarm/app.js
+++ b/apps/sleepphasealarm/app.js
@@ -1,9 +1,18 @@
const BANGLEJS2 = process.env.HWVERSION == 2; // check for bangle 2
+const CONFIGFILE = "sleepphasealarm.json";
const Layout = require("Layout");
const locale = require('locale');
const alarms = require("Storage").readJSON("sched.json",1) || [];
-const config = require("Storage").readJSON("sleepphasealarm.json",1) || {logs: []};
+const config = Object.assign({
+ logs: [], // array of length 31 with one entry for each day of month
+ settings: {
+ startBeforeAlarm: 0, // 0 = start immediately, 1..23 = start 1h..23h before alarm time
+ disableAlarm: false,
+ }
+}, require("Storage").readJSON(CONFIGFILE,1) || {});
const active = alarms.filter(a=>a.on);
+const schedSettings = require("sched").getSettings();
+let buzzCount = schedSettings.buzzCount;
let logs = [];
// Sleep/Wake detection with Estimation of Stationary Sleep-segments (ESS):
@@ -43,7 +52,8 @@ function calc_ess(acc_magn) {
}
// locate next alarm
-var nextAlarm;
+var nextAlarmDate;
+var nextAlarmConfig;
active.forEach(alarm => {
const now = new Date();
const time = require("time_utils").decodeTime(alarm.t);
@@ -52,8 +62,9 @@ active.forEach(alarm => {
dateAlarm.setTime(dateAlarm.getTime() + (24*60*60*1000));
}
if ((alarm.dow >> dateAlarm.getDay()) & 1) { // check valid day of week
- if (nextAlarm === undefined || dateAlarm < nextAlarm) {
- nextAlarm = dateAlarm;
+ if (nextAlarmDate === undefined || dateAlarm < nextAlarmDate) {
+ nextAlarmDate = dateAlarm;
+ nextAlarmConfig = alarm;
}
}
});
@@ -69,8 +80,8 @@ var layout = new Layout({
}, {lazy:true});
function drawApp() {
- var alarmHour = nextAlarm.getHours();
- var alarmMinute = nextAlarm.getMinutes();
+ var alarmHour = nextAlarmDate.getHours();
+ var alarmMinute = nextAlarmDate.getMinutes();
if (alarmHour < 10) alarmHour = "0" + alarmHour;
if (alarmMinute < 10) alarmMinute = "0" + alarmMinute;
layout.alarm_date.label = "Alarm at " + alarmHour + ":" + alarmMinute;
@@ -80,7 +91,7 @@ function drawApp() {
if (Bangle.isLCDOn()) {
const now = new Date();
layout.date.label = locale.time(now, BANGLEJS2 && Bangle.isLocked() ? 1 : 0); // hide seconds on bangle 2
- const diff = nextAlarm - now;
+ const diff = nextAlarmDate - now;
const diffHour = Math.floor((diff % 86400000) / 3600000).toString();
const diffMinutes = Math.floor(((diff % 86400000) % 3600000) / 60000).toString();
layout.eta.label = "ETA: -"+ diffHour + ":" + diffMinutes.padStart(2, '0');
@@ -92,70 +103,91 @@ function drawApp() {
setInterval(drawTime, 500); // 2Hz
}
-var buzzCount = 19;
function buzz() {
if ((require('Storage').readJSON('setting.json',1)||{}).quiet>1) return; // total silence
- Bangle.setLCDPower(1);
- Bangle.buzz().then(()=>{
- if (buzzCount--) {
- setTimeout(buzz, 500);
- } else {
- // back to main after finish
- setTimeout(load, 1000);
- }
- });
+ Bangle.setLCDPower(1);
+ require("buzz").pattern(nextAlarmConfig.vibrate || ";");
+ if (buzzCount--) {
+ setTimeout(buzz, schedSettings.buzzIntervalMillis);
+ } else {
+ // back to main after finish
+ setTimeout(load, 1000);
+ }
}
function addLog(time, type) {
logs.push({time: time, type: type});
- require("Storage").writeJSON("sleepphasealarm.json", config);
+ if (logs.length > 1) { // Do not write if there is only one state
+ require("Storage").writeJSON(CONFIGFILE, config);
+ }
}
// run
var minAlarm = new Date();
var measure = true;
-if (nextAlarm !== undefined) {
- config.logs[nextAlarm.getDate()] = []; // overwrite log on each day of month
- logs = config.logs[nextAlarm.getDate()];
+if (nextAlarmDate !== undefined) {
+ config.logs[nextAlarmDate.getDate()] = []; // overwrite log on each day of month
+ logs = config.logs[nextAlarmDate.getDate()];
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
let swest_last;
// minimum alert 30 minutes early
- minAlarm.setTime(nextAlarm.getTime() - (30*60*1000));
- Bangle.on('accel', (accelData) => { // 12.5Hz
- const now = new Date();
- const acc = accelData.mag;
- const swest = calc_ess(acc);
+ minAlarm.setTime(nextAlarmDate.getTime() - (30*60*1000));
+ run = () => {
+ layout.state.label = "Start";
+ layout.render();
+ Bangle.on('accel', (accelData) => { // 12.5Hz
+ const now = new Date();
+ const acc = accelData.mag;
+ const swest = calc_ess(acc);
- if (swest !== undefined) {
- if (Bangle.isLCDOn()) {
- layout.state.label = swest ? "Sleep" : "Awake";
- layout.render();
- }
- // log
- if (swest_last != swest) {
- if (swest) {
- addLog(new Date(now - sleepthresh*13/12.5*1000), "sleep"); // calculate begin of no motion phase, 13 values/second at 12.5Hz
- } else {
- addLog(now, "awake");
+ if (swest !== undefined) {
+ if (Bangle.isLCDOn()) {
+ layout.state.label = swest ? "Sleep" : "Awake";
+ layout.render();
+ }
+ // log
+ if (swest_last != swest) {
+ if (swest) {
+ addLog(new Date(now - sleepthresh*13/12.5*1000), "sleep"); // calculate begin of no motion phase, 13 values/second at 12.5Hz
+ } else {
+ addLog(now, "awake");
+ }
+ swest_last = swest;
}
- swest_last = swest;
}
- }
- if (now >= nextAlarm) {
- // The alarm widget should handle this one
- addLog(now, "alarm");
- setTimeout(load, 1000);
- } else if (measure && now >= minAlarm && swest === false) {
- addLog(now, "alarm");
- buzz();
- measure = false;
- }
- });
+ if (now >= nextAlarmDate) {
+ // The alarm widget should handle this one
+ addLog(now, "alarm");
+ setTimeout(load, 1000);
+ } else if (measure && now >= minAlarm && swest_last === false) {
+ addLog(now, "alarm");
+ buzz();
+ measure = false;
+ if (config.settings.disableAlarm) {
+ // disable alarm for scheduler
+ nextAlarmConfig.last = now.getDate();
+ require("Storage").writeJSON("sched.json", alarms);
+ }
+ }
+ });
+ };
drawApp();
+ if (config.settings.startBeforeAlarm === 0) {
+ // Start immediately
+ run();
+ } else {
+ // defer start
+ layout.state.label = "Deferred";
+ layout.render();
+ const diff = nextAlarmDate - Date.now();
+ let timeout = diff-config.settings.startBeforeAlarm*60*60*1000;
+ if (timeout < 0) timeout = 0;
+ setTimeout(run, timeout);
+ }
} else {
E.showMessage('No Alarm');
setTimeout(load, 1000);
diff --git a/apps/sleepphasealarm/interface.html b/apps/sleepphasealarm/interface.html
index 9a7cb0f93..f45c183e1 100644
--- a/apps/sleepphasealarm/interface.html
+++ b/apps/sleepphasealarm/interface.html
@@ -1,7 +1,6 @@
-
Please select a wakeup day:
diff --git a/apps/sleepphasealarm/metadata.json b/apps/sleepphasealarm/metadata.json
index c74a617ab..6ec5f4180 100644
--- a/apps/sleepphasealarm/metadata.json
+++ b/apps/sleepphasealarm/metadata.json
@@ -2,7 +2,7 @@
"id": "sleepphasealarm",
"name": "SleepPhaseAlarm",
"shortName": "SleepPhaseAlarm",
- "version": "0.08",
+ "version": "0.09",
"description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.",
"icon": "app.png",
"tags": "alarm",
@@ -11,6 +11,7 @@
"dependencies": {"scheduler":"type"},
"storage": [
{"name":"sleepphasealarm.app.js","url":"app.js"},
+ {"name":"sleepphasealarm.settings.js","url":"settings.js"},
{"name":"sleepphasealarm.img","url":"app-icon.js","evaluate":true}
],
"data": [{"name":"sleepphasealarm.json","storageFile":true}],
diff --git a/apps/sleepphasealarm/settings.js b/apps/sleepphasealarm/settings.js
new file mode 100644
index 000000000..a79abb598
--- /dev/null
+++ b/apps/sleepphasealarm/settings.js
@@ -0,0 +1,37 @@
+(function(back) {
+ const CONFIGFILE = "sleepphasealarm.json";
+ // Load settings
+ const config = Object.assign({
+ logs: [], // array of length 31 with one entry for each day of month
+ settings: {
+ startBeforeAlarm: 0, // 0 = start immediately, 1..23 = start 1h..23h before alarm time
+ disableAlarm: false,
+ }
+ }, require("Storage").readJSON(CONFIGFILE,1) || {});
+
+ function writeSettings() {
+ require('Storage').writeJSON(CONFIGFILE, config);
+ }
+
+ // Show the menu
+ E.showMenu({
+ "" : { "title" : "SleepPhaseAlarm" },
+ 'Keep alarm enabled': {
+ value: !!config.settings.disableAlarm,
+ format: v => v?"No":"Yes",
+ onchange: v => {
+ config.settings.disableAlarm = v;
+ writeSettings();
+ }
+ }, "< Back" : () => back(),
+ 'Run before alarm': {
+ format: v => v === 0 ? 'disabled' : v+'h',
+ value: config.settings.startBeforeAlarm,
+ min: 0, max: 23,
+ onchange: v => {
+ config.settings.startBeforeAlarm = v;
+ writeSettings();
+ }
+ },
+ });
+})
From fd1cab5b96884de25435e7c633ffd257b4a3d2bf Mon Sep 17 00:00:00 2001
From: Erik Andresen
Date: Sat, 11 Jun 2022 09:05:31 +0200
Subject: [PATCH 02/14] sleepphasealarm. updated documentation
---
apps/sleepphasealarm/ChangeLog | 2 ++
apps/sleepphasealarm/README.md | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/apps/sleepphasealarm/ChangeLog b/apps/sleepphasealarm/ChangeLog
index 4ca4fb723..6bf296342 100644
--- a/apps/sleepphasealarm/ChangeLog
+++ b/apps/sleepphasealarm/ChangeLog
@@ -9,3 +9,5 @@
0.08: Update to new time_utils module
0.09: Vibrate with configured pattern
Add setting to defer start of algorithm
+ Add setting to disable scheduler alarm
+
diff --git a/apps/sleepphasealarm/README.md b/apps/sleepphasealarm/README.md
index 218ce5363..ecb3feb06 100644
--- a/apps/sleepphasealarm/README.md
+++ b/apps/sleepphasealarm/README.md
@@ -12,7 +12,7 @@ The display shows:
## Settings
* **Keep alarm enabled**
- - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at 6:45 (the calculated time from the ESS algorithm) and again at 7:00.
+ - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at the calculated time from the ESS algorithm (for example 6:45) and again at 7:00.
- No: No action at configured alarm time from scheduler.
* **Run before alarm**
- disabled: (default) The ESS algorithm starts immediately when the application starts.
From 7fcd86b4bca38585693ca66ac17876108b60f723 Mon Sep 17 00:00:00 2001
From: Erik Andresen
Date: Sun, 12 Jun 2022 10:39:48 +0200
Subject: [PATCH 03/14] sleepphasealarm: Replace setInterval with setTimeout
---
apps/sleepphasealarm/app.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js
index 23df53b22..92f4b3dc7 100644
--- a/apps/sleepphasealarm/app.js
+++ b/apps/sleepphasealarm/app.js
@@ -97,10 +97,13 @@ function drawApp() {
layout.eta.label = "ETA: -"+ diffHour + ":" + diffMinutes.padStart(2, '0');
layout.render();
}
+
+ setTimeout(()=>{
+ drawTime();
+ }, 1000 - (Date.now() % 1000));
}
drawTime();
- setInterval(drawTime, 500); // 2Hz
}
function buzz() {
From 19c3e0e20eb347958e523bd2d96a23d7e07109ed Mon Sep 17 00:00:00 2001
From: Alessandro Cocco
Date: Mon, 25 Apr 2022 20:54:52 +0200
Subject: [PATCH 04/14] [Scheduler] Remove custom boolean formatter
The new menu system handles booleans by default
---
apps/sched/settings.js | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/apps/sched/settings.js b/apps/sched/settings.js
index a2b3a5241..b73cd41d1 100644
--- a/apps/sched/settings.js
+++ b/apps/sched/settings.js
@@ -4,11 +4,10 @@
E.showMenu({
"": { "title": /*LANG*/"Scheduler" },
- /*LANG*/"< Back": () => back(),
+ "< Back": () => back(),
/*LANG*/"Unlock at Buzz": {
value: settings.unlockAtBuzz,
- format: v => v ? /*LANG*/"Yes" : /*LANG*/"No",
onchange: v => {
settings.unlockAtBuzz = v;
require("sched").setSettings(settings);
@@ -17,7 +16,6 @@
/*LANG*/"Default Auto Snooze": {
value: settings.defaultAutoSnooze,
- format: v => v ? /*LANG*/"Yes" : /*LANG*/"No",
onchange: v => {
settings.defaultAutoSnooze = v;
require("sched").setSettings(settings);
@@ -38,7 +36,6 @@
/*LANG*/"Default Repeat": {
value: settings.defaultRepeat,
- format: v => v ? /*LANG*/"Yes" : /*LANG*/"No",
onchange: v => {
settings.defaultRepeat = v;
require("sched").setSettings(settings);
From fa2fa9e4a721145ceebd9536ca391f3bc1063472 Mon Sep 17 00:00:00 2001
From: Erik Andresen
Date: Tue, 14 Jun 2022 20:09:57 +0200
Subject: [PATCH 05/14] sleepphasealarm: set acc fixed intervall
---
apps/sleepphasealarm/app.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js
index 92f4b3dc7..9f2e6c3b4 100644
--- a/apps/sleepphasealarm/app.js
+++ b/apps/sleepphasealarm/app.js
@@ -141,7 +141,8 @@ if (nextAlarmDate !== undefined) {
run = () => {
layout.state.label = "Start";
layout.render();
- Bangle.on('accel', (accelData) => { // 12.5Hz
+ Bangle.setPollInterval(80); // 12.5Hz, do not dynamically change accelerometer poll interval
+ Bangle.on('accel', (accelData) => {
const now = new Date();
const acc = accelData.mag;
const swest = calc_ess(acc);
From ee8f62d250b8c91732d5d21c5841b7ca31055295 Mon Sep 17 00:00:00 2001
From: Erik Andresen
Date: Tue, 14 Jun 2022 20:29:10 +0200
Subject: [PATCH 06/14] sleepphasealarm set powerSave=false
do not dynamically change accelerometer poll interval
---
apps/sleepphasealarm/app.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js
index 9f2e6c3b4..b19799c4b 100644
--- a/apps/sleepphasealarm/app.js
+++ b/apps/sleepphasealarm/app.js
@@ -141,7 +141,8 @@ if (nextAlarmDate !== undefined) {
run = () => {
layout.state.label = "Start";
layout.render();
- Bangle.setPollInterval(80); // 12.5Hz, do not dynamically change accelerometer poll interval
+ Bangle.setOptions({powerSave: false}); // do not dynamically change accelerometer poll interval
+ Bangle.setPollInterval(80); // 12.5Hz
Bangle.on('accel', (accelData) => {
const now = new Date();
const acc = accelData.mag;
From 433f8adc187849ccb9221d129ecb6ac3d4a6f9cb Mon Sep 17 00:00:00 2001
From: julowe
Date: Wed, 15 Jun 2022 10:27:51 -0700
Subject: [PATCH 07/14] qrcode: add MeCard (contact info) creation
add html elements and script for First & Last Names, Phone Number, Email, and Website elements of meCard format. Bump to v0.06
---
apps/qrcode/ChangeLog | 1 +
apps/qrcode/custom.html | 60 +++++++++++++++++++++++++++++++++++++--
apps/qrcode/metadata.json | 2 +-
3 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/apps/qrcode/ChangeLog b/apps/qrcode/ChangeLog
index 6d9cc0569..52eadbcf9 100644
--- a/apps/qrcode/ChangeLog
+++ b/apps/qrcode/ChangeLog
@@ -3,3 +3,4 @@
0.03: Forces integer scaling and adds more configuration (error correction, description, display)
0.04: Allow scanning of QR codes from camera or file
0.05: Change brightness on touch
+0.06: Add ability to generate contact info (MeCard format) QR code
diff --git a/apps/qrcode/custom.html b/apps/qrcode/custom.html
index 7ae3eb3af..9955ea6c9 100644
--- a/apps/qrcode/custom.html
+++ b/apps/qrcode/custom.html
@@ -8,6 +8,8 @@
+
+
@@ -64,6 +66,14 @@
+
+
Try your QR Code:
@@ -156,7 +166,7 @@
function toggleVis(id){
console.info("Got id", id);
- ["srcScanFile", "srcText", "srcWifi", "srcScanCam"].forEach(function (item){
+ ["srcScanFile", "srcText", "srcWifi", "srcScanCam", "srcMeCard"].forEach(function (item){
document.getElementById(item).style.display = "none";
});
if (id != undefined && id != null) document.getElementById(id).style.display = "block";
@@ -188,6 +198,37 @@
}
return qrstring;
}
+
+ function generateMeCardString(meNameFirst, meNameLast, mePhoneNumber, meEmail, meWebsite){
+ var meCardStringOutput = 'MECARD:';
+
+ //first & Last name part of string, can have one or both
+ if (meNameFirst.trim().length != 0 && meNameLast.trim().length != 0) {
+ meCardStringOutput += 'N:'+meNameLast.trim()+','+meNameFirst.trim()+';';
+ }
+ else if (meNameLast.trim().length != 0) {
+ meCardStringOutput += 'N:'+meNameLast.trim()+';';
+ }
+ else if (meNameFirst.trim().length != 0) {
+ meCardStringOutput += 'N:'+meNameFirst.trim()+';';
+ }
+
+ if (mePhoneNumber.trim().length != 0) {
+ meCardStringOutput += 'TEL:'+mePhoneNumber.trim()+';';
+ }
+
+ if (meEmail.trim().length != 0) {
+ meCardStringOutput += 'EMAIL:'+meEmail.trim()+';';
+ }
+
+ if (meWebsite.trim().length != 0) {
+ meCardStringOutput += 'URL:'+meWebsite.trim()+';';
+ }
+
+ meCardStringOutput += ';';
+ return meCardStringOutput;
+ }
+
function refreshQRCode(){
if (qrcode == null){
qrcode = new QRCode("qrcode", {
@@ -206,6 +247,14 @@
const hidden = document.getElementById("hidden").checked;
const wifiString = generateWifiString(ssid, password, hidden, encryption);
qrText= wifiString;
+ } else if (document.getElementById("useMECARD").checked) {
+ const meNameFirst = document.getElementById("meNameFirst").value;
+ const meNameLast = document.getElementById("meNameLast").value;
+ const mePhoneNumber = document.getElementById("mePhoneNumber").value;
+ const meEmail = document.getElementById("meEmail").value;
+ const meWebsite = document.getElementById("meWebsite").value;
+ const meCardString = generateMeCardString(meNameFirst, meNameLast, mePhoneNumber, meEmail, meWebsite);
+ qrText = meCardString;
} else if (document.getElementById("useCAM").checked) {
qrText= document.getElementById("camQrResult").innerText;
} else if (document.getElementById("useFILE").checked) {
@@ -258,6 +307,14 @@
}
document.getElementById("useTEXT").addEventListener("change",function(){toggleVis("srcText");});
+
+ document.getElementById("useMECARD").addEventListener("change",function(){toggleVis("srcMeCard");});
+ document.getElementById("meNameFirst").addEventListener("change",refreshQRCode);
+ document.getElementById("meNameLast").addEventListener("change",refreshQRCode);
+ document.getElementById("mePhoneNumber").addEventListener("change",refreshQRCode);
+ document.getElementById("meEmail").addEventListener("change",refreshQRCode);
+ document.getElementById("meWebsite").addEventListener("change",refreshQRCode);
+
document.getElementById("useCAM").addEventListener("change",function(){
initQrScanner();
initQrCam();
@@ -314,7 +371,6 @@ g.setColor(1,1,1);
});
-
document.getElementById('camList').addEventListener('change', event => {
scanner.setCamera(event.target.value).then(updateFlashAvailability);
});
diff --git a/apps/qrcode/metadata.json b/apps/qrcode/metadata.json
index 22f8f7b53..24af7b813 100644
--- a/apps/qrcode/metadata.json
+++ b/apps/qrcode/metadata.json
@@ -1,7 +1,7 @@
{
"id": "qrcode",
"name": "Custom QR Code",
- "version": "0.05",
+ "version": "0.06",
"description": "Use this to upload a customised QR code to Bangle.js",
"icon": "app.png",
"tags": "qrcode",
From 0eeb8e79768f2101ec4f662e4b3c065734b4e48b Mon Sep 17 00:00:00 2001
From: thyttan <97237430+thyttan@users.noreply.github.com>
Date: Wed, 15 Jun 2022 22:30:42 +0200
Subject: [PATCH 08/14] 'Swipe to exit' now uses load()
...instead of showClock() which is now removed completely.
---
apps/dtlaunch/app-b2.js | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/apps/dtlaunch/app-b2.js b/apps/dtlaunch/app-b2.js
index 46194ec5d..8cd5790bb 100644
--- a/apps/dtlaunch/app-b2.js
+++ b/apps/dtlaunch/app-b2.js
@@ -89,7 +89,7 @@ function drawPage(p){
Bangle.on("swipe",(dirLeftRight, dirUpDown)=>{
selected = 0;
oldselected=-1;
- if(settings.swipeExit && dirLeftRight==1) showClock();
+ if(settings.swipeExit && dirLeftRight==1) load();
if (dirUpDown==-1||dirLeftRight==-1){
++page; if (page>maxPage) page=0;
drawPage(page);
@@ -99,12 +99,6 @@ Bangle.on("swipe",(dirLeftRight, dirUpDown)=>{
}
});
-function showClock(){
- var app = require("Storage").readJSON('setting.json', 1).clock;
- if (app) load(app);
- else E.showMessage("clock\nnot found");
-}
-
function isTouched(p,n){
if (n<0 || n>3) return false;
var x1 = (n%2)*72+XOFF; var y1 = n>1?72+YOFF:YOFF;
From 9e4b3925e61e7fea178b590dc771a9e099e60bbb Mon Sep 17 00:00:00 2001
From: thyttan <97237430+thyttan@users.noreply.github.com>
Date: Wed, 15 Jun 2022 22:46:35 +0200
Subject: [PATCH 09/14] 'Swipe to exit' now uses load()
..instead of showClock() which has been completely removed.
---
apps/dtlaunch/ChangeLog | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/dtlaunch/ChangeLog b/apps/dtlaunch/ChangeLog
index 09804b82e..c06e6fa34 100644
--- a/apps/dtlaunch/ChangeLog
+++ b/apps/dtlaunch/ChangeLog
@@ -12,3 +12,4 @@
0.12: On Bangle 2 change to swiping up/down to move between pages as to match page indicator. Swiping from left to right now loads the clock.
0.13: Added swipeExit setting so that left-right to exit is an option
0.14: Don't move pages when doing exit swipe.
+0.15: 'Swipe to exit'-code is slightly altered to be more reliable.
From 45394ef7eefc4d3fb0a52a7e56dc9451e444154a Mon Sep 17 00:00:00 2001
From: thyttan <97237430+thyttan@users.noreply.github.com>
Date: Wed, 15 Jun 2022 22:47:18 +0200
Subject: [PATCH 10/14] 'Swipe to exit' now uses load()
...instead of showClock() which has been completely removed.
---
apps/dtlaunch/metadata.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/dtlaunch/metadata.json b/apps/dtlaunch/metadata.json
index 4a0b8067c..9711a6964 100644
--- a/apps/dtlaunch/metadata.json
+++ b/apps/dtlaunch/metadata.json
@@ -1,7 +1,7 @@
{
"id": "dtlaunch",
"name": "Desktop Launcher",
- "version": "0.14",
+ "version": "0.15",
"description": "Desktop style App Launcher with six (four for Bangle 2) apps per page - fast access if you have lots of apps installed.",
"screenshots": [{"url":"shot1.png"},{"url":"shot2.png"},{"url":"shot3.png"}],
"icon": "icon.png",
From 978b2c804d2dead2793699c9decf3cd1a4cb8f34 Mon Sep 17 00:00:00 2001
From: thyttan <97237430+thyttan@users.noreply.github.com>
Date: Wed, 15 Jun 2022 22:56:47 +0200
Subject: [PATCH 11/14] Clarify Bangle 2 on 0.14 and 0.15
---
apps/dtlaunch/ChangeLog | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/dtlaunch/ChangeLog b/apps/dtlaunch/ChangeLog
index c06e6fa34..a360e4875 100644
--- a/apps/dtlaunch/ChangeLog
+++ b/apps/dtlaunch/ChangeLog
@@ -11,5 +11,5 @@
0.11: Fix bangle.js 1 white icons not displaying
0.12: On Bangle 2 change to swiping up/down to move between pages as to match page indicator. Swiping from left to right now loads the clock.
0.13: Added swipeExit setting so that left-right to exit is an option
-0.14: Don't move pages when doing exit swipe.
-0.15: 'Swipe to exit'-code is slightly altered to be more reliable.
+0.14: Don't move pages when doing exit swipe - Bangle 2.
+0.15: 'Swipe to exit'-code is slightly altered to be more reliable - Bangle 2.
From 5e245af74536d67d8025b0a7ffa45797119d2d67 Mon Sep 17 00:00:00 2001
From: thyttan <97237430+thyttan@users.noreply.github.com>
Date: Wed, 15 Jun 2022 22:58:06 +0200
Subject: [PATCH 12/14] spelling
---
apps/dtlaunch/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/dtlaunch/README.md b/apps/dtlaunch/README.md
index 55c9f53b8..1835bc842 100644
--- a/apps/dtlaunch/README.md
+++ b/apps/dtlaunch/README.md
@@ -27,7 +27,7 @@ Bangle 2:
## Controls- Bangle 2
-**Touch** - icon to select, scond touch launches app
+**Touch** - icon to select, second touch launches app
**Swipe Left/Up** - move to next page of app icons
From ce62d98a26a6e6e241596de52723f431e2afc835 Mon Sep 17 00:00:00 2001
From: BartS23 <10829389+BartS23@users.noreply.github.com>
Date: Thu, 16 Jun 2022 08:48:40 +0200
Subject: [PATCH 13/14] Fix wrong function call
---
apps/health/interface.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/health/interface.html b/apps/health/interface.html
index 0791acd24..a708e2645 100644
--- a/apps/health/interface.html
+++ b/apps/health/interface.html
@@ -113,7 +113,7 @@ function getMonthList() {
Util.showModal("Deleting...");
Util.eraseStorage(filename,()=>{
Util.hideModal();
- getTrackList();
+ getMonthList();
});
}
if (task=="downloadcsv") {
From 267f043dfe88442efd5c2682925ba2b081e52b8f Mon Sep 17 00:00:00 2001
From: Felix Wiedenbach
Date: Thu, 16 Jun 2022 10:28:25 +0200
Subject: [PATCH 14/14] documents all four possible widget areas
---
README.md | 2 +-
typescript/types/globals.d.ts | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index e8d5579c0..ea485da86 100644
--- a/README.md
+++ b/README.md
@@ -191,7 +191,7 @@ widget bar at the top of the screen they can add themselves to the global
```
WIDGETS["mywidget"]={
- area:"tl", // tl (top left), tr (top right)
+ area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right)
sortorder:0, // (Optional) determines order of widgets in the same corner
width: 24, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout
draw:draw // called to draw the widget
diff --git a/typescript/types/globals.d.ts b/typescript/types/globals.d.ts
index e82c3da3d..e2da49a0e 100644
--- a/typescript/types/globals.d.ts
+++ b/typescript/types/globals.d.ts
@@ -33,7 +33,7 @@ done "heatshrink": "readonly",
"Math": "readonly",
"Modules": "readonly",
"NRF": "readonly",
- "Number": "readonly",
+ "Number": "readonly",
"Object": "readonly",
"OneWire": "readonly",
"Pin": "readonly",
@@ -176,8 +176,9 @@ declare type GraphicsApi = {
declare const Graphics: GraphicsApi;
declare const g: GraphicsApi;
+type WidgetArea = 'tl' | 'tr' | 'bl' | 'br';
declare type Widget = {
- area: 'tr' | 'tl';
+ area: WidgetArea;
width: number;
draw: (this: { x: number; y: number }) => void;
};