Merge remote-tracking branch 'upstream/master' into no-unused-vars
|
@ -149,7 +149,7 @@ module.exports = {
|
|||
],
|
||||
"no-constant-condition": "off",
|
||||
"no-delete-var": "off",
|
||||
"no-empty": "off",
|
||||
"no-empty": ["warn", { "allowEmptyCatch": true }],
|
||||
"no-global-assign": "off",
|
||||
"no-inner-declarations": "off",
|
||||
"no-prototype-builtins": "off",
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
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
|
||||
|
||||
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.
|
||||
|
||||
#ToDo
|
||||
Settings page, current status indicator.
|
||||
Current status indicator
|
||||
|
||||
## Creator
|
||||
|
||||
|
|
|
@ -6,11 +6,14 @@ let current = 0|bSettings.quiet;
|
|||
//1 alarms
|
||||
//2 silent
|
||||
|
||||
const dndSettings =
|
||||
require('Storage').readJSON("a_dndtoggle.settings.json", true) || {};
|
||||
|
||||
console.log("old: " + current);
|
||||
|
||||
switch (current) {
|
||||
case 0:
|
||||
bSettings.quiet = 2;
|
||||
bSettings.quiet = dndSettings.mode || 2;
|
||||
Bangle.buzz();
|
||||
setTimeout('Bangle.buzz();',500);
|
||||
break;
|
||||
|
@ -29,7 +32,7 @@ switch (current) {
|
|||
|
||||
console.log("new: " + bSettings.quiet);
|
||||
|
||||
E.showMessage(modeNames[current] + " -> " + modeNames[bSettings.quiet]);
|
||||
E.showMessage(modeNames[current] + " -> \n" + modeNames[bSettings.quiet]);
|
||||
setTimeout('exitApp();', 2000);
|
||||
|
||||
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
"id": "a_dndtoggle",
|
||||
"name": "a_dndtoggle - Toggle Quiet Mode of the watch",
|
||||
"shortName": "A_DND Toggle",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "Toggle Quiet Mode of the watch just by starting this app.",
|
||||
"icon": "a_dndtoggle.png",
|
||||
"type": "app",
|
||||
"tags": "tool",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"data" : [
|
||||
{"name":"a_dndtoggle.settings.json"}
|
||||
],
|
||||
"storage": [
|
||||
{"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}
|
||||
],
|
||||
"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) {
|
||||
secondInterval = setInterval(draw, 1000);
|
||||
draw(); // draw immediately
|
||||
}else{
|
||||
}
|
||||
});
|
||||
Bangle.on('lock',on=>{
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
0.06: Formatting
|
||||
0.07: Added potato GLaDOS and quote functionality when you tap her
|
||||
0.08: Fixed drawing issues with the quotes and added more
|
||||
0.09: Minor code improvements
|
||||
|
|
|
@ -270,8 +270,7 @@ function queueDraw() {
|
|||
|
||||
|
||||
function draw() {
|
||||
if (pause){}
|
||||
else{
|
||||
if (!pause){
|
||||
// get date
|
||||
var d = new Date();
|
||||
var da = d.toString().split(" ");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "aptsciclk",
|
||||
"name": "Apeture Science Clock",
|
||||
"shortName":"AptSci Clock",
|
||||
"version": "0.08",
|
||||
"version": "0.09",
|
||||
"description": "A clock based on the portal series",
|
||||
"icon": "app.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.02: Removed unneeded squares
|
||||
0.03: Added settings with fullscreen option
|
||||
0.04: Minor code improvements
|
||||
0.03: Added setting for fullscreen option
|
||||
0.04: Added settings to hide unused squares and show date
|
||||
0.05: Minor code improvements
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
var settings = Object.assign({
|
||||
fullscreen: false,
|
||||
fullscreen: false,
|
||||
hidesq: false,
|
||||
showdate: false,
|
||||
}, require('Storage').readJSON("binaryclk.json", true) || {});
|
||||
|
||||
function draw() {
|
||||
|
||||
var dt = new Date();
|
||||
var h = dt.getHours(), m = dt.getMinutes();
|
||||
var h = dt.getHours(), m = dt.getMinutes(), d = dt.getDate();
|
||||
const t = [];
|
||||
|
||||
t[0] = Math.floor(h/10);
|
||||
t[1] = Math.floor(h%10);
|
||||
t[2] = Math.floor(m/10);
|
||||
|
@ -17,25 +21,44 @@ function draw() {
|
|||
let i = 0;
|
||||
var gap = 8;
|
||||
var mgn = 20;
|
||||
|
||||
if (settings.fullscreen) {
|
||||
gap = 12;
|
||||
mgn = 0;
|
||||
}
|
||||
|
||||
const sq = 29;
|
||||
var pos = sq + gap;
|
||||
|
||||
for (let r = 3; r >= 0; r--) {
|
||||
for (let c = 0; c < 4; c++) {
|
||||
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 {
|
||||
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++;
|
||||
}
|
||||
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();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"id": "binaryclk",
|
||||
"name": "Bin Clock",
|
||||
"version": "0.04",
|
||||
"description": "Clock face to show binary time in 24 hr format",
|
||||
"version": "0.05",
|
||||
"description": "Clock face to show binary time in 24 hour format",
|
||||
"icon": "app-icon.png",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"type": "clock",
|
||||
|
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 16 KiB |
|
@ -2,6 +2,8 @@
|
|||
var FILE = "binaryclk.json";
|
||||
var settings = Object.assign({
|
||||
fullscreen: false,
|
||||
hidesq: false,
|
||||
showdate: false,
|
||||
}, require('Storage').readJSON(FILE, true) || {});
|
||||
|
||||
function writeSettings() {
|
||||
|
@ -16,7 +18,21 @@
|
|||
onchange: v => {
|
||||
settings.fullscreen = v;
|
||||
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.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.04: Minor code improvements
|
||||
0.04: Minor code improvements.
|
||||
|
|
|
@ -66,10 +66,8 @@ function moveEnemyPosition(){
|
|||
enemyPositonCenterX2 = 120;
|
||||
}else if((randomRoadPositionIndicator2 == 3)){
|
||||
enemyPositonCenterX2 = 155;
|
||||
}else if(level == 7||level == 8){
|
||||
|
||||
}
|
||||
}
|
||||
} // TODO: else if(level == 7)
|
||||
}
|
||||
|
||||
function collision(){
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
0.01: Simple app to display loyalty cards
|
||||
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.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
|
||||
const WHITE=-1
|
||||
const BLACK=0
|
||||
|
@ -89,6 +97,10 @@ function printLinearCode(binary) {
|
|||
}
|
||||
|
||||
function showCode(card) {
|
||||
// set to full bright when the setting is true
|
||||
if(settings.fullBrightness) {
|
||||
Bangle.setLCDBrightness(1);
|
||||
}
|
||||
widget_utils.hide();
|
||||
E.showScroller();
|
||||
// keeping it on rising edge would come back twice..
|
||||
|
@ -129,6 +141,10 @@ function showCode(card) {
|
|||
}
|
||||
|
||||
function showCard(card) {
|
||||
// reset brightness to old value after maxing it out
|
||||
if(settings.fullBrightness) {
|
||||
Bangle.setLCDBrightness(brightness);
|
||||
}
|
||||
var lines = [];
|
||||
var bodyFont = fontBig;
|
||||
if(!card) return;
|
||||
|
@ -206,4 +222,7 @@ function showList() {
|
|||
back : () => load()
|
||||
});
|
||||
}
|
||||
if(settings.fullBrightness) {
|
||||
loadBrightness();
|
||||
}
|
||||
showList();
|
||||
|
|
|
@ -14,6 +14,13 @@
|
|||
updateSettings();
|
||||
}
|
||||
},
|
||||
/*LANG*/"Full Brightness" : {
|
||||
value : !!settings.fullBrightness,
|
||||
onchange: v => {
|
||||
settings.fullBrightness = v;
|
||||
updateSettings();
|
||||
}
|
||||
}
|
||||
};
|
||||
E.showMenu(mainmenu);
|
||||
})
|
||||
|
|
|
@ -7,3 +7,4 @@
|
|||
Improve connection code
|
||||
0.07: Make Bangle.js 2 compatible
|
||||
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() {
|
||||
mySensor.screenInit = true;
|
||||
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;
|
||||
E.showMessage("Found device");
|
||||
return device.gatt.connect();
|
||||
|
@ -249,6 +249,7 @@ function connection_setup() {
|
|||
}).catch(function(e) {
|
||||
E.showMessage(e.toString(), "ERROR");
|
||||
console.log(e);
|
||||
setTimeout(connection_setup, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "cscsensor",
|
||||
"name": "Cycling speed sensor",
|
||||
"shortName": "CSCSensor",
|
||||
"version": "0.08",
|
||||
"version": "0.09",
|
||||
"description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch",
|
||||
"icon": "icons8-cycling-48.png",
|
||||
"tags": "outdoors,exercise,ble,bluetooth,bike,cycle,bicycle",
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
0.05: extraneous comments and code removed
|
||||
display improved
|
||||
now supports Adjust Clock widget, if installed
|
||||
0.06: Minor code improvements
|
||||
0.06: Minor code improvements
|
|
@ -223,9 +223,8 @@ function fixTime() {
|
|||
Bangle.on("GPS",function cb(g) {
|
||||
Bangle.setGPSPower(0,"time");
|
||||
Bangle.removeListener("GPS",cb);
|
||||
if (!g.time || (g.time.getFullYear()<2000) ||
|
||||
(g.time.getFullYear()>2200)) {
|
||||
} else {
|
||||
if (g.time && (g.time.getFullYear()>=2000) &&
|
||||
(g.time.getFullYear()<=2200)) {
|
||||
// We have a GPS time. Set time
|
||||
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.09: Add option for showing battery high mark
|
||||
0.10: Fix background color
|
||||
0.11: Minor code improvements
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "A Battery Widget (with percentage) - Hanks Mod",
|
||||
"shortName":"H Battery Widget",
|
||||
"icon": "widget.png",
|
||||
"version":"0.10",
|
||||
"version":"0.11",
|
||||
"type": "widget",
|
||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
var s = width - 1;
|
||||
var x = this.x;
|
||||
var y = this.y;
|
||||
if ((typeof x === 'undefined') || (typeof y === 'undefined')) {
|
||||
} else {
|
||||
if (x !== undefined && y !== undefined) {
|
||||
g.setBgColor(COLORS.white);
|
||||
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.04: Fix clkinfo -- use .get instead of .show
|
||||
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(){
|
||||
var date = new Date();
|
||||
return twoD(date.getDate()) + "." + twoD(date.getMonth());
|
||||
return twoD(date.getDate()) + "." + twoD(date.getMonth() + 1);
|
||||
}
|
||||
|
||||
function getDay(){
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "linuxclock",
|
||||
"name": "Linux Clock",
|
||||
"version": "0.05",
|
||||
"version": "0.06",
|
||||
"description": "A Linux inspired clock.",
|
||||
"readme": "README.md",
|
||||
"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" }
|
||||
},
|
||||
"ca_ES": {
|
||||
lang: "es_ES",
|
||||
lang: "ca_ES",
|
||||
icon: "🇪🇺",
|
||||
decimal_point: ",",
|
||||
thousands_sep: ".",
|
||||
currency_symbol: "€",
|
||||
|
@ -800,7 +801,7 @@ var locales = {
|
|||
temperature: "°C",
|
||||
ampm: { 0: "", 1: "" },
|
||||
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.",
|
||||
month: "gener,febrer,març,abril,maig,juny,juliol,agost,setembre,octobre,novembre,desembre",
|
||||
abday: "dg.,dl.,dt.,dc.,dj.,dv.,ds.",
|
||||
|
|
|
@ -101,4 +101,6 @@
|
|||
0.72: Nav message updastes don't automatically launch navigation menu unless they're new
|
||||
0.73: Add sharp left+right nav icons
|
||||
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 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 swipe up/down to show newer/older message
|
||||
* If shown, the 'tick' button:
|
||||
* **Android** opens the notification on the phone
|
||||
* **iOS** responds positively to the notification (accept call/etc)
|
||||
|
|
|
@ -289,7 +289,8 @@ function showMessageSettings(msg) {
|
|||
}
|
||||
|
||||
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) {
|
||||
clearInterval(updateLabelsInterval);
|
||||
updateLabelsInterval=undefined;
|
||||
|
@ -389,9 +390,11 @@ function showMessage(msgid) {
|
|||
{type:"h",fillx:1, c: footer}
|
||||
]},{back:goBack});
|
||||
|
||||
Bangle.swipeHandler = lr => {
|
||||
Bangle.swipeHandler = (lr,ud) => {
|
||||
if (lr>0 && posHandler) posHandler();
|
||||
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);
|
||||
g.reset().clearRect(Bangle.appRect);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "messagegui",
|
||||
"name": "Message UI",
|
||||
"shortName": "Messages",
|
||||
"version": "0.75",
|
||||
"version": "0.76",
|
||||
"description": "Default app to display notifications from iOS and Gadgetbridge/Android",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
0.06: Support fastloading
|
||||
0.07: Fix fastloading support - ensure drag handler's restored after
|
||||
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));
|
||||
}
|
||||
|
||||
E.showScroller({
|
||||
const s = E.showScroller({
|
||||
h : 40, c : timers.length+2,
|
||||
back : function() {load();},
|
||||
draw : (idx, r) => {
|
||||
|
@ -138,7 +138,7 @@ function timerMenu(idx) {
|
|||
}, 1000 - (a.t % 1000));
|
||||
}
|
||||
|
||||
E.showScroller({
|
||||
const s = E.showScroller({
|
||||
h : 40, c : 5,
|
||||
back : function() {
|
||||
clearInt();
|
||||
|
@ -328,9 +328,22 @@ function editTimer(idx, a) {
|
|||
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() {
|
||||
layer = 1;
|
||||
const sw = require("Storage").readJSON("multitimer.json", true) || [];
|
||||
const sw = readJson().sw;
|
||||
|
||||
function updateTimers(idx) {
|
||||
if (!timerInt1[idx]) timerInt1[idx] = setTimeout(function() {
|
||||
|
@ -341,7 +354,7 @@ function drawSw() {
|
|||
}, 1000 - (sw[idx].t % 1000));
|
||||
}
|
||||
|
||||
E.showScroller({
|
||||
const s = E.showScroller({
|
||||
h : 40, c : sw.length+2,
|
||||
back : function() {load();},
|
||||
draw : (idx, r) => {
|
||||
|
@ -382,12 +395,13 @@ function drawSw() {
|
|||
|
||||
function swMenu(idx, a) {
|
||||
layer = -1;
|
||||
const sw = require("Storage").readJSON("multitimer.json", true) || [];
|
||||
const json = readJson();
|
||||
const sw = json.sw;
|
||||
if (sw[idx]) a = sw[idx];
|
||||
else {
|
||||
a = {"t" : 0, "on" : false, "msg" : ""};
|
||||
sw[idx] = a;
|
||||
require("Storage").writeJSON("multitimer.json", sw);
|
||||
require("Storage").writeJSON("multitimer.json", json);
|
||||
}
|
||||
|
||||
function updateTimer() {
|
||||
|
@ -408,7 +422,7 @@ function swMenu(idx, a) {
|
|||
}
|
||||
else delete a.msg;
|
||||
sw[idx] = a;
|
||||
require("Storage").writeJSON("multitimer.json", sw);
|
||||
require("Storage").writeJSON("multitimer.json", json);
|
||||
swMenu(idx, a);
|
||||
});
|
||||
}
|
||||
|
@ -420,7 +434,7 @@ function swMenu(idx, a) {
|
|||
setUI();
|
||||
}
|
||||
|
||||
E.showScroller({
|
||||
const s = E.showScroller({
|
||||
h : 40, c : 5,
|
||||
back : function() {
|
||||
clearInt();
|
||||
|
@ -458,7 +472,7 @@ function swMenu(idx, a) {
|
|||
select : (i) => {
|
||||
|
||||
function saveAndReload() {
|
||||
require("Storage").writeJSON("multitimer.json", sw);
|
||||
require("Storage").writeJSON("multitimer.json", json);
|
||||
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",
|
||||
"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.",
|
||||
"icon": "app.png",
|
||||
"screenshots": [
|
||||
|
@ -16,6 +16,7 @@
|
|||
{"name":"multitimer.app.js","url":"app.js"},
|
||||
{"name":"multitimer.boot.js","url":"boot.js"},
|
||||
{"name":"multitimer.alarm.js","url":"alarm.js"},
|
||||
{"name":"multitimer.settings.js","url":"settings.js"},
|
||||
{"name":"multitimer.img","url":"app-icon.js","evaluate":true}
|
||||
],
|
||||
"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
|
||||
});
|
||||
}, speed * 5);
|
||||
} else {}
|
||||
}
|
||||
} else {
|
||||
|
||||
g.drawImage(novaEyesStage4(), -10, -10, {
|
||||
|
@ -126,7 +126,7 @@ function novaOpenEyes(speed, white, animation) {
|
|||
});
|
||||
open = true;
|
||||
}, speed * 5);
|
||||
} else {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ function novaCloseEyes(speed, white, animation) {
|
|||
g.drawImage(novaEyesStage0(), -10, -10, {
|
||||
scale: 2.2
|
||||
});
|
||||
} else {}
|
||||
}
|
||||
setTimeout(function() {
|
||||
g.drawImage(novaEyesStage1(), -10, -10, {
|
||||
scale: 2.2
|
||||
|
@ -164,7 +164,7 @@ function novaCloseEyes(speed, white, animation) {
|
|||
g.drawImage(novaEyesWhiteStage0(), -10, -10, {
|
||||
scale: 2.2
|
||||
});
|
||||
} else {}
|
||||
}
|
||||
setTimeout(function() {
|
||||
timedraw(true);
|
||||
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.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.07: Minor code improvements
|
||||
0.07: Minor code improvements.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Red 7 Card Game",
|
||||
"shortName" : "Red 7",
|
||||
"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!",
|
||||
"tags": "game",
|
||||
"supports":["BANGLEJS2"],
|
||||
|
|
|
@ -486,8 +486,7 @@ function canPlay(hand, palette, otherPalette) {
|
|||
} else {
|
||||
//Check if any palette play can win with rule.
|
||||
for(let h of hand.handCards) {
|
||||
if(h === c) {}
|
||||
else {
|
||||
if(h !== c) {
|
||||
clonePalette.addCard(c);
|
||||
if(isWinningCombo(c, clonePalette, otherPalette)) {
|
||||
return true;
|
||||
|
@ -531,8 +530,7 @@ class AI {
|
|||
} else {
|
||||
//Check if any palette play can win with rule.
|
||||
for(let h of this.hand.handCards) {
|
||||
if(h === c) {}
|
||||
else {
|
||||
if(h !== c) {
|
||||
clonePalette.addCard(h);
|
||||
if(isWinningCombo(c, clonePalette, otherPalette)) {
|
||||
ruleStack.addCard(c);
|
||||
|
|
|
@ -101,7 +101,8 @@ function getData() {
|
|||
uploadBtn.disabled = true;
|
||||
|
||||
Util.showModal("Loading...");
|
||||
Util.readStorageJSON(repJson, reps => {
|
||||
Util.readStorageJSON(repJson, reps_ => {
|
||||
reps = reps_;
|
||||
Util.hideModal();
|
||||
for(const rep of reps){
|
||||
renderRep(rep);
|
||||
|
|
|
@ -23,3 +23,5 @@
|
|||
0.20: Alarm dismiss and snooze events
|
||||
0.21: Fix crash in clock_info
|
||||
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
|
||||
- `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 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
|
||||
- `Buzz Count` - The number of buzzes before the watch goes silent, or "forever" to buzz until stopped.
|
||||
- `Buzz Interval` - The interval between one buzz and the next
|
||||
- `Default Alarm/Timer Pattern` - Default vibration pattern for newly created alarms/timers
|
||||
|
||||
|
|
|
@ -2,6 +2,26 @@
|
|||
<head>
|
||||
<link rel="stylesheet" href="../../css/spectre.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="https://cdnjs.cloudflare.com/ajax/libs/ical.js/1.5.0/ical.min.js"></script>
|
||||
<script>
|
||||
|
@ -115,15 +135,17 @@ function renderAlarm(alarm, exists) {
|
|||
const localDate = alarm.date ? dateFromAlarm(alarm) : null;
|
||||
|
||||
const tr = document.createElement('tr');
|
||||
const tr2 = document.createElement('tr');
|
||||
tr.classList.add('event-row');
|
||||
tr.dataset.uid = alarm.id;
|
||||
|
||||
const tdType = document.createElement('td');
|
||||
tdType.type = "text";
|
||||
tdType.classList.add('event-summary');
|
||||
tr.appendChild(tdType);
|
||||
const inputTime = document.createElement('input');
|
||||
let type;
|
||||
if (localDate) {
|
||||
tdType.textContent = "Event";
|
||||
type = "Event";
|
||||
inputTime.type = "datetime-local";
|
||||
inputTime.value = localDate.toISOString().slice(0,16);
|
||||
inputTime.onchange = (e => {
|
||||
|
@ -139,18 +161,19 @@ function renderAlarm(alarm, exists) {
|
|||
inputTime.value = `${hours}:${mins}:${secs}`;
|
||||
|
||||
if (alarm.timer) {
|
||||
tdType.textContent = "Timer";
|
||||
type = "Timer";
|
||||
inputTime.onchange = e => {
|
||||
alarm.timer = hmsToMs(inputTime.value);
|
||||
// alarm.t is set on upload
|
||||
};
|
||||
} else {
|
||||
tdType.textContent = "Alarm";
|
||||
type = "Alarm";
|
||||
inputTime.onchange = e => {
|
||||
alarm.t = hmsToMs(inputTime.value);
|
||||
};
|
||||
}
|
||||
}
|
||||
tdType.textContent = type;
|
||||
if (!exists) {
|
||||
const asterisk = document.createElement('sup');
|
||||
asterisk.textContent = '*';
|
||||
|
@ -160,11 +183,33 @@ function renderAlarm(alarm, exists) {
|
|||
inputTime.classList.add('form-input');
|
||||
inputTime.dataset.uid = alarm.id;
|
||||
const tdTime = document.createElement('td');
|
||||
tr.appendChild(tdTime);
|
||||
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');
|
||||
tr.appendChild(tdSummary);
|
||||
const inputSummary = document.createElement('input');
|
||||
inputSummary.type = "text";
|
||||
inputSummary.classList.add('event-summary');
|
||||
|
@ -181,9 +226,8 @@ function renderAlarm(alarm, exists) {
|
|||
inputSummary.onchange();
|
||||
|
||||
const tdOptions = document.createElement('td');
|
||||
tr.appendChild(tdOptions);
|
||||
|
||||
const onOffCheck = document.createElement('input');
|
||||
tdOptions.classList.add('btn-center');
|
||||
onOffCheck.type = 'checkbox';
|
||||
onOffCheck.checked = alarm.on;
|
||||
onOffCheck.onchange = e => {
|
||||
|
@ -199,8 +243,6 @@ function renderAlarm(alarm, exists) {
|
|||
tdOptions.appendChild(onOff);
|
||||
|
||||
const tdInfo = document.createElement('td');
|
||||
tr.appendChild(tdInfo);
|
||||
|
||||
const buttonDelete = document.createElement('button');
|
||||
buttonDelete.classList.add('btn');
|
||||
buttonDelete.classList.add('btn-action');
|
||||
|
@ -212,9 +254,22 @@ function renderAlarm(alarm, exists) {
|
|||
buttonDelete.onclick = (e => {
|
||||
alarms = alarms.filter(a => a !== alarm);
|
||||
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(tr2);
|
||||
document.getElementById('upload').disabled = false;
|
||||
}
|
||||
|
||||
|
@ -318,11 +373,9 @@ function onInit() {
|
|||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Date/Time</th>
|
||||
<th colspan="3">Time & Options</th>
|
||||
<th>Days</th>
|
||||
<th>Summary</th>
|
||||
<th>On?</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="events">
|
||||
|
|
|
@ -55,10 +55,7 @@ exports.getTimeToAlarm = function(alarm, time) {
|
|||
/// Force a reload of the current alarms and widget
|
||||
exports.reload = function() {
|
||||
eval(require("Storage").read("sched.boot.js"));
|
||||
if (global.WIDGETS && WIDGETS["alarm"]) {
|
||||
WIDGETS["alarm"].reload();
|
||||
Bangle.drawWidgets();
|
||||
}
|
||||
Bangle.emit("alarmReload");
|
||||
};
|
||||
// Factory that creates a new alarm with default values
|
||||
exports.newDefaultAlarm = function () {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "sched",
|
||||
"name": "Scheduler",
|
||||
"version": "0.22",
|
||||
"version": "0.24",
|
||||
"description": "Scheduling library for alarms and timers",
|
||||
"icon": "app.png",
|
||||
"type": "scheduler",
|
||||
|
|
|
@ -71,7 +71,7 @@ function showAlarm(alarm) {
|
|||
|
||||
const pattern = alarm.vibrate || (alarm.timer ? settings.defaultTimerPattern : settings.defaultAlarmPattern);
|
||||
require("buzz").pattern(pattern).then(() => {
|
||||
if (buzzCount--) {
|
||||
if (buzzCount == null || buzzCount--) {
|
||||
setTimeout(buzz, settings.buzzIntervalMillis);
|
||||
} else if (alarm.as) { // auto-snooze
|
||||
buzzCount = settings.buzzCount;
|
||||
|
|
|
@ -43,12 +43,13 @@
|
|||
},
|
||||
|
||||
/*LANG*/"Buzz Count": {
|
||||
value: settings.buzzCount,
|
||||
min: 5,
|
||||
value: settings.buzzCount == null ? 4 : settings.buzzCount,
|
||||
min: 4,
|
||||
max: 15,
|
||||
step: 1,
|
||||
format: v => v === 4 ? "Forever" : v,
|
||||
onchange: v => {
|
||||
settings.buzzCount = v;
|
||||
settings.buzzCount = v === 4 ? null : v;
|
||||
require("sched").setSettings(settings);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -77,4 +77,5 @@ of 'Select Clock'
|
|||
calibration was done.
|
||||
0.67: Rename 'Wake on BTN1/Touch' to 'Wake on Button/Tap' on Bangle.js 2
|
||||
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",
|
||||
"name": "Settings",
|
||||
"version": "0.69",
|
||||
"version": "0.70",
|
||||
"description": "A menu for setting up Bangle.js",
|
||||
"icon": "settings.png",
|
||||
"tags": "tool,system",
|
||||
|
|
|
@ -641,7 +641,7 @@ function showUtilMenu() {
|
|||
storage.writeJSON("setting.json",s);
|
||||
E.showAlert(/*LANG*/"Calibrated!").then(() => load("setting.app.js"));
|
||||
} 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"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -10,4 +10,5 @@
|
|||
0.12: Improve README, option to add functions triggered by status changes or time periods, remove old log (<0.10) conversion
|
||||
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.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
|
||||
if (firstDay < thisFirstDay) {
|
||||
// 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
|
||||
firstDay = lastDay;
|
||||
} else {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id":"sleeplog",
|
||||
"name":"Sleep Log",
|
||||
"shortName": "SleepLog",
|
||||
"version": "0.15",
|
||||
"version": "0.16",
|
||||
"description": "Log and view your sleeping habits. This app is using the built in movement calculation.",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
|
|
|
@ -8,8 +8,6 @@ const hs = require('./heatshrink.js');
|
|||
if (pc) {
|
||||
fs = require('fs');
|
||||
var print=console.log;
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
break;
|
||||
case 0: // food
|
||||
if (tama.sleep) {
|
||||
} else {
|
||||
if (!tama.sleep) {
|
||||
// evolution = 0;
|
||||
mode = 'food';
|
||||
lightSelect = 0;
|
||||
|
@ -983,8 +982,7 @@ function activateItem () {
|
|||
mode = 'light';
|
||||
break;
|
||||
case 2: // game
|
||||
if (tama.sleep) {
|
||||
} else {
|
||||
if (!tama.sleep) {
|
||||
animateToGame();
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
0.01: Moved out of 'alarm' app
|
||||
0.02: Decouple reloading of widget when alarms change
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "widalarm",
|
||||
"name": "Alarms Widget",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "Displays an alarm icon in the widgets bar if any alarm is active",
|
||||
"icon": "app.png",
|
||||
"type": "widget",
|
||||
|
|
|
@ -6,3 +6,9 @@ WIDGETS["alarm"]={area:"tl",width:0,draw:function() {
|
|||
}
|
||||
};
|
||||
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.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.11: Bugfix: handle changes in alarms (e.g. done without a load, such as via fastload)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "widalarmeta",
|
||||
"name": "Alarm & Timer 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).",
|
||||
"icon": "widget.png",
|
||||
"type": "widget",
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
loadSettings();
|
||||
|
||||
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;
|
||||
if (alarms.length > 0) {
|
||||
const times = alarms.map(alarm => require("sched").getTimeToAlarm(alarm, date) || Number.POSITIVE_INFINITY);
|
||||
|
@ -116,16 +120,18 @@
|
|||
} /* draw */
|
||||
|
||||
if (config.maxhours > 0) {
|
||||
// add your widget
|
||||
WIDGETS["widalarmeta"]={
|
||||
area:"tl",
|
||||
width: 0, // hide by default = assume no timer
|
||||
draw:draw,
|
||||
reload: () => {
|
||||
reload: function () {
|
||||
this.nextAlarm = undefined;
|
||||
|
||||
loadSettings();
|
||||
g.clear();
|
||||
Bangle.drawWidgets();
|
||||
},
|
||||
};
|
||||
|
||||
Bangle.on("alarmReload", () => WIDGETS["widalarmeta"].reload());
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -150,10 +150,13 @@ apps.forEach((app,appIdx) => {
|
|||
} else {
|
||||
var changeLog = fs.readFileSync(appDir+"ChangeLog").toString();
|
||||
var versions = changeLog.match(/\d+\.\d+:/g);
|
||||
if (!versions) ERROR(`No versions found in ${app.id} ChangeLog (${appDir}ChangeLog)`, {file:metadataFile});
|
||||
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 (!versions) {
|
||||
ERROR(`No versions found in ${app.id} ChangeLog (${appDir}ChangeLog)`, {file:metadataFile});
|
||||
} else {
|
||||
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});
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
{"code":"pt_PT","name":"Portuguese","url":"pt_PT.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":"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":"et_ET","name":"Estonian","url":"et_ET.json"},
|
||||
{"code":"lt_LT","name":"Lithuanian","url":"lt_LT.json"},
|
||||
|
|
|
@ -87,7 +87,7 @@ declare module Sched {
|
|||
defaultSnoozeMillis: number,
|
||||
defaultAutoSnooze: boolean,
|
||||
defaultDeleteExpiredTimers: boolean,
|
||||
buzzCount: number,
|
||||
buzzCount: number | null, // null means buzz forever
|
||||
buzzIntervalMillis: number,
|
||||
defaultAlarmPattern: string,
|
||||
defaultTimerPattern: string,
|
||||
|
|