diff --git a/README.md b/README.md
index aa8afdbca..6ad899421 100644
--- a/README.md
+++ b/README.md
@@ -277,7 +277,7 @@ and which gives information about the app for the Launcher.
// 'game' - a game
// 'bluetooth' - uses Bluetooth LE
// 'system' - used by the system
- // 'clkinfo' - provides or uses clock_info module for data on your clock face (see modules/clock_info.js)
+ // 'clkinfo' - provides or uses clock_info module for data on your clock face or clocks that support it (see apps/clock_info/README.md)
"supports": ["BANGLEJS2"], // List of device IDs supported, either BANGLEJS or BANGLEJS2
"dependencies" : { "notify":"type" } // optional, app 'types' we depend on (see "type" above)
"dependencies" : { "messages":"app" } // optional, depend on a specific app ID
diff --git a/android.html b/android.html
index 8a70a46e9..3c78f486c 100644
--- a/android.html
+++ b/android.html
@@ -20,9 +20,6 @@
Translations (BETA - more info). Any apps that are uploaded to Bangle.js after changing this will have any text automatically translated.
-
+
+ Advanced Options
+
+
+
Device info
diff --git a/apps/aiclock/metadata.json b/apps/aiclock/metadata.json
index d8d1e9d68..ee9059f75 100644
--- a/apps/aiclock/metadata.json
+++ b/apps/aiclock/metadata.json
@@ -9,7 +9,7 @@
"dependencies" : { "clock_info":"module" },
"description": "A watch face that was designed by an AI (stable diffusion) and implemented by a human.",
"type": "clock",
- "tags": "clock",
+ "tags": "clock,clkinfo",
"screenshots": [
{"url":"orig.png"},
{"url":"impl.png"},
diff --git a/apps/assistedgps/metadata.json b/apps/assistedgps/metadata.json
index d2e7334c4..fd137aceb 100644
--- a/apps/assistedgps/metadata.json
+++ b/apps/assistedgps/metadata.json
@@ -1,14 +1,16 @@
{
"id": "assistedgps",
"name": "Assisted GPS Updater (AGPS)",
+ "shortName": "AGPS",
"version": "0.05",
"description": "Downloads assisted GPS (AGPS) data to Bangle.js for faster GPS startup and more accurate fixes. **No app will be installed**, this just uploads new data to the GPS chip.",
"sortorder": -1,
"icon": "app.png",
"type": "RAM",
- "tags": "tool,outdoors,agps,gps,a-gps",
+ "tags": "tool,outdoors,agps,gps,a-gps,agps",
"supports": ["BANGLEJS","BANGLEJS2"],
"custom": "custom.html",
"customConnect": true,
- "storage": []
+ "storage": [],
+ "sortorder": -1
}
diff --git a/apps/circlesclock/metadata.json b/apps/circlesclock/metadata.json
index 06d8b4d91..f96a7872c 100644
--- a/apps/circlesclock/metadata.json
+++ b/apps/circlesclock/metadata.json
@@ -6,7 +6,7 @@
"icon": "app.png",
"screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}],
"type": "clock",
- "tags": "clock",
+ "tags": "clock,clkinfo",
"supports" : ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" },
"readme": "README.md",
diff --git a/apps/cogclock/ChangeLog b/apps/cogclock/ChangeLog
index 403cd2258..23885e519 100644
--- a/apps/cogclock/ChangeLog
+++ b/apps/cogclock/ChangeLog
@@ -2,3 +2,4 @@
0.02: Use ClockFace library, add settings
0.03: Use ClockFace_menu.addSettingsFile
0.04: Hide widgets instead of not loading them at all
+0.05: Support Bangle.js 2
diff --git a/apps/cogclock/app.js b/apps/cogclock/app.js
index d24031684..30df613ae 100644
--- a/apps/cogclock/app.js
+++ b/apps/cogclock/app.js
@@ -44,7 +44,7 @@ const clock = new ClockFace({
precision: 1,
settingsFile: "cogclock.settings.json",
init: function() {
- this.r1 = 84; // inner radius
+ this.r1 = (process.env.HWVERSION>1) ? 68 : 84; // inner radius
this.r3 = Math.min(Bangle.appRect.w/2, Bangle.appRect.h/2); // outer radius
this.r2 = (this.r1*3+this.r3*2)/5;
this.teeth = 12;
diff --git a/apps/cogclock/metadata.json b/apps/cogclock/metadata.json
index d404275ee..fee8982df 100644
--- a/apps/cogclock/metadata.json
+++ b/apps/cogclock/metadata.json
@@ -1,13 +1,13 @@
{
"id": "cogclock",
"name": "Cog Clock",
- "version": "0.04",
+ "version": "0.05",
"description": "A cross-shaped clock inside a cog",
"icon": "icon.png",
- "screenshots": [{"url":"screenshot.png"}],
+ "screenshots": [{"url":"screenshot_b1.png"},{"url":"screenshot_b2.png"}],
"type": "clock",
"tags": "clock",
- "supports": ["BANGLEJS"],
+ "supports": ["BANGLEJS","BANGLEJS2"],
"allow_emulator": true,
"storage": [
{"name":"cogclock.app.js","url":"app.js"},
diff --git a/apps/cogclock/screenshot.png b/apps/cogclock/screenshot_b1.png
similarity index 100%
rename from apps/cogclock/screenshot.png
rename to apps/cogclock/screenshot_b1.png
diff --git a/apps/cogclock/screenshot_b2.png b/apps/cogclock/screenshot_b2.png
new file mode 100644
index 000000000..3eddda615
Binary files /dev/null and b/apps/cogclock/screenshot_b2.png differ
diff --git a/apps/fwupdate/custom.html b/apps/fwupdate/custom.html
index a648030c1..90f7c642b 100644
--- a/apps/fwupdate/custom.html
+++ b/apps/fwupdate/custom.html
@@ -15,7 +15,7 @@
Your current firmware version is unknown and DFU is unknown
-
If you have an early (KickStarter or developer) Bangle.js device and still have the old 2v10.x DFU, the Firmware Update
+
If you have an early (KickStarter or developer) Bangle.js device and still have the old 2v10.x DFU, the Firmware Update
will fail with a message about the DFU version. If so, please click here to update to DFU 2v12 and then click the 'Upload' button that appears.
The currently available Espruino firmware releases are:
@@ -104,6 +104,9 @@ function onInit(device) {
version += `(⚠ update required)`;
}
document.getElementById("boot-version").innerHTML = version;
+ var versionNumber = parseFloat(version.replace(".","").replace("v","."));
+ if (versionNumber>=2.15)
+ document.getElementById("fw-old-bootloader-msg").style.display = "none";
});
}
@@ -156,7 +159,8 @@ function checkForFileOnServer() {
for (var i=0;i {
e.preventDefault();
- downloadURL(e.target.href).then(info=>{
+ var href = e.target.href;
+ if (href) downloadURL(href).then(info=>{
document.getElementById("upload").style = ""; // show upload
});
});
diff --git a/apps/lato/metadata.json b/apps/lato/metadata.json
index e4def2df9..994fec77d 100644
--- a/apps/lato/metadata.json
+++ b/apps/lato/metadata.json
@@ -7,7 +7,7 @@
"icon": "app.png",
"screenshots": [{"url":"screenshot3.png"}],
"type": "clock",
- "tags": "clock",
+ "tags": "clock,clkinfo",
"supports": ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" },
"storage": [
diff --git a/apps/linuxclock/metadata.json b/apps/linuxclock/metadata.json
index 412fd53b4..2bfe1d51f 100644
--- a/apps/linuxclock/metadata.json
+++ b/apps/linuxclock/metadata.json
@@ -7,7 +7,7 @@
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"}, {"url":"screenshot_2.png"}],
"type": "clock",
- "tags": "clock",
+ "tags": "clock,clkinfo",
"supports": ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" },
"storage": [
diff --git a/apps/recorder/widget.js b/apps/recorder/widget.js
index 34def1e13..58519e24c 100644
--- a/apps/recorder/widget.js
+++ b/apps/recorder/widget.js
@@ -289,13 +289,14 @@
l = f.readLine(f);
}
var asyncTimeout;
+ var color = g.getColor();
function plotPartial() {
asyncTimeout = undefined;
if (l===undefined) return; // empty file?
mp = m.latLonToXY(+c[la], +c[lo]);
- g.moveTo(mp.x,mp.y);
+ g.moveTo(mp.x,mp.y).setColor(color);
l = f.readLine(f);
- var n = options.async ? 50 : 200; // only plot first 200 points to keep things fast(ish)
+ var n = options.async ? 20 : 200; // only plot first 200 points to keep things fast(ish)
while(l && n--) {
c = l.split(",");
if (c[la]) {
diff --git a/apps/red7game/ChangeLog b/apps/red7game/ChangeLog
index 360b1a305..1356f492a 100644
--- a/apps/red7game/ChangeLog
+++ b/apps/red7game/ChangeLog
@@ -2,3 +2,4 @@
0.02: Fix mistake preventing game from ending in some cases.
0.03: Update help screen with more details.
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.
diff --git a/apps/red7game/metadata.json b/apps/red7game/metadata.json
index 15fec4d21..8e8aca407 100644
--- a/apps/red7game/metadata.json
+++ b/apps/red7game/metadata.json
@@ -2,7 +2,7 @@
"name": "Red 7 Card Game",
"shortName" : "Red 7",
"icon": "icon.png",
- "version":"0.04",
+ "version":"0.05",
"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"],
diff --git a/apps/red7game/red7.js b/apps/red7game/red7.js
index 2b22488b9..e2fe50f50 100644
--- a/apps/red7game/red7.js
+++ b/apps/red7game/red7.js
@@ -814,8 +814,20 @@ function drawMainMenu() {
}
}
menu["New Game"] = function() {
+ if(startedGame == true) {
+ E.showPrompt("Discard and start new game?").then(function(v) {
+ if(v) {
+ E.showMenu();
+ resetToNewGame();
+ } else {
+ E.showMenu();
+ drawScreen1();
+ }
+ });
+ } else {
E.showMenu();
resetToNewGame();
+ }
};
menu["Help"] = function() {
drawScreenHelp();
diff --git a/apps/sched/metadata.json b/apps/sched/metadata.json
index 1a4a64994..aa286ce6a 100644
--- a/apps/sched/metadata.json
+++ b/apps/sched/metadata.json
@@ -5,7 +5,7 @@
"description": "Scheduling library for alarms and timers",
"icon": "app.png",
"type": "scheduler",
- "tags": "tool,system,alarm",
+ "tags": "tool,system,alarm,clkinfo",
"supports": ["BANGLEJS","BANGLEJS2"],
"provides_modules" : ["sched"],
"default" : true,
diff --git a/apps/simplestpp/metadata.json b/apps/simplestpp/metadata.json
index 93ae72bbe..64dc19ae2 100644
--- a/apps/simplestpp/metadata.json
+++ b/apps/simplestpp/metadata.json
@@ -8,7 +8,7 @@
"icon": "app.png",
"screenshots": [{"url":"screenshot3.png"}],
"type": "clock",
- "tags": "clock",
+ "tags": "clock,clkinfo",
"supports": ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" },
"storage": [
diff --git a/apps/slopeclockpp/metadata.json b/apps/slopeclockpp/metadata.json
index 30bc2ea3e..116b6c665 100644
--- a/apps/slopeclockpp/metadata.json
+++ b/apps/slopeclockpp/metadata.json
@@ -5,7 +5,7 @@
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"}],
"type": "clock",
- "tags": "clock",
+ "tags": "clock,clkinfo",
"supports" : ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" },
"readme": "README.md",
diff --git a/apps/wid_edit/ChangeLog b/apps/wid_edit/ChangeLog
index d8e165029..279fa2438 100644
--- a/apps/wid_edit/ChangeLog
+++ b/apps/wid_edit/ChangeLog
@@ -2,3 +2,4 @@
0.02: Wrap loadWidgets instead of replacing to keep original functionality intact
Change back entry to menu option
Allow changing widgets into all areas, including bottom widget bar
+0.03: Fix editing widgets whose draw method takes the widget
diff --git a/apps/wid_edit/metadata.json b/apps/wid_edit/metadata.json
index d963a53d0..e80e45d45 100644
--- a/apps/wid_edit/metadata.json
+++ b/apps/wid_edit/metadata.json
@@ -1,6 +1,6 @@
{
"id": "wid_edit",
- "version": "0.02",
+ "version": "0.03",
"name": "Widget Editor",
"icon": "icon.png",
"description": "Customize widget locations",
diff --git a/apps/wid_edit/settings.js b/apps/wid_edit/settings.js
index 1d34ae0ca..be09923f2 100644
--- a/apps/wid_edit/settings.js
+++ b/apps/wid_edit/settings.js
@@ -67,7 +67,7 @@
function highlight() {
if (WIDGET.width > 0) {
// draw widget, then draw a highlighted border on top
- WIDGET.draw();
+ WIDGET.draw(WIDGET);
g.setColor(g.theme.fgH)
.drawRect(WIDGET.x, WIDGET.y, WIDGET.x+WIDGET.width-1, WIDGET.y+23);
} else {
diff --git a/apps/widalarmeta/ChangeLog b/apps/widalarmeta/ChangeLog
index f412fc45f..e014721f6 100644
--- a/apps/widalarmeta/ChangeLog
+++ b/apps/widalarmeta/ChangeLog
@@ -10,3 +10,4 @@
Redraw only every hour when no alarm in next 24h
0.07: Fix when no alarms are present
0.08: Selectable font. Allow to disable hour padding.
+0.09: Match draw() API e.g. to allow wid_edit to alter this widget
diff --git a/apps/widalarmeta/metadata.json b/apps/widalarmeta/metadata.json
index 5bb7f7795..66882c16f 100644
--- a/apps/widalarmeta/metadata.json
+++ b/apps/widalarmeta/metadata.json
@@ -2,7 +2,7 @@
"id": "widalarmeta",
"name": "Alarm & Timer ETA",
"shortName": "Alarm ETA",
- "version": "0.08",
+ "version": "0.09",
"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",
diff --git a/apps/widalarmeta/widget.js b/apps/widalarmeta/widget.js
index 77b7ebb88..d24b185d9 100644
--- a/apps/widalarmeta/widget.js
+++ b/apps/widalarmeta/widget.js
@@ -25,7 +25,7 @@
}
} // getNextAlarm
- function draw(fromInterval) {
+ function draw(_w, fromInterval) {
if (this.nextAlarm === undefined) {
let alarm = getNextAlarm();
if (alarm === undefined) {
@@ -101,8 +101,9 @@
clearTimeout(this.timeoutId);
}
this.timeoutId = setTimeout(()=>{
- WIDGETS["widalarmeta"].timeoutId = undefined;
- WIDGETS["widalarmeta"].draw(true);
+ var w = WIDGETS["widalarmeta"];
+ w.timeoutId = undefined;
+ w.draw(w, true);
}, timeout);
} /* draw */
diff --git a/apps/widbatpc/ChangeLog b/apps/widbatpc/ChangeLog
index 3592656a9..e9326fd2c 100644
--- a/apps/widbatpc/ChangeLog
+++ b/apps/widbatpc/ChangeLog
@@ -16,3 +16,4 @@
0.17: Add option 'Remove Jitter'='Drop only' to prevent percentage from getting up again when not charging
Add option to disable vibration when charger connects
0.18: Only redraw when values change
+0.19: Match draw() API e.g. to allow wid_edit to alter this widget
diff --git a/apps/widbatpc/metadata.json b/apps/widbatpc/metadata.json
index d361da442..4c364a864 100644
--- a/apps/widbatpc/metadata.json
+++ b/apps/widbatpc/metadata.json
@@ -2,7 +2,7 @@
"id": "widbatpc",
"name": "Battery Level Widget (with percentage)",
"shortName": "Battery Widget",
- "version": "0.18",
+ "version": "0.19",
"description": "Show the current battery level and charging status in the top right of the clock, with charge percentage",
"icon": "widget.png",
"type": "widget",
diff --git a/apps/widbatpc/widget.js b/apps/widbatpc/widget.js
index b508cce8b..7ba060d6d 100644
--- a/apps/widbatpc/widget.js
+++ b/apps/widbatpc/widget.js
@@ -181,7 +181,7 @@
if (on) update();
});
- var id = setInterval(()=>WIDGETS["batpc"].draw(true), intervalLow);
+ var id = setInterval(()=>WIDGETS["batpc"].draw(WIDGETS["batpc"], true), intervalLow);
WIDGETS["batpc"]={area:"tr",width:40,draw:draw,reload:reload};
setWidth();
diff --git a/apps/widmessages/ChangeLog b/apps/widmessages/ChangeLog
index 348d49528..507d9c13b 100644
--- a/apps/widmessages/ChangeLog
+++ b/apps/widmessages/ChangeLog
@@ -3,3 +3,4 @@
Remove library stub
0.03: Fix messages not showing if UI auto-open is disabled
0.04: Now shows message icons again (#2416)
+0.05: Match draw() API e.g. to allow wid_edit to alter this widget
diff --git a/apps/widmessages/metadata.json b/apps/widmessages/metadata.json
index 0e399f71f..f058beacc 100644
--- a/apps/widmessages/metadata.json
+++ b/apps/widmessages/metadata.json
@@ -1,7 +1,7 @@
{
"id": "widmessages",
"name": "Message Widget",
- "version": "0.04",
+ "version": "0.05",
"description": "Widget showing new messages",
"icon": "app.png",
"type": "widget",
diff --git a/apps/widmessages/widget.js b/apps/widmessages/widget.js
index 44f525ec8..357ca06e3 100644
--- a/apps/widmessages/widget.js
+++ b/apps/widmessages/widget.js
@@ -11,7 +11,7 @@
// the name still needs to be "messages": the library calls WIDGETS["messages'].hide()/show()
// see e.g. widmsggrid
WIDGETS["messages"] = {
- area: "tl", width: 0, srcs: [], draw: function(recall) {
+ area: "tl", width: 0, srcs: [], draw: function(_w, recall) {
// If we had a setTimeout queued from the last time we were called, remove it
if (WIDGETS["messages"].i) {
clearTimeout(WIDGETS["messages"].i);
@@ -42,7 +42,7 @@
this.x+12+i*24, this.y+12, {rotate: 0/*force centering*/});
}
}
- WIDGETS["messages"].i = setTimeout(() => WIDGETS["messages"].draw(true), 1000);
+ WIDGETS["messages"].i = setTimeout(() => WIDGETS["messages"].draw(WIDGETS["messages"], true), 1000);
if (process.env.HWVERSION>1) Bangle.on("touch", this.touch);
}, onMsg: function(type, msg) {
if (this.hidden) return;
diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js
index b27e4e26d..ecba1876e 100755
--- a/bin/sanitycheck.js
+++ b/bin/sanitycheck.js
@@ -116,7 +116,7 @@ apps.forEach((app,appIdx) => {
if (!app.id) ERROR(`App ${appIdx} has no id`);
var appDirRelative = APPSDIR_RELATIVE+app.id+"/";
var appDir = APPSDIR+app.id+"/";
- var metadataFile = appDirRelative+"metadata.json";
+ var metadataFile = appDirRelative+"metadata.json";
if (existingApps.includes(app.id)) ERROR(`Duplicate app '${app.id}'`, {file:metadataFile});
existingApps.push(app.id);
//console.log(`Checking ${app.id}...`);
@@ -124,6 +124,7 @@ apps.forEach((app,appIdx) => {
if (!fs.existsSync(APPSDIR+app.id)) ERROR(`App ${app.id} has no directory`);
if (!app.name) ERROR(`App ${app.id} has no name`, {file:metadataFile});
var isApp = !app.type || app.type=="app";
+ var appTags = app.tags ? app.tags.split(",") : [];
if (app.name.length>20 && !app.shortName && isApp) ERROR(`App ${app.id} has a long name, but no shortName`, {file:metadataFile});
if (app.type && !METADATA_TYPES.includes(app.type))
ERROR(`App ${app.id} 'type' is one one of `+METADATA_TYPES, {file:metadataFile});
@@ -174,6 +175,8 @@ apps.forEach((app,appIdx) => {
if (app.customConnect && !app.custom) ERROR(`App ${app.id} has customConnect but no customn HTML`, {file:metadataFile});
if (app.interface && !fs.existsSync(appDir+app.interface)) ERROR(`App ${app.id} interface HTML doesn't exist`, {file:metadataFile});
if (app.dependencies) {
+ if (app.dependencies.clock_info && !appTags.includes("clkinfo"))
+ WARN(`App ${app.id} uses clock_info but doesn't have clkinfo tag`, {file:metadataFile});
if (("object"==typeof app.dependencies) && !Array.isArray(app.dependencies)) {
Object.keys(app.dependencies).forEach(dependency => {
if (!["type","app","module","widget"].includes(app.dependencies[dependency]))
@@ -185,6 +188,8 @@ apps.forEach((app,appIdx) => {
ERROR(`App ${app.id} 'dependencies' must be an object`, {file:metadataFile});
}
+ if (app.storage.find(f=>f.name.endsWith(".clkinfo.js")) && !appTags.includes("clkinfo"))
+ WARN(`App ${app.id} provides ...clkinfo.js but doesn't have clkinfo tag`, {file:metadataFile});
var fileNames = [];
app.storage.forEach((file) => {
if (!file.name) ERROR(`App ${app.id} has a file with no name`, {file:metadataFile});
diff --git a/core b/core
index 425c4a98a..83d92f217 160000
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit 425c4a98aed7c4d9b640e37463b534a45a20def7
+Subproject commit 83d92f2178901aa3130643e3a580fdda0801f8c1
diff --git a/css/main.css b/css/main.css
index ceb9fcd17..2ea2ab40d 100644
--- a/css/main.css
+++ b/css/main.css
@@ -125,3 +125,16 @@ a.btn.btn-link.dropdown-toggle {
transform: translate(-50%,-50%);
content: url("data:image/svg+xml,%3C%3Fxml version='1.0'%3F%3E%3Csvg fill='rgb(87, 85, 217)' xmlns='http://www.w3.org/2000/svg' viewBox='2 2 28 28' width='1.5em' height='1.5em'%3E%3Cpath d='M 6 4 C 4.895 4 4 4.895 4 6 L 4 24 C 4 25.105 4.895 26 6 26 L 24 26 C 25.105 26 26 25.105 26 24 L 26 8 L 22 4 L 20 4 L 20 10 C 20 10.552 19.552 11 19 11 L 10 11 C 9.448 11 9 10.552 9 10 L 9 4 L 6 4 z M 16 4 L 16 9 L 18 9 L 18 4 L 16 4 z M 10 16 L 20 16 C 21.105 16 22 16.895 22 18 L 22 24 L 8 24 L 8 18 C 8 16.895 8.895 16 10 16 z'/%3E%3C/svg%3E");
}
+
+/* https://github.com/picturepan2/spectre/issues/595 */
+.chip.tooltip:hover {
+ overflow: visible;
+ overflow-y: unset;
+}
+
+/* Normally tooltips don't wrap, but if you enable it, then they wrap until they are really thin!
+Not sure how to get 'normal' wrap behaviour (eg fill up until max-width, then wrap) */
+/*.tooltip:hover::after {
+ white-space: normal;
+ min-width: 160px;
+}*/
\ No newline at end of file
diff --git a/index.html b/index.html
index 1ed95107e..d7ca4169f 100644
--- a/index.html
+++ b/index.html
@@ -73,25 +73,26 @@