1
0
Fork 0
David Peer 2022-02-10 22:17:21 +01:00
commit 5c9f84d00e
22 changed files with 275 additions and 100 deletions

View File

@ -7,7 +7,7 @@
active = active.sort((a,b)=>(a.hr-b.hr)+(a.last-b.last)*24); active = active.sort((a,b)=>(a.hr-b.hr)+(a.last-b.last)*24);
var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600); var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
if (!require('Storage').read("alarm.js")) { if (!require('Storage').read("alarm.js")) {
console.log(/*LANG*/"No alarm app!"); console.log("No alarm app!");
require('Storage').write('alarm.json',"[]"); require('Storage').write('alarm.json',"[]");
} else { } else {
var t = 3600000*(active[0].hr-hr); var t = 3600000*(active[0].hr-hr);

View File

@ -1 +1,2 @@
0.01: Display pressure as number and hand 0.01: Display pressure as number and hand
0.02: Use theme color

View File

@ -1,77 +1,77 @@
const center = { var center = {
x: g.getWidth()/2, x: g.getWidth()/2,
y: g.getHeight()/2, y: g.getHeight()/2,
}; };
const MIN = 940; var MIN = 940;
const MAX = 1090; var MAX = 1090;
const NUMBER_OF_VALUES = MAX - MIN; var NUMBER_OF_VALUES = MAX - MIN;
const SCALE_TICK_STEP = 5; var SCALE_TICK_STEP = 5;
const SCALE_VALUES_STEP = 25; var SCALE_VALUES_STEP = 25;
const NUMBER_OF_LABELS = NUMBER_OF_VALUES / SCALE_VALUES_STEP; var NUMBER_OF_LABELS = NUMBER_OF_VALUES / SCALE_VALUES_STEP;
const NUMBER_OF_TICKS = NUMBER_OF_VALUES / SCALE_TICK_STEP; var NUMBER_OF_TICKS = NUMBER_OF_VALUES / SCALE_TICK_STEP;
const ZERO_OFFSET = (Math.PI / 4) * 3; var ZERO_OFFSET = (Math.PI / 4) * 3;
const SCALE_SPAN = (Math.PI / 2) * 3; var SCALE_SPAN = (Math.PI / 2) * 3;
const TICK_LENGTH = 10; var TICK_LENGTH = 10;
const HAND_LENGTH = 45; var HAND_LENGTH = 45;
const HAND_WIDTH = 5; var HAND_WIDTH = 5;
function generatePoly(radius, width, angle){ function generatePoly(radius, width, angle){
const x = center.x + Math.cos(angle) * radius; var x = center.x + Math.cos(angle) * radius;
const y = center.y + Math.sin(angle) * radius; var y = center.y + Math.sin(angle) * radius;
const d = { var d = {
x: width/2 * Math.cos(angle + Math.PI/2), x: width/2 * Math.cos(angle + Math.PI/2),
y: width/2 * Math.sin(angle + Math.PI/2), y: width/2 * Math.sin(angle + Math.PI/2),
}; };
const poly = [center.x - d.x, center.y - d.y, center.x + d.x, center.y + d.y, x + d.x, y + d.y, x - d.x, y - d.y]; var poly = [center.x - d.x, center.y - d.y, center.x + d.x, center.y + d.y, x + d.x, y + d.y, x - d.x, y - d.y];
return poly; return poly;
} }
function drawHand(value){ function drawHand(value){
g.setColor(256, 0, 0); g.setColor(g.theme.fg2);
g.setFontAlign(0,0); g.setFontAlign(0,0);
g.setFont("Vector",15); g.setFont("Vector",15);
g.drawString(value, center.x, center.y * 2 - 15, true); g.drawString(value, center.x, center.y * 2 - 15, true);
const angle = SCALE_SPAN / NUMBER_OF_VALUES * (value - MIN) + ZERO_OFFSET; var angle = SCALE_SPAN / NUMBER_OF_VALUES * (value - MIN) + ZERO_OFFSET;
g.fillPoly(generatePoly(HAND_LENGTH, HAND_WIDTH, angle), true); g.fillPoly(generatePoly(HAND_LENGTH, HAND_WIDTH, angle), true);
g.fillCircle(center.x ,center.y, 4); g.fillCircle(center.x ,center.y, 4);
} }
function drawTicks(){ function drawTicks(){
g.setColor(1,1,1); g.setColor(g.theme.fg);
for(let i= 0; i <= NUMBER_OF_TICKS; i++){ for(let i= 0; i <= NUMBER_OF_TICKS; i++){
const angle = (i * (SCALE_SPAN/NUMBER_OF_TICKS)) + ZERO_OFFSET; var angle = (i * (SCALE_SPAN/NUMBER_OF_TICKS)) + ZERO_OFFSET;
const tickWidth = i%5==0 ? 5 : 2; var tickWidth = i%5==0 ? 5 : 2;
g.fillPoly(generatePoly(center.x, tickWidth, angle), true); g.fillPoly(generatePoly(center.x, tickWidth, angle), true);
} }
g.setColor(0,0,0); g.setColor(g.theme.bg);
g.fillCircle(center.x,center.y,center.x - TICK_LENGTH); g.fillCircle(center.x,center.y,center.x - TICK_LENGTH);
} }
function drawScaleLabels(){ function drawScaleLabels(){
g.setColor(1,1,1); g.setColor(g.theme.fg);
g.setFont("Vector",12); g.setFont("Vector",12);
let label = MIN; let label = MIN;
for (let i=0;i <= NUMBER_OF_LABELS; i++){ for (let i=0;i <= NUMBER_OF_LABELS; i++){
const angle = (i * (SCALE_SPAN/NUMBER_OF_LABELS)) + ZERO_OFFSET; var angle = (i * (SCALE_SPAN/NUMBER_OF_LABELS)) + ZERO_OFFSET;
const labelDimensions = g.stringMetrics(label); var labelDimensions = g.stringMetrics(label);
const LABEL_PADDING = 5; var LABEL_PADDING = 5;
const radius = center.x - TICK_LENGTH - LABEL_PADDING; var radius = center.x - TICK_LENGTH - LABEL_PADDING;
const x = center.x + Math.cos(angle) * radius; var x = center.x + Math.cos(angle) * radius;
const y = center.y + Math.sin(angle) * radius; var y = center.y + Math.sin(angle) * radius;
const visualX = x > center.x ? x - labelDimensions.width : x + labelDimensions.width > center.x ? x - (labelDimensions.width / 2) : x; var visualX = x > center.x ? x - labelDimensions.width : x + labelDimensions.width > center.x ? x - (labelDimensions.width / 2) : x;
const visualY = y >= center.y - labelDimensions.height / 2 ? y - labelDimensions.height / 2 : y; var visualY = y >= center.y - labelDimensions.height / 2 ? y - labelDimensions.height / 2 : y;
g.drawString(label, visualX, visualY); g.drawString(label, visualX, visualY);
@ -80,29 +80,29 @@ function drawScaleLabels(){
} }
function drawIcons() { function drawIcons() {
const sunIcon = { var sunIcon = {
width : 24, height : 24, bpp : 4, width : 24, height : 24, bpp : 1,
transparent : 0, transparent : 0,
buffer : require("heatshrink").decompress(atob("AAkP+ALeA40PAYf/BYv/CYYLBBwIICCQ4ACHI4ICEIgkEAg48GDApcFAoYPBBY5NDBZIjLHZpTLNZiDKTZSzMZZT7iA=")) buffer : require("heatshrink").decompress(atob("gEYAQ0IgEQjkAnEMv0wgH/gEB4eAgcA4EHgHgg0AsHmgFnAQQICBwQUCDQQgCEwQsCGQQ+IA"))
}; };
g.drawImage(sunIcon, center.x + 15, center.y - 12); g.drawImage(sunIcon, center.x + 15, center.y - 12);
const sunRainIcon = { var sunRainIcon = {
width : 24, height : 24, bpp : 4, width : 24, height : 24, bpp : 1,
transparent : 0, transparent : 0,
buffer : require("heatshrink").decompress(atob("AB/wBbEPBAoGEDI/wh4jJBQIMJEgUP///IpAJCBgf/+ALCAQRJFAoIHECgI7FIYwSEHAoGBEQwsEDIJdHCYYLLFwwTEQQwGFQQQACYpYpLf0AAEA")) buffer : require("heatshrink").decompress(atob("AAeAAQmEgEQhEAhIIBg1ggEEj8AhEw4HokFAglAnEGoEGgHAgcRgEBkQCBgQCBgcAgUBwARBv/4HAcgiAFDCoIAC"))
}; };
g.drawImage(sunRainIcon, center.x - 12, 30); g.drawImage(sunRainIcon, center.x - 12, 30);
const rainIcon = { var rainIcon = {
width : 24, height : 24, bpp : 4, width : 24, height : 24, bpp : 1,
transparent : 0, transparent : 0,
buffer : require("heatshrink").decompress(atob("ADnwBRP/AIQAGh4ZKA4YLLh//EwoTFh4GCCIIfGDAQ5DIQ5bIBbQvII4gAGWLwzBOoarLCw4RKLBAAgA")) buffer : require("heatshrink").decompress(atob("AA0gAQPMgEBgUAgQCCgPwAgMYj0AhkQgEECwICGBYMIj//+ArFgURwAqBB4NEgEQghAJ"))
}; };
g.drawImage(rainIcon, center.x - 44, center.y - 12); g.drawImage(rainIcon, center.x - 44, center.y - 12);
} }
g.setBgColor(0,0,0); g.setBgColor(g.theme.bg);
g.clear(); g.clear();
drawTicks(); drawTicks();

View File

@ -1,7 +1,7 @@
{ "id": "barometer", { "id": "barometer",
"name": "Barometer", "name": "Barometer",
"shortName":"Barometer", "shortName":"Barometer",
"version":"0.01", "version":"0.02",
"description": "A simple barometer that displays the current air pressure", "description": "A simple barometer that displays the current air pressure",
"icon": "barometer.png", "icon": "barometer.png",
"tags": "tool,outdoors", "tags": "tool,outdoors",

View File

@ -2,7 +2,7 @@
"id": "floralclk", "id": "floralclk",
"name": "Floral Clock", "name": "Floral Clock",
"version": "0.01", "version": "0.01",
"description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: Works on any Bangle.js 2 but requires firmware 2v11 or later on Bangle.js 1**", "description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/)",
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot_floral.png"}], "screenshots": [{"url":"screenshot_floral.png"}],
"type": "clock", "type": "clock",

View File

@ -2,7 +2,7 @@
"id": "health", "id": "health",
"name": "Health Tracking", "name": "Health Tracking",
"version": "0.11", "version": "0.11",
"description": "Logs health data and provides an app to view it (requires firmware 2v10.100 or later)", "description": "Logs health data and provides an app to view it",
"icon": "app.png", "icon": "app.png",
"tags": "tool,system,health", "tags": "tool,system,health",
"supports": ["BANGLEJS","BANGLEJS2"], "supports": ["BANGLEJS","BANGLEJS2"],

View File

@ -8,7 +8,7 @@
require("Storage").write("launch.json",settings); require("Storage").write("launch.json",settings);
} }
const appMenu = { const appMenu = {
/*LANG*/"": {"title": /*LANG*/"Launcher Settings"}, "": {"title": /*LANG*/"Launcher Settings"},
/*LANG*/"< Back": back, /*LANG*/"< Back": back,
/*LANG*/"Font": { /*LANG*/"Font": {
value: fonts.includes(settings.font)? fonts.indexOf(settings.font) : fonts.indexOf("12x20"), value: fonts.includes(settings.font)? fonts.indexOf(settings.font) : fonts.indexOf("12x20"),

View File

@ -258,7 +258,7 @@ var locales = {
temperature: "°C", temperature: "°C",
ampm: { 0: "", 1: "" }, ampm: { 0: "", 1: "" },
timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" }, timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" },
datePattern: { 0: "%A %d %B %Y", "1": "%d/%m/%Y" }, // dimanche 1 mars 2020 // 01/03/2020 datePattern: { 0: "%d %B %Y", "1": "%d/%m/%Y" }, // 1 mars 2020 // 01/03/2020
abmonth: "janv,févr,mars,avril,mai,juin,juil,août,sept,oct,nov,déc", abmonth: "janv,févr,mars,avril,mai,juin,juil,août,sept,oct,nov,déc",
month: "janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre", month: "janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre",
abday: "dim,lun,mar,mer,jeu,ven,sam", abday: "dim,lun,mar,mer,jeu,ven,sam",

View File

@ -29,3 +29,4 @@
Back button now goes back to list of messages Back button now goes back to list of messages
If showMessage called with no message (eg all messages deleted) now return to the clock (fix #1267) If showMessage called with no message (eg all messages deleted) now return to the clock (fix #1267)
0.19: Use a larger font for message text if it'll fit 0.19: Use a larger font for message text if it'll fit
0.20: Allow tapping on the body to show a scrollable view of the message and title in a bigger font (fix #1405, #1031)

View File

@ -26,19 +26,15 @@ When a new message is received:
When a message is shown, you'll see a screen showing the message title and text. When a message is shown, you'll see a screen showing the message title and text.
### Android * The 'back-arrow' button (or physical button on Bangle.js 2) goes back to Messages, marking the current message as read.
* The 'back-arrow' button goes back to Messages, marking the current message as read.
* If shown, the 'tick' button opens the notification on the phone
* If shown, the 'cross' button dismisses the notification on the phone
* The top-left icon shows more options, for instance deleting the message of marking unread
### iOS
* The 'back-arrow' button goes back to Messages, marking the current message as read.
* If shown, the 'tick' button responds positively to the notification (accept call/etc)
* If shown, the 'cross' button responds negatively to the notification (dismiss call/etc)
* The top-left icon shows more options, for instance deleting the message of marking unread * The top-left icon shows more options, for instance deleting the message of marking unread
* On Bangle.js 2 you can tap on the message body to view a scrollable version of the title and text (or can use the top-left icon + `View Message`)
* If shown, the 'tick' button:
* **Android** opens the notification on the phone
* **iOS** responds positively to the notification (accept call/etc)
* If shown, the 'cross' button:
* **Android** dismisses the notification on the phone
* **iOS** responds negatively to the notification (dismiss call/etc)
## Images ## Images
_1. Screenshot of a notification_ _1. Screenshot of a notification_

View File

@ -198,9 +198,39 @@ function showMusicMessage(msg) {
layout.render(); layout.render();
} }
function showMessageScroller(msg) {
var bodyFont = fontBig;
g.setFont(bodyFont);
var lines = [];
if (msg.title) lines = g.wrapString(msg.title, g.getWidth()-10)
var titleCnt = lines.length;
if (titleCnt) lines.push(""); // add blank line after title
lines = lines.concat(g.wrapString(msg.body, g.getWidth()-10),["",/*LANG*/"< Back"]);
E.showScroller({
h : g.getFontHeight(), // height of each menu item in pixels
c : lines.length, // number of menu items
// a function to draw a menu item
draw : function(idx, r) {
// FIXME: in 2v13 onwards, clearRect(r) will work fine. There's a bug in 2v12
g.setBgColor(idx<titleCnt ? colBg : g.theme.bg).clearRect(r.x,r.y,r.x+r.w, r.y+r.h);
g.setFont(bodyFont).drawString(lines[idx], r.x, r.y);
}, select : function(idx) {
if (idx>=lines.length-2)
showMessage(msg.id);
}
});
// ensure button-press on Bangle.js 2 takes us back
if (process.env.HWVERSION>1) Bangle.btnWatches = [
setWatch(() => showMessage(msg.id), BTN1, {repeat:1,edge:"falling"})
];
}
function showMessageSettings(msg) { function showMessageSettings(msg) {
E.showMenu({"":{"title":/*LANG*/"Message"}, E.showMenu({"":{"title":/*LANG*/"Message"},
"< Back" : () => showMessage(msg.id), "< Back" : () => showMessage(msg.id),
/*LANG*/"View Message" : () => {
showMessageScroller(msg);
},
/*LANG*/"Delete" : () => { /*LANG*/"Delete" : () => {
MESSAGES = MESSAGES.filter(m=>m.id!=msg.id); MESSAGES = MESSAGES.filter(m=>m.id!=msg.id);
saveMessages(); saveMessages();
@ -245,12 +275,13 @@ function showMessage(msgid) {
title = (lines.length>2) ? lines.slice(0,2).join("\n")+"..." : lines.join("\n"); title = (lines.length>2) ? lines.slice(0,2).join("\n")+"..." : lines.join("\n");
} }
} }
function goBack() {
msg.new = false; saveMessages(); // read mail
cancelReloadTimeout(); // don't auto-reload to clock now
checkMessages({clockIfNoMsg:1,clockIfAllRead:0,showMsgIfUnread:0});
}
var buttons = [ var buttons = [
{type:"btn", src:getBackImage(), cb:()=>{ {type:"btn", src:getBackImage(), cb:goBack} // back
msg.new = false; saveMessages(); // read mail
cancelReloadTimeout(); // don't auto-reload to clock now
checkMessages({clockIfNoMsg:1,clockIfAllRead:0,showMsgIfUnread:0});
}} // back
]; ];
if (msg.positive) { if (msg.positive) {
buttons.push({fillx:1}); buttons.push({fillx:1});
@ -281,7 +312,7 @@ function showMessage(msgid) {
body = (lines.length>4) ? lines.slice(0,4).join("\n")+"..." : lines.join("\n"); body = (lines.length>4) ? lines.slice(0,4).join("\n")+"..." : lines.join("\n");
} }
} }
layout = new Layout({ type:"v", c: [ layout = new Layout({ type:"v", c: [
{type:"h", fillx:1, bgCol:colBg, c: [ {type:"h", fillx:1, bgCol:colBg, c: [
{ type:"btn", src:getMessageImage(msg), col:getMessageImageCol(msg), pad: 3, cb:()=>{ { type:"btn", src:getMessageImage(msg), col:getMessageImageCol(msg), pad: 3, cb:()=>{
@ -293,11 +324,18 @@ function showMessage(msgid) {
title?{type:"txt", font:titleFont, label:title, bgCol:colBg, fillx:1, pad:2 }:{}, title?{type:"txt", font:titleFont, label:title, bgCol:colBg, fillx:1, pad:2 }:{},
]}, ]},
]}, ]},
{type:"txt", font:bodyFont, label:body, fillx:1, filly:1, pad:2 }, {type:"txt", font:bodyFont, label:body, fillx:1, filly:1, pad:2, cb:()=>{
// allow tapping to show a larger version
showMessageScroller(msg);
} },
{type:"h",fillx:1, c: buttons} {type:"h",fillx:1, c: buttons}
]}); ]});
g.clearRect(Bangle.appRect); g.clearRect(Bangle.appRect);
layout.render(); layout.render();
// ensure button-press on Bangle.js 2 takes us back
if (process.env.HWVERSION>1) Bangle.btnWatches = [
setWatch(goBack, BTN1, {repeat:1,edge:"falling"})
];
} }

View File

@ -1,7 +1,7 @@
{ {
"id": "messages", "id": "messages",
"name": "Messages", "name": "Messages",
"version": "0.19", "version": "0.20",
"description": "App to display notifications from iOS and Gadgetbridge", "description": "App to display notifications from iOS and Gadgetbridge",
"icon": "app.png", "icon": "app.png",
"type": "app", "type": "app",

View File

@ -11,3 +11,5 @@
0.11: Changed cycle on minute to prevInfo to avoid the 2nd one being the blank line 0.11: Changed cycle on minute to prevInfo to avoid the 2nd one being the blank line
0.12: Removed dependancy on widpedom, now uses Bangle.getHealthStatus("day").steps 0.12: Removed dependancy on widpedom, now uses Bangle.getHealthStatus("day").steps
which requires 2.11.27 firmware to reset at midnight which requires 2.11.27 firmware to reset at midnight
0.13: call process.memory(false) to avoid triggering a GC of memory
supported in pre 2.12.13 firmware

View File

@ -2,8 +2,8 @@
"id": "pastel", "id": "pastel",
"name": "Pastel Clock", "name": "Pastel Clock",
"shortName": "Pastel", "shortName": "Pastel",
"version": "0.12", "version": "0.13",
"description": "A Configurable clock with custom fonts, background and weather display. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times. Requires firmware 2.11.27", "description": "A Configurable clock with custom fonts, background and weather display. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times.",
"icon": "pastel.png", "icon": "pastel.png",
"dependencies": {"mylocation":"app","weather":"app"}, "dependencies": {"mylocation":"app","weather":"app"},
"screenshots": [{"url":"screenshot_pastel.png"}, {"url":"weather_icons.png"}], "screenshots": [{"url":"screenshot_pastel.png"}, {"url":"weather_icons.png"}],

View File

@ -83,7 +83,7 @@ const infoData = {
ID_SS: { calc: () => 'Sunset: ' + sunSet }, ID_SS: { calc: () => 'Sunset: ' + sunSet },
ID_STEP: { calc: () => 'Steps: ' + getSteps() }, ID_STEP: { calc: () => 'Steps: ' + getSteps() },
ID_BATT: { calc: () => 'Battery: ' + E.getBattery() + '%' }, ID_BATT: { calc: () => 'Battery: ' + E.getBattery() + '%' },
ID_MEM: { calc: () => {var val = process.memory(); return 'Ram: ' + Math.round(val.usage*100/val.total) + '%';} }, ID_MEM: { calc: () => {var val = process.memory(false); return 'Ram: ' + Math.round(val.usage*100/val.total) + '%';} },
ID_ID: { calc: () => {var val = NRF.getAddress().split(':'); return 'Id: ' + val[4] + val[5];} }, ID_ID: { calc: () => {var val = NRF.getAddress().split(':'); return 'Id: ' + val[4] + val[5];} },
ID_FW: { calc: () => 'Fw: ' + process.env.VERSION } ID_FW: { calc: () => 'Fw: ' + process.env.VERSION }
}; };

View File

@ -2,7 +2,7 @@
"id": "waveclk", "id": "waveclk",
"name": "Wave Clock", "name": "Wave Clock",
"version": "0.02", "version": "0.02",
"description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: Works on any Bangle.js 2, but requires firmware 2v11 or later on Bangle.js 1**", "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/)",
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot.png"}], "screenshots": [{"url":"screenshot.png"}],
"type": "clock", "type": "clock",

View File

@ -5,6 +5,6 @@ A simple widget that shows the on/off status of the GPS.
The GPS can quickly run the battery down if it is on all the time so The GPS can quickly run the battery down if it is on all the time so
it is useful to know if it has been switched on or not. it is useful to know if it has been switched on or not.
- Uses Bangle.isGPSOn(), requires firmware v2.08.167 or later - Uses Bangle.isGPSOn()
- Shows in grey when the GPS is off - Shows in grey when the GPS is off
- Shows in amber when the GPS is on - Shows in amber when the GPS is on

View File

@ -8,7 +8,7 @@
"type": "widget", "type": "widget",
"supports": ["BANGLEJS", "BANGLEJS2"], "supports": ["BANGLEJS", "BANGLEJS2"],
"readme": "README.md", "readme": "README.md",
"description": "Displays the current step count from `Bangle.getHealthStatus(\"day\").steps` in 12x16 font, requires firmware v2.11.21 or later", "description": "Displays the current step count from `Bangle.getHealthStatus(\"day\").steps` in 12x16 font",
"tags": "widget,battery", "tags": "widget,battery",
"storage": [ "storage": [
{"name":"widpa.wid.js","url":"widpa.wid.js"} {"name":"widpa.wid.js","url":"widpa.wid.js"}

View File

@ -8,7 +8,7 @@
"type": "widget", "type": "widget",
"supports": ["BANGLEJS", "BANGLEJS2"], "supports": ["BANGLEJS", "BANGLEJS2"],
"readme": "README.md", "readme": "README.md",
"description": "Displays the current step count from `Bangle.getHealthStatus(\"day\").steps` in the Lato font, requires firmware v2.11.21 or later", "description": "Displays the current step count from `Bangle.getHealthStatus(\"day\").steps` in the Lato font",
"tags": "widget,battery", "tags": "widget,battery",
"storage": [ "storage": [
{"name":"widpb.wid.js","url":"widpb.wid.js"} {"name":"widpb.wid.js","url":"widpb.wid.js"}

View File

@ -157,19 +157,29 @@ log(untranslatedStrings.filter(e => e.uses>2).filter(e => !translatedStrings.fin
log(""); log("");
//process.exit(1); //process.exit(1);
var languages = JSON.parse(fs.readFileSync(BASEDIR+"/lang/index.json").toString()); let languages = JSON.parse(fs.readFileSync(`${BASEDIR}/lang/index.json`).toString());
languages.forEach(language => { languages.forEach(language => {
if (language.code=="en_GB") { if (language.code == "en_GB") {
console.log("Ignoring "+language.code); console.log(`Ignoring ${language.code}`);
return; return;
} }
console.log("Scanning "+language.code); console.log(`Scanning ${language.code}`);
log(language.code); log(language.code);
log("=========="); log("==========");
var translations = JSON.parse(fs.readFileSync(BASEDIR+"/lang/"+language.url).toString()); let translations = JSON.parse(fs.readFileSync(`${BASEDIR}/lang/${language.url}`).toString());
translatedStrings.forEach(str => { translatedStrings.forEach(translationItem => {
if (!translations.GLOBAL[str.str]) if (!translations.GLOBAL[translationItem.str]) {
console.log(`Missing translation for ${JSON.stringify(str)}`); console.log(`Missing GLOBAL translation for ${JSON.stringify(translationItem)}`);
translationItem.files.forEach(file => {
let m = file.match(/\/([a-zA-Z0-9_-]*)\//g);
if (m && m[0]) {
let appName = m[0].replaceAll("/", "");
if (translations[appName] && translations[appName][translationItem.str]) {
console.log(` but LOCAL translation found in \"${appName}\"`);
}
}
});
}
}); });
log(""); log("");
}); });

View File

@ -1,21 +1,148 @@
{ {
"//":"Italian language translations", "//1": "Italian language translations",
"GLOBAL": { "GLOBAL": {
"//":"Translations that apply for all apps", "//": "Translations that apply for all apps",
"Alarms" : "Sveglie", "On": "On",
"Hours" : "Ore", "on": "on",
"Minutes" : "Minuti", "Off": "Off",
"Enabled" : "Attiva", "off": "off",
"New Alarm" : "Nuova sveglia", "Ok": "Ok",
"Save" : "Salva", "Yes": "Sì",
"Back" : "Indietro", "No": "No",
"Repeat" : "Ripeti", "Alarm": "Sveglia",
"Delete" : "Cancella", "ALARM": "SVEGLIA",
"ALARM!" : "SVEGLIA!", "Alarms": "Sveglie",
"Sleep" : "Dormi" "Date": "Data",
"Year": "Anno",
"Month": "Mese",
"Day": "Giorno",
"Hour": "Ora",
"Hours": "Ore",
"Minute": "Minuto",
"Minutes": "Minuti",
"Second": "Secondo",
"Seconds": "Secondi",
"week": "settimana",
"Week": "Settimana",
"Enabled": "Attivo/a",
"New Alarm": "Nuova sveglia",
"Save": "Salva",
"Cancel": "Annulla",
"Back": "Indietro",
"Repeat": "Ripeti",
"Delete": "Cancella",
"ALARM!": "SVEGLIA!",
"Sleep": "Dormi",
"Timer": "Timer",
"TIMER": "TIMER",
"New Timer": "Nuovo timer",
"(repeat)": "(ripeti)",
"Auto snooze": "Posticipa automaticamente",
"Connected": "Connesso",
"Delete all messages": "Cancella tutti i messaggi",
"Delete All Messages": "Cancella tutti i messaggi",
"Message": "Messaggio",
"Messages": "Messaggi",
"No Messages": "Nessun messaggio",
"Keep Msgs": "Tieni i messaggi",
"Mark Unread": "Segna come non letto",
"Vibrate": "Vibrazione",
"Are you sure": "Sei sicuro/a",
"Music": "Musica",
"Apps": "App",
"App Settings": "Impostazioni app",
"Bluetooth": "Bluetooth",
"BLE": "BLE",
"Make Connectable": "Rendi collegabile",
"Programmable": "Programmabile",
"Remove": "Rimuovi",
"Utils": "Utilità",
"LCD": "LCD",
"LCD Brightness": "Luminosità LCD",
"LCD Timeout": "Timeout LCD",
"Wake on BTN1": "Risveglia con BTN1",
"Wake on BTN2": "Risveglia con BTN2",
"Wake on BTN3": "Risveglia con BTN3",
"Wake on FaceUp": "Risveglia a faccia in su",
"Wake on Touch": "Risveglia al tocco",
"Wake on Twist": "Risveglia con polso",
"Twist Timeout": "Timeout torsione",
"Twist Max Y": "Torsione Y max",
"Twist Threshold": "Soglia torsione",
"Customize": "Personalizza",
"Add Device": "Aggiungi dispositivo",
"Left": "Sinistra",
"Right": "Destra",
"Widgets": "Widget",
"Settings": "Impostazioni",
"No app has settings": "Non ci sono app con delle impostazioni",
"System": "Sistema",
"Alerts": "Avvisi",
"Theme": "Tema",
"Foreground": "Primo piano",
"Background": "Sfondo",
"Foreground 2": "Primo piano 2",
"Background 2": "Sfondo 2",
"Highlight FG": "Selezione PP",
"Highlight BG": "Selezione Sf",
"Utilities": "Utilità",
"Storage": "Memoria",
"Compact Storage": "Compatta memoria",
"Select Clock": "Seleziona orologio",
"No Clocks Found": "Nessun orologio trovato",
"Locale": "Localizzazione",
"Set Time": "Imposta orario",
"Time Zone": "Fuso orario",
"Whitelist": "Whitelist",
"Quiet Mode": "Modalità silenziosa",
"Disable": "Disabilita",
"Vibration": "Vibrazione",
"Show": "Mostra",
"Hide": "Nascondi",
"Rewrite Settings": "Riscrivi impostazioni",
"Reset Settings": "Reset impostazioni",
"Factory Reset": "Ripristino condizioni iniziali",
"Flatten Battery": "Scarica la batteria",
"Turn Off": "Spegni",
"This will remove everything": "Questo rimuoverà TUTTO",
"Error in settings": "Errore nelle impostazioni",
"Invalid settings": "Impostazioni non valide",
"Loading": "Caricamento",
"Launcher Settings": "Impostazioni Launcher",
"Font": "Font",
"Show clocks": "Mostra orologi",
"Log": "Log",
"Steps": "Passi",
"steps": "passi"
}, },
"alarm": { "//2": "App-specific overrides",
"//":"App-specific overrides", "launch": {
"rpt" : "ripeti" "Vector font size": "Dim. font vett.",
"App Source\nNot found": "Codice app\nnon trovato"
},
"messages": {
"Unread timer": "Timer msg non letti"
},
"run": {
"Record Run": "Registra corsa"
},
"setting": {
"Clock Style": "Formato ora",
"Compacting...\nTakes approx\n1 minute": "Compattamento in corso...\nCi vorrà circa un minuto",
"//1": "The new line before 'operazione' improves the layout",
"Flattening battery - this can take hours.\nLong-press button to cancel": "Scaricamento batteria in corso - l'\noperazione può richiedere ore. Tieni premuto il pulsante per annullare",
"Reset to Defaults": "Ripristinare le impostazioni predefinite",
"Connectable": "Collegamento",
"Connect device\nto add to\nwhitelist": "Collega un\ndispositivo\nper metterlo\nin whitelist",
"Stay Connectable": "Rimanere collegabile",
"Light BW": "Chiaro",
"Dark BW": "Scuro"
},
"wid_edit": {
"Reset": "Ripristina",
"Reset All": "Ripristina tutto",
"Reset all widgets": "Ripristina tutti i widget",
"Sort Order": "Ordinamento",
"Side": "Lato"
} }
} }

View File

@ -164,7 +164,7 @@ function Layout(layout, options) {
// Handler for touch events // Handler for touch events
function touchHandler(l,e) { function touchHandler(l,e) {
if (l.type=="btn" && l.cb && e.x>=l.x && e.y>=l.y && e.x<=l.x+l.w && e.y<=l.y+l.h) { if (l.cb && e.x>=l.x && e.y>=l.y && e.x<=l.x+l.w && e.y<=l.y+l.h) {
if (e.type==2 && l.cbl) l.cbl(e); else if (l.cb) l.cb(e); if (e.type==2 && l.cbl) l.cbl(e); else if (l.cb) l.cb(e);
} }
if (l.c) l.c.forEach(n => touchHandler(n,e)); if (l.c) l.c.forEach(n => touchHandler(n,e));