forked from GitHubMirrors/silverbullet-icalendar
fix duplicates and filter canceled/declined events - v0.4.7 [skip-ci]
Some checks failed
Build SilverBullet Plug / build (push) Has been cancelled
Some checks failed
Build SilverBullet Plug / build (push) Has been cancelled
This commit is contained in:
2
PLUG.md
2
PLUG.md
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Library/sstent/icalendar
|
||||
version: "0.4.6"
|
||||
version: "0.4.7"
|
||||
tags: meta/library
|
||||
files:
|
||||
- icalendar.plug.js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "icalendar-plug",
|
||||
"version": "0.4.6",
|
||||
"version": "0.4.7",
|
||||
"nodeModulesDir": "auto",
|
||||
"tasks": {
|
||||
"sync-version": "deno run -A scripts/sync-version.ts",
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
name: icalendar
|
||||
version: 0.4.6
|
||||
version: 0.4.7
|
||||
author: sstent
|
||||
index: icalendar.ts
|
||||
# Legacy SilverBullet permission name
|
||||
|
||||
38
icalendar.ts
38
icalendar.ts
@@ -3,7 +3,7 @@ import ICAL from "ical.js";
|
||||
import { RRule, RRuleSet } from "rrule";
|
||||
import { getUtcOffsetMs, resolveIanaName } from "./timezones.ts";
|
||||
|
||||
const VERSION = "0.4.6";
|
||||
const VERSION = "0.4.7";
|
||||
const CACHE_KEY = "icalendar:lastSync";
|
||||
|
||||
console.log(`[iCalendar] Plug script executing at top level (Version ${VERSION})`);
|
||||
@@ -325,21 +325,55 @@ async function fetchAndParseCalendar(source: any, windowDays = 365, displayTimez
|
||||
const vcalendar = new ICAL.Component(jcalData);
|
||||
const vevents = vcalendar.getAllSubcomponents("vevent");
|
||||
|
||||
// First pass: map of UID -> Set of ISO strings for RECURRENCE-ID exceptions
|
||||
const overrides = new Map<string, Set<string>>();
|
||||
for (const vevent of vevents) {
|
||||
const recId = vevent.getFirstPropertyValue("recurrence-id") as ICAL.Time | null;
|
||||
const uid = vevent.getFirstPropertyValue("uid") as string | null;
|
||||
if (recId && uid) {
|
||||
if (!overrides.has(uid)) overrides.set(uid, new Set());
|
||||
overrides.get(uid)!.add(recId.toJSDate().toISOString());
|
||||
}
|
||||
}
|
||||
|
||||
const events: any[] = [];
|
||||
for (const vevent of vevents) {
|
||||
const icsEvent = new ICAL.Event(vevent);
|
||||
const status = vevent.getFirstPropertyValue("status") as string | null;
|
||||
const summary = icsEvent.summary || "";
|
||||
|
||||
// 1. Skip explicitly cancelled events
|
||||
if (status?.toUpperCase() === "CANCELLED") continue;
|
||||
if (summary.toLowerCase().startsWith("canceled:") || summary.toLowerCase().startsWith("cancelled:")) continue;
|
||||
|
||||
// 2. Skip declined events (look for PARTSTAT=DECLINED in attendees)
|
||||
const attendees = vevent.getAllProperties("attendee");
|
||||
let declined = false;
|
||||
for (const attendee of attendees) {
|
||||
const partstat = attendee.getParameter("partstat");
|
||||
if (partstat?.toUpperCase() === "DECLINED") {
|
||||
// Note: In a multi-user environment, we'd need to check if this is *the* user's status.
|
||||
// For a personal plug, we assume any DECLINED attendee means the user declined or the event is out.
|
||||
declined = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (declined) continue;
|
||||
|
||||
// Extract raw properties for recurrence expansion
|
||||
const summary = icsEvent.summary;
|
||||
const uid = icsEvent.uid;
|
||||
const description = icsEvent.description;
|
||||
const location = icsEvent.location;
|
||||
const rrule = vevent.getFirstPropertyValue("rrule");
|
||||
const exdates = vevent.getAllProperties("exdate").map((p: any) => p.getFirstValue().toJSDate().toISOString());
|
||||
|
||||
// Add recurrence-id overrides to exdates so the Master doesn't expand them
|
||||
if (uid && overrides.has(uid) && !vevent.getFirstPropertyValue("recurrence-id")) {
|
||||
for (const overDate of overrides.get(uid)!) {
|
||||
exdates.push(overDate);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve start/end times
|
||||
const startDateUTC = icsEvent.startDate.toJSDate();
|
||||
const endDateUTC = icsEvent.endDate ? icsEvent.endDate.toJSDate() : null;
|
||||
|
||||
Reference in New Issue
Block a user