From ba3d45372d3cd9703c131afe15198664dbce639b Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 11 Mar 2026 16:24:21 -0700 Subject: [PATCH] feat: integrate heartbeat with rSchedule shapes folk-calendar subscribes to clock:tick/daily to refresh today marker. folk-reminders-widget auto-refreshes every 5 minutes. Co-Authored-By: Claude Opus 4.6 --- lib/folk-calendar.ts | 14 ++++++++++++++ .../rschedule/components/folk-reminders-widget.ts | 10 ++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/folk-calendar.ts b/lib/folk-calendar.ts index e27a05d..95f8b0d 100644 --- a/lib/folk-calendar.ts +++ b/lib/folk-calendar.ts @@ -192,6 +192,10 @@ declare global { export class FolkCalendar extends FolkShape { static override tagName = "folk-calendar"; + static override portDescriptors = [ + { name: "date", type: "string" as const, direction: "output" as const }, + ]; + static { const sheet = new CSSStyleSheet(); const parentRules = Array.from(FolkShape.styles.cssRules) @@ -467,4 +471,14 @@ export class FolkCalendar extends FolkShape { this.events = data.events.map((e: any) => ({ ...e, date: new Date(e.date) })); } } + + /** + * Handle system clock heartbeat events. + * Refreshes the calendar to update the "today" marker on day boundaries. + */ + override onEventReceived(channel: string, payload: unknown): void { + if (channel === "clock:tick" || channel === "clock:daily") { + this.#render(); + } + } } diff --git a/modules/rschedule/components/folk-reminders-widget.ts b/modules/rschedule/components/folk-reminders-widget.ts index f762cc9..eade319 100644 --- a/modules/rschedule/components/folk-reminders-widget.ts +++ b/modules/rschedule/components/folk-reminders-widget.ts @@ -27,6 +27,7 @@ class FolkRemindersWidget extends HTMLElement { private showAddForm = false; private formTitle = ""; private formDate = ""; + private refreshTimer: ReturnType | null = null; constructor() { super(); @@ -36,6 +37,15 @@ class FolkRemindersWidget extends HTMLElement { connectedCallback() { this.space = this.getAttribute("space") || "demo"; this.loadReminders(); + // Auto-refresh every 5 minutes to pick up newly-due reminders + this.refreshTimer = setInterval(() => this.loadReminders(), 5 * 60_000); + } + + disconnectedCallback() { + if (this.refreshTimer) { + clearInterval(this.refreshTimer); + this.refreshTimer = null; + } } private getApiBase(): string {