2 import { Paperclip, Image, FileText, File, Volume2 } from '@lucide/svelte';
3 import { Button } from '$lib/components/ui/button';
4 import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
5 import * as Tooltip from '$lib/components/ui/tooltip';
6 import { TOOLTIP_DELAY_DURATION } from '$lib/constants/tooltip-config';
7 import { FileTypeCategory } from '$lib/enums/files';
8 import { supportsAudio, supportsVision } from '$lib/stores/server.svelte';
13 onFileUpload?: (fileType?: FileTypeCategory) => void;
16 let { class: className = '', disabled = false, onFileUpload }: Props = $props();
18 const fileUploadTooltipText = $derived.by(() => {
19 return !supportsVision()
20 ? 'Text files and PDFs supported. Images, audio, and video require vision models.'
24 function handleFileUpload(fileType?: FileTypeCategory) {
25 onFileUpload?.(fileType);
29 <div class="flex items-center gap-1 {className}">
31 <DropdownMenu.Trigger name="Attach files">
32 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
35 class="file-upload-button h-8 w-8 rounded-full bg-transparent p-0 text-muted-foreground hover:bg-foreground/10 hover:text-foreground"
39 <span class="sr-only">Attach files</span>
41 <Paperclip class="h-4 w-4" />
46 <p>{fileUploadTooltipText}</p>
49 </DropdownMenu.Trigger>
51 <DropdownMenu.Content align="start" class="w-48">
52 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
53 <Tooltip.Trigger class="w-full">
55 class="images-button flex cursor-pointer items-center gap-2"
56 disabled={!supportsVision()}
57 onclick={() => handleFileUpload(FileTypeCategory.IMAGE)}
59 <Image class="h-4 w-4" />
65 {#if !supportsVision()}
67 <p>Images require vision models to be processed</p>
72 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
73 <Tooltip.Trigger class="w-full">
75 class="audio-button flex cursor-pointer items-center gap-2"
76 disabled={!supportsAudio()}
77 onclick={() => handleFileUpload(FileTypeCategory.AUDIO)}
79 <Volume2 class="h-4 w-4" />
81 <span>Audio Files</span>
85 {#if !supportsAudio()}
87 <p>Audio files require audio models to be processed</p>
93 class="flex cursor-pointer items-center gap-2"
94 onclick={() => handleFileUpload(FileTypeCategory.TEXT)}
96 <FileText class="h-4 w-4" />
98 <span>Text Files</span>
101 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
102 <Tooltip.Trigger class="w-full">
104 class="flex cursor-pointer items-center gap-2"
105 onclick={() => handleFileUpload(FileTypeCategory.PDF)}
107 <File class="h-4 w-4" />
109 <span>PDF Files</span>
113 {#if !supportsVision()}
115 <p>PDFs will be converted to text. Image-based PDFs may not work properly.</p>
119 </DropdownMenu.Content>