/** * rCal applet definitions — Next Event, Timeline View. */ import type { AppletDefinition, AppletLiveData } from "../../shared/applet-types"; import { projectSpace } from "../../shared/markwhen"; const nextEvent: AppletDefinition = { id: "next-event", label: "Next Event", icon: "📅", accentColor: "#2563eb", ports: [ { name: "events-in", type: "json", direction: "input" }, { name: "event-out", type: "json", direction: "output" }, ], renderCompact(data: AppletLiveData): string { const { snapshot } = data; const title = (snapshot.title as string) || "No upcoming events"; const time = (snapshot.time as string) || ""; const location = (snapshot.location as string) || ""; return `
${title}
${time ? `
🕐 ${time}
` : ""} ${location ? `
📍 ${location}
` : ""} ${!time && !location ? `
Connect a calendar feed
` : ""}
`; }, onInputReceived(portName, value, ctx) { if (portName === "events-in" && Array.isArray(value) && value.length > 0) { ctx.emitOutput("event-out", value[0]); } }, }; const timelineView: AppletDefinition = { id: "timeline-view", label: "Timeline", icon: "🕒", accentColor: "#2563eb", ports: [ { name: "range-in", type: "json", direction: "input" }, { name: "mw-out", type: "json", direction: "output" }, ], renderCompact(data: AppletLiveData): string { const count = Number(data.snapshot.count ?? 0); const preview = (data.snapshot.preview as string) || ""; return `
${count} event(s)
${preview || "Open to render timeline"}
`; }, async fetchLiveData(space: string) { const projection = await projectSpace(space, { modules: ["rcal"] }); const first = projection.events[0]; return { count: projection.count, preview: first ? first.title : "", mw: projection.text, }; }, onInputReceived(portName, value, ctx) { if (portName === "range-in" && value && typeof value === "object") { const range = value as { from?: number; to?: number }; projectSpace(ctx.space, { modules: ["rcal"], from: range.from, to: range.to }) .then(p => ctx.emitOutput("mw-out", p.text)); } }, }; export const calApplets: AppletDefinition[] = [nextEvent, timelineView];