Merge remote-tracking branch 'upstream/master' into no-unused-vars
|
@ -149,7 +149,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
"no-constant-condition": "off",
|
"no-constant-condition": "off",
|
||||||
"no-delete-var": "off",
|
"no-delete-var": "off",
|
||||||
"no-empty": "off",
|
"no-empty": ["warn", { "allowEmptyCatch": true }],
|
||||||
"no-global-assign": "off",
|
"no-global-assign": "off",
|
||||||
"no-inner-declarations": "off",
|
"no-inner-declarations": "off",
|
||||||
"no-prototype-builtins": "off",
|
"no-prototype-builtins": "off",
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
0.01: Initial version
|
0.01: Initial version
|
||||||
|
0.02: Add settings page; Add line break to update message
|
|
@ -1,10 +1,13 @@
|
||||||
# a_dndtoggle - Toggle Quiet Mode of the watch
|
# a_dndtoggle - Toggle Quiet Mode of the watch
|
||||||
|
|
||||||
When Quiet mode is off, just start this app to set quiet mode. Start it again to turn off quiet mode.
|
When Quiet mode is off, just start this app to set quiet mode. Start it again to turn off quiet mode.
|
||||||
|
|
||||||
|
Use the app settings to choose which quiet mode you prefer ("Alarms" or "Silent"). Default is "Silent".
|
||||||
|
|
||||||
Work in progress.
|
Work in progress.
|
||||||
|
|
||||||
#ToDo
|
#ToDo
|
||||||
Settings page, current status indicator.
|
Current status indicator
|
||||||
|
|
||||||
## Creator
|
## Creator
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,14 @@ let current = 0|bSettings.quiet;
|
||||||
//1 alarms
|
//1 alarms
|
||||||
//2 silent
|
//2 silent
|
||||||
|
|
||||||
|
const dndSettings =
|
||||||
|
require('Storage').readJSON("a_dndtoggle.settings.json", true) || {};
|
||||||
|
|
||||||
console.log("old: " + current);
|
console.log("old: " + current);
|
||||||
|
|
||||||
switch (current) {
|
switch (current) {
|
||||||
case 0:
|
case 0:
|
||||||
bSettings.quiet = 2;
|
bSettings.quiet = dndSettings.mode || 2;
|
||||||
Bangle.buzz();
|
Bangle.buzz();
|
||||||
setTimeout('Bangle.buzz();',500);
|
setTimeout('Bangle.buzz();',500);
|
||||||
break;
|
break;
|
||||||
|
@ -29,7 +32,7 @@ switch (current) {
|
||||||
|
|
||||||
console.log("new: " + bSettings.quiet);
|
console.log("new: " + bSettings.quiet);
|
||||||
|
|
||||||
E.showMessage(modeNames[current] + " -> " + modeNames[bSettings.quiet]);
|
E.showMessage(modeNames[current] + " -> \n" + modeNames[bSettings.quiet]);
|
||||||
setTimeout('exitApp();', 2000);
|
setTimeout('exitApp();', 2000);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,18 @@
|
||||||
"id": "a_dndtoggle",
|
"id": "a_dndtoggle",
|
||||||
"name": "a_dndtoggle - Toggle Quiet Mode of the watch",
|
"name": "a_dndtoggle - Toggle Quiet Mode of the watch",
|
||||||
"shortName": "A_DND Toggle",
|
"shortName": "A_DND Toggle",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "Toggle Quiet Mode of the watch just by starting this app.",
|
"description": "Toggle Quiet Mode of the watch just by starting this app.",
|
||||||
"icon": "a_dndtoggle.png",
|
"icon": "a_dndtoggle.png",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
"tags": "tool",
|
"tags": "tool",
|
||||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
|
"data" : [
|
||||||
|
{"name":"a_dndtoggle.settings.json"}
|
||||||
|
],
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"a_dndtoggle.app.js","url":"a_dndtoggle.app.js"},
|
{"name":"a_dndtoggle.app.js","url":"a_dndtoggle.app.js"},
|
||||||
|
{"name":"a_dndtoggle.settings.js","url":"settings.js"},
|
||||||
{"name":"a_dndtoggle.img","url":"app-icon.js","evaluate":true}
|
{"name":"a_dndtoggle.img","url":"app-icon.js","evaluate":true}
|
||||||
],
|
],
|
||||||
"readme": "README.md"
|
"readme": "README.md"
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
(function(back) {
|
||||||
|
|
||||||
|
const settings =
|
||||||
|
require('Storage').readJSON("a_dndtoggle.settings.json", true) || {};
|
||||||
|
|
||||||
|
function updateSettings() {
|
||||||
|
require('Storage').writeJSON("a_dndtoggle.settings.json", settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMainMenu(){
|
||||||
|
// 0-Noisy is only a placeholder so that the other values map to the Bangle quiet mode options
|
||||||
|
const modes = [/*LANG*/"Noisy",/*LANG*/"Alarms",/*LANG*/"Silent"];
|
||||||
|
let mainmenu = {
|
||||||
|
'': { 'title': 'A_DND Toggle' },
|
||||||
|
'< Back': back,
|
||||||
|
/*LANG*/"Quiet Mode": {
|
||||||
|
value: settings.mode || 2,
|
||||||
|
min: 1, // don't allow choosing 0-Noisy
|
||||||
|
max: modes.length - 1,
|
||||||
|
format: v => modes[v],
|
||||||
|
onchange: v => {
|
||||||
|
settings.mode = v;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return mainmenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
E.showMenu(buildMainMenu());
|
||||||
|
});
|
||||||
|
|
|
@ -104,7 +104,6 @@ Bangle.on('lcdPower',on=>{
|
||||||
if (on) {
|
if (on) {
|
||||||
secondInterval = setInterval(draw, 1000);
|
secondInterval = setInterval(draw, 1000);
|
||||||
draw(); // draw immediately
|
draw(); // draw immediately
|
||||||
}else{
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Bangle.on('lock',on=>{
|
Bangle.on('lock',on=>{
|
||||||
|
|
|
@ -6,3 +6,4 @@
|
||||||
0.06: Formatting
|
0.06: Formatting
|
||||||
0.07: Added potato GLaDOS and quote functionality when you tap her
|
0.07: Added potato GLaDOS and quote functionality when you tap her
|
||||||
0.08: Fixed drawing issues with the quotes and added more
|
0.08: Fixed drawing issues with the quotes and added more
|
||||||
|
0.09: Minor code improvements
|
||||||
|
|
|
@ -270,8 +270,7 @@ function queueDraw() {
|
||||||
|
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
if (pause){}
|
if (!pause){
|
||||||
else{
|
|
||||||
// get date
|
// get date
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
var da = d.toString().split(" ");
|
var da = d.toString().split(" ");
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "aptsciclk",
|
"id": "aptsciclk",
|
||||||
"name": "Apeture Science Clock",
|
"name": "Apeture Science Clock",
|
||||||
"shortName":"AptSci Clock",
|
"shortName":"AptSci Clock",
|
||||||
"version": "0.08",
|
"version": "0.09",
|
||||||
"description": "A clock based on the portal series",
|
"description": "A clock based on the portal series",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"screenshots": [{"url":"screenshot.png"}],
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Auto Reset
|
||||||
|
|
||||||
|
Sets a timeout to load the clock face. The timeout is stopped and started again upon user input.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Install with app loader and Auto Reset will run in background. If you don't interact with the watch it will time out to the clock face after 10 minutes.
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
- Add settings page
|
||||||
|
- set how many minutes the timeout should count down.
|
||||||
|
- whitelist/blacklist for apps.
|
||||||
|
|
||||||
|
## Requests
|
||||||
|
|
||||||
|
Mention @thyttan in an issue on the espruino/BangleApps repo for bug reports and feature requests.
|
||||||
|
|
||||||
|
## Creator
|
||||||
|
|
||||||
|
thyttan
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
let timeoutAutoreset;
|
||||||
|
let resetTimeoutAutoreset = (force)=>{
|
||||||
|
if (timeoutAutoreset) clearTimeout(timeoutAutoreset);
|
||||||
|
setTimeout(()=>{ // Short outer timeout to make sure we have time to leave clock face before checking `Bangle.CLOCK!=1`.
|
||||||
|
if (Bangle.CLOCK!=1) { // Only add timeout if not already on clock face.
|
||||||
|
timeoutAutoreset = setTimeout(()=>{
|
||||||
|
if (Bangle.CLOCK!=1) Bangle.showClock();
|
||||||
|
}, 10*60*1000);
|
||||||
|
}
|
||||||
|
},200);
|
||||||
|
};
|
||||||
|
|
||||||
|
Bangle.on('touch', resetTimeoutAutoreset);
|
||||||
|
Bangle.on('swipe', resetTimeoutAutoreset);
|
||||||
|
Bangle.on('message', resetTimeoutAutoreset);
|
||||||
|
setWatch(resetTimeoutAutoreset, BTN, {repeat:true, edge:'rising'});
|
||||||
|
|
||||||
|
if (Bangle.CLOCK!=1) resetTimeoutAutoreset();
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{ "id": "autoreset",
|
||||||
|
"name": "Auto Reset",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Sets a timeout to load the clock face. The timeout is stopped and started again upon user input.",
|
||||||
|
"icon": "app.png",
|
||||||
|
"type": "bootloader",
|
||||||
|
"tags": "system",
|
||||||
|
"supports" : ["BANGLEJS2"],
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"autoreset.boot.js","url":"boot.js"}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
0.01: Added app
|
0.01: Added app
|
||||||
0.02: Removed unneeded squares
|
0.02: Removed unneeded squares
|
||||||
0.03: Added settings with fullscreen option
|
0.03: Added setting for fullscreen option
|
||||||
0.04: Minor code improvements
|
0.04: Added settings to hide unused squares and show date
|
||||||
|
0.05: Minor code improvements
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
var settings = Object.assign({
|
var settings = Object.assign({
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
|
hidesq: false,
|
||||||
|
showdate: false,
|
||||||
}, require('Storage').readJSON("binaryclk.json", true) || {});
|
}, require('Storage').readJSON("binaryclk.json", true) || {});
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
|
|
||||||
var dt = new Date();
|
var dt = new Date();
|
||||||
var h = dt.getHours(), m = dt.getMinutes();
|
var h = dt.getHours(), m = dt.getMinutes(), d = dt.getDate();
|
||||||
const t = [];
|
const t = [];
|
||||||
|
|
||||||
t[0] = Math.floor(h/10);
|
t[0] = Math.floor(h/10);
|
||||||
t[1] = Math.floor(h%10);
|
t[1] = Math.floor(h%10);
|
||||||
t[2] = Math.floor(m/10);
|
t[2] = Math.floor(m/10);
|
||||||
|
@ -17,25 +21,44 @@ function draw() {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
var gap = 8;
|
var gap = 8;
|
||||||
var mgn = 20;
|
var mgn = 20;
|
||||||
|
|
||||||
if (settings.fullscreen) {
|
if (settings.fullscreen) {
|
||||||
gap = 12;
|
gap = 12;
|
||||||
mgn = 0;
|
mgn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sq = 29;
|
const sq = 29;
|
||||||
var pos = sq + gap;
|
var pos = sq + gap;
|
||||||
|
|
||||||
for (let r = 3; r >= 0; r--) {
|
for (let r = 3; r >= 0; r--) {
|
||||||
for (let c = 0; c < 4; c++) {
|
for (let c = 0; c < 4; c++) {
|
||||||
if (t[c] & Math.pow(2, r)) {
|
if (t[c] & Math.pow(2, r)) {
|
||||||
g.fillRect(mgn/2 + gap + c * pos, mgn + gap + i * pos, mgn/2 + gap + c * pos + sq, mgn + gap + i * pos + sq);
|
g.fillRect(Math.floor(mgn/2) + gap + c * pos, mgn + gap + i * pos, Math.floor(mgn/2) + gap + c * pos + sq, mgn + gap + i * pos + sq);
|
||||||
} else {
|
} else {
|
||||||
g.drawRect(mgn/2 + gap + c * pos, mgn + gap + i * pos, mgn/2 + gap + c * pos + sq, mgn + gap + i * pos + sq);
|
g.drawRect(Math.floor(mgn/2) + gap + c * pos, mgn + gap + i * pos, Math.floor(mgn/2) + gap + c * pos + sq, mgn + gap + i * pos + sq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
g.clearRect(mgn/2 + gap, mgn + gap, mgn/2 + gap + sq, mgn + 2 * gap + 2 * sq);
|
|
||||||
g.clearRect(mgn/2 + 3 * gap + 2 * sq, mgn + gap, mgn/2 + 3 * gap + 3 * sq, mgn + gap + sq);
|
var c1sqhide = 0;
|
||||||
|
var c3sqhide = 0;
|
||||||
|
|
||||||
|
if (settings.hidesq) {
|
||||||
|
c1sqhide = 2;
|
||||||
|
c3sqhide = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.hidesq) {
|
||||||
|
g.clearRect(Math.floor(mgn/2), mgn, Math.floor(mgn/2) + pos, mgn + c1sqhide * pos);
|
||||||
|
g.clearRect(Math.floor(mgn/2) + 2 * pos + gap, mgn, Math.floor(mgn/2) + 3 * pos, mgn + c3sqhide * pos);
|
||||||
|
}
|
||||||
|
if (settings.showdate) {
|
||||||
|
g.setFontAlign(0, 0);
|
||||||
|
g.setFont("Vector",20);
|
||||||
|
g.drawRect(Math.floor(mgn/2) + gap, mgn + gap, Math.floor(mgn/2) + gap + sq, mgn + gap + sq);
|
||||||
|
g.drawString(d, Math.ceil(mgn/2) + gap + Math.ceil(sq/2) + 1, mgn + gap + Math.ceil(sq/2) + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g.clear();
|
g.clear();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"id": "binaryclk",
|
"id": "binaryclk",
|
||||||
"name": "Bin Clock",
|
"name": "Bin Clock",
|
||||||
"version": "0.04",
|
"version": "0.05",
|
||||||
"description": "Clock face to show binary time in 24 hr format",
|
"description": "Clock face to show binary time in 24 hour format",
|
||||||
"icon": "app-icon.png",
|
"icon": "app-icon.png",
|
||||||
"screenshots": [{"url":"screenshot.png"}],
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
|
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 16 KiB |
|
@ -2,6 +2,8 @@
|
||||||
var FILE = "binaryclk.json";
|
var FILE = "binaryclk.json";
|
||||||
var settings = Object.assign({
|
var settings = Object.assign({
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
|
hidesq: false,
|
||||||
|
showdate: false,
|
||||||
}, require('Storage').readJSON(FILE, true) || {});
|
}, require('Storage').readJSON(FILE, true) || {});
|
||||||
|
|
||||||
function writeSettings() {
|
function writeSettings() {
|
||||||
|
@ -16,7 +18,21 @@
|
||||||
onchange: v => {
|
onchange: v => {
|
||||||
settings.fullscreen = v;
|
settings.fullscreen = v;
|
||||||
writeSettings();
|
writeSettings();
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
'Hide Squares': {
|
||||||
|
value: settings.hidesq,
|
||||||
|
onchange: v => {
|
||||||
|
settings.hidesq = v;
|
||||||
|
writeSettings();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'Show Date': {
|
||||||
|
value: settings.showdate,
|
||||||
|
onchange: v => {
|
||||||
|
settings.showdate = v;
|
||||||
|
writeSettings();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
0.01: Car Crazy is now avialable for testing in beta!
|
0.01: Car Crazy is now avialable for testing in beta!
|
||||||
0.02: 10 Levels are now added making the game harder as it goes along. Some of the levels include multiple cars and faster cars. More levels coming soon.
|
0.02: 10 Levels are now added making the game harder as it goes along. Some of the levels include multiple cars and faster cars. More levels coming soon.
|
||||||
0.03: Settings are now added so that you can reset your high score.
|
0.03: Settings are now added so that you can reset your high score.
|
||||||
0.04: Minor code improvements
|
0.04: Minor code improvements.
|
||||||
|
|
|
@ -66,10 +66,8 @@ function moveEnemyPosition(){
|
||||||
enemyPositonCenterX2 = 120;
|
enemyPositonCenterX2 = 120;
|
||||||
}else if((randomRoadPositionIndicator2 == 3)){
|
}else if((randomRoadPositionIndicator2 == 3)){
|
||||||
enemyPositonCenterX2 = 155;
|
enemyPositonCenterX2 = 155;
|
||||||
}else if(level == 7||level == 8){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} // TODO: else if(level == 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
function collision(){
|
function collision(){
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
0.01: Simple app to display loyalty cards
|
0.01: Simple app to display loyalty cards
|
||||||
0.02: Hiding widgets while showing the code
|
0.02: Hiding widgets while showing the code
|
||||||
0.03: Minor code improvements
|
0.03: Added option to use max brightness when showing code
|
||||||
|
0.04: Minor code improvements
|
||||||
|
|
|
@ -14,6 +14,14 @@
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
|
// get brightness
|
||||||
|
let brightness;
|
||||||
|
|
||||||
|
function loadBrightness() {
|
||||||
|
const getBrightness = require('Storage').readJSON("setting.json", 1) || {};
|
||||||
|
brightness = getBrightness.brightness || 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
//may make it configurable in the future
|
//may make it configurable in the future
|
||||||
const WHITE=-1
|
const WHITE=-1
|
||||||
const BLACK=0
|
const BLACK=0
|
||||||
|
@ -89,6 +97,10 @@ function printLinearCode(binary) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showCode(card) {
|
function showCode(card) {
|
||||||
|
// set to full bright when the setting is true
|
||||||
|
if(settings.fullBrightness) {
|
||||||
|
Bangle.setLCDBrightness(1);
|
||||||
|
}
|
||||||
widget_utils.hide();
|
widget_utils.hide();
|
||||||
E.showScroller();
|
E.showScroller();
|
||||||
// keeping it on rising edge would come back twice..
|
// keeping it on rising edge would come back twice..
|
||||||
|
@ -129,6 +141,10 @@ function showCode(card) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showCard(card) {
|
function showCard(card) {
|
||||||
|
// reset brightness to old value after maxing it out
|
||||||
|
if(settings.fullBrightness) {
|
||||||
|
Bangle.setLCDBrightness(brightness);
|
||||||
|
}
|
||||||
var lines = [];
|
var lines = [];
|
||||||
var bodyFont = fontBig;
|
var bodyFont = fontBig;
|
||||||
if(!card) return;
|
if(!card) return;
|
||||||
|
@ -206,4 +222,7 @@ function showList() {
|
||||||
back : () => load()
|
back : () => load()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if(settings.fullBrightness) {
|
||||||
|
loadBrightness();
|
||||||
|
}
|
||||||
showList();
|
showList();
|
||||||
|
|
|
@ -14,6 +14,13 @@
|
||||||
updateSettings();
|
updateSettings();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/*LANG*/"Full Brightness" : {
|
||||||
|
value : !!settings.fullBrightness,
|
||||||
|
onchange: v => {
|
||||||
|
settings.fullBrightness = v;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
E.showMenu(mainmenu);
|
E.showMenu(mainmenu);
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,3 +7,4 @@
|
||||||
Improve connection code
|
Improve connection code
|
||||||
0.07: Make Bangle.js 2 compatible
|
0.07: Make Bangle.js 2 compatible
|
||||||
0.08: Convert Yes/No On/Off in settings to checkboxes
|
0.08: Convert Yes/No On/Off in settings to checkboxes
|
||||||
|
0.09: Automatically reconnect on error
|
||||||
|
|
|
@ -226,7 +226,7 @@ function getSensorBatteryLevel(gatt) {
|
||||||
function connection_setup() {
|
function connection_setup() {
|
||||||
mySensor.screenInit = true;
|
mySensor.screenInit = true;
|
||||||
E.showMessage("Scanning for CSC sensor...");
|
E.showMessage("Scanning for CSC sensor...");
|
||||||
NRF.requestDevice({ filters: [{services:["1816"]}]}).then(function(d) {
|
NRF.requestDevice({ filters: [{services:["1816"]}], maxInterval: 100}).then(function(d) {
|
||||||
device = d;
|
device = d;
|
||||||
E.showMessage("Found device");
|
E.showMessage("Found device");
|
||||||
return device.gatt.connect();
|
return device.gatt.connect();
|
||||||
|
@ -249,6 +249,7 @@ function connection_setup() {
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
E.showMessage(e.toString(), "ERROR");
|
E.showMessage(e.toString(), "ERROR");
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
setTimeout(connection_setup, 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "cscsensor",
|
"id": "cscsensor",
|
||||||
"name": "Cycling speed sensor",
|
"name": "Cycling speed sensor",
|
||||||
"shortName": "CSCSensor",
|
"shortName": "CSCSensor",
|
||||||
"version": "0.08",
|
"version": "0.09",
|
||||||
"description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch",
|
"description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch",
|
||||||
"icon": "icons8-cycling-48.png",
|
"icon": "icons8-cycling-48.png",
|
||||||
"tags": "outdoors,exercise,ble,bluetooth,bike,cycle,bicycle",
|
"tags": "outdoors,exercise,ble,bluetooth,bike,cycle,bicycle",
|
||||||
|
|
|
@ -223,9 +223,8 @@ function fixTime() {
|
||||||
Bangle.on("GPS",function cb(g) {
|
Bangle.on("GPS",function cb(g) {
|
||||||
Bangle.setGPSPower(0,"time");
|
Bangle.setGPSPower(0,"time");
|
||||||
Bangle.removeListener("GPS",cb);
|
Bangle.removeListener("GPS",cb);
|
||||||
if (!g.time || (g.time.getFullYear()<2000) ||
|
if (g.time && (g.time.getFullYear()>=2000) &&
|
||||||
(g.time.getFullYear()>2200)) {
|
(g.time.getFullYear()<=2200)) {
|
||||||
} else {
|
|
||||||
// We have a GPS time. Set time
|
// We have a GPS time. Set time
|
||||||
setTime(g.time.getTime()/1000);
|
setTime(g.time.getTime()/1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
node_modules/
|
||||||
|
res/
|
||||||
|
|
||||||
|
fallout_clock.code-workspace
|
||||||
|
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
|
@ -0,0 +1,5 @@
|
||||||
|
0.10: (20240125) Basic Working Clock.
|
||||||
|
0.11: (20240125) Widgets Added. Improved Interval Loop.
|
||||||
|
0.12: (20240221) Fix: Month Reporting Wrong.
|
||||||
|
0.20: (20240223) Created as a Package.
|
||||||
|
0.21: (20240223) Added StandardJS and NPM.
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Zachary D. Skelton <zskelton@skeltonnetworks.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Fallout Clock
|
||||||
|
|
||||||
|
Inspired by the aesthetic of the Fallout series, this clock face looks to emulate the color and feel of a PipBoy.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
You can also go into Settings, and choose it as the default clock under **Select Clock**.
|
||||||
|
|
||||||
|
## Planned Features:
|
||||||
|
- Display Steps as Health
|
||||||
|
- Display Heartrate
|
||||||
|
- Brighter Color when the backlight is not on.
|
||||||
|
- Configurable Settings
|
||||||
|
|
||||||
|
## Controls
|
||||||
|
|
||||||
|
Zero Settings, Zero Configuration. Install and add as your clockface.
|
||||||
|
|
||||||
|
## Requests
|
||||||
|
|
||||||
|
To request new features, add [an issue](https://github.com/zskelton/fallout_clock/issues).
|
||||||
|
|
||||||
|
## Creator
|
||||||
|
|
||||||
|
Zachary D. Skelton <zskelton@skeltonnetworks.com>\
|
||||||
|
[Skelton Networks](https://skeltonnetworks.com)\
|
||||||
|
[Github](https://github.com/zskelton)
|
|
@ -0,0 +1 @@
|
||||||
|
atob("MDDDAb88//9u/1r/1/YZrgAAit4kkkkkkkkkkAAVIkkkkkkkkkkkkkkkkkkAAAARJJIkkkkkkkkkkkkkkkAAAACJJJJUkkkkkkkkkkkkkAAAAARJJJJAAkkkkkkkkkkkAAAAACpJJJKgAAkkkkkkkkkgAAAAAVJJJJIAAAEkkkkkkkkAAAAACpJfpJUAAAAkkkkkkkgAAAAABJf/9JAAAAAEkkkkkkAAAAAARJdf/+gAAAAAkkkkkgAAAAAC//dL//gAAAAAEkkkkAAAAYADpJJL//8AAAAAAkkkkAAAD8AdJJJL///gAAAAAkkkgAAADr/pJJL////0AAAAAEkkgAAABJJL/pfb////gAAAAAkkAAAADpJeu22X////4AAAAAkkAAAADpL1tttuf/7f8AAAAAkgAAAAb/+ttttuSSS7/AAAAAEgAAAAdeyttttySSSb/gAAAAEgAAAC9eWtttuaySSf/2SSSSkgAAAVfxtttttyySX//9JJJQAAAAAJetttttttyST//9JJJUAAAABJeOaNyNutySW//9JJKgAAAARJdu6N1tvRySS3/JJJUAAAACJJVuVu1tzRyST2/JJKAAAAAVJL1ttyttuNuSWW7pJKgAAACpJLxtt6NtttuSS27pJUAAAAVJJLxtt6ttttuSWT9JKgAAAAJJJLxttzNtttuSST9JIAAAAiJJJL1ttttt2NuSSS9JUAAAA2222212xtty3RySSS9KgAAAEgAAAAZ6OW2tu1ySST9QAAAAEgAAAAaW1ttu2VySSXKAAAAAEkAAAACtu221ttySbdKgAAAAEkAAAADNty1ttuST9JUAAAAAkkAAAAAVty1ttuSXpKAAAAAAkkgAAAACtttttyT9JIAAAAAEkkkAAAAARttttyfdJUAAAAAEkkkAAAAACtttuSzJKgAAAAAkkkkgAAAAAWtuSSfpQAAAAAEkkkkkAAAAADa2yT9JAAAAAAkkkkkkgAAAAD7e3/pKgAAAAAkkkkkkkAAAAVL/9JJUAAAAAEkkkkkkkgAAARJJJJKAAAAAEkkkkkkkkkAAAJJJJJIAAAAAkkkkkkkkkkkACpJJJJUAAAAEkkkkkkkkkkkgCJJJJKgAAAEkkkkkkkkkkkkklJJJJQAAAEkkkkkkkkkkkkkkkkpJJAAEkkkkkkkkk=")
|
|
@ -0,0 +1,141 @@
|
||||||
|
/* global Bangle, Graphics, g */
|
||||||
|
|
||||||
|
// NAME: Fallout Clock (Bangle.js 2)
|
||||||
|
// DOCS: https://www.espruino.com/ReferenceBANGLEJS2
|
||||||
|
// AUTHOR: Zachary D. Skelton <zskelton@bws-solutions.com>
|
||||||
|
// VERSION: 0.1.0 (24JAN2024) - Creating [ Maj.Min.Bug ] REF: https://semver.org/
|
||||||
|
// LICENSE: MIT License (2024) [ https://opensource.org/licenses/MIT ]
|
||||||
|
|
||||||
|
/* THEME COLORS */
|
||||||
|
// Dark Full - #000000 - (0,0.00,0)
|
||||||
|
// Dark Half - #002f00 - (0,0.18,0)
|
||||||
|
// Dark Zero - #005f00 - (0,0.37,0)
|
||||||
|
// Light Zero - #008e00 - (0,0.55,0)
|
||||||
|
// Light Half - #00bf00 - (0,0.75,0)
|
||||||
|
// Light Full - #00ee00 - (0,0.93,0)
|
||||||
|
|
||||||
|
/* FONTS */
|
||||||
|
// Font: Good Time Rg - https://www.dafont.com/good-times.font
|
||||||
|
// Large = 50px
|
||||||
|
Graphics.prototype.setLargeFont = function () {
|
||||||
|
this.setFontCustom(
|
||||||
|
atob('AAAAAAAAAAAAAAAAAAAAAABAAAAAAAB8AAAAAAA/gAAAAAAP4AAAAAAD+AAAAAAA/gAAAAAAP4AAAAAAB8AAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAADwAAAAAAD8AAAAAAD/AAAAAAD/wAAAAAD/8AAAAAH/8AAAAAH/8AAAAAH/4AAAAAH/4AAAAAH/4AAAAAH/4AAAAAP/4AAAAAP/wAAAAAP/wAAAAAP/wAAAAAP/wAAAAAH/wAAAAAB/wAAAAAAfgAAAAAAHgAAAAAABgAAAAAAAAAAAAAAAAAAOAAAAAAB//AAAAAB//8AAAAB///wAAAA////AAAAf///4AAAP////AAAH////4AAD/+B//AAB/8AD/wAAf8AAP+AAP+AAB/gAD/AAAP8AA/gAAB/AAf4AAAf4AH8AAAD+AB/AAAA/gAfwAAAP4AH8AAAD+AB/AAAA/gAfwAAAP4AH8AAAD+AB/AAAA/gAfwAAAP4AH8AAAD+AB/gAAB/gAP4AAAfwAD/AAAP8AA/4AAH+AAH/AAD/gAB/8AD/wAAP/4H/8AAB////+AAAP////AAAB////gAAAP///wAAAB///wAAAAH//wAAAAAf/wAAAAAAOAAAAAAAAAAAAAfgAAAAAAH8AAAAAAB/AAAAAAAfwAAAAAAH8AAAAAAB/AAAAAAAfwAAAAAAH+AAAAAAB/wAAAAAAf/////wAD/////8AA//////AAH/////wAA/////8AAH/////AAAf////wAAA////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wAH8AA//8AB/AA///AAfwAf//wAH8AH//8AB/AD///AAfwA///wAH8Af//8AB/AH8B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwD+AfwAH+B/AH8AB///wB/AAf//8AfwAD///AH8AA///gB/AAH//wAfwAA//4AH8AAH/8AB/AAAf8AAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AB/AAAB/AAfwAAAfwAH8AAAH8AB/AAAB/AAfwAAAfwAH8AAAH8AB/AAAB/AAfwAAAfwAH8AfAH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8A/gH8AB/gP4D/AAf8H/A/wAH///8/8AA/////+AAP/////gAB/////4AAf/8//8AAD/+P/+AAAf/B//AAAA/AH/AAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAH///AAAAB///8AAAAf///gAAAH///8AAAB////gAAAf///4AAAH////AAAAAAD/wAAAAAAP8AAAAAAB/AAAAAAAfwAAAAAAD+AAAAAAA/gAAAAAAP4AAAAAAD+AAAAAAA/gAAAAAAP4AAAAAAD+AAAAAAA/gAAAAAAP4AAAAAAD+AAAAAAA/gAAAAAAP4AAAAAAD+AAAAAAA/gAAAAAAP4AAAAAAD+AAAH/////8AB//////AAf/////wAH/////8AB//////AAf/////wAH/////8AAAAAP4AAAAAAD+AAAAAAA/gAAAAAAP4AAAAAAD+AAAAAAA/AAAAAAAAAAAAAAAAAAAAH///AD8AB///4B/AAf//+AfwAH///gH8AB///4B/AAf//+AfwAH///gH8AB///4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH8D/AAfwB/h/wAH8Af//8AB/AD//+AAfwA///gAH8AH//wAB/AA//4AAfgAH/8AAAAAAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAAAAB//4AAAAB///wAAAB////AAAA////4AAAf////AAAP////4AAH/////AAB//fv/wAA/8H4f+AAP+B+D/gAH/AfgP8AB/gH4D/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+A/wAH8Afwf8AB/AH///AAfwA///gAH8AP//4AB/AD//8AAfwAf/+AAH8AD//AAAAAAP/gAAAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAB/AAAABAAfwAAAAwAH8AAAAcAB/AAAAfAAfwAAAPwAH8AAAH8AB/AAAD/AAfwAAD/wAH8AAB/8AB/AAA//AAfwAAf/gAH8AAP/gAB/AAP/wAAfwAH/4AAH8AD/8AAB/AB/8AAAfwB/+AAAH8A//AAAB/Af/gAAAfwP/gAAAH8P/wAAAB/H/4AAAAfz/8AAAAH9/8AAAAB//+AAAAAf//AAAAAH//gAAAAB//gAAAAAf/wAAAAAH/4AAAAAB/8AAAAAAf8AAAAAAH+AAAAAAB/AAAAAAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4AAAD/gP/gAAB/+H/8AAA//z//gAAf////8AAP/////gAD/////4AB//////AAf+P/B/wAH+A/gP8AB/AP4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8AfgH8AB/AH4B/AAfwB+AfwAH8A/gH8AB/gP8D/AAf+P/h/wAH/////8AA/////+AAP/////gAB/////wAAP/8//4AAB/+H/8AAAH+A/+AAAAAAD+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAH/4AAAAAH//gAAAAD//8AAAAB///AD8AA///4B/AAP///AfwAH///wH8AB/4f8B/AAf4B/AfwAH8APwH8AB/AD8B/AAfwA/AfwAH8APwH8AB/AD8B/AAfwA/AfwAH8APwH8AB/AD8B/AAfwA/AfwAH8APwH8AB/AD8B/AAfwA/AfwAH8APwH8AB/AD8B/AAfwA/AfwAH8APwH8AB/AD8B/AAfwA/AfwAH+APwP8AB/wD8D/AAP+A/B/gAD/wPx/4AAf/j9/+AAH/////AAA/////gAAH////4AAA////8AAAH///8AAAAf//+AAAAA//8AAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEAAAAD4AHwAAAB/AD+AAAAfwA/gAAAH8AP4AAAB/AD+AAAAfwA/gAAAD4AHwAAAAMAAYAAAAAAAAAAAAAAAAA'),
|
||||||
|
46,
|
||||||
|
atob('DRYqEykpKiwsJi0rDQ=='),
|
||||||
|
50 | 65536
|
||||||
|
)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Medium = 16px ()
|
||||||
|
Graphics.prototype.setMediumFont = function () {
|
||||||
|
this.setFontCustom(
|
||||||
|
atob('AAAAAAAADwAAAB8AAAAPAAAAGwAAAb8AAB/9AAH/kAAv+QAA/4AAAPQAAAACvkAAH//wAD///AC/Qf4A/AA/APQAHwDwAA8A9AAfAPwAPwC+Qf4AP//8AB//9AAG/4AAoAAAAPAAAAD4AAAA////AL///wAv//8AAAAAAPAL/wDwH/8A8D//APA9DwDwPA8A8DwPAPA8DwDwPA8A9DwPAP78DwD/+A8AL+APAPAADwDwAA8A8BQPAPA8DwDwPA8A8DwPAPA8DwDwPA8A9DwfAP7/vwD///8AP+v8AAUBUACqqQAA//9AAP//wABVW8AAAAPAAAADwAAAA8AAAAPAAAADwAD///8A////AP///wAAA8AAAAKAAAAAAAD//A8A//wPAP/8DwDwPA8A8DwPAPA8DwDwPA8A8DwPAPA8DwDwPR8A8D+/APAv/gCgC/gAC//gAD///AC///4A/Tx/APg8LwDwPA8A8DwPAPA8DwDwPA8A8D0fAPA/vwDwL/4AoAv4AAAAQABQAAAA8AAHAPAAHwDwAL8A8AP/APAf+ADwf9AA8v9AAP/4AAD/4AAA/0AAAP0AAAAAAEAAL9v4AL///gD//78A+H0vAPA8DwDwPA8A8DwPAPA8DwDwPA8A9D0fAP7/vwD///8AP9v8AC/4AAC//g8A/r8PAPQfDwDwDw8A8A8PAPAPDwDwDw8A+A8fAP5PfwC///4AL//8AAb/4AAAAAAAAAAAAAA8DwAAfB8AADwPAA=='),
|
||||||
|
46,
|
||||||
|
atob('BAcNBg0NDg4ODA4OBA=='),
|
||||||
|
16 | 131072
|
||||||
|
)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VARIABLES */
|
||||||
|
// Const
|
||||||
|
const H = g.getHeight()
|
||||||
|
const W = g.getWidth()
|
||||||
|
// Mutable
|
||||||
|
let timer = null
|
||||||
|
|
||||||
|
/* UTILITY FUNCTIONS */
|
||||||
|
// Return String of Current Time
|
||||||
|
function getCurrentTime () {
|
||||||
|
try {
|
||||||
|
const d = new Date()
|
||||||
|
const h = d.getHours()
|
||||||
|
const m = d.getMinutes()
|
||||||
|
return `${h}:${m.toString().padStart(2, 0)}`
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
return '0:00'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return String of Current Date
|
||||||
|
function getCurrentDate () {
|
||||||
|
try {
|
||||||
|
const d = new Date()
|
||||||
|
const year = d.getFullYear()
|
||||||
|
const month = d.getMonth()
|
||||||
|
const day = d.getDate()
|
||||||
|
const display = `${month + 1}.${day.toString().padStart(2, 0)}.${year}`
|
||||||
|
return display
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
return '0.0.0000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set A New Draw for the Next Minute
|
||||||
|
function setNextDraw () {
|
||||||
|
console.log('tick')
|
||||||
|
// Clear Timeout
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
|
// Calculate time until next minute
|
||||||
|
const d = new Date()
|
||||||
|
const s = d.getSeconds()
|
||||||
|
const ms = d.getMilliseconds()
|
||||||
|
const delay = 60000 - (s * 1000) - ms
|
||||||
|
// Set Timeout
|
||||||
|
timer = setInterval(draw, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw () {
|
||||||
|
// Reset Variables
|
||||||
|
g.reset()
|
||||||
|
// Set Background Color
|
||||||
|
g.setBgColor(0, 0, 0)
|
||||||
|
// Draw Background
|
||||||
|
g.setColor(0, 0, 0)
|
||||||
|
g.fillRect(0, 0, W, H)
|
||||||
|
// Set Font for Time
|
||||||
|
g.setColor(0, 0.93, 0)
|
||||||
|
g.setLargeFont()
|
||||||
|
g.setFontAlign(0, 0)
|
||||||
|
// Draw Time
|
||||||
|
const time = getCurrentTime()
|
||||||
|
g.drawString(time, W / 2, H / 2, true /* clear background */)
|
||||||
|
// Set Font for Date
|
||||||
|
g.setColor(0, 0.75, 0)
|
||||||
|
g.setMediumFont()
|
||||||
|
g.setFontAlign(0, 1)
|
||||||
|
// Draw Date
|
||||||
|
const dateStr = getCurrentDate()
|
||||||
|
g.drawString(dateStr, W / 2, H - 45, true)
|
||||||
|
// Draw Border
|
||||||
|
g.setColor(0, 0.93, 0)
|
||||||
|
g.drawLine(5, 36, W - 5, 36)
|
||||||
|
g.drawLine(5, H - 9, W - 5, H - 9)
|
||||||
|
g.setColor(0, 0.18, 0)
|
||||||
|
g.fillRect(0, 27, W, 32)
|
||||||
|
g.fillRect(0, H, W, H - 5)
|
||||||
|
// Draw Widgets
|
||||||
|
Bangle.drawWidgets()
|
||||||
|
// Schedule Next Draw
|
||||||
|
setNextDraw()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MAIN LOOP */
|
||||||
|
function main () {
|
||||||
|
// Clear Screen
|
||||||
|
g.clear()
|
||||||
|
// Set as Clock to Enable Launcher Screen on BTN1
|
||||||
|
Bangle.setUI('clock')
|
||||||
|
// Load Widgets
|
||||||
|
Bangle.loadWidgets()
|
||||||
|
// Draw Clock
|
||||||
|
draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BOOT CODE */
|
||||||
|
main()
|
After Width: | Height: | Size: 7.8 KiB |
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"id":"fallout_clock",
|
||||||
|
"name":"Fallout Clock",
|
||||||
|
"version":"0.21",
|
||||||
|
"description":"A simple clock for the Fallout fan",
|
||||||
|
"icon":"icon.png",
|
||||||
|
"type":"clock",
|
||||||
|
"tags": "clock,fallout,green,retro",
|
||||||
|
"supports": ["BANGLEJS2"],
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"fallout_clock.app.js", "url":"clock.js"},
|
||||||
|
{"name":"fallout_clock.img", "url":"app-icon.js", "evaluate":true}
|
||||||
|
],
|
||||||
|
"screenshots": [
|
||||||
|
{"url":"./screenshot.png", "name":"Fallout Clock Screenshot"}
|
||||||
|
]
|
||||||
|
}
|
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
|
@ -8,3 +8,4 @@
|
||||||
0.08: Handling exceptions
|
0.08: Handling exceptions
|
||||||
0.09: Add option for showing battery high mark
|
0.09: Add option for showing battery high mark
|
||||||
0.10: Fix background color
|
0.10: Fix background color
|
||||||
|
0.11: Minor code improvements
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"name": "A Battery Widget (with percentage) - Hanks Mod",
|
"name": "A Battery Widget (with percentage) - Hanks Mod",
|
||||||
"shortName":"H Battery Widget",
|
"shortName":"H Battery Widget",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.10",
|
"version":"0.11",
|
||||||
"type": "widget",
|
"type": "widget",
|
||||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
var s = width - 1;
|
var s = width - 1;
|
||||||
var x = this.x;
|
var x = this.x;
|
||||||
var y = this.y;
|
var y = this.y;
|
||||||
if ((typeof x === 'undefined') || (typeof y === 'undefined')) {
|
if (x !== undefined && y !== undefined) {
|
||||||
} else {
|
|
||||||
g.setBgColor(COLORS.white);
|
g.setBgColor(COLORS.white);
|
||||||
g.clearRect(old_x, old_y, old_x + width, old_y + height);
|
g.clearRect(old_x, old_y, old_x + width, old_y + height);
|
||||||
|
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
0.03: Update clock_info to avoid a redraw
|
0.03: Update clock_info to avoid a redraw
|
||||||
0.04: Fix clkinfo -- use .get instead of .show
|
0.04: Fix clkinfo -- use .get instead of .show
|
||||||
0.05: Use clock_info module as an app
|
0.05: Use clock_info module as an app
|
||||||
|
0.06: Fix month in date (jan 0 -> 1, etc)
|
|
@ -112,7 +112,7 @@ function getTime(){
|
||||||
|
|
||||||
function getDate(){
|
function getDate(){
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
return twoD(date.getDate()) + "." + twoD(date.getMonth());
|
return twoD(date.getDate()) + "." + twoD(date.getMonth() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDay(){
|
function getDay(){
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "linuxclock",
|
"id": "linuxclock",
|
||||||
"name": "Linux Clock",
|
"name": "Linux Clock",
|
||||||
"version": "0.05",
|
"version": "0.06",
|
||||||
"description": "A Linux inspired clock.",
|
"description": "A Linux inspired clock.",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
|
|
@ -790,7 +790,8 @@ var locales = {
|
||||||
trans: { yes: "ja", Yes: "Ja", no: "nei", No: "Nei", ok: "ok", on: "på", off: "av", "< Back": "< Tilbake", "Delete": "Slett", "Mark Unread": "Merk som ulest" }
|
trans: { yes: "ja", Yes: "Ja", no: "nei", No: "Nei", ok: "ok", on: "på", off: "av", "< Back": "< Tilbake", "Delete": "Slett", "Mark Unread": "Merk som ulest" }
|
||||||
},
|
},
|
||||||
"ca_ES": {
|
"ca_ES": {
|
||||||
lang: "es_ES",
|
lang: "ca_ES",
|
||||||
|
icon: "🇪🇺",
|
||||||
decimal_point: ",",
|
decimal_point: ",",
|
||||||
thousands_sep: ".",
|
thousands_sep: ".",
|
||||||
currency_symbol: "€",
|
currency_symbol: "€",
|
||||||
|
@ -800,7 +801,7 @@ var locales = {
|
||||||
temperature: "°C",
|
temperature: "°C",
|
||||||
ampm: { 0: "", 1: "" },
|
ampm: { 0: "", 1: "" },
|
||||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||||
datePattern: { 0: "%A, %d de %B %Y", "1": "%d/%m/%y" },
|
datePattern: { 0: "%d %B %Y", "1": "%d/%m/%y" },
|
||||||
abmonth: "gen.,febr.,març,abr.,maig,juny,jul.,ag.,set.,oct.,nov.,des.",
|
abmonth: "gen.,febr.,març,abr.,maig,juny,jul.,ag.,set.,oct.,nov.,des.",
|
||||||
month: "gener,febrer,març,abril,maig,juny,juliol,agost,setembre,octobre,novembre,desembre",
|
month: "gener,febrer,març,abril,maig,juny,juliol,agost,setembre,octobre,novembre,desembre",
|
||||||
abday: "dg.,dl.,dt.,dc.,dj.,dv.,ds.",
|
abday: "dg.,dl.,dt.,dc.,dj.,dv.,ds.",
|
||||||
|
|
|
@ -102,3 +102,5 @@
|
||||||
0.73: Add sharp left+right nav icons
|
0.73: Add sharp left+right nav icons
|
||||||
0.74: Add option for driving on left (affects roundabout icons in navigation)
|
0.74: Add option for driving on left (affects roundabout icons in navigation)
|
||||||
0.75: Handle text with images in messages list by just displaying the first line
|
0.75: Handle text with images in messages list by just displaying the first line
|
||||||
|
0.76: Swipe up/down on a shown message to show the next newer/older message.
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ When a message is shown, you'll see a screen showing the message title and text.
|
||||||
* The 'back-arrow' button (or physical button on Bangle.js 2) goes back to Messages, marking the current message as read.
|
* The 'back-arrow' button (or physical button on Bangle.js 2) goes back to Messages, marking the current message as read.
|
||||||
* The top-left icon shows more options, for instance deleting the message of marking unread
|
* The top-left icon shows more options, for instance deleting the message of marking unread
|
||||||
* On Bangle.js 2 you can tap on the message body to view a scrollable version of the title and text (or can use the top-left icon + `View Message`)
|
* On Bangle.js 2 you can tap on the message body to view a scrollable version of the title and text (or can use the top-left icon + `View Message`)
|
||||||
|
- On Bangle.js 2 swipe up/down to show newer/older message
|
||||||
* If shown, the 'tick' button:
|
* If shown, the 'tick' button:
|
||||||
* **Android** opens the notification on the phone
|
* **Android** opens the notification on the phone
|
||||||
* **iOS** responds positively to the notification (accept call/etc)
|
* **iOS** responds positively to the notification (accept call/etc)
|
||||||
|
|
|
@ -289,7 +289,8 @@ function showMessageSettings(msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMessage(msgid) {
|
function showMessage(msgid) {
|
||||||
var msg = MESSAGES.find(m=>m.id==msgid);
|
let idx = MESSAGES.findIndex(m=>m.id==msgid);
|
||||||
|
var msg = MESSAGES[idx];
|
||||||
if (updateLabelsInterval) {
|
if (updateLabelsInterval) {
|
||||||
clearInterval(updateLabelsInterval);
|
clearInterval(updateLabelsInterval);
|
||||||
updateLabelsInterval=undefined;
|
updateLabelsInterval=undefined;
|
||||||
|
@ -389,9 +390,11 @@ function showMessage(msgid) {
|
||||||
{type:"h",fillx:1, c: footer}
|
{type:"h",fillx:1, c: footer}
|
||||||
]},{back:goBack});
|
]},{back:goBack});
|
||||||
|
|
||||||
Bangle.swipeHandler = lr => {
|
Bangle.swipeHandler = (lr,ud) => {
|
||||||
if (lr>0 && posHandler) posHandler();
|
if (lr>0 && posHandler) posHandler();
|
||||||
if (lr<0 && negHandler) negHandler();
|
if (lr<0 && negHandler) negHandler();
|
||||||
|
if (ud>0 && idx<MESSAGES.length-1) showMessage(MESSAGES[idx+1].id);
|
||||||
|
if (ud<0 && idx>0) showMessage(MESSAGES[idx-1].id);
|
||||||
};
|
};
|
||||||
Bangle.on("swipe", Bangle.swipeHandler);
|
Bangle.on("swipe", Bangle.swipeHandler);
|
||||||
g.reset().clearRect(Bangle.appRect);
|
g.reset().clearRect(Bangle.appRect);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "messagegui",
|
"id": "messagegui",
|
||||||
"name": "Message UI",
|
"name": "Message UI",
|
||||||
"shortName": "Messages",
|
"shortName": "Messages",
|
||||||
"version": "0.75",
|
"version": "0.76",
|
||||||
"description": "Default app to display notifications from iOS and Gadgetbridge/Android",
|
"description": "Default app to display notifications from iOS and Gadgetbridge/Android",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
|
|
|
@ -6,3 +6,4 @@
|
||||||
0.06: Support fastloading
|
0.06: Support fastloading
|
||||||
0.07: Fix fastloading support - ensure drag handler's restored after
|
0.07: Fix fastloading support - ensure drag handler's restored after
|
||||||
menu display/fastload removes it
|
menu display/fastload removes it
|
||||||
|
0.08: Add setting for initial page to display
|
||||||
|
|
|
@ -78,7 +78,7 @@ function drawTimers() {
|
||||||
}, 1000 - (timers[idx].t % 1000));
|
}, 1000 - (timers[idx].t % 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
E.showScroller({
|
const s = E.showScroller({
|
||||||
h : 40, c : timers.length+2,
|
h : 40, c : timers.length+2,
|
||||||
back : function() {load();},
|
back : function() {load();},
|
||||||
draw : (idx, r) => {
|
draw : (idx, r) => {
|
||||||
|
@ -138,7 +138,7 @@ function timerMenu(idx) {
|
||||||
}, 1000 - (a.t % 1000));
|
}, 1000 - (a.t % 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
E.showScroller({
|
const s = E.showScroller({
|
||||||
h : 40, c : 5,
|
h : 40, c : 5,
|
||||||
back : function() {
|
back : function() {
|
||||||
clearInt();
|
clearInt();
|
||||||
|
@ -328,9 +328,22 @@ function editTimer(idx, a) {
|
||||||
setUI();
|
setUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readJson() {
|
||||||
|
let json = require("Storage").readJSON("multitimer.json", true) || {};
|
||||||
|
|
||||||
|
if (Array.isArray(json)) {
|
||||||
|
// old format, convert
|
||||||
|
json = { sw: json };
|
||||||
|
require("Storage").writeJSON("multitimer.json", json);
|
||||||
|
}
|
||||||
|
if (!json.sw) json.sw = [];
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
function drawSw() {
|
function drawSw() {
|
||||||
layer = 1;
|
layer = 1;
|
||||||
const sw = require("Storage").readJSON("multitimer.json", true) || [];
|
const sw = readJson().sw;
|
||||||
|
|
||||||
function updateTimers(idx) {
|
function updateTimers(idx) {
|
||||||
if (!timerInt1[idx]) timerInt1[idx] = setTimeout(function() {
|
if (!timerInt1[idx]) timerInt1[idx] = setTimeout(function() {
|
||||||
|
@ -341,7 +354,7 @@ function drawSw() {
|
||||||
}, 1000 - (sw[idx].t % 1000));
|
}, 1000 - (sw[idx].t % 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
E.showScroller({
|
const s = E.showScroller({
|
||||||
h : 40, c : sw.length+2,
|
h : 40, c : sw.length+2,
|
||||||
back : function() {load();},
|
back : function() {load();},
|
||||||
draw : (idx, r) => {
|
draw : (idx, r) => {
|
||||||
|
@ -382,12 +395,13 @@ function drawSw() {
|
||||||
|
|
||||||
function swMenu(idx, a) {
|
function swMenu(idx, a) {
|
||||||
layer = -1;
|
layer = -1;
|
||||||
const sw = require("Storage").readJSON("multitimer.json", true) || [];
|
const json = readJson();
|
||||||
|
const sw = json.sw;
|
||||||
if (sw[idx]) a = sw[idx];
|
if (sw[idx]) a = sw[idx];
|
||||||
else {
|
else {
|
||||||
a = {"t" : 0, "on" : false, "msg" : ""};
|
a = {"t" : 0, "on" : false, "msg" : ""};
|
||||||
sw[idx] = a;
|
sw[idx] = a;
|
||||||
require("Storage").writeJSON("multitimer.json", sw);
|
require("Storage").writeJSON("multitimer.json", json);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimer() {
|
function updateTimer() {
|
||||||
|
@ -408,7 +422,7 @@ function swMenu(idx, a) {
|
||||||
}
|
}
|
||||||
else delete a.msg;
|
else delete a.msg;
|
||||||
sw[idx] = a;
|
sw[idx] = a;
|
||||||
require("Storage").writeJSON("multitimer.json", sw);
|
require("Storage").writeJSON("multitimer.json", json);
|
||||||
swMenu(idx, a);
|
swMenu(idx, a);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -420,7 +434,7 @@ function swMenu(idx, a) {
|
||||||
setUI();
|
setUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
E.showScroller({
|
const s = E.showScroller({
|
||||||
h : 40, c : 5,
|
h : 40, c : 5,
|
||||||
back : function() {
|
back : function() {
|
||||||
clearInt();
|
clearInt();
|
||||||
|
@ -458,7 +472,7 @@ function swMenu(idx, a) {
|
||||||
select : (i) => {
|
select : (i) => {
|
||||||
|
|
||||||
function saveAndReload() {
|
function saveAndReload() {
|
||||||
require("Storage").writeJSON("multitimer.json", sw);
|
require("Storage").writeJSON("multitimer.json", json);
|
||||||
s.draw();
|
s.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,5 +721,17 @@ function onDrag(e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawTimers();
|
switch (readJson().initialScreen) {
|
||||||
|
case 1:
|
||||||
|
drawSw();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
drawAlarms();
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
case undefined:
|
||||||
|
default:
|
||||||
|
drawTimers();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "multitimer",
|
"id": "multitimer",
|
||||||
"name": "Multi Timer",
|
"name": "Multi Timer",
|
||||||
"version": "0.07",
|
"version": "0.08",
|
||||||
"description": "Set timers and chronographs (stopwatches) and watch them count down in real time. Pause, create, edit, and delete timers and chronos, and add custom labels/messages. Also sets alarms.",
|
"description": "Set timers and chronographs (stopwatches) and watch them count down in real time. Pause, create, edit, and delete timers and chronos, and add custom labels/messages. Also sets alarms.",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"screenshots": [
|
"screenshots": [
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
{"name":"multitimer.app.js","url":"app.js"},
|
{"name":"multitimer.app.js","url":"app.js"},
|
||||||
{"name":"multitimer.boot.js","url":"boot.js"},
|
{"name":"multitimer.boot.js","url":"boot.js"},
|
||||||
{"name":"multitimer.alarm.js","url":"alarm.js"},
|
{"name":"multitimer.alarm.js","url":"alarm.js"},
|
||||||
|
{"name":"multitimer.settings.js","url":"settings.js"},
|
||||||
{"name":"multitimer.img","url":"app-icon.js","evaluate":true}
|
{"name":"multitimer.img","url":"app-icon.js","evaluate":true}
|
||||||
],
|
],
|
||||||
"data": [{"name":"multitimer.json"}],
|
"data": [{"name":"multitimer.json"}],
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
(function(back) {
|
||||||
|
const file = "multitimer.json";
|
||||||
|
let json = require('Storage').readJSON(file, true) || {};
|
||||||
|
if (Array.isArray(json)) {
|
||||||
|
// old format, convert
|
||||||
|
json = { sw: json };
|
||||||
|
}
|
||||||
|
if (!json.sw) json.sw = [];
|
||||||
|
|
||||||
|
function writeSettings() {
|
||||||
|
require('Storage').writeJSON(file, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
const screens = ["Timers", "Chronos", "Alarms"];
|
||||||
|
|
||||||
|
E.showMenu({
|
||||||
|
"": {
|
||||||
|
"title": "multitimer"
|
||||||
|
},
|
||||||
|
"< Back": back,
|
||||||
|
"Initial screen": {
|
||||||
|
value: json.initialScreen || 0,
|
||||||
|
min: 0,
|
||||||
|
max: screens.length - 1,
|
||||||
|
format: v => screens[v],
|
||||||
|
onchange: v => {
|
||||||
|
json.initialScreen = v;
|
||||||
|
writeSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
|
@ -85,7 +85,7 @@ function novaOpenEyes(speed, white, animation) {
|
||||||
scale: 2.2
|
scale: 2.2
|
||||||
});
|
});
|
||||||
}, speed * 5);
|
}, speed * 5);
|
||||||
} else {}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
g.drawImage(novaEyesStage4(), -10, -10, {
|
g.drawImage(novaEyesStage4(), -10, -10, {
|
||||||
|
@ -126,7 +126,7 @@ function novaOpenEyes(speed, white, animation) {
|
||||||
});
|
});
|
||||||
open = true;
|
open = true;
|
||||||
}, speed * 5);
|
}, speed * 5);
|
||||||
} else {}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ function novaCloseEyes(speed, white, animation) {
|
||||||
g.drawImage(novaEyesStage0(), -10, -10, {
|
g.drawImage(novaEyesStage0(), -10, -10, {
|
||||||
scale: 2.2
|
scale: 2.2
|
||||||
});
|
});
|
||||||
} else {}
|
}
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
g.drawImage(novaEyesStage1(), -10, -10, {
|
g.drawImage(novaEyesStage1(), -10, -10, {
|
||||||
scale: 2.2
|
scale: 2.2
|
||||||
|
@ -164,7 +164,7 @@ function novaCloseEyes(speed, white, animation) {
|
||||||
g.drawImage(novaEyesWhiteStage0(), -10, -10, {
|
g.drawImage(novaEyesWhiteStage0(), -10, -10, {
|
||||||
scale: 2.2
|
scale: 2.2
|
||||||
});
|
});
|
||||||
} else {}
|
}
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
timedraw(true);
|
timedraw(true);
|
||||||
g.drawImage(novaEyesTransStage1(), -10, -10, {
|
g.drawImage(novaEyesTransStage1(), -10, -10, {
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
0.04: Update cards to draw rounded on newer firmware. Make sure in-game menu can't be pulled up during end of game.
|
0.04: Update cards to draw rounded on newer firmware. Make sure in-game menu can't be pulled up during end of game.
|
||||||
0.05: add confirmation prompt to new game to prevent fat fingering new game during existing one.
|
0.05: add confirmation prompt to new game to prevent fat fingering new game during existing one.
|
||||||
0.06: fix AI logic typo and add prompt to show what AI played each turn.
|
0.06: fix AI logic typo and add prompt to show what AI played each turn.
|
||||||
0.07: Minor code improvements
|
0.07: Minor code improvements.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "Red 7 Card Game",
|
"name": "Red 7 Card Game",
|
||||||
"shortName" : "Red 7",
|
"shortName" : "Red 7",
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
"version": "0.07",
|
"version":"0.07",
|
||||||
"description": "An implementation of the card game Red 7 for your watch. Play against the AI and be the last player still in the game to win!",
|
"description": "An implementation of the card game Red 7 for your watch. Play against the AI and be the last player still in the game to win!",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"supports":["BANGLEJS2"],
|
"supports":["BANGLEJS2"],
|
||||||
|
|
|
@ -486,8 +486,7 @@ function canPlay(hand, palette, otherPalette) {
|
||||||
} else {
|
} else {
|
||||||
//Check if any palette play can win with rule.
|
//Check if any palette play can win with rule.
|
||||||
for(let h of hand.handCards) {
|
for(let h of hand.handCards) {
|
||||||
if(h === c) {}
|
if(h !== c) {
|
||||||
else {
|
|
||||||
clonePalette.addCard(c);
|
clonePalette.addCard(c);
|
||||||
if(isWinningCombo(c, clonePalette, otherPalette)) {
|
if(isWinningCombo(c, clonePalette, otherPalette)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -531,8 +530,7 @@ class AI {
|
||||||
} else {
|
} else {
|
||||||
//Check if any palette play can win with rule.
|
//Check if any palette play can win with rule.
|
||||||
for(let h of this.hand.handCards) {
|
for(let h of this.hand.handCards) {
|
||||||
if(h === c) {}
|
if(h !== c) {
|
||||||
else {
|
|
||||||
clonePalette.addCard(h);
|
clonePalette.addCard(h);
|
||||||
if(isWinningCombo(c, clonePalette, otherPalette)) {
|
if(isWinningCombo(c, clonePalette, otherPalette)) {
|
||||||
ruleStack.addCard(c);
|
ruleStack.addCard(c);
|
||||||
|
|
|
@ -101,7 +101,8 @@ function getData() {
|
||||||
uploadBtn.disabled = true;
|
uploadBtn.disabled = true;
|
||||||
|
|
||||||
Util.showModal("Loading...");
|
Util.showModal("Loading...");
|
||||||
Util.readStorageJSON(repJson, reps => {
|
Util.readStorageJSON(repJson, reps_ => {
|
||||||
|
reps = reps_;
|
||||||
Util.hideModal();
|
Util.hideModal();
|
||||||
for(const rep of reps){
|
for(const rep of reps){
|
||||||
renderRep(rep);
|
renderRep(rep);
|
||||||
|
|
|
@ -23,3 +23,5 @@
|
||||||
0.20: Alarm dismiss and snooze events
|
0.20: Alarm dismiss and snooze events
|
||||||
0.21: Fix crash in clock_info
|
0.21: Fix crash in clock_info
|
||||||
0.22: Dated event repeat option
|
0.22: Dated event repeat option
|
||||||
|
0.23: Allow buzzing forever when an alarm fires
|
||||||
|
0.24: Emit alarmReload when alarms change (used by widalarm)
|
||||||
|
|
|
@ -14,10 +14,10 @@ Global Settings
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
- `Unlock at Buzz` - If `Yes` the alarm/timer will unlock the watch
|
- `Unlock at Buzz` - If `Yes` the alarm/timer will unlock the watch
|
||||||
|
- `Delete Expired Timers` - Default for whether expired timers are removed after firing.
|
||||||
- `Default Auto Snooze` - Default _Auto Snooze_ value for newly created alarms (_Alarms_ only)
|
- `Default Auto Snooze` - Default _Auto Snooze_ value for newly created alarms (_Alarms_ only)
|
||||||
- `Default Snooze` - Default _Snooze_ value for newly created alarms/timers
|
- `Default Snooze` - Default _Snooze_ value for newly created alarms/timers
|
||||||
- `Default Repeat` - Default _Repeat_ value for newly created alarms (_Alarms_ only)
|
- `Buzz Count` - The number of buzzes before the watch goes silent, or "forever" to buzz until stopped.
|
||||||
- `Buzz Count` - The number of buzzes before the watch goes silent
|
|
||||||
- `Buzz Interval` - The interval between one buzz and the next
|
- `Buzz Interval` - The interval between one buzz and the next
|
||||||
- `Default Alarm/Timer Pattern` - Default vibration pattern for newly created alarms/timers
|
- `Default Alarm/Timer Pattern` - Default vibration pattern for newly created alarms/timers
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,26 @@
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||||
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
||||||
|
<style>
|
||||||
|
.multi-select {
|
||||||
|
/* e.g. day <select> */
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.single-row {
|
||||||
|
/* no border between single rowspans */
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-center {
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-summary {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<script src="../../core/lib/interface.js"></script>
|
<script src="../../core/lib/interface.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ical.js/1.5.0/ical.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ical.js/1.5.0/ical.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
@ -115,15 +135,17 @@ function renderAlarm(alarm, exists) {
|
||||||
const localDate = alarm.date ? dateFromAlarm(alarm) : null;
|
const localDate = alarm.date ? dateFromAlarm(alarm) : null;
|
||||||
|
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
|
const tr2 = document.createElement('tr');
|
||||||
tr.classList.add('event-row');
|
tr.classList.add('event-row');
|
||||||
tr.dataset.uid = alarm.id;
|
tr.dataset.uid = alarm.id;
|
||||||
|
|
||||||
const tdType = document.createElement('td');
|
const tdType = document.createElement('td');
|
||||||
tdType.type = "text";
|
tdType.type = "text";
|
||||||
tdType.classList.add('event-summary');
|
tdType.classList.add('event-summary');
|
||||||
tr.appendChild(tdType);
|
|
||||||
const inputTime = document.createElement('input');
|
const inputTime = document.createElement('input');
|
||||||
|
let type;
|
||||||
if (localDate) {
|
if (localDate) {
|
||||||
tdType.textContent = "Event";
|
type = "Event";
|
||||||
inputTime.type = "datetime-local";
|
inputTime.type = "datetime-local";
|
||||||
inputTime.value = localDate.toISOString().slice(0,16);
|
inputTime.value = localDate.toISOString().slice(0,16);
|
||||||
inputTime.onchange = (e => {
|
inputTime.onchange = (e => {
|
||||||
|
@ -139,18 +161,19 @@ function renderAlarm(alarm, exists) {
|
||||||
inputTime.value = `${hours}:${mins}:${secs}`;
|
inputTime.value = `${hours}:${mins}:${secs}`;
|
||||||
|
|
||||||
if (alarm.timer) {
|
if (alarm.timer) {
|
||||||
tdType.textContent = "Timer";
|
type = "Timer";
|
||||||
inputTime.onchange = e => {
|
inputTime.onchange = e => {
|
||||||
alarm.timer = hmsToMs(inputTime.value);
|
alarm.timer = hmsToMs(inputTime.value);
|
||||||
// alarm.t is set on upload
|
// alarm.t is set on upload
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
tdType.textContent = "Alarm";
|
type = "Alarm";
|
||||||
inputTime.onchange = e => {
|
inputTime.onchange = e => {
|
||||||
alarm.t = hmsToMs(inputTime.value);
|
alarm.t = hmsToMs(inputTime.value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tdType.textContent = type;
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
const asterisk = document.createElement('sup');
|
const asterisk = document.createElement('sup');
|
||||||
asterisk.textContent = '*';
|
asterisk.textContent = '*';
|
||||||
|
@ -160,11 +183,33 @@ function renderAlarm(alarm, exists) {
|
||||||
inputTime.classList.add('form-input');
|
inputTime.classList.add('form-input');
|
||||||
inputTime.dataset.uid = alarm.id;
|
inputTime.dataset.uid = alarm.id;
|
||||||
const tdTime = document.createElement('td');
|
const tdTime = document.createElement('td');
|
||||||
tr.appendChild(tdTime);
|
|
||||||
tdTime.appendChild(inputTime);
|
tdTime.appendChild(inputTime);
|
||||||
|
|
||||||
|
let tdDays;
|
||||||
|
if (type === "Alarm") {
|
||||||
|
tdDays = document.createElement('td');
|
||||||
|
const selectDays = document.createElement('select');
|
||||||
|
selectDays.multiple = true;
|
||||||
|
selectDays.classList.add('form-input', 'multi-select');
|
||||||
|
selectDays.dataset.uid = alarm.id;
|
||||||
|
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||||
|
const options = days.map((day, i) => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = day;
|
||||||
|
option.text = day;
|
||||||
|
option.selected = alarm.dow & (1 << i);
|
||||||
|
if(day !== "Sun")
|
||||||
|
selectDays.appendChild(option);
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
selectDays.appendChild(options.find(o => o.text === "Sun"));
|
||||||
|
selectDays.onchange = (e => {
|
||||||
|
alarm.dow = options.reduce((bits, opt, i) => bits | (opt.selected ? 1 << i : 0), 0);
|
||||||
|
});
|
||||||
|
tdDays.appendChild(selectDays);
|
||||||
|
}
|
||||||
|
|
||||||
const tdSummary = document.createElement('td');
|
const tdSummary = document.createElement('td');
|
||||||
tr.appendChild(tdSummary);
|
|
||||||
const inputSummary = document.createElement('input');
|
const inputSummary = document.createElement('input');
|
||||||
inputSummary.type = "text";
|
inputSummary.type = "text";
|
||||||
inputSummary.classList.add('event-summary');
|
inputSummary.classList.add('event-summary');
|
||||||
|
@ -181,9 +226,8 @@ function renderAlarm(alarm, exists) {
|
||||||
inputSummary.onchange();
|
inputSummary.onchange();
|
||||||
|
|
||||||
const tdOptions = document.createElement('td');
|
const tdOptions = document.createElement('td');
|
||||||
tr.appendChild(tdOptions);
|
|
||||||
|
|
||||||
const onOffCheck = document.createElement('input');
|
const onOffCheck = document.createElement('input');
|
||||||
|
tdOptions.classList.add('btn-center');
|
||||||
onOffCheck.type = 'checkbox';
|
onOffCheck.type = 'checkbox';
|
||||||
onOffCheck.checked = alarm.on;
|
onOffCheck.checked = alarm.on;
|
||||||
onOffCheck.onchange = e => {
|
onOffCheck.onchange = e => {
|
||||||
|
@ -199,8 +243,6 @@ function renderAlarm(alarm, exists) {
|
||||||
tdOptions.appendChild(onOff);
|
tdOptions.appendChild(onOff);
|
||||||
|
|
||||||
const tdInfo = document.createElement('td');
|
const tdInfo = document.createElement('td');
|
||||||
tr.appendChild(tdInfo);
|
|
||||||
|
|
||||||
const buttonDelete = document.createElement('button');
|
const buttonDelete = document.createElement('button');
|
||||||
buttonDelete.classList.add('btn');
|
buttonDelete.classList.add('btn');
|
||||||
buttonDelete.classList.add('btn-action');
|
buttonDelete.classList.add('btn-action');
|
||||||
|
@ -212,9 +254,22 @@ function renderAlarm(alarm, exists) {
|
||||||
buttonDelete.onclick = (e => {
|
buttonDelete.onclick = (e => {
|
||||||
alarms = alarms.filter(a => a !== alarm);
|
alarms = alarms.filter(a => a !== alarm);
|
||||||
document.getElementById('events').removeChild(tr);
|
document.getElementById('events').removeChild(tr);
|
||||||
|
document.getElementById('events').removeChild(tr2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tr.appendChild(tdTime); tdTime.colSpan = 3; tdTime.classList.add('single-row');
|
||||||
|
tr2.appendChild(tdType);
|
||||||
|
tr2.appendChild(tdOptions);
|
||||||
|
tr2.appendChild(tdInfo);
|
||||||
|
if (tdDays) {
|
||||||
|
tr.appendChild(tdDays); tdDays.rowSpan = 2;
|
||||||
|
} else {
|
||||||
|
tdSummary.colSpan = 2;
|
||||||
|
}
|
||||||
|
tr.appendChild(tdSummary); tdSummary.rowSpan = 2;
|
||||||
|
|
||||||
document.getElementById('events').appendChild(tr);
|
document.getElementById('events').appendChild(tr);
|
||||||
|
document.getElementById('events').appendChild(tr2);
|
||||||
document.getElementById('upload').disabled = false;
|
document.getElementById('upload').disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,11 +373,9 @@ function onInit() {
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Type</th>
|
<th colspan="3">Time & Options</th>
|
||||||
<th>Date/Time</th>
|
<th>Days</th>
|
||||||
<th>Summary</th>
|
<th>Summary</th>
|
||||||
<th>On?</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="events">
|
<tbody id="events">
|
||||||
|
|
|
@ -55,10 +55,7 @@ exports.getTimeToAlarm = function(alarm, time) {
|
||||||
/// Force a reload of the current alarms and widget
|
/// Force a reload of the current alarms and widget
|
||||||
exports.reload = function() {
|
exports.reload = function() {
|
||||||
eval(require("Storage").read("sched.boot.js"));
|
eval(require("Storage").read("sched.boot.js"));
|
||||||
if (global.WIDGETS && WIDGETS["alarm"]) {
|
Bangle.emit("alarmReload");
|
||||||
WIDGETS["alarm"].reload();
|
|
||||||
Bangle.drawWidgets();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
// Factory that creates a new alarm with default values
|
// Factory that creates a new alarm with default values
|
||||||
exports.newDefaultAlarm = function () {
|
exports.newDefaultAlarm = function () {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "sched",
|
"id": "sched",
|
||||||
"name": "Scheduler",
|
"name": "Scheduler",
|
||||||
"version": "0.22",
|
"version": "0.24",
|
||||||
"description": "Scheduling library for alarms and timers",
|
"description": "Scheduling library for alarms and timers",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"type": "scheduler",
|
"type": "scheduler",
|
||||||
|
|
|
@ -71,7 +71,7 @@ function showAlarm(alarm) {
|
||||||
|
|
||||||
const pattern = alarm.vibrate || (alarm.timer ? settings.defaultTimerPattern : settings.defaultAlarmPattern);
|
const pattern = alarm.vibrate || (alarm.timer ? settings.defaultTimerPattern : settings.defaultAlarmPattern);
|
||||||
require("buzz").pattern(pattern).then(() => {
|
require("buzz").pattern(pattern).then(() => {
|
||||||
if (buzzCount--) {
|
if (buzzCount == null || buzzCount--) {
|
||||||
setTimeout(buzz, settings.buzzIntervalMillis);
|
setTimeout(buzz, settings.buzzIntervalMillis);
|
||||||
} else if (alarm.as) { // auto-snooze
|
} else if (alarm.as) { // auto-snooze
|
||||||
buzzCount = settings.buzzCount;
|
buzzCount = settings.buzzCount;
|
||||||
|
|
|
@ -43,12 +43,13 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
/*LANG*/"Buzz Count": {
|
/*LANG*/"Buzz Count": {
|
||||||
value: settings.buzzCount,
|
value: settings.buzzCount == null ? 4 : settings.buzzCount,
|
||||||
min: 5,
|
min: 4,
|
||||||
max: 15,
|
max: 15,
|
||||||
step: 1,
|
step: 1,
|
||||||
|
format: v => v === 4 ? "Forever" : v,
|
||||||
onchange: v => {
|
onchange: v => {
|
||||||
settings.buzzCount = v;
|
settings.buzzCount = v === 4 ? null : v;
|
||||||
require("sched").setSettings(settings);
|
require("sched").setSettings(settings);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -78,3 +78,4 @@ of 'Select Clock'
|
||||||
0.67: Rename 'Wake on BTN1/Touch' to 'Wake on Button/Tap' on Bangle.js 2
|
0.67: Rename 'Wake on BTN1/Touch' to 'Wake on Button/Tap' on Bangle.js 2
|
||||||
0.68: Fix syntax error
|
0.68: Fix syntax error
|
||||||
0.69: Add option to wake on double tap
|
0.69: Add option to wake on double tap
|
||||||
|
0.70: Fix load() typo
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "setting",
|
"id": "setting",
|
||||||
"name": "Settings",
|
"name": "Settings",
|
||||||
"version": "0.69",
|
"version": "0.70",
|
||||||
"description": "A menu for setting up Bangle.js",
|
"description": "A menu for setting up Bangle.js",
|
||||||
"icon": "settings.png",
|
"icon": "settings.png",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system",
|
||||||
|
|
|
@ -641,7 +641,7 @@ function showUtilMenu() {
|
||||||
storage.writeJSON("setting.json",s);
|
storage.writeJSON("setting.json",s);
|
||||||
E.showAlert(/*LANG*/"Calibrated!").then(() => load("setting.app.js"));
|
E.showAlert(/*LANG*/"Calibrated!").then(() => load("setting.app.js"));
|
||||||
} else {
|
} else {
|
||||||
E.showAlert(/*LANG*/"Please charge Bangle.js for 3 hours and try again").then(() => load("settings.app.js"));
|
E.showAlert(/*LANG*/"Please charge Bangle.js for 3 hours and try again").then(() => load("setting.app.js"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,3 +11,4 @@
|
||||||
0.13: Prevent to stay in consecutive sleep if not worn, correct trigger calling, add trigger object itself as argument to the fn function
|
0.13: Prevent to stay in consecutive sleep if not worn, correct trigger calling, add trigger object itself as argument to the fn function
|
||||||
0.14: Add "Delete all logfiles before" to interface.html, display all logfiles in the interface
|
0.14: Add "Delete all logfiles before" to interface.html, display all logfiles in the interface
|
||||||
0.15: Issue newline before GB commands (solves issue with console.log and ignored commands)
|
0.15: Issue newline before GB commands (solves issue with console.log and ignored commands)
|
||||||
|
0.16: Only write logs if we have a non-empty log to write
|
||||||
|
|
|
@ -169,7 +169,8 @@ exports = {
|
||||||
// check if before this fortnight period
|
// check if before this fortnight period
|
||||||
if (firstDay < thisFirstDay) {
|
if (firstDay < thisFirstDay) {
|
||||||
// write log in seperate file
|
// write log in seperate file
|
||||||
require("Storage").writeJSON("sleeplog_" + this.msToFn(firstDay) + ".log", log);
|
if(log.length > 0)
|
||||||
|
require("Storage").writeJSON("sleeplog_" + this.msToFn(firstDay) + ".log", log);
|
||||||
// set last day as first
|
// set last day as first
|
||||||
firstDay = lastDay;
|
firstDay = lastDay;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id":"sleeplog",
|
"id":"sleeplog",
|
||||||
"name":"Sleep Log",
|
"name":"Sleep Log",
|
||||||
"shortName": "SleepLog",
|
"shortName": "SleepLog",
|
||||||
"version": "0.15",
|
"version": "0.16",
|
||||||
"description": "Log and view your sleeping habits. This app is using the built in movement calculation.",
|
"description": "Log and view your sleeping habits. This app is using the built in movement calculation.",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
|
|
|
@ -8,8 +8,6 @@ const hs = require('./heatshrink.js');
|
||||||
if (pc) {
|
if (pc) {
|
||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
var print=console.log;
|
var print=console.log;
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeDir(json) {
|
function writeDir(json) {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Swipe Inversion
|
||||||
|
|
||||||
|
Inverts swipe direction globally or per app, see settings. If global inversion is enabled, you can unselect the inversion per app and vice versa.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
Swipe Inversion can only invert directions on apps that use `Bangle.setUI` to set up swipes. Swipes set up with `Bangle.on("swipe", ...)` is currently not managed.
|
||||||
|
|
||||||
|
Swiping behavior that uses the `drag` event is not altered either.
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
- Try to handle swipes from `Bangle.on("swipe", ...)`
|
||||||
|
- alternatively refactor apps using that to only use `Bangle.setUI` for setting up swipes.
|
||||||
|
- Think about how to accommodate e.g. `touch` or `back` handlers set up in `Layout` library calls. They are removed if we refactor some `Bangle.on("swipe", ...)` to `Bangle.setUI`. (Is it maybe resolved if we call `Bangle.setUI` before the `Layout` call? - have not tested that yet.)
|
||||||
|
- Add bootloader apps and widgets to the list of apps that can be individually toggled in settings?
|
||||||
|
|
||||||
|
## Requests
|
||||||
|
|
||||||
|
Bug reports and feature requests should be done to the espruino/BangleApps github issue tracker.
|
||||||
|
|
||||||
|
## Creator
|
||||||
|
|
||||||
|
nxdefiant
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
After Width: | Height: | Size: 1.0 KiB |
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
const settings = Object.assign({
|
||||||
|
global: false,
|
||||||
|
apps: []
|
||||||
|
}, require("Storage").readJSON("swipeinv.json", true) || {});
|
||||||
|
|
||||||
|
if (settings.global || settings.apps.length > 0) {
|
||||||
|
const setURIOrig = Bangle.setUI;
|
||||||
|
Bangle.setUI = (mode, callback) => {
|
||||||
|
if (typeof mode === "object" && mode.swipe) {
|
||||||
|
if (settings.global ^ settings.apps.includes(global.__FILE__)) {
|
||||||
|
const origSwipeCb = mode.swipe;
|
||||||
|
mode.swipe = (dirLR, dirUD) => origSwipeCb(dirLR*-1, dirUD*-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return setURIOrig(mode, callback);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"id": "swipeinv",
|
||||||
|
"name": "Swipe inversion",
|
||||||
|
"shortName":"Swipe inv.",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Inverts swipe direction globally or per app, see settings. If global inversion is enabled, you can unselect the inversion per app and vice versa.",
|
||||||
|
"readme":"README.md",
|
||||||
|
"type": "bootloader",
|
||||||
|
"tags": "system",
|
||||||
|
"supports": ["BANGLEJS2"],
|
||||||
|
"storage": [
|
||||||
|
{"name":"swipeinv.boot.js","url":"boot.js"},
|
||||||
|
{"name":"swipeinv.settings.js","url":"settings.js"}
|
||||||
|
],
|
||||||
|
"data": [{"name":"swipeinv.json"}]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
(function(back) {
|
||||||
|
var FILE = "swipeinv.json";
|
||||||
|
// Load settings
|
||||||
|
const settings = Object.assign({
|
||||||
|
global: false,
|
||||||
|
apps: []
|
||||||
|
}, require("Storage").readJSON(FILE, true) || {});
|
||||||
|
|
||||||
|
function writeSettings() {
|
||||||
|
require('Storage').writeJSON(FILE, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appMenu() {
|
||||||
|
menu = {
|
||||||
|
"" : { "title" : /*LANG*/"Swipe inversion apps" },
|
||||||
|
"< Back" : () => { writeSettings(); mainMenu();}
|
||||||
|
};
|
||||||
|
require("Storage").list(/\.info$/).map(app=>require("Storage").readJSON(app,1)).filter(app => app.type === "app" || !app.type).sort((a,b) => {
|
||||||
|
if (a.name<b.name) return -1;
|
||||||
|
if (a.name>b.name) return 1;
|
||||||
|
return 0;
|
||||||
|
}).forEach(app => {
|
||||||
|
menu[app.name] = {
|
||||||
|
value: settings.apps.includes(app.src),
|
||||||
|
onchange: v => {
|
||||||
|
if (v) {
|
||||||
|
settings.apps.push(app.src);
|
||||||
|
} else {
|
||||||
|
const idx = settings.apps.indexOf(app.src);
|
||||||
|
if (idx !== -1) {
|
||||||
|
settings.apps.splice(idx, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mainMenu() {
|
||||||
|
E.showMenu({
|
||||||
|
"" : { "title" : /*LANG*/"Swipe inversion" },
|
||||||
|
"< Back" : () => back(),
|
||||||
|
|
||||||
|
/*LANG*/'Invert globally': {
|
||||||
|
value: !!settings.global,
|
||||||
|
onchange: v => {
|
||||||
|
settings.global = v;
|
||||||
|
writeSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*LANG*/'Select apps': () => appMenu()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mainMenu();
|
||||||
|
})
|
|
@ -972,8 +972,7 @@ function activateItem () {
|
||||||
animateToClock();
|
animateToClock();
|
||||||
break;
|
break;
|
||||||
case 0: // food
|
case 0: // food
|
||||||
if (tama.sleep) {
|
if (!tama.sleep) {
|
||||||
} else {
|
|
||||||
// evolution = 0;
|
// evolution = 0;
|
||||||
mode = 'food';
|
mode = 'food';
|
||||||
lightSelect = 0;
|
lightSelect = 0;
|
||||||
|
@ -983,8 +982,7 @@ function activateItem () {
|
||||||
mode = 'light';
|
mode = 'light';
|
||||||
break;
|
break;
|
||||||
case 2: // game
|
case 2: // game
|
||||||
if (tama.sleep) {
|
if (!tama.sleep) {
|
||||||
} else {
|
|
||||||
animateToGame();
|
animateToGame();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
0.01: Moved out of 'alarm' app
|
0.01: Moved out of 'alarm' app
|
||||||
|
0.02: Decouple reloading of widget when alarms change
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "widalarm",
|
"id": "widalarm",
|
||||||
"name": "Alarms Widget",
|
"name": "Alarms Widget",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "Displays an alarm icon in the widgets bar if any alarm is active",
|
"description": "Displays an alarm icon in the widgets bar if any alarm is active",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"type": "widget",
|
"type": "widget",
|
||||||
|
|
|
@ -6,3 +6,9 @@ WIDGETS["alarm"]={area:"tl",width:0,draw:function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
WIDGETS["alarm"].reload();
|
WIDGETS["alarm"].reload();
|
||||||
|
Bangle.on("alarmReload", () => {
|
||||||
|
if (WIDGETS["alarm"]) {
|
||||||
|
WIDGETS["alarm"].reload();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -12,3 +12,4 @@
|
||||||
0.08: Selectable font. Allow to disable hour padding.
|
0.08: Selectable font. Allow to disable hour padding.
|
||||||
0.09: Match draw() API e.g. to allow wid_edit to alter this widget
|
0.09: Match draw() API e.g. to allow wid_edit to alter this widget
|
||||||
0.10: Change 4x5 font to 6x8, teletext is now default font
|
0.10: Change 4x5 font to 6x8, teletext is now default font
|
||||||
|
0.11: Bugfix: handle changes in alarms (e.g. done without a load, such as via fastload)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "widalarmeta",
|
"id": "widalarmeta",
|
||||||
"name": "Alarm & Timer ETA",
|
"name": "Alarm & Timer ETA",
|
||||||
"shortName": "Alarm ETA",
|
"shortName": "Alarm ETA",
|
||||||
"version": "0.10",
|
"version": "0.11",
|
||||||
"description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h (configurable).",
|
"description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h (configurable).",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"type": "widget",
|
"type": "widget",
|
||||||
|
|
|
@ -19,7 +19,11 @@
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
function getNextAlarm(date) {
|
function getNextAlarm(date) {
|
||||||
const alarms = (require("Storage").readJSON("sched.json",1) || []).filter(alarm => alarm.on && alarm.hidden !== true);
|
const alarms = require("sched")
|
||||||
|
.getAlarms()
|
||||||
|
// more precise filtering is done using getTimeToAlarm() below
|
||||||
|
.filter(alarm => alarm.on && alarm.hidden !== true);
|
||||||
|
|
||||||
WIDGETS["widalarmeta"].numActiveAlarms = alarms.length;
|
WIDGETS["widalarmeta"].numActiveAlarms = alarms.length;
|
||||||
if (alarms.length > 0) {
|
if (alarms.length > 0) {
|
||||||
const times = alarms.map(alarm => require("sched").getTimeToAlarm(alarm, date) || Number.POSITIVE_INFINITY);
|
const times = alarms.map(alarm => require("sched").getTimeToAlarm(alarm, date) || Number.POSITIVE_INFINITY);
|
||||||
|
@ -116,16 +120,18 @@
|
||||||
} /* draw */
|
} /* draw */
|
||||||
|
|
||||||
if (config.maxhours > 0) {
|
if (config.maxhours > 0) {
|
||||||
// add your widget
|
|
||||||
WIDGETS["widalarmeta"]={
|
WIDGETS["widalarmeta"]={
|
||||||
area:"tl",
|
area:"tl",
|
||||||
width: 0, // hide by default = assume no timer
|
width: 0, // hide by default = assume no timer
|
||||||
draw:draw,
|
draw:draw,
|
||||||
reload: () => {
|
reload: function () {
|
||||||
|
this.nextAlarm = undefined;
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
g.clear();
|
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Bangle.on("alarmReload", () => WIDGETS["widalarmeta"].reload());
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -150,10 +150,13 @@ apps.forEach((app,appIdx) => {
|
||||||
} else {
|
} else {
|
||||||
var changeLog = fs.readFileSync(appDir+"ChangeLog").toString();
|
var changeLog = fs.readFileSync(appDir+"ChangeLog").toString();
|
||||||
var versions = changeLog.match(/\d+\.\d+:/g);
|
var versions = changeLog.match(/\d+\.\d+:/g);
|
||||||
if (!versions) ERROR(`No versions found in ${app.id} ChangeLog (${appDir}ChangeLog)`, {file:metadataFile});
|
if (!versions) {
|
||||||
var lastChangeLog = versions.pop().slice(0,-1);
|
ERROR(`No versions found in ${app.id} ChangeLog (${appDir}ChangeLog)`, {file:metadataFile});
|
||||||
if (lastChangeLog != app.version)
|
} else {
|
||||||
ERROR(`App ${app.id} app version (${app.version}) and ChangeLog (${lastChangeLog}) don't agree`, {file:appDirRelative+"ChangeLog", line:changeLog.split("\n").length-1});
|
var lastChangeLog = versions.pop().slice(0,-1);
|
||||||
|
if (lastChangeLog != app.version)
|
||||||
|
ERROR(`App ${app.id} app version (${app.version}) and ChangeLog (${lastChangeLog}) don't agree`, {file:appDirRelative+"ChangeLog", line:changeLog.split("\n").length-1});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!app.description) ERROR(`App ${app.id} has no description`, {file:metadataFile});
|
if (!app.description) ERROR(`App ${app.id} has no description`, {file:metadataFile});
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
{"code":"pt_PT","name":"Portuguese","url":"pt_PT.json"},
|
{"code":"pt_PT","name":"Portuguese","url":"pt_PT.json"},
|
||||||
{"code":"pt_BR","name":"Portuguese Brasil","url":"pt_BR.json"},
|
{"code":"pt_BR","name":"Portuguese Brasil","url":"pt_BR.json"},
|
||||||
{"code":"bg_BG","name":"Bulgarian","url":"bg_BG.json", "disabled":"Characters not in ISO Latin codepage"},
|
{"code":"bg_BG","name":"Bulgarian","url":"bg_BG.json", "disabled":"Characters not in ISO Latin codepage"},
|
||||||
{"code":"da_DA","name":"Danish","url":"da_DA.json"},
|
{"code":"da_DK","name":"Danish","url":"da_DK.json"},
|
||||||
{"code":"el_EL","name":"Greek","url":"el_EL.json", "disabled":"Characters not in ISO Latin codepage"},
|
{"code":"el_EL","name":"Greek","url":"el_EL.json", "disabled":"Characters not in ISO Latin codepage"},
|
||||||
{"code":"et_ET","name":"Estonian","url":"et_ET.json"},
|
{"code":"et_ET","name":"Estonian","url":"et_ET.json"},
|
||||||
{"code":"lt_LT","name":"Lithuanian","url":"lt_LT.json"},
|
{"code":"lt_LT","name":"Lithuanian","url":"lt_LT.json"},
|
||||||
|
|
|
@ -87,7 +87,7 @@ declare module Sched {
|
||||||
defaultSnoozeMillis: number,
|
defaultSnoozeMillis: number,
|
||||||
defaultAutoSnooze: boolean,
|
defaultAutoSnooze: boolean,
|
||||||
defaultDeleteExpiredTimers: boolean,
|
defaultDeleteExpiredTimers: boolean,
|
||||||
buzzCount: number,
|
buzzCount: number | null, // null means buzz forever
|
||||||
buzzIntervalMillis: number,
|
buzzIntervalMillis: number,
|
||||||
defaultAlarmPattern: string,
|
defaultAlarmPattern: string,
|
||||||
defaultTimerPattern: string,
|
defaultTimerPattern: string,
|
||||||
|
|