|
|
|
|
@ -1,3 +1,4 @@
|
|
|
|
|
{
|
|
|
|
|
const maxX = g.getWidth();
|
|
|
|
|
const maxY = g.getHeight();
|
|
|
|
|
const fontSize = g.getWidth() > 200 ? 2 : 1;
|
|
|
|
|
@ -17,71 +18,85 @@ const red = "#d41706";
|
|
|
|
|
const blue = "#0000ff";
|
|
|
|
|
const yellow = "#ffff00";
|
|
|
|
|
const cyan = "#00ffff";
|
|
|
|
|
let bgColor = color4;
|
|
|
|
|
let bgColorMonth = color1;
|
|
|
|
|
let bgColorDow = color2;
|
|
|
|
|
let bgColorWeekend = color3;
|
|
|
|
|
let fgOtherMonth = gray1;
|
|
|
|
|
let fgSameMonth = white;
|
|
|
|
|
let bgEvent = blue;
|
|
|
|
|
let bgOtherEvent = "#ff8800";
|
|
|
|
|
let bgColor;
|
|
|
|
|
let bgColorMonth;
|
|
|
|
|
let bgColorDow;
|
|
|
|
|
let bgColorWeekend;
|
|
|
|
|
let fgOtherMonth;
|
|
|
|
|
let fgSameMonth;
|
|
|
|
|
let bgEvent;
|
|
|
|
|
let bgOtherEvent;
|
|
|
|
|
const eventsPerDay=6; // how much different events per day we can display
|
|
|
|
|
const date = new Date();
|
|
|
|
|
|
|
|
|
|
const timeutils = require("time_utils");
|
|
|
|
|
let settings = require('Storage').readJSON("calendar.json", true) || {};
|
|
|
|
|
let startOnSun = ((require("Storage").readJSON("setting.json", true) || {}).firstDayOfWeek || 0) === 0;
|
|
|
|
|
// all alarms that run on a specific date
|
|
|
|
|
const events = (require("Storage").readJSON("sched.json",1) || []).filter(a => a.on && a.date).map(a => {
|
|
|
|
|
const date = new Date(a.date);
|
|
|
|
|
const time = timeutils.decodeTime(a.t);
|
|
|
|
|
date.setHours(time.h);
|
|
|
|
|
date.setMinutes(time.m);
|
|
|
|
|
date.setSeconds(time.s);
|
|
|
|
|
return {date: date, msg: a.msg, type: "e"};
|
|
|
|
|
});
|
|
|
|
|
// add holidays & other events
|
|
|
|
|
(require("Storage").readJSON("calendar.days.json",1) || []).forEach(d => {
|
|
|
|
|
const date = new Date(d.date);
|
|
|
|
|
const o = {date: date, msg: d.name, type: d.type};
|
|
|
|
|
if (d.repeat) {
|
|
|
|
|
o.repeat = d.repeat;
|
|
|
|
|
}
|
|
|
|
|
events.push(o);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (settings.ndColors === undefined) {
|
|
|
|
|
settings.ndColors = !g.theme.dark;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (settings.ndColors === true) {
|
|
|
|
|
bgColor = white;
|
|
|
|
|
bgColorMonth = blue;
|
|
|
|
|
bgColorDow = black;
|
|
|
|
|
bgColorWeekend = yellow;
|
|
|
|
|
fgOtherMonth = blue;
|
|
|
|
|
fgSameMonth = black;
|
|
|
|
|
bgEvent = color2;
|
|
|
|
|
bgOtherEvent = cyan;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getDowLbls(locale) {
|
|
|
|
|
let days = startOnSun ? [0, 1, 2, 3, 4, 5, 6] : [1, 2, 3, 4, 5, 6, 0];
|
|
|
|
|
let events;
|
|
|
|
|
const dowLbls = function() {
|
|
|
|
|
const locale = require('locale').name;
|
|
|
|
|
const days = startOnSun ? [0, 1, 2, 3, 4, 5, 6] : [1, 2, 3, 4, 5, 6, 0];
|
|
|
|
|
const d = new Date();
|
|
|
|
|
return days.map(i => {
|
|
|
|
|
d.setDate(d.getDate() + (i + 7 - d.getDay()) % 7);
|
|
|
|
|
return require("locale").dow(d, 1);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}();
|
|
|
|
|
|
|
|
|
|
function sameDay(d1, d2) {
|
|
|
|
|
const loadEvents = () => {
|
|
|
|
|
// all alarms that run on a specific date
|
|
|
|
|
events = (require("Storage").readJSON("sched.json",1) || []).filter(a => a.on && a.date).map(a => {
|
|
|
|
|
const date = new Date(a.date);
|
|
|
|
|
const time = timeutils.decodeTime(a.t);
|
|
|
|
|
date.setHours(time.h);
|
|
|
|
|
date.setMinutes(time.m);
|
|
|
|
|
date.setSeconds(time.s);
|
|
|
|
|
return {date: date, msg: a.msg, type: "e"};
|
|
|
|
|
});
|
|
|
|
|
// add holidays & other events
|
|
|
|
|
(require("Storage").readJSON("calendar.days.json",1) || []).forEach(d => {
|
|
|
|
|
const date = new Date(d.date);
|
|
|
|
|
const o = {date: date, msg: d.name, type: d.type};
|
|
|
|
|
if (d.repeat) {
|
|
|
|
|
o.repeat = d.repeat;
|
|
|
|
|
}
|
|
|
|
|
events.push(o);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const loadSettings = () => {
|
|
|
|
|
let settings = require('Storage').readJSON("calendar.json", true) || {};
|
|
|
|
|
if (settings.ndColors === undefined) {
|
|
|
|
|
settings.ndColors = !g.theme.dark;
|
|
|
|
|
}
|
|
|
|
|
if (settings.ndColors === true) {
|
|
|
|
|
bgColor = white;
|
|
|
|
|
bgColorMonth = blue;
|
|
|
|
|
bgColorDow = black;
|
|
|
|
|
bgColorWeekend = yellow;
|
|
|
|
|
fgOtherMonth = blue;
|
|
|
|
|
fgSameMonth = black;
|
|
|
|
|
bgEvent = color2;
|
|
|
|
|
bgOtherEvent = cyan;
|
|
|
|
|
} else {
|
|
|
|
|
bgColor = color4;
|
|
|
|
|
bgColorMonth = color1;
|
|
|
|
|
bgColorDow = color2;
|
|
|
|
|
bgColorWeekend = color3;
|
|
|
|
|
fgOtherMonth = gray1;
|
|
|
|
|
fgSameMonth = white;
|
|
|
|
|
bgEvent = blue;
|
|
|
|
|
bgOtherEvent = "#ff8800";
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const sameDay = function(d1, d2) {
|
|
|
|
|
"jit";
|
|
|
|
|
return d1.getFullYear() === d2.getFullYear() &&
|
|
|
|
|
d1.getMonth() === d2.getMonth() &&
|
|
|
|
|
d1.getDate() === d2.getDate();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function drawEvent(ev, curDay, x1, y1, x2, y2) {
|
|
|
|
|
const drawEvent = function(ev, curDay, x1, y1, x2, y2) {
|
|
|
|
|
"ram";
|
|
|
|
|
switch(ev.type) {
|
|
|
|
|
case "e": // alarm/event
|
|
|
|
|
@ -99,9 +114,33 @@ function drawEvent(ev, curDay, x1, y1, x2, y2) {
|
|
|
|
|
g.setColor(bgOtherEvent).fillRect(x1+1, y1+1, x2-1, y2-1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function drawCalendar(date) {
|
|
|
|
|
const calcDays = (month, monthMaxDayMap, dowNorm) => {
|
|
|
|
|
"jit";
|
|
|
|
|
const maxDay = colN * (rowN - 1) + 1;
|
|
|
|
|
const days = [];
|
|
|
|
|
let nextMonthDay = 1;
|
|
|
|
|
let thisMonthDay = 51;
|
|
|
|
|
const month2 = month;
|
|
|
|
|
let prevMonthDay = monthMaxDayMap[month > 0 ? month - 1 : 11] - dowNorm + 1;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < maxDay; i++) {
|
|
|
|
|
if (i < dowNorm) {
|
|
|
|
|
days.push(prevMonthDay);
|
|
|
|
|
prevMonthDay++;
|
|
|
|
|
} else if (thisMonthDay <= monthMaxDayMap[month] + 50) {
|
|
|
|
|
days.push(thisMonthDay);
|
|
|
|
|
thisMonthDay++;
|
|
|
|
|
} else {
|
|
|
|
|
days.push(nextMonthDay);
|
|
|
|
|
nextMonthDay++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return days;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const drawCalendar = function(date) {
|
|
|
|
|
g.setBgColor(bgColor);
|
|
|
|
|
g.clearRect(0, 0, maxX, maxY);
|
|
|
|
|
g.setBgColor(bgColorMonth);
|
|
|
|
|
@ -139,7 +178,6 @@ function drawCalendar(date) {
|
|
|
|
|
true
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let dowLbls = getDowLbls(require('locale').name);
|
|
|
|
|
dowLbls.forEach((lbl, i) => {
|
|
|
|
|
g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
|
|
|
|
|
});
|
|
|
|
|
@ -163,23 +201,7 @@ function drawCalendar(date) {
|
|
|
|
|
11: 31
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let days = [];
|
|
|
|
|
let nextMonthDay = 1;
|
|
|
|
|
let thisMonthDay = 51;
|
|
|
|
|
let prevMonthDay = monthMaxDayMap[month > 0 ? month - 1 : 11] - dowNorm + 1;
|
|
|
|
|
for (let i = 0; i < colN * (rowN - 1) + 1; i++) {
|
|
|
|
|
if (i < dowNorm) {
|
|
|
|
|
days.push(prevMonthDay);
|
|
|
|
|
prevMonthDay++;
|
|
|
|
|
} else if (thisMonthDay <= monthMaxDayMap[month] + 50) {
|
|
|
|
|
days.push(thisMonthDay);
|
|
|
|
|
thisMonthDay++;
|
|
|
|
|
} else {
|
|
|
|
|
days.push(nextMonthDay);
|
|
|
|
|
nextMonthDay++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const days = calcDays(month, monthMaxDayMap, dowNorm);
|
|
|
|
|
const weekBeforeMonth = new Date(date.getTime());
|
|
|
|
|
weekBeforeMonth.setDate(weekBeforeMonth.getDate() - 7);
|
|
|
|
|
const week2AfterMonth = new Date(date.getFullYear(), date.getMonth()+1, 0);
|
|
|
|
|
@ -189,8 +211,15 @@ function drawCalendar(date) {
|
|
|
|
|
ev.date.setFullYear(ev.date.getMonth() < 6 ? week2AfterMonth.getFullYear() : weekBeforeMonth.getFullYear());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const eventsThisMonth = events.filter(ev => ev.date > weekBeforeMonth && ev.date < week2AfterMonth);
|
|
|
|
|
eventsThisMonth.sort((a,b) => a.date - b.date);
|
|
|
|
|
|
|
|
|
|
const eventsThisMonthPerDay = events.filter(ev => ev.date > weekBeforeMonth && ev.date < week2AfterMonth).reduce((acc, ev) => {
|
|
|
|
|
const day = ev.date.getDate();
|
|
|
|
|
if (!acc[day]) {
|
|
|
|
|
acc[day] = [];
|
|
|
|
|
}
|
|
|
|
|
acc[day].push(ev);
|
|
|
|
|
return acc;
|
|
|
|
|
}, []);
|
|
|
|
|
let i = 0;
|
|
|
|
|
g.setFont("8x12", fontSize);
|
|
|
|
|
for (y = 0; y < rowN - 1; y++) {
|
|
|
|
|
@ -205,13 +234,13 @@ function drawCalendar(date) {
|
|
|
|
|
const x2 = x * colW + colW;
|
|
|
|
|
const y2 = y * rowH + headerH + rowH + rowH;
|
|
|
|
|
|
|
|
|
|
if (eventsThisMonth.length > 0) {
|
|
|
|
|
const eventsThisDay = eventsThisMonthPerDay[curDay.getDate()];
|
|
|
|
|
if (eventsThisDay && eventsThisDay.length > 0) {
|
|
|
|
|
// Display events for this day
|
|
|
|
|
eventsThisMonth.forEach((ev, idx) => {
|
|
|
|
|
eventsThisDay.forEach((ev, idx) => {
|
|
|
|
|
if (sameDay(ev.date, curDay)) {
|
|
|
|
|
drawEvent(ev, curDay, x1, y1, x2, y2);
|
|
|
|
|
|
|
|
|
|
eventsThisMonth.splice(idx, 1); // this event is no longer needed
|
|
|
|
|
eventsThisDay.splice(idx, 1); // this event is no longer needed
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
@ -235,9 +264,44 @@ function drawCalendar(date) {
|
|
|
|
|
);
|
|
|
|
|
} // end for (x = 0; x < colN; x++)
|
|
|
|
|
} // end for (y = 0; y < rowN - 1; y++)
|
|
|
|
|
} // end function drawCalendar
|
|
|
|
|
}; // end function drawCalendar
|
|
|
|
|
|
|
|
|
|
const showMenu = function() {
|
|
|
|
|
const menu = {
|
|
|
|
|
"" : {
|
|
|
|
|
title : "Calendar",
|
|
|
|
|
remove: () => {
|
|
|
|
|
require("widget_utils").show();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"< Back": () => {
|
|
|
|
|
require("widget_utils").hide();
|
|
|
|
|
E.showMenu();
|
|
|
|
|
setUI();
|
|
|
|
|
},
|
|
|
|
|
/*LANG*/"Exit": () => load(),
|
|
|
|
|
/*LANG*/"Settings": () => {
|
|
|
|
|
const appSettings = eval(require('Storage').read('calendar.settings.js'));
|
|
|
|
|
appSettings(() => {
|
|
|
|
|
loadSettings();
|
|
|
|
|
loadEvents();
|
|
|
|
|
showMenu();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
if (require("Storage").read("alarm.app.js")) {
|
|
|
|
|
menu[/*LANG*/"Launch Alarms"] = () => {
|
|
|
|
|
load("alarm.app.js");
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
require("widget_utils").show();
|
|
|
|
|
E.showMenu(menu);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const setUI = function() {
|
|
|
|
|
require("widget_utils").hide(); // No space for widgets!
|
|
|
|
|
drawCalendar(date);
|
|
|
|
|
|
|
|
|
|
function setUI() {
|
|
|
|
|
Bangle.setUI({
|
|
|
|
|
mode : "custom",
|
|
|
|
|
swipe: (dirLR, dirUD) => {
|
|
|
|
|
@ -261,7 +325,14 @@ function setUI() {
|
|
|
|
|
drawCalendar(date);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
btn: (n) => n === (process.env.HWVERSION === 2 ? 1 : 3) && load(),
|
|
|
|
|
btn: (n) => {
|
|
|
|
|
if (process.env.HWVERSION === 2 || n === 2) {
|
|
|
|
|
showMenu();
|
|
|
|
|
} else if (n === 3) {
|
|
|
|
|
// directly exit only on Bangle.js 1
|
|
|
|
|
load();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
touch: (n,e) => {
|
|
|
|
|
events.sort((a,b) => a.date - b.date);
|
|
|
|
|
const menu = events.filter(ev => ev.date.getFullYear() === date.getFullYear() && ev.date.getMonth() === date.getMonth()).map(e => {
|
|
|
|
|
@ -274,16 +345,19 @@ function setUI() {
|
|
|
|
|
}
|
|
|
|
|
menu[""] = { title: require("locale").month(date) + " " + date.getFullYear() };
|
|
|
|
|
menu["< Back"] = () => {
|
|
|
|
|
require("widget_utils").hide();
|
|
|
|
|
E.showMenu();
|
|
|
|
|
drawCalendar(date);
|
|
|
|
|
setUI();
|
|
|
|
|
};
|
|
|
|
|
require("widget_utils").show();
|
|
|
|
|
E.showMenu(menu);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
loadSettings();
|
|
|
|
|
loadEvents();
|
|
|
|
|
Bangle.loadWidgets();
|
|
|
|
|
require("Font8x12").add(Graphics);
|
|
|
|
|
drawCalendar(date);
|
|
|
|
|
setUI();
|
|
|
|
|
// No space for widgets!
|
|
|
|
|
}
|
|
|
|
|
|