commit
92efe31a4b
|
|
@ -16,4 +16,5 @@
|
|||
0.16: Bangle.http now fails immediately if there is no Bluetooth connection (fix #2152)
|
||||
0.17: Now kick off Calendar sync as soon as connected to Gadgetbridge
|
||||
0.18: Use new message library
|
||||
If connected to Gadgetbridge, allow GPS forwarding from phone (Gadgetbridge code still not merged)
|
||||
If connected to Gadgetbridge, allow GPS forwarding from phone (Gadgetbridge code still not merged)
|
||||
0.19: Add automatic translation for a couple of strings.
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
t:event.cmd=="incoming"?"add":"remove",
|
||||
id:"call", src:"Phone",
|
||||
positive:true, negative:true,
|
||||
title:event.name||"Call", body:"Incoming call\n"+event.number});
|
||||
title:event.name||/*LANG*/"Call", body:/*LANG*/"Incoming call\n"+event.number});
|
||||
require("messages").pushMessage(event);
|
||||
},
|
||||
"alarm" : function() {
|
||||
|
|
@ -148,7 +148,7 @@
|
|||
Bangle.http = (url,options)=>{
|
||||
options = options||{};
|
||||
if (!NRF.getSecurityStatus().connected)
|
||||
return Promise.reject("Not connected to Bluetooth");
|
||||
return Promise.reject(/*LANG*/"Not connected to Bluetooth");
|
||||
if (Bangle.httpRequest === undefined)
|
||||
Bangle.httpRequest={};
|
||||
if (options.id === undefined) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "android",
|
||||
"name": "Android Integration",
|
||||
"shortName": "Android",
|
||||
"version": "0.18",
|
||||
"version": "0.19",
|
||||
"description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,system,messages,notifications,gadgetbridge",
|
||||
|
|
|
|||
|
|
@ -3,4 +3,5 @@
|
|||
0.04: Add functionality to sort apps manually or alphabetically ascending/descending.
|
||||
0.05: Tweaks to help with memory usage
|
||||
0.06: Reduce memory usage
|
||||
0.07: Allow negative numbers when manual-sorting
|
||||
0.07: Allow negative numbers when manual-sorting
|
||||
0.08: Automatic translation of strings.
|
||||
|
|
|
|||
|
|
@ -3,20 +3,20 @@ const store = require('Storage');
|
|||
function showMainMenu() {
|
||||
const mainmenu = {
|
||||
'': {
|
||||
'title': 'App Manager',
|
||||
'title': /*LANG*/'App Manager',
|
||||
},
|
||||
'< Back': ()=> {load();},
|
||||
'Sort Apps': () => showSortAppsMenu(),
|
||||
'Manage Apps': ()=> showApps(),
|
||||
'Compact': () => {
|
||||
E.showMessage('Compacting...');
|
||||
/*LANG*/'Sort Apps': () => showSortAppsMenu(),
|
||||
/*LANG*/'Manage Apps': ()=> showApps(),
|
||||
/*LANG*/'Compact': () => {
|
||||
E.showMessage(/*LANG*/'Compacting...');
|
||||
try {
|
||||
store.compact();
|
||||
} catch (e) {
|
||||
}
|
||||
showMainMenu();
|
||||
},
|
||||
'Free': {
|
||||
/*LANG*/'Free': {
|
||||
value: undefined,
|
||||
format: (v) => {
|
||||
return store.getFree();
|
||||
|
|
@ -65,13 +65,13 @@ function eraseData(info) {
|
|||
});
|
||||
}
|
||||
function eraseApp(app, files,data) {
|
||||
E.showMessage('Erasing\n' + app.name + '...');
|
||||
E.showMessage(/*LANG*/'Erasing\n' + app.name + '...');
|
||||
var info = store.readJSON(app.id + ".info", 1)||{};
|
||||
if (files) eraseFiles(info);
|
||||
if (data) eraseData(info);
|
||||
}
|
||||
function eraseOne(app, files,data){
|
||||
E.showPrompt('Erase\n'+app.name+'?').then((v) => {
|
||||
E.showPrompt(/*LANG*/'Erase\n'+app.name+'?').then((v) => {
|
||||
if (v) {
|
||||
Bangle.buzz(100, 1);
|
||||
eraseApp(app, files, data);
|
||||
|
|
@ -82,7 +82,7 @@ function eraseOne(app, files,data){
|
|||
});
|
||||
}
|
||||
function eraseAll(apps, files,data) {
|
||||
E.showPrompt('Erase all?').then((v) => {
|
||||
E.showPrompt(/*LANG*/'Erase all?').then((v) => {
|
||||
if (v) {
|
||||
Bangle.buzz(100, 1);
|
||||
apps.forEach(app => eraseApp(app, files, data));
|
||||
|
|
@ -99,11 +99,11 @@ function showAppMenu(app) {
|
|||
'< Back': () => showApps(),
|
||||
};
|
||||
if (app.hasData) {
|
||||
appmenu['Erase Completely'] = () => eraseOne(app, true, true);
|
||||
appmenu['Erase App,Keep Data'] = () => eraseOne(app, true, false);
|
||||
appmenu['Only Erase Data'] = () => eraseOne(app, false, true);
|
||||
appmenu[/*LANG*/'Erase Completely'] = () => eraseOne(app, true, true);
|
||||
appmenu[/*LANG*/'Erase App,Keep Data'] = () => eraseOne(app, true, false);
|
||||
appmenu[/*LANG*/'Only Erase Data'] = () => eraseOne(app, false, true);
|
||||
} else {
|
||||
appmenu['Erase'] = () => eraseOne(app, true, false);
|
||||
appmenu[/*LANG*/'Erase'] = () => eraseOne(app, true, false);
|
||||
}
|
||||
E.showMenu(appmenu);
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ function showAppMenu(app) {
|
|||
function showApps() {
|
||||
const appsmenu = {
|
||||
'': {
|
||||
'title': 'Apps',
|
||||
'title': /*LANG*/'Apps',
|
||||
},
|
||||
'< Back': () => showMainMenu(),
|
||||
};
|
||||
|
|
@ -128,17 +128,17 @@ function showApps() {
|
|||
menu[app.name] = () => showAppMenu(app);
|
||||
return menu;
|
||||
}, appsmenu);
|
||||
appsmenu['Erase All'] = () => {
|
||||
appsmenu[/*LANG*/'Erase All'] = () => {
|
||||
E.showMenu({
|
||||
'': {'title': 'Erase All'},
|
||||
'Erase Everything': () => eraseAll(list, true, true),
|
||||
'Erase Apps,Keep Data': () => eraseAll(list, true, false),
|
||||
'Only Erase Data': () => eraseAll(list, false, true),
|
||||
'': {'title': /*LANG*/'Erase All'},
|
||||
/*LANG*/'Erase Everything': () => eraseAll(list, true, true),
|
||||
/*LANG*/'Erase Apps,Keep Data': () => eraseAll(list, true, false),
|
||||
/*LANG*/'Only Erase Data': () => eraseAll(list, false, true),
|
||||
'< Back': () => showApps(),
|
||||
});
|
||||
};
|
||||
} else {
|
||||
appsmenu['...No Apps...'] = {
|
||||
appsmenu[/*LANG*/'...No Apps...'] = {
|
||||
value: undefined,
|
||||
format: ()=> '',
|
||||
onchange: ()=> {}
|
||||
|
|
@ -150,16 +150,16 @@ function showApps() {
|
|||
function showSortAppsMenu() {
|
||||
const sorterMenu = {
|
||||
'': {
|
||||
'title': 'App Sorter',
|
||||
'title': /*LANG*/'App Sorter',
|
||||
},
|
||||
'< Back': () => showMainMenu(),
|
||||
'Sort: manually': ()=> showSortAppsManually(),
|
||||
'Sort: alph. ASC': () => {
|
||||
E.showMessage('Sorting:\nAlphabetically\nascending ...');
|
||||
/*LANG*/'Sort: manually': ()=> showSortAppsManually(),
|
||||
/*LANG*/'Sort: alph. ASC': () => {
|
||||
E.showMessage(/*LANG*/'Sorting:\nAlphabetically\nascending ...');
|
||||
sortAlphabet(false);
|
||||
},
|
||||
'Sort: alph. DESC': () => {
|
||||
E.showMessage('Sorting:\nAlphabetically\ndescending ...');
|
||||
E.showMessage(/*LANG*/'Sorting:\nAlphabetically\ndescending ...');
|
||||
sortAlphabet(true);
|
||||
}
|
||||
};
|
||||
|
|
@ -169,7 +169,7 @@ function showSortAppsMenu() {
|
|||
function showSortAppsManually() {
|
||||
const appsSorterMenu = {
|
||||
'': {
|
||||
'title': 'Sort: manually',
|
||||
'title': /*LANG*/'Sort: manually',
|
||||
},
|
||||
'< Back': () => showSortAppsMenu(),
|
||||
};
|
||||
|
|
@ -186,7 +186,7 @@ function showSortAppsManually() {
|
|||
return menu;
|
||||
}, appsSorterMenu);
|
||||
} else {
|
||||
appsSorterMenu['...No Apps...'] = {
|
||||
appsSorterMenu[/*LANG*/'...No Apps...'] = {
|
||||
value: undefined,
|
||||
format: ()=> '',
|
||||
onchange: ()=> {}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "files",
|
||||
"name": "App Manager",
|
||||
"version": "0.07",
|
||||
"version": "0.08",
|
||||
"description": "Show currently installed apps, free space, and allow their deletion from the watch",
|
||||
"icon": "files.png",
|
||||
"tags": "tool,system,files",
|
||||
|
|
|
|||
|
|
@ -8,3 +8,4 @@
|
|||
0.08: Don't force backlight on/watch unlocked on Bangle 2
|
||||
0.09: Grey out BPM until confidence is over 50%
|
||||
0.10: Autoscale raw graph to maximum value seen
|
||||
0.11: Automatic translation of strings.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ function updateHrm(){
|
|||
var px = g.getWidth()/2;
|
||||
g.setFontAlign(0,-1);
|
||||
g.clearRect(0,24,g.getWidth(),80);
|
||||
g.setFont("6x8").drawString("Confidence "+(hrmInfo.confidence || "--")+"%", px, 70);
|
||||
g.setFont("6x8").drawString(/*LANG*/"Confidence "+(hrmInfo.confidence || "--")+"%", px, 70);
|
||||
|
||||
updateScale();
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ function updateHrm(){
|
|||
g.setFontVector(40).setColor(hrmInfo.confidence > 50 ? g.theme.fg : "#888").drawString(str,px,45);
|
||||
px += g.stringWidth(str)/2;
|
||||
g.setFont("6x8").setColor(g.theme.fg);
|
||||
g.drawString("BPM",px+15,45);
|
||||
g.drawString(/*LANG*/"BPM",px+15,45);
|
||||
}
|
||||
|
||||
function updateScale(){
|
||||
|
|
@ -101,7 +101,7 @@ Bangle.loadWidgets();
|
|||
Bangle.drawWidgets();
|
||||
g.setColor(g.theme.fg);
|
||||
g.reset().setFont("6x8",2).setFontAlign(0,-1);
|
||||
g.drawString("Please wait...",g.getWidth()/2,g.getHeight()/2 - 16);
|
||||
g.drawString(/*LANG*/"Please wait...",g.getWidth()/2,g.getHeight()/2 - 16);
|
||||
countDown();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "hrm",
|
||||
"name": "Heart Rate Monitor",
|
||||
"version": "0.10",
|
||||
"version": "0.11",
|
||||
"description": "Measure your heart rate and see live sensor data",
|
||||
"icon": "heartrate.png",
|
||||
"tags": "health",
|
||||
|
|
|
|||
|
|
@ -23,3 +23,4 @@
|
|||
0.17: Use default Bangle formatter for booleans
|
||||
0.18: Improve widget load speed, allow currently recording track to be plotted in openstmap
|
||||
0.19: Fix track plotting code
|
||||
0.20: Automatic translation of some more strings.
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ function showMainMenu() {
|
|||
setTimeout(function() {
|
||||
E.showMenu();
|
||||
WIDGETS["recorder"].setRecording(v).then(function() {
|
||||
print("Complete");
|
||||
print(/*LANG*/"Complete");
|
||||
loadSettings();
|
||||
print(settings.recording);
|
||||
showMainMenu();
|
||||
|
|
@ -96,7 +96,7 @@ function showMainMenu() {
|
|||
};
|
||||
var recorders = WIDGETS["recorder"].getRecorders();
|
||||
Object.keys(recorders).forEach(id=>{
|
||||
mainmenu["Log "+recorders[id]().name] = menuRecord(id);
|
||||
mainmenu[/*LANG*/"Log "+recorders[id]().name] = menuRecord(id);
|
||||
});
|
||||
delete recorders;
|
||||
return E.showMenu(mainmenu);
|
||||
|
|
@ -404,7 +404,7 @@ function viewTrack(filename, info) {
|
|||
title: title,
|
||||
miny: min,
|
||||
maxy: max,
|
||||
xlabel : x=>Math.round(x*dur/(60*infn.length))+" min" // minutes
|
||||
xlabel : x=>Math.round(x*dur/(60*infn.length))+/*LANG*/" min" // minutes
|
||||
});
|
||||
g.setFont("6x8",2);
|
||||
g.setFontAlign(0,0,3);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "recorder",
|
||||
"name": "Recorder",
|
||||
"shortName": "Recorder",
|
||||
"version": "0.19",
|
||||
"version": "0.20",
|
||||
"description": "Record GPS position, heart rate and more in the background, then download to your PC.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,outdoors,gps,widget",
|
||||
|
|
|
|||
|
|
@ -17,4 +17,6 @@
|
|||
0.18: Added hasRange to clkinfo.
|
||||
0.19: Added weather condition to clkinfo.
|
||||
0.20: Added weather condition with temperature to clkinfo.
|
||||
0.21: Updated clkinfo icon.
|
||||
0.21: Updated clkinfo icon.
|
||||
0.22: Automatic translation of strings, some left untranslated.
|
||||
>>>>>>> b37fcacd1 (weather - autotranslate strings)
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ var layout = new Layout({type:"v", bgCol: g.theme.bg, c: [
|
|||
{type: "txt", font: "12%", valign: -1, id: "tempUnit", label: "°C"},
|
||||
]},
|
||||
{filly: 1},
|
||||
{type: "txt", font: "6x8", pad: 2, halign: 1, label: "Humidity"},
|
||||
{type: "txt", font: "6x8", pad: 2, halign: 1, label: /*LANG*/"Humidity"},
|
||||
{type: "txt", font: "9%", pad: 2, halign: 1, id: "hum", label: "000%"},
|
||||
{filly: 1},
|
||||
{type: "txt", font: "6x8", pad: 2, halign: -1, label: "Wind"},
|
||||
{type: "txt", font: "6x8", pad: 2, halign: -1, label: /*LANG*/"Wind"},
|
||||
{type: "h", halign: -1, c: [
|
||||
{type: "txt", font: "9%", pad: 2, id: "wind", label: "00"},
|
||||
{type: "txt", font: "6x8", pad: 2, valign: -1, id: "windUnit", label: "km/h"},
|
||||
|
|
@ -27,22 +27,22 @@ var layout = new Layout({type:"v", bgCol: g.theme.bg, c: [
|
|||
]},
|
||||
]},
|
||||
{filly: 1},
|
||||
{type: "txt", font: "9%", wrap: true, height: g.getHeight()*0.18, fillx: 1, id: "cond", label: "Weather condition"},
|
||||
{type: "txt", font: "9%", wrap: true, height: g.getHeight()*0.18, fillx: 1, id: "cond", label: /*LANG*/"Weather condition"},
|
||||
{filly: 1},
|
||||
{type: "h", c: [
|
||||
{type: "txt", font: "6x8", pad: 4, id: "loc", label: "Toronto"},
|
||||
{fillx: 1},
|
||||
{type: "txt", font: "6x8", pad: 4, id: "updateTime", label: "15 minutes ago"},
|
||||
{type: "txt", font: "6x8", pad: 4, id: "updateTime", label: /*LANG*/"15 minutes ago"},
|
||||
]},
|
||||
{filly: 1},
|
||||
]}, {lazy: true});
|
||||
|
||||
function formatDuration(millis) {
|
||||
let pluralize = (n, w) => n + " " + w + (n == 1 ? "" : "s");
|
||||
if (millis < 60000) return "< 1 minute";
|
||||
if (millis < 3600000) return pluralize(Math.floor(millis/60000), "minute");
|
||||
if (millis < 86400000) return pluralize(Math.floor(millis/3600000), "hour");
|
||||
return pluralize(Math.floor(millis/86400000), "day");
|
||||
if (millis < 60000) return /*LANG*/"< 1 minute";
|
||||
if (millis < 3600000) return pluralize(Math.floor(millis/60000), /*LANG*/"minute");
|
||||
if (millis < 86400000) return pluralize(Math.floor(millis/3600000), /*LANG*/"hour");
|
||||
return pluralize(Math.floor(millis/86400000), /*LANG*/"day");
|
||||
}
|
||||
|
||||
function draw() {
|
||||
|
|
@ -57,7 +57,7 @@ function draw() {
|
|||
layout.windUnit.label = wind[2] + " " + (current.wrose||'').toUpperCase();
|
||||
layout.cond.label = current.txt.charAt(0).toUpperCase()+(current.txt||'').slice(1);
|
||||
layout.loc.label = current.loc;
|
||||
layout.updateTime.label = `${formatDuration(Date.now() - current.time)} ago`;
|
||||
layout.updateTime.label = `${formatDuration(Date.now() - current.time)} ago`; // How to autotranslate this and similar?
|
||||
layout.update();
|
||||
layout.render();
|
||||
}
|
||||
|
|
@ -77,9 +77,9 @@ function update() {
|
|||
} else {
|
||||
layout.forgetLazyState();
|
||||
if (NRF.getSecurityStatus().connected) {
|
||||
E.showMessage("Weather\nunknown\n\nIs Gadgetbridge\nweather\nreporting set\nup on your\nphone?");
|
||||
E.showMessage(/*LANG*/"Weather\nunknown\n\nIs Gadgetbridge\nweather\nreporting set\nup on your\nphone?");
|
||||
} else {
|
||||
E.showMessage("Weather\nunknown\n\nGadgetbridge\nnot connected");
|
||||
E.showMessage(/*LANG*/"Weather\nunknown\n\nGadgetbridge\nnot connected");
|
||||
NRF.on("connect", update);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "weather",
|
||||
"name": "Weather",
|
||||
"version": "0.21",
|
||||
"version": "0.22",
|
||||
"description": "Show Gadgetbridge weather report",
|
||||
"icon": "icon.png",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
|
|
|
|||
Loading…
Reference in New Issue