Merge branch 'master' into icon-notifs
|
@ -4,4 +4,5 @@
|
|||
0.04: Obey system quiet mode
|
||||
0.05: Battery optimisation, add the pause option, bug fixes
|
||||
0.06: Add a temperature threshold to detect (and not alert) if the BJS isn't worn. Better support for the peoples using the app at night
|
||||
0.07: Fix bug on the cutting edge firmware
|
||||
0.07: Fix bug on the cutting edge firmware
|
||||
0.08: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Activity Reminder",
|
||||
"shortName":"Activity Reminder",
|
||||
"description": "A reminder to take short walks for the ones with a sedentary lifestyle",
|
||||
"version":"0.07",
|
||||
"version":"0.08",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
"tags": "tool,activity",
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
"< Back": () => back(),
|
||||
'Enable': {
|
||||
value: settings.enabled,
|
||||
format: v => v ? "Yes" : "No",
|
||||
onchange: v => {
|
||||
settings.enabled = v;
|
||||
activityreminder.writeSettings(settings);
|
||||
|
@ -38,9 +37,7 @@
|
|||
settings.maxInnactivityMin = v;
|
||||
activityreminder.writeSettings(settings);
|
||||
},
|
||||
format: x => {
|
||||
return x + " min";
|
||||
}
|
||||
format: x => x + "m"
|
||||
},
|
||||
'Dismiss delay': {
|
||||
value: settings.dismissDelayMin,
|
||||
|
@ -49,9 +46,7 @@
|
|||
settings.dismissDelayMin = v;
|
||||
activityreminder.writeSettings(settings);
|
||||
},
|
||||
format: x => {
|
||||
return x + " min";
|
||||
}
|
||||
format: x => x + "m"
|
||||
},
|
||||
'Pause delay': {
|
||||
value: settings.pauseDelayMin,
|
||||
|
@ -61,7 +56,7 @@
|
|||
activityreminder.writeSettings(settings);
|
||||
},
|
||||
format: x => {
|
||||
return x + " min";
|
||||
return x + "m";
|
||||
}
|
||||
},
|
||||
'Min steps': {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0.01: AdvCasio first version
|
|
@ -0,0 +1,62 @@
|
|||
# Adv Casio Clock
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/2981891/175355586-1dfc0d66-6555-4385-b124-1605fdb71a11.jpg" width="250" />
|
||||
|
||||
An over-engineered clock inspired by Casio watches.<br/>
|
||||
It has a dedicated timer, a scratchpad and can display the weather condition 4 days ahead.<br/>
|
||||
It uses a <a target="_blank" href="https://dotgreg.github.io/advCasioBangleClock/">custom web app</a> to update its content.<br/>
|
||||
Forked from the awesome Cassio Watch.<br/>
|
||||
|
||||
## Todo
|
||||
|
||||
- Improving quality of the background images, right now it is quite blurry.
|
||||
- Improving screenshots quality.
|
||||
- Improving web app look.
|
||||
- Improving bangle app performances (using functions for images and specialized array).
|
||||
|
||||
## Functionalities
|
||||
|
||||
- Current time
|
||||
- Current day and month
|
||||
- Footsteps
|
||||
- Battery
|
||||
- Simple Timer embedded
|
||||
- Weather forecast (7 days)
|
||||
- Scratchpad
|
||||
|
||||
## Screenshots
|
||||
Clock:<br/>
|
||||
<img src="https://user-images.githubusercontent.com/2981891/175519126-049caf93-73d0-4472-9650-33b28f80843c.jpg" width="250" />
|
||||
<img src="https://user-images.githubusercontent.com/2981891/175519128-96926e32-2165-4c61-9364-843440304bb9.jpg" width="250" />
|
||||
<img src="https://user-images.githubusercontent.com/2981891/175519130-4921073c-48fc-4c29-932d-d42acc3b395c.jpg" width="250" />
|
||||
|
||||
Web interface to update weather & scratchpad <br/>
|
||||
<a target="_blank" ref="https://dotgreg.github.io/advCasioBangleClock/">https://dotgreg.github.io/advCasioBangleClock</a>
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/2981891/175519121-851bb209-7192-40db-a014-490c344f7597.jpg" width="250" />
|
||||
|
||||
## Usage
|
||||
### How to update the tasks list / weather
|
||||
- you will need a <a target="_blank" href="https://openweathermap.org/price#weather">free openweathermap.org api key</a>.
|
||||
- go to https://dotgreg.github.io/advCasioBangleClock/
|
||||
- Alternatively you can install it on your own server/heroku/service/github pages, the web-app code is <a target="_blank" href="https://github.com/dotgreg/advCasioBangleClock/tree/master/web-app">here</a>
|
||||
- fill the location and the api key (it will be saved on your browser, no need to do it each time)
|
||||
- edit the scratchpad with what you want
|
||||
- click on sync
|
||||
- reload your clock!
|
||||
|
||||
### How to start/stop the timer
|
||||
- swipe up : add time (+5min)
|
||||
- swipe down : remove time (-5min)
|
||||
- swipe right : start timer
|
||||
- swipe left : stop timer
|
||||
|
||||
## Links
|
||||
### Issues, suggestions and bugtracker
|
||||
<a target="_blank" href="https://github.com/dotgreg/advCasioBangleClock/issues">https://github.com/dotgreg/advCasioBangleClock/issues</a>
|
||||
|
||||
### Code repository (bangle app and web app)
|
||||
<a target="_blank" href="https://github.com/dotgreg/advCasioBangleClock">https://github.com/dotgreg/advCasioBangleClock</a>
|
||||
|
||||
### Creator
|
||||
<a target="_blank" href="https://github.com/dotgreg">https://github.com/dotgreg</a>
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwghC/AH4A/AGsCmUQC6kf/8wC6k///wgEv//zD4PxAQIJBABP//4QBC4IcBh/yEQIXKgP/l4rBl/yGAMP/4iBKJUC/5gBIAQVBBAMR/8gC5IQBAAMQC4IVBFoMjAYIXNmAXBgYXCPgQAJl/xHwPwj/yn5kC/55BUxSlC+JiBVgQ5BUxiDBUIIXBIQQXBcCoA/AH4ADXAUgUAUQBAkPeoTDFgIHBAALQEA4XwC4IOEAAQRBbAQBBCAIgBEYMQC4TnEC4XyeQgBDAAMwC4pIDC4kDAgJLD//xC5QIBNQISCFYIZCC4aEBAQRCDAAPyl4hBOIh3Cn53GNgMRiKxGBAR5BAoYA/AH4A/AH4A5A"))
|
|
@ -0,0 +1,306 @@
|
|||
const storage = require('Storage');
|
||||
|
||||
require("Font6x12").add(Graphics);
|
||||
require("Font6x8").add(Graphics);
|
||||
require("Font8x12").add(Graphics);
|
||||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
|
||||
function bigThenSmall(big, small, x, y) {
|
||||
g.setFont("7x11Numeric7Seg", 2);
|
||||
g.drawString(big, x, y);
|
||||
x += g.stringWidth(big);
|
||||
g.setFont("8x12");
|
||||
g.drawString(small, x, y);
|
||||
}
|
||||
|
||||
function getClockBg() {
|
||||
return require("heatshrink").decompress(atob("icVgf/ABv8v4DBx4CB+PH8F+nAGB48fwEHBwXjxwqBuPH//+nAGBBwIjCAwI2D/wGBgIyDI4QGDwAGBHYX/4AGBn4UFEYQpCEYYpCAAMfMhP4FIgABwJ8OEBIA=="));
|
||||
}
|
||||
|
||||
|
||||
// sun, cloud, rain, thunder
|
||||
var iconsWeather = [
|
||||
require("heatshrink").decompress(atob("i8Ugf/ACcfA434BA/AAwsAv0/8F/BAcDwEHHIpECFI3wn4GC/gOC+PAGoXggEH/+ODQgXBGQv/wAbBBAnguEACIn4gfxI4JXFwJmG/kPBA3jSynw")), require("heatshrink").decompress(atob("i0Ugf/AEXggIGE/0A/kPBAmBCIN/A4Y8CgAICwEHBYoUE/ACCj4sDn4CBC4YyDwBrDCgYA3A")), require("heatshrink").decompress(atob("h8Rgf/AAuBAgf8h4FDCwM/AgPA/gFC/0HgEBBQPwnEfDoWAg4jC/gOCAoQmBAQXjFIV//8f//4IQP4j/+gAIB4EcHII4CAoI+DLQJXF/AA==")), require("heatshrink").decompress(atob("h0Pgf/AA8fAYX+g4EC8EBAgXADAeAgAECgAOC/wrCDQIOBBYfwgAaC/kAn4EB/EAv4aDHAeBIg38"))
|
||||
];
|
||||
|
||||
|
||||
function getBackgroundImage() {
|
||||
return require("heatshrink").decompress(atob("2GwghC/AH4A/AH4AMl////wAwURiQECgUzmcxBQQCBiYUBBARW+LAcCAgcPBYgFBkAIFG7kQiAKIiIKBgISOAAJBD//zKQfxK4vyAoMQCgn/ERBhBBYR5BAwR1DB4Y2DgYPCGIQRCCQcP+EfGJI0FEgRSCGAQCCX4JXCkAhDn4lI+HyK4YWBFIPzJYJXHAIMSK4cwJ4I3CAYMzA4cfcRMBdwytBK4i6FK4IUCMgYAEGIITBK4cCaAPwgJXB+fzK4sAgYtCK5EfA4pXR+AmBaIZYCK6KcCAwSjDEYXx/8vK5QRCK4kPK6cDkJREBIMBfgIrDK5svUAIQBAwIaCK4w+DK4YGBK7IaBboIuCK4gFCJwYBBiBCCCgQhHHYgGDgArBK5IGDAYMgJ4Xwn53BGgLVDmBXKAAinDLpJXCAAYhHR4YODn/wJIPyTYZXDE4RXD+ECNILIDAIPwj4xIAAYNCR4fyVIYLFA4KEBBAglKAGUCmcykEAiMQBIURBYM/BgIUEgcz+bTKAH4A/AH4A/AHP/AGY1d+BWCh5X/LCpW1K74fgG/5X/AH5X/K9Bg/K63wK/5XWgBX/K6pWBK/5XU+BWBh5J/K6auCK/5XTVwRfFAH5XOKwRX/K6auDh5I/K6SuDWP5XSVwYADWX6vXK/5XQWQpW/K6auDJP5XWV35XT+Cu/K7Ku/K65H/K6hW/K7EPI35XWIv5XWAH5X/K/4A/K/5X/K/4A/K9cAAH4A/AFzz/AHRX/K/5X/AH5X/K/5X/AH5X/K/4A/K/5X/K/4A/K/5X/K/4A/K/5X/AH5X/K/5X/AH5X/K/5X/AH5X/K/4A/K/5X/K/4A/K/5X/K/4A/K/5X/AH5X/K/5X/AH5X/K/5X/AH5X/K/4A/K/5X/K/4A/K/5X/K/4A/K/5X/AH5X/K/5X/AH5X/K/5X/AH5X/K/4A/K/5X/K/4A/K/5X/K/4A/K/5X/AH5X/K/5X/AH5X/K/40VAH4A/AFzLb+EPDm4AdK/5X/K+PwgEAHy5X9HgMAK/5XXH6xX/H65X/K/5X/K98AK7sAgBX3DjBWFO644DSTHwGzJXED4RXaDoLqcK7weWDIQcXK8I6YK77KXK4o8DPbY6ZK7qvDDy6vdR7JXDh60EDyw5BAIRXYSwjMbAgIhUDwJZCHwJX0GwjRWNwIAEHSwBCDSpXFH4pXzDS5XIEARXVSYbQEDaYzCK+6vcKaxXNDypX9HwQkbHS40COSpXKK2A6CHgRXcPIhX0SwpXYVuQ6EgBX/K644YODBXkSDJX/K/5X/DtRX6gA3YOkRWbLDZX4KwYA/AG8F5vdABncKH4AGhpRJAYXNAgPAKP4AF5vMJwoDBAQIKE6BR/AAvc5vO9wAB7oCB9veAoPcAoPcK+kwh8AgcA98An//gH/+sD//wCISgBJ4IABAYpaC9vdK4UP/9AAQNQr/zgHwEYNQFYQAh+EP+FegH+A4QBCMQIKBAAPNK4yxBA4RXCV4YZBE4IjChwCDmApCK8VdmHggHgFYf0SQJXE5nMK4anCAoYHC5pXCaQJXBop+BqAGEK7f/AAQeEKwQrBqCtDAILjBCQfNK4JTCAYZXF7qvD//gV4S2DgEFFIYAECgIACMC8PKoIBB8n1K4ivF5vc5xOCWYZbBAYavHU4RXCr4pEAEMDfoNQGoMEgEwYQPwAoIBBAAPM5ipC7oDCVIIAE7hXCD4SdBiEP+gGBgihCFYIAz5pXBAAnN7oIB7nc5gOBK4QA/K4pNCWgSpCBInNK/4AGhncKIStC7gCBA4QAC4BR/AAysCABZW/AHwA="));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// schedule a draw for the next minute
|
||||
let rocketInterval;
|
||||
var drawTimeout;
|
||||
function queueDraw() {
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = setTimeout(function() {
|
||||
drawTimeout = undefined;
|
||||
draw();
|
||||
}, 60000 - (Date.now() % 60000));
|
||||
}
|
||||
|
||||
|
||||
function clearIntervals() {
|
||||
if (rocketInterval) clearInterval(rocketInterval);
|
||||
rocketInterval = undefined;
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = undefined;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
// TIMER FUNC
|
||||
//
|
||||
var timer_time = 0;
|
||||
var alreadyListenTouch = false;
|
||||
function initTouchTimer () {
|
||||
if (alreadyListenTouch) return;
|
||||
alreadyListenTouch = true;
|
||||
|
||||
Bangle.on('swipe', function(dirX,dirY) {
|
||||
if (canTouch === false) return;
|
||||
var njson = getDataJson();
|
||||
if (!njson) return;
|
||||
|
||||
if (dirX === -1) {
|
||||
timer_time = 0;
|
||||
delete njson.timer;
|
||||
setDataJson(njson);
|
||||
}
|
||||
else if (dirX === 1) {
|
||||
var now = new Date().getTime();
|
||||
njson.timer = now + (timer_time * 1000 * 60);
|
||||
Bangle.setLocked(true);
|
||||
setDataJson(njson);
|
||||
Bangle.buzz(200, 0);
|
||||
timer_time = 0;
|
||||
}
|
||||
else if (dirY === -1) {
|
||||
if (canTouch === false || njson.timer) return;
|
||||
timer_time = timer_time + 5;
|
||||
}
|
||||
else if (dirY === 1) {
|
||||
if (canTouch === false || njson.timer) return;
|
||||
timer_time = timer_time - 5;
|
||||
}
|
||||
draw();
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
initTouchTimer ();
|
||||
});
|
||||
|
||||
function getTimerTime() {
|
||||
// if timer_time !== -1, take it
|
||||
if (timer_time !== 0) {
|
||||
return timer_time + "m";
|
||||
} else {
|
||||
// else, show diff between njsontime and now
|
||||
var njson = getDataJson();
|
||||
if (!njson) return false;
|
||||
var now = new Date().getTime();
|
||||
var diff = Math.round((njson.timer - now) / (1000 * 60));
|
||||
//console.log(123, njson, diff, now, njson.timer - now);
|
||||
if (diff > 0) return diff + "m";
|
||||
else if (njson.timer) {
|
||||
Bangle.buzz(1000, 1);
|
||||
console.log("END OF TIMER");
|
||||
delete njson.timer;
|
||||
setDataJson(njson);
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// if diff is <0, delete timer from json
|
||||
}
|
||||
}
|
||||
function drawTimer() {
|
||||
//g.drawString(getTimerTime(), 100, 100);
|
||||
g.setFont("8x12", 2);
|
||||
var t = 97;
|
||||
var l = 105;
|
||||
var time = getTimerTime();
|
||||
if (time || timer_time !== 0) g.drawString(time, l+5, t+0);
|
||||
if (time && timer_time === 0) g.drawImage(getClockBg(), l-20, t+2, { scale: 1 });
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
// DATA READING
|
||||
//
|
||||
function getDataJson(){
|
||||
var res = {"tasks":"", "weather":[]};
|
||||
try {
|
||||
res = storage.readJSON('advcasio.data.json');
|
||||
} catch(ex) {
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
function setDataJson(resJson){
|
||||
try {
|
||||
res = storage.writeJSON('advcasio.data.json', resJson);
|
||||
} catch(ex) {
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
var dataJson = getDataJson();
|
||||
|
||||
////////////////////////////////////////////
|
||||
// WEATHER!
|
||||
//
|
||||
function drawWeather(arr) {
|
||||
g.setFont("6x8", 1);
|
||||
var p = {l: 8, tText: 40, tIcon:20, decal:25};
|
||||
var today = new Date().getTime();
|
||||
var yesterday = today - (1000 * 60 * 60 * 24);
|
||||
var testday = today + (1000 * 60 * 60 * 24 * 2);
|
||||
//12h auj > 12h hier qui est sup a 0h auj
|
||||
//23h59 hier est sup a 0h auj
|
||||
var j = 0;
|
||||
for(var i = 0; i<arr.length;i++) {
|
||||
if (arr[i][2] > yesterday && j < 4) {
|
||||
g.drawString(arr[i][0], p.l + p.decal*j + 4, p.tText);
|
||||
g.drawImage(iconsWeather[arr[i][1]], p.l + p.decal*j, p.tIcon, { scale: 1 });
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
// DRAWING FUNCS
|
||||
//
|
||||
function drawTasks(str) {
|
||||
g.setFont("6x8", 1);
|
||||
var t = 57;
|
||||
var l = 0;
|
||||
g.drawString(str, l+5, t+0);
|
||||
}
|
||||
|
||||
function drawSteps() {
|
||||
g.setFont("8x12", 2);
|
||||
var t = 132;
|
||||
var l = 150;
|
||||
g.drawString(getSteps(), l+5, t+0);
|
||||
}
|
||||
|
||||
|
||||
function drawClock() {
|
||||
g.setFont("7x11Numeric7Seg", 3);
|
||||
g.clearRect(80, 57, 170, 96);
|
||||
g.setColor(255, 255, 255);
|
||||
var l = 77;
|
||||
var t = 57;
|
||||
var w = 170;
|
||||
var h = 116;
|
||||
g.drawRect(l, t, w, h);
|
||||
g.fillRect(l, t, w, h);
|
||||
g.setColor(0, 0, 0);
|
||||
g.drawString(require("locale").time(new Date(), 1), 76, 60);
|
||||
|
||||
// day
|
||||
//g.setFont("8x12", 1);
|
||||
//g.setFont("9x18", 1);
|
||||
//g.drawString(require("locale").dow(new Date(), 2).toUpperCase(), 25, 136);
|
||||
g.setFont("8x12", 2);
|
||||
g.drawString(require("locale").dow(new Date(), 2), 18, 130);
|
||||
|
||||
// month
|
||||
g.setFont("8x12");
|
||||
g.drawString(require("locale").month(new Date(), 2).toUpperCase(), 80, 127);
|
||||
|
||||
// day nb
|
||||
g.setFont("8x12", 2);
|
||||
const time = new Date().getDate();
|
||||
g.drawString(time < 10 ? "0" + time : time, 78, 137);
|
||||
}
|
||||
|
||||
function drawBattery() {
|
||||
bigThenSmall(E.getBattery(), "%", 140, 23);
|
||||
}
|
||||
|
||||
|
||||
function getSteps() {
|
||||
var steps = 0;
|
||||
try{
|
||||
if (WIDGETS.wpedom !== undefined) {
|
||||
steps = WIDGETS.wpedom.getSteps();
|
||||
} else if (WIDGETS.activepedom !== undefined) {
|
||||
steps = WIDGETS.activepedom.getSteps();
|
||||
} else {
|
||||
steps = Bangle.getHealthStatus("day").steps;
|
||||
}
|
||||
} catch(ex) {
|
||||
// In case we failed, we can only show 0 steps.
|
||||
return "? k";
|
||||
}
|
||||
|
||||
steps = Math.round(steps/1000);
|
||||
return steps + "k";
|
||||
}
|
||||
|
||||
|
||||
|
||||
function draw() {
|
||||
|
||||
queueDraw();
|
||||
|
||||
g.reset();
|
||||
g.clear();
|
||||
g.setColor(255, 255, 255);
|
||||
g.fillRect(0, 0, g.getWidth(), g.getHeight());
|
||||
let background = getBackgroundImage();
|
||||
g.drawImage(background, 0, 0, { scale: 1 });
|
||||
|
||||
|
||||
g.setColor(0, 0, 0);
|
||||
g.setFont("6x12");
|
||||
if(dataJson && dataJson.weather) drawWeather(dataJson.weather);
|
||||
if(dataJson && dataJson.tasks) drawTasks(dataJson.tasks);
|
||||
|
||||
|
||||
g.setFontAlign(0,-1);
|
||||
g.setFont("8x12", 2);
|
||||
|
||||
drawSteps();
|
||||
g.setFontAlign(-1,-1);
|
||||
drawClock();
|
||||
drawBattery();
|
||||
drawTimer();
|
||||
// Hide widgets
|
||||
for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
|
||||
}
|
||||
|
||||
// save batt power, does not seem to work although...
|
||||
var canTouch = true;
|
||||
Bangle.on("lcdPower", (on) => {
|
||||
if (on) {
|
||||
draw();
|
||||
} else {
|
||||
canTouch = false;
|
||||
clearIntervals();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Bangle.on("lock", (locked) => {
|
||||
clearIntervals();
|
||||
draw();
|
||||
if (!locked) {
|
||||
canTouch = true;
|
||||
} else {
|
||||
canTouch = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Load widgets, but don't show them
|
||||
Bangle.loadWidgets();
|
||||
Bangle.setUI("clock");
|
||||
|
||||
g.reset();
|
||||
g.clear();
|
||||
draw();
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1 @@
|
|||
{"tasks":"", "weather":[]};
|
|
@ -0,0 +1,25 @@
|
|||
{ "id": "advcasio",
|
||||
"name": "Advanced Casio Clock",
|
||||
"shortName":"advcasio",
|
||||
"version":"0.01",
|
||||
"description": "An over-engineered clock inspired by Casio watches. It has a 4 days weather, a timer using swipe and a scratchpad. Can be updated using a dedicated webapp.",
|
||||
"icon": "app.png",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
"screenshots": [
|
||||
{ "url": "screenshot-clock-1.jpg" },
|
||||
{ "url": "screenshot-clock-2.jpg" },
|
||||
{ "url": "screenshot-clock-3.jpg" },
|
||||
{ "url": "screenshot-webapp.jpg" }
|
||||
],
|
||||
"supports" : ["BANGLEJS", "BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
{"name":"advcasio.app.js","url":"app.js"},
|
||||
{"name":"advcasio.img","url":"app-icon.js","evaluate":true}
|
||||
],
|
||||
"data": [
|
||||
{ "name": "advcasio.data.json", "url": "data.json", "storageFile": true }
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 230 KiB |
|
@ -1 +1,2 @@
|
|||
0.01: Basic agenda with events from GB
|
||||
0.02: Added settings page to force calendar sync
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0.01: First, proof of concept
|
|
@ -0,0 +1,18 @@
|
|||
# A-GPS Data
|
||||
|
||||
Load assisted GPS data directly to the watch using the new http requests on Android GadgetBridge.
|
||||
|
||||
Make sure:
|
||||
* your GadgetBridge version supports http requests
|
||||
* turn on internet access in GadgetBridge settings
|
||||
|
||||
Currently proof of concept on Bangle2 only. Will eventually add a widget for automatic download.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Creator
|
||||
[@pidajo](https://github.com/pidajo)
|
|
@ -0,0 +1 @@
|
|||
atob("MDCEAAAAAAAAAAAAAAAAiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAACIiIiIAAAAAAAAAAAAAAAAAAAAAAAAAACIiIiIAAAAAAAAAAAAAAAAAAAAAAAAAACIiIiIAAAAAAAAAAAAAAAAAAAAAAAAAAiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAIiIOIiIiAAAAAAAAAAAAAAAAAAAAAAAAIiDOIiIiAAAAAAAAAAAAAAAAAAAAAAAAIiDOIiIiIAAAAAAAAAAAAAAAAAAAAAACIiPOIiIiIAAAAAAAAAAAAAAAAAAAAAAiIj/OIiIiIgAAAAAAAAAAAAAAAAAAAAAiI//OIiIiIgAAAAAAAAAAAAAAAAAAAAAiI//OIiIiIiAAAAAAAAAAAAAAAAAAAAAiD//OIiIiIiAAAAAAAAAAAAAAAAAAAAIiP//OIiIiIiAAAAAAAAAAAAAAAAAAAAIg///OIiIiIiIAAAAAAAAAAAAAAAAAACIj///OIiIiIiIAAAAAAAAAAAAAAAAAACIP///OIiIiIiIgAAAAAAAAAAAAAAAAACI////OIiIiIiIgAAAAAAAAAAAAAAAAAiD////OIiIiIiIiAAAAAAAAAAAAAAAAAiP////OIiIiIiIiAAAAAAAAAAAAAAAAIiP////OIiIiIiIiIAAAAAAAAAAAAAAAIj/////OIiIiIiIiIAAAAAAAAAAAAAACIj/////OIiIiIiIiIgAAAAAAAAAAAAACI//////OIiIiIiIiIgAAAAAAAAAAAAAiI//////OIiIiIiIiIgAAAAAAAAAAAAAiIiIiIiIgzMzMzMziIiAAAAAAAAAAAAAiIiIiIiIj///////+IiAAAAAAAAAAAAIiIiIiIiIj////////4iIAAAAAAAAAAAIiIiIiIiIgzMzMzMzM4iIAAAAAAAAAACIP///////OIiIiIiIiIiIgAAAAAAAAACI////////OIiIiIiIiIiIgAAAAAAAAAiI////////OIiIiIiIiIiIiAAAAAAAAAiP////////OIiIiIiIiIiIiAAAAAAAAIiP////////OIiIiIiIiIiIiIAAAAAAAIj/////////OIiIiIiIiIiIiIAAAAAACIj////////ziIiIiIiIiIiIiIgAAAAACIP///////+IiIiIiIiIiIiIiIgAAAAACI//////84gYiIiIiIiIiIiIiIgAAAAAiD////84iIiAAAiIiIiIiIiIiIiAAAAAiP///ziIiIAAAAAIiIiIiIiIiIiAAAAIg/8ziIiIAAAAAAAAAIiIiIiIiIiIAAAIj/iIiIAAAAAAAAAAAAAIiIiIiIiIAACIiIiBgAAAAAAAAAAAAAAACIiIiIiIgACIiIgAAAAAAAAAAAAAAAAAAACIiIiIgACIgAAAAAAAAAAAAAAAAAAAAAAAiIiIgA==")
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,125 @@
|
|||
var _GB = global.GB;
|
||||
var counter = 0;
|
||||
|
||||
function GB(msg) {
|
||||
console.log(msg);
|
||||
if (msg.t == "http") {
|
||||
display("Received", "(" + msg.resp.length + ") Touch to apply", () => {
|
||||
display("Apply data..", "");
|
||||
setTimeout(() => {
|
||||
if (setAGPS(msg.resp)) {
|
||||
display("Success", "Touch for restart", httpTest);
|
||||
}
|
||||
else {
|
||||
display("Error", "Touch for restart", httpTest);
|
||||
}
|
||||
}, 1);
|
||||
});
|
||||
}
|
||||
if (_GB) {
|
||||
_GB(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function setAGPS(data) {
|
||||
var js = jsFromBase64(data);
|
||||
console.log(js);
|
||||
try {
|
||||
eval(js);
|
||||
return true;
|
||||
}
|
||||
catch(e) {
|
||||
console.log("Error:", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function jsFromBase64(b64) {
|
||||
var bin = atob(b64);
|
||||
var chunkSize = 128;
|
||||
var js = "Bangle.setGPSPower(1);\n"; // turn GPS on
|
||||
var gnss_select="1";
|
||||
js += `Serial1.println("${CASIC_CHECKSUM("$PCAS04,"+gnss_select)}")\n`; // set GNSS mode
|
||||
// What about:
|
||||
// NAV-TIMEUTC (0x01 0x10)
|
||||
// NAV-PV (0x01 0x03)
|
||||
// or AGPS.zip uses AID-INI (0x0B 0x01)
|
||||
|
||||
for (var i=0;i<bin.length;i+=chunkSize) {
|
||||
var chunk = bin.substr(i,chunkSize);
|
||||
js += `Serial1.write(atob("${btoa(chunk)}"))\n`;
|
||||
}
|
||||
return js;
|
||||
}
|
||||
|
||||
function CASIC_CHECKSUM(cmd) {
|
||||
var cs = 0;
|
||||
for (var i=1;i<cmd.length;i++)
|
||||
cs = cs ^ cmd.charCodeAt(i);
|
||||
return cmd+"*"+cs.toString(16).toUpperCase().padStart(2, '0');
|
||||
}
|
||||
|
||||
function display(text1, text2, next) {
|
||||
g.reset();
|
||||
g.clear();
|
||||
var img = require("Storage").read("agpsdata.img");
|
||||
if (img) {
|
||||
g.drawImage(img, g.getWidth() - 48, g.getHeight()-48-24);
|
||||
}
|
||||
g.setFont("Vector", 30);
|
||||
g.setFontAlign(0, 1);
|
||||
g.drawString(text1, g.getWidth() / 2, g.getHeight() / 3 + 24);
|
||||
g.setFont("Vector", 15);
|
||||
g.setFontAlign(-1, -1);
|
||||
g.drawString(text2, 0, g.getHeight() / 3 + 29);
|
||||
Bangle.drawWidgets();
|
||||
nextStep = null;
|
||||
if (next) {
|
||||
nextStep = next;
|
||||
}
|
||||
}
|
||||
|
||||
function httpTest() {
|
||||
counter++;
|
||||
display("AGPS Data", "Touch for start", () => {
|
||||
display("Request...", "Touch for restart", httpTest);
|
||||
if (Bluetooth.println) {
|
||||
console.log("On device");
|
||||
Bluetooth.println(JSON.stringify({t:"info", msg:"HTTP Request"}));
|
||||
Bluetooth.println(JSON.stringify({t:"http", url:"https://www.espruino.com/agps/casic.base64"}));
|
||||
}
|
||||
else {
|
||||
console.log("Testing on Emulator");
|
||||
setTimeout(() => {
|
||||
GB({t:"http", resp:testData});
|
||||
}, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var nextStep = null;
|
||||
|
||||
Bangle.on("touch", () => {
|
||||
if (nextStep) {
|
||||
nextStep();
|
||||
}
|
||||
});
|
||||
|
||||
httpTest();
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
// Load widgets
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
|
||||
/*
|
||||
require("Storage").write("httptest.info",{
|
||||
"id":"httptest",
|
||||
"name":"Http Test",
|
||||
"src":"httptest.js",
|
||||
"icon":"wristlight.img"
|
||||
});
|
||||
*/
|
||||
|
||||
var testData = "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";
|
|
@ -0,0 +1,16 @@
|
|||
{ "id": "agpsdata",
|
||||
"name": "A-GPS Data",
|
||||
"shortName":"AGPS Data",
|
||||
"icon": "agpsdata.png",
|
||||
"version":"0.01",
|
||||
"description": "Download assisted GPS data directly to watch",
|
||||
"tags": "assisted,gps,agps,http",
|
||||
"allow_emulator":true,
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme":"README.md",
|
||||
"screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot2.png" }, { "url":"screenshot3.png" }, { "url":"screenshot4.png" }, { "url":"screenshot5.png" } ],
|
||||
"storage": [
|
||||
{"name":"agpsdata.app.js","url":"app.js"},
|
||||
{"name":"agpsdata.img","url":"agpsdata-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 959 B |
After Width: | Height: | Size: 613 B |
After Width: | Height: | Size: 695 B |
After Width: | Height: | Size: 533 B |
After Width: | Height: | Size: 578 B |
|
@ -31,3 +31,6 @@
|
|||
0.29: Fix wrong 'dow' handling in new timer if first day of week is Monday
|
||||
0.30: Fix "Enable All"
|
||||
0.31: Add seconds to timers
|
||||
0.32: Fix wrong hidden filter
|
||||
Add option for auto-delete a timer after it expires
|
||||
|
||||
|
|
|
@ -280,6 +280,10 @@ function showEditTimerMenu(selectedTimer, timerIndex) {
|
|||
value: timer.on,
|
||||
onchange: v => timer.on = v
|
||||
},
|
||||
/*LANG*/"Delete After Expiration": {
|
||||
value: timer.del,
|
||||
onchange: v => timer.del = v
|
||||
},
|
||||
/*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v),
|
||||
/*LANG*/"Cancel": () => showMainMenu()
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "alarm",
|
||||
"name": "Alarms & Timers",
|
||||
"shortName": "Alarms",
|
||||
"version": "0.31",
|
||||
"version": "0.32",
|
||||
"description": "Set alarms and timers on your Bangle",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,alarm,widget",
|
||||
|
|
|
@ -2,7 +2,7 @@ WIDGETS["alarm"]={area:"tl",width:0,draw:function() {
|
|||
if (this.width) g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
|
||||
},reload:function() {
|
||||
// don't include library here as we're trying to use as little RAM as possible
|
||||
WIDGETS["alarm"].width = (require('Storage').readJSON('sched.json',1)||[]).some(alarm=>alarm.on&&(alarm.hidden!==false)) ? 24 : 0;
|
||||
WIDGETS["alarm"].width = (require('Storage').readJSON('sched.json',1)||[]).some(alarm=>alarm.on&&(alarm.hidden!==true)) ? 24 : 0;
|
||||
}
|
||||
};
|
||||
WIDGETS["alarm"].reload();
|
||||
|
|
|
@ -9,3 +9,4 @@
|
|||
0.08: Handling of alarms
|
||||
0.09: Alarm vibration, repeat, and auto-snooze now handled by sched
|
||||
0.10: Fix SMS bug
|
||||
0.12: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "android",
|
||||
"name": "Android Integration",
|
||||
"shortName": "Android",
|
||||
"version": "0.11",
|
||||
"version": "0.12",
|
||||
"description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,system,messages,notifications,gadgetbridge",
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
}),
|
||||
/*LANG*/"Keep Msgs" : {
|
||||
value : !!settings.keep,
|
||||
format : v=>v?/*LANG*/"Yes":/*LANG*/"No",
|
||||
onchange: v => {
|
||||
settings.keep = v;
|
||||
updateSettings();
|
||||
|
|
|
@ -9,4 +9,5 @@
|
|||
when weekday name and calendar weeknumber are on then display is <weekday short> #<calweek>
|
||||
week is buffered until date or timezone changes
|
||||
0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users)
|
||||
0.08: fixed calendar weeknumber not shortened to two digits
|
||||
0.08: fixed calendar weeknumber not shortened to two digits
|
||||
0.09: Use default Bangle formatter for booleans
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "antonclk",
|
||||
"name": "Anton Clock",
|
||||
"version": "0.08",
|
||||
"version": "0.09",
|
||||
"description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.",
|
||||
"readme":"README.md",
|
||||
"icon": "app.png",
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
(function(back) {
|
||||
var FILE = "antonclk.json";
|
||||
// Load settings
|
||||
var settings = Object.assign({
|
||||
secondsOnUnlock: false,
|
||||
}, require('Storage').readJSON(FILE, true) || {});
|
||||
|
@ -41,7 +40,6 @@
|
|||
"Date": stringInSettings("dateOnMain", ["Long", "Short", "ISO8601"]),
|
||||
"Show Weekday": {
|
||||
value: (settings.weekDay !== undefined ? settings.weekDay : true),
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.weekDay = v;
|
||||
writeSettings();
|
||||
|
@ -49,7 +47,6 @@
|
|||
},
|
||||
"Show CalWeek": {
|
||||
value: (settings.calWeek !== undefined ? settings.calWeek : false),
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.calWeek = v;
|
||||
writeSettings();
|
||||
|
@ -57,7 +54,6 @@
|
|||
},
|
||||
"Uppercase": {
|
||||
value: (settings.upperCase !== undefined ? settings.upperCase : true),
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.upperCase = v;
|
||||
writeSettings();
|
||||
|
@ -65,7 +61,6 @@
|
|||
},
|
||||
"Vector font": {
|
||||
value: (settings.vectorFont !== undefined ? settings.vectorFont : false),
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.vectorFont = v;
|
||||
writeSettings();
|
||||
|
@ -82,7 +77,6 @@
|
|||
"Show": stringInSettings("secondsMode", ["Never", "Unlocked", "Always"]),
|
||||
"With \":\"": {
|
||||
value: (settings.secondsWithColon !== undefined ? settings.secondsWithColon : true),
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.secondsWithColon = v;
|
||||
writeSettings();
|
||||
|
@ -90,7 +84,6 @@
|
|||
},
|
||||
"Color": {
|
||||
value: (settings.secondsColoured !== undefined ? settings.secondsColoured : true),
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.secondsColoured = v;
|
||||
writeSettings();
|
||||
|
@ -99,9 +92,6 @@
|
|||
"Date": stringInSettings("dateOnSecs", ["Year", "Weekday", "No"])
|
||||
};
|
||||
|
||||
// Actually display the menu
|
||||
E.showMenu(mainmenu);
|
||||
|
||||
});
|
||||
|
||||
// end of file
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
0.01: New App!
|
||||
0.02: Barometer altitude adjustment setting
|
||||
0.03: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "bikespeedo",
|
||||
"name": "Bike Speedometer (beta)",
|
||||
"shortName": "Bike Speedometer",
|
||||
"version": "0.02",
|
||||
"version": "0.03",
|
||||
"description": "Shows GPS speed, GPS heading, Compass heading, GPS altitude and Barometer altitude from internal sources",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"Screenshot.png"}],
|
||||
|
|
|
@ -33,12 +33,10 @@
|
|||
'< Back': function() { E.showMenu(appMenu); },
|
||||
'Speed' : {
|
||||
value : settings.spdFilt,
|
||||
format : v => v?"On":"Off",
|
||||
onchange : () => { settings.spdFilt = !settings.spdFilt; writeSettings(); }
|
||||
},
|
||||
'Altitude' : {
|
||||
value : settings.altFilt,
|
||||
format : v => v?"On":"Off",
|
||||
onchange : () => { settings.altFilt = !settings.altFilt; writeSettings(); }
|
||||
}
|
||||
};
|
||||
|
|
|
@ -22,3 +22,4 @@
|
|||
Restructure the settings menu
|
||||
0.08: Allow scanning for devices in settings
|
||||
0.09: Misc Fixes and improvements (https://github.com/espruino/BangleApps/pull/1655)
|
||||
0.10: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "bthrm",
|
||||
"name": "Bluetooth Heart Rate Monitor",
|
||||
"shortName": "BT HRM",
|
||||
"version": "0.09",
|
||||
"version": "0.10",
|
||||
"description": "Overrides Bangle.js's build in heart rate monitor with an external Bluetooth one.",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
|
|
|
@ -85,14 +85,12 @@
|
|||
'< Back': function() { E.showMenu(buildMainMenu()); },
|
||||
'Alert on disconnect': {
|
||||
value: !!settings.warnDisconnect,
|
||||
format: v => settings.warnDisconnect ? "On" : "Off",
|
||||
onchange: v => {
|
||||
writeSettings("warnDisconnect",v);
|
||||
}
|
||||
},
|
||||
'Debug log': {
|
||||
value: !!settings.debuglog,
|
||||
format: v => settings.debuglog ? "On" : "Off",
|
||||
onchange: v => {
|
||||
writeSettings("debuglog",v);
|
||||
}
|
||||
|
|
|
@ -6,4 +6,6 @@
|
|||
0.06: Design and usability improvements.
|
||||
0.07: Improved positioning.
|
||||
0.08: Select the color of widgets correctly. Additional settings to hide colon.
|
||||
0.09: Larger font size if colon is hidden to improve readability further.
|
||||
0.09: Larger font size if colon is hidden to improve readability further.
|
||||
0.10: HomeAssistant integration if HomeAssistant is installed.
|
||||
0.11: Performance improvements.
|
|
@ -7,6 +7,7 @@
|
|||
- Tab left/right of screen to show steps, temperature etc.
|
||||
- Enable / disable lock icon in the settings.
|
||||
- If the "sched" app is installed tab top / bottom of the screen to set the timer.
|
||||
- If HomeAssistant is installed, triggers are shown. Simple select the trigger and touch the middle of the screen to send the trigger to HomeAssistant.
|
||||
- The design is adapted to the theme of your bangle.
|
||||
- The colon (e.g. 7:35 = 735) can be hidden now in the settings.
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"id": "bwclk",
|
||||
"name": "BW Clock",
|
||||
"version": "0.09",
|
||||
"version": "0.11",
|
||||
"description": "BW Clock.",
|
||||
"readme": "README.md",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot.png"}, {"url":"screenshot_2.png"}, {"url":"screenshot_3.png"}],
|
||||
"screenshots": [{"url":"screenshot.png"}, {"url":"screenshot_2.png"}, {"url":"screenshot_3.png"}, {"url":"screenshot_4.png"}],
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS2"],
|
||||
|
|
After Width: | Height: | Size: 3.3 KiB |
|
@ -8,3 +8,4 @@
|
|||
0.08: Do not register as watch, manually start clock on button
|
||||
read start of week from system settings
|
||||
0.09: Fix scope of let variables
|
||||
0.10: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "calendar",
|
||||
"name": "Calendar",
|
||||
"version": "0.09",
|
||||
"version": "0.10",
|
||||
"description": "Simple calendar",
|
||||
"icon": "calendar.png",
|
||||
"screenshots": [{"url":"screenshot_calendar.png"}],
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"< Back": () => back(),
|
||||
'B2 Colors': {
|
||||
value: settings.ndColors,
|
||||
format: v => v ? "Yes" : "No",
|
||||
onchange: v => {
|
||||
settings.ndColors = v;
|
||||
writeSettings();
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
1.00: New App!
|
||||
1.01: Use fractional numbers and scale the points to keep working consistently on whole screen
|
||||
0.01: New App!
|
||||
0.02: Use fractional numbers and scale the points to keep working consistently on whole screen
|
||||
0.03: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Touchscreen Calibration",
|
||||
"shortName":"Calibration",
|
||||
"icon": "calibration.png",
|
||||
"version":"1.01",
|
||||
"version":"0.03",
|
||||
"description": "A simple calibration app for the touchscreen",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
"< Back" : () => back(),
|
||||
'Active': {
|
||||
value: !!settings.active,
|
||||
format: v => v? "On":"Off",
|
||||
onchange: v => {
|
||||
settings.active = v;
|
||||
writeSettings();
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
0.04: Change to 7 segment font, move to top widget bar
|
||||
Better auto-update behaviour, less RAM used
|
||||
0.05: Fix error running app on new firmwares (fix #1140)
|
||||
0.06: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -79,7 +79,6 @@ function showMenu() {
|
|||
},
|
||||
'Timer on': {
|
||||
value: settingsChronowid.started,
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settingsChronowid.started = v;
|
||||
updateSettings();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "chronowid",
|
||||
"name": "Chrono Widget",
|
||||
"shortName": "Chrono Widget",
|
||||
"version": "0.05",
|
||||
"version": "0.06",
|
||||
"description": "Chronometer (timer) which runs as widget.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,widget",
|
||||
|
|
|
@ -24,3 +24,5 @@
|
|||
Improve performance, reduce memory usage
|
||||
Small optical adjustments
|
||||
0.12: Allow configuration of update interval
|
||||
0.13: Load step goal from Bangle health app as fallback
|
||||
Memory optimizations
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
const locale = require("locale");
|
||||
const storage = require("Storage");
|
||||
const SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
|
||||
|
||||
const shoesIcon = atob("EBCBAAAACAAcAB4AHgAeABwwADgGeAZ4AHgAMAAAAHAAIAAA");
|
||||
const temperatureIcon = atob("EBCBAAAAAYADwAJAAkADwAPAA8ADwAfgB+AH4AfgA8ABgAAA");
|
||||
|
||||
Graphics.prototype.setFontRobotoRegular50NumericOnly = function(scale) {
|
||||
// Actual height 39 (40 - 2)
|
||||
this.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAB8AAAAAAAfAAAAAAAPwAAAAAAB8AAAAAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAA4AAAAAAB+AAAAAAD/gAAAAAD/4AAAAAH/4AAAAAP/wAAAAAP/gAAAAAf/gAAAAAf/AAAAAA/+AAAAAB/+AAAAAB/8AAAAAD/4AAAAAH/4AAAAAD/wAAAAAA/wAAAAAAPgAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///wAAAB////gAAA////8AAA/////gAAP////8AAH8AAA/gAB8AAAD4AA+AAAAfAAPAAAADwADwAAAA8AA8AAAAPAAPAAAADwADwAAAA8AA8AAAAPAAPgAAAHwAB8AAAD4AAfwAAD+AAD/////AAA/////wAAH////4AAAf///4AAAB///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAAAAPgAAAAAADwAAAAAAB8AAAAAAAfAAAAAAAHgAAAAAAD4AAAAAAA+AAAAAAAPAAAAAAAH/////wAB/////8AA//////AAP/////wAD/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAfgAADwAAP4AAB8AAH+AAA/AAD/gAAfwAB/AAAf8AAfAAAP/AAPgAAH7wAD4AAD88AA8AAB+PAAPAAA/DwADwAAfg8AA8AAPwPAAPAAH4DwADwAH8A8AA+AD+APAAPwB/ADwAB/D/gA8AAf//gAPAAD//wADwAAf/wAA8AAD/4AAPAAAHwAADwAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAADgAAAHwAA+AAAD8AAP4AAB/AAD/AAA/wAA/wAAf4AAD+AAHwAAAPgAD4APAB8AA+ADwAPAAPAA8ADwADwAPAA8AA8ADwAPAAPAA8ADwADwAfAA8AA8AH4APAAPgD+AHwAB8B/wD4AAf7/+B+AAD//v//AAA//x//wAAD/4P/4AAAf8B/4AAAAYAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAHwAAAAAAH8AAAAAAD/AAAAAAD/wAAAAAD/8AAAAAB/vAAAAAB/jwAAAAA/g8AAAAA/wPAAAAAfwDwAAAAf4A8AAAAf4APAAAAP8ADwAAAP8AA8AAAH8AAPAAAD/////8AA//////AAP/////wAD/////8AA//////AAAAAAPAAAAAAADwAAAAAAA8AAAAAAAPAAAAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAB/APwAAH//wD+AAD//8A/wAA///AH+AAP//wAPgAD/B4AB8AA8A+AAfAAPAPAADwADwDwAA8AA8A8AAPAAPAPAADwADwD4AA8AA8A+AAPAAPAPwAHwADwD8AD4AA8AfwD+AAPAH///AADwA///wAA8AH//4AAPAAf/4AAAAAB/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAD//+AAAAD///4AAAD////AAAB////4AAA/78D/AAAfw8AH4AAPweAA+AAD4PgAHwAB8DwAA8AAfA8AAPAAHgPAADwAD4DwAA8AA+A8AAPAAPAPgAHwADwD4AB8AA8AfgA+AAPAH+B/gAAAA///wAAAAH//4AAAAA//8AAAAAH/8AAAAAAP4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAAAAAA8AAAAAAAPAAAAAAADwAAAAAAA8AAAABAAPAAAABwADwAAAB8AA8AAAB/AAPAAAB/wADwAAD/8AA8AAD/8AAPAAD/4AADwAD/4AAA8AD/4AAAPAH/wAAADwH/wAAAA8H/wAAAAPH/wAAAAD3/gAAAAA//gAAAAAP/gAAAAAD/gAAAAAA/AAAAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwA/4AAAH/Af/AAAH/8P/4AAD//n//AAA//7//4AAfx/+A+AAHwD+AHwAD4AfgB8AA8AHwAPAAPAA8ADwADwAPAA8AA8ADwAPAAPAA8ADwADwAfAA8AA+AH4AfAAHwD+AHwAB/D/4D4AAP/+/n+AAD//n//AAAf/w//gAAB/wH/wAAAHwA/4AAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAD/8AAAAAD//wAAAAB//+AAAAA///wAAAAf4H+APAAH4AfgDwAD8AB8A8AA+AAfAPAAPAADwDwADwAA8B8AA8AAPAfAAPAADwHgADwAA8D4AA+AAeB+AAHwAHg/AAB+ADwfgAAP8D4/4AAD////8AAAf///8AAAB///+AAAAP//+AAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAOAAAB8AAHwAAAfgAD8AAAH4AA/AAAB8AAHwAAAOAAA4AAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("DRUcHBwcHBwcHBwcDA=="), 50+(scale<<8)+(1<<16));
|
||||
|
@ -22,10 +17,16 @@ let settings = Object.assign(
|
|||
storage.readJSON("circlesclock.default.json", true) || {},
|
||||
storage.readJSON(SETTINGS_FILE, true) || {}
|
||||
);
|
||||
// Load step goal from pedometer widget as fallback
|
||||
|
||||
// Load step goal from health app and pedometer widget as fallback
|
||||
if (settings.stepGoal == undefined) {
|
||||
const d = storage.readJSON("wpedom.json", true) || {};
|
||||
settings.stepGoal = d != undefined && d.settings != undefined ? d.settings.goal : 10000;
|
||||
let d = storage.readJSON("health.json", true) || {};
|
||||
settings.stepGoal = d != undefined && d.settings != undefined ? d.settings.stepGoal : undefined;
|
||||
|
||||
if (settings.stepGoal == undefined) {
|
||||
d = storage.readJSON("wpedom.json", true) || {};
|
||||
settings.stepGoal = d != undefined && d.settings != undefined ? d.settings.goal : 10000;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -125,20 +126,11 @@ function draw() {
|
|||
g.setFontAlign(0, 0);
|
||||
g.drawString(locale.date(new Date()), w / 2, h2);
|
||||
g.drawString(locale.dow(new Date()), w / 2, h2 + dowOffset);
|
||||
|
||||
// draw the circles a little bit delayed so we decrease the blocking time
|
||||
setTimeout(function() {
|
||||
drawCircle(1);
|
||||
}, 1);
|
||||
setTimeout(function() {
|
||||
drawCircle(2);
|
||||
}, 1);
|
||||
setTimeout(function() {
|
||||
drawCircle(3);
|
||||
}, 1);
|
||||
setTimeout(function() {
|
||||
if (circleCount >= 4) drawCircle(4);
|
||||
}, 1);
|
||||
|
||||
drawCircle(1);
|
||||
drawCircle(2);
|
||||
drawCircle(3);
|
||||
if (circleCount >= 4) drawCircle(4);
|
||||
}
|
||||
|
||||
function drawCircle(index) {
|
||||
|
@ -294,7 +286,7 @@ function drawSteps(w) {
|
|||
|
||||
writeCircleText(w, shortValue(steps));
|
||||
|
||||
g.drawImage(getImage(shoesIcon, getCircleIconColor("steps", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
g.drawImage(getImage(atob("EBCBAAAACAAcAB4AHgAeABwwADgGeAZ4AHgAMAAAAHAAIAAA"), getCircleIconColor("steps", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
}
|
||||
|
||||
function drawStepsDistance(w) {
|
||||
|
@ -319,7 +311,7 @@ function drawStepsDistance(w) {
|
|||
|
||||
writeCircleText(w, shortValue(stepsDistance));
|
||||
|
||||
g.drawImage(getImage(shoesIcon, getCircleIconColor("stepsDistance", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
g.drawImage(getImage(atob("EBCBAAAACAAcAB4AHgAeABwwADgGeAZ4AHgAMAAAAHAAIAAA"), getCircleIconColor("stepsDistance", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
}
|
||||
|
||||
function drawHeartRate(w) {
|
||||
|
@ -490,8 +482,8 @@ function drawTemperature(w) {
|
|||
|
||||
if (temperature)
|
||||
writeCircleText(w, locale.temp(temperature));
|
||||
|
||||
g.drawImage(getImage(temperatureIcon, getCircleIconColor("temperature", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
|
||||
g.drawImage(getImage(atob("EBCBAAAAAYADwAJAAkADwAPAA8ADwAfgB+AH4AfgA8ABgAAA"), getCircleIconColor("temperature", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -517,7 +509,7 @@ function drawPressure(w) {
|
|||
if (pressure)
|
||||
writeCircleText(w, Math.round(pressure));
|
||||
|
||||
g.drawImage(getImage(temperatureIcon, getCircleIconColor("pressure", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
g.drawImage(getImage(atob("EBCBAAAAAYADwAJAAkADwAPAA8ADwAfgB+AH4AfgA8ABgAAA"), getCircleIconColor("pressure", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -543,7 +535,7 @@ function drawAltitude(w) {
|
|||
if (altitude)
|
||||
writeCircleText(w, locale.distance(Math.round(altitude)));
|
||||
|
||||
g.drawImage(getImage(temperatureIcon, getCircleIconColor("altitude", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
g.drawImage(getImage(atob("EBCBAAAAAYADwAJAAkADwAPAA8ADwAfgB+AH4AfgA8ABgAAA"), getCircleIconColor("altitude", color, percent)), w - iconOffset, h3 + radiusOuter - iconOffset);
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -614,8 +606,8 @@ function getWeatherIconByCode(code) {
|
|||
default:
|
||||
return weatherCloudy;
|
||||
}
|
||||
default:
|
||||
return undefined;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -641,6 +633,7 @@ function formatSeconds(s) {
|
|||
|
||||
function getSunData() {
|
||||
if (location != undefined && location.lat != undefined) {
|
||||
const SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
|
||||
// get today's sunlight times for lat/lon
|
||||
return SunCalc ? SunCalc.getTimes(new Date(), location.lat, location.lon) : undefined;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{ "id": "circlesclock",
|
||||
"name": "Circles clock",
|
||||
"shortName":"Circles clock",
|
||||
"version":"0.12",
|
||||
"version":"0.13",
|
||||
"description": "A clock with three or four circles for different data at the bottom in a probably familiar style",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}],
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
0.01: Initial upload
|
||||
0.02: Added scrollable calendar and swipe gestures
|
||||
0.03: Configurable drag gestures
|
||||
0.04: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "clockcal",
|
||||
"name": "Clock & Calendar",
|
||||
"version": "0.03",
|
||||
"version": "0.04",
|
||||
"description": "Clock with Calendar",
|
||||
"readme":"README.md",
|
||||
"icon": "app.png",
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
"< Back": () => back(),
|
||||
'Buzz(dis)conn.?': {
|
||||
value: settings.BUZZ_ON_BT,
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.BUZZ_ON_BT = v;
|
||||
writeSettings();
|
||||
|
@ -59,7 +58,6 @@
|
|||
},
|
||||
'Red Saturday?': {
|
||||
value: settings.REDSAT,
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.REDSAT = v;
|
||||
writeSettings();
|
||||
|
@ -67,7 +65,6 @@
|
|||
},
|
||||
'Red Sunday?': {
|
||||
value: settings.REDSUN,
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settings.REDSUN = v;
|
||||
writeSettings();
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
0.01: New app
|
||||
0.02: Cleanup interface and add settings, widget, add skin temp reporting.
|
||||
0.03: Move code for recording to this app
|
||||
0.04: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "coretemp",
|
||||
"name": "CoreTemp",
|
||||
"version": "0.03",
|
||||
"version": "0.04",
|
||||
"description": "Display CoreTemp device sensor data",
|
||||
"icon": "coretemp.png",
|
||||
"type": "app",
|
||||
|
|
|
@ -35,7 +35,6 @@ const menu = {
|
|||
'< Back' : back,
|
||||
'Enabled' : {
|
||||
value : !!s.enabled,
|
||||
format : v => v ? "Yes" : "No",
|
||||
onchange : v => {
|
||||
s.enabled = v;
|
||||
updateSettings();
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
0.04: added heart rate which is switched on when cycled to it through up/down touch on rhs
|
||||
0.05: changed text to uppercase, just looks better, removed colons on text
|
||||
0.06: better contrast for light theme, use fg color instead of dithered for ring
|
||||
0.07: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ "id": "daisy",
|
||||
"name": "Daisy",
|
||||
"version":"0.06",
|
||||
"version":"0.07",
|
||||
"dependencies": {"mylocation":"app"},
|
||||
"description": "A beautiful digital clock with large ring guage, idle timer and a cyclic information line that includes, day, date, steps, battery, sunrise and sunset times",
|
||||
"icon": "app.png",
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
},
|
||||
'Idle Warning': {
|
||||
value: !!s.idle_check,
|
||||
format: v => v ? /*LANG*/"Yes":/*LANG*/"No",
|
||||
onchange: v => {
|
||||
s.idle_check = v;
|
||||
save();
|
||||
|
|
|
@ -4,4 +4,5 @@
|
|||
0.04: Move code to Arwes Module
|
||||
0.05: Add icon
|
||||
0.06: remove app image as it is unused
|
||||
0.07: Bump version number for change to apps.json causing 404 on upload
|
||||
0.07: Bump version number for change to apps.json causing 404 on upload
|
||||
0.08: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "dane_tcr",
|
||||
"name": "DANE Touch Launcher",
|
||||
"shortName": "DANE Toucher",
|
||||
"version": "0.07",
|
||||
"version": "0.08",
|
||||
"description": "Touch enable left to right launcher in the style of the DANE Watchface",
|
||||
"icon": "app.png",
|
||||
"type": "launch",
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
},
|
||||
"Animation" : {
|
||||
value : settings.animation,
|
||||
format : v => v?"On":"Off",
|
||||
onchange : saveChange('animation')
|
||||
},
|
||||
"Frame rate" : {
|
||||
|
@ -51,7 +50,6 @@
|
|||
},
|
||||
"Debug" : {
|
||||
value : settings.debug,
|
||||
format : v => v?"On":"Off",
|
||||
onchange : saveChange('debug')
|
||||
},
|
||||
'< Back': back
|
||||
|
|
|
@ -13,3 +13,4 @@
|
|||
0.13: Added swipeExit setting so that left-right to exit is an option
|
||||
0.14: Don't move pages when doing exit swipe - Bangle 2.
|
||||
0.15: 'Swipe to exit'-code is slightly altered to be more reliable - Bangle 2.
|
||||
0.16: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "dtlaunch",
|
||||
"name": "Desktop Launcher",
|
||||
"version": "0.15",
|
||||
"version": "0.16",
|
||||
"description": "Desktop style App Launcher with six (four for Bangle 2) apps per page - fast access if you have lots of apps installed.",
|
||||
"screenshots": [{"url":"shot1.png"},{"url":"shot2.png"},{"url":"shot3.png"}],
|
||||
"icon": "icon.png",
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
"< Back" : () => back(),
|
||||
'Show clocks': {
|
||||
value: settings.showClocks,
|
||||
format: v => v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.showClocks = v;
|
||||
writeSettings();
|
||||
|
@ -23,7 +22,6 @@
|
|||
},
|
||||
'Show launchers': {
|
||||
value: settings.showLaunchers,
|
||||
format: v => v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.showLaunchers = v;
|
||||
writeSettings();
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
"< Back" : () => back(),
|
||||
'Show clocks': {
|
||||
value: settings.showClocks,
|
||||
format: v => v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.showClocks = v;
|
||||
writeSettings();
|
||||
|
@ -26,7 +25,6 @@
|
|||
},
|
||||
'Show launchers': {
|
||||
value: settings.showLaunchers,
|
||||
format: v => v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.showLaunchers = v;
|
||||
writeSettings();
|
||||
|
@ -34,7 +32,6 @@
|
|||
},
|
||||
'Direct launch': {
|
||||
value: settings.direct,
|
||||
format: v => v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.direct = v;
|
||||
writeSettings();
|
||||
|
@ -42,7 +39,6 @@
|
|||
},
|
||||
'Swipe Exit': {
|
||||
value: settings.swipeExit,
|
||||
format: v => v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.swipeExit = v;
|
||||
writeSettings();
|
||||
|
@ -50,7 +46,6 @@
|
|||
},
|
||||
'One click exit': {
|
||||
value: settings.oneClickExit,
|
||||
format: v => v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.oneClickExit = v;
|
||||
writeSettings();
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0.01: Created the app. The logo bounces and buzz when it hits the angles.
|
|
@ -0,0 +1,9 @@
|
|||
# Bouncing DVD logo
|
||||
|
||||
Have you ever wanted to admire the bouncing DVD logo on your watch? Now you can! Let's hope it touches an angle.
|
||||
|
||||

|
||||
|
||||
## Creator
|
||||
|
||||
I'm [TrinTragula](https://github.com/TrinTragula) on Github. Feel free to reach me.
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwhC/AH4A/AH4A/ACWIAA4MJwAXPhALKC5AlCBZYADE4gXELQ4SDC4gCBC4IDCAwYTEBAghCBYYCEC5YUFAooOIBBAKDMwwIFCwQIDNIZtGTRANEEIiyMVYrYHLIq0GQA4OGABIPPAA77GC8CDGABAfFBAbpCAIIfCAQqmJhAXDhB4CCIMIEgIYETAoaCC5zYHIIRQDDATAKPJasWAH4A/AH4A/AE4"))
|
|
@ -0,0 +1,108 @@
|
|||
// The DVD logo
|
||||
var dvdLogo = require("heatshrink").decompress(atob("3dTwIFC/4AG/ALCgYJEwAcDj4XHBgYJF4AJCg4WH8AMCn4KFF4YWH/wLCh4KJIpA7CgIKG+BnHOg1/BYxGCCw4LDHQ/8IpQ6CQBBRBIpBpDBY4uCKA6jDUQy8FTIn3EQYIBGYSQDBYTVF/x0DKITMGFwh4D96jDKILuDDoSvDEAn9AQIeDB4glCwA5ELwW/FIRNB/x2BVQSvDHIgIB+ZvCNwWPOwZ7DAYKEFDwJoBAYPhHgYeC8ADCP4QEB85YCEQRFELoIqBBA5oFL4SMEwBFEBAWfDwQFB4K1EJoPwIooIB+InCHIQ8EOgYIHA4PAIQP8IogqCBYQIFw4TBAoRICIoQiB/AaDBAfwJAOAUwTrEFQZFHAQPwCYPwCIIxBWIZFIwICBSIIKBIo4IHFYXgSwRFKBARFCFYLlC8DDCRZTaDOIPPHgngaIhFFBoQfB/YhCIojRDBAg/B/gaCGYRFEHgaUED4IEBD4JBDIAIDBLgQEBIoYbC4AMCHAQcBG4IbCAgJFDCQRlBJIIzCIogJCBAgWCD4IICHARFDCwQIEIAY7DGYRmBEAIWCBAJOCNwYfBPAQSBEIWDMog8DAAQfBUYYzEAATkCBAq+CGgQzEYQgIGD4Q3CGYJnDKYhFGCwLtEVAjQDIow2BawY8HNQQIFCwR0CfYgWFBAoWDEAJ5CIogWCIooHCEAR5CJQQWFIoYPCOgg0BHgiJBIooHDUYaCCIoRLCABl/CB4AFg5MFACBNGAB8fQYYARgL/CACc/CysHLisAuAWVhgWVgL/BCyn/WyX/AAx4Mv4VHAARLJFZAAEbA5VBABwWFh4WPJAs/CZoODOA3A/8H/k//BNBK4N/AQQPB/wWF/kf4P/w4jBg4+BKIMAgYuC/BEF4P4n/w//gEIPwCYJYBCAYLBT4f4n0P/0f/k+g/+FoPwn4uDHQYACwZFB4ZHB8A2BKAQYBCAXwW4nwuF//BCBFgJ3CwZ/BCAR1BUIkEJYJHCFgINB+F/GgIAC4BLENgXhI4J5B8BfCI4KMEFwY0BKoK6BvwSDYoIoDCAIuE8APBXQMPwJaC/kPDALqEGgf8NAK6NAoLpDTYS6CCAKCCAoK+BCwhYBMYQiBXQOALQQ2BAQQWFXggAMGoIAECx6gBAArVEABJDDAAhQDABCTBABIYJ4AVKAAbCDChYA="));
|
||||
|
||||
// Screen width
|
||||
const WIDTH = g.getWidth();
|
||||
// Screen height
|
||||
const HEIGHT = g.getHeight();
|
||||
// dvd logo image width
|
||||
const IMG_WIDTH = 94;
|
||||
/// dvd logo image height
|
||||
const IMG_HEIGHT = 42;
|
||||
|
||||
// Assign a random X and Y initial speed between 1.5 and 1
|
||||
var speedX = 1.5 - Math.random() / 2;
|
||||
var speedY = 1.5 - Math.random() / 2;
|
||||
// The logo X and Y position
|
||||
var posX = 0;
|
||||
var posY = 0;
|
||||
|
||||
// The current logo color
|
||||
var currentColor = "#ff00ff";
|
||||
|
||||
// Get a random value between "ff" and "00"
|
||||
function getHexColor() {
|
||||
if (Math.round(Math.random())) {
|
||||
return "ff";
|
||||
} else {
|
||||
return "00";
|
||||
}
|
||||
}
|
||||
|
||||
// Get a new 8 bit color
|
||||
function getNewColor() {
|
||||
return "#" + getHexColor() + getHexColor() + getHexColor();
|
||||
}
|
||||
|
||||
// Change the dvd logo color on impact
|
||||
// Only allow colors different from the current one
|
||||
// and different from the bg
|
||||
function changeColor() {
|
||||
var newColor = getNewColor();
|
||||
while (newColor == currentColor || newColor == "#000000") {
|
||||
newColor = getNewColor();
|
||||
}
|
||||
currentColor = newColor;
|
||||
g.setColor(newColor);
|
||||
}
|
||||
|
||||
// Draw the logo
|
||||
function draw() {
|
||||
// Move it
|
||||
posX += speedX;
|
||||
posY += speedY;
|
||||
|
||||
var collisions = 0;
|
||||
// Collision detection
|
||||
if (posX <= 0) {
|
||||
speedX = -speedX;
|
||||
posX = 0;
|
||||
collisions++;
|
||||
}
|
||||
if (posY <= 0) {
|
||||
speedY = -speedY;
|
||||
posY = 0;
|
||||
collisions++;
|
||||
}
|
||||
if (posX >= (WIDTH - IMG_WIDTH)) {
|
||||
speedX = -speedX;
|
||||
posX = WIDTH - IMG_WIDTH;
|
||||
collisions++;
|
||||
}
|
||||
if (posY >= (HEIGHT - IMG_HEIGHT)) {
|
||||
speedY = -speedY;
|
||||
posY = HEIGHT - IMG_HEIGHT;
|
||||
collisions++;
|
||||
}
|
||||
|
||||
// If we detected 2 collisions, we touched an angle, HURRAY!
|
||||
if (collisions > 1) {
|
||||
Bangle.buzz();
|
||||
}
|
||||
|
||||
// Change logo color on collision
|
||||
if (collisions > 0) {
|
||||
changeColor();
|
||||
}
|
||||
|
||||
// Actually draw the logo
|
||||
g.clear();
|
||||
g.drawImage(dvdLogo, posX, posY, {
|
||||
scale: 0.5
|
||||
});
|
||||
setTimeout(function () {
|
||||
draw();
|
||||
}, 15);
|
||||
}
|
||||
|
||||
// Set the background to black
|
||||
g.setBgColor(0, 0, 0);
|
||||
// Start from purple
|
||||
g.setColor(currentColor);
|
||||
// Clear the screen
|
||||
g.clear();
|
||||
// Start drawing
|
||||
draw();
|
||||
|
||||
// Exit on button press
|
||||
setWatch(Bangle.showLauncher, BTN, { repeat: false, edge: "falling" });
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"id": "dvdbounce",
|
||||
"name": "Bouncing DVD logo",
|
||||
"shortName": "Bouncing DVD",
|
||||
"version": "0.01",
|
||||
"description": "Have you ever wanted to admire the bouncing DVD logo on your watch? Now you can! Let's hope it touches an angle.",
|
||||
"icon": "dvdbounce.png",
|
||||
"tags": "game",
|
||||
"supports": [
|
||||
"BANGLEJS",
|
||||
"BANGLEJS2"
|
||||
],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{
|
||||
"name": "dvdbounce.app.js",
|
||||
"url": "dvdbounce.app.js"
|
||||
},
|
||||
{
|
||||
"name": "dvdbounce.img",
|
||||
"url": "dvdbounce-icon.js",
|
||||
"evaluate": true
|
||||
}
|
||||
],
|
||||
"screenshots": [
|
||||
{
|
||||
"url": "screenshot.gif"
|
||||
}
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 116 KiB |
|
@ -1,7 +1,5 @@
|
|||
const store = require('Storage');
|
||||
|
||||
const boolFormat = (v) => v ? "On" : "Off";
|
||||
|
||||
function showMainMenu() {
|
||||
const mainmenu = {
|
||||
'': {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "football",
|
||||
"name": "football",
|
||||
"shortName": "football",
|
||||
"version": "1.00",
|
||||
"version": "1.01",
|
||||
"type": "app",
|
||||
"description": "Classic football game of the CASIO chronometer",
|
||||
"icon": "app.png",
|
||||
|
|
|
@ -8,3 +8,4 @@
|
|||
0.08: Bug fix at end of the game with victorious splash and glorious orchestra
|
||||
0.09: Added settings menu, removed symbol selection button (*), added highscore reset
|
||||
0.10: fixed clockmode in settings
|
||||
0.11: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{ "id": "game1024",
|
||||
"name": "1024 Game",
|
||||
"shortName" : "1024 Game",
|
||||
"version": "0.10",
|
||||
"version": "0.11",
|
||||
"icon": "game1024.png",
|
||||
"screenshots": [ {"url":"screenshot.png" } ],
|
||||
"readme":"README.md",
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
}
|
||||
},
|
||||
"Exit press:": {
|
||||
value: !settings.clockMode, // ! converts undefined to true
|
||||
value: !settings.clockMode,
|
||||
format: v => v?"short":"long",
|
||||
onchange: v => {
|
||||
settings.clockMode = v;
|
||||
|
@ -40,8 +40,7 @@
|
|||
},
|
||||
},
|
||||
"Debug mode:": {
|
||||
value: !!settings.debugMode, // !! converts undefined to false
|
||||
format: v => v?"On":"Off",
|
||||
value: !!settings.debugMode,
|
||||
onchange: v => {
|
||||
settings.debugMode = v;
|
||||
writeSettings();
|
||||
|
|
|
@ -9,3 +9,4 @@
|
|||
0.09: Move event listener from widget to boot code, stops music from showing up in messages
|
||||
0.10: Simplify touch events
|
||||
Remove date+time
|
||||
0.11: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "gbmusic",
|
||||
"name": "Gadgetbridge Music Controls",
|
||||
"shortName": "Music Controls",
|
||||
"version": "0.10",
|
||||
"version": "0.11",
|
||||
"description": "Control the music on your Gadgetbridge-connected phone",
|
||||
"icon": "icon.png",
|
||||
"screenshots": [{"url":"screenshot_v1_d.png"},{"url":"screenshot_v1_l.png"},
|
||||
|
|
|
@ -25,19 +25,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
const yesNo = (v) => translate(v ? "Yes" : "No");
|
||||
let menu = {
|
||||
"": {"title": "Music Control"},
|
||||
};
|
||||
menu[translate("< Back")] = back;
|
||||
menu[translate("Auto start")] = {
|
||||
value: !!s.autoStart,
|
||||
format: yesNo,
|
||||
onchange: save("autoStart"),
|
||||
};
|
||||
menu[translate("Simple button")] = {
|
||||
value: !!s.simpleButton,
|
||||
format: yesNo,
|
||||
onchange: save("simpleButton"),
|
||||
};
|
||||
|
||||
|
|
|
@ -27,3 +27,4 @@
|
|||
0.25: workaround call notification
|
||||
Fix inflated step number
|
||||
0.26: Include charging status in battery updates to phone
|
||||
0.27: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "gbridge",
|
||||
"name": "Gadgetbridge",
|
||||
"version": "0.26",
|
||||
"version": "0.27",
|
||||
"description": "(NOT RECOMMENDED) Displays Gadgetbridge notifications from Android. Please use the 'Android Integration' Bangle.js app instead.",
|
||||
"icon": "app.png",
|
||||
"type": "widget",
|
||||
|
|
|
@ -27,13 +27,11 @@
|
|||
"Connected" : { value : NRF.getSecurityStatus().connected?"Yes":"No" },
|
||||
"Show Icon" : {
|
||||
value: settings().showIcon,
|
||||
format: v => v?"Yes":"No",
|
||||
onchange: setIcon
|
||||
},
|
||||
"Find Phone" : function() { E.showMenu(findPhone); },
|
||||
"Record HRM" : {
|
||||
value: !!settings().hrm,
|
||||
format: v => v?"Yes":"No",
|
||||
onchange: v => updateSetting('hrm', v)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
0.01: New App!
|
||||
0.02: Set Bangle.js 2 compatible
|
||||
0.03: Add setting to hide the widget
|
||||
0.04: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "gpsautotime",
|
||||
"name": "GPS auto time",
|
||||
"shortName": "GPS auto time",
|
||||
"version": "0.03",
|
||||
"version": "0.04",
|
||||
"description": "A widget that automatically updates the Bangle.js time to the GPS time whenever there is a valid GPS fix.",
|
||||
"icon": "widget.png",
|
||||
"type": "widget",
|
||||
|
|
|
@ -13,9 +13,8 @@
|
|||
E.showMenu({
|
||||
"" : { "title" : "GPS auto time" },
|
||||
"< Back" : () => back(),
|
||||
'Show widget?': {
|
||||
value: !!settings.show, // !! converts undefined to false
|
||||
format: v => v?"Show":"Hide",
|
||||
'Show Widgets': {
|
||||
value: !!settings.show,
|
||||
onchange: v => {
|
||||
settings.show = v;
|
||||
writeSettings();
|
||||
|
|
|
@ -30,3 +30,4 @@
|
|||
0.26: Multiple bugfixes
|
||||
0.27: Map drawing with light theme (fix #1023)
|
||||
0.28: Show distance more accurately in conjunction with new locale app (fix #1523)
|
||||
0.29: Use default Bangle formatter for booleans
|
||||
|
|
|
@ -22,7 +22,6 @@ function showMainMenu() {
|
|||
'': { 'title': 'GPS Record' },
|
||||
'RECORD': {
|
||||
value: !!settings.recording,
|
||||
format: v=>v?"On":"Off",
|
||||
onchange: v => {
|
||||
settings.recording = v;
|
||||
updateSettings();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "gpsrec",
|
||||
"name": "GPS Recorder",
|
||||
"version": "0.28",
|
||||
"version": "0.29",
|
||||
"description": "(NOT RECOMMENDED) - please use the more flexible 'Recorder' app instead. Application that allows you to record a GPS track. Can run in background",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,outdoors,gps,widget",
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
0.01: Release
|
||||
0.02: Includeas the ha.lib.js library that can be used by other apps or clocks.
|