2021-11-26 20:25:28 +00:00
|
|
|
var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
|
2021-11-22 22:08:19 +00:00
|
|
|
require("f_latosmall").add(Graphics);
|
2021-12-19 21:09:00 +00:00
|
|
|
const storage = require('Storage');
|
|
|
|
const locale = require("locale");
|
2021-09-14 21:01:20 +00:00
|
|
|
const SETTINGS_FILE = "pastel.json";
|
2021-11-26 20:25:28 +00:00
|
|
|
const LOCATION_FILE = "mylocation.json";
|
2022-02-08 23:12:18 +00:00
|
|
|
const w = g.getWidth();
|
|
|
|
const h = g.getHeight();
|
2021-11-22 22:50:27 +00:00
|
|
|
let settings;
|
2021-11-26 20:25:28 +00:00
|
|
|
let location;
|
2021-09-14 21:01:20 +00:00
|
|
|
|
2022-02-08 23:12:18 +00:00
|
|
|
// variable for controlling idle alert
|
|
|
|
let lastStep = getTime();
|
|
|
|
let lastStepTime = '??';
|
|
|
|
let warned = 0;
|
|
|
|
let idle = false;
|
|
|
|
let IDLE_MINUTES = 26;
|
|
|
|
|
2021-12-19 21:09:00 +00:00
|
|
|
// cloud, sun, partSun, snow, rain, storm, error
|
|
|
|
// create 1 bit, max contrast, brightness set to 85
|
|
|
|
var cloudIcon = require("heatshrink").decompress(atob("kEggIfcj+AAYM/8ADBuFwAYPAmADCCAMBwEf8ADBhFwg4aBnEPAYMYjAVBhgDDDoQDHCYc4jwDB+EP///FYIDBMTgA=="));
|
|
|
|
var sunIcon = require("heatshrink").decompress(atob("kEggILIgOAAZkDAYPAgeBwPAgIFBBgPhw4TBp/yAYMcnADBnEcAYMwhgDBsEGgE/AYP8AYYLDCYgbDEYYrD8fHIwI7CIYZLDL54AHA=="));
|
|
|
|
var sunPartIcon = require("heatshrink").decompress(atob("kEggIHEmADJjEwsEAjkw8EAh0B4EAg35wEAgP+CYMDwv8AYMDBAP2g8HgH+g0DBYMMgPwAYX8gOMEwMG3kAg8OvgSBjg2BgcYGQIcBAY5CBg0Av//HAM///4MYgNBEIMOCoUMDoUAnBwGkEA"));
|
|
|
|
var snowIcon = require("heatshrink").decompress(atob("kEggITQj/AAYM98ADBsEwAYPAjADCj+AgOAj/gAYMIuEHwEAjEPAYQVChk4AYQhCAYcYBYQTDnEPgEB+EH///IAQACE4IAB8EICIPghwDB4EeBYNAjgDBg8EAYQYCg4bCgZuFA=="));
|
|
|
|
var rainIcon = require("heatshrink").decompress(atob("kEggIPMh+AAYM/8ADBuFwAYPgmADB4EbAYOAj/ggOAhnwg4aBnAeCjEcCIMMjADCDoQDHjAPCnAXCuEP///8EDAYJECAAXBwkAgPDhwDBwUMgEEhkggEOjFgFgMQLYQAOA=="));
|
|
|
|
var errIcon = require("heatshrink").decompress(atob("kEggILIgOAAYsD4ADBg/gAYMGsADBhkwAYsYjADCjgDBmEMAYNxxwDBsOGAYPBwYDEgOBwOAgYDB4EDHYPAgwDBsADDhgDBFIcwjAHBjE4AYMcmADBhhNCKIcG/4AGOw4A=="));
|
|
|
|
|
2022-02-08 23:12:18 +00:00
|
|
|
// saves having to recode all the small font calls
|
|
|
|
function setSmallFont() {
|
|
|
|
g.setFontLatoSmall();
|
|
|
|
}
|
2021-12-19 21:09:00 +00:00
|
|
|
|
2021-09-14 21:01:20 +00:00
|
|
|
function loadSettings() {
|
|
|
|
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
|
|
|
|
settings.grid = settings.grid||false;
|
|
|
|
settings.font = settings.font||"Lato";
|
2022-09-19 14:17:23 +00:00
|
|
|
settings.idle_check = (settings.idle_check === undefined ? true : settings.idle_check);
|
2021-09-14 21:01:20 +00:00
|
|
|
}
|
|
|
|
|
2021-11-26 20:25:28 +00:00
|
|
|
// requires the myLocation app
|
|
|
|
function loadLocation() {
|
2022-02-11 23:27:47 +00:00
|
|
|
location = require("Storage").readJSON(LOCATION_FILE,1)||{};
|
|
|
|
location.lat = location.lat||51.5072;
|
|
|
|
location.lon = location.lon||0.1276;
|
|
|
|
location.location = location.location||"London";
|
2021-11-26 20:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function extractTime(d){
|
|
|
|
var h = d.getHours(), m = d.getMinutes();
|
|
|
|
return(("0"+h).substr(-2) + ":" + ("0"+m).substr(-2));
|
|
|
|
}
|
|
|
|
|
|
|
|
var sunRise = "00:00";
|
|
|
|
var sunSet = "00:00";
|
2021-11-27 11:23:03 +00:00
|
|
|
var drawCount = 0;
|
2021-11-26 20:25:28 +00:00
|
|
|
|
|
|
|
function updateSunRiseSunSet(now, lat, lon, line){
|
|
|
|
// get today's sunlight times for lat/lon
|
|
|
|
var times = SunCalc.getTimes(new Date(), lat, lon);
|
|
|
|
|
|
|
|
// format sunrise time from the Date object
|
|
|
|
sunRise = extractTime(times.sunrise);
|
|
|
|
sunSet = extractTime(times.sunset);
|
|
|
|
}
|
|
|
|
|
2021-11-22 21:17:50 +00:00
|
|
|
function loadFonts() {
|
|
|
|
// load font files based on settings.font
|
|
|
|
if (settings.font == "Architect")
|
2021-11-22 22:50:27 +00:00
|
|
|
require("f_architect").add(Graphics);
|
2021-11-22 21:17:50 +00:00
|
|
|
else if (settings.font == "GochiHand")
|
|
|
|
require("f_gochihand").add(Graphics);
|
|
|
|
else if (settings.font == "CabinSketch")
|
|
|
|
require("f_cabin").add(Graphics);
|
|
|
|
else if (settings.font == "Orbitron")
|
|
|
|
require("f_orbitron").add(Graphics);
|
|
|
|
else if (settings.font == "Monoton")
|
|
|
|
require("f_monoton").add(Graphics);
|
|
|
|
else if (settings.font == "Elite")
|
|
|
|
require("f_elite").add(Graphics);
|
|
|
|
else
|
2021-11-22 22:08:19 +00:00
|
|
|
require("f_lato").add(Graphics);
|
2021-11-22 21:17:50 +00:00
|
|
|
}
|
2021-11-22 21:03:53 +00:00
|
|
|
|
2022-01-20 23:29:37 +00:00
|
|
|
function getSteps() {
|
|
|
|
try {
|
|
|
|
return Bangle.getHealthStatus("day").steps;
|
|
|
|
} catch (e) {
|
|
|
|
if (WIDGETS.wpedom !== undefined)
|
|
|
|
return WIDGETS.wpedom.getSteps();
|
|
|
|
else
|
2022-02-08 23:12:18 +00:00
|
|
|
return '???';
|
2021-11-24 19:06:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const infoData = {
|
|
|
|
ID_BLANK: { calc: () => '' },
|
2022-02-08 23:12:18 +00:00
|
|
|
ID_DATE: { calc: () => {var d = (new Date()).toString().split(" "); return d[2] + ' ' + d[1] + ' ' + d[3];} },
|
|
|
|
ID_DAY: { calc: () => {var d = require("locale").dow(new Date()).toLowerCase(); return d[0].toUpperCase() + d.substring(1);} },
|
2021-11-26 20:25:28 +00:00
|
|
|
ID_SR: { calc: () => 'Sunrise: ' + sunRise },
|
|
|
|
ID_SS: { calc: () => 'Sunset: ' + sunSet },
|
2022-01-20 23:29:37 +00:00
|
|
|
ID_STEP: { calc: () => 'Steps: ' + getSteps() },
|
2022-02-08 23:12:18 +00:00
|
|
|
ID_LAST: { calc: () => 'Last Step: ' + lastStepTime },
|
2021-11-24 19:06:06 +00:00
|
|
|
ID_BATT: { calc: () => 'Battery: ' + E.getBattery() + '%' },
|
2022-02-07 23:05:59 +00:00
|
|
|
ID_MEM: { calc: () => {var val = process.memory(false); return 'Ram: ' + Math.round(val.usage*100/val.total) + '%';} },
|
2021-11-24 19:06:06 +00:00
|
|
|
ID_ID: { calc: () => {var val = NRF.getAddress().split(':'); return 'Id: ' + val[4] + val[5];} },
|
|
|
|
ID_FW: { calc: () => 'Fw: ' + process.env.VERSION }
|
|
|
|
};
|
|
|
|
|
|
|
|
const infoList = Object.keys(infoData).sort();
|
|
|
|
let infoMode = infoList[0];
|
|
|
|
|
|
|
|
function nextInfo() {
|
|
|
|
let idx = infoList.indexOf(infoMode);
|
|
|
|
if (idx > -1) {
|
|
|
|
if (idx === infoList.length - 1) infoMode = infoList[0];
|
|
|
|
else infoMode = infoList[idx + 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function prevInfo() {
|
|
|
|
let idx = infoList.indexOf(infoMode);
|
|
|
|
if (idx > -1) {
|
|
|
|
if (idx === 0) infoMode = infoList[infoList.length - 1];
|
|
|
|
else infoMode = infoList[idx - 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-19 21:09:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
Choose weather icon to display based on condition.
|
|
|
|
Based on function from the Bangle weather app so it should handle all of the conditions
|
|
|
|
sent from gadget bridge.
|
|
|
|
*/
|
|
|
|
function chooseIcon(condition) {
|
|
|
|
condition = condition.toLowerCase();
|
|
|
|
if (condition.includes("thunderstorm")) return stormIcon;
|
|
|
|
if (condition.includes("freezing")||condition.includes("snow")||
|
|
|
|
condition.includes("sleet")) {
|
|
|
|
return snowIcon;
|
|
|
|
}
|
|
|
|
if (condition.includes("drizzle")||
|
|
|
|
condition.includes("shower")) {
|
|
|
|
return rainIcon;
|
|
|
|
}
|
|
|
|
if (condition.includes("rain")) return rainIcon;
|
|
|
|
if (condition.includes("clear")) return sunIcon;
|
|
|
|
if (condition.includes("few clouds")) return partSunIcon;
|
|
|
|
if (condition.includes("scattered clouds")) return cloudIcon;
|
|
|
|
if (condition.includes("clouds")) return cloudIcon;
|
|
|
|
if (condition.includes("mist") ||
|
|
|
|
condition.includes("smoke") ||
|
|
|
|
condition.includes("haze") ||
|
|
|
|
condition.includes("sand") ||
|
|
|
|
condition.includes("dust") ||
|
|
|
|
condition.includes("fog") ||
|
|
|
|
condition.includes("ash") ||
|
|
|
|
condition.includes("squalls") ||
|
|
|
|
condition.includes("tornado")) {
|
|
|
|
return cloudIcon;
|
|
|
|
}
|
|
|
|
return cloudIcon;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Get weather stored in json file by weather app.
|
|
|
|
*/
|
|
|
|
function getWeather() {
|
|
|
|
let jsonWeather = storage.readJSON('weather.json');
|
|
|
|
return jsonWeather;
|
|
|
|
}
|
|
|
|
|
2021-09-13 19:26:53 +00:00
|
|
|
function draw() {
|
2022-02-08 23:12:18 +00:00
|
|
|
if (!idle)
|
|
|
|
drawClock();
|
|
|
|
else
|
|
|
|
drawIdle();
|
|
|
|
queueDraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawClock() {
|
2021-09-13 19:26:53 +00:00
|
|
|
var d = new Date();
|
|
|
|
var da = d.toString().split(" ");
|
|
|
|
var time = da[4].substr(0,5);
|
|
|
|
|
|
|
|
var hh = da[4].substr(0,2);
|
|
|
|
var mm = da[4].substr(3,2);
|
|
|
|
var day = da[0];
|
|
|
|
var month_day = da[1] + " " + da[2];
|
|
|
|
|
|
|
|
// fix hh for 12hr clock
|
|
|
|
var h2 = "0" + parseInt(hh) % 12 || 12;
|
2021-09-27 22:03:59 +00:00
|
|
|
if (parseInt(hh) > 12)
|
|
|
|
hh = h2.substr(h2.length -2);
|
2021-09-13 19:26:53 +00:00
|
|
|
|
|
|
|
var x = (g.getWidth()/2);
|
|
|
|
var y = (g.getHeight()/3);
|
2021-12-19 21:09:00 +00:00
|
|
|
var weatherJson = getWeather();
|
|
|
|
var w_temp;
|
|
|
|
var w_icon;
|
|
|
|
var w_wind;
|
|
|
|
|
|
|
|
if (settings.weather && weatherJson && weatherJson.weather) {
|
|
|
|
var currentWeather = weatherJson.weather;
|
|
|
|
const temp = locale.temp(currentWeather.temp-273.15).match(/^(\D*\d*)(.*)$/);
|
|
|
|
w_temp = temp[1] + " " + temp[2];
|
|
|
|
w_icon = chooseIcon(currentWeather.txt);
|
|
|
|
const wind = locale.speed(currentWeather.wind).match(/^(\D*\d*)(.*)$/);
|
|
|
|
w_wind = wind[1] + " " + wind[2] + " " + (currentWeather.wrose||'').toUpperCase();
|
|
|
|
} else {
|
|
|
|
w_temp = "Err";
|
|
|
|
w_wind = "???";
|
|
|
|
w_icon = errIcon;
|
|
|
|
}
|
|
|
|
|
2021-09-13 19:26:53 +00:00
|
|
|
g.reset();
|
2022-02-08 23:12:18 +00:00
|
|
|
g.setColor(g.theme.bg);
|
|
|
|
g.fillRect(Bangle.appRect);
|
2021-12-19 22:25:18 +00:00
|
|
|
|
2021-09-13 19:26:53 +00:00
|
|
|
// draw a grid like graph paper
|
2021-09-14 21:01:20 +00:00
|
|
|
if (settings.grid && process.env.HWVERSION !=1) {
|
2021-09-13 23:50:52 +00:00
|
|
|
g.setColor("#0f0");
|
|
|
|
for (var gx=20; gx <= w; gx += 20)
|
2021-10-14 17:55:13 +00:00
|
|
|
g.drawLine(gx, 30, gx, h - 24);
|
|
|
|
for (var gy=30; gy <= h - 24; gy += 20)
|
2021-09-13 23:50:52 +00:00
|
|
|
g.drawLine(0, gy, w, gy);
|
|
|
|
}
|
|
|
|
|
2021-09-15 20:38:21 +00:00
|
|
|
g.setColor(g.theme.fg);
|
2021-09-13 19:26:53 +00:00
|
|
|
|
2021-12-19 21:09:00 +00:00
|
|
|
// draw weather line
|
|
|
|
if (settings.weather) {
|
|
|
|
g.drawImage(w_icon, (w/2) - 40, 24);
|
|
|
|
g.setFontLatoSmall();
|
|
|
|
g.setFontAlign(-1,0); // left aligned
|
|
|
|
if (drawCount % 2 == 0)
|
|
|
|
g.drawString(w_temp, (w/2) + 6, 24 + ((y - 24)/2));
|
|
|
|
else
|
|
|
|
g.drawString( (w_wind.split(' ').slice(0, 2).join(' ')), (w/2) + 6, 24 + ((y - 24)/2));
|
|
|
|
// display first 2 words of the wind string eg '4 mph'
|
|
|
|
}
|
|
|
|
|
2021-09-14 21:01:20 +00:00
|
|
|
if (settings.font == "Architect")
|
|
|
|
g.setFontArchitect();
|
|
|
|
else if (settings.font == "GochiHand")
|
|
|
|
g.setFontGochiHand();
|
|
|
|
else if (settings.font == "CabinSketch")
|
|
|
|
g.setFontCabinSketch();
|
2021-09-14 22:04:48 +00:00
|
|
|
else if (settings.font == "Orbitron")
|
|
|
|
g.setFontOrbitron();
|
2021-10-16 13:49:13 +00:00
|
|
|
else if (settings.font == "Monoton")
|
|
|
|
g.setFontMonoton();
|
|
|
|
else if (settings.font == "Elite")
|
|
|
|
g.setFontSpecialElite();
|
2021-09-14 21:01:20 +00:00
|
|
|
else
|
2021-11-22 22:50:27 +00:00
|
|
|
g.setFontLato();
|
2021-09-14 21:01:20 +00:00
|
|
|
|
2021-09-13 19:26:53 +00:00
|
|
|
g.setFontAlign(1,-1); // right aligned
|
|
|
|
g.drawString(hh, x - 6, y);
|
|
|
|
g.setFontAlign(-1,-1); // left aligned
|
2021-09-30 22:03:47 +00:00
|
|
|
g.drawString(mm, x + 6, y);
|
2021-09-13 19:26:53 +00:00
|
|
|
|
|
|
|
// for the colon
|
|
|
|
g.setFontAlign(0,-1); // centre aligned
|
2021-12-19 21:09:00 +00:00
|
|
|
g.drawString(":", x,y);
|
2021-11-24 20:18:29 +00:00
|
|
|
g.setFontLatoSmall();
|
|
|
|
g.setFontAlign(0, -1);
|
|
|
|
g.drawString((infoData[infoMode].calc()), w/2, h - 24 - 24);
|
2021-11-27 11:23:03 +00:00
|
|
|
|
2021-12-19 21:09:00 +00:00
|
|
|
// recalc sunrise / sunset every hour
|
|
|
|
if (drawCount % 60 == 0)
|
2021-11-27 11:23:03 +00:00
|
|
|
updateSunRiseSunSet(new Date(), location.lat, location.lon);
|
|
|
|
drawCount++;
|
2021-12-19 21:09:00 +00:00
|
|
|
queueDraw();
|
2021-09-13 19:26:53 +00:00
|
|
|
}
|
|
|
|
|
2022-02-08 23:12:18 +00:00
|
|
|
|
|
|
|
///////////////// IDLE TIMER /////////////////////////////////////
|
|
|
|
|
|
|
|
function log_debug(o) {
|
|
|
|
//print(o);
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawIdle() {
|
|
|
|
let mins = Math.round((getTime() - lastStep) / 60);
|
|
|
|
g.reset();
|
|
|
|
g.setColor(g.theme.bg);
|
|
|
|
g.fillRect(Bangle.appRect);
|
|
|
|
g.setColor(g.theme.fg);
|
|
|
|
setSmallFont();
|
|
|
|
g.setFontAlign(0, 0);
|
|
|
|
g.drawString('Last step was', w/2, (h/3));
|
|
|
|
g.drawString(mins + ' minutes ago', w/2, 20+(h/3));
|
|
|
|
dismissBtn.draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////// BUTTON CLASS ///////////////////////////////////////////
|
|
|
|
|
|
|
|
// simple on screen button class
|
|
|
|
function BUTTON(name,x,y,w,h,c,f,tx) {
|
|
|
|
this.name = name;
|
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
this.w = w;
|
|
|
|
this.h = h;
|
|
|
|
this.color = c;
|
|
|
|
this.callback = f;
|
|
|
|
this.text = tx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if pressed the callback
|
|
|
|
BUTTON.prototype.check = function(x,y) {
|
|
|
|
//console.log(this.name + ":check() x=" + x + " y=" + y +"\n");
|
|
|
|
|
|
|
|
if (x>= this.x && x<= (this.x + this.w) && y>= this.y && y<= (this.y + this.h)) {
|
|
|
|
log_debug(this.name + ":callback\n");
|
|
|
|
this.callback();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
BUTTON.prototype.draw = function() {
|
|
|
|
g.setColor(this.color);
|
|
|
|
g.fillRect(this.x, this.y, this.x + this.w, this.y + this.h);
|
|
|
|
g.setColor("#000"); // the icons and boxes are drawn black
|
|
|
|
setSmallFont();
|
|
|
|
g.setFontAlign(0, 0);
|
|
|
|
g.drawString(this.text, (this.x + this.w/2), (this.y + this.h/2));
|
|
|
|
g.drawRect(this.x, this.y, (this.x + this.w), (this.y + this.h));
|
|
|
|
};
|
|
|
|
|
|
|
|
function dismissPrompt() {
|
|
|
|
idle = false;
|
|
|
|
warned = false;
|
|
|
|
lastStep = getTime();
|
|
|
|
Bangle.buzz(100);
|
|
|
|
draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
var dismissBtn = new BUTTON("big",0, 3*h/4 ,w, h/4, "#0ff", dismissPrompt, "Dismiss");
|
|
|
|
|
|
|
|
Bangle.on('touch', function(button, xy) {
|
|
|
|
if (idle && dismissBtn.check(xy.x, xy.y)) return;
|
|
|
|
});
|
|
|
|
|
|
|
|
// if we get a step then we are not idle
|
|
|
|
Bangle.on('step', s => {
|
|
|
|
setLastStepTime();
|
|
|
|
lastStep = getTime();
|
|
|
|
// redraw if we had been idle
|
|
|
|
if (idle == true) {
|
|
|
|
dismissPrompt();
|
|
|
|
}
|
|
|
|
idle = false;
|
|
|
|
warned = 0;
|
|
|
|
});
|
|
|
|
|
|
|
|
function setLastStepTime() {
|
|
|
|
var date = new Date();
|
|
|
|
lastStepTime = require("locale").time(date,1);
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkIdle() {
|
2022-02-12 00:34:38 +00:00
|
|
|
if (!settings.idle_check) {
|
2022-02-08 23:12:18 +00:00
|
|
|
idle = false;
|
|
|
|
warned = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let hour = (new Date()).getHours();
|
|
|
|
let active = (hour >= 9 && hour < 21);
|
|
|
|
//let active = true;
|
|
|
|
let dur = getTime() - lastStep;
|
|
|
|
|
|
|
|
if (active && dur > IDLE_MINUTES * 60) {
|
|
|
|
drawIdle();
|
|
|
|
if (warned++ < 3) {
|
|
|
|
buzzer(warned);
|
|
|
|
log_debug("checkIdle: warned=" + warned);
|
|
|
|
Bangle.setLocked(false);
|
|
|
|
}
|
|
|
|
idle = true;
|
|
|
|
} else {
|
|
|
|
idle = false;
|
|
|
|
warned = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setLastStepTime();
|
|
|
|
|
|
|
|
// timeout for multi-buzzer
|
|
|
|
var buzzTimeout;
|
|
|
|
|
|
|
|
// n buzzes
|
|
|
|
function buzzer(n) {
|
|
|
|
log_debug("buzzer n=" + n);
|
|
|
|
|
|
|
|
if (n-- < 1) return;
|
|
|
|
Bangle.buzz(250);
|
|
|
|
|
|
|
|
if (buzzTimeout) clearTimeout(buzzTimeout);
|
|
|
|
buzzTimeout = setTimeout(function() {
|
|
|
|
buzzTimeout = undefined;
|
|
|
|
buzzer(n);
|
|
|
|
}, 500);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2021-12-19 21:09:00 +00:00
|
|
|
// timeout used to update every minute
|
|
|
|
var drawTimeout;
|
|
|
|
|
|
|
|
// schedule a draw for the next minute
|
|
|
|
function queueDraw() {
|
|
|
|
if (drawTimeout) clearTimeout(drawTimeout);
|
|
|
|
drawTimeout = setTimeout(function() {
|
|
|
|
drawTimeout = undefined;
|
2022-01-08 20:43:06 +00:00
|
|
|
prevInfo();
|
2022-02-08 23:12:18 +00:00
|
|
|
checkIdle();
|
2021-12-19 21:09:00 +00:00
|
|
|
draw();
|
|
|
|
}, 60000 - (Date.now() % 60000));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop updates when LCD is off, restart when on
|
|
|
|
Bangle.on('lcdPower',on=>{
|
|
|
|
if (on) {
|
|
|
|
draw(); // draw immediately, queue redraw
|
|
|
|
} else { // stop draw timer
|
|
|
|
if (drawTimeout) clearTimeout(drawTimeout);
|
|
|
|
drawTimeout = undefined;
|
|
|
|
}
|
2021-09-13 19:26:53 +00:00
|
|
|
});
|
|
|
|
|
2021-11-24 19:59:46 +00:00
|
|
|
Bangle.setUI("clockupdown", btn=> {
|
|
|
|
if (btn<0) prevInfo();
|
|
|
|
if (btn>0) nextInfo();
|
|
|
|
draw();
|
|
|
|
});
|
|
|
|
|
2021-11-22 21:17:50 +00:00
|
|
|
loadSettings();
|
|
|
|
loadFonts();
|
2021-11-26 20:25:28 +00:00
|
|
|
loadLocation();
|
|
|
|
|
2021-09-30 22:03:47 +00:00
|
|
|
g.clear();
|
|
|
|
Bangle.loadWidgets();
|
|
|
|
Bangle.drawWidgets();
|
2021-12-19 21:09:00 +00:00
|
|
|
draw();
|