forked from FOSS/BangleApps
Merge branch 'espruino:master' into master
commit
2ad5076443
16
apps.json
16
apps.json
|
@ -170,16 +170,15 @@
|
|||
"id": "launch",
|
||||
"name": "Launcher",
|
||||
"shortName": "Launcher",
|
||||
"version": "0.10",
|
||||
"version": "0.11",
|
||||
"description": "This is needed to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.",
|
||||
"icon": "app.png",
|
||||
"type": "launch",
|
||||
"tags": "tool,system,launcher",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"storage": [
|
||||
{"name":"launch.app.js","url":"app-bangle1.js","supports":["BANGLEJS"]},
|
||||
{"name":"launch.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]},
|
||||
{"name":"launch.settings.js","url":"settings.js","supports":["BANGLEJS2"]}
|
||||
{"name":"launch.app.js","url":"app.js"},
|
||||
{"name":"launch.settings.js","url":"settings.js"}
|
||||
],
|
||||
"data": [{"name":"launch.json"}],
|
||||
"sortorder": -10
|
||||
|
@ -839,9 +838,10 @@
|
|||
{
|
||||
"id": "slevel",
|
||||
"name": "Spirit Level",
|
||||
"version": "0.02",
|
||||
"version": "0.04",
|
||||
"description": "Show the current angle of the watch, so you can use it to make sure something is absolutely flat",
|
||||
"icon": "spiritlevel.png",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"tags": "tool",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"storage": [
|
||||
|
@ -1359,12 +1359,12 @@
|
|||
{
|
||||
"id": "pparrot",
|
||||
"name": "Party Parrot",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "Party with a parrot on your wrist",
|
||||
"icon": "party-parrot.png",
|
||||
"type": "app",
|
||||
"tags": "party,parrot,lol",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-party-parrot-screenshot.png"}],
|
||||
"storage": [
|
||||
|
@ -1541,7 +1541,7 @@
|
|||
{
|
||||
"id": "gpsinfo",
|
||||
"name": "GPS Info",
|
||||
"version": "0.09",
|
||||
"version": "0.10",
|
||||
"description": "An application that displays information about altitude, lat/lon, satellites and time",
|
||||
"icon": "gps-info.png",
|
||||
"type": "app",
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
0.07: Resolve one FIFO_FULL case and exit App with button press
|
||||
0.08: Leave GPS power switched on on exit (will switch off after 0.5 seconds anyway)
|
||||
0.09: Fix FIFO_FULL error
|
||||
0.10: Show satellites "in view" separated by GNS-system
|
||||
|
|
|
@ -16,9 +16,8 @@ var lastFix = {
|
|||
time: 0,
|
||||
satellites: 0
|
||||
};
|
||||
var SATinView = 0;
|
||||
var nofBD = 0;
|
||||
var nofGP = 0;
|
||||
var SATinView = 0, lastSATinView = -1, nofGP = 0, nofBD = 0, nofGL = 0;
|
||||
const leaveNofixLayout = 1; // 0 = stay on initial screen for debugging (default = 1)
|
||||
var listenerGPSraw = 0;
|
||||
|
||||
function formatTime(now) {
|
||||
|
@ -63,7 +62,7 @@ function getMaidenHead(param1,param2){
|
|||
function onGPS(fix) {
|
||||
if (lastFix.fix != fix.fix) {
|
||||
// if fix is different, change the layout
|
||||
if (fix.fix) {
|
||||
if (fix.fix && leaveNofixLayout) {
|
||||
layout = new Layout( {
|
||||
type:"v", c: [
|
||||
{type:"txt", font:"6x8:2", label:"GPS Info" },
|
||||
|
@ -92,11 +91,12 @@ function onGPS(fix) {
|
|||
g.clearRect(0,24,g.getWidth(),g.getHeight());
|
||||
layout.render();
|
||||
}
|
||||
//lastFix = fix;
|
||||
if (fix.fix) {
|
||||
if (fix.fix && leaveNofixLayout) {
|
||||
if (listenerGPSraw == 1) {
|
||||
Bangle.removeListener('GPS-raw', onGPSraw);
|
||||
listenerGPSraw = 0;
|
||||
lastSATinView = -1;
|
||||
Bangle.buzz(50);
|
||||
}
|
||||
var locale = require("locale");
|
||||
var satellites = fix.satellites;
|
||||
|
@ -115,27 +115,31 @@ function onGPS(fix) {
|
|||
layout.sat.label = fix.satellites;
|
||||
layout.render(layout.sat);
|
||||
}
|
||||
if (SATinView != lastFix.SATinView) {
|
||||
if (SATinView != lastSATinView) {
|
||||
if (!leaveNofixLayout) SATinView = -1;
|
||||
lastSATinView = SATinView;
|
||||
layout.clear(layout.progress);
|
||||
layout.progress.label = "in view: " + SATinView;
|
||||
layout.progress.label = "in view GP/BD/GL: " + nofGP + " " + nofBD + " " + nofGL;
|
||||
// console.log("in view GP/BD/GL: " + nofGP + " " + nofBD + " " + nofGL);
|
||||
layout.render(layout.progress);
|
||||
}
|
||||
}
|
||||
//layout.render();
|
||||
|
||||
if (listenerGPSraw == 0 && !fix.fix) {
|
||||
setTimeout(() => Bangle.on('GPS-raw', onGPSraw), 10);
|
||||
listenerGPSraw = 1;
|
||||
}
|
||||
|
||||
lastFix = fix;
|
||||
lastFix.SATinView = SATinView;
|
||||
}
|
||||
|
||||
function onGPSraw(nmea) {
|
||||
if (nmea.slice(0,7) == "$BDGSV,") nofBD = Number(nmea.slice(11,13));
|
||||
if (nmea.slice(0,7) == "$GPGSV,") nofGP = Number(nmea.slice(11,13));
|
||||
SATinView = nofBD + nofGP;
|
||||
if (nmea.slice(3,6) == "GSV") {
|
||||
// console.log(nmea.slice(1,3) + " " + nmea.slice(11,13));
|
||||
if (nmea.slice(0,7) == "$GPGSV,") nofGP = Number(nmea.slice(11,13));
|
||||
if (nmea.slice(0,7) == "$BDGSV,") nofBD = Number(nmea.slice(11,13));
|
||||
if (nmea.slice(0,7) == "$GLGSV,") nofGL = Number(nmea.slice(11,13));
|
||||
SATinView = nofGP + nofBD + nofGL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,3 +9,4 @@
|
|||
0.09: Bangle.js 2 - pressing the button goes back to clock (fix #971)
|
||||
After 10s of being locked, the launcher goes back to the clock screen
|
||||
0.10: added in selectable font in settings including scalable vector font
|
||||
0.11: Merge Bangle.js 1 and 2 launchers, again
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
var s = require("Storage");
|
||||
var apps = s.list(/\.info$/).map(app=>{var a=s.readJSON(app,1);return a&&{name:a.name,type:a.type,icon:a.icon,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="clock" || !app.type));
|
||||
apps.sort((a,b)=>{
|
||||
var n=(0|a.sortorder)-(0|b.sortorder);
|
||||
if (n) return n; // do sortorder first
|
||||
if (a.name<b.name) return -1;
|
||||
if (a.name>b.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
var selected = 0;
|
||||
var menuScroll = 0;
|
||||
var menuShowing = false;
|
||||
|
||||
function drawMenu() {
|
||||
g.reset().setFont("6x8",2).setFontAlign(-1,0);
|
||||
var w = g.getWidth();
|
||||
var h = g.getHeight();
|
||||
var m = w/2;
|
||||
var n = Math.floor((h-48)/64);
|
||||
if (selected>=n+menuScroll) menuScroll = 1+selected-n;
|
||||
if (selected<menuScroll) menuScroll = selected;
|
||||
// arrows
|
||||
g.setColor(menuScroll ? g.theme.fg : g.theme.bg);
|
||||
g.fillPoly([m,6,m-14,20,m+14,20]);
|
||||
g.setColor((apps.length>n+menuScroll) ? g.theme.fg : g.theme.bg);
|
||||
g.fillPoly([m,h-7,m-14,h-21,m+14,h-21]);
|
||||
// draw
|
||||
g.setColor(g.theme.fg);
|
||||
for (var i=0;i<n;i++) {
|
||||
var app = apps[i+menuScroll];
|
||||
if (!app) break;
|
||||
var y = 24+i*64;
|
||||
if (i+menuScroll==selected) {
|
||||
g.setColor(g.theme.bgH).fillRect(0,y,w-1,y+63);
|
||||
g.setColor(g.theme.fgH).drawRect(0,y,w-1,y+63);
|
||||
} else {
|
||||
g.clearRect(0, y, w-1, y+63);
|
||||
g.setColor(g.theme.fg);
|
||||
}
|
||||
g.drawString(app.name,64,y+32);
|
||||
var icon=undefined;
|
||||
if (app.icon) icon = s.read(app.icon);
|
||||
if (icon) try {g.drawImage(icon,8,y+8);} catch(e){}
|
||||
}
|
||||
}
|
||||
g.clear();
|
||||
drawMenu();
|
||||
Bangle.setUI("updown",dir=>{
|
||||
if (dir) {
|
||||
selected += dir;
|
||||
if (selected<0) selected = apps.length-1;
|
||||
if (selected>=apps.length) selected = 0;
|
||||
drawMenu();
|
||||
} else {
|
||||
if (!apps[selected].src) return;
|
||||
if (require("Storage").read(apps[selected].src)===undefined) {
|
||||
E.showMessage("App Source\nNot found");
|
||||
setTimeout(drawMenu, 2000);
|
||||
} else {
|
||||
E.showMessage("Loading...");
|
||||
load(apps[selected].src);
|
||||
}
|
||||
}
|
||||
});
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
// 10s of inactivity goes back to clock
|
||||
if (Bangle.setLocked) Bangle.setLocked(false); // unlock initially
|
||||
var lockTimeout;
|
||||
Bangle.on('lock', locked => {
|
||||
if (lockTimeout) clearTimeout(lockTimeout);
|
||||
lockTimeout = undefined;
|
||||
if (locked)
|
||||
lockTimeout = setTimeout(_=>load(), 10000);
|
||||
});
|
|
@ -63,8 +63,11 @@ E.showScroller({
|
|||
}
|
||||
});
|
||||
|
||||
// pressing button goes back
|
||||
setWatch(_=>load(), BTN1, {edge:"falling"});
|
||||
// on bangle.js 2, the screen is used for navigating, so the single button goes back
|
||||
// on bangle.js 1, the buttons are used for navigating
|
||||
if (process.env.HWVERSION==2) {
|
||||
setWatch(_=>load(), BTN1, {edge:"falling"});
|
||||
}
|
||||
|
||||
// 10s of inactivity goes back to clock
|
||||
Bangle.setLocked(false); // unlock initially
|
|
@ -1 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: Bangle.js 2 compatibility
|
||||
|
|
|
@ -5,16 +5,17 @@ var imgs = [
|
|||
atob("qE5xH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AdwOBlcAAAsrq2BJn+BqxMHKX5NFJhgAFqxO5TYcruug0HLAAoIBvdQCIZN11icDqBLHAA+gMYRQ0TgcrvhNOAAaiCeWWBTgZNSKAuBJ17rDvZOVeQK4C1hOxdaYAFvbxvdgZOGbgMlLCF8DwSgrJxSKCKALvRUFmslbsJJ4YMG0F1qElld10ATGgGBJ9BOCvaLHHYgNEIoqsBKAIJFUFDtCurbIvhPHcgcrAAL9DBQclUFDtCGQIAJIIUAcYQHDq2ArmAqxsDfIL2BKFAxCvhPK0F7uoODSYVWrgACwBXCLwYQDlaekE4ROKAA97CwJODAAJuCfwYABuqglwKeNAA9QMoJPFrjwDAAjxBlesd0hOSHgeAJwjwDWRCgh1guBqBPTHYKfHOBIIBqxPhEgN7J6yfFJ5VQBILwgwJPWWwJPK0DwpJ66LBd6OgJ8TvXuoXBJ6HLBINWJ8VQJ6d8HYROEwD5BkpP/bYpPFrgIBuoUHqEAlZPiZxAAMHYWAdw18CY91BYOsJ8WgJ6d7UAzuBN5JPCwJPivagUC4MrJwoeJJ4VcJ72BJ4UrJ6igCKALtCqASJqDvhJ4bwVHodWTwQcJ0AQCJz3+QASCMABclDYd1MBmBJ76ABkrYCvZPUR4QABBxInCT0DuCJYJ3CeKt1NJZdClesd0RKBFIbxVqEldtusdwJJDvgqBqDxVTxjtgdwd8Fgd7KC77MT0H+TwLQGKAT4CJ/9WTwxQGupPbd4QABldWq2B1hPbTwwvDVYJRCUbRxDAAhTCJyusSRowEktQAAKhXvd1qBSHKKmBdxIwFuotFUjQjBvgkElZPWlaOCABRPFChwAPEYpPSqy9GAGlWJ6JO7UJgA=="),
|
||||
atob("qE5xH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AtwNWlcAAAUrq2BJP5MJAApS/JoRMJAApR7JotPumfAA10VQlWJ2+AHwZMB4nDABHEz9PeoesJ2icDp5NLKIpkCKGesG4UlJoJOBKJQJBBYT1BeQRQwwJOCTgI/Bb4V0KAxIBp8llb+BCYlWJ2V0IYbzCgBCBJwgKDBoefkoFCUFuBGISWEIglPBI8rAAIYDCYeAJ2hPJcgmArmAqylGJ9ZODz5OEJ5IICq1cAAZQGlZOuJoiWFVQIICcgRPFrhLCuklAgOBJ0+AlZOJJAYABAwgUBJwtcDwMr4itCeE+sJwV0dgoAKU4UrwBPFeARuBUAMr1jslJyhPBIAMlJ5auCeEotCJyRPBMwRPLeAVWJ0eAE4NPJqLvR4iglwIlBFgQATH4ROFJ4qgmFYUAdqRPSWASghTwclJ6qPDJ4srBIIQGwCejT63DksAlZPHp4iD4gQCT0SfXb4ZPFA4N0CIl0eECeCZgSfWeA4hCz4QHJ7usEANPOgQtFeCagDOYV0OIpPCeDruCugkCZoqgUlbtDkpwGB4UAJ7mATYXEQoNPeC3EXYVWTwS/HJ8ErD4IlBeDXDEAQABNxBPfPQTqCEoSgXIIhtJf4ZOawIeBkomDUDYbCNhJPCwBOZwB6Hz8lK4oAT4lPNZRcCwJOheL10DJHEO4LuZdgUAugoHPAQ2JADDubToZOHAATVBBpb6YgGsJy1WdhJQIlYQMTylWJ05QEUQOfejd0EAOBJzElRh/EFwRRDAATuWkrBBJysrbaufKIhqCd1ydCJyZREQYIACDizuWJzLUDdoLyBDSq9CJ6eBJzYAbJ4WsTyuf4gAzT6usCoKfBp4AzlY4BwBPRCoQA5qxPRJ3ZQMA==")
|
||||
];
|
||||
var scale = g.getWidth()<200 ? 2 : 3;
|
||||
|
||||
function drawImg (i) {
|
||||
g.drawImage({
|
||||
width: 80, height: 57, bpp: 8,
|
||||
buffer: require("heatshrink").decompress(imgs[i])
|
||||
}, 0, 0, {scale: 3});
|
||||
}, (g.getWidth()-80*scale)/2, (g.getHeight()-57*scale)/2, {scale: scale});
|
||||
}
|
||||
|
||||
var currImg = 0;
|
||||
g.clear();
|
||||
g.setBgColor(0).clear();
|
||||
drawImg(currImg);
|
||||
setInterval(function() {
|
||||
currImg = (currImg + 1) % imgs.length;
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
0.01: New App!
|
||||
0.02: Updated to work with both Bangle.js 1 and 2.
|
||||
0.03: Now also visible on Bangle.js 2
|
||||
0.04: Now work with different themes
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
|
@ -2,6 +2,7 @@ g.clear();
|
|||
var old = {x:0,y:0};
|
||||
var W = g.getWidth();
|
||||
var H = g.getHeight();
|
||||
|
||||
Bangle.on('accel',function(v) {
|
||||
var max = Math.max(Math.abs(v.x),Math.abs(v.y),Math.abs(v.z));
|
||||
if (Math.abs(v.y)==max) {
|
||||
|
@ -12,21 +13,26 @@ Bangle.on('accel',function(v) {
|
|||
|
||||
var d = Math.sqrt(v.x*v.x+v.y*v.y);
|
||||
var ang = Math.atan2(d,Math.abs(v.z))*180/Math.PI;
|
||||
|
||||
g.setColor(1,1,1);
|
||||
g.setFont("6x8",2);
|
||||
g.setFontAlign(0,-1);
|
||||
g.clearRect(W*(1/4),0,W*(3/4),H*(1/16));
|
||||
g.drawString(ang.toFixed(1),W/2,0);
|
||||
|
||||
g.reset();
|
||||
g.clearRect(W*(1/4),0,W*(3/4),16);// clear behind text
|
||||
g.setFont("6x8",2).setFontAlign(0,-1).drawString(ang.toFixed(1),W/2,0);
|
||||
var n = {
|
||||
x:E.clip(W/2+v.x*256,4,W-4),
|
||||
y:E.clip(H/2+v.y*256,4,H-4)};
|
||||
g.clearRect(old.x-3,old.y-3,old.x+6,old.y+6);
|
||||
g.setColor(1,1,1);
|
||||
g.fillRect(n.x-3,n.y-3,n.x+6,n.y+6);
|
||||
g.setColor(1,0,0);
|
||||
g.clearRect(old.x-3,old.y-3,old.x+6,old.y+6); // clear old marker
|
||||
g.setColor("#0f0");
|
||||
g.fillRect(n.x-3,n.y-3,n.x+6,n.y+6); // draw new marker
|
||||
// draw rings
|
||||
g.setColor("#f00");
|
||||
g.drawCircle(W/2,H/2,W*(1/12));
|
||||
g.drawCircle(W/2,H/2,W*(1/4));
|
||||
g.drawCircle(W/2,H/2,W*(5/12));
|
||||
old = n;
|
||||
});
|
||||
|
||||
setWatch(_=>load(), BTN1);
|
||||
if (global.BTN2) {
|
||||
setWatch(_=>load(), BTN2);
|
||||
setWatch(_=>load(), BTN3);
|
||||
}
|
||||
|
|
|
@ -2,15 +2,20 @@
|
|||
/* Scans for strings that may be in English in each app, and
|
||||
outputs a list of strings that have been found.
|
||||
|
||||
Early work towards internationalisation.
|
||||
See https://github.com/espruino/BangleApps/issues/136
|
||||
See https://github.com/espruino/BangleApps/issues/1311
|
||||
*/
|
||||
|
||||
var IGNORE_STRINGS = [
|
||||
"5x5",
|
||||
"5x9Numeric7Seg",
|
||||
"Vector"
|
||||
];
|
||||
|
||||
var BASEDIR = __dirname+"/../";
|
||||
Espruino = require(BASEDIR+"core/lib/espruinotools.js");
|
||||
var fs = require("fs");
|
||||
|
||||
var APPSDIR = BASEDIR+"apps/";
|
||||
|
||||
function ERROR(s) {
|
||||
console.error("ERROR: "+s);
|
||||
process.exit(1);
|
||||
|
@ -18,6 +23,9 @@ function ERROR(s) {
|
|||
function WARN(s) {
|
||||
console.log("Warning: "+s);
|
||||
}
|
||||
function log(s) {
|
||||
console.log(s);
|
||||
}
|
||||
|
||||
var appsFile, apps;
|
||||
try {
|
||||
|
@ -39,31 +47,65 @@ function isNotString(s) {
|
|||
if (s.endsWith(".json") || s.endsWith(".img")) return true; // a filename
|
||||
if (s.endsWith("=")) return true; // probably base64
|
||||
if (s.startsWith("BTN")) return true; // button name
|
||||
if (IGNORE_STRINGS.includes(s)) return true; // one we know to ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
var textStrings = [];
|
||||
// A string that *could* be translated?
|
||||
var untranslatedStrings = [];
|
||||
// Strings that are marked with 'LANG'
|
||||
var translatedStrings = [];
|
||||
|
||||
console.log("Scanning...");
|
||||
console.log("Scanning apps...");
|
||||
apps.forEach((app,appIdx) => {
|
||||
var appDir = APPSDIR+app.id+"/";
|
||||
app.storage.forEach((file) => {
|
||||
if (!file.url || !file.name.endsWith(".js")) return;
|
||||
var fileContents = fs.readFileSync(appDir+file.url).toString();
|
||||
var lex = Espruino.Core.Utils.getLexer(fileContents);
|
||||
var lastIdx = 0;
|
||||
var tok = lex.next();
|
||||
while (tok!==undefined) {
|
||||
var previousString = fileContents.substring(lastIdx, tok.startIdx);
|
||||
if (tok.type=="STRING") {
|
||||
if (!isNotString(tok.value)) {
|
||||
//console.log(tok.str);
|
||||
if (!textStrings.includes(tok.value))
|
||||
textStrings.push(tok.value);
|
||||
if (previousString.includes("/*LANG*/")) { // translated!
|
||||
if (!translatedStrings.includes(tok.value))
|
||||
translatedStrings.push(tok.value);
|
||||
} else { // untranslated - potential to translate?
|
||||
if (!isNotString(tok.value)) {
|
||||
if (!untranslatedStrings.includes(tok.value))
|
||||
untranslatedStrings.push(tok.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastIdx = tok.endIdx;
|
||||
tok = lex.next();
|
||||
}
|
||||
});
|
||||
});
|
||||
console.log("Done");
|
||||
textStrings.sort();
|
||||
console.log(textStrings.join("\n"));
|
||||
untranslatedStrings.sort();
|
||||
translatedStrings.sort();
|
||||
|
||||
var report = "";
|
||||
/* // too many! don't output these
|
||||
log("Possible English Strings that could be translated");
|
||||
log("=================================================================");
|
||||
log("");
|
||||
log("Add these to IGNORE_STRINGS if the don't make sense...");
|
||||
log("");
|
||||
log(untranslatedStrings.map(s=>JSON.stringify(s)).join(",\n"));*/
|
||||
log("");
|
||||
|
||||
var languages = JSON.parse(fs.readFileSync(BASEDIR+"/lang/index.json").toString());
|
||||
languages.forEach(language => {
|
||||
console.log("Scanning "+language.code);
|
||||
log(language.code);
|
||||
log("==========");
|
||||
var translations = JSON.parse(fs.readFileSync(BASEDIR+"/lang/"+language.url).toString());
|
||||
translatedStrings.forEach(str => {
|
||||
if (!translations.GLOBAL[str])
|
||||
console.log(`Missing translation for ${JSON.stringify(str)}`);
|
||||
});
|
||||
log("");
|
||||
});
|
||||
console.log("Done.");
|
||||
|
|
|
@ -141,6 +141,11 @@
|
|||
<input type="checkbox" id="settings-settime">
|
||||
<i class="form-icon"></i> Always update time when we connect
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<select class="form-select form-inline" id="settings-lang" style="width: 10em">
|
||||
<option value="">None (English)</option>
|
||||
</select> <span>Translations (<a href="https://github.com/espruino/BangleApps/issues/1311" target="_blank">BETA - more info</a>)</span>
|
||||
</div>
|
||||
<button class="btn" id="defaultsettings">Default settings</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"//":"British English language translations - the default strings in apps are all english anyway, so no need to have translations for most things",
|
||||
"GLOBAL": {
|
||||
"//":"Translations that apply for all apps",
|
||||
"//":"Translations that apply for all apps"
|
||||
},
|
||||
"alarm": {
|
||||
"//":"App-specific overrides",
|
||||
"//":"App-specific overrides"
|
||||
}
|
||||
}
|
||||
|
|
42
loader.js
42
loader.js
|
@ -164,6 +164,48 @@ window.addEventListener('load', (event) => {
|
|||
showToast("App Install failed, "+err,"error");
|
||||
});
|
||||
});
|
||||
|
||||
// Load language list
|
||||
httpGet("lang/index.json").then(languagesJSON=>{
|
||||
var languages;
|
||||
try {
|
||||
languages = JSON.parse(languagesJSON);
|
||||
} catch(e) {
|
||||
console.error("lang/index.json Corrupted", e);
|
||||
}
|
||||
|
||||
function reloadLanguage() {
|
||||
LANGUAGE = undefined;
|
||||
if (SETTINGS.language) {
|
||||
var language = languages.find(l=>l.code==SETTINGS.language);
|
||||
if (language) {
|
||||
var langURL = "lang/"+language.url;
|
||||
httpGet(langURL).then(languageJSON=>{
|
||||
try {
|
||||
LANGUAGE = JSON.parse(languageJSON);
|
||||
console.log(`${langURL} loaded successfully`);
|
||||
} catch(e) {
|
||||
console.error(`${langURL} Corrupted`, e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error(`Language code ${JSON.stringify(SETTINGS.language)} not found in lang/index.json`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var selectLang = document.getElementById("settings-lang");
|
||||
console.log(languages);
|
||||
languages.forEach(lang => {
|
||||
selectLang.innerHTML += `<option value="${lang.code}" ${SETTINGS.language==lang.code?"selected":""}>${lang.name} (${lang.code})</option>`;
|
||||
});
|
||||
selectLang.addEventListener("change",event=>{
|
||||
SETTINGS.language = event.target.value;
|
||||
reloadLanguage();
|
||||
saveSettings();
|
||||
});
|
||||
reloadLanguage();
|
||||
});
|
||||
});
|
||||
|
||||
function onAppJSONLoaded() {
|
||||
|
|
Loading…
Reference in New Issue