your personal website on atproto - mirror
blento.app
1import { parseUri } from '$lib/atproto';
2import type { CardDefinition } from '../types';
3import CreateEventCardModal from './CreateEventCardModal.svelte';
4import EventCard from './EventCard.svelte';
5
6const EVENT_COLLECTION = 'community.lexicon.calendar.event';
7
8export type EventData = {
9 mode: string;
10 name: string;
11 status: string;
12 startsAt: string;
13 endsAt?: string;
14 description?: string;
15 locations?: Array<{
16 address?: {
17 locality?: string;
18 region?: string;
19 country?: string;
20 };
21 }>;
22 media?: Array<{
23 alt?: string;
24 role?: string;
25 content?: {
26 ref?: {
27 $link: string;
28 };
29 mimeType?: string;
30 };
31 aspect_ratio?: {
32 width: number;
33 height: number;
34 };
35 }>;
36 countGoing?: number;
37 countInterested?: number;
38 url: string;
39};
40
41export const EventCardDefinition = {
42 type: 'event',
43 contentComponent: EventCard,
44 creationModalComponent: CreateEventCardModal,
45 sidebarButtonText: 'Event',
46
47 createNew: (card) => {
48 card.w = 4;
49 card.h = 4;
50 card.mobileW = 8;
51 card.mobileH = 6;
52 },
53
54 loadData: async (items) => {
55 const eventDataMap: Record<string, EventData> = {};
56
57 for (const item of items) {
58 const uri = item.cardData?.uri;
59 if (!uri) continue;
60
61 const { did, rkey } = parseUri(uri);
62
63 try {
64 const response = await fetch(
65 `https://smokesignal.events/xrpc/community.lexicon.calendar.GetEvent?repository=${encodeURIComponent(did)}&record_key=${encodeURIComponent(rkey)}`
66 );
67
68 if (response.ok) {
69 const data = await response.json();
70 eventDataMap[item.id] = data as EventData;
71 }
72 } catch (error) {
73 console.error('Failed to fetch event data:', error);
74 }
75 }
76
77 return eventDataMap;
78 },
79
80 onUrlHandler: (url, item) => {
81 // Match smokesignal.events URLs: https://smokesignal.events/{did}/{rkey}
82 const smokesignalMatch = url.match(/^https?:\/\/smokesignal\.events\/(did:[^/]+)\/([^/?#]+)/);
83 if (smokesignalMatch) {
84 const [, did, rkey] = smokesignalMatch;
85 item.w = 4;
86 item.h = 4;
87 item.mobileW = 8;
88 item.mobileH = 6;
89 item.cardType = 'event';
90 item.cardData.uri = `at://${did}/${EVENT_COLLECTION}/${rkey}`;
91 return item;
92 }
93
94 // Match AT URIs: at://{did}/community.lexicon.calendar.event/{rkey}
95 const atUriMatch = url.match(/^at:\/\/(did:[^/]+)\/([^/]+)\/([^/?#]+)/);
96 if (atUriMatch) {
97 const [, did, collection, rkey] = atUriMatch;
98 if (collection === EVENT_COLLECTION) {
99 item.w = 4;
100 item.h = 4;
101 item.mobileW = 8;
102 item.mobileH = 6;
103 item.cardType = 'event';
104 item.cardData.uri = `at://${did}/${collection}/${rkey}`;
105 return item;
106 }
107 }
108
109 return null;
110 },
111
112 urlHandlerPriority: 5,
113
114 name: 'Event Card'
115} as CardDefinition & { type: 'event' };