Merge branch 'master' of github.com:espruino/BangleApps

master
Gordon Williams 2022-11-16 15:23:09 +00:00
commit b51b9e8fab
24 changed files with 294 additions and 117 deletions

View File

@ -21,3 +21,6 @@ back-functionality through setUI, adding the red back button as well. Hardware
button to exit is no longer an option. button to exit is no longer an option.
0.19: Bangle 2: Utilize new Bangle.load(), Bangle.showClock() functions to 0.19: Bangle 2: Utilize new Bangle.load(), Bangle.showClock() functions to
facilitate 'fast switching' of apps where available. facilitate 'fast switching' of apps where available.
0.20: Bangle 2: Revert use of Bangle.load() to classic load() calls since
widgets would still be loaded when they weren't supposed to.

View File

@ -1,18 +1,18 @@
{ // must be inside our own scope here so that when we are unloaded everything disappears { // must be inside our own scope here so that when we are unloaded everything disappears
/* Desktop launcher /* Desktop launcher
* *
*/ */
let settings = Object.assign({ let settings = Object.assign({
showClocks: true, showClocks: true,
showLaunchers: true, showLaunchers: true,
direct: false, direct: false,
swipeExit: false, swipeExit: false,
timeOut: "Off" timeOut: "Off"
}, require('Storage').readJSON("dtlaunch.json", true) || {}); }, require('Storage').readJSON("dtlaunch.json", true) || {});
let s = require("Storage"); let s = require("Storage");
var apps = s.list(/\.info$/).map(app=>{ var apps = s.list(/\.info$/).map(app=>{
let a=s.readJSON(app,1); let a=s.readJSON(app,1);
return a && { return a && {
@ -20,28 +20,28 @@ let s = require("Storage");
};}).filter( };}).filter(
app=>app && (app.type=="app" || (app.type=="clock" && settings.showClocks) || (app.type=="launch" && settings.showLaunchers) || !app.type)); app=>app && (app.type=="app" || (app.type=="clock" && settings.showClocks) || (app.type=="launch" && settings.showLaunchers) || !app.type));
apps.sort((a,b)=>{ apps.sort((a,b)=>{
let n=(0|a.sortorder)-(0|b.sortorder); let n=(0|a.sortorder)-(0|b.sortorder);
if (n) return n; // do sortorder first if (n) return n; // do sortorder first
if (a.name<b.name) return -1; if (a.name<b.name) return -1;
if (a.name>b.name) return 1; if (a.name>b.name) return 1;
return 0; return 0;
}); });
apps.forEach(app=>{ apps.forEach(app=>{
if (app.icon) if (app.icon)
app.icon = s.read(app.icon); // should just be a link to a memory area app.icon = s.read(app.icon); // should just be a link to a memory area
}); });
let Napps = apps.length; let Napps = apps.length;
let Npages = Math.ceil(Napps/4); let Npages = Math.ceil(Napps/4);
let maxPage = Npages-1; let maxPage = Npages-1;
let selected = -1; let selected = -1;
let oldselected = -1; let oldselected = -1;
let page = 0; let page = 0;
const XOFF = 24; const XOFF = 24;
const YOFF = 30; const YOFF = 30;
let drawIcon= function(p,n,selected) { let drawIcon= function(p,n,selected) {
let x = (n%2)*72+XOFF; let x = (n%2)*72+XOFF;
let y = n>1?72+YOFF:YOFF; let y = n>1?72+YOFF:YOFF;
(selected?g.setColor(g.theme.fgH):g.setColor(g.theme.bg)).fillRect(x+11,y+3,x+60,y+52); (selected?g.setColor(g.theme.fgH):g.setColor(g.theme.bg)).fillRect(x+11,y+3,x+60,y+52);
@ -65,9 +65,9 @@ let drawIcon= function(p,n,selected) {
} }
} }
g.drawString(line.trim(),x+36,y+54+lineY*8); g.drawString(line.trim(),x+36,y+54+lineY*8);
}; };
let drawPage = function(p){ let drawPage = function(p){
g.reset(); g.reset();
g.clearRect(0,24,175,175); g.clearRect(0,24,175,175);
let O = 88+YOFF/2-12*(Npages/2); let O = 88+YOFF/2-12*(Npages/2);
@ -82,12 +82,12 @@ let drawPage = function(p){
drawIcon(p,i,selected==i && !settings.direct); drawIcon(p,i,selected==i && !settings.direct);
} }
g.flip(); g.flip();
}; };
Bangle.loadWidgets(); Bangle.loadWidgets();
drawPage(0); drawPage(0);
let swipeListenerDt = function(dirLeftRight, dirUpDown){ let swipeListenerDt = function(dirLeftRight, dirUpDown){
updateTimeoutToClock(); updateTimeoutToClock();
selected = 0; selected = 0;
oldselected=-1; oldselected=-1;
@ -99,16 +99,16 @@ let swipeListenerDt = function(dirLeftRight, dirUpDown){
--page; if (page<0) page=maxPage; --page; if (page<0) page=maxPage;
drawPage(page); drawPage(page);
} }
}; };
let isTouched = function(p,n){ let isTouched = function(p,n){
if (n<0 || n>3) return false; if (n<0 || n>3) return false;
let x1 = (n%2)*72+XOFF; let y1 = n>1?72+YOFF:YOFF; let x1 = (n%2)*72+XOFF; let y1 = n>1?72+YOFF:YOFF;
let x2 = x1+71; let y2 = y1+81; let x2 = x1+71; let y2 = y1+81;
return (p.x>x1 && p.y>y1 && p.x<x2 && p.y<y2); return (p.x>x1 && p.y>y1 && p.x<x2 && p.y<y2);
}; };
let touchListenerDt = function(_,p){ let touchListenerDt = function(_,p){
updateTimeoutToClock(); updateTimeoutToClock();
let i; let i;
for (i=0;i<4;i++){ for (i=0;i<4;i++){
@ -119,7 +119,7 @@ let touchListenerDt = function(_,p){
if (selected!=i && !settings.direct){ if (selected!=i && !settings.direct){
drawIcon(page,selected,false); drawIcon(page,selected,false);
} else { } else {
Bangle.load(apps[page*4+i].src); load(apps[page*4+i].src);
} }
} }
selected=i; selected=i;
@ -131,25 +131,25 @@ let touchListenerDt = function(_,p){
drawIcon(page,selected,false); drawIcon(page,selected,false);
selected=-1; selected=-1;
} }
}; };
Bangle.setUI({ Bangle.setUI({
mode : 'custom', mode : 'custom',
back : Bangle.showClock, back : Bangle.showClock,
swipe : swipeListenerDt, swipe : swipeListenerDt,
touch : touchListenerDt, touch : touchListenerDt,
remove : ()=>{if (timeoutToClock) clearTimeout(timeoutToClock);} remove : ()=>{if (timeoutToClock) clearTimeout(timeoutToClock);}
}); });
// taken from Icon Launcher with minor alterations // taken from Icon Launcher with minor alterations
let timeoutToClock; let timeoutToClock;
const updateTimeoutToClock = function(){ const updateTimeoutToClock = function(){
if (settings.timeOut!="Off"){ if (settings.timeOut!="Off"){
let time=parseInt(settings.timeOut); //the "s" will be trimmed by the parseInt let time=parseInt(settings.timeOut); //the "s" will be trimmed by the parseInt
if (timeoutToClock) clearTimeout(timeoutToClock); if (timeoutToClock) clearTimeout(timeoutToClock);
timeoutToClock = setTimeout(Bangle.showClock,time*1000); timeoutToClock = setTimeout(Bangle.showClock,time*1000);
} }
}; };
updateTimeoutToClock(); updateTimeoutToClock();
} // end of app scope } // end of app scope

View File

@ -1,7 +1,7 @@
{ {
"id": "dtlaunch", "id": "dtlaunch",
"name": "Desktop Launcher", "name": "Desktop Launcher",
"version": "0.19", "version": "0.20",
"description": "Desktop style App Launcher with six (four for Bangle 2) apps per page - fast access if you have lots of apps installed.", "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"}], "screenshots": [{"url":"shot1.png"},{"url":"shot2.png"},{"url":"shot3.png"}],
"icon": "icon.png", "icon": "icon.png",

View File

@ -7,3 +7,5 @@
0.21: Add Settings 0.21: Add Settings
0.22: Use default Bangle formatter for booleans 0.22: Use default Bangle formatter for booleans
0.23: Added note to configure position in "my location" if not done yet. Small fixes. 0.23: Added note to configure position in "my location" if not done yet. Small fixes.
0.24: Added fast load
0.25: Minor code optimization

View File

@ -1,3 +1,5 @@
{ // must be inside our own scope here so that when we are unloaded everything disappears
// ------- Settings file // ------- Settings file
const SETTINGSFILE = "hworldclock.json"; const SETTINGSFILE = "hworldclock.json";
var secondsMode; var secondsMode;
@ -153,15 +155,15 @@ function updatePos() {
function drawSeconds() { function drawSeconds() {
// get date // get date
var d = new Date(); let d = new Date();
var da = d.toString().split(" "); let da = d.toString().split(" ");
// default draw styles // default draw styles
g.reset().setBgColor(g.theme.bg).setFontAlign(0, 0); g.reset().setBgColor(g.theme.bg).setFontAlign(0, 0);
// draw time // draw time
var time = da[4].split(":"); let time = da[4].split(":");
var seconds = time[2]; let seconds = time[2];
g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3);
if (g.theme.dark) { if (g.theme.dark) {
@ -184,15 +186,15 @@ function drawSeconds() {
function draw() { function draw() {
// get date // get date
var d = new Date(); let d = new Date();
var da = d.toString().split(" "); let da = d.toString().split(" ");
// default draw styles // default draw styles
g.reset().setBgColor(g.theme.bg).setFontAlign(0, 0); g.reset().setBgColor(g.theme.bg).setFontAlign(0, 0);
// draw time // draw time
var time = da[4].split(":"); let time = da[4].split(":");
var hours = time[0], let hours = time[0],
minutes = time[1]; minutes = time[1];
@ -223,7 +225,7 @@ function draw() {
// am / PM ? // am / PM ?
if (_12hour){ if (_12hour){
//do 12 hour stuff //do 12 hour stuff
//var ampm = require("locale").medidian(new Date()); Not working //let ampm = require("locale").medidian(new Date()); Not working
g.setFont("Vector", 17); g.setFont("Vector", 17);
g.drawString(ampm, xyCenterSeconds, yAmPm, true); g.drawString(ampm, xyCenterSeconds, yAmPm, true);
} }
@ -232,14 +234,14 @@ function draw() {
// draw Day, name of month, Date // draw Day, name of month, Date
//DATE //DATE
var localDate = require("locale").date(new Date(), 1); let localDate = require("locale").date(new Date(), 1);
localDate = localDate.substring(0, localDate.length - 5); localDate = localDate.substring(0, localDate.length - 5);
g.setFont("Vector", 17); g.setFont("Vector", 17);
g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true); g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true);
g.setFont(font, primaryDateFontSize); g.setFont(font, primaryDateFontSize);
// set gmt to UTC+0 // set gmt to UTC+0
var gmt = new Date(d.getTime() + d.getTimezoneOffset() * 60 * 1000); let gmt = new Date(d.getTime() + d.getTimezoneOffset() * 60 * 1000);
// Loop through offset(s) and render // Loop through offset(s) and render
offsets.forEach((offset, index) => { offsets.forEach((offset, index) => {
@ -249,7 +251,7 @@ function draw() {
if (offsets.length === 1) { if (offsets.length === 1) {
var date = [require("locale").dow(new Date(), 1), require("locale").date(new Date(), 1)]; let date = [require("locale").dow(new Date(), 1), require("locale").date(new Date(), 1)];
// For a single secondary timezone, draw it bigger and drop time zone to second line // For a single secondary timezone, draw it bigger and drop time zone to second line
const xOffset = 30; const xOffset = 30;
g.setFont(font, secondaryTimeFontSize).drawString(`${hours}:${minutes}`, xyCenter, yposTime2, true); g.setFont(font, secondaryTimeFontSize).drawString(`${hours}:${minutes}`, xyCenter, yposTime2, true);
@ -295,8 +297,18 @@ g.clear();
// Init the settings of the app // Init the settings of the app
loadMySettings(); loadMySettings();
// Show launcher when button pressed // Show launcher when middle button pressed
Bangle.setUI("clock"); Bangle.setUI({
mode : "clock",
remove : function() {
// Called to unload all of the clock app
if (PosInterval) clearInterval(PosInterval);
PosInterval = undefined;
if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds);
drawTimeoutSeconds = undefined;
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
}});
Bangle.loadWidgets(); Bangle.loadWidgets();
Bangle.drawWidgets(); Bangle.drawWidgets();
@ -307,7 +319,7 @@ draw();
if (!Bangle.isLocked()) { // Initial state if (!Bangle.isLocked()) { // Initial state
if (showSunInfo) { if (showSunInfo) {
if (PosInterval != 0) clearInterval(PosInterval); if (PosInterval != 0 && typeof PosInterval != 'undefined') clearInterval(PosInterval);
PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins
updatePos(); updatePos();
} }
@ -333,7 +345,7 @@ if (!Bangle.isLocked()) { // Initial state
drawTimeout = undefined; drawTimeout = undefined;
if (showSunInfo) { if (showSunInfo) {
if (PosInterval != 0) clearInterval(PosInterval); if (PosInterval != 0 && typeof PosInterval != 'undefined') clearInterval(PosInterval);
PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins
updatePos(); updatePos();
} }
@ -379,3 +391,4 @@ Bangle.on('lock',on=>{
draw(); // draw immediately, queue redraw draw(); // draw immediately, queue redraw
} }
}); });
}

View File

@ -2,7 +2,7 @@
"id": "hworldclock", "id": "hworldclock",
"name": "Hanks World Clock", "name": "Hanks World Clock",
"shortName": "Hanks World Clock", "shortName": "Hanks World Clock",
"version": "0.23", "version": "0.25",
"description": "Current time zone plus up to three others", "description": "Current time zone plus up to three others",
"allow_emulator":true, "allow_emulator":true,
"icon": "app.png", "icon": "app.png",

View File

@ -15,3 +15,6 @@
0.11: Cleanup timeout when changing to clock 0.11: Cleanup timeout when changing to clock
Reset timeout on swipe and drag Reset timeout on swipe and drag
0.12: Use Bangle.load and Bangle.showClock 0.12: Use Bangle.load and Bangle.showClock
0.13: Fix automatic switch to clock
0.14: Revert use of Bangle.load to classic load calls since widgets would
still be loaded when they weren't supposed to.

View File

@ -94,7 +94,7 @@
const appId = id * appsN + iconN; const appId = id * appsN + iconN;
if( settings.direct && launchCache.apps[appId]) if( settings.direct && launchCache.apps[appId])
{ {
Bangle.load(launchCache.apps[appId].src); load(launchCache.apps[appId].src);
return; return;
} }
if (appId == selectedItem && launchCache.apps[appId]) { if (appId == selectedItem && launchCache.apps[appId]) {
@ -102,7 +102,7 @@
if (!app.src || s.read(app.src) === undefined) { if (!app.src || s.read(app.src) === undefined) {
E.showMessage( /*LANG*/ "App Source\nNot found"); E.showMessage( /*LANG*/ "App Source\nNot found");
} else { } else {
Bangle.load(app.src); load(app.src);
} }
} }
selectedItem = appId; selectedItem = appId;
@ -198,7 +198,7 @@
if (settings.timeOut!="Off"){ if (settings.timeOut!="Off"){
let time=parseInt(settings.timeOut); //the "s" will be trimmed by the parseInt let time=parseInt(settings.timeOut); //the "s" will be trimmed by the parseInt
if (timeout) clearTimeout(timeout); if (timeout) clearTimeout(timeout);
timeout = setTimeout(returnToClock,time*1000); timeout = setTimeout(Bangle.showClock,time*1000);
} }
}; };

View File

@ -2,7 +2,7 @@
"id": "iconlaunch", "id": "iconlaunch",
"name": "Icon Launcher", "name": "Icon Launcher",
"shortName" : "Icon launcher", "shortName" : "Icon launcher",
"version": "0.12", "version": "0.14",
"icon": "app.png", "icon": "app.png",
"description": "A launcher inspired by smartphones, with an icon-only scrollable menu.", "description": "A launcher inspired by smartphones, with an icon-only scrollable menu.",
"tags": "tool,system,launcher", "tags": "tool,system,launcher",

View File

@ -1 +1,2 @@
0.01: New app 0.01: New app
0.02: Clear between redraws

View File

@ -1,7 +1,7 @@
{ {
"id": "widanclk", "id": "widanclk",
"name": "Analog clock widget", "name": "Analog clock widget",
"version": "0.01", "version": "0.02",
"description": "A simple analog clock widget that appears when not showing a fullscreen clock", "description": "A simple analog clock widget that appears when not showing a fullscreen clock",
"icon": "widget.png", "icon": "widget.png",
"type": "widget", "type": "widget",

View File

@ -12,7 +12,8 @@ WIDGETS["wdanclk"]={area:"tl",width:Bangle.CLOCK?0:24,draw:function() {
let x=this.x+12, y=this.y+12, let x=this.x+12, y=this.y+12,
ah = (d.getHours()+d.getMinutes()/60)*Math.PI/6, ah = (d.getHours()+d.getMinutes()/60)*Math.PI/6,
am = d.getMinutes()*Math.PI/30; am = d.getMinutes()*Math.PI/30;
g.drawCircle(x, y, 11). g.clearRect(this.x, this.y, this.x+this.width-1, this.y+23).
drawCircle(x, y, 11).
drawLine(x,y, x+Math.sin(ah)*7, y-Math.cos(ah)*7). drawLine(x,y, x+Math.sin(ah)*7, y-Math.cos(ah)*7).
drawLine(x,y, x+Math.sin(am)*9, y-Math.cos(am)*9); drawLine(x,y, x+Math.sin(am)*9, y-Math.cos(am)*9);
// queue draw in one minute // queue draw in one minute

View File

@ -13,3 +13,4 @@
0.14: Added configuration option 0.14: Added configuration option
0.15: Added option to hide widget when connected 0.15: Added option to hide widget when connected
0.16: Simplify code, add option to disable displaying a message 0.16: Simplify code, add option to disable displaying a message
0.17: Minor display fix

View File

@ -1,7 +1,7 @@
{ {
"id": "widbt_notify", "id": "widbt_notify",
"name": "Bluetooth Widget with Notification", "name": "Bluetooth Widget with Notification",
"version": "0.16", "version": "0.17",
"description": "Show the current Bluetooth connection status with some optional features: show message, buzz on connect/loss, hide always/if connected.", "description": "Show the current Bluetooth connection status with some optional features: show message, buzz on connect/loss, hide always/if connected.",
"icon": "widget.png", "icon": "widget.png",
"type": "widget", "type": "widget",

View File

@ -40,7 +40,7 @@
redrawCurrentApp: function() { redrawCurrentApp: function() {
if (typeof(draw) == 'function') { if (typeof(draw) == 'function') {
g.clear(); g.reset().clear();
draw(); draw();
Bangle.loadWidgets(); Bangle.loadWidgets();
Bangle.drawWidgets(); Bangle.drawWidgets();

View File

@ -3,3 +3,4 @@
0.03: Ensure redrawing works with variable size widget system 0.03: Ensure redrawing works with variable size widget system
0.04: tag HRM power requests to allow this ot work alongside other widgets/apps (fix #799) 0.04: tag HRM power requests to allow this ot work alongside other widgets/apps (fix #799)
0.05: Use new 'lock' event, not LCD (so it works on Bangle.js 2) 0.05: Use new 'lock' event, not LCD (so it works on Bangle.js 2)
0.06: Allow configuration of minimum confidence for HRM values

View File

@ -1,13 +1,15 @@
{ {
"id": "widhrm", "id": "widhrm",
"name": "Simple Heart Rate widget", "name": "Simple Heart Rate widget",
"version": "0.05", "version": "0.06",
"description": "When the screen is on, the widget turns on the heart rate monitor and displays the current heart rate (or last known in grey). For this to work well you'll need at least a 15 second LCD Timeout.", "description": "When the screen is on, the widget turns on the heart rate monitor and displays the current heart rate (or last known in grey). For this to work well you'll need at least a 15 second LCD Timeout.",
"icon": "widget.png", "icon": "widget.png",
"type": "widget", "type": "widget",
"tags": "health,widget", "tags": "health,widget",
"supports": ["BANGLEJS","BANGLEJS2"], "supports": ["BANGLEJS","BANGLEJS2"],
"storage": [ "storage": [
{"name":"widhrm.wid.js","url":"widget.js"} {"name":"widhrm.wid.js","url":"widget.js"},
] {"name":"widhrm.settings.js","url":"settings.js"}
],
"data": [{"name":"widhrm.json"}]
} }

36
apps/widhrm/settings.js Normal file
View File

@ -0,0 +1,36 @@
/**
* @param {function} back Use back() to return to settings menu
*/
(function(back) {
const SETTINGS_FILE = "widhrm.json";
const storage = require("Storage");
let s = {
confidence: 0
};
const saved = storage.readJSON(SETTINGS_FILE, 1) || {};
for(const key in saved) {
s[key] = saved[key];
}
function save(key, value) {
s[key] = value;
storage.write(SETTINGS_FILE, s);
}
const menu = {
"": {"title": "Simple Heart Rate widget"},
"< Back": back,
/*LANG*/'min. confidence': {
value: s.confidence,
min: 0,
max : 100,
step: 5,
format: x => {
return x + "%";
},
onchange: x => save('confidence', x),
},
};
E.showMenu(menu);
});

View File

@ -1,5 +1,18 @@
(() => { (() => {
if (!Bangle.isLocked) return; // old firmware if (!Bangle.isLocked) return; // old firmware
const SETTINGS_FILE = 'widhrm.json';
let settings;
function loadSettings() {
settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {};
const DEFAULTS = {
'confidence': 0
};
Object.keys(DEFAULTS).forEach(k=>{
if (settings[k]===undefined) settings[k]=DEFAULTS[k];
});
}
var currentBPM; var currentBPM;
var lastBPM; var lastBPM;
var isHRMOn = false; var isHRMOn = false;
@ -39,7 +52,7 @@
bpm = lastBPM; bpm = lastBPM;
isCurrent = false; isCurrent = false;
} }
if (bpm===undefined) if (bpm===undefined || (settings && bpm<settings["confidence"]))
bpm = "--"; bpm = "--";
g.setColor(isCurrent ? g.theme.fg : "#808080"); g.setColor(isCurrent ? g.theme.fg : "#808080");
g.drawString(bpm, this.x+width/2, this.y+19); g.drawString(bpm, this.x+width/2, this.y+19);

View File

@ -0,0 +1,4 @@
0.01: First version
0.02: Load settings only once
Better icons
Read sleep status on every draw

View File

@ -0,0 +1,16 @@
{
"id": "widsleepstatus",
"name": "Sleep Status Widget",
"version": "0.02",
"description": "Shows current status of sleep from sleeplog app.",
"icon": "widget.png",
"type": "widget",
"tags": "widget,sleep",
"supports": ["BANGLEJS","BANGLEJS2"],
"dependencies" : { "sleeplog":"app" },
"storage": [
{"name":"widsleepstatus.wid.js","url":"widget.js"},
{"name":"widsleepstatus.settings.js","url":"settings.js"}
],
"data": [{"name":"widsleepstatus.json"}]
}

View File

@ -0,0 +1,32 @@
/**
* @param {function} back Use back() to return to settings menu
*/
(function(back) {
const SETTINGS_FILE = "widsleepstatus.json";
const storage = require("Storage");
let s = {
hidewhenawake: true
};
const saved = storage.readJSON(SETTINGS_FILE, 1) || {};
for(const key in saved) {
s[key] = saved[key];
}
function save(key) {
return function(value) {
s[key] = value;
storage.write(SETTINGS_FILE, s);
};
}
const menu = {
"": {"title": "Sleep Status Widget"},
"< Back": back,
"Hide when awake": {
value: s.hidewhenawake,
onchange: save("hidewhenawake"),
},
};
E.showMenu(menu);
});

View File

@ -0,0 +1,49 @@
(function() {
if (!sleeplog) return;
const SETTINGS_FILE = 'widsleepstatus.json';
let settings;
function loadSettings() {
settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {};
const DEFAULTS = {
'hidewhenawake': true
};
Object.keys(DEFAULTS).forEach(k => {
if (settings[k] === undefined) settings[k] = DEFAULTS[k];
});
}
loadSettings();
WIDGETS.sleepstatus = {
area: "tr",
width: 0,
draw: function(w) {
let status = sleeplog.status || 0;
if (w.width != (status >= 2 ? 24 : 0)){
w.width = status >= 2 ? 24 : 0;
return Bangle.drawWidgets();
}
g.reset();
switch (status) {
case 0:
case 1:
break;
case 2: // awake
if (settings && !settings["hidewhenawake"]) g.drawImage(atob("GBiBAAAAAAAAAAAMAAA+AAAjAAEjMAGyYAGeYAzAwB5/gB4/AB4jAB4jAB4jAB4jAB//+Bv/+Bg2GB+2+B+2eB42eAAAAAAAAAAAAA=="), w.x, w.y);
break;
case 3: // light sleep
g.drawImage(atob("GBiBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAGAAAGAAAGAAAGcf/Ge//GWwBGewBmcwBn///mAABmAABmAABgAAAAAAAAAAAA=="), w.x, w.y);
break;
case 4: // deep sleep
g.drawImage(atob("GBiBAAAAAAAAAAAB4APw4APxwADh8AHAAAOAAGPwAGAAAGAAAGAAAGcf/Ge//GWwBGewBmcwBn///mAABmAABmAABgAAAAAAAAAAAA=="), w.x, w.y);
break;
}
}
};
setInterval(()=>{
WIDGETS.sleepstatus.draw(WIDGETS.sleepstatus);
}, 60000);
Bangle.drawWidgets();
})()

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B