Calendar: Edit holidays on device in settings

app: Only refactoring, no changed functionality
master
Erik Andresen 2023-07-24 18:24:14 +02:00
parent 4777d98c10
commit 1a932b0618
4 changed files with 167 additions and 35 deletions

View File

@ -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

View File

@ -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!

View File

@ -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"}],

View File

@ -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,21 +8,147 @@
} 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);
} }
E.showMenu({ function writeHolidays() {
"": { "title": "Calendar" }, holidays.sort((a,b) => new Date(a.date) - new Date(b.date));
"< Back": () => back(), require('Storage').writeJSON(HOLIDAY_FILE, holidays);
'B2 Colors': { }
value: settings.ndColors,
onchange: v => {
settings.ndColors = v;
writeSettings();
}
},
});
})
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({
"": { "title": "Calendar" },
"< Back": () => back(),
'B2 Colors': {
value: settings.ndColors,
onchange: v => {
settings.ndColors = v;
writeSettings();
}
},
/*LANG*/"Edit Holidays": () => editdates(),
/*LANG*/"Add Holiday": () => {
holidays.push({
"date":formatDate(new Date()),
"name":/*LANG*/"New",
"type":'h',
});
editdate(holidays.length-1);
},
});
};
settingsmenu();
})