diff --git a/apps.json b/apps.json index 48053e64b..bfea97d09 100644 --- a/apps.json +++ b/apps.json @@ -2,7 +2,7 @@ { "id": "boot", "name": "Bootloader", "icon": "bootloader.png", - "version":"0.03", + "version":"0.04", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "tags": "tool,system", "storage": [ @@ -13,7 +13,7 @@ "sortorder" : -10 }, { "id": "launch", - "name": "Launcher", + "name": "Default Launcher", "icon": "app.png", "version":"0.01", "description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", @@ -66,6 +66,20 @@ ], "sortorder" : -2 }, + { "id": "alarm", + "name": "Default Alarm", + "icon": "app.png", + "version":"0.01", + "description": "Set and respond to alarms", + "tags": "tool,alarm", + "storage": [ + {"name":"+alarm","url":"app.json"}, + {"name":"-alarm","url":"app.js"}, + {"name":"@alarm","content":"[]"}, + {"name":"*alarm","url":"app-icon.js","evaluate":true}, + {"name":"=alarm","url":"widget.js"} + ] + }, { "id": "wclock", "name": "Word Clock", "icon": "clock-word.png", diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/alarm/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/alarm/app-icon.js b/apps/alarm/app-icon.js new file mode 100644 index 000000000..05515e859 --- /dev/null +++ b/apps/alarm/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkGswAhiMRCCAREAo4eHBIQLEAgwYHsIJDiwHB5gACBpIhHCoYZEGA4gFCw4ABGA4HEjgXJ4IXGAwcUB4VEmf//8zogICoJIFAodMBoNDCoIADmgJB4gXIFwXDCwoABngwFC4guB4k/CQXwh4EC+YMCC44iBp4qDC4n/+gNBC41sEIJCEC4v/GAPGC4dhXYRdFC4xhCCYIXCdQRdDC5HzegQXCsxGHC45IDCwQXCUgwXHJAIXGRogXJSIIXcOw4XIPAYXcBwv/mEDBAwXOgtQC65QGC5vzoEAJAx3Nmk/mEABIiPN+dDAQIwFC4zXGFwKRCGAjvMFwQECGAgXI4YuGGAUvAgU8C4/EFwwGCAgdMC4p4EFwobFOwoXDJAIoEAApGBC4xIEABJGHGAapEAAqNBFwwXD4heI+YuBC5BIBVQhdHIw4wD5inFS4IKCCxFmigNCokzCoMzogICoIWIsMRjgPCAA3BiMWC48RBQIXJEgMRFxAJCCw4lEC44IECooOIBAaBJKwhgIAH4ACA==")) diff --git a/apps/alarm/app.js b/apps/alarm/app.js new file mode 100644 index 000000000..153a6ef3b --- /dev/null +++ b/apps/alarm/app.js @@ -0,0 +1,151 @@ +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +var alarms = require("Storage").readJSON("@alarm")||[]; +/*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 + } +];*/ + +function formatTime(t) { + var hrs = 0|t; + var mins = 0|((t-hrs)*60); + return hrs+":"+("0"+mins).substr(-2); +} + +function getCurrentHr() { + var time = new Date(); + return time.getHours()+(time.getMinutes()/60); +} + +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; + if (!newAlarm) { + var a = alarms[alarmIndex]; + hrs = 0|a.hr; + mins = 0|((a.hr-hrs)*60); + en = a.on; + repeat = a.rp; + } + const menu = { + '': { 'title': 'Alarms' }, + 'Hours': { + value: hrs, + min: 0, + max: 23, + onchange: v=>hrs=v + }, + 'Minutes': { + value: mins, + min: 0, + max: 60, + onchange: v=>mins=v + }, + 'Enabled': { + value: en, + format: v=>v?"On":"Off", + onchange: v=>en=v + }, + 'Repeat': { + value: en, + format: v=>v?"Yes":"No", + onchange: v=>repeat=v + } + }; + function getAlarm() { + var hr = hrs+(mins/60); + var day = 0; + // If alarm is for tomorrow not today, set day + if (hr > getCurrentHr()) + day = (new Date()).getDate(); + // Save alarm + return { + on : en, hr : hr, + last : day, rp : repeat + }; + } + if (newAlarm) { + menu["> New Alarm"] = function() { + alarms.push(getAlarm()); + require("Storage").write("@alarm",JSON.stringify(alarms)); + showMainMenu(); + }; + } else { + menu["> Save"] = function() { + alarms[alarmIndex] = getAlarm(); + require("Storage").write("@alarm",JSON.stringify(alarms)); + showMainMenu(); + }; + } + menu['< Back'] = showMainMenu; + return E.showMenu(menu); +} + +function showAlarm(alarm) { + var msg = formatTime(alarm.hr); + var buzzCount = 10; + if (alarm.msg) + msg += "\n"+alarm.msg; + E.showPrompt(msg,{ + title:"ALARM!", + buttons : {"Sleep":true,"Ok":false} // default is sleep so it'll come back in 10 mins + }).then(function(sleep) { + buzzCount = 0; + if (sleep) { + alarm.hr += 10/60; // 10 minutes + } else { + alarm.last = (new Date()).getDate(); + if (!alarm.rp) alarm.on = false; + } + require("Storage").write("@alarm",JSON.stringify(alarms)); + load(); + }); + function buzz() { + Bangle.buzz(100).then(()=>{ + setTimeout(()=>{ + Bangle.buzz(100).then(function() { + if (buzzCount--) + setTimeout(buzz, 3000); + }); + },100); + }); + } + buzz(); +} + +// Check for alarms +var day = (new Date()).getDate(); +var hr = getCurrentHr(); +var active = alarms.filter(a=>a.on&&(a.hr