some ICS fixes, handle empty calendar list
This commit is contained in:
parent
d7d86601f0
commit
6bf9758605
@ -102,31 +102,43 @@ function display_event_date(item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeICSField(text) {
|
function format_ICS_text(text) {
|
||||||
return text.replace(/\\/g, "\\\\")
|
return text.replace(/[\\,;]/g, "\\$&") // escape backslash and separators
|
||||||
.replace(/[,;]/g, "\\$&")
|
.replace(/\n/g, "\\n") // escape newline
|
||||||
.replace(/\n/g, "\\n");
|
.replace(/[\x00-\x1f]+/g, " ") // replace control characters with whitespace
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_ICS_date(date) {
|
||||||
|
if (date) {
|
||||||
|
date = new Date(date);
|
||||||
|
} else {
|
||||||
|
date = new Date(); // default to "now"
|
||||||
|
}
|
||||||
|
// remove "-" and ":" separators (but keep "T"), and drop microseconds
|
||||||
|
return date.toISOString().replace(/-|:|\.\d+/g, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
function createICSLink(item, settings) {
|
function createICSLink(item, settings) {
|
||||||
const start = new Date(item.calculated.startDate).toISOString().replace(/-|:|\.\d+/g, '');
|
const start = format_ICS_date(item.calculated.startDate);
|
||||||
const end = new Date(item.calculated.endDate).toISOString().replace(/-|:|\.\d+/g, '');
|
const end = format_ICS_date(item.calculated.endDate);
|
||||||
|
|
||||||
const summary = item.base.caption;
|
const summary = item.base.caption;
|
||||||
const description = item.base.information || "";
|
const description = item.base.information || "";
|
||||||
const location = item.base.address?.meetingAt || "";
|
const location = item.base.address?.meetingAt || "";
|
||||||
|
|
||||||
// Escape special characters for ICS fields
|
// Escape special characters for ICS fields
|
||||||
const escapedSummary = escapeICSField(summary /* .replace(/['"]/g, "") */);
|
const escapedSummary = format_ICS_text(summary /* .replace(/['"]/g, "") */);
|
||||||
const escapedDescription = escapeICSField(description /* .replace(/['"]/g, "") */);
|
const escapedDescription = format_ICS_text(description /* .replace(/['"]/g, "") */);
|
||||||
const escapedLocation = escapeICSField(location);
|
const escapedLocation = format_ICS_text(location);
|
||||||
|
|
||||||
const icsContent = `BEGIN:VCALENDAR
|
const icsContent = `BEGIN:VCALENDAR
|
||||||
VERSION:2.0
|
VERSION:2.0
|
||||||
PRODID:-//Evang Kirchengemeinde Malmsheim//Gottesdienste//EN
|
PRODID:-//churchtools-next-events//EN
|
||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
UID:${crypto.randomUUID()}@malmsheim-evangelisch.de
|
UID:appointment-${item.base.id}@${window.location.hostname}
|
||||||
DTSTAMP:${new Date().toISOString().replace(/-|:|\.\d+/g, '')}
|
CREATED:${format_ICS_date(item.base.meta?.createdDate)}
|
||||||
|
LAST-MODIFIED:${format_ICS_date(item.base.meta?.modifiedDate)}
|
||||||
DTSTART:${start}
|
DTSTART:${start}
|
||||||
DTEND:${end}
|
DTEND:${end}
|
||||||
SUMMARY:${escapedSummary}
|
SUMMARY:${escapedSummary}
|
||||||
@ -396,6 +408,9 @@ async function load_events(dom_node, defaults) {
|
|||||||
const calendars = all_calendars.filter((calendar) => r_cal_regex.exec(calendar.name));
|
const calendars = all_calendars.filter((calendar) => r_cal_regex.exec(calendar.name));
|
||||||
const calendar_ids = calendars.map((calendar) => calendar.id);
|
const calendar_ids = calendars.map((calendar) => calendar.id);
|
||||||
|
|
||||||
|
let appointments;
|
||||||
|
|
||||||
|
if (calendar_ids.length) {
|
||||||
const filters = calendar_ids.map((cal_id) => `calendar_ids[]=${cal_id}`);
|
const filters = calendar_ids.map((cal_id) => `calendar_ids[]=${cal_id}`);
|
||||||
const from = new Date();
|
const from = new Date();
|
||||||
filters.push(`from=${format_date(from)}`);
|
filters.push(`from=${format_date(from)}`);
|
||||||
@ -403,11 +418,14 @@ async function load_events(dom_node, defaults) {
|
|||||||
filters.push(`to=${format_date(to)}`);
|
filters.push(`to=${format_date(to)}`);
|
||||||
const query = filters.join("&");
|
const query = filters.join("&");
|
||||||
const all_appointments = (await (await fetch(settings.instance + `/api/calendars/appointments?${query}`, req_config)).json()).data;
|
const all_appointments = (await (await fetch(settings.instance + `/api/calendars/appointments?${query}`, req_config)).json()).data;
|
||||||
const appointments = all_appointments.filter((appointment) => r_event_regex.exec(appointment.base.title));
|
appointments = all_appointments.filter((appointment) => r_event_regex.exec(appointment.base.title));
|
||||||
|
|
||||||
if (appointments.length > settings.limit) {
|
if (appointments.length > settings.limit) {
|
||||||
appointments.length = settings.limit;
|
appointments.length = settings.limit;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
appointments = [];
|
||||||
|
}
|
||||||
|
|
||||||
const Appointments = {
|
const Appointments = {
|
||||||
view: function(vnode) {
|
view: function(vnode) {
|
||||||
|
Loading…
Reference in New Issue
Block a user