Calendar: Edit holidays on device in settings
app: Only refactoring, no changed functionalitymaster
parent
4777d98c10
commit
1a932b0618
|
|
@ -14,3 +14,4 @@
|
||||||
0.13: Switch to swipe left/right for month and up/down for year selection
|
0.13: Switch to swipe left/right for month and up/down for year selection
|
||||||
Display events for current month on touch
|
Display events for current month on touch
|
||||||
0.14: Add support for holidays
|
0.14: Add support for holidays
|
||||||
|
0.15: Edit holidays on device in settings
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,31 @@ function getDowLbls(locale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function sameDay(d1, d2) {
|
function sameDay(d1, d2) {
|
||||||
|
"compiled";
|
||||||
return d1.getFullYear() === d2.getFullYear() &&
|
return d1.getFullYear() === d2.getFullYear() &&
|
||||||
d1.getMonth() === d2.getMonth() &&
|
d1.getMonth() === d2.getMonth() &&
|
||||||
d1.getDate() === d2.getDate();
|
d1.getDate() === d2.getDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function drawEvent(ev, curDay, x1, y1, x2, y2) {
|
||||||
|
switch(ev.type) {
|
||||||
|
case "e": // alarm/event
|
||||||
|
const hour = 0|ev.date.getHours() + 0|ev.date.getMinutes()/60.0;
|
||||||
|
const slice = hour/24*(eventsPerDay-1); // slice 0 for 0:00 up to eventsPerDay for 23:59
|
||||||
|
const height = (y2-2) - (y1+2); // height of a cell
|
||||||
|
const sliceHeight = height/eventsPerDay;
|
||||||
|
const ystart = (y1+2) + slice*sliceHeight;
|
||||||
|
g.setColor(bgEvent).fillRect(x1+1, ystart, x2-2, ystart+sliceHeight);
|
||||||
|
break;
|
||||||
|
case "h": // holiday
|
||||||
|
g.setColor(bgColorWeekend).fillRect(x1+1, y1+1, x2-1, y2-1);
|
||||||
|
break;
|
||||||
|
case "o": // other
|
||||||
|
g.setColor(bgOtherEvent).fillRect(x1+1, y1+1, x2-1, y2-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function drawCalendar(date) {
|
function drawCalendar(date) {
|
||||||
g.setBgColor(bgColor);
|
g.setBgColor(bgColor);
|
||||||
g.clearRect(0, 0, maxX, maxY);
|
g.clearRect(0, 0, maxX, maxY);
|
||||||
|
|
@ -118,7 +138,6 @@ function drawCalendar(date) {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
g.setFont("6x8", fontSize);
|
|
||||||
let dowLbls = getDowLbls(require('locale').name);
|
let dowLbls = getDowLbls(require('locale').name);
|
||||||
dowLbls.forEach((lbl, i) => {
|
dowLbls.forEach((lbl, i) => {
|
||||||
g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
|
g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
|
||||||
|
|
@ -172,6 +191,7 @@ function drawCalendar(date) {
|
||||||
const eventsThisMonth = events.filter(ev => ev.date > weekBeforeMonth && ev.date < week2AfterMonth);
|
const eventsThisMonth = events.filter(ev => ev.date > weekBeforeMonth && ev.date < week2AfterMonth);
|
||||||
eventsThisMonth.sort((a,b) => a.date - b.date);
|
eventsThisMonth.sort((a,b) => a.date - b.date);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
g.setFont("8x12", fontSize);
|
||||||
for (y = 0; y < rowN - 1; y++) {
|
for (y = 0; y < rowN - 1; y++) {
|
||||||
for (x = 0; x < colN; x++) {
|
for (x = 0; x < colN; x++) {
|
||||||
i++;
|
i++;
|
||||||
|
|
@ -188,22 +208,7 @@ function drawCalendar(date) {
|
||||||
// Display events for this day
|
// Display events for this day
|
||||||
eventsThisMonth.forEach((ev, idx) => {
|
eventsThisMonth.forEach((ev, idx) => {
|
||||||
if (sameDay(ev.date, curDay)) {
|
if (sameDay(ev.date, curDay)) {
|
||||||
switch(ev.type) {
|
drawEvent(ev, curDay, x1, y1, x2, y2);
|
||||||
case "e": // alarm/event
|
|
||||||
const hour = ev.date.getHours() + ev.date.getMinutes()/60.0;
|
|
||||||
const slice = hour/24*(eventsPerDay-1); // slice 0 for 0:00 up to eventsPerDay for 23:59
|
|
||||||
const height = (y2-2) - (y1+2); // height of a cell
|
|
||||||
const sliceHeight = height/eventsPerDay;
|
|
||||||
const ystart = (y1+2) + slice*sliceHeight;
|
|
||||||
g.setColor(bgEvent).fillRect(x1+1, ystart, x2-2, ystart+sliceHeight);
|
|
||||||
break;
|
|
||||||
case "h": // holiday
|
|
||||||
g.setColor(bgColorWeekend).fillRect(x1+1, y1+1, x2-1, y2-1);
|
|
||||||
break;
|
|
||||||
case "o": // other
|
|
||||||
g.setColor(bgOtherEvent).fillRect(x1+1, y1+1, x2-1, y2-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
eventsThisMonth.splice(idx, 1); // this event is no longer needed
|
eventsThisMonth.splice(idx, 1); // this event is no longer needed
|
||||||
}
|
}
|
||||||
|
|
@ -221,17 +226,15 @@ function drawCalendar(date) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
require("Font8x12").add(Graphics);
|
|
||||||
g.setFont("8x12", fontSize);
|
|
||||||
g.setColor(day < 50 ? fgOtherMonth : fgSameMonth);
|
g.setColor(day < 50 ? fgOtherMonth : fgSameMonth);
|
||||||
g.drawString(
|
g.drawString(
|
||||||
(day > 50 ? day - 50 : day).toString(),
|
(day > 50 ? day - 50 : day).toString(),
|
||||||
x * colW + colW / 2,
|
x * colW + colW / 2,
|
||||||
headerH + rowH + y * rowH + rowH / 2
|
headerH + rowH + y * rowH + rowH / 2
|
||||||
);
|
);
|
||||||
}
|
} // end for (x = 0; x < colN; x++)
|
||||||
}
|
} // end for (y = 0; y < rowN - 1; y++)
|
||||||
}
|
} // end function drawCalendar
|
||||||
|
|
||||||
function setUI() {
|
function setUI() {
|
||||||
Bangle.setUI({
|
Bangle.setUI({
|
||||||
|
|
@ -279,6 +282,7 @@ function setUI() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require("Font8x12").add(Graphics);
|
||||||
drawCalendar(date);
|
drawCalendar(date);
|
||||||
setUI();
|
setUI();
|
||||||
// No space for widgets!
|
// No space for widgets!
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "calendar",
|
"id": "calendar",
|
||||||
"name": "Calendar",
|
"name": "Calendar",
|
||||||
"version": "0.14",
|
"version": "0.15",
|
||||||
"description": "Simple calendar",
|
"description": "Simple calendar",
|
||||||
"icon": "calendar.png",
|
"icon": "calendar.png",
|
||||||
"screenshots": [{"url":"screenshot_calendar.png"}],
|
"screenshots": [{"url":"screenshot_calendar.png"}],
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
(function (back) {
|
(function (back) {
|
||||||
var FILE = "calendar.json";
|
var FILE = "calendar.json";
|
||||||
|
const HOLIDAY_FILE = "calendar.days.json";
|
||||||
var settings = require('Storage').readJSON(FILE, true) || {};
|
var settings = require('Storage').readJSON(FILE, true) || {};
|
||||||
if (settings.ndColors === undefined)
|
if (settings.ndColors === undefined)
|
||||||
if (process.env.HWVERSION == 2) {
|
if (process.env.HWVERSION == 2) {
|
||||||
|
|
@ -7,11 +8,127 @@
|
||||||
} else {
|
} else {
|
||||||
settings.ndColors = false;
|
settings.ndColors = false;
|
||||||
}
|
}
|
||||||
|
const holidays = require("Storage").readJSON(HOLIDAY_FILE,1).sort((a,b) => new Date(a.date) - new Date(b.date)) || [];
|
||||||
|
|
||||||
function writeSettings() {
|
function writeSettings() {
|
||||||
require('Storage').writeJSON(FILE, settings);
|
require('Storage').writeJSON(FILE, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function writeHolidays() {
|
||||||
|
holidays.sort((a,b) => new Date(a.date) - new Date(b.date));
|
||||||
|
require('Storage').writeJSON(HOLIDAY_FILE, holidays);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDate(d) {
|
||||||
|
return d.getFullYear() + "-" + (d.getMonth() + 1).toString().padStart(2, '0') + "-" + d.getDate().toString().padStart(2, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
const editdate = (i) => {
|
||||||
|
const holiday = holidays[i];
|
||||||
|
const date = new Date(holiday.date);
|
||||||
|
const dateStr = require("locale").date(date, 1);
|
||||||
|
const menu = {
|
||||||
|
"": { "title" : holiday.name},
|
||||||
|
"< Back": () => {
|
||||||
|
writeHolidays();
|
||||||
|
editdates();
|
||||||
|
},
|
||||||
|
/*LANG*/"Day": {
|
||||||
|
value: date ? date.getDate() : null,
|
||||||
|
min: 1,
|
||||||
|
max: 31,
|
||||||
|
wrap: true,
|
||||||
|
onchange: v => {
|
||||||
|
date.setDate(v);
|
||||||
|
holiday.date = formatDate(date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*LANG*/"Month": {
|
||||||
|
value: date ? date.getMonth() + 1 : null,
|
||||||
|
format: v => require("date_utils").month(v),
|
||||||
|
onchange: v => {
|
||||||
|
date.setMonth((v+11)%12);
|
||||||
|
holiday.date = formatDate(date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*LANG*/"Year": {
|
||||||
|
value: date ? date.getFullYear() : null,
|
||||||
|
min: 1900,
|
||||||
|
max: 2100,
|
||||||
|
onchange: v => {
|
||||||
|
date.setFullYear(v);
|
||||||
|
holiday.date = formatDate(date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*LANG*/"Name": () => {
|
||||||
|
require("textinput").input({text:holiday.name}).then(result => {
|
||||||
|
holiday.name = result;
|
||||||
|
editdate(i);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/*LANG*/"Type": {
|
||||||
|
value: function() {
|
||||||
|
switch(holiday.type) {
|
||||||
|
case 'h': return 0;
|
||||||
|
case 'o': return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}(),
|
||||||
|
min: 0, max: 1,
|
||||||
|
format: v => [/*LANG*/"Holiday", /*LANG*/"Other"][v],
|
||||||
|
onchange: v => {
|
||||||
|
holiday.type = function() {
|
||||||
|
switch(v) {
|
||||||
|
case 0: return 'h';
|
||||||
|
case 1: return 'o';
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*LANG*/"Repeat": {
|
||||||
|
value: !!holiday.repeat,
|
||||||
|
format: v => v ? /*LANG*/"Yearly" : /*LANG*/"Never",
|
||||||
|
onchange: v => {
|
||||||
|
holiday.repeat = v ? 'y' : undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*LANG*/"Delete": () => E.showPrompt(/*LANG*/"Delete" + " " + menu[""].title + "?").then(function(v) {
|
||||||
|
if (v) {
|
||||||
|
holidays.splice(i, 1);
|
||||||
|
writeHolidays();
|
||||||
|
editdates();
|
||||||
|
} else {
|
||||||
|
editday(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
require("textinput");
|
||||||
|
} catch(e) {
|
||||||
|
// textinput not installed
|
||||||
|
delete menu[/*LANG*/"Name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
E.showMenu(menu);
|
||||||
|
};
|
||||||
|
|
||||||
|
const editdates = () => {
|
||||||
|
const menu = holidays.map((holiday,i) => {
|
||||||
|
const date = new Date(holiday.date);
|
||||||
|
const dateStr = require("locale").date(date, 1);
|
||||||
|
return {
|
||||||
|
title: dateStr + ' ' + holiday.name,
|
||||||
|
onchange: v => setTimeout(() => editdate(i), 10),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
menu[''] = { 'title': 'Holidays' };
|
||||||
|
menu['< Back'] = ()=>settingsmenu();
|
||||||
|
E.showMenu(menu);
|
||||||
|
};
|
||||||
|
|
||||||
|
const settingsmenu = () => {
|
||||||
E.showMenu({
|
E.showMenu({
|
||||||
"": { "title": "Calendar" },
|
"": { "title": "Calendar" },
|
||||||
"< Back": () => back(),
|
"< Back": () => back(),
|
||||||
|
|
@ -22,6 +139,16 @@
|
||||||
writeSettings();
|
writeSettings();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/*LANG*/"Edit Holidays": () => editdates(),
|
||||||
|
/*LANG*/"Add Holiday": () => {
|
||||||
|
holidays.push({
|
||||||
|
"date":formatDate(new Date()),
|
||||||
|
"name":/*LANG*/"New",
|
||||||
|
"type":'h',
|
||||||
});
|
});
|
||||||
|
editdate(holidays.length-1);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
settingsmenu();
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue