your personal website on atproto - mirror
blento.app
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 { parseGrainGalleryUrl } from './helpers';
6 import { resolveHandle } from '$lib/atproto';
7 import type { Handle } from '@atcute/lexicons';
8
9 let { item = $bindable(), oncreate, oncancel }: CreationModalComponentProps = $props();
10
11 let isValidating = $state(false);
12 let errorMessage = $state('');
13
14 async function checkUrl() {
15 errorMessage = '';
16 isValidating = true;
17
18 try {
19 const parsed = parseGrainGalleryUrl(item.cardData.href);
20 if (!parsed) {
21 errorMessage = 'Please enter a valid grain.social gallery URL';
22 return false;
23 }
24
25 const did = await resolveHandle({ handle: parsed.handle as Handle });
26 if (!did) {
27 errorMessage = 'Could not resolve handle';
28 return false;
29 }
30
31 item.cardData.galleryUri = `at://${did}/social.grain.gallery/${parsed.rkey}`;
32 return true;
33 } finally {
34 isValidating = false;
35 }
36 }
37</script>
38
39<Modal open={true} closeButton={false}>
40 <form
41 onsubmit={async () => {
42 if (await checkUrl()) oncreate();
43 }}
44 class="flex flex-col gap-2"
45 >
46 <Subheading>Enter a grain.social gallery URL</Subheading>
47 <Input
48 bind:value={item.cardData.href}
49 placeholder="https://grain.social/profile/handle/gallery/..."
50 />
51
52 {#if errorMessage}
53 <Alert type="error" title="Invalid URL"><span>{errorMessage}</span></Alert>
54 {/if}
55
56 <div class="mt-4 flex justify-end gap-2">
57 <Button onclick={oncancel} variant="ghost">Cancel</Button>
58 <Button type="submit" disabled={isValidating}>
59 {isValidating ? 'Creating...' : 'Create'}
60 </Button>
61 </div>
62 </form>
63</Modal>