1<script lang="ts">
2 import * as Dialog from '$lib/components/ui/dialog';
3 import { ChatAttachmentPreview } from '$lib/components/app';
4 import { formatFileSize } from '$lib/utils';
5
6 interface Props {
7 open: boolean;
8 onOpenChange?: (open: boolean) => void;
9 // Either an uploaded file or a stored attachment
10 uploadedFile?: ChatUploadedFile;
11 attachment?: DatabaseMessageExtra;
12 // For uploaded files
13 preview?: string;
14 name?: string;
15 size?: number;
16 textContent?: string;
17 // For vision modality check
18 activeModelId?: string;
19 }
20
21 let {
22 open = $bindable(),
23 onOpenChange,
24 uploadedFile,
25 attachment,
26 preview,
27 name,
28 size,
29 textContent,
30 activeModelId
31 }: Props = $props();
32
33 let chatAttachmentPreviewRef: ChatAttachmentPreview | undefined = $state();
34
35 let displayName = $derived(uploadedFile?.name || attachment?.name || name || 'Unknown File');
36
37 let displaySize = $derived(uploadedFile?.size || size);
38
39 $effect(() => {
40 if (open && chatAttachmentPreviewRef) {
41 chatAttachmentPreviewRef.reset();
42 }
43 });
44</script>
45
46<Dialog.Root bind:open {onOpenChange}>
47 <Dialog.Content class="grid max-h-[90vh] max-w-5xl overflow-hidden sm:w-auto sm:max-w-6xl">
48 <Dialog.Header>
49 <Dialog.Title class="pr-8">{displayName}</Dialog.Title>
50 <Dialog.Description>
51 {#if displaySize}
52 {formatFileSize(displaySize)}
53 {/if}
54 </Dialog.Description>
55 </Dialog.Header>
56
57 <ChatAttachmentPreview
58 bind:this={chatAttachmentPreviewRef}
59 {uploadedFile}
60 {attachment}
61 {preview}
62 name={displayName}
63 {textContent}
64 {activeModelId}
65 />
66 </Dialog.Content>
67</Dialog.Root>