Merge pull request #1707 from alessandrococco/sched-unlock-display-at-buzz
[Scheduler] New functions & Settings pagemaster
commit
c214f47313
|
|
@ -18,3 +18,4 @@
|
|||
0.17: Moving alarm internals to 'sched' library
|
||||
0.18: Cope with >1 identical alarm at once (#1667)
|
||||
0.19: Ensure rescheduled alarms that already fired have 'last' reset
|
||||
0.20: Use the new 'sched' factories to initialize new alarms/timers
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
var alarms = require("sched").getAlarms();
|
||||
// An array of alarm objects (see sched/README.md)
|
||||
let alarms = require("sched").getAlarms();
|
||||
|
||||
// time in ms -> { hrs, mins }
|
||||
function decodeTime(t) {
|
||||
t = 0|t; // sanitise
|
||||
var hrs = 0|(t/3600000);
|
||||
return { hrs : hrs, mins : Math.round((t-hrs*3600000)/60000) };
|
||||
t = 0 | t; // sanitise
|
||||
let hrs = 0 | (t / 3600000);
|
||||
return { hrs: hrs, mins: Math.round((t - hrs * 3600000) / 60000) };
|
||||
}
|
||||
|
||||
// time in { hrs, mins } -> ms
|
||||
function encodeTime(o) {
|
||||
return o.hrs*3600000 + o.mins*60000;
|
||||
return o.hrs * 3600000 + o.mins * 60000;
|
||||
}
|
||||
|
||||
function formatTime(t) {
|
||||
var o = decodeTime(t);
|
||||
return o.hrs+":"+("0"+o.mins).substr(-2);
|
||||
let o = decodeTime(t);
|
||||
return o.hrs + ":" + ("0" + o.mins).substr(-2);
|
||||
}
|
||||
|
||||
function getCurrentTime() {
|
||||
var time = new Date();
|
||||
let time = new Date();
|
||||
return (
|
||||
time.getHours() * 3600000 +
|
||||
time.getMinutes() * 60000 +
|
||||
|
|
@ -39,7 +39,7 @@ function showMainMenu() {
|
|||
// Timer img "\0"+atob("DhKBAP////MDDAwwMGGBzgPwB4AeAPwHOBhgwMMzDez////w")
|
||||
// Alarm img "\0"+atob("FBSBAABgA4YcMPDGP8Zn/mx/48//PP/zD/8A//AP/wD/8A//AP/wH/+D//w//8AAAADwAAYA")
|
||||
const menu = {
|
||||
'': { 'title': 'Alarm/Timer' },
|
||||
'': { 'title': /*LANG*/'Alarms&Timers' },
|
||||
/*LANG*/'< Back' : ()=>{load();},
|
||||
/*LANG*/'New Alarm': ()=>editAlarm(-1),
|
||||
/*LANG*/'New Timer': ()=>editTimer(-1)
|
||||
|
|
@ -76,13 +76,13 @@ function showMainMenu() {
|
|||
function editDOW(dow, onchange) {
|
||||
const menu = {
|
||||
'': { 'title': /*LANG*/'Days of Week' },
|
||||
'< Back' : () => onchange(dow)
|
||||
/*LANG*/'< Back' : () => onchange(dow)
|
||||
};
|
||||
for (var i = 0; i < 7; i++) (i => {
|
||||
var dayOfWeek = require("locale").dow({ getDay: () => i });
|
||||
for (let i = 0; i < 7; i++) (i => {
|
||||
let dayOfWeek = require("locale").dow({ getDay: () => i });
|
||||
menu[dayOfWeek] = {
|
||||
value: !!(dow&(1<<i)),
|
||||
format: v => v ? "Yes" : "No",
|
||||
format: v => v ? /*LANG*/"Yes" : /*LANG*/"No",
|
||||
onchange: v => v ? dow |= 1<<i : dow &= ~(1<<i),
|
||||
};
|
||||
})(i);
|
||||
|
|
@ -90,23 +90,15 @@ function editDOW(dow, onchange) {
|
|||
}
|
||||
|
||||
function editAlarm(alarmIndex, alarm) {
|
||||
var newAlarm = alarmIndex<0;
|
||||
var a = {
|
||||
t : 12*3600000, // 12 o clock default
|
||||
on : true,
|
||||
rp : false, // repeat not the default
|
||||
as : false,
|
||||
dow : 0b1111111,
|
||||
last : 0,
|
||||
vibrate : ".."
|
||||
}
|
||||
let newAlarm = alarmIndex < 0;
|
||||
let a = require("sched").newDefaultAlarm();
|
||||
if (!newAlarm) Object.assign(a, alarms[alarmIndex]);
|
||||
if (alarm) Object.assign(a,alarm);
|
||||
var t = decodeTime(a.t);
|
||||
let t = decodeTime(a.t);
|
||||
|
||||
const menu = {
|
||||
'': { 'title': /*LANG*/'Alarm' },
|
||||
'< Back' : () => showMainMenu(),
|
||||
/*LANG*/'< Back' : () => showMainMenu(),
|
||||
/*LANG*/'Hours': {
|
||||
value: t.hrs, min : 0, max : 23, wrap : true,
|
||||
onchange: v => t.hrs=v
|
||||
|
|
@ -117,23 +109,23 @@ function editAlarm(alarmIndex, alarm) {
|
|||
},
|
||||
/*LANG*/'Enabled': {
|
||||
value: a.on,
|
||||
format: v=>v?"On":"Off",
|
||||
format: v => v ? /*LANG*/"On" : /*LANG*/"Off",
|
||||
onchange: v=>a.on=v
|
||||
},
|
||||
/*LANG*/'Repeat': {
|
||||
value: a.rp,
|
||||
format: v=>v?"Yes":"No",
|
||||
onchange: v=>a.rp=v
|
||||
format: v => v ? /*LANG*/"Yes" : /*LANG*/"No",
|
||||
onchange: v => a.rp = v
|
||||
},
|
||||
/*LANG*/'Days': {
|
||||
value: "SMTWTFS".split("").map((d,n)=>a.dow&(1<<n)?d:".").join(""),
|
||||
onchange: () => editDOW(a.dow, d=>{a.dow=d;editAlarm(alarmIndex,a)})
|
||||
},
|
||||
/*LANG*/'Vibrate': require("buzz_menu").pattern(a.vibrate, v => a.vibrate=v ),
|
||||
/*LANG*/'Auto snooze': {
|
||||
/*LANG*/'Auto Snooze': {
|
||||
value: a.as,
|
||||
format: v=>v?"Yes":"No",
|
||||
onchange: v=>a.as=v
|
||||
format: v => v ? /*LANG*/"Yes" : /*LANG*/"No",
|
||||
onchange: v => a.as = v
|
||||
}
|
||||
};
|
||||
menu[/*LANG*/"Save"] = function() {
|
||||
|
|
@ -155,23 +147,15 @@ function editAlarm(alarmIndex, alarm) {
|
|||
}
|
||||
|
||||
function editTimer(alarmIndex, alarm) {
|
||||
var newAlarm = alarmIndex<0;
|
||||
var a = {
|
||||
timer : 5*60*1000, // 5 minutes
|
||||
on : true,
|
||||
rp : false,
|
||||
as : false,
|
||||
dow : 0b1111111,
|
||||
last : 0,
|
||||
vibrate : ".."
|
||||
}
|
||||
let newAlarm = alarmIndex < 0;
|
||||
let a = require("sched").newDefaultTimer();
|
||||
if (!newAlarm) Object.assign(a, alarms[alarmIndex]);
|
||||
if (alarm) Object.assign(a,alarm);
|
||||
var t = decodeTime(a.timer);
|
||||
let t = decodeTime(a.timer);
|
||||
|
||||
const menu = {
|
||||
'': { 'title': /*LANG*/'Timer' },
|
||||
'< Back' : () => showMainMenu(),
|
||||
/*LANG*/'< Back' : () => showMainMenu(),
|
||||
/*LANG*/'Hours': {
|
||||
value: t.hrs, min : 0, max : 23, wrap : true,
|
||||
onchange: v => t.hrs=v
|
||||
|
|
@ -182,8 +166,8 @@ function editTimer(alarmIndex, alarm) {
|
|||
},
|
||||
/*LANG*/'Enabled': {
|
||||
value: a.on,
|
||||
format: v=>v?"On":"Off",
|
||||
onchange: v=>a.on=v
|
||||
format: v => v ? /*LANG*/"On" : /*LANG*/"Off",
|
||||
onchange: v => a.on = v
|
||||
},
|
||||
/*LANG*/'Vibrate': require("buzz_menu").pattern(a.vibrate, v => a.vibrate=v ),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"id": "alarm",
|
||||
"name": "Alarm & Timer",
|
||||
"name": "Alarms & Timers",
|
||||
"shortName": "Alarms",
|
||||
"version": "0.19",
|
||||
"version": "0.20",
|
||||
"description": "Set alarms and timers on your Bangle",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,alarm,widget",
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@
|
|||
0.02: Fix scheduling of other alarms if there is a pending alarm from the past (fix #1667)
|
||||
0.03: Fix `getTimeToAlarm` for a timer already used at same day, don't set `last` for timers.
|
||||
0.04: Fix `getTimeToAlarm` to check for next dow if alarm.t lower currentTime.
|
||||
0.05: Export new functions (`newDefaultAlarm/Timer`), add Settings page
|
||||
|
|
|
|||
|
|
@ -8,8 +8,17 @@ Other apps can use this to provide alarm functionality.
|
|||
App
|
||||
---
|
||||
|
||||
The Alarm app allows you to add/modify any running timers.
|
||||
The **Alarms & Timers** app allows you to add/modify any running alarms and timers.
|
||||
|
||||
Global Settings
|
||||
---------------
|
||||
|
||||
- `Unlock at Buzz` - If `Yes` the alarm/timer will unlock the watch
|
||||
- `Default Auto Snooze` - Default _Auto Snooze_ value for newly created alarms (_Alarms_ only)
|
||||
- `Default Snooze` - Default _Snooze_ value for newly created alarms/timers
|
||||
- `Buzz Count` - The number of buzzes before the watch goes silent
|
||||
- `Buzz Interval` - The interval between one buzz and the next
|
||||
- `Default Alarm/Timer Pattern` - Default vibration pattern for newly created alarms/timers
|
||||
|
||||
Internals / Library
|
||||
-------------------
|
||||
|
|
@ -53,21 +62,27 @@ use too much RAM.
|
|||
It can be used as follows:
|
||||
|
||||
```
|
||||
// add/update an existing alarm
|
||||
// Get a new alarm with default values
|
||||
let alarm = require("sched").newDefaultAlarm();
|
||||
|
||||
// Get a new timer with default values
|
||||
let timer = require("sched").newDefaultTimer();
|
||||
|
||||
// Add/update an existing alarm
|
||||
require("sched").setAlarm("mytimer", {
|
||||
msg : "Wake up",
|
||||
timer : 10*60*1000, // 10 Minutes
|
||||
timer : 10 * 60 * 1000 // 10 minutes
|
||||
});
|
||||
// Ensure the widget and alarm timer updates to schedule the new alarm properly
|
||||
require("sched").reload();
|
||||
|
||||
// Get the time to the next alarm for us
|
||||
var timeToNext = require("sched").getTimeToAlarm(require("sched").getAlarm("mytimer"));
|
||||
// timeToNext===undefined if no alarm or alarm disabled
|
||||
let timeToNext = require("sched").getTimeToAlarm(require("sched").getAlarm("mytimer"));
|
||||
// timeToNext === undefined if no alarm or alarm disabled
|
||||
|
||||
// delete an alarm
|
||||
// Delete an alarm
|
||||
require("sched").setAlarm("mytimer", undefined);
|
||||
// reload after deleting...
|
||||
// Reload after deleting
|
||||
require("sched").reload();
|
||||
|
||||
// Or add an alarm that runs your own code - in this case
|
||||
|
|
@ -76,12 +91,15 @@ require("sched").reload();
|
|||
require("sched").setAlarm("customrunner", {
|
||||
appid : "myapp",
|
||||
js : "load('setting.app.js')",
|
||||
timer : 1*60*1000, // 1 Minute
|
||||
timer : 1 * 60 * 1000 // 1 minute
|
||||
});
|
||||
|
||||
// If you have been specifying `appid` you can also find any alarms that
|
||||
// your app has created with the following:
|
||||
require("sched").getAlarms().filter(a=>a.appid=="myapp");
|
||||
require("sched").getAlarms().filter(a => a.appid == "myapp");
|
||||
|
||||
// Get the scheduler settings
|
||||
let settings = require("sched").getSettings();
|
||||
```
|
||||
|
||||
If your app requires alarms, you can specify that the alarms app needs to
|
||||
|
|
|
|||
|
|
@ -52,3 +52,58 @@ exports.reload = function() {
|
|||
Bangle.drawWidgets();
|
||||
}
|
||||
};
|
||||
// Factory that creates a new alarm with default values
|
||||
exports.newDefaultAlarm = function () {
|
||||
const settings = exports.getSettings();
|
||||
|
||||
let alarm = {
|
||||
t: 12 * 3600000, // Default to 12:00
|
||||
on: true,
|
||||
rp: false, // repeat not the default
|
||||
as: settings.defaultAutoSnooze || false,
|
||||
dow: 0b1111111,
|
||||
last: 0,
|
||||
vibrate: settings.defaultAlarmPattern,
|
||||
};
|
||||
|
||||
delete settings;
|
||||
|
||||
return alarm;
|
||||
}
|
||||
// Factory that creates a new timer with default values
|
||||
exports.newDefaultTimer = function () {
|
||||
const settings = exports.getSettings();
|
||||
|
||||
let timer = {
|
||||
timer: 5 * 60 * 1000, // 5 minutes
|
||||
on: true,
|
||||
rp: false,
|
||||
as: false,
|
||||
dow: 0b1111111,
|
||||
last: 0,
|
||||
vibrate: settings.defaultTimerPattern
|
||||
}
|
||||
|
||||
delete settings;
|
||||
|
||||
return timer;
|
||||
};
|
||||
// Return the scheduler settings
|
||||
exports.getSettings = function () {
|
||||
return Object.assign(
|
||||
{
|
||||
unlockAtBuzz: false,
|
||||
defaultSnoozeMillis: 600000, // 10 minutes
|
||||
defaultAutoSnooze: false,
|
||||
buzzCount: 10,
|
||||
buzzIntervalMillis: 3000, // 3 seconds
|
||||
defaultAlarmPattern: "..",
|
||||
defaultTimerPattern: ".."
|
||||
},
|
||||
require("Storage").readJSON("sched.settings.json", true) || {}
|
||||
);
|
||||
}
|
||||
// Write the updated settings back to storage
|
||||
exports.setSettings = function(settings) {
|
||||
require("Storage").writeJSON("sched.settings.json", settings);
|
||||
};
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "sched",
|
||||
"name": "Scheduler",
|
||||
"version": "0.04",
|
||||
"version": "0.05",
|
||||
"description": "Scheduling library for alarms and timers",
|
||||
"icon": "app.png",
|
||||
"type": "scheduler",
|
||||
|
|
@ -12,7 +12,8 @@
|
|||
{"name":"sched.boot.js","url":"boot.js"},
|
||||
{"name":"sched.js","url":"sched.js"},
|
||||
{"name":"sched.img","url":"app-icon.js","evaluate":true},
|
||||
{"name":"sched","url":"lib.js"}
|
||||
{"name":"sched","url":"lib.js"},
|
||||
{"name":"sched.settings.js","url":"settings.js"}
|
||||
],
|
||||
"data": [{"name":"sched.json"}]
|
||||
"data": [{"name":"sched.json"}, {"name":"sched.settings.json"}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ function formatTime(t) {
|
|||
}
|
||||
|
||||
function showAlarm(alarm) {
|
||||
var msg = "";
|
||||
const settings = require("sched").getSettings();
|
||||
|
||||
let msg = "";
|
||||
msg += alarm.timer ? formatTime(alarm.timer) : formatTime(alarm.t);
|
||||
if (alarm.msg) {
|
||||
msg += "\n"+alarm.msg;
|
||||
|
|
@ -28,9 +30,12 @@ function showAlarm(alarm) {
|
|||
else
|
||||
msg = atob("AC0swgF97///RcEpMlVVVVVVf9VVVVVVVVX/9VVf9VVf/1VVV///1Vf9VX///VVX///VWqqlV///1Vf//9aqqqqpf//9V///2qqqqqqn///V///6qqqqqqr///X//+qqoAAKqqv//3//6qoAAAAKqr//3//qqAAAAAAqq//3/+qoAADwAAKqv/3/+qgAADwAACqv/3/aqAAADwAAAqp/19qoAAADwAAAKqfV1qgAAADwAAACqXVWqgAAADwAAACqlVWqAAAADwAAAAqlVWqAAAADwAAAAqlVWqAAAADwAAAAqlVaoAAAADwAAAAKpVaoAAAADwAAAAKpVaoAAAADwAAAAKpVaoAAAAOsAAAAKpVaoAAAAOsAAAAKpVaoAAAAL/AAAAKpVaoAAAAgPwAAAKpVaoAAACAD8AAAKpVWqAAAIAA/AAAqlVWqAAAgAAPwAAqlVWqAACAAADwAAqlVWqgAIAAAAAACqlVVqgAgAAAAAACqVVVqoAAAAAAAAKqVVVaqAAAAAAAAqpVVVWqgAAAAAACqlVVVWqoAAAAAAKqlVVVVqqAAAAAAqqVVVVVaqoAAAAKqpVVVVVeqqoAAKqqtVVVVV/6qqqqqqr/VVVVX/2qqqqqqn/1VVVf/VaqqqqpV/9VVVf9VVWqqlVVf9VVVf1VVVVVVVVX9VQ==")+" "+msg;
|
||||
}
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
var buzzCount = 10;
|
||||
|
||||
let buzzCount = settings.buzzCount;
|
||||
|
||||
E.showPrompt(msg,{
|
||||
title:alarm.timer ? /*LANG*/"TIMER!" : /*LANG*/"ALARM!",
|
||||
buttons : {/*LANG*/"Snooze":true,/*LANG*/"Ok":false} // default is sleep so it'll come back in 10 mins
|
||||
|
|
@ -38,7 +43,7 @@ function showAlarm(alarm) {
|
|||
buzzCount = 0;
|
||||
if (sleep) {
|
||||
if(alarm.ot===undefined) alarm.ot = alarm.t;
|
||||
alarm.t += 10*60*1000; // 10 minutes
|
||||
alarm.t += settings.defaultSnoozeMillis;
|
||||
} else {
|
||||
if (!alarm.timer) alarm.last = (new Date()).getDate();
|
||||
if (alarm.ot!==undefined) {
|
||||
|
|
@ -51,24 +56,35 @@ function showAlarm(alarm) {
|
|||
require("sched").setAlarms(alarms);
|
||||
load();
|
||||
});
|
||||
|
||||
function buzz() {
|
||||
require("buzz").pattern(alarm.vibrate===undefined?"..":alarm.vibrate).then(function() {
|
||||
if (buzzCount--)
|
||||
setTimeout(buzz, 3000);
|
||||
else if(alarm.as) { // auto-snooze
|
||||
buzzCount = 10;
|
||||
setTimeout(buzz, 600000);
|
||||
if (settings.unlockAtBuzz) {
|
||||
Bangle.setLocked(false);
|
||||
}
|
||||
|
||||
require("buzz").pattern(alarm.vibrate === undefined ? ".." : alarm.vibrate).then(() => {
|
||||
if (buzzCount--) {
|
||||
setTimeout(buzz, settings.buzzIntervalMillis);
|
||||
} else if (alarm.as) { // auto-snooze
|
||||
buzzCount = settings.buzzCount;
|
||||
setTimeout(buzz, settings.defaultSnoozeMillis);
|
||||
}
|
||||
});
|
||||
}
|
||||
if ((require('Storage').readJSON('setting.json',1)||{}).quiet>1) return;
|
||||
|
||||
if ((require("Storage").readJSON("setting.json", 1) || {}).quiet > 1)
|
||||
return;
|
||||
|
||||
buzz();
|
||||
}
|
||||
|
||||
// Check for alarms
|
||||
var alarms = require("sched").getAlarms();
|
||||
var active = require("sched").getActiveAlarms(alarms);
|
||||
if (active.length) // if there's an alarm, show it
|
||||
let alarms = require("sched").getAlarms();
|
||||
let active = require("sched").getActiveAlarms(alarms);
|
||||
if (active.length) {
|
||||
// if there's an alarm, show it
|
||||
showAlarm(active[0]);
|
||||
else // otherwise just go back to default app
|
||||
} else {
|
||||
// otherwise just go back to default app
|
||||
setTimeout(load, 100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
(function (back) {
|
||||
let settings = require("sched").getSettings();
|
||||
|
||||
E.showMenu({
|
||||
"": { "title": /*LANG*/"Scheduler" },
|
||||
|
||||
/*LANG*/"< 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);
|
||||
}
|
||||
},
|
||||
|
||||
/*LANG*/"Default Auto Snooze": {
|
||||
value: settings.defaultAutoSnooze,
|
||||
format: v => v ? /*LANG*/"Yes" : /*LANG*/"No",
|
||||
onchange: v => {
|
||||
settings.defaultAutoSnooze = v;
|
||||
require("sched").setSettings(settings);
|
||||
}
|
||||
},
|
||||
|
||||
/*LANG*/"Default Snooze": {
|
||||
value: settings.defaultSnoozeMillis / 60000,
|
||||
min: 5,
|
||||
max: 30,
|
||||
step: 5,
|
||||
format: v => v + /*LANG*/" min",
|
||||
onchange: v => {
|
||||
settings.defaultSnoozeMillis = v * 60000;
|
||||
require("sched").setSettings(settings);
|
||||
}
|
||||
},
|
||||
|
||||
/*LANG*/"Buzz Count": {
|
||||
value: settings.buzzCount,
|
||||
min: 5,
|
||||
max: 15,
|
||||
step: 1,
|
||||
onchange: v => {
|
||||
settings.buzzCount = v;
|
||||
require("sched").setSettings(settings);
|
||||
}
|
||||
},
|
||||
|
||||
/*LANG*/"Buzz Interval": {
|
||||
value: settings.buzzIntervalMillis / 1000,
|
||||
min: 1,
|
||||
max: 5,
|
||||
step: 1,
|
||||
format: v => v + /*LANG*/"s",
|
||||
onchange: v => {
|
||||
settings.buzzIntervalMillis = v * 1000;
|
||||
require("sched").setSettings(settings);
|
||||
}
|
||||
},
|
||||
|
||||
/*LANG*/"Default Alarm Pattern": require("buzz_menu").pattern(settings.defaultAlarmPattern, v => {
|
||||
settings.defaultAlarmPattern = v;
|
||||
require("sched").setSettings(settings);
|
||||
}),
|
||||
|
||||
/*LANG*/"Default Timer Pattern": require("buzz_menu").pattern(settings.defaultTimerPattern, v => {
|
||||
settings.defaultTimerPattern = v;
|
||||
require("sched").setSettings(settings);
|
||||
})
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue