import { parseUri, getRecord } from '$lib/atproto'; import type { CardDefinition } from '../../types'; import CreateEventCardModal from './CreateEventCardModal.svelte'; import EventCard from './EventCard.svelte'; import type { Did } from '@atcute/lexicons'; const EVENT_COLLECTION = 'community.lexicon.calendar.event'; export type EventData = { mode: string; name: string; status: string; startsAt: string; endsAt?: string; description?: string; locations?: Array<{ $type: string; address?: { locality?: string; region?: string; country?: string; }; }>; media?: Array<{ alt?: string; role?: string; content?: { $type: 'blob'; ref: { $link: string; }; mimeType?: string; }; aspect_ratio?: { width: number; height: number; }; }>; facets?: Array<{ index: { byteStart: number; byteEnd: number }; features: Array<{ $type: string; [key: string]: unknown }>; }>; uris?: Array<{ uri: string; name?: string; }>; url?: string; }; export const EventCardDefinition = { type: 'event', contentComponent: EventCard, creationModalComponent: CreateEventCardModal, createNew: (card) => { card.w = 4; card.h = 4; card.mobileW = 8; card.mobileH = 6; }, loadData: async (items) => { const eventDataMap: Record = {}; for (const item of items) { const uri = item.cardData?.uri; if (!uri) continue; const parsedUri = parseUri(uri); if (!parsedUri || !parsedUri.rkey || !parsedUri.repo) continue; try { const record = await getRecord({ did: parsedUri.repo as Did, collection: EVENT_COLLECTION, rkey: parsedUri.rkey }); if (record?.value) { eventDataMap[item.id] = record.value as EventData; } } catch (error) { console.error('Failed to fetch event data:', error); } } return eventDataMap; }, onUrlHandler: (url, item) => { // Match smokesignal.events URLs: https://smokesignal.events/{did}/{rkey} const smokesignalMatch = url.match(/^https?:\/\/smokesignal\.events\/(did:[^/]+)\/([^/?#]+)/); if (smokesignalMatch) { const [, did, rkey] = smokesignalMatch; item.w = 4; item.h = 4; item.mobileW = 8; item.mobileH = 6; item.cardType = 'event'; item.cardData.uri = `at://${did}/${EVENT_COLLECTION}/${rkey}`; return item; } // Match AT URIs: at://{did}/community.lexicon.calendar.event/{rkey} const atUriMatch = url.match(/^at:\/\/(did:[^/]+)\/([^/]+)\/([^/?#]+)/); if (atUriMatch) { const [, did, collection, rkey] = atUriMatch; if (collection === EVENT_COLLECTION) { item.w = 4; item.h = 4; item.mobileW = 8; item.mobileH = 6; item.cardType = 'event'; item.cardData.uri = `at://${did}/${collection}/${rkey}`; return item; } } return null; }, urlHandlerPriority: 5, name: 'Event', keywords: ['calendar', 'meetup', 'schedule', 'date', 'rsvp', 'smokesignal'], groups: ['Social'], icon: `` } as CardDefinition & { type: 'event' };