2022-09-06 17:32:51 +00:00
|
|
|
Bangle.setUI("clock");
|
2022-03-05 10:37:35 +00:00
|
|
|
Bangle.loadWidgets();
|
2022-03-05 08:26:40 +00:00
|
|
|
|
2022-03-05 10:37:35 +00:00
|
|
|
var s = Object.assign({
|
|
|
|
CAL_ROWS: 4, //number of calendar rows.(weeks) Shouldn't exceed 5 when using widgets.
|
|
|
|
BUZZ_ON_BT: true, //2x slow buzz on disconnect, 2x fast buzz on connect. Will be extra widget eventually
|
|
|
|
MODE24: true, //24h mode vs 12h mode
|
2022-03-23 13:37:44 +00:00
|
|
|
FIRSTDAY: 6, //First day of the week: mo, tu, we, th, fr, sa, su
|
2022-03-05 10:37:35 +00:00
|
|
|
REDSUN: true, // Use red color for sunday?
|
|
|
|
REDSAT: true, // Use red color for saturday?
|
2022-03-23 13:37:44 +00:00
|
|
|
DRAGDOWN: "[AI:messg]",
|
|
|
|
DRAGRIGHT: "[AI:music]",
|
|
|
|
DRAGLEFT: "[ignore]",
|
|
|
|
DRAGUP: "[calend.]"
|
2022-03-05 10:37:35 +00:00
|
|
|
}, require('Storage').readJSON("clockcal.json", true) || {});
|
|
|
|
|
|
|
|
const h = g.getHeight();
|
|
|
|
const w = g.getWidth();
|
|
|
|
const CELL_W = w / 7;
|
2022-03-14 08:01:42 +00:00
|
|
|
const CELL2_W = w / 8;//full calendar
|
2022-03-05 10:37:35 +00:00
|
|
|
const CELL_H = 15;
|
|
|
|
const CAL_Y = h - s.CAL_ROWS * CELL_H;
|
|
|
|
const DEBUG = false;
|
2022-03-14 08:01:42 +00:00
|
|
|
var state = "watch";
|
|
|
|
var monthOffset = 0;
|
2022-03-05 10:37:35 +00:00
|
|
|
|
2022-03-14 08:01:42 +00:00
|
|
|
/*
|
|
|
|
* Calendar features
|
|
|
|
*/
|
|
|
|
function drawFullCalendar(monthOffset) {
|
|
|
|
addMonths = function (_d, _am) {
|
2022-03-23 13:37:44 +00:00
|
|
|
var ay = 0, m = _d.getMonth(), y = _d.getFullYear();
|
|
|
|
while ((m + _am) > 11) { ay++; _am -= 12; }
|
|
|
|
while ((m + _am) < 0) { ay--; _am += 12; }
|
|
|
|
n = new Date(_d.getTime());
|
|
|
|
n.setMonth(m + _am);
|
|
|
|
n.setFullYear(y + ay);
|
|
|
|
return n;
|
2022-03-14 08:01:42 +00:00
|
|
|
};
|
|
|
|
monthOffset = (typeof monthOffset == "undefined") ? 0 : monthOffset;
|
|
|
|
state = "calendar";
|
|
|
|
var start = Date().getTime();
|
|
|
|
const months = ['Jan.', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec.'];
|
|
|
|
const monthclr = ['#0f0', '#f0f', '#00f', '#ff0', '#0ff', '#fff'];
|
|
|
|
if (typeof dayInterval !== "undefined") clearTimeout(dayInterval);
|
|
|
|
if (typeof secondInterval !== "undefined") clearTimeout(secondInterval);
|
|
|
|
if (typeof minuteInterval !== "undefined") clearTimeout(minuteInterval);
|
|
|
|
d = addMonths(Date(), monthOffset);
|
|
|
|
tdy = Date().getDate() + "." + Date().getMonth();
|
2022-03-23 13:37:44 +00:00
|
|
|
newmonth = false;
|
2022-03-14 08:01:42 +00:00
|
|
|
c_y = 0;
|
|
|
|
g.reset();
|
|
|
|
g.setBgColor(0);
|
|
|
|
g.clear();
|
2022-03-23 13:37:44 +00:00
|
|
|
var prevmonth = addMonths(d, -1);
|
2022-03-14 08:01:42 +00:00
|
|
|
const today = prevmonth.getDate();
|
|
|
|
var rD = new Date(prevmonth.getTime());
|
|
|
|
rD.setDate(rD.getDate() - (today - 1));
|
2022-03-23 13:37:44 +00:00
|
|
|
const dow = (s.FIRSTDAY + rD.getDay()) % 7;
|
2022-03-14 08:01:42 +00:00
|
|
|
rD.setDate(rD.getDate() - dow);
|
|
|
|
var rDate = rD.getDate();
|
|
|
|
bottomrightY = c_y - 3;
|
2022-03-23 13:37:44 +00:00
|
|
|
clrsun = s.REDSUN ? '#f00' : '#fff';
|
|
|
|
clrsat = s.REDSUN ? '#f00' : '#fff';
|
|
|
|
var fg = [clrsun, '#fff', '#fff', '#fff', '#fff', '#fff', clrsat];
|
2022-03-14 08:01:42 +00:00
|
|
|
for (var y = 1; y <= 11; y++) {
|
|
|
|
bottomrightY += CELL_H;
|
|
|
|
bottomrightX = -2;
|
|
|
|
for (var x = 1; x <= 7; x++) {
|
|
|
|
bottomrightX += CELL2_W;
|
|
|
|
rMonth = rD.getMonth();
|
|
|
|
rDate = rD.getDate();
|
|
|
|
if (tdy == rDate + "." + rMonth) {
|
2022-03-23 13:37:44 +00:00
|
|
|
caldrawToday(rDate);
|
2022-03-14 08:01:42 +00:00
|
|
|
} else if (rDate == 1) {
|
2022-03-23 13:37:44 +00:00
|
|
|
caldrawFirst(rDate);
|
2022-03-14 08:01:42 +00:00
|
|
|
} else {
|
2022-03-23 13:37:44 +00:00
|
|
|
caldrawNormal(rDate, fg[rD.getDay()]);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
if (newmonth && x == 7) {
|
2022-03-23 13:37:44 +00:00
|
|
|
caldrawMonth(rDate, monthclr[rMonth % 6], months[rMonth], rD);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
rD.setDate(rDate + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete addMonths;
|
|
|
|
if (DEBUG) console.log("Calendar performance (ms):" + (Date().getTime() - start));
|
|
|
|
}
|
2022-03-23 13:37:44 +00:00
|
|
|
function caldrawMonth(rDate, c, m, rD) {
|
2022-03-14 08:01:42 +00:00
|
|
|
g.setColor(c);
|
|
|
|
g.setFont("Vector", 18);
|
|
|
|
g.setFontAlign(-1, 1, 1);
|
|
|
|
drawyear = ((rMonth % 11) == 0) ? String(rD.getFullYear()).substr(-2) : "";
|
|
|
|
g.drawString(m + drawyear, bottomrightX, bottomrightY - CELL_H, 1);
|
|
|
|
newmonth = false;
|
|
|
|
}
|
|
|
|
function caldrawToday(rDate) {
|
2022-03-23 13:37:44 +00:00
|
|
|
g.setFont("Vector", 16);
|
|
|
|
g.setFontAlign(1, 1);
|
|
|
|
g.setColor('#0f0');
|
|
|
|
g.fillRect(bottomrightX - CELL2_W + 1, bottomrightY - CELL_H - 1, bottomrightX, bottomrightY - 2);
|
|
|
|
g.setColor('#000');
|
|
|
|
g.drawString(rDate, bottomrightX, bottomrightY);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
function caldrawFirst(rDate) {
|
2022-03-23 13:37:44 +00:00
|
|
|
g.flip();
|
|
|
|
g.setFont("Vector", 16);
|
|
|
|
g.setFontAlign(1, 1);
|
|
|
|
bottomrightY += 3;
|
|
|
|
newmonth = true;
|
|
|
|
g.setColor('#0ff');
|
|
|
|
g.fillRect(bottomrightX - CELL2_W + 1, bottomrightY - CELL_H - 1, bottomrightX, bottomrightY - 2);
|
|
|
|
g.setColor('#000');
|
|
|
|
g.drawString(rDate, bottomrightX, bottomrightY);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
2022-03-23 13:37:44 +00:00
|
|
|
function caldrawNormal(rDate, c) {
|
|
|
|
g.setFont("Vector", 16);
|
|
|
|
g.setFontAlign(1, 1);
|
|
|
|
g.setColor(c);
|
|
|
|
g.drawString(rDate, bottomrightX, bottomrightY);//100
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
2022-03-05 10:37:35 +00:00
|
|
|
function drawMinutes() {
|
|
|
|
if (DEBUG) console.log("|-->minutes");
|
|
|
|
var d = new Date();
|
|
|
|
var hours = s.MODE24 ? d.getHours().toString().padStart(2, ' ') : ((d.getHours() + 24) % 12 || 12).toString().padStart(2, ' ');
|
|
|
|
var minutes = d.getMinutes().toString().padStart(2, '0');
|
2022-05-13 13:25:47 +00:00
|
|
|
var textColor = NRF.getSecurityStatus().connected ? '#99f' : '#fff';
|
2022-03-05 10:37:35 +00:00
|
|
|
var size = 50;
|
|
|
|
var clock_x = (w - 20) / 2;
|
|
|
|
if (dimSeconds) {
|
|
|
|
size = 65;
|
|
|
|
clock_x = 4 + (w / 2);
|
|
|
|
}
|
|
|
|
g.setBgColor(0);
|
|
|
|
g.setColor(textColor);
|
|
|
|
g.setFont("Vector", size);
|
|
|
|
g.setFontAlign(0, 1);
|
|
|
|
g.drawString(hours + ":" + minutes, clock_x, CAL_Y - 10, 1);
|
|
|
|
var nextminute = (61 - d.getSeconds());
|
|
|
|
if (typeof minuteInterval !== "undefined") clearTimeout(minuteInterval);
|
|
|
|
minuteInterval = setTimeout(drawMinutes, nextminute * 1000);
|
2022-03-05 08:26:40 +00:00
|
|
|
}
|
|
|
|
|
2022-03-05 10:37:35 +00:00
|
|
|
function drawSeconds() {
|
|
|
|
if (DEBUG) console.log("|--->seconds");
|
|
|
|
var d = new Date();
|
|
|
|
g.setColor();
|
|
|
|
g.fillRect(w - 31, CAL_Y - 36, w - 3, CAL_Y - 19);
|
|
|
|
g.setBgColor(0);
|
|
|
|
g.setColor('#fff');
|
|
|
|
g.setFont("Vector", 24);
|
|
|
|
g.setFontAlign(1, 1);
|
|
|
|
g.drawString(" " + d.getSeconds().toString().padStart(2, '0'), w, CAL_Y - 13);
|
|
|
|
if (typeof secondInterval !== "undefined") clearTimeout(secondInterval);
|
|
|
|
if (!dimSeconds) secondInterval = setTimeout(drawSeconds, 1000);
|
2022-03-05 08:26:40 +00:00
|
|
|
}
|
|
|
|
|
2022-03-14 08:01:42 +00:00
|
|
|
function drawWatch() {
|
2022-03-05 10:37:35 +00:00
|
|
|
if (DEBUG) console.log("CALENDAR");
|
2022-03-14 08:01:42 +00:00
|
|
|
monthOffset = 0;
|
|
|
|
state = "watch";
|
2022-03-05 10:37:35 +00:00
|
|
|
var d = new Date();
|
|
|
|
g.reset();
|
|
|
|
g.setBgColor(0);
|
|
|
|
g.clear();
|
|
|
|
drawMinutes();
|
|
|
|
if (!dimSeconds) drawSeconds();
|
2022-03-23 13:37:44 +00:00
|
|
|
const dow = (s.FIRSTDAY + d.getDay()) % 7; //MO=0, SU=6
|
2022-03-05 10:37:35 +00:00
|
|
|
const today = d.getDate();
|
|
|
|
var rD = new Date(d.getTime());
|
|
|
|
rD.setDate(rD.getDate() - dow);
|
|
|
|
var rDate = rD.getDate();
|
|
|
|
g.setFontAlign(1, 1);
|
|
|
|
for (var y = 1; y <= s.CAL_ROWS; y++) {
|
|
|
|
for (var x = 1; x <= 7; x++) {
|
|
|
|
bottomrightX = x * CELL_W - 2;
|
|
|
|
bottomrightY = y * CELL_H + CAL_Y;
|
|
|
|
g.setFont("Vector", 16);
|
|
|
|
var fg = ((s.REDSUN && rD.getDay() == 0) || (s.REDSAT && rD.getDay() == 6)) ? '#f00' : '#fff';
|
|
|
|
if (y == 1 && today == rDate) {
|
|
|
|
g.setColor('#0f0');
|
|
|
|
g.fillRect(bottomrightX - CELL_W + 1, bottomrightY - CELL_H - 1, bottomrightX, bottomrightY - 2);
|
|
|
|
g.setColor('#000');
|
|
|
|
g.drawString(rDate, bottomrightX, bottomrightY);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
g.setColor(fg);
|
|
|
|
g.drawString(rDate, bottomrightX, bottomrightY);
|
|
|
|
}
|
|
|
|
rD.setDate(rDate + 1);
|
|
|
|
rDate = rD.getDate();
|
|
|
|
}
|
2022-03-05 08:26:40 +00:00
|
|
|
}
|
2022-03-05 10:37:35 +00:00
|
|
|
Bangle.drawWidgets();
|
2022-03-05 08:26:40 +00:00
|
|
|
|
2022-03-05 10:37:35 +00:00
|
|
|
var nextday = (3600 * 24) - (d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds() + 1);
|
|
|
|
if (DEBUG) console.log("Next Day:" + (nextday / 3600));
|
|
|
|
if (typeof dayInterval !== "undefined") clearTimeout(dayInterval);
|
2022-03-14 08:01:42 +00:00
|
|
|
dayInterval = setTimeout(drawWatch, nextday * 1000);
|
2022-03-05 08:26:40 +00:00
|
|
|
}
|
|
|
|
|
2022-03-05 10:37:35 +00:00
|
|
|
function BTevent() {
|
|
|
|
drawMinutes();
|
|
|
|
if (s.BUZZ_ON_BT) {
|
|
|
|
var interval = (NRF.getSecurityStatus().connected) ? 100 : 500;
|
|
|
|
Bangle.buzz(interval);
|
|
|
|
setTimeout(function () { Bangle.buzz(interval); }, interval * 3);
|
|
|
|
}
|
2022-03-05 08:26:40 +00:00
|
|
|
}
|
2022-03-23 13:37:44 +00:00
|
|
|
function action(a) {
|
|
|
|
g.reset();
|
|
|
|
if (typeof secondInterval !== "undefined") clearTimeout(secondInterval);
|
|
|
|
if (DEBUG) console.log("action:" + a);
|
|
|
|
switch (a) {
|
|
|
|
case "[ignore]":
|
|
|
|
break;
|
|
|
|
case "[calend.]":
|
|
|
|
drawFullCalendar();
|
|
|
|
break;
|
|
|
|
case "[AI:music]":
|
|
|
|
l = require("Storage").list(RegExp("music.*app.js"));
|
|
|
|
if (l.length > 0) {
|
|
|
|
load(l[0]);
|
|
|
|
} else E.showAlert("Music app not found", "Not found").then(drawWatch);
|
|
|
|
break;
|
|
|
|
case "[AI:messg]":
|
|
|
|
l = require("Storage").list(RegExp("message.*app.js"));
|
|
|
|
if (l.length > 0) {
|
|
|
|
load(l[0]);
|
|
|
|
} else E.showAlert("Message app not found", "Not found").then(drawWatch);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
l = require("Storage").list(RegExp(a + ".app.js"));
|
|
|
|
if (l.length > 0) {
|
|
|
|
load(l[0]);
|
|
|
|
} else E.showAlert(a + ": App not found", "Not found").then(drawWatch);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-03-14 08:01:42 +00:00
|
|
|
function input(dir) {
|
2022-03-23 13:37:44 +00:00
|
|
|
Bangle.buzz(100, 1);
|
|
|
|
if (DEBUG) console.log("swipe:" + dir);
|
2022-03-14 08:01:42 +00:00
|
|
|
switch (dir) {
|
|
|
|
case "r":
|
|
|
|
if (state == "calendar") {
|
|
|
|
drawWatch();
|
|
|
|
} else {
|
2022-03-23 13:37:44 +00:00
|
|
|
action(s.DRAGRIGHT);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "l":
|
|
|
|
if (state == "calendar") {
|
|
|
|
drawWatch();
|
2022-03-23 13:37:44 +00:00
|
|
|
} else {
|
|
|
|
action(s.DRAGLEFT);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "d":
|
|
|
|
if (state == "calendar") {
|
|
|
|
monthOffset--;
|
|
|
|
drawFullCalendar(monthOffset);
|
|
|
|
} else {
|
2022-03-23 13:37:44 +00:00
|
|
|
action(s.DRAGDOWN);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "u":
|
2022-03-23 13:37:44 +00:00
|
|
|
if (state == "calendar") {
|
2022-03-14 08:01:42 +00:00
|
|
|
monthOffset++;
|
|
|
|
drawFullCalendar(monthOffset);
|
2022-03-23 13:37:44 +00:00
|
|
|
} else {
|
|
|
|
action(s.DRAGUP);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (state == "calendar") {
|
|
|
|
drawWatch();
|
|
|
|
}
|
|
|
|
break;
|
2022-03-23 13:37:44 +00:00
|
|
|
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let drag;
|
|
|
|
Bangle.on("drag", e => {
|
2022-03-23 13:37:44 +00:00
|
|
|
if (!drag) {
|
|
|
|
drag = { x: e.x, y: e.y };
|
|
|
|
} else if (!e.b) {
|
|
|
|
const dx = e.x - drag.x, dy = e.y - drag.y;
|
|
|
|
var dir = "t";
|
|
|
|
if (Math.abs(dx) > Math.abs(dy) + 20) {
|
|
|
|
dir = (dx > 0) ? "r" : "l";
|
|
|
|
} else if (Math.abs(dy) > Math.abs(dx) + 20) {
|
|
|
|
dir = (dy > 0) ? "d" : "u";
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
2022-03-23 13:37:44 +00:00
|
|
|
drag = null;
|
|
|
|
input(dir);
|
2022-03-14 08:01:42 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-03-05 10:37:35 +00:00
|
|
|
//register events
|
|
|
|
Bangle.on('lock', locked => {
|
|
|
|
if (typeof secondInterval !== "undefined") clearTimeout(secondInterval);
|
|
|
|
dimSeconds = locked; //dim seconds if lock=on
|
2022-03-14 08:01:42 +00:00
|
|
|
drawWatch();
|
2022-03-05 10:37:35 +00:00
|
|
|
});
|
|
|
|
NRF.on('connect', BTevent);
|
|
|
|
NRF.on('disconnect', BTevent);
|
2022-03-05 08:26:40 +00:00
|
|
|
|
2022-03-05 10:37:35 +00:00
|
|
|
dimSeconds = Bangle.isLocked();
|
2022-03-14 08:01:42 +00:00
|
|
|
drawWatch();
|
2022-09-06 17:32:51 +00:00
|
|
|
|