Added library to qalarm and created a simple timer app which is an alternative UI.
|
@ -14,4 +14,3 @@
|
|||
0.13: Alarm widget state now updates when setting/resetting an alarm
|
||||
0.14: Order of 'back' menu item
|
||||
0.15: Fix hour/minute wrapping code for new menu system
|
||||
0.16: Expose functions for other apps
|
|
@ -1,3 +0,0 @@
|
|||
exports.createTimer = function() {
|
||||
return 0;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"id": "alarm",
|
||||
"name": "Default Alarm & Timer",
|
||||
"shortName": "Alarms",
|
||||
"version": "0.16",
|
||||
"version": "0.15",
|
||||
"description": "Set and respond to alarms and timers",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,alarm,widget",
|
||||
|
@ -12,8 +12,7 @@
|
|||
{"name":"alarm.boot.js","url":"boot.js"},
|
||||
{"name":"alarm.js","url":"alarm.js"},
|
||||
{"name":"alarm.img","url":"app-icon.js","evaluate":true},
|
||||
{"name":"alarm.wid.js","url":"widget.js"},
|
||||
{"name":"alarm","url":"lib.js"}
|
||||
{"name":"alarm.wid.js","url":"widget.js"}
|
||||
],
|
||||
"data": [{"name":"alarm.json"}]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
WIDGETS["alarm"]={area:"tl",width:0,draw:function() {
|
||||
if (this.width) g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
|
||||
},reload:function() {
|
||||
WIDGETS["alarm"].width = (require('Storage').readJSON('alarm.json',1)||[]).some(alarm=>alarm.on) ? 24 : 0;
|
||||
}
|
||||
if (this.width) g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
|
||||
},reload:function() {
|
||||
WIDGETS["alarm"].width = (require('Storage').readJSON('alarm.json',1)||[]).some(alarm=>alarm.on) ? 24 : 0;
|
||||
}
|
||||
};
|
||||
WIDGETS["alarm"].reload();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
Fix app icon
|
||||
Change menu order so 'back' is at the top
|
||||
0.04: Fix alarm not activating sometimes.
|
||||
0.05: Include library for other apps.
|
||||
0.05: Include library that can be used by other apps.
|
|
@ -5,8 +5,19 @@ let alarms = require("Storage").readJSON("qalarm.json", 1) || [];
|
|||
/**
|
||||
* LIBRARY
|
||||
*/
|
||||
|
||||
function getCurrentTime() {
|
||||
let time = new Date();
|
||||
return (
|
||||
time.getHours() * 3600000 +
|
||||
time.getMinutes() * 60000 +
|
||||
time.getSeconds() * 1000
|
||||
);
|
||||
}
|
||||
|
||||
function alarmExists(alarmIndex){
|
||||
return alarmIndex > 0 && alarmIndex < alarms.length;
|
||||
var exists = alarmIndex >= 0 && alarmIndex < alarms.length;
|
||||
return exists;
|
||||
}
|
||||
|
||||
function isAlarmStarted(alarmIndex){
|
||||
|
@ -18,20 +29,23 @@ function isAlarmStarted(alarmIndex){
|
|||
let t = getCurrentTime();
|
||||
a = alarms[alarmIndex];
|
||||
return a.on &&
|
||||
a.t <= t &&
|
||||
t <= a.t &&
|
||||
a.last != time.getDate() &&
|
||||
(a.timer || a.daysOfWeek[time.getDay()]);
|
||||
}
|
||||
|
||||
function getAlarmMin(alarmIndex){
|
||||
function getTimerMin(alarmIndex){
|
||||
if(!isAlarmStarted(alarmIndex)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
let t = getCurrentTime();
|
||||
let a = alarms[alarmIndex] ;
|
||||
return a.t - t * 60;
|
||||
}
|
||||
let diff = a.t - getCurrentTime();
|
||||
// let hrs = Math.floor(t / 3600000);
|
||||
let mins = Math.round((diff / 60000) % 60);
|
||||
// return hrs + ":" + ("0" + mins).substr(-2);
|
||||
return mins;
|
||||
}
|
||||
|
||||
function _reload(){
|
||||
require("Storage").write("qalarm.json", JSON.stringify(alarms));
|
||||
|
@ -41,34 +55,31 @@ function _reload(){
|
|||
|
||||
function editTimer(alarmIndex, hrs, mins, secs){
|
||||
var a = {
|
||||
timer: 300,
|
||||
on: true,
|
||||
rp: false,
|
||||
as: false,
|
||||
hard: false,
|
||||
};
|
||||
a.timer = hrs * 3600 + mins * 60 + secs;
|
||||
a.t = (getCurrentTime() + alarm.timer * 1000) % 86400000;
|
||||
a.t = (getCurrentTime() + a.timer * 1000) % 86400000;
|
||||
|
||||
if(alarmExists(a)){
|
||||
alarms[alarmIndex] = a;
|
||||
} else {
|
||||
alarmIndex = alarms.length;
|
||||
alarms.push(a)
|
||||
alarmIndex = alarms.length-1;
|
||||
}
|
||||
|
||||
_reload();
|
||||
return alarmIndex;
|
||||
}
|
||||
|
||||
|
||||
function deleteAlarm(alarmIndex){
|
||||
if(!alarmExists(alarmIndex)){
|
||||
return;
|
||||
}
|
||||
|
||||
alarms.splice(alarmIndex, 1);
|
||||
|
||||
_reload();
|
||||
}
|
||||
|
||||
|
@ -76,6 +87,10 @@ function deleteAlarm(alarmIndex){
|
|||
// Export functions
|
||||
exports.alarmExists = alarmExists;
|
||||
exports.isAlarmStarted = isAlarmStarted;
|
||||
exports.getAlarmMin = getAlarmMin;
|
||||
exports.editTimer = editTimer;
|
||||
exports.deleteAlarm = deleteAlarm;
|
||||
|
||||
exports.timerExists = alarmExists;
|
||||
exports.isTimerStarted = isAlarmStarted;
|
||||
exports.getTimerMin = getTimerMin;
|
||||
exports.editTimer = editTimer;
|
||||
exports.deleteTimer = deleteAlarm;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# Simple Timer
|
||||
|
||||
A simple app to set a timer quickly. Simply tab on top/bottom/left/right
|
||||
to select the minutes and tab in the middle of the screen to start/stop
|
||||
the timer. Note that this timer depends on qalarm.
|
||||
|
||||
# Overview
|
||||
If you open the app, you can simply control the timer
|
||||
by clicking on top, bottom, left or right of the screen.
|
||||
If you tab at the middle of the screen, the timer is
|
||||
started / stopped.
|
||||
|
||||

|
||||
|
||||
|
||||
# Creator
|
||||
[David Peer](https://github.com/peerdavid)
|
||||
|
||||
|
||||
# Thanks to...
|
||||
Time icon created by <a href="https://www.flaticon.com/free-icons/time" title="time icons">CreativeCons - Flaticon</a>
|
|
@ -15,32 +15,26 @@ Bangle.loadWidgets();
|
|||
|
||||
|
||||
const storage = require('Storage');
|
||||
const alarm = require('qalarm');
|
||||
|
||||
let settings;
|
||||
|
||||
const screenWidth = g.getWidth();
|
||||
const screenHeight = g.getHeight();
|
||||
const cx = parseInt(screenWidth/2);
|
||||
const cy = parseInt(screenHeight/2)-12;
|
||||
var minutes = 5;
|
||||
var interval; //used for the 1 second interval timer
|
||||
|
||||
|
||||
function updateSettings() {
|
||||
var now = new Date();
|
||||
const goal = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
|
||||
now.getHours(), now.getMinutes() + settings.minutes, now.getSeconds());
|
||||
settings.goal = goal.getTime();
|
||||
storage.writeJSON('widtmr.json', settings);
|
||||
if (WIDGETS["widtmr"]) WIDGETS["widtmr"].reload();
|
||||
}
|
||||
|
||||
|
||||
function resetSettings() {
|
||||
settings = {
|
||||
hours : 0,
|
||||
minutes : 0,
|
||||
seconds : 0,
|
||||
started : false,
|
||||
counter : 0,
|
||||
goal : 0,
|
||||
alarmIndex: -1
|
||||
};
|
||||
updateSettings();
|
||||
}
|
||||
|
@ -55,15 +49,25 @@ function draw(){
|
|||
g.clear(1);
|
||||
Bangle.drawWidgets();
|
||||
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
interval = undefined;
|
||||
|
||||
// Write time
|
||||
g.setFontAlign(0, 0, 0);
|
||||
g.setFont("Vector", 32).setFontAlign(0,-1);
|
||||
var started = alarm.isTimerStarted(settings.alarmIndex);
|
||||
var text = minutes + " min.";
|
||||
if(started){
|
||||
var min = alarm.getTimerMin(settings.alarmIndex);
|
||||
text = min + " min.";
|
||||
}
|
||||
|
||||
print(require("alarm").createTimer());
|
||||
|
||||
var text = settings.minutes + " min.";
|
||||
var rectWidth = parseInt(g.stringWidth(text) / 2);
|
||||
|
||||
if(settings.started){
|
||||
if(started){
|
||||
interval = setInterval(draw, 1000);
|
||||
g.setColor("#ff0000");
|
||||
} else {
|
||||
g.setColor(g.theme.fg);
|
||||
|
@ -74,6 +78,7 @@ function draw(){
|
|||
g.drawString(text, cx, cy);
|
||||
}
|
||||
|
||||
|
||||
Bangle.on('touch', function(btn, e){
|
||||
var left = parseInt(g.getWidth() * 0.25);
|
||||
var right = g.getWidth() - left;
|
||||
|
@ -84,27 +89,34 @@ Bangle.on('touch', function(btn, e){
|
|||
var isRight = e.x > right;
|
||||
var isUpper = e.y < upper;
|
||||
var isLower = e.y > lower;
|
||||
var isMiddle = !isLeft && !isRight && !isUpper && !isLower;
|
||||
print(settings.alarmIndex);
|
||||
var started = alarm.isTimerStarted(settings.alarmIndex);
|
||||
|
||||
if(isRight){
|
||||
settings.minutes += 1;
|
||||
if(isRight && !started){
|
||||
minutes += 1;
|
||||
Bangle.buzz(40, 0.3);
|
||||
} else if(isLeft){
|
||||
settings.minutes -= 1;
|
||||
} else if(isLeft && !started){
|
||||
minutes -= 1;
|
||||
Bangle.buzz(40, 0.3);
|
||||
} else if(isUpper){
|
||||
settings.minutes += 5;
|
||||
} else if(isUpper && !started){
|
||||
minutes += 5;
|
||||
Bangle.buzz(40, 0.3);
|
||||
} else if(isLower){
|
||||
settings.minutes -= 5;
|
||||
} else if(isLower && !started){
|
||||
minutes -= 5;
|
||||
Bangle.buzz(40, 0.3);
|
||||
} else {
|
||||
settings.started = !settings.started;
|
||||
Bangle.buzz(120, 0.6);
|
||||
}
|
||||
|
||||
if(settings.minutes <= 0){
|
||||
settings.minutes = 0;
|
||||
settings.started = false;
|
||||
} else if(isMiddle) {
|
||||
if(!started){
|
||||
settings.alarmIndex = alarm.editTimer(settings.alarmIndex, 0, minutes, 0);
|
||||
print("-----")
|
||||
print(settings.alarmIndex);
|
||||
print(alarm.timerExists(settings.alarmIndex))
|
||||
print(alarm.isTimerStarted(settings.alarmIndex))
|
||||
print("-----")
|
||||
} else {
|
||||
alarm.deleteTimer(settings.alarmIndex);
|
||||
}
|
||||
Bangle.buzz(80, 0.6);
|
||||
}
|
||||
|
||||
updateSettings();
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"id": "smpltmr",
|
||||
"name": "Simple Timer",
|
||||
"shortName": "Simple Timer",
|
||||
"version": "0.01",
|
||||
"description": "A simple app to set a timer.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool",
|
||||
"dependencies": {"qalarm":"app"},
|
||||
"supports": ["BANGLEJS2"],
|
||||
"screenshots": [{"url":"screenshot.png"}, {"url": "screenshot_2.png"}],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"smpltmr.app.js","url":"app.js"},
|
||||
{"name":"smpltmr.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
@ -1,67 +0,0 @@
|
|||
# Timer Widget
|
||||
|
||||
This is a fork of the Chrono Widget, but implements a
|
||||
simpler UI. Additionally, it exposes functions for other
|
||||
apps or clocks such that they can easily implement a timer.
|
||||
Currently, it is used by lcars and notanalog.
|
||||
|
||||
# Overview
|
||||
If you open the app, you can simply control the timer
|
||||
by clicking on top, bottom, left or right of the screen.
|
||||
If you tab at the middle of the screen, the timer is
|
||||
started / stopped.
|
||||
|
||||

|
||||
|
||||
|
||||
# Lib
|
||||
Different functions are exposed by widtmr which enables other
|
||||
apps to directly use and integrate this functionality:
|
||||
|
||||
The following functions are available:
|
||||
- isStarted() -> boolean
|
||||
- setStarted(boolean) -> void
|
||||
- setTimer(t) -> void
|
||||
- increaseTimer(int) -> void
|
||||
- decreaseTimer(int) -> void
|
||||
- getRemainingMinutes() -> int
|
||||
- getRemainingTime() -> DateTime
|
||||
- getRemainingTimeStr() -> str
|
||||
|
||||
For example if we want to increase the timer by +5 minutes each time
|
||||
the touch event is fired:
|
||||
```Javascript
|
||||
Bangle.loadWidgets();
|
||||
...
|
||||
Bangle.on('touch', function(btn, e){
|
||||
// Set to zero if alarm was disabled before. Otherwise
|
||||
// it starts from the last setting made by the user.
|
||||
if(!isAlarmEnabled()){
|
||||
WIDGETS["widtmr"].setTimer(0);
|
||||
}
|
||||
|
||||
WIDGETS["widtmr"].increaseTimer(5);
|
||||
WIDGETS["widtmr"].setStarted(true);
|
||||
});
|
||||
```
|
||||
|
||||
Example to decrease the timer by 5 and stop if 0 is reached:
|
||||
```Javascript
|
||||
Bangle.loadWidgets();
|
||||
...
|
||||
Bangle.on('touch', function(btn, e){
|
||||
WIDGETS["widtmr"].decreaseTimer(5);
|
||||
}
|
||||
```
|
||||
|
||||
You can find implementations and usages in the lcars or notanalog app.
|
||||
|
||||
|
||||
# Creator
|
||||
[David Peer](https://github.com/peerdavid)
|
||||
|
||||
|
||||
# Thanks to...
|
||||
Forked from Chrono Widget of [Purple-Tentacle](https://github.com/Purple-Tentacle)
|
||||
|
||||
Time icon created by <a href="https://www.flaticon.com/free-icons/time" title="time icons">CreativeCons - Flaticon</a>
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"id": "widtmr",
|
||||
"name": "Timer Widget",
|
||||
"shortName": "Timer Widget",
|
||||
"version": "0.01",
|
||||
"description": "Fork from Chrono Widget with a simpler UI and a lib for other apps.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,widget",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"screenshots": [{"url":"screenshot.png"}, {"url": "screenshot_2.png"}],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"widtmr.wid.js","url":"widget.js"},
|
||||
{"name":"widtmr.app.js","url":"app.js"},
|
||||
{"name":"widtmr.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
(() => {
|
||||
let storage = require('Storage');
|
||||
|
||||
var settings;
|
||||
var interval = 0; //used for the 1 second interval timer
|
||||
var diff;
|
||||
|
||||
|
||||
//Convert ms to time
|
||||
function getTime(t) {
|
||||
var milliseconds = parseInt((t % 1000) / 100),
|
||||
seconds = Math.floor((t / 1000) % 60),
|
||||
minutes = Math.floor((t / (1000 * 60)) % 60),
|
||||
hours = Math.floor((t / (1000 * 60 * 60)) % 24);
|
||||
return hours.toString().padStart(2,0) + ":" + minutes.toString().padStart(2,0) + ":" + seconds.toString().padStart(2,0);
|
||||
}
|
||||
|
||||
|
||||
//counts down, calculates and displays
|
||||
function countDown() {
|
||||
var now = new Date();
|
||||
diff = settings.goal - now; //calculate difference
|
||||
// time is up
|
||||
if (settings.started && diff < 1000) {
|
||||
Bangle.buzz(1500);
|
||||
//write timer off to file
|
||||
settings.started = false;
|
||||
storage.writeJSON('widtmr.json', settings);
|
||||
clearInterval(interval); //stop interval
|
||||
interval = undefined;
|
||||
}
|
||||
// calculates width and redraws accordingly
|
||||
WIDGETS["widtmr"].redraw();
|
||||
}
|
||||
|
||||
|
||||
function updateSettings(){
|
||||
var now = new Date();
|
||||
const goal = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
|
||||
now.getHours(), now.getMinutes() + settings.minutes, now.getSeconds());
|
||||
settings.goal = goal.getTime();
|
||||
|
||||
settings.goal = goal.getTime();
|
||||
storage.writeJSON('widtmr.json', settings);
|
||||
WIDGETS["widtmr"].reload();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add the widgets and functions for other apps
|
||||
*/
|
||||
WIDGETS["widtmr"]={area:"tl",width:0,draw:function() {
|
||||
if (!this.width) {
|
||||
return;
|
||||
}
|
||||
|
||||
g.reset().setFontAlign(0,0).clearRect(this.x,this.y,this.x+this.width,this.y+23);
|
||||
|
||||
var scale;
|
||||
var timeStr;
|
||||
if (diff < 3600000) { //less than 1 hour left
|
||||
width = 58;
|
||||
scale = 2;
|
||||
timeStr = getTime(diff).substring(3); // remove hour part 00:00:00 -> 00:00
|
||||
} else { //one hour or more left
|
||||
width = 48;
|
||||
scale = 1;
|
||||
timeStr = getTime(diff); //display hour 00:00:00 but small
|
||||
}
|
||||
|
||||
// Font5x9Numeric7Seg - just build this in as it's tiny
|
||||
g.setFontCustom(atob("AAAAAAAAAAIAAAQCAQAAAd0BgMBdwAAAAAAAdwAB0RiMRcAAAERiMRdwAcAQCAQdwAcERiMRBwAd0RiMRBwAAEAgEAdwAd0RiMRdwAcERiMRdwAFAAd0QiEQdwAdwRCIRBwAd0BgMBAAABwRCIRdwAd0RiMRAAAd0QiEQAAAAAAAAAA="), 32, atob("BgAAAAAAAAAAAAAAAAYCAAYGBgYGBgYGBgYCAAAAAAAABgYGBgYG"), 9 + (scale<<8));
|
||||
g.drawString(timeStr, this.x+this.width/2, this.y+12);
|
||||
|
||||
}, redraw:function() {
|
||||
var last = this.width;
|
||||
if (!settings.started) {
|
||||
this.width = 0;
|
||||
} else {
|
||||
this.width = (diff < 3600000) ? 58 : 48;
|
||||
}
|
||||
|
||||
if (last != this.width) {
|
||||
Bangle.drawWidgets();
|
||||
} else {
|
||||
this.draw();
|
||||
}
|
||||
|
||||
}, reload:function() {
|
||||
settings = storage.readJSON("widtmr.json",1)||{};
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
interval = undefined;
|
||||
|
||||
// start countdown each second
|
||||
if (settings.started) {
|
||||
interval = setInterval(countDown, 1000);
|
||||
}
|
||||
|
||||
// reset everything
|
||||
countDown();
|
||||
|
||||
}, isStarted: function(){
|
||||
settings = storage.readJSON("widtmr.json",1)||{started: false};
|
||||
return settings.started;
|
||||
|
||||
}, setStarted: function(started){
|
||||
settings.started=started;
|
||||
updateSettings();
|
||||
|
||||
}, increaseTimer: function(m){
|
||||
settings.minutes += m;
|
||||
updateSettings();
|
||||
|
||||
}, decreaseTimer: function(m){
|
||||
settings.minutes -= m;
|
||||
if(settings.minutes <= 0){
|
||||
settings.started=false;
|
||||
settings.minutes=0;
|
||||
}
|
||||
updateSettings();
|
||||
|
||||
}, setTimer: function(t){
|
||||
settings.minutes = Math.max(0, t);
|
||||
settings.started = t > 0;
|
||||
updateSettings();
|
||||
|
||||
}, getRemainingMinutes: function(){
|
||||
settings = storage.readJSON("widtmr.json",1)||{started: false};
|
||||
if(!settings.started){
|
||||
return -1;
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
var diff = settings.goal - now;
|
||||
return Math.round(diff / (1000*60));
|
||||
|
||||
}, getRemainingTimeStr: function(){
|
||||
settings = storage.readJSON("widtmr.json",1)||{started: false};
|
||||
if(!settings.started){
|
||||
return;
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
var diff = settings.goal - now;
|
||||
var timeStr = getTime(diff);
|
||||
if(diff < 3600000){
|
||||
timeStr = timeStr.substring(3); // remove hour part 00:00:00 -> 00:00
|
||||
}
|
||||
return timeStr;
|
||||
|
||||
}, getRemainingTime: function(){
|
||||
settings = storage.readJSON("widtmr.json",1)||{started: false};
|
||||
if(!settings.started){
|
||||
return;
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
var diff = settings.goal - now;
|
||||
return diff;
|
||||
}
|
||||
};
|
||||
|
||||
// set width correctly, start countdown each second
|
||||
WIDGETS["widtmr"].reload();
|
||||
})();
|