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
// '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

View File

@ -20,9 +20,6 @@
<title>Bangle.js App Loader</title>
</head>
<body>
<!--<button id="test">Test</button>
<div id="status"></div>-->
<header class="navbar-primary navbar">
<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">
@ -76,20 +73,26 @@
</ul>
</div>
<div class="filter-nav">
<label class="chip active" filterid="">Default</label>
<label class="chip" filterid="clock">Clocks</label>
<label class="chip" filterid="game">Games</label>
<label class="chip" filterid="tool">Tools</label>
<label class="chip" filterid="widget">Widgets</label>
<label class="chip" filterid="bluetooth">Bluetooth</label>
<label class="chip" filterid="outdoors">Outdoors</label>
<label class="chip" filterid="favourites">Favourites</label>
<label class="chip active" filterid="" data-tooltip="Show all apps">All</label>
<label class="chip tooltip" filterid="clock" data-tooltip="To tell the time!">Clocks</label>
<label class="chip tooltip" filterid="launch" data-tooltip="Choose which apps to launch">Launchers</label>
<label class="chip tooltip" filterid="game" data-tooltip="Have fun!">Games</label>
<label class="chip tooltip" filterid="tool" data-tooltip="Useful applications">Tools</label>
<label class="chip tooltip" filterid="textinput" data-tooltip="To allow you to enter text">Keyboards</label>
<label class="chip tooltip" filterid="widget" data-tooltip="Appear in the top bar of Bangle.js apps">Widgets</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 class="sort-nav hidden">
<span>Sort by:</span>
<label class="chip active" sortid="">None</label>
<label class="chip" sortid="created">New</label>
<label class="chip" sortid="modified">Updated</label>
<label class="chip hidden tooltip" sortid="created" data-tooltip="Most recent apps">New</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>
@ -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>
<h3>Utilities</h3>
<p><button class="btn" id="settime">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" id="reinstallall" data-tooltip="Remove and re-install every app, leaving all other data intact">Reinstall apps</button>
<button class="btn" id="installdefault">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>
<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 tooltip-right" id="uploadallapps" data-tooltip="Restore Bangle.js from a ZIP file">Restore</button></p>
<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 tooltip" id="removeall" data-tooltip="Delete everything, leave it blank">Remove all Apps</button>
<button class="btn tooltip" id="reinstallall" data-tooltip="Re-install every app, leave all data">Reinstall apps</button>
<button class="btn tooltip" id="installdefault" data-tooltip="Delete everything, install default apps">Install default apps</button>
<button class="btn tooltip" id="installfavourite" data-tooltip="Delete everything, install your favourites">Install favourite apps</button>
<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" 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>
<div class="form-group">
<label class="form-switch">
@ -147,12 +151,24 @@
<input type="checkbox" id="settings-settime">
<i class="form-icon"></i> Always update time when we connect
</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">
<select class="form-select form-inline" id="settings-lang" style="width: 10em">
<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>
</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 id="more-deviceinfo" style="display:none">
<h3>Device info</h3>

View File

@ -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"},

View File

@ -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
}

View File

@ -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",

View File

@ -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

View File

@ -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;

View File

@ -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"},

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>
</ul>
<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>
<div id="latest-firmware" style="display:none">
<p>The currently available Espruino firmware releases are:</p>
@ -104,6 +104,9 @@ function onInit(device) {
version += `(&#9888; 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<fwlinks.length;i++)
fwlinks[i].addEventListener("click", e => {
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
});
});

View File

@ -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": [

View File

@ -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": [

View File

@ -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]) {

View File

@ -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.

View File

@ -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"],

View File

@ -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();

View File

@ -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,

View File

@ -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": [

View File

@ -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",

View File

@ -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

View File

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

View File

@ -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 {

View File

@ -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

View File

@ -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",

View File

@ -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 */

View File

@ -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

View File

@ -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",

View File

@ -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();

View File

@ -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

View File

@ -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",

View File

@ -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;

View File

@ -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});

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%);
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>
</div>
<div class="filter-nav">
<label class="chip active" filterid="">Default</label>
<label class="chip" filterid="clock">Clocks</label>
<label class="chip" filterid="launch">Launchers</label>
<label class="chip" filterid="game">Games</label>
<label class="chip" filterid="tool">Tools</label>
<label class="chip" filterid="textinput">Keyboards</label>
<label class="chip" filterid="widget">Widgets</label>
<label class="chip" filterid="bluetooth">Bluetooth</label>
<label class="chip" filterid="outdoors">Outdoors</label>
<label class="chip" filterid="ram">Online</label>
<label class="chip" filterid="favourites">Favourites</label>
<label class="chip active" filterid="" data-tooltip="Show all apps">All</label>
<label class="chip tooltip" filterid="clock" data-tooltip="To tell the time!">Clocks</label>
<label class="chip tooltip" filterid="launch" data-tooltip="Choose which apps to launch">Launchers</label>
<label class="chip tooltip" filterid="game" data-tooltip="Have fun!">Games</label>
<label class="chip tooltip" filterid="tool" data-tooltip="Useful applications">Tools</label>
<label class="chip tooltip" filterid="textinput" data-tooltip="To allow you to enter text">Keyboards</label>
<label class="chip tooltip" filterid="widget" data-tooltip="Appear in the top bar of Bangle.js apps">Widgets</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 class="sort-nav hidden">
<span>Sort by:</span>
<label class="chip active" sortid="">None</label>
<label class="chip hidden" sortid="created">New</label>
<label class="chip hidden" sortid="modified">Updated</label>
<label class="chip hidden" sortid="installs">Installed</label>
<label class="chip hidden" sortid="favourites">Favourited</label>
<label class="chip hidden tooltip" sortid="created" data-tooltip="Most recent apps">New</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>
@ -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>
<h3>Utilities</h3>
<p><button class="btn" id="settime">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" id="reinstallall" data-tooltip="Remove and re-install every app, leaving all other data intact">Reinstall apps</button>
<button class="btn" id="installdefault">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" 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>
<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="settime" data-tooltip="Set the Bangle's time to your Browser's time">Set Bangle.js Time</button>
<button class="btn tooltip" id="removeall" data-tooltip="Delete everything, leave it blank">Remove all Apps</button>
<button class="btn tooltip" id="reinstallall" data-tooltip="Re-install every app, leave all data">Reinstall apps</button>
<button class="btn tooltip" id="installdefault" data-tooltip="Delete everything, install default apps">Install default apps</button>
<button class="btn tooltip" id="installfavourite" data-tooltip="Delete everything, install your favourites">Install favourite apps</button>
<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" 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>
<div class="form-group">
<label class="form-switch">
<input type="checkbox" id="settings-pretokenise">
<i class="form-icon"></i> Pretokenise apps before upload (smaller, faster apps)
</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">
<input type="checkbox" id="settings-settime">
<i class="form-icon"></i> Always update time when we connect
@ -168,7 +165,14 @@
<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>
</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 id="more-deviceinfo" style="display:none">
<h3>Device info</h3>