Link upcoming events to their ICS URL
The "Nächste Veranstaltungen" table read the event URL via `ICAL.Event.url`,
but ical.js does not expose a `url` getter on `ICAL.Event` (it only has uid,
summary, description, color, location, sequence, the dates, organizer and
attendees). `event.url` was therefore always `undefined` and the `?? ""`
fallback turned it into an empty string, so every row rendered as
`<a href="">`, a dead link that just reloads the start page.
Read the URL from the VEVENT component instead. This also picks up the
`URL;VALUE=URI:` form used by most events in the published calendar, which is
exported from a CalDAV client and does not use a bare `URL:` property.
Not every event has a URL, so only wrap the name in a link when one is
present and emit plain text otherwise.
Checked against https://berlin.ccc.de/calendars/all.ics (31 events, 1 of them
without a URL):
before: <td><a href="">CCCB Plenum</a></td>
after: <td><a href="https://wiki.berlin.ccc.de/Plenum">CCCB Plenum</a></td>
after: <td>Aktionstag gegen Überwachung im Chaos Computer Club Berlin</td>
Fixes: c28f04c6e8 ("switch to ics files; make calendars work; fix some minor issues")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
b11d80aac2
commit
b8ec457818
1 changed files with 15 additions and 7 deletions
|
|
@ -7,7 +7,7 @@ import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js";
|
||||||
* @param {Date} now Events must start after this date
|
* @param {Date} now Events must start after this date
|
||||||
* @param {number} maxEvents Maximum number of events to return
|
* @param {number} maxEvents Maximum number of events to return
|
||||||
* @param {number} maxDays Maximum number of days into the future
|
* @param {number} maxDays Maximum number of days into the future
|
||||||
* @returns {{start: Date, name: string, url: string}[]}
|
* @returns {{start: Date, name: string, url: string}[]} url is empty when the event has no URL
|
||||||
*/
|
*/
|
||||||
function getUpcomingEvents(icsText, now, maxEvents, maxDays) {
|
function getUpcomingEvents(icsText, now, maxEvents, maxDays) {
|
||||||
const jcal = ICAL.parse(icsText);
|
const jcal = ICAL.parse(icsText);
|
||||||
|
|
@ -25,6 +25,9 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ICAL.Event does not expose the URL property, so read it from the component.
|
||||||
|
const url = component.getFirstPropertyValue("url") ?? "";
|
||||||
|
|
||||||
if (event.isRecurring()) {
|
if (event.isRecurring()) {
|
||||||
const iterator = event.iterator();
|
const iterator = event.iterator();
|
||||||
|
|
||||||
|
|
@ -47,7 +50,7 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) {
|
||||||
events.push({
|
events.push({
|
||||||
start,
|
start,
|
||||||
name: event.summary ?? "",
|
name: event.summary ?? "",
|
||||||
url: event.url ?? "",
|
url,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +61,7 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) {
|
||||||
events.push({
|
events.push({
|
||||||
start,
|
start,
|
||||||
name: event.summary ?? "",
|
name: event.summary ?? "",
|
||||||
url: event.url ?? "",
|
url,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -100,11 +103,16 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|
||||||
const colName = document.createElement("td");
|
const colName = document.createElement("td");
|
||||||
|
|
||||||
const a = document.createElement("a");
|
if (event.url) {
|
||||||
a.href = event.url;
|
const a = document.createElement("a");
|
||||||
a.text = event.name;
|
a.href = event.url;
|
||||||
|
a.text = event.name;
|
||||||
|
|
||||||
|
colName.appendChild(a);
|
||||||
|
} else {
|
||||||
|
colName.innerText = event.name;
|
||||||
|
}
|
||||||
|
|
||||||
colName.appendChild(a);
|
|
||||||
row.appendChild(colName);
|
row.appendChild(colName);
|
||||||
|
|
||||||
table.appendChild(row);
|
table.appendChild(row);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue