Merge pull request #1661 from peerdavid/master
New and updated apps using the new "sched" librarymaster
|
|
@ -0,0 +1,2 @@
|
||||||
|
0.01: New App!
|
||||||
|
0.02: Fullscreen settings.
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# 90s Clock
|
||||||
|
|
||||||
|
A watch face in 90s style:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Fullscreen mode can be enabled in the settings:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Creator
|
||||||
|
- [David Peer](https://github.com/peerdavid)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwgc8+fAgEgwAMDvPnz99BYdl2weHtu27ft2AGBiEcuEAhAPDg4jGgECIRMN23fthUNgP374vBAB3gAgc/gAXNjlx4EDxwJEpAjG/6IBjkBL4UAjVgBAJuCgPHBQMFEIkkyQjFhwEClgXBEYNBwkQJoibCBwNFBAUCEAVAQZAjC/8euPHDon//hKB//xEYMP//jBYP/+ARDNYM///+EYIgBj1B/8fCIUhEYQRB//FUIM/EZU4EYMkEYP/8VhEYUH/gRBWAUfI4MD+AjBoAsBwEH8EB/EDwE4HwYjCuEHWAOHgExEYKbBCIZNB8fAEYQHByE/EwPABAY+BgRHDBANyJQXHNwIjD8CSBj/+BwMSTwOOBYK2D/4CCNYZQB/iJBQwYjCCIcAgeBSoOAWYQjEVoIRCNAIjKAQKJBgAFC8ZoCWwJbDABMHGQPAAoMQB5EDx/4A4gqBZwIGCWwIABuBWC4EBZwPgv/AcwS/EAAcIU4IRBVQIRKEwIjBv0ARIUDCJIjD//x/ARK/5HC/+BCJkcI45uDgECUgQjCWAM4WwUBWYanEAA8cTARWBEYUC5RAHw1YgEOFQXADQPHIIkAhgICuARBh0A23blhHBagIKBsOGjNswhHDEYUUAoTUBhkxEYMwKwU503bvuwXILmCEYMYsumWYYjB85lDEYovBEYXm7fs25EBI4kYtOWNwIjD4+8NYsw4YjGz9/2hrEoOGjVBwE4NYdzNYSwBuEDEYcxaIUA8+atugGogjBiVgWAI"))
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"id": "90sclk",
|
||||||
|
"name": "90s Clock",
|
||||||
|
"version": "0.02",
|
||||||
|
"description": "A 90s style watch-face",
|
||||||
|
"readme": "README.md",
|
||||||
|
"icon": "app.png",
|
||||||
|
"screenshots": [{"url":"screenshot.png"},{"url":"screenshot_2.png"}],
|
||||||
|
"type": "clock",
|
||||||
|
"tags": "clock",
|
||||||
|
"supports": ["BANGLEJS2"],
|
||||||
|
"allow_emulator": true,
|
||||||
|
"storage": [
|
||||||
|
{"name":"90sclk.app.js","url":"app.js"},
|
||||||
|
{"name":"90sclk.img","url":"app-icon.js","evaluate":true},
|
||||||
|
{"name":"90sclk.settings.js","url":"settings.js"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
|
@ -0,0 +1,31 @@
|
||||||
|
(function(back) {
|
||||||
|
const SETTINGS_FILE = "90sclk.setting.json";
|
||||||
|
|
||||||
|
// initialize with default settings...
|
||||||
|
const storage = require('Storage')
|
||||||
|
let settings = {
|
||||||
|
fullscreen: false,
|
||||||
|
};
|
||||||
|
let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings;
|
||||||
|
for (const key in saved_settings) {
|
||||||
|
settings[key] = saved_settings[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
storage.write(SETTINGS_FILE, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
E.showMenu({
|
||||||
|
'': { 'title': '90s Clock' },
|
||||||
|
'< Back': back,
|
||||||
|
'Full Screen': {
|
||||||
|
value: settings.fullscreen,
|
||||||
|
format: () => (settings.fullscreen ? 'Yes' : 'No'),
|
||||||
|
onchange: () => {
|
||||||
|
settings.fullscreen = !settings.fullscreen;
|
||||||
|
save();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
0.01: New App.
|
||||||
|
0.02: Use build in function for steps and other improvements.
|
||||||
|
0.03: Adapt colors based on the theme of the user.
|
||||||
|
0.04: Steps can be hidden now such that the time is even larger.
|
||||||
|
0.05: Included icons for information.
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Black & White clock
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Fullscreen on/off
|
||||||
|
- The design is adapted to the theme of your bangle.
|
||||||
|
- Tab left/right of screen to show steps, temperature etc.
|
||||||
|
- Enable / disable lock icon in the settings.
|
||||||
|
- If the "sched" app is installed tab top / bottom of the screen to set the timer.
|
||||||
|
|
||||||
|
## Thanks to
|
||||||
|
<a href="https://www.flaticon.com/free-icons/" title="Icons">Icons created by Flaticon</a>
|
||||||
|
|
||||||
|
## Creator
|
||||||
|
- [David Peer](https://github.com/peerdavid)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwgIcah0EgEB/H8iFsAoOY4kMBYMDhmGgXkAoUGiWkAoQQBoAFCjgnCAoM4hgFDuEI+wpC8EKyg1C/0eAoMAsEAiQvBAAeAApQAB/4Ao+P4v/wn0P8Pgn/wnkH4Pjv/j/nn9PH//n/nj/IFF4F88AXBAoM88EcAoPHj//jlDAoOf/+Y+YFHjnnjAjBEIIjD+BHDO9IALA=="))
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"id": "bwclk",
|
||||||
|
"name": "BlackWhite Clock",
|
||||||
|
"version": "0.05",
|
||||||
|
"description": "Black and white clock.",
|
||||||
|
"readme": "README.md",
|
||||||
|
"icon": "app.png",
|
||||||
|
"screenshots": [{"url":"screenshot.png"}, {"url":"screenshot_2.png"}],
|
||||||
|
"type": "clock",
|
||||||
|
"tags": "clock",
|
||||||
|
"supports": ["BANGLEJS2"],
|
||||||
|
"allow_emulator": true,
|
||||||
|
"storage": [
|
||||||
|
{"name":"bwclk.app.js","url":"app.js"},
|
||||||
|
{"name":"bwclk.img","url":"app-icon.js","evaluate":true},
|
||||||
|
{"name":"bwclk.settings.js","url":"settings.js"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -0,0 +1,40 @@
|
||||||
|
(function(back) {
|
||||||
|
const SETTINGS_FILE = "bwclk.setting.json";
|
||||||
|
|
||||||
|
// initialize with default settings...
|
||||||
|
const storage = require('Storage')
|
||||||
|
let settings = {
|
||||||
|
fullscreen: false,
|
||||||
|
showLock: true,
|
||||||
|
};
|
||||||
|
let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings;
|
||||||
|
for (const key in saved_settings) {
|
||||||
|
settings[key] = saved_settings[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
storage.write(SETTINGS_FILE, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
E.showMenu({
|
||||||
|
'': { 'title': 'BlackWhite Clock' },
|
||||||
|
'< Back': back,
|
||||||
|
'Fullscreen': {
|
||||||
|
value: settings.fullscreen,
|
||||||
|
format: () => (settings.fullscreen ? 'Yes' : 'No'),
|
||||||
|
onchange: () => {
|
||||||
|
settings.fullscreen = !settings.fullscreen;
|
||||||
|
save();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'Show Lock': {
|
||||||
|
value: settings.showLock,
|
||||||
|
format: () => (settings.showLock ? 'Yes' : 'No'),
|
||||||
|
onchange: () => {
|
||||||
|
settings.showLock = !settings.showLock;
|
||||||
|
save();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
@ -17,3 +17,4 @@
|
||||||
0.17: Settings for mph/kph and other minor improvements.
|
0.17: Settings for mph/kph and other minor improvements.
|
||||||
0.18: Fullscreen mode can now be enabled or disabled in the settings.
|
0.18: Fullscreen mode can now be enabled or disabled in the settings.
|
||||||
0.19: Alarms can not go bigger than 100.
|
0.19: Alarms can not go bigger than 100.
|
||||||
|
0.20: Use alarm for alarm functionality instead of own implementation.
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
A simple LCARS inspired clock.
|
A simple LCARS inspired clock.
|
||||||
Note: To display the steps, the wpedom app is required. To show weather data
|
Note: To display the steps, the wpedom app is required. To show weather data
|
||||||
such as temperature, humidity or window you BangleJS must be connected
|
such as temperature, humidity or window you BangleJS must be connected
|
||||||
with Gadgetbride and the weather app must be installed.
|
with Gadgetbride and the weather app must be installed. To use the timer
|
||||||
|
the "sched" app must be installed on your device.
|
||||||
|
|
||||||
## Control
|
## Control
|
||||||
* Tap left / right to change between screens.
|
* Tap left / right to change between screens.
|
||||||
|
|
@ -15,7 +16,7 @@ with Gadgetbride and the weather app must be installed.
|
||||||
* Tab on left/right to switch between different screens.
|
* Tab on left/right to switch between different screens.
|
||||||
* Cusomizable data that is shown on screen 1 (steps, weather etc.)
|
* Cusomizable data that is shown on screen 1 (steps, weather etc.)
|
||||||
* Shows random and real images of planets.
|
* Shows random and real images of planets.
|
||||||
* Tap on top/bottom of screen 1 to activate an alarm.
|
* Tap on top/bottom of screen 1 to activate an alarm. Depends on widtmr.
|
||||||
* The lower orange line indicates the battery level.
|
* The lower orange line indicates the battery level.
|
||||||
* Display graphs (day or month) for steps + hrm on the second screen.
|
* Display graphs (day or month) for steps + hrm on the second screen.
|
||||||
|
|
||||||
|
|
@ -36,8 +37,9 @@ Access different screens via tap on the left/ right side of the screen
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
## Creator
|
||||||
|
- [David Peer](https://github.com/peerdavid)
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
- [David Peer](https://github.com/peerdavid).
|
- [Adam Schmalhofer](https://github.com/adamschmalhofer)
|
||||||
- [Adam Schmalhofer](https://github.com/adamschmalhofer).
|
- [Jon Warrington](https://github.com/BartokW)
|
||||||
- [Jon Warrington](https://github.com/BartokW).
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
const TIMER_IDX = "lcars";
|
||||||
const SETTINGS_FILE = "lcars.setting.json";
|
const SETTINGS_FILE = "lcars.setting.json";
|
||||||
const locale = require('locale');
|
const locale = require('locale');
|
||||||
const storage = require('Storage')
|
const storage = require('Storage');
|
||||||
let settings = {
|
let settings = {
|
||||||
alarm: -1,
|
alarm: -1,
|
||||||
dataRow1: "Steps",
|
dataRow1: "Steps",
|
||||||
|
|
@ -124,11 +125,16 @@ Graphics.prototype.setFontAntonioLarge = function(scale) {
|
||||||
*/
|
*/
|
||||||
var drawTimeout;
|
var drawTimeout;
|
||||||
function queueDraw() {
|
function queueDraw() {
|
||||||
|
|
||||||
|
// Faster updates during alarm to ensure that it is
|
||||||
|
// shown correctly...
|
||||||
|
var timeout = isAlarmEnabled() ? 10000 : 60000;
|
||||||
|
|
||||||
if (drawTimeout) clearTimeout(drawTimeout);
|
if (drawTimeout) clearTimeout(drawTimeout);
|
||||||
drawTimeout = setTimeout(function() {
|
drawTimeout = setTimeout(function() {
|
||||||
drawTimeout = undefined;
|
drawTimeout = undefined;
|
||||||
draw();
|
draw();
|
||||||
}, 60000 - (Date.now() % 60000));
|
}, timeout - (Date.now() % timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -238,6 +244,7 @@ function drawInfo(){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g.setFontAlign(-1, -1, 0);
|
||||||
g.setFontAntonioMedium();
|
g.setFontAntonioMedium();
|
||||||
g.setColor(cOrange);
|
g.setColor(cOrange);
|
||||||
g.clearRect(120, 10, g.getWidth(), 75);
|
g.clearRect(120, 10, g.getWidth(), 75);
|
||||||
|
|
@ -480,9 +487,6 @@ function draw(){
|
||||||
// Queue draw first to ensure that its called in one minute again.
|
// Queue draw first to ensure that its called in one minute again.
|
||||||
queueDraw();
|
queueDraw();
|
||||||
|
|
||||||
// First handle alarm to show this correctly afterwards
|
|
||||||
handleAlarm();
|
|
||||||
|
|
||||||
// Next draw the watch face
|
// Next draw the watch face
|
||||||
g.reset();
|
g.reset();
|
||||||
g.clearRect(0, 0, g.getWidth(), g.getHeight());
|
g.clearRect(0, 0, g.getWidth(), g.getHeight());
|
||||||
|
|
@ -561,43 +565,57 @@ function getWeather(){
|
||||||
/*
|
/*
|
||||||
* Handle alarm
|
* Handle alarm
|
||||||
*/
|
*/
|
||||||
function getCurrentTimeInMinutes(){
|
|
||||||
return Math.floor(Date.now() / (1000*60));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAlarmEnabled(){
|
function isAlarmEnabled(){
|
||||||
return settings.alarm >= 0;
|
try{
|
||||||
|
var alarm = require('sched');
|
||||||
|
var alarmObj = alarm.getAlarm(TIMER_IDX);
|
||||||
|
if(alarmObj===undefined || !alarmObj.on){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch(ex){ }
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAlarmMinutes(){
|
function getAlarmMinutes(){
|
||||||
var currentTime = getCurrentTimeInMinutes();
|
if(!isAlarmEnabled()){
|
||||||
return settings.alarm - currentTime;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var alarm = require('sched');
|
||||||
|
var alarmObj = alarm.getAlarm(TIMER_IDX);
|
||||||
|
return Math.round(alarm.getTimeToAlarm(alarmObj)/(60*1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAlarm(){
|
function increaseAlarm(){
|
||||||
if(!isAlarmEnabled()){
|
try{
|
||||||
return;
|
var minutes = isAlarmEnabled() ? getAlarmMinutes() : 0;
|
||||||
}
|
var alarm = require('sched')
|
||||||
|
alarm.setAlarm(TIMER_IDX, {
|
||||||
|
timer : (minutes+5)*60*1000,
|
||||||
|
});
|
||||||
|
alarm.reload();
|
||||||
|
} catch(ex){ }
|
||||||
|
}
|
||||||
|
|
||||||
if(getAlarmMinutes() > 0){
|
function decreaseAlarm(){
|
||||||
return;
|
try{
|
||||||
}
|
var minutes = getAlarmMinutes();
|
||||||
|
minutes -= 5;
|
||||||
|
|
||||||
// Alarm
|
var alarm = require('sched')
|
||||||
var t = 300;
|
alarm.setAlarm(TIMER_IDX, undefined);
|
||||||
Bangle.buzz(t, 1)
|
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, t)))
|
if(minutes > 0){
|
||||||
.then(() => Bangle.buzz(t, 1))
|
alarm.setAlarm(TIMER_IDX, {
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, t)))
|
timer : minutes*60*1000,
|
||||||
.then(() => Bangle.buzz(t, 1))
|
});
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, t)))
|
}
|
||||||
.then(() => Bangle.buzz(t, 1))
|
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, 5E3)))
|
alarm.reload();
|
||||||
.then(() => {
|
} catch(ex){ }
|
||||||
// Update alarm state to disabled
|
|
||||||
settings.alarm = -1;
|
|
||||||
storage.writeJSON(SETTINGS_FILE, settings);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -625,27 +643,6 @@ Bangle.on('charging',function(charging) {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function increaseAlarm(){
|
|
||||||
if(isAlarmEnabled() && getAlarmMinutes() < 95){
|
|
||||||
settings.alarm += 5;
|
|
||||||
} else {
|
|
||||||
settings.alarm = getCurrentTimeInMinutes() + 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.writeJSON(SETTINGS_FILE, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function decreaseAlarm(){
|
|
||||||
if(isAlarmEnabled() && (settings.alarm-5 > getCurrentTimeInMinutes())){
|
|
||||||
settings.alarm -= 5;
|
|
||||||
} else {
|
|
||||||
settings.alarm = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.writeJSON(SETTINGS_FILE, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
function feedback(){
|
function feedback(){
|
||||||
Bangle.buzz(40, 0.3);
|
Bangle.buzz(40, 0.3);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"name": "LCARS Clock",
|
"name": "LCARS Clock",
|
||||||
"shortName":"LCARS",
|
"shortName":"LCARS",
|
||||||
"icon": "lcars.png",
|
"icon": "lcars.png",
|
||||||
"version":"0.19",
|
"version":"0.20",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
"description": "Library Computer Access Retrieval System (LCARS) clock.",
|
"description": "Library Computer Access Retrieval System (LCARS) clock.",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
0.01: Launch app.
|
0.01: Launch app.
|
||||||
0.02: 12k steps are 360 degrees - improves readability of steps.
|
0.02: 12k steps are 360 degrees - improves readability of steps.
|
||||||
0.03: Battery improvements through sleep (no minute updates) and partial updates of drawing.
|
0.03: Battery improvements through sleep (no minute updates) and partial updates of drawing.
|
||||||
|
0.04: Use alarm for timer instead of own alarm implementation.
|
||||||
|
|
@ -8,8 +8,8 @@ black one the battery level (100% = 360 degrees).
|
||||||
The selected theme is also respected. Note that this watch face is in fullscreen
|
The selected theme is also respected. Note that this watch face is in fullscreen
|
||||||
mode, but widgets are still loaded in background.
|
mode, but widgets are still loaded in background.
|
||||||
|
|
||||||
## Other features
|
## Other Features
|
||||||
- Set a timer - simply touch top (+5min.) or bottom (-5 min.).
|
- Set a timer - simply touch top (+5min.) or bottom (-5 min.). This only works if "sched" is installed.
|
||||||
- If the weather is available through the weather app, the outside temp. will be shown.
|
- If the weather is available through the weather app, the outside temp. will be shown.
|
||||||
- Sleep modus at midnight to save more battery (no minute updates).
|
- Sleep modus at midnight to save more battery (no minute updates).
|
||||||
- Icons for charging and GPS.
|
- Icons for charging and GPS.
|
||||||
|
|
@ -29,5 +29,5 @@ which helped a lot for this development.
|
||||||
|
|
||||||
Icons from <a href="https://www.flaticon.com/free-icons" title="icons">by Freepik - Flaticon</a>
|
Icons from <a href="https://www.flaticon.com/free-icons" title="icons">by Freepik - Flaticon</a>
|
||||||
|
|
||||||
## Contributors
|
## Creator
|
||||||
- [David Peer](https://github.com/peerdavid).
|
- [David Peer](https://github.com/peerdavid).
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"name": "Not Analog",
|
"name": "Not Analog",
|
||||||
"shortName":"Not Analog",
|
"shortName":"Not Analog",
|
||||||
"icon": "notanalog.png",
|
"icon": "notanalog.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
"description": "An analog watch face for people that can not read analog watch faces.",
|
"description": "An analog watch face for people that can not read analog watch faces.",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* NOT ANALOG CLOCK
|
* NOT ANALOG CLOCK
|
||||||
*/
|
*/
|
||||||
|
const TIMER_IDX = "notanalog";
|
||||||
const locale = require('locale');
|
const locale = require('locale');
|
||||||
const storage = require('Storage')
|
const storage = require('Storage')
|
||||||
const SETTINGS_FILE = "notanalog.setting.json";
|
const SETTINGS_FILE = "notanalog.setting.json";
|
||||||
|
|
@ -291,7 +291,6 @@ function drawSleep(){
|
||||||
function draw(fastUpdate){
|
function draw(fastUpdate){
|
||||||
// Execute handlers
|
// Execute handlers
|
||||||
handleState(fastUpdate);
|
handleState(fastUpdate);
|
||||||
handleAlarm();
|
|
||||||
|
|
||||||
if(state.sleep){
|
if(state.sleep){
|
||||||
drawSleep();
|
drawSleep();
|
||||||
|
|
@ -377,82 +376,80 @@ Bangle.on('touch', function(btn, e){
|
||||||
* Some helpers
|
* Some helpers
|
||||||
*/
|
*/
|
||||||
function queueDraw() {
|
function queueDraw() {
|
||||||
|
|
||||||
|
// Faster updates during alarm to ensure that it is
|
||||||
|
// shown correctly...
|
||||||
|
var timeout = isAlarmEnabled() ? 10000 : 60000;
|
||||||
|
|
||||||
if (drawTimeout) clearTimeout(drawTimeout);
|
if (drawTimeout) clearTimeout(drawTimeout);
|
||||||
drawTimeout = setTimeout(function() {
|
drawTimeout = setTimeout(function() {
|
||||||
drawTimeout = undefined;
|
drawTimeout = undefined;
|
||||||
draw(true);
|
draw();
|
||||||
}, 60000 - (Date.now() % 60000));
|
}, timeout - (Date.now() % timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle alarm
|
* Handle alarm
|
||||||
*/
|
*/
|
||||||
function getCurrentTimeInMinutes(){
|
|
||||||
return Math.floor(Date.now() / (1000*60));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAlarmEnabled(){
|
function isAlarmEnabled(){
|
||||||
return settings.alarm >= 0;
|
try{
|
||||||
}
|
var alarm = require('sched');
|
||||||
|
var alarmObj = alarm.getAlarm(TIMER_IDX);
|
||||||
|
if(alarmObj===undefined || !alarmObj.on){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch(ex){ }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function getAlarmMinutes(){
|
function getAlarmMinutes(){
|
||||||
var currentTime = getCurrentTimeInMinutes();
|
|
||||||
return settings.alarm - currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleAlarm(){
|
|
||||||
if(!isAlarmEnabled()){
|
if(!isAlarmEnabled()){
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(getAlarmMinutes() > 0){
|
var alarm = require('sched');
|
||||||
return;
|
var alarmObj = alarm.getAlarm(TIMER_IDX);
|
||||||
}
|
return Math.round(alarm.getTimeToAlarm(alarmObj)/(60*1000));
|
||||||
|
|
||||||
// Alarm
|
|
||||||
var t = 300;
|
|
||||||
Bangle.buzz(t, 1)
|
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, t)))
|
|
||||||
.then(() => Bangle.buzz(t, 1))
|
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, t)))
|
|
||||||
.then(() => Bangle.buzz(t, 1))
|
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, t)))
|
|
||||||
.then(() => Bangle.buzz(t, 1))
|
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, 5E3)))
|
|
||||||
.then(() => {
|
|
||||||
// Update alarm state to disabled
|
|
||||||
settings.alarm = -1;
|
|
||||||
storage.writeJSON(SETTINGS_FILE, settings);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function increaseAlarm(){
|
function increaseAlarm(){
|
||||||
if(isAlarmEnabled()){
|
try{
|
||||||
settings.alarm += 5;
|
var minutes = isAlarmEnabled() ? getAlarmMinutes() : 0;
|
||||||
} else {
|
var alarm = require('sched')
|
||||||
settings.alarm = getCurrentTimeInMinutes() + 5;
|
alarm.setAlarm(TIMER_IDX, {
|
||||||
}
|
timer : (minutes+5)*60*1000,
|
||||||
|
});
|
||||||
storage.writeJSON(SETTINGS_FILE, settings);
|
alarm.reload();
|
||||||
|
} catch(ex){ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function decreaseAlarm(){
|
function decreaseAlarm(){
|
||||||
if(isAlarmEnabled() && (settings.alarm-5 > getCurrentTimeInMinutes())){
|
try{
|
||||||
settings.alarm -= 5;
|
var minutes = getAlarmMinutes();
|
||||||
} else {
|
minutes -= 5;
|
||||||
settings.alarm = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.writeJSON(SETTINGS_FILE, settings);
|
var alarm = require('sched')
|
||||||
|
alarm.setAlarm(TIMER_IDX, undefined);
|
||||||
|
|
||||||
|
if(minutes > 0){
|
||||||
|
alarm.setAlarm(TIMER_IDX, {
|
||||||
|
timer : minutes*60*1000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm.reload();
|
||||||
|
} catch(ex){ }
|
||||||
}
|
}
|
||||||
|
|
||||||
function feedback(){
|
function feedback(){
|
||||||
Bangle.buzz(40, 0.6);
|
Bangle.buzz(40, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lets start widgets, listen for btn etc.
|
* Lets start widgets, listen for btn etc.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: Release
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwMAg//AAXgApcAvAZBhwCBuAFuGoUeAQM4AQM8AQl8Bwn4AQMPgEB+AFBg+AgZYBgED4AHBAoIPBCYIAC/AfCGwQrCGAQ3CAAMcIYQFCJ4QABnoREvIdE/eeAgUB+fPAoUD8/nIIUHz/zJoUPn/5LIUev/8MoU8//+OIU5XwO8AoN7AoPeAoNzAoPOAsrFKg4QBAAPgApYA=="))
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* SIMPLE TIMER
|
||||||
|
*
|
||||||
|
* Creator: David Peer
|
||||||
|
* Date: 02/2022
|
||||||
|
*/
|
||||||
|
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
|
||||||
|
|
||||||
|
const alarm = require("sched");
|
||||||
|
|
||||||
|
const TIMER_IDX = "smpltmr";
|
||||||
|
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 isTimerEnabled(){
|
||||||
|
var alarmObj = alarm.getAlarm(TIMER_IDX);
|
||||||
|
if(alarmObj===undefined || !alarmObj.on){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimerMin(){
|
||||||
|
var alarmObj = alarm.getAlarm(TIMER_IDX);
|
||||||
|
return Math.round(alarm.getTimeToAlarm(alarmObj)/(60*1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTimer(minutes){
|
||||||
|
alarm.setAlarm(TIMER_IDX, {
|
||||||
|
// msg : "Simple Timer",
|
||||||
|
timer : minutes*60*1000,
|
||||||
|
});
|
||||||
|
alarm.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTimer(){
|
||||||
|
alarm.setAlarm(TIMER_IDX, undefined);
|
||||||
|
alarm.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
setWatch(_=>load(), BTN1);
|
||||||
|
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 = isTimerEnabled();
|
||||||
|
var text = minutes + " min.";
|
||||||
|
if(started){
|
||||||
|
var min = getTimerMin();
|
||||||
|
text = min + " min.";
|
||||||
|
}
|
||||||
|
|
||||||
|
var rectWidth = parseInt(g.stringWidth(text) / 2);
|
||||||
|
|
||||||
|
if(started){
|
||||||
|
interval = setInterval(draw, 1000);
|
||||||
|
g.setColor("#ff0000");
|
||||||
|
} else {
|
||||||
|
g.setColor(g.theme.fg);
|
||||||
|
}
|
||||||
|
g.fillRect(cx-rectWidth-5, cy-5, cx+rectWidth, cy+30);
|
||||||
|
|
||||||
|
g.setColor(g.theme.bg);
|
||||||
|
g.drawString(text, cx, cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Bangle.on('touch', function(btn, e){
|
||||||
|
var left = parseInt(g.getWidth() * 0.25);
|
||||||
|
var right = g.getWidth() - left;
|
||||||
|
var upper = parseInt(g.getHeight() * 0.25);
|
||||||
|
var lower = g.getHeight() - upper;
|
||||||
|
|
||||||
|
var isLeft = e.x < left;
|
||||||
|
var isRight = e.x > right;
|
||||||
|
var isUpper = e.y < upper;
|
||||||
|
var isLower = e.y > lower;
|
||||||
|
var isMiddle = !isLeft && !isRight && !isUpper && !isLower;
|
||||||
|
var started = isTimerEnabled();
|
||||||
|
|
||||||
|
if(isRight && !started){
|
||||||
|
minutes += 1;
|
||||||
|
Bangle.buzz(40, 0.3);
|
||||||
|
} else if(isLeft && !started){
|
||||||
|
minutes -= 1;
|
||||||
|
Bangle.buzz(40, 0.3);
|
||||||
|
} else if(isUpper && !started){
|
||||||
|
minutes += 5;
|
||||||
|
Bangle.buzz(40, 0.3);
|
||||||
|
} else if(isLower && !started){
|
||||||
|
minutes -= 5;
|
||||||
|
Bangle.buzz(40, 0.3);
|
||||||
|
} else if(isMiddle) {
|
||||||
|
if(!started){
|
||||||
|
setTimer(minutes);
|
||||||
|
} else {
|
||||||
|
deleteTimer();
|
||||||
|
}
|
||||||
|
Bangle.buzz(80, 0.6);
|
||||||
|
}
|
||||||
|
minutes = Math.max(0, minutes);
|
||||||
|
|
||||||
|
draw();
|
||||||
|
});
|
||||||
|
|
||||||
|
g.reset();
|
||||||
|
draw();
|
||||||
|
After Width: | Height: | Size: 1.1 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 very simple app to start a timer.",
|
||||||
|
"icon": "app.png",
|
||||||
|
"tags": "tool",
|
||||||
|
"dependencies": {"sched":"type"},
|
||||||
|
"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}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |