your personal website on atproto - mirror blento.app
at small-event-card-fixes 99 lines 3.0 kB view raw
1<script lang="ts"> 2 import { Alert, Button, Input, Subheading } from '@foxui/core'; 3 import Modal from '$lib/components/modal/Modal.svelte'; 4 import type { CreationModalComponentProps } from '../../types'; 5 import { getRecord } from '$lib/atproto/methods'; 6 import type { Did } from '@atcute/lexicons'; 7 8 const EVENT_COLLECTION = 'community.lexicon.calendar.event'; 9 10 let { item = $bindable(), oncreate, oncancel }: CreationModalComponentProps = $props(); 11 12 let isValidating = $state(false); 13 let errorMessage = $state(''); 14 let eventUrl = $state(''); 15 16 function parseEventUrl(url: string): { did: string; rkey: string } | null { 17 // Match smokesignal.events URLs: https://smokesignal.events/{did}/{rkey} 18 const smokesignalMatch = url.match(/^https?:\/\/smokesignal\.events\/(did:[^/]+)\/([^/?#]+)/); 19 if (smokesignalMatch) { 20 return { did: smokesignalMatch[1], rkey: smokesignalMatch[2] }; 21 } 22 23 // Match AT URIs: at://{did}/community.lexicon.calendar.event/{rkey} 24 const atUriMatch = url.match(/^at:\/\/(did:[^/]+)\/([^/]+)\/([^/?#]+)/); 25 if (atUriMatch && atUriMatch[2] === EVENT_COLLECTION) { 26 return { did: atUriMatch[1], rkey: atUriMatch[3] }; 27 } 28 29 return null; 30 } 31 32 async function validateAndCreate() { 33 errorMessage = ''; 34 isValidating = true; 35 36 try { 37 const parsed = parseEventUrl(eventUrl.trim()); 38 39 if (!parsed) { 40 throw new Error('Invalid URL format'); 41 } 42 43 // Validate the event exists by fetching the record directly 44 const record = await getRecord({ 45 did: parsed.did as Did, 46 collection: EVENT_COLLECTION, 47 rkey: parsed.rkey 48 }); 49 50 if (!record?.value) { 51 throw new Error('Event not found'); 52 } 53 54 // Store as AT URI 55 item.cardData.uri = `at://${parsed.did}/${EVENT_COLLECTION}/${parsed.rkey}`; 56 57 return true; 58 } catch (err) { 59 errorMessage = 60 err instanceof Error && err.message === 'Event not found' 61 ? "Couldn't find that event. Please check the URL and try again." 62 : 'Invalid URL. Please enter a valid event AT URI or smokesignal.events URL.'; 63 return false; 64 } finally { 65 isValidating = false; 66 } 67 } 68</script> 69 70<Modal open={true} closeButton={false}> 71 <form 72 onsubmit={async () => { 73 if (await validateAndCreate()) oncreate(); 74 }} 75 class="flex flex-col gap-2" 76 > 77 <Subheading>Enter an event URL</Subheading> 78 <Input 79 bind:value={eventUrl} 80 placeholder="at://did:.../community.lexicon.calendar.event/..." 81 class="mt-4" 82 /> 83 84 {#if errorMessage} 85 <Alert type="error" title="Failed to create event card"><span>{errorMessage}</span></Alert> 86 {/if} 87 88 <p class="text-base-500 dark:text-base-400 mt-2 text-xs"> 89 Paste an AT URI for a calendar event or a smokesignal.events URL. 90 </p> 91 92 <div class="mt-4 flex justify-end gap-2"> 93 <Button onclick={oncancel} variant="ghost">Cancel</Button> 94 <Button type="submit" disabled={isValidating || !eventUrl.trim()} 95 >{isValidating ? 'Creating...' : 'Create'}</Button 96 > 97 </div> 98 </form> 99</Modal>