Merge branch 'espruino:master' into dev
32
apps.json
|
@ -2429,7 +2429,7 @@
|
|||
{
|
||||
"id": "calendar",
|
||||
"name": "Calendar",
|
||||
"version": "0.03",
|
||||
"version": "0.04",
|
||||
"description": "Simple calendar",
|
||||
"icon": "calendar.png",
|
||||
"screenshots": [{"url":"screenshot_calendar.png"}],
|
||||
|
@ -3896,7 +3896,7 @@
|
|||
"id": "qmsched",
|
||||
"name": "Quiet Mode Schedule and Widget",
|
||||
"shortName": "Quiet Mode",
|
||||
"version": "0.05",
|
||||
"version": "0.06",
|
||||
"description": "Automatically turn Quiet Mode on or off at set times, and change LCD options while Quiet Mode is active.",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot_b1_main.png"},{"url":"screenshot_b1_edit.png"},{"url":"screenshot_b1_lcd.png"},
|
||||
|
@ -4014,11 +4014,12 @@
|
|||
{
|
||||
"id": "thermom",
|
||||
"name": "Thermometer",
|
||||
"version": "0.04",
|
||||
"description": "Displays the current temperature in degree Celsius, updated every 20 seconds",
|
||||
"version": "0.05",
|
||||
"description": "Displays the current temperature in degree Celsius/Fahrenheit (depending on locale), updates every 10 seconds with average of last 5 readings.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool",
|
||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"thermom.app.js","url":"app.js"},
|
||||
|
@ -4080,7 +4081,7 @@
|
|||
"id": "thermomF",
|
||||
"name": "Fahrenheit Temp",
|
||||
"version": "0.01",
|
||||
"description": "A modification of the Thermometer App to display temprature in Fahrenheit",
|
||||
"description": "[NOT RECOMMENDED] A modification of the Thermometer App to display temprature in Fahrenheit. Please use the 'Thermometer App' and install 'Languages' to get the temperature in the correct format for your locale.",
|
||||
"icon": "thermf.png",
|
||||
"tags": "tool",
|
||||
"supports": ["BANGLEJS"],
|
||||
|
@ -4486,7 +4487,7 @@
|
|||
"name": "LCARS Clock",
|
||||
"shortName":"LCARS",
|
||||
"icon": "lcars.png",
|
||||
"version":"0.06",
|
||||
"version":"0.07",
|
||||
"readme": "README.md",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"description": "Library Computer Access Retrieval System (LCARS) clock.",
|
||||
|
@ -4495,7 +4496,8 @@
|
|||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"lcars.app.js","url":"lcars.app.js"},
|
||||
{"name":"lcars.img","url":"lcars.icon.js","evaluate":true}
|
||||
{"name":"lcars.img","url":"lcars.icon.js","evaluate":true},
|
||||
{"name":"lcars.settings.js","url":"lcars.settings.js"}
|
||||
]
|
||||
},
|
||||
{ "id": "binwatch",
|
||||
|
@ -5044,5 +5046,21 @@
|
|||
"data": [
|
||||
{"name":"circlesclock.json"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ltherm",
|
||||
"name": "Localized Thermometer",
|
||||
"shortName": "Thermometer",
|
||||
"version": "0.01",
|
||||
"description": "Displays the current temperature in localized units.",
|
||||
"icon": "thermf.png",
|
||||
"tags": "tool",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"ltherm.app.js","url":"app.js"},
|
||||
{"name":"ltherm.img","url":"icon.js","evaluate":true}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
0.01: Basic calendar
|
||||
0.02: Make Bangle 2 compatible
|
||||
0.03: Add setting to start week on Sunday
|
||||
0.04: Add setting to switch color schemes. On Bangle 2 non-dithering colors will be used by default. Use localized names for months and days of the week (Language app needed).
|
||||
|
|
|
@ -9,5 +9,6 @@ Basic calendar
|
|||
|
||||
## Settings
|
||||
|
||||
- Starts on Sunday: whether the calendar should start on Sunday (default is Monday).
|
||||
- Starts Sunday: whether the calendar should start on Sunday (default is Monday).
|
||||
- B2 Colors: use non-dithering colors (default, recommended for Bangle 2) or the original color scheme.
|
||||
|
||||
|
|
|
@ -1,5 +1 @@
|
|||
require("heatshrink").decompress(
|
||||
atob(
|
||||
"mEwxH+AH4A/ADuIUCARRDhgePCKIv13YAEDoYJFAA4RJFyQvcGBYRGy4dDy4uLCJgv/DoOBDgOBF5oRLF6IeBDgIvNCJYvQDwQuNCJovRADov/F9OsAEgv/F/4vhwIACAqYv/F/4vnd94vvX/4v/F/7vvF96//F/4v/d94v/F/4wsFxQwjFxgA/AH4A/AH4AZA=="
|
||||
)
|
||||
)
|
||||
require("heatshrink").decompress(atob("mEwwcCpMkyQC3wAIFgIRJn8JAoeQ/gRYwB0Bn57F/gCBHAgfCn8EDgdI/kSAoIR8oBkFgAFCCIysKCPM//4AKZAgR3/0Aj+Ag/ggP4gF/CPpr/Nf5r/NfYRhw4RL8IRDyEAABUJCIYC/AVI="))
|
|
@ -1,6 +1,6 @@
|
|||
const maxX = g.getWidth();
|
||||
const maxY = g.getHeight();
|
||||
const fontSize = g.getWidth()>200?2:1;
|
||||
const fontSize = g.getWidth() > 200 ? 2 : 1;
|
||||
const rowN = 7;
|
||||
const colN = 7;
|
||||
const headerH = maxY / 7;
|
||||
|
@ -10,26 +10,109 @@ const color1 = "#035AA6";
|
|||
const color2 = "#4192D9";
|
||||
const color3 = "#026873";
|
||||
const color4 = "#038C8C";
|
||||
const color5 = "#03A696";
|
||||
const gray1 = "#bbbbbb";
|
||||
const black = "#000000";
|
||||
const white = "#ffffff";
|
||||
const gray1 = "#444444";
|
||||
const gray2 = "#888888";
|
||||
const gray3 = "#bbbbbb";
|
||||
const red = "#d41706";
|
||||
const blue = "#0000ff";
|
||||
const yellow = "#ffff00";
|
||||
|
||||
let settings = require('Storage').readJSON("calendar.json", true) || {};
|
||||
if (settings.startOnSun === undefined)
|
||||
settings.startOnSun = false;
|
||||
if (settings.ndColors === undefined)
|
||||
if (process.env.HWVERSION == 2) {
|
||||
settings.ndColors = true;
|
||||
} else {
|
||||
settings.ndColors = false;
|
||||
}
|
||||
|
||||
if (settings.ndColors === true) {
|
||||
let bgColor = white;
|
||||
let bgColorMonth = blue;
|
||||
let bgColorDow = black;
|
||||
let bgColorWeekend = yellow;
|
||||
let fgOtherMonth = blue;
|
||||
let fgSameMonth = black;
|
||||
} else {
|
||||
let bgColor = color4;
|
||||
let bgColorMonth = color1;
|
||||
let bgColorDow = color2;
|
||||
let bgColorWeekend = color3;
|
||||
let fgOtherMonth = gray1;
|
||||
let fgSameMonth = white;
|
||||
}
|
||||
|
||||
function getDowLbls(locale) {
|
||||
let dowLbls;
|
||||
//TODO: Find some clever way to generate this programmatically from locale lib
|
||||
switch (locale) {
|
||||
case "de_AT":
|
||||
case "de_CH":
|
||||
case "de_DE":
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
|
||||
} else {
|
||||
dowLbls = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];
|
||||
}
|
||||
break;
|
||||
case "nl_NL":
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["zo", "ma", "di", "wo", "do", "vr", "za"];
|
||||
} else {
|
||||
dowLbls = ["ma", "di", "wo", "do", "vr", "za", "zo"];
|
||||
}
|
||||
break;
|
||||
case "fr_BE":
|
||||
case "fr_CH":
|
||||
case "fr_FR":
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"];
|
||||
} else {
|
||||
dowLbls = ["Lu", "Ma", "Me", "Je", "Ve", "Sa", "Di"];
|
||||
}
|
||||
break;
|
||||
case "sv_SE":
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"];
|
||||
} else {
|
||||
dowLbls = ["Lu", "Ma", "Me", "Je", "Ve", "Sa", "Di"];
|
||||
}
|
||||
break;
|
||||
case "it_CH":
|
||||
case "it_IT":
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa"];
|
||||
} else {
|
||||
dowLbls = ["Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"];
|
||||
}
|
||||
break;
|
||||
case "oc_FR":
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["dg", "dl", "dm", "dc", "dj", "dv", "ds"];
|
||||
} else {
|
||||
dowLbls = ["dl", "dm", "dc", "dj", "dv", "ds", "dg"];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
||||
} else {
|
||||
dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return dowLbls;
|
||||
}
|
||||
|
||||
function drawCalendar(date) {
|
||||
g.setBgColor(color4);
|
||||
g.setBgColor(bgColor);
|
||||
g.clearRect(0, 0, maxX, maxY);
|
||||
g.setBgColor(color1);
|
||||
g.setBgColor(bgColorMonth);
|
||||
g.clearRect(0, 0, maxX, headerH);
|
||||
g.setBgColor(color2);
|
||||
g.setBgColor(bgColorDow);
|
||||
g.clearRect(0, headerH, maxX, headerH + rowH);
|
||||
g.setBgColor(color3);
|
||||
g.setBgColor(bgColorWeekend);
|
||||
g.clearRect(colW * 5, headerH + rowH, maxX, maxY);
|
||||
for (let y = headerH; y < maxY; y += rowH) {
|
||||
g.drawLine(0, y, maxX, y);
|
||||
|
@ -40,24 +123,11 @@ function drawCalendar(date) {
|
|||
|
||||
const month = date.getMonth();
|
||||
const year = date.getFullYear();
|
||||
const monthMap = {
|
||||
0: "January",
|
||||
1: "February",
|
||||
2: "March",
|
||||
3: "April",
|
||||
4: "May",
|
||||
5: "June",
|
||||
6: "July",
|
||||
7: "August",
|
||||
8: "September",
|
||||
9: "October",
|
||||
10: "November",
|
||||
11: "December"
|
||||
};
|
||||
const localeMonth = require('locale').month(date);
|
||||
g.setFontAlign(0, 0);
|
||||
g.setFont("6x8", fontSize);
|
||||
g.setColor(white);
|
||||
g.drawString(`${monthMap[month]} ${year}`, maxX / 2, headerH / 2);
|
||||
g.drawString(`${localeMonth} ${year}`, maxX / 2, headerH / 2);
|
||||
g.drawPoly([10, headerH / 2, 20, 10, 20, headerH - 10], true);
|
||||
g.drawPoly(
|
||||
[maxX - 10, headerH / 2, maxX - 20, 10, maxX - 20, headerH - 10],
|
||||
|
@ -65,12 +135,7 @@ function drawCalendar(date) {
|
|||
);
|
||||
|
||||
g.setFont("6x8", fontSize);
|
||||
let dowLbls;
|
||||
if (settings.startOnSun) {
|
||||
dowLbls = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
||||
} else {
|
||||
dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
||||
}
|
||||
let dowLbls = getDowLbls(require('locale').name);
|
||||
dowLbls.forEach((lbl, i) => {
|
||||
g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
|
||||
});
|
||||
|
@ -120,14 +185,19 @@ function drawCalendar(date) {
|
|||
today.year === year && today.month === month && today.day === day - 50;
|
||||
if (isToday) {
|
||||
g.setColor(red);
|
||||
let x1 = x * colW;
|
||||
let y1 = y * rowH + headerH + rowH;
|
||||
let x2 = x * colW + colW;
|
||||
let y2 = y * rowH + headerH + rowH + rowH;
|
||||
g.drawRect(x1, y1, x2, y2);
|
||||
g.drawRect(
|
||||
x * colW,
|
||||
y * rowH + headerH + rowH,
|
||||
x * colW + colW - 1,
|
||||
y * rowH + headerH + rowH + rowH
|
||||
x1 + 1,
|
||||
y1 + 1,
|
||||
x2 - 1,
|
||||
y2 - 1
|
||||
);
|
||||
}
|
||||
g.setColor(day < 50 ? gray3 : white);
|
||||
g.setColor(day < 50 ? fgOtherMonth : fgSameMonth);
|
||||
g.drawString(
|
||||
(day > 50 ? day - 50 : day).toString(),
|
||||
x * colW + colW / 2,
|
||||
|
@ -145,10 +215,10 @@ const today = {
|
|||
};
|
||||
drawCalendar(date);
|
||||
clearWatch();
|
||||
Bangle.on("touch",area=>{
|
||||
Bangle.on("touch", area => {
|
||||
const month = date.getMonth();
|
||||
let prevMonth;
|
||||
if (area==1) {
|
||||
if (area == 1) {
|
||||
let prevMonth = month > 0 ? month - 1 : 11;
|
||||
if (prevMonth === 11) date.setFullYear(date.getFullYear() - 1);
|
||||
date.setMonth(prevMonth);
|
||||
|
|
Before Width: | Height: | Size: 540 B After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -1,24 +1,38 @@
|
|||
(function(back) {
|
||||
(function (back) {
|
||||
var FILE = "calendar.json";
|
||||
var settings = require('Storage').readJSON(FILE, true) || {};
|
||||
if (settings.startOnSun === undefined)
|
||||
settings.startOnSun = true;
|
||||
settings.startOnSun = false;
|
||||
if (settings.ndColors === undefined)
|
||||
if (process.env.HWVERSION == 2) {
|
||||
settings.ndColors = true;
|
||||
} else {
|
||||
settings.ndColors = false;
|
||||
}
|
||||
|
||||
function writeSettings() {
|
||||
require('Storage').writeJSON(FILE, settings);
|
||||
}
|
||||
|
||||
E.showMenu({
|
||||
"" : { "title" : "Calendar" },
|
||||
"< Back" : () => back(),
|
||||
'Start on Sunday': {
|
||||
"": { "title": "Calendar" },
|
||||
"< Back": () => back(),
|
||||
'Start Sunday': {
|
||||
value: settings.startOnSun,
|
||||
format: v => v?"Yes":"No",
|
||||
format: v => v ? "Yes" : "No",
|
||||
onchange: v => {
|
||||
settings.startOnSun = v;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
'B2 Colors': {
|
||||
value: settings.ndColors,
|
||||
format: v => v ? "Yes" : "No",
|
||||
onchange: v => {
|
||||
settings.ndColors = v;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
0.03: New design with different icons if gps, hrm or compass is on.
|
||||
0.04: Inluded LCARS Logo.
|
||||
0.05: Additional icons for (1) charging and (2) bat < 30%.
|
||||
0.06: Fix - Alarm disabled, if clock was closed
|
||||
0.06: Fix - Alarm disabled, if clock was closed.
|
||||
0.07: Added settings to adjust data that is shown for each row.
|
|
@ -5,10 +5,9 @@ Note: To display the steps, its necessary to install
|
|||
the [Pedometer widget](https://banglejs.com/apps/#pedometer%20widget).
|
||||
|
||||
## Features
|
||||
* Shows the time
|
||||
* Shows the date
|
||||
* Shows the current battery level in %
|
||||
* Shows the number of daily steps
|
||||
* LCARS Style watch face
|
||||
* Shows satate (charging, out of battery etc.)
|
||||
* SHows data that can be configured (steps, HRM, temperature etc.)
|
||||
* Swipe left/right to activate an alarm
|
||||
|
||||
## Icons
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 8.5 KiB |
|
@ -1,8 +1,21 @@
|
|||
const filename = "lcars.setting.json";
|
||||
const SETTINGS_FILE = "lcars.setting.json";
|
||||
const Storage = require("Storage");
|
||||
let settings = Storage.readJSON(filename,1) || {
|
||||
|
||||
|
||||
// ...and overwrite them with any saved values
|
||||
// This way saved values are preserved if a new version adds more settings
|
||||
const storage = require('Storage')
|
||||
let settings = {
|
||||
alarm: -1,
|
||||
dataRow1: "Battery",
|
||||
dataRow2: "Steps",
|
||||
dataRow3: "Temp."
|
||||
};
|
||||
let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings;
|
||||
for (const key in saved_settings) {
|
||||
settings[key] = saved_settings[key]
|
||||
}
|
||||
let hrmValue = 0;
|
||||
|
||||
/*
|
||||
* Requirements and globals
|
||||
|
@ -12,7 +25,7 @@ const locale = require('locale');
|
|||
var backgroundImage = {
|
||||
width : 176, height : 151, bpp : 3,
|
||||
transparent : 2,
|
||||
buffer : require("heatshrink").decompress(atob("AAUEufPnnzATkAg4daIIXnz15ATvkwEDDrUAgPHQDyDghyAeQcNzJQ0cuPHATCDBDrUDJQ1AgAA3jjOF+BA4T4KDFyBB5Qf4ABQAaD9QAaD/QesH8CD/n/8Qf8//+AQfsB///GQ6D2h5BJQf6D7/yD8jl/IIIABjiD5n4/DAAWAQe8B//8QYfH//x4CD2HwMDQIf4AoP4Qesf/56BQYYFBuP/Qev//0AQYoKBn/gQecH/lwQwQADBYaDzGoZBHR4OAQehBKj5BBsuWrICDBAIAofYZBFBAZ6qIJJ6DQZBB3IAiDDgZBygJ6EIIn8IOqDKIIscuPHAQdwINkHIJEfIIPnz15AQeAINT+CHwcPAYI1BIIU8+fPAQbOqg56BQYcAgKD4IIv4RgSDCAQSD34AIC//wBYSDyO4P+IIoIB+E/8AFBQeL7B//HHYJKE+P/AoSDygF/QQJBF//4AoSDygEBQYgFBj/xZYaDzgE/PoIAE/wMDQeZBB/jICAAMcuAMDQevgQwR0CvyD3gP/BAxBEQek4A40OQe4ANQegAMQf6D/AAccQf8Ak6DFyCD/QfcDQYueIPMAuaDE+fBIPMOQYoCb8glB7dt2wCW2EAgKDFATkAg2atOmAS5eBhKDigyDZ2zHCjiD/AAMChEgwQCcQb4AiQb5BiQbscuPHATyDfyfPnnzATnwQbsBQD6DghKAeQcJoHiFBggCYQYVhdwQATgOmgVPNAnOECwAGQYIZXgM2dI1wIL2aoCDYibsF4CD/QcGYILGmyaDFwCD/QfaADQf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D4jCD/ADKDnILSD/Qf6DEHO6DJIP6D/Qf6D/QY8cuPHAQdAQfPz588AQeAQf8cuCD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6DqoCD5HO6DJIP6D/Qf6D/QY8cuPHAQdwE7sGzCDZ+fPngCDwBBe7aD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/QfcTQYvAQf6DgzVAQbECp6DE5yD5gCDFATqDCsOAIKtB00AhKDEATnwQYVt2wCXQwKDltOmAS6IC2aD82BBCQccaQbGAA=="))
|
||||
buffer : require("heatshrink").decompress(atob("AAdx48cATsAg4daIAX3799ATv2wEFDrUAgNHQDyDghaAeQcJKG86D4gRKGgAA4jxKFuBB5iaDF6BB5ZwyD6QAYCC4CD/Qf6Dzg/gQf8H/iD/n//wCD9gP///wQfpBKQf6D4h5BB/yD8jl/IIIABjiD5n4/DAAWAQe8B//8QYfHj//PAaDzHwICCAAP4gYCBQep6DIIYFBRgKD1j/+gB9BQYYKBn/gQen/+BBFQAUH/iDzGoZBHJoOAQeRBDj5BHj6PB0WKlACDJQIAofYZBFBAZBBAGMHPQZB8QYZAEIIcDIOiDI/hB3QZBBFjlx44CDuBBpg4DCIJEfIIPnz15AQeAQeH8gIDBGoJBCnnz54CDZ1UHPQMHIIUAIIKD3II6MBQYQCCQeI1B+BBC/BKCBASGCQeK5B/xBC4BKEn/gAoKDyj//45BFj/xZYSDzgF/IAP+JQrLCQecAgKDBF4cHQYKJDQecAn6EBAAiJEQeZBB/jICAAMcvwMDQevgQwR0CIIiDzgP/BA1/4CD3nAHGhyD3ABqD0ABiD/Qf4ADjiD/gEnQYuQQf6D7gaDFzxB5gFzQYnz4BB5hyDFATfkEoIdagEBQYoCcgEHDrReBhKDhwEBQbYABjiD/AH4A/AH4AGiFx48cATsAg4daIIWSpMkATuQEbkAgJfbQckJQDyDhZxQA1gRKFpBA4gEQQYtwIPMSQYtAIPKADQfqADAQRA5Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4A/AH4A/AH4A/AFkcuPHAQdAIPOSpMkAQaD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4A/AH4A/AH4A/AGUcuPHAQdwIPOSpMkAQaD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4AciSDFoCD/QfcCQYtIIPMAQYoC6gEJQYgC6gEBQf7HCQf4ABiiD9"))
|
||||
}
|
||||
|
||||
var iconEarth = {
|
||||
|
@ -95,6 +108,33 @@ function queueDraw() {
|
|||
}
|
||||
|
||||
|
||||
function printData(key, y){
|
||||
g.setFontAlign(-1,-1,0);
|
||||
|
||||
if(key == "Battery"){
|
||||
var bat = E.getBattery();
|
||||
g.drawString("BAT:", 30, y);
|
||||
g.drawString(bat+ "%", 68, y);
|
||||
|
||||
} else if(key == "Steps"){
|
||||
var steps = getSteps();
|
||||
g.drawString("STEP:", 30, y);
|
||||
g.drawString(steps, 68, y);
|
||||
|
||||
} else if(key == "Temp."){
|
||||
var temperature = Math.floor(E.getTemperature());
|
||||
g.drawString("TEMP:", 30, y);
|
||||
g.drawString(temperature + "C", 69, y);
|
||||
|
||||
} else if(key == "HRM"){
|
||||
g.drawString("HRM:", 30, y);
|
||||
g.drawString(hrmValue, 69, y);
|
||||
|
||||
} else {
|
||||
g.drawString("NOT FOUND", 30, y);
|
||||
}
|
||||
}
|
||||
|
||||
function draw(){
|
||||
|
||||
// First handle alarm to show this correctly afterwards
|
||||
|
@ -125,7 +165,7 @@ function draw(){
|
|||
// Alarm within symbol
|
||||
g.setFontAlign(0,0,0);
|
||||
g.setFontAntonioSmall();
|
||||
g.drawString(iconImg.text, 115+25, 102);
|
||||
g.drawString(iconImg.text, 115+25, 105);
|
||||
if(isAlarmEnabled() > 0){
|
||||
g.drawString(getAlarmMinutes(), 115+25, 115+25);
|
||||
}
|
||||
|
@ -147,18 +187,9 @@ function draw(){
|
|||
g.drawString(dayName, 100, 55);
|
||||
|
||||
// Draw battery
|
||||
g.drawString("BAT:", 25, 98);
|
||||
g.drawString(bat+ "%", 62, 98);
|
||||
|
||||
// Draw steps
|
||||
var steps = getSteps();
|
||||
g.drawString("STEP:", 25, 121);
|
||||
g.drawString(steps, 62, 121);
|
||||
|
||||
// Temperature
|
||||
g.setFontAlign(-1,-1,0);
|
||||
g.drawString("TEMP:", 25, 144);
|
||||
g.drawString(Math.floor(E.getTemperature()) + "C", 62, 144);
|
||||
printData(settings.dataRow1, 98);
|
||||
printData(settings.dataRow2, 121);
|
||||
printData(settings.dataRow3, 144);
|
||||
|
||||
// Queue draw in one minute
|
||||
queueDraw();
|
||||
|
@ -182,6 +213,12 @@ function stepsWidget() {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
/*
|
||||
* HRM Listener
|
||||
*/
|
||||
Bangle.on('HRM', function (hrm) {
|
||||
hrmValue = hrm.bpm;
|
||||
});
|
||||
|
||||
/*
|
||||
* Handle alarm
|
||||
|
@ -220,7 +257,7 @@ function handleAlarm(){
|
|||
|
||||
// Update alarm state to disabled
|
||||
settings.alarm = -1;
|
||||
Storage.writeJSON(filename, settings);
|
||||
Storage.writeJSON(SETTINGS_FILE, settings);
|
||||
}
|
||||
|
||||
|
||||
|
@ -250,7 +287,7 @@ Bangle.on('swipe',function(dir) {
|
|||
draw();
|
||||
|
||||
// Update alarm state
|
||||
Storage.writeJSON(filename, settings);
|
||||
Storage.writeJSON(SETTINGS_FILE, settings);
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
(function(back) {
|
||||
const SETTINGS_FILE = "lcars.setting.json";
|
||||
|
||||
// initialize with default settings...
|
||||
const storage = require('Storage')
|
||||
let settings = {
|
||||
alarm: -1,
|
||||
dataRow1: "Battery",
|
||||
dataRow2: "Steps",
|
||||
dataRow3: "Temp."
|
||||
};
|
||||
let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings;
|
||||
for (const key in saved_settings) {
|
||||
settings[key] = saved_settings[key]
|
||||
}
|
||||
|
||||
function save() {
|
||||
storage.write(SETTINGS_FILE, settings)
|
||||
}
|
||||
|
||||
var data_options = ['Battery', 'Steps', 'Temp.', "HRM"];
|
||||
|
||||
E.showMenu({
|
||||
'': { 'title': 'LCARS Clock' },
|
||||
'< Back': back,
|
||||
'Row 1': {
|
||||
value: 0 | data_options.indexOf(settings.dataRow1),
|
||||
min: 0, max: 3,
|
||||
format: v => data_options[v],
|
||||
onchange: v => {
|
||||
settings.dataRow1 = data_options[v];
|
||||
save();
|
||||
},
|
||||
},
|
||||
'Row 2': {
|
||||
value: 0 | data_options.indexOf(settings.dataRow2),
|
||||
min: 0, max: 3,
|
||||
format: v => data_options[v],
|
||||
onchange: v => {
|
||||
settings.dataRow2 = data_options[v];
|
||||
save();
|
||||
},
|
||||
},
|
||||
'Row 3': {
|
||||
value: 0 | data_options.indexOf(settings.dataRow3),
|
||||
min: 0, max: 3,
|
||||
format: v => data_options[v],
|
||||
onchange: v => {
|
||||
settings.dataRow3 = data_options[v];
|
||||
save();
|
||||
},
|
||||
}
|
||||
});
|
||||
})
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,3 @@
|
|||
# Thermometer
|
||||
|
||||
Localized Bangle.js 2 thermometer app. It also starts maintaining an average of the temperature to help lower the margin of error after 10 consecutive readings; due to the low quality die-thermometer.
|
|
@ -0,0 +1,25 @@
|
|||
function drawTemperature() {
|
||||
g.reset(1).clearRect(0,24,g.getWidth(),g.getHeight());
|
||||
g.setFont("6x8",2).setFontAlign(0,0);
|
||||
var x = g.getWidth()/2;
|
||||
var y = g.getHeight()/2 + 10;
|
||||
g.drawString("Temp", x, y - 45);
|
||||
g.setFontVector(70).setFontAlign(0,0);
|
||||
var h = E.getTemperature();
|
||||
if (avg.length < 10) {
|
||||
avg[avg.length] = h;
|
||||
} else {
|
||||
avg.shift();
|
||||
avg[avg.length] = h;
|
||||
h = ((avg[0] + avg[1] + avg[2] + avg[3] + avg[4] + avg[5] + avg[6] + avg[7] + avg[8] + avg[9]) / 10);
|
||||
}
|
||||
var t = require('locale').temp(h);
|
||||
g.drawString(t, x, y);
|
||||
}
|
||||
const avg = [];
|
||||
setInterval(function() {
|
||||
drawTemperature();
|
||||
}, 2000);
|
||||
E.showMessage("Loading...");
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwhC/AH4AChGIxGAC6eIAQgARFgUIC9ReCAYJgSC7BHDF6gUBC6ovWI/5Hga/6P/ABsCkABDC/4XxkQXDkQuSAQwXPDQkAC6BBCkQDDC6MCmczFoIXQCQQXBDgQXP2EA2YXBncAhYXR3YXB3YXRCQWznYcCC6ICBAYYXPhYrBApAwPFyQqCIoYuRLwZgDAH4A/"))
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -3,3 +3,4 @@
|
|||
0.03: Bangle.js 2 support
|
||||
0.04: Move Quiet Mode LCD options from global settings to this app
|
||||
0.05: Avoid immediately redrawing widgets on load
|
||||
0.06: Fix: don't try to redraw widget when widgets not loaded
|
|
@ -19,5 +19,5 @@ exports.setMode = function(mode) {
|
|||
{quiet:mode}
|
||||
));
|
||||
exports.applyOptions(mode);
|
||||
if (WIDGETS && "qmsched" in WIDGETS) WIDGETS["qmsched"].draw();
|
||||
if (typeof WIDGETS === "object" && "qmsched" in WIDGETS) WIDGETS["qmsched"].draw();
|
||||
};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
0.02: New App!
|
||||
0.03: Improved messages and added Celsius sign
|
||||
0.04: Make temperature value readable on smaller screens
|
||||
0.05: Use temperature from current locale
|
||||
Update every 10s, average last 5 readings
|
||||
Changes based on #1092
|
||||
|
|
|
@ -1,13 +1,27 @@
|
|||
// history of temperature readings
|
||||
var history = [];
|
||||
|
||||
|
||||
// When we get temperature...
|
||||
function onTemperature(p) {
|
||||
g.reset(1).clearRect(0,24,g.getWidth(),g.getHeight());
|
||||
var rect = Bangle.appRect;
|
||||
g.reset(1).clearRect(rect.x, rect.y, rect.x2, rect.y2);
|
||||
g.setFont("6x8",2).setFontAlign(0,0);
|
||||
var x = g.getWidth()/2;
|
||||
var y = g.getHeight()/2 + 10;
|
||||
var x = (rect.x+rect.x2)/2;
|
||||
var y = (rect.y+rect.y2)/2 + 10;
|
||||
g.drawString("Temperature:", x, y - 45);
|
||||
g.setFontVector(g.getWidth() > 200 ? 70 : 40).setFontAlign(0,0);
|
||||
g.drawString(p.temperature.toFixed(1) + " °C", x, y);
|
||||
g.setFontVector(g.getWidth() > 200 ? 70 : 50).setFontAlign(0,0);
|
||||
|
||||
// Average the last 5 temperature readings
|
||||
while (history.length>4) history.shift();
|
||||
history.push(p.temperature);
|
||||
var avrTemp = E.sum(history) / history.length;
|
||||
// Draw the temperature
|
||||
var t = require('locale').temp(avrTemp).replace("'","°");
|
||||
g.drawString(t, x, y);
|
||||
}
|
||||
|
||||
// Gets the temperature in the most accurate way (pressure sensor or inbuilt thermistor)
|
||||
function drawTemperature() {
|
||||
if (Bangle.getPressure) {
|
||||
Bangle.getPressure().then(onTemperature);
|
||||
|
@ -18,11 +32,10 @@ function drawTemperature() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
setInterval(function() {
|
||||
drawTemperature();
|
||||
}, 20000);
|
||||
drawTemperature();
|
||||
}, 10000);
|
||||
E.showMessage("Reading temperature...");
|
||||
drawTemperature();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
|
After Width: | Height: | Size: 2.4 KiB |
|
@ -60,7 +60,7 @@ const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'suppo
|
|||
const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate'];
|
||||
const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info
|
||||
const VALID_DUPLICATES = [ '.tfmodel', '.tfnames' ];
|
||||
const GRANDFATHERED_ICONS = ["hebrew_calendar", "fontclock", "slidingtext", "solarclock", "sweepclock", "matrixclock", "speedo", "s7clk", "mmonday", "bclock", "snek", "dane", "fclock", "digiclock", "astral", "alpinenav", "slomoclock", "tapelauncher", "arrow", "doztime", "swiperclocklaunch", "pebble", "rebble"];
|
||||
const GRANDFATHERED_ICONS = ["s7clk", "snek", "astral", "alpinenav", "slomoclock", "arrow", "pebble", "rebble"];
|
||||
|
||||
function globToRegex(pattern) {
|
||||
const ESCAPE = '.*+-?^${}()|[]\\';
|
||||
|
@ -188,9 +188,9 @@ apps.forEach((app,appIdx) => {
|
|||
else ERROR(`JS icon ${file.name} does not match the pattern 'require("heatshrink").decompress(atob("..."))'`);
|
||||
}
|
||||
if (match) {
|
||||
if (icon[0] != 48 || icon[1] != 48) {
|
||||
if (GRANDFATHERED_ICONS.includes(app.id)) WARN(`JS icon ${file.name} should be 48x48px but is instead ${icon[0]}x${icon[1]}px`);
|
||||
else ERROR(`JS icon ${file.name} should be 48x48px but is instead ${icon[0]}x${icon[1]}px`);
|
||||
if (icon[0] > 48 || icon[0] < 24 || icon[1] > 48 || icon[1] < 24) {
|
||||
if (GRANDFATHERED_ICONS.includes(app.id)) WARN(`JS icon ${file.name} should be 48x48px (or slightly under) but is instead ${icon[0]}x${icon[1]}px`);
|
||||
else ERROR(`JS icon ${file.name} should be 48x48px (or slightly under) but is instead ${icon[0]}x${icon[1]}px`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|