mirror of https://github.com/espruino/BangleApps
add hardalarm
parent
e339b9b523
commit
369d076745
18
apps.json
18
apps.json
|
@ -2490,5 +2490,23 @@
|
||||||
{"name":"HRV.app.js","url":"app.js"},
|
{"name":"HRV.app.js","url":"app.js"},
|
||||||
{"name":"HRV.img","url":"app-icon.js","evaluate":true}
|
{"name":"HRV.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{ "id": "hardalarm",
|
||||||
|
"name": "Hard Alarm",
|
||||||
|
"shortName":"HardAlarm",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Count to the right number to turn off the alarm",
|
||||||
|
"tags": "tool,alarm,widget",
|
||||||
|
"storage": [
|
||||||
|
{"name":"hardalarm.app.js","url":"app.js"},
|
||||||
|
{"name":"hardalarm.boot.js","url":"boot.js"},
|
||||||
|
{"name":"hardalarm.js","url":"hardalarm.js"},
|
||||||
|
{"name":"hardalarm.img","url":"app-icon.js","evaluate":true},
|
||||||
|
{"name":"hardalarm.wid.js","url":"widget.js"}
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
{"name":"alarm.json"}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: Add a number to match to turn off alarm
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwkE5gA/AF9cBZXFQYIOGBIUMC5PATgQJFqAIBgovMBwISDAYQ5HGBAAGFxQ/FgMzmcgJ5BIKgAXFIxYuBgMxCIMjmcQgECiBHLFwITBFYIvBiBLBmQwLqECCYMziICBmIeBD4IwKFwQAIGAJGJRQUhgIbDAocQJBHAgYlCOQIrDAoUwhhGIiZZBX4gFEAgIXICIMwX4gFFC45eDF5RgI4pZHAo0gC43AXoaPJC4J4GRwQAMSA4XfmKuBC6kQRYQXMO4YACXYYADO46nDIwcCiBIFU47XDBwcTkBQFa4/MH4sAkYxBBAoWGC4I/DmQ1BdwJPEC5CQEmAECGQKOKMA0gCYRgELxBICCYUyFQZgCJgIWI5lQYIxjCGYMFC5PFLAiKDFwRGJGATCFLoYuKGAYYGiAuMDAkiCoMiCx6SCAAq7IF48F4tQCoMFqAXP4AQF4B1MSAZXFMwIXPA41VC5wA/ADAA=="))
|
|
@ -0,0 +1,112 @@
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
|
var alarms = require("Storage").readJSON("hardalarm.json",1)||[];
|
||||||
|
/*alarms = [
|
||||||
|
{ on : true,
|
||||||
|
hr : 6.5, // hours + minutes/60
|
||||||
|
msg : "Eat chocolate",
|
||||||
|
last : 0, // last day of the month we alarmed on - so we don't alarm twice in one day!
|
||||||
|
rp : true, // repeat
|
||||||
|
as : false, // auto snooze
|
||||||
|
}
|
||||||
|
];*/
|
||||||
|
|
||||||
|
function formatTime(t) {
|
||||||
|
var hrs = 0|t;
|
||||||
|
var mins = Math.round((t-hrs)*60);
|
||||||
|
return hrs+":"+("0"+mins).substr(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentHr() {
|
||||||
|
var time = new Date();
|
||||||
|
return time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMainMenu() {
|
||||||
|
const menu = {
|
||||||
|
'': { 'title': 'Alarms' },
|
||||||
|
'New Alarm': ()=>editAlarm(-1)
|
||||||
|
};
|
||||||
|
alarms.forEach((alarm,idx)=>{
|
||||||
|
txt = (alarm.on?"on ":"off ")+formatTime(alarm.hr);
|
||||||
|
if (alarm.rp) txt += " (repeat)";
|
||||||
|
menu[txt] = function() {
|
||||||
|
editAlarm(idx);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
menu['< Back'] = ()=>{load();};
|
||||||
|
return E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function editAlarm(alarmIndex) {
|
||||||
|
var newAlarm = alarmIndex<0;
|
||||||
|
var hrs = 12;
|
||||||
|
var mins = 0;
|
||||||
|
var en = true;
|
||||||
|
var repeat = true;
|
||||||
|
var as = false;
|
||||||
|
if (!newAlarm) {
|
||||||
|
var a = alarms[alarmIndex];
|
||||||
|
hrs = 0|a.hr;
|
||||||
|
mins = Math.round((a.hr-hrs)*60);
|
||||||
|
en = a.on;
|
||||||
|
repeat = a.rp;
|
||||||
|
as = a.as;
|
||||||
|
}
|
||||||
|
const menu = {
|
||||||
|
'': { 'title': 'Alarms' },
|
||||||
|
'Hours': {
|
||||||
|
value: hrs,
|
||||||
|
onchange: function(v){if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} // no arrow fn -> preserve 'this'
|
||||||
|
},
|
||||||
|
'Minutes': {
|
||||||
|
value: mins,
|
||||||
|
onchange: function(v){if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} // no arrow fn -> preserve 'this'
|
||||||
|
},
|
||||||
|
'Enabled': {
|
||||||
|
value: en,
|
||||||
|
format: v=>v?"On":"Off",
|
||||||
|
onchange: v=>en=v
|
||||||
|
},
|
||||||
|
'Repeat': {
|
||||||
|
value: en,
|
||||||
|
format: v=>v?"Yes":"No",
|
||||||
|
onchange: v=>repeat=v
|
||||||
|
},
|
||||||
|
'Auto snooze': {
|
||||||
|
value: as,
|
||||||
|
format: v=>v?"Yes":"No",
|
||||||
|
onchange: v=>as=v
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function getAlarm() {
|
||||||
|
var hr = hrs+(mins/60);
|
||||||
|
var day = 0;
|
||||||
|
// If alarm is for tomorrow not today (eg, in the past), set day
|
||||||
|
if (hr < getCurrentHr())
|
||||||
|
day = (new Date()).getDate();
|
||||||
|
// Save alarm
|
||||||
|
return {
|
||||||
|
on : en, hr : hr,
|
||||||
|
last : day, rp : repeat, as: as
|
||||||
|
};
|
||||||
|
}
|
||||||
|
menu["> Save"] = function() {
|
||||||
|
if (newAlarm) alarms.push(getAlarm());
|
||||||
|
else alarms[alarmIndex] = getAlarm();
|
||||||
|
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
|
||||||
|
showMainMenu();
|
||||||
|
};
|
||||||
|
if (!newAlarm) {
|
||||||
|
menu["> Delete"] = function() {
|
||||||
|
alarms.splice(alarmIndex,1);
|
||||||
|
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
|
||||||
|
showMainMenu();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
menu['< Back'] = showMainMenu;
|
||||||
|
return E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
showMainMenu();
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,25 @@
|
||||||
|
// check for alarms
|
||||||
|
(function() {
|
||||||
|
var alarms = require('Storage').readJSON('hardalarm.json',1)||[];
|
||||||
|
var time = new Date();
|
||||||
|
var active = alarms.filter(a=>a.on);
|
||||||
|
if (active.length) {
|
||||||
|
active = active.sort((a,b)=>(a.hr-b.hr)+(a.last-b.last)*24);
|
||||||
|
var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
|
||||||
|
if (!require('Storage').read("hardalarm.js")) {
|
||||||
|
console.log("No alarm app!");
|
||||||
|
require('Storage').write('hardalarm.json',"[]");
|
||||||
|
} else {
|
||||||
|
var t = 3600000*(active[0].hr-hr);
|
||||||
|
if (active[0].last == time.getDate() || t < 0) t += 86400000;
|
||||||
|
if (t<1000) t=1000;
|
||||||
|
/* execute alarm at the correct time. We avoid execing immediately
|
||||||
|
since this code will get called AGAIN when hardalarm.js is loaded. alarm.js
|
||||||
|
will then clearInterval() to get rid of this call so it can proceed
|
||||||
|
normally. */
|
||||||
|
setTimeout(function() {
|
||||||
|
load("hardalarm.js");
|
||||||
|
},t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
|
@ -0,0 +1,127 @@
|
||||||
|
// Chances are boot0.js got run already and scheduled *another*
|
||||||
|
// 'load(hardalarm.js)' - so let's remove it first!
|
||||||
|
clearInterval();
|
||||||
|
|
||||||
|
function formatTime(t) {
|
||||||
|
var hrs = 0|t;
|
||||||
|
var mins = Math.round((t-hrs)*60);
|
||||||
|
return hrs+":"+("0"+mins).substr(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentHr() {
|
||||||
|
var time = new Date();
|
||||||
|
return time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRandomInt(max) {
|
||||||
|
return Math.floor(Math.random() * Math.floor(max));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRandomFromRange(lowerRangeMin, lowerRangeMax, higherRangeMin, higherRangeMax) {
|
||||||
|
var lowerRange = lowerRangeMax - lowerRangeMin;
|
||||||
|
var higherRange = higherRangeMax - higherRangeMin;
|
||||||
|
var fullRange = lowerRange + higherRange;
|
||||||
|
var randomNum = getRandomInt(fullRange);
|
||||||
|
if(randomNum <= (lowerRangeMax - lowerRangeMin)) {
|
||||||
|
return randomNum + lowerRangeMin;
|
||||||
|
} else {
|
||||||
|
return randomNum + (higherRangeMin - lowerRangeMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showNumberPicker(currentGuess, randomNum) {
|
||||||
|
if(currentGuess == randomNum) {
|
||||||
|
E.showMessage("" + currentGuess + "\n PRESS ENTER", "Get to " + randomNum);
|
||||||
|
} else {
|
||||||
|
E.showMessage("" + currentGuess, "Get to " + randomNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showPrompt(msg, buzzCount, alarm) {
|
||||||
|
E.showPrompt(msg,{
|
||||||
|
title:"STAY AWAKE!",
|
||||||
|
buttons : {"Sleep":0,"Stop":1} // default is sleep so it'll come back in 10 mins
|
||||||
|
}).then(function(choice) {
|
||||||
|
buzzCount = 0;
|
||||||
|
if (choice==0) {
|
||||||
|
if(alarm.ohr===undefined) alarm.ohr = alarm.hr;
|
||||||
|
alarm.hr += 10/60; // 10 minutes
|
||||||
|
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
|
||||||
|
load();
|
||||||
|
} else if(choice==1) {
|
||||||
|
alarm.last = (new Date()).getDate();
|
||||||
|
if (alarm.ohr!==undefined) {
|
||||||
|
alarm.hr = alarm.ohr;
|
||||||
|
delete alarm.ohr;
|
||||||
|
}
|
||||||
|
if (!alarm.rp) alarm.on = false;
|
||||||
|
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAlarm(alarm) {
|
||||||
|
var msg = formatTime(alarm.hr);
|
||||||
|
var buzzCount = 20;
|
||||||
|
if (alarm.msg)
|
||||||
|
msg += "\n"+alarm.msg;
|
||||||
|
var okClicked = false;
|
||||||
|
var currentGuess = 10;
|
||||||
|
var randomNum = getRandomFromRange(0, 7, 13, 20);
|
||||||
|
showNumberPicker(currentGuess, randomNum)
|
||||||
|
setWatch(o => {
|
||||||
|
if(!okClicked && currentGuess < 20) {
|
||||||
|
currentGuess = currentGuess + 1;
|
||||||
|
showNumberPicker(currentGuess, randomNum);
|
||||||
|
}
|
||||||
|
}, BTN1, {repeat: true, edge: 'rising'});
|
||||||
|
|
||||||
|
setWatch(o => {
|
||||||
|
if(currentGuess == randomNum) {
|
||||||
|
okClicked = true;
|
||||||
|
showPrompt(msg, buzzCount, alarm);
|
||||||
|
}
|
||||||
|
}, BTN2, {repeat: true, edge: 'rising'});
|
||||||
|
|
||||||
|
setWatch(o => {
|
||||||
|
if(!okClicked && currentGuess > 0) {
|
||||||
|
currentGuess = currentGuess - 1;
|
||||||
|
showNumberPicker(currentGuess, randomNum);
|
||||||
|
}
|
||||||
|
}, BTN3, {repeat: true, edge: 'rising'});
|
||||||
|
|
||||||
|
function buzz() {
|
||||||
|
Bangle.buzz(500).then(()=>{
|
||||||
|
setTimeout(()=>{
|
||||||
|
Bangle.buzz(500).then(function() {
|
||||||
|
setTimeout(()=>{
|
||||||
|
Bangle.buzz(2000).then(function() {
|
||||||
|
if (buzzCount--)
|
||||||
|
setTimeout(buzz, 2000);
|
||||||
|
else if(alarm.as) { // auto-snooze
|
||||||
|
buzzCount = 20;
|
||||||
|
setTimeout(buzz, 600000); // 10 minutes
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},100);
|
||||||
|
});
|
||||||
|
},100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
buzz();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for alarms
|
||||||
|
var day = (new Date()).getDate();
|
||||||
|
var hr = getCurrentHr()+10000; // get current time - 10s in future to ensure we alarm if we've started the app a tad early
|
||||||
|
var alarms = require("Storage").readJSON("hardalarm.json",1)||[];
|
||||||
|
var active = alarms.filter(a=>a.on&&(a.hr<hr)&&(a.last!=day));
|
||||||
|
if (active.length) {
|
||||||
|
// if there's an alarm, show it
|
||||||
|
active = active.sort((a,b)=>a.hr-b.hr);
|
||||||
|
showAlarm(active[0]);
|
||||||
|
} else {
|
||||||
|
// otherwise just go back to default app
|
||||||
|
setTimeout(load, 100);
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
(() => {
|
||||||
|
var alarms = require('Storage').readJSON('hardalarm.json',1)||[];
|
||||||
|
alarms = alarms.filter(alarm=>alarm.on);
|
||||||
|
if (!alarms.length) return; // no alarms, no widget!
|
||||||
|
delete alarms;
|
||||||
|
// add the widget
|
||||||
|
WIDGETS["alarm"]={area:"tl",width:24,draw:function() {
|
||||||
|
g.setColor(-1);
|
||||||
|
g.drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
|
||||||
|
}};
|
||||||
|
})()
|
Loading…
Reference in New Issue