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 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-11 16:24:21 -07:00
parent fee72573ba
commit ba3d45372d
2 changed files with 24 additions and 0 deletions

View File

@ -192,6 +192,10 @@ declare global {
export class FolkCalendar extends FolkShape { export class FolkCalendar extends FolkShape {
static override tagName = "folk-calendar"; static override tagName = "folk-calendar";
static override portDescriptors = [
{ name: "date", type: "string" as const, direction: "output" as const },
];
static { static {
const sheet = new CSSStyleSheet(); const sheet = new CSSStyleSheet();
const parentRules = Array.from(FolkShape.styles.cssRules) 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) })); 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();
}
}
} }

View File

@ -27,6 +27,7 @@ class FolkRemindersWidget extends HTMLElement {
private showAddForm = false; private showAddForm = false;
private formTitle = ""; private formTitle = "";
private formDate = ""; private formDate = "";
private refreshTimer: ReturnType<typeof setInterval> | null = null;
constructor() { constructor() {
super(); super();
@ -36,6 +37,15 @@ class FolkRemindersWidget extends HTMLElement {
connectedCallback() { connectedCallback() {
this.space = this.getAttribute("space") || "demo"; this.space = this.getAttribute("space") || "demo";
this.loadReminders(); 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 { private getApiBase(): string {