calendar: Add type other+repeat

master
Erik Andresen 2023-05-03 22:09:14 +02:00
parent 5da64a5f83
commit 044fc173c5
4 changed files with 83 additions and 30 deletions

View File

@ -10,7 +10,7 @@ Basic calendar
- Swipe down (Bangle.js 2 only) to go to the next year
- Touch to display events for current month
- Press the button (button 3 on Bangle.js 1) to exit
- Holidays have same color as weekends and can be edited with the 'Download'-interface
- Holidays have same color as weekends and can be edited with the 'Download'-interface, e.g. by uploading an iCalendar file.
## Settings

View File

@ -38,12 +38,15 @@ const events = (require("Storage").readJSON("sched.json",1) || []).filter(a => a
date.setSeconds(time.s);
return {date: date, msg: a.msg, type: "e"};
});
// add holidays
(require("Storage").readJSON("calendar.holiday.json",1) || []).forEach(h => {
const date = new Date(h.date);
events.push({date: date, msg: h.name, type: "h"});
// 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);
});
events.sort((a,b) => a.date - b.date);
if (settings.ndColors === undefined) {
settings.ndColors = !g.theme.dark;
@ -158,8 +161,12 @@ function drawCalendar(date) {
weekBeforeMonth.setDate(weekBeforeMonth.getDate() - 7);
const week2AfterMonth = new Date(date.getFullYear(), date.getMonth()+1, 0);
week2AfterMonth.setDate(week2AfterMonth.getDate() + 14);
events.forEach(ev => {
if (ev.repeat === "y") {
ev.date.setFullYear(date.getFullYear());
}
});
const eventsThisMonth = events.filter(ev => ev.date > weekBeforeMonth && ev.date < week2AfterMonth);
let i = 0;
for (y = 0; y < rowN - 1; y++) {
for (x = 0; x < colN; x++) {
@ -177,15 +184,21 @@ function drawCalendar(date) {
// Display events for this day
eventsThisMonth.forEach((ev, idx) => {
if (sameDay(ev.date, curDay)) {
if (ev.type === "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);
} else if (ev.type === "h") { // holiday
g.setColor(bgColorWeekend).fillRect(x1+1, y1+1, x2-1, y2-1);
switch(ev.type) {
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("#88ff00").fillRect(x1+1, y1+1, x2-1, y2-1);
break;
}
eventsThisMonth.splice(idx, 1); // this event is no longer needed
@ -242,6 +255,7 @@ function setUI() {
},
btn: (n) => n === (process.env.HWVERSION === 2 ? 1 : 3) && 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 => {
const dateStr = require("locale").date(e.date, 1);
const timeStr = require("locale").time(e.date, 1);

View File

@ -53,6 +53,7 @@ function eventToHoliday(event) {
const holiday = {
date: formatDate(date),
name: event.summary,
type: 'h',
};
return holiday;
}
@ -63,7 +64,7 @@ function formatDate(d) {
function upload() {
Util.showModal("Saving...");
Util.writeStorage("calendar.holiday.json", JSON.stringify(holidays), () => {
Util.writeStorage("calendar.days.json", JSON.stringify(holidays), () => {
location.reload(); // reload so we see current data
});
}
@ -82,7 +83,7 @@ function renderHoliday(holiday) {
inputTime.value = formatDate(localDate)
inputTime.onchange = (e => {
const date = new Date(inputTime.value);
holiday.date = formatDate(date.toISOString())
holiday.date = formatDate(date);
});
tdTime.appendChild(inputTime);
@ -101,13 +102,50 @@ function renderHoliday(holiday) {
tdSummary.appendChild(inputSummary);
inputSummary.onchange();
const tdInfo = document.createElement('td');
tr.appendChild(tdInfo);
const tdType = document.createElement('td');
tr.appendChild(tdType);
const selectType = document.createElement("select");
selectType.classList.add('form-select');
tdType.prepend(selectType);
const optionHoliday = document.createElement("option");
optionHoliday.text = "Holiday";
optionHoliday.value = "h";
optionHoliday.selected = holiday.type === "h";
selectType.add(optionHoliday);
const optionOther = document.createElement("option");
optionOther.text = "Other";
optionOther.value = "o";
optionOther.selected = holiday.type === "o";
selectType.add(optionOther);
selectType.onchange = (e => {
holiday.type = e.target.value;
});
const tdRepeat = document.createElement('td');
tr.appendChild(tdRepeat);
const selectRepeat = document.createElement("select");
selectRepeat.classList.add('form-select');
tdRepeat.prepend(selectRepeat);
const optionNever = document.createElement("option");
optionNever.text = "Never";
optionNever.selected = !holiday.repeat;
selectRepeat.add(optionNever);
const optionYearly = document.createElement("option");
optionYearly.text = "Yearly";
optionYearly.value = "y";
optionYearly.selected = holiday.repeat === "y";
selectRepeat.add(optionYearly);
selectRepeat.onchange = (e => {
holiday.repeat = e.target.value;
});
const tdAction = document.createElement('td');
tr.appendChild(tdAction);
const buttonDelete = document.createElement('button');
buttonDelete.classList.add('btn');
buttonDelete.classList.add('btn-action');
tdInfo.prepend(buttonDelete);
tdAction.prepend(buttonDelete);
const iconDelete = document.createElement('i');
iconDelete.classList.add('icon');
iconDelete.classList.add('icon-delete');
@ -129,22 +167,21 @@ function addHoliday() {
}
function getData() {
Util.showModal("Loading...");
Puck.write(`\x10(function() {
Bluetooth.print(JSON.stringify(require("Storage").list("calendar.holiday.json").sort()));
Bluetooth.print(JSON.stringify(require("Storage").list("calendar.days.json").sort()));
})()\n`, contents => {
const fileNames = JSON.parse(contents);
if (fileNames.length > 0) {
Util.showModal("Loading...");
Util.readStorage('calendar.holiday.json',data=>{
Util.readStorage('calendar.days.json',data=>{
holidays = JSON.parse(data || "[]") || [];
Util.hideModal();
holidays.forEach(holiday => {
renderHoliday(holiday);
});
render();
});
} else {
holidays = [];
Util.hideModal();
}
});
}
@ -156,7 +193,7 @@ function onInit() {
</script>
</head>
<body>
<h4>Holidays</h4>
<h4 class="float-left">Holidays</h4>
<div class="float-right">
<button class="btn" onclick="addHoliday();">
@ -164,11 +201,13 @@ function onInit() {
</button>
</div>
<table class="table">
<table class="table table-scroll" style="clear:both;">
<thead>
<tr>
<th>Date</th>
<th>Holiday</th>
<th>Type</th>
<th>Repeat</th>
<th></th>
</tr>
</thead>

View File

@ -15,5 +15,5 @@
{"name":"calendar.settings.js","url":"settings.js"},
{"name":"calendar.img","url":"calendar-icon.js","evaluate":true}
],
"data": [{"name":"calendar.json"}, {"name":"calendar.holiday.json"}]
"data": [{"name":"calendar.json"}, {"name":"calendar.days.json"}]
}