Merge remote-tracking branch 'upstream/master'

pull/2713/head
Hugh Barney 2023-04-28 19:23:22 +01:00
commit c6fc025fd0
36 changed files with 145 additions and 81 deletions

View File

@ -277,7 +277,7 @@ and which gives information about the app for the Launcher.
// 'game' - a game // 'game' - a game
// 'bluetooth' - uses Bluetooth LE // 'bluetooth' - uses Bluetooth LE
// 'system' - used by the system // '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 "supports": ["BANGLEJS2"], // List of device IDs supported, either BANGLEJS or BANGLEJS2
"dependencies" : { "notify":"type" } // optional, app 'types' we depend on (see "type" above) "dependencies" : { "notify":"type" } // optional, app 'types' we depend on (see "type" above)
"dependencies" : { "messages":"app" } // optional, depend on a specific app ID "dependencies" : { "messages":"app" } // optional, depend on a specific app ID

View File

@ -20,9 +20,6 @@
<title>Bangle.js App Loader</title> <title>Bangle.js App Loader</title>
</head> </head>
<body> <body>
<!--<button id="test">Test</button>
<div id="status"></div>-->
<header class="navbar-primary navbar"> <header class="navbar-primary navbar">
<section class="navbar-section" > <section class="navbar-section" >
<a href="https://banglejs.com" target="_blank" class="navbar-brand mr-2" ><img src="img/banglejs-logo-sml.png" alt="Bangle.js"> <a href="https://banglejs.com" target="_blank" class="navbar-brand mr-2" ><img src="img/banglejs-logo-sml.png" alt="Bangle.js">
@ -76,20 +73,26 @@
</ul> </ul>
</div> </div>
<div class="filter-nav"> <div class="filter-nav">
<label class="chip active" filterid="">Default</label> <label class="chip active" filterid="" data-tooltip="Show all apps">All</label>
<label class="chip" filterid="clock">Clocks</label> <label class="chip tooltip" filterid="clock" data-tooltip="To tell the time!">Clocks</label>
<label class="chip" filterid="game">Games</label> <label class="chip tooltip" filterid="launch" data-tooltip="Choose which apps to launch">Launchers</label>
<label class="chip" filterid="tool">Tools</label> <label class="chip tooltip" filterid="game" data-tooltip="Have fun!">Games</label>
<label class="chip" filterid="widget">Widgets</label> <label class="chip tooltip" filterid="tool" data-tooltip="Useful applications">Tools</label>
<label class="chip" filterid="bluetooth">Bluetooth</label> <label class="chip tooltip" filterid="textinput" data-tooltip="To allow you to enter text">Keyboards</label>
<label class="chip" filterid="outdoors">Outdoors</label> <label class="chip tooltip" filterid="widget" data-tooltip="Appear in the top bar of Bangle.js apps">Widgets</label>
<label class="chip" filterid="favourites">Favourites</label> <label class="chip tooltip" filterid="bluetooth" data-tooltip="Using Bluetooth Functionality">Bluetooth</label>
<label class="chip tooltip" filterid="outdoors" data-tooltip="For outdoor use">Outdoors</label>
<label class="chip tooltip" filterid="ram" data-tooltip="Apps that don't save anything to flash memory">Online</label>
<label class="chip tooltip" filterid="clkinfo" data-tooltip="Info displayed on clocks, or clocks with info">Clock Info</label>
<label class="chip tooltip" filterid="favourites" data-tooltip="Apps that you've liked ❤️">Favourites</label>
</div> </div>
<div class="sort-nav hidden"> <div class="sort-nav hidden">
<span>Sort by:</span> <span>Sort by:</span>
<label class="chip active" sortid="">None</label> <label class="chip active" sortid="">None</label>
<label class="chip" sortid="created">New</label> <label class="chip hidden tooltip" sortid="created" data-tooltip="Most recent apps">New</label>
<label class="chip" sortid="modified">Updated</label> <label class="chip hidden tooltip" sortid="modified" data-tooltip="Most recently changed">Updated</label>
<label class="chip hidden tooltip" sortid="installs" data-tooltip="Most installed by users">Installed</label>
<label class="chip hidden tooltip" sortid="favourites" data-tooltip="Most liked by users">Favourited</label>
</div> </div>
</div> </div>
@ -130,13 +133,14 @@
<p>Using <a href="https://espruino.com/" target="_blank">Espruino</a>, Icons from <a href="https://icons8.com/" target="_blank">icons8.com</a></p> <p>Using <a href="https://espruino.com/" target="_blank">Espruino</a>, Icons from <a href="https://icons8.com/" target="_blank">icons8.com</a></p>
<h3>Utilities</h3> <h3>Utilities</h3>
<p><button class="btn" id="settime">Set Bangle.js Time</button> <p><button class="btn tooltip" id="settime" data-tooltip="Set the Bangle's time to your Browser's time">Set Bangle.js Time</button>
<button class="btn" id="removeall" data-tooltip="Delete everything from your Bangle, leaving it blank">Remove all Apps</button> <button class="btn tooltip" id="removeall" data-tooltip="Delete everything, leave it blank">Remove all Apps</button>
<button class="btn" id="reinstallall" data-tooltip="Remove and re-install every app, leaving all other data intact">Reinstall apps</button> <button class="btn tooltip" id="reinstallall" data-tooltip="Re-install every app, leave all data">Reinstall apps</button>
<button class="btn" id="installdefault">Install default apps</button> <button class="btn tooltip" id="installdefault" data-tooltip="Delete everything, install default apps">Install default apps</button>
<button class="btn" id="installfavourite" data-tooltip="Delete everything, install apps you've marked as favourites">Install favourite apps</button></p> <button class="btn tooltip" id="installfavourite" data-tooltip="Delete everything, install your favourites">Install favourite apps</button>
<p><button class="btn tooltip tooltip-right" id="downloadallapps" data-tooltip="Download all Bangle.js files to a ZIP file">Backup</button> <button class="btn tooltip" id="newGithubIssue" data-tooltip="Create a new issue on GitHub">New issue on GitHub</button></p>
<button class="btn tooltip tooltip-right" id="uploadallapps" data-tooltip="Restore Bangle.js from a ZIP file">Restore</button></p> <p><button class="btn tooltip" id="downloadallapps" data-tooltip="Download all Bangle.js files to a ZIP file">Backup</button>
<button class="btn tooltip" id="uploadallapps" data-tooltip="Restore Bangle.js from a ZIP file">Restore</button></p>
<h3>Settings</h3> <h3>Settings</h3>
<div class="form-group"> <div class="form-group">
<label class="form-switch"> <label class="form-switch">
@ -147,12 +151,24 @@
<input type="checkbox" id="settings-settime"> <input type="checkbox" id="settings-settime">
<i class="form-icon"></i> Always update time when we connect <i class="form-icon"></i> Always update time when we connect
</label> </label>
<label class="form-switch">
<input type="checkbox" id="settings-usage-stats">
<i class="form-icon"></i> Send app analytics to banglejs.com (apps installed, favourites, firmware version).<br/>
<small>Used for 'Sort by Installed/Favourited' functionality. See the <a href="http://www.espruino.com/Privacy">privacy policy</a></small>.
</label>
<div class="form-group"> <div class="form-group">
<select class="form-select form-inline" id="settings-lang" style="width: 10em"> <select class="form-select form-inline" id="settings-lang" style="width: 10em">
<option value="">None (English)</option> <option value="">None (English)</option>
</select>&nbsp;&nbsp;<span>Translations (<a href="https://github.com/espruino/BangleApps/issues/1311" target="_blank">BETA - more info</a>). Any apps that are uploaded to Bangle.js after changing this will have any text automatically translated.</span> </select>&nbsp;&nbsp;<span>Translations (<a href="https://github.com/espruino/BangleApps/issues/1311" target="_blank">BETA - more info</a>). Any apps that are uploaded to Bangle.js after changing this will have any text automatically translated.</span>
</div> </div>
<button class="btn" id="defaultsettings">Default settings</button> <details>
<summary>Advanced Options</summary>
<label class="form-switch">
<input type="checkbox" id="settings-minify">
<i class="form-icon"></i> Minify apps before upload (⚠DANGER⚠: Not recommended. Uploads smaller, faster apps but this <b>will</b> break many apps)
</label>
<button class="btn" id="defaultsettings">Reset to default settings</button>
</details>
</div> </div>
<div id="more-deviceinfo" style="display:none"> <div id="more-deviceinfo" style="display:none">
<h3>Device info</h3> <h3>Device info</h3>

View File

@ -9,7 +9,7 @@
"dependencies" : { "clock_info":"module" }, "dependencies" : { "clock_info":"module" },
"description": "A watch face that was designed by an AI (stable diffusion) and implemented by a human.", "description": "A watch face that was designed by an AI (stable diffusion) and implemented by a human.",
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock,clkinfo",
"screenshots": [ "screenshots": [
{"url":"orig.png"}, {"url":"orig.png"},
{"url":"impl.png"}, {"url":"impl.png"},

View File

@ -1,14 +1,16 @@
{ {
"id": "assistedgps", "id": "assistedgps",
"name": "Assisted GPS Updater (AGPS)", "name": "Assisted GPS Updater (AGPS)",
"shortName": "AGPS",
"version": "0.05", "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.", "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, "sortorder": -1,
"icon": "app.png", "icon": "app.png",
"type": "RAM", "type": "RAM",
"tags": "tool,outdoors,agps,gps,a-gps", "tags": "tool,outdoors,agps,gps,a-gps,agps",
"supports": ["BANGLEJS","BANGLEJS2"], "supports": ["BANGLEJS","BANGLEJS2"],
"custom": "custom.html", "custom": "custom.html",
"customConnect": true, "customConnect": true,
"storage": [] "storage": [],
"sortorder": -1
} }

View File

@ -6,7 +6,7 @@
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}], "screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}],
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock,clkinfo",
"supports" : ["BANGLEJS2"], "supports" : ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" }, "dependencies" : { "clock_info":"module" },
"readme": "README.md", "readme": "README.md",

View File

@ -2,3 +2,4 @@
0.02: Use ClockFace library, add settings 0.02: Use ClockFace library, add settings
0.03: Use ClockFace_menu.addSettingsFile 0.03: Use ClockFace_menu.addSettingsFile
0.04: Hide widgets instead of not loading them at all 0.04: Hide widgets instead of not loading them at all
0.05: Support Bangle.js 2

View File

@ -44,7 +44,7 @@ const clock = new ClockFace({
precision: 1, precision: 1,
settingsFile: "cogclock.settings.json", settingsFile: "cogclock.settings.json",
init: function() { 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.r3 = Math.min(Bangle.appRect.w/2, Bangle.appRect.h/2); // outer radius
this.r2 = (this.r1*3+this.r3*2)/5; this.r2 = (this.r1*3+this.r3*2)/5;
this.teeth = 12; this.teeth = 12;

View File

@ -1,13 +1,13 @@
{ {
"id": "cogclock", "id": "cogclock",
"name": "Cog Clock", "name": "Cog Clock",
"version": "0.04", "version": "0.05",
"description": "A cross-shaped clock inside a cog", "description": "A cross-shaped clock inside a cog",
"icon": "icon.png", "icon": "icon.png",
"screenshots": [{"url":"screenshot.png"}], "screenshots": [{"url":"screenshot_b1.png"},{"url":"screenshot_b2.png"}],
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock",
"supports": ["BANGLEJS"], "supports": ["BANGLEJS","BANGLEJS2"],
"allow_emulator": true, "allow_emulator": true,
"storage": [ "storage": [
{"name":"cogclock.app.js","url":"app.js"}, {"name":"cogclock.app.js","url":"app.js"},

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -15,7 +15,7 @@
<p>Your current firmware version is <span id="fw-version" style="font-weight:bold">unknown</span> and DFU is <span id="boot-version" style="font-weight:bold">unknown</span></p> <p>Your current firmware version is <span id="fw-version" style="font-weight:bold">unknown</span> and DFU is <span id="boot-version" style="font-weight:bold">unknown</span></p>
</ul> </ul>
<div id="fw-ok" style="display:none"> <div id="fw-ok" style="display:none">
<p>If you have an early (KickStarter or developer) Bangle.js device and still have the old 2v10.x DFU, the Firmware Update <p id="fw-old-bootloader-msg">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 <a href="bootloader_espruino_2v12_banglejs2.hex" class="fw-link">click here to update to DFU 2v12</a> and then click the 'Upload' button that appears.</p> will fail with a message about the DFU version. If so, please <a href="bootloader_espruino_2v12_banglejs2.hex" class="fw-link">click here to update to DFU 2v12</a> and then click the 'Upload' button that appears.</p>
<div id="latest-firmware" style="display:none"> <div id="latest-firmware" style="display:none">
<p>The currently available Espruino firmware releases are:</p> <p>The currently available Espruino firmware releases are:</p>
@ -104,6 +104,9 @@ function onInit(device) {
version += `(&#9888; update required)`; version += `(&#9888; update required)`;
} }
document.getElementById("boot-version").innerHTML = version; 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<fwlinks.length;i++) for (var i=0;i<fwlinks.length;i++)
fwlinks[i].addEventListener("click", e => { fwlinks[i].addEventListener("click", e => {
e.preventDefault(); 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 document.getElementById("upload").style = ""; // show upload
}); });
}); });

View File

@ -7,7 +7,7 @@
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot3.png"}], "screenshots": [{"url":"screenshot3.png"}],
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock,clkinfo",
"supports": ["BANGLEJS2"], "supports": ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" }, "dependencies" : { "clock_info":"module" },
"storage": [ "storage": [

View File

@ -7,7 +7,7 @@
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot.png"}, {"url":"screenshot_2.png"}], "screenshots": [{"url":"screenshot.png"}, {"url":"screenshot_2.png"}],
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock,clkinfo",
"supports": ["BANGLEJS2"], "supports": ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" }, "dependencies" : { "clock_info":"module" },
"storage": [ "storage": [

View File

@ -289,13 +289,14 @@
l = f.readLine(f); l = f.readLine(f);
} }
var asyncTimeout; var asyncTimeout;
var color = g.getColor();
function plotPartial() { function plotPartial() {
asyncTimeout = undefined; asyncTimeout = undefined;
if (l===undefined) return; // empty file? if (l===undefined) return; // empty file?
mp = m.latLonToXY(+c[la], +c[lo]); 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); 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--) { while(l && n--) {
c = l.split(","); c = l.split(",");
if (c[la]) { if (c[la]) {

View File

@ -2,3 +2,4 @@
0.02: Fix mistake preventing game from ending in some cases. 0.02: Fix mistake preventing game from ending in some cases.
0.03: Update help screen with more details. 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.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.

View File

@ -2,7 +2,7 @@
"name": "Red 7 Card Game", "name": "Red 7 Card Game",
"shortName" : "Red 7", "shortName" : "Red 7",
"icon": "icon.png", "icon": "icon.png",
"version":"0.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!", "description": "An implementation of the card game Red 7 for your watch. Play against the AI and be the last player still in the game to win!",
"tags": "game", "tags": "game",
"supports":["BANGLEJS2"], "supports":["BANGLEJS2"],

View File

@ -814,8 +814,20 @@ function drawMainMenu() {
} }
} }
menu["New Game"] = function() { 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(); E.showMenu();
resetToNewGame(); resetToNewGame();
}
}; };
menu["Help"] = function() { menu["Help"] = function() {
drawScreenHelp(); drawScreenHelp();

View File

@ -5,7 +5,7 @@
"description": "Scheduling library for alarms and timers", "description": "Scheduling library for alarms and timers",
"icon": "app.png", "icon": "app.png",
"type": "scheduler", "type": "scheduler",
"tags": "tool,system,alarm", "tags": "tool,system,alarm,clkinfo",
"supports": ["BANGLEJS","BANGLEJS2"], "supports": ["BANGLEJS","BANGLEJS2"],
"provides_modules" : ["sched"], "provides_modules" : ["sched"],
"default" : true, "default" : true,

View File

@ -8,7 +8,7 @@
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot3.png"}], "screenshots": [{"url":"screenshot3.png"}],
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock,clkinfo",
"supports": ["BANGLEJS2"], "supports": ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" }, "dependencies" : { "clock_info":"module" },
"storage": [ "storage": [

View File

@ -5,7 +5,7 @@
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot.png"}], "screenshots": [{"url":"screenshot.png"}],
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock,clkinfo",
"supports" : ["BANGLEJS2"], "supports" : ["BANGLEJS2"],
"dependencies" : { "clock_info":"module" }, "dependencies" : { "clock_info":"module" },
"readme": "README.md", "readme": "README.md",

View File

@ -2,3 +2,4 @@
0.02: Wrap loadWidgets instead of replacing to keep original functionality intact 0.02: Wrap loadWidgets instead of replacing to keep original functionality intact
Change back entry to menu option Change back entry to menu option
Allow changing widgets into all areas, including bottom widget bar Allow changing widgets into all areas, including bottom widget bar
0.03: Fix editing widgets whose draw method takes the widget

View File

@ -1,6 +1,6 @@
{ {
"id": "wid_edit", "id": "wid_edit",
"version": "0.02", "version": "0.03",
"name": "Widget Editor", "name": "Widget Editor",
"icon": "icon.png", "icon": "icon.png",
"description": "Customize widget locations", "description": "Customize widget locations",

View File

@ -67,7 +67,7 @@
function highlight() { function highlight() {
if (WIDGET.width > 0) { if (WIDGET.width > 0) {
// draw widget, then draw a highlighted border on top // draw widget, then draw a highlighted border on top
WIDGET.draw(); WIDGET.draw(WIDGET);
g.setColor(g.theme.fgH) g.setColor(g.theme.fgH)
.drawRect(WIDGET.x, WIDGET.y, WIDGET.x+WIDGET.width-1, WIDGET.y+23); .drawRect(WIDGET.x, WIDGET.y, WIDGET.x+WIDGET.width-1, WIDGET.y+23);
} else { } else {

View File

@ -10,3 +10,4 @@
Redraw only every hour when no alarm in next 24h Redraw only every hour when no alarm in next 24h
0.07: Fix when no alarms are present 0.07: Fix when no alarms are present
0.08: Selectable font. Allow to disable hour padding. 0.08: Selectable font. Allow to disable hour padding.
0.09: Match draw() API e.g. to allow wid_edit to alter this widget

View File

@ -2,7 +2,7 @@
"id": "widalarmeta", "id": "widalarmeta",
"name": "Alarm & Timer ETA", "name": "Alarm & Timer ETA",
"shortName": "Alarm 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).", "description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h (configurable).",
"icon": "widget.png", "icon": "widget.png",
"type": "widget", "type": "widget",

View File

@ -25,7 +25,7 @@
} }
} // getNextAlarm } // getNextAlarm
function draw(fromInterval) { function draw(_w, fromInterval) {
if (this.nextAlarm === undefined) { if (this.nextAlarm === undefined) {
let alarm = getNextAlarm(); let alarm = getNextAlarm();
if (alarm === undefined) { if (alarm === undefined) {
@ -101,8 +101,9 @@
clearTimeout(this.timeoutId); clearTimeout(this.timeoutId);
} }
this.timeoutId = setTimeout(()=>{ this.timeoutId = setTimeout(()=>{
WIDGETS["widalarmeta"].timeoutId = undefined; var w = WIDGETS["widalarmeta"];
WIDGETS["widalarmeta"].draw(true); w.timeoutId = undefined;
w.draw(w, true);
}, timeout); }, timeout);
} /* draw */ } /* draw */

View File

@ -16,3 +16,4 @@
0.17: Add option 'Remove Jitter'='Drop only' to prevent percentage from getting up again when not charging 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 Add option to disable vibration when charger connects
0.18: Only redraw when values change 0.18: Only redraw when values change
0.19: Match draw() API e.g. to allow wid_edit to alter this widget

View File

@ -2,7 +2,7 @@
"id": "widbatpc", "id": "widbatpc",
"name": "Battery Level Widget (with percentage)", "name": "Battery Level Widget (with percentage)",
"shortName": "Battery Widget", "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", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage",
"icon": "widget.png", "icon": "widget.png",
"type": "widget", "type": "widget",

View File

@ -181,7 +181,7 @@
if (on) update(); 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}; WIDGETS["batpc"]={area:"tr",width:40,draw:draw,reload:reload};
setWidth(); setWidth();

View File

@ -3,3 +3,4 @@
Remove library stub Remove library stub
0.03: Fix messages not showing if UI auto-open is disabled 0.03: Fix messages not showing if UI auto-open is disabled
0.04: Now shows message icons again (#2416) 0.04: Now shows message icons again (#2416)
0.05: Match draw() API e.g. to allow wid_edit to alter this widget

View File

@ -1,7 +1,7 @@
{ {
"id": "widmessages", "id": "widmessages",
"name": "Message Widget", "name": "Message Widget",
"version": "0.04", "version": "0.05",
"description": "Widget showing new messages", "description": "Widget showing new messages",
"icon": "app.png", "icon": "app.png",
"type": "widget", "type": "widget",

View File

@ -11,7 +11,7 @@
// the name still needs to be "messages": the library calls WIDGETS["messages'].hide()/show() // the name still needs to be "messages": the library calls WIDGETS["messages'].hide()/show()
// see e.g. widmsggrid // see e.g. widmsggrid
WIDGETS["messages"] = { 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 we had a setTimeout queued from the last time we were called, remove it
if (WIDGETS["messages"].i) { if (WIDGETS["messages"].i) {
clearTimeout(WIDGETS["messages"].i); clearTimeout(WIDGETS["messages"].i);
@ -42,7 +42,7 @@
this.x+12+i*24, this.y+12, {rotate: 0/*force centering*/}); 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); if (process.env.HWVERSION>1) Bangle.on("touch", this.touch);
}, onMsg: function(type, msg) { }, onMsg: function(type, msg) {
if (this.hidden) return; if (this.hidden) return;

View File

@ -124,6 +124,7 @@ apps.forEach((app,appIdx) => {
if (!fs.existsSync(APPSDIR+app.id)) ERROR(`App ${app.id} has no directory`); 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}); if (!app.name) ERROR(`App ${app.id} has no name`, {file:metadataFile});
var isApp = !app.type || app.type=="app"; 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.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)) if (app.type && !METADATA_TYPES.includes(app.type))
ERROR(`App ${app.id} 'type' is one one of `+METADATA_TYPES, {file:metadataFile}); 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.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.interface && !fs.existsSync(appDir+app.interface)) ERROR(`App ${app.id} interface HTML doesn't exist`, {file:metadataFile});
if (app.dependencies) { 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)) { if (("object"==typeof app.dependencies) && !Array.isArray(app.dependencies)) {
Object.keys(app.dependencies).forEach(dependency => { Object.keys(app.dependencies).forEach(dependency => {
if (!["type","app","module","widget"].includes(app.dependencies[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}); 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 = []; var fileNames = [];
app.storage.forEach((file) => { app.storage.forEach((file) => {
if (!file.name) ERROR(`App ${app.id} has a file with no name`, {file:metadataFile}); if (!file.name) ERROR(`App ${app.id} has a file with no name`, {file:metadataFile});

2
core

@ -1 +1 @@
Subproject commit 425c4a98aed7c4d9b640e37463b534a45a20def7 Subproject commit 83d92f2178901aa3130643e3a580fdda0801f8c1

View File

@ -125,3 +125,16 @@ a.btn.btn-link.dropdown-toggle {
transform: translate(-50%,-50%); 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"); 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;
}*/

View File

@ -73,25 +73,26 @@
</ul> </ul>
</div> </div>
<div class="filter-nav"> <div class="filter-nav">
<label class="chip active" filterid="">Default</label> <label class="chip active" filterid="" data-tooltip="Show all apps">All</label>
<label class="chip" filterid="clock">Clocks</label> <label class="chip tooltip" filterid="clock" data-tooltip="To tell the time!">Clocks</label>
<label class="chip" filterid="launch">Launchers</label> <label class="chip tooltip" filterid="launch" data-tooltip="Choose which apps to launch">Launchers</label>
<label class="chip" filterid="game">Games</label> <label class="chip tooltip" filterid="game" data-tooltip="Have fun!">Games</label>
<label class="chip" filterid="tool">Tools</label> <label class="chip tooltip" filterid="tool" data-tooltip="Useful applications">Tools</label>
<label class="chip" filterid="textinput">Keyboards</label> <label class="chip tooltip" filterid="textinput" data-tooltip="To allow you to enter text">Keyboards</label>
<label class="chip" filterid="widget">Widgets</label> <label class="chip tooltip" filterid="widget" data-tooltip="Appear in the top bar of Bangle.js apps">Widgets</label>
<label class="chip" filterid="bluetooth">Bluetooth</label> <label class="chip tooltip" filterid="bluetooth" data-tooltip="Using Bluetooth Functionality">Bluetooth</label>
<label class="chip" filterid="outdoors">Outdoors</label> <label class="chip tooltip" filterid="outdoors" data-tooltip="For outdoor use">Outdoors</label>
<label class="chip" filterid="ram">Online</label> <label class="chip tooltip" filterid="ram" data-tooltip="Apps that don't save anything to flash memory">Online</label>
<label class="chip" filterid="favourites">Favourites</label> <label class="chip tooltip" filterid="clkinfo" data-tooltip="Info displayed on clocks, or clocks with info">Clock Info</label>
<label class="chip tooltip" filterid="favourites" data-tooltip="Apps that you've liked ❤️">Favourites</label>
</div> </div>
<div class="sort-nav hidden"> <div class="sort-nav hidden">
<span>Sort by:</span> <span>Sort by:</span>
<label class="chip active" sortid="">None</label> <label class="chip active" sortid="">None</label>
<label class="chip hidden" sortid="created">New</label> <label class="chip hidden tooltip" sortid="created" data-tooltip="Most recent apps">New</label>
<label class="chip hidden" sortid="modified">Updated</label> <label class="chip hidden tooltip" sortid="modified" data-tooltip="Most recently changed">Updated</label>
<label class="chip hidden" sortid="installs">Installed</label> <label class="chip hidden tooltip" sortid="installs" data-tooltip="Most installed by users">Installed</label>
<label class="chip hidden" sortid="favourites">Favourited</label> <label class="chip hidden tooltip" sortid="favourites" data-tooltip="Most liked by users">Favourited</label>
</div> </div>
</div> </div>
@ -132,24 +133,20 @@
<p>Using <a href="https://espruino.com/" target="_blank">Espruino</a>, Icons from <a href="https://icons8.com/" target="_blank">icons8.com</a></p> <p>Using <a href="https://espruino.com/" target="_blank">Espruino</a>, Icons from <a href="https://icons8.com/" target="_blank">icons8.com</a></p>
<h3>Utilities</h3> <h3>Utilities</h3>
<p><button class="btn" id="settime">Set Bangle.js Time</button> <p><button class="btn tooltip" id="settime" data-tooltip="Set the Bangle's time to your Browser's time">Set Bangle.js Time</button>
<button class="btn" id="removeall" data-tooltip="Delete everything from your Bangle, leaving it blank">Remove all Apps</button> <button class="btn tooltip" id="removeall" data-tooltip="Delete everything, leave it blank">Remove all Apps</button>
<button class="btn" id="reinstallall" data-tooltip="Remove and re-install every app, leaving all other data intact">Reinstall apps</button> <button class="btn tooltip" id="reinstallall" data-tooltip="Re-install every app, leave all data">Reinstall apps</button>
<button class="btn" id="installdefault">Install default apps</button> <button class="btn tooltip" id="installdefault" data-tooltip="Delete everything, install default apps">Install default apps</button>
<button class="btn" id="installfavourite" data-tooltip="Delete everything, install apps you've marked as favourites">Install favourite apps</button> <button class="btn tooltip" id="installfavourite" data-tooltip="Delete everything, install your favourites">Install favourite apps</button>
<button class="btn" id="newGithubIssue" data-tooltip="Create a new issue on github">New issue on github</button></p> <button class="btn tooltip" id="newGithubIssue" data-tooltip="Create a new issue on GitHub">New issue on GitHub</button></p>
<p><button class="btn tooltip tooltip-right" id="downloadallapps" data-tooltip="Download all Bangle.js files to a ZIP file">Backup</button> <p><button class="btn tooltip" id="downloadallapps" data-tooltip="Download all Bangle.js files to a ZIP file">Backup</button>
<button class="btn tooltip tooltip-right" id="uploadallapps" data-tooltip="Restore Bangle.js from a ZIP file">Restore</button></p> <button class="btn tooltip" id="uploadallapps" data-tooltip="Restore Bangle.js from a ZIP file">Restore</button></p>
<h3>Settings</h3> <h3>Settings</h3>
<div class="form-group"> <div class="form-group">
<label class="form-switch"> <label class="form-switch">
<input type="checkbox" id="settings-pretokenise"> <input type="checkbox" id="settings-pretokenise">
<i class="form-icon"></i> Pretokenise apps before upload (smaller, faster apps) <i class="form-icon"></i> Pretokenise apps before upload (smaller, faster apps)
</label> </label>
<label class="form-switch">
<input type="checkbox" id="settings-minify">
<i class="form-icon"></i> Minify apps before upload (BETA, not recommended. Uploads smaller, faster apps but this may cause some apps to stop working)
</label>
<label class="form-switch"> <label class="form-switch">
<input type="checkbox" id="settings-settime"> <input type="checkbox" id="settings-settime">
<i class="form-icon"></i> Always update time when we connect <i class="form-icon"></i> Always update time when we connect
@ -168,7 +165,14 @@
<option value="">None (English)</option> <option value="">None (English)</option>
</select>&nbsp;&nbsp;<span>Translations (<a href="https://github.com/espruino/BangleApps/issues/1311" target="_blank">BETA - more info</a>). Any apps that are uploaded to Bangle.js after changing this will have any text automatically translated.</span> </select>&nbsp;&nbsp;<span>Translations (<a href="https://github.com/espruino/BangleApps/issues/1311" target="_blank">BETA - more info</a>). Any apps that are uploaded to Bangle.js after changing this will have any text automatically translated.</span>
</div> </div>
<button class="btn" id="defaultsettings">Default settings</button> <details>
<summary>Advanced Options</summary>
<label class="form-switch">
<input type="checkbox" id="settings-minify">
<i class="form-icon"></i> Minify apps before upload (⚠DANGER⚠: Not recommended. Uploads smaller, faster apps but this <b>will</b> break many apps)
</label>
<button class="btn" id="defaultsettings">Reset to default settings</button>
</details>
</div> </div>
<div id="more-deviceinfo" style="display:none"> <div id="more-deviceinfo" style="display:none">
<h3>Device info</h3> <h3>Device info</h3>