|
9 | 9 | class?: string; |
10 | 10 | disabled?: boolean; |
11 | 11 | isLoading?: boolean; |
12 | | - onSend?: (message: string, files?: ChatUploadedFile[]) => void; |
| 12 | + onSend?: (message: string, files?: ChatUploadedFile[]) => Promise<boolean>; |
13 | 13 | onStop?: () => void; |
14 | 14 | showHelperText?: boolean; |
15 | 15 | uploadedFiles?: ChatUploadedFile[]; |
16 | 16 | onFileUpload?: (files: File[]) => void; |
17 | 17 | onFileRemove?: (fileId: string) => void; |
18 | | - // Paste configuration |
19 | | - pasteLongTextToFileLen?: number; |
| 18 | + pasteLongTextToFileLength?: number; |
20 | 19 | } |
21 | 20 |
|
22 | 21 | let { |
|
29 | 28 | uploadedFiles = $bindable([]), |
30 | 29 | onFileUpload, |
31 | 30 | onFileRemove, |
32 | | - pasteLongTextToFileLen = 2500 |
| 31 | + pasteLongTextToFileLength = 2500 |
33 | 32 | }: Props = $props(); |
34 | 33 |
|
35 | 34 | let message = $state(''); |
36 | 35 | let textareaElement: HTMLTextAreaElement | undefined; |
37 | 36 | let fileInputElement: HTMLInputElement | undefined; |
38 | 37 |
|
39 | | - function handleSubmit(event: SubmitEvent) { |
| 38 | + async function handleSubmit(event: SubmitEvent) { |
40 | 39 | event.preventDefault(); |
41 | 40 | if (!message.trim() || disabled || isLoading) return; |
42 | 41 |
|
43 | | - onSend?.(message.trim(), uploadedFiles); |
44 | | - message = ''; |
45 | | - uploadedFiles = []; |
| 42 | + const success = await onSend?.(message.trim(), uploadedFiles); |
46 | 43 |
|
47 | | - if (textareaElement) { |
48 | | - textareaElement.style.height = 'auto'; |
| 44 | + if (success) { |
| 45 | + message = ''; |
| 46 | + uploadedFiles = []; |
| 47 | +
|
| 48 | + if (textareaElement) { |
| 49 | + textareaElement.style.height = 'auto'; |
| 50 | + } |
49 | 51 | } |
50 | 52 | } |
51 | 53 |
|
52 | | - function handleKeydown(event: KeyboardEvent) { |
| 54 | + async function handleKeydown(event: KeyboardEvent) { |
53 | 55 | if (event.key === 'Enter' && !event.shiftKey) { |
54 | 56 | event.preventDefault(); |
55 | 57 |
|
56 | 58 | if (!message.trim() || disabled || isLoading) return; |
57 | 59 |
|
58 | | - onSend?.(message.trim(), uploadedFiles); |
59 | | - message = ''; |
60 | | - uploadedFiles = []; |
| 60 | + const success = await onSend?.(message.trim(), uploadedFiles); |
61 | 61 |
|
62 | | - if (textareaElement) { |
63 | | - textareaElement.style.height = 'auto'; |
| 62 | + if (success) { |
| 63 | + message = ''; |
| 64 | + uploadedFiles = []; |
| 65 | +
|
| 66 | + if (textareaElement) { |
| 67 | + textareaElement.style.height = 'auto'; |
| 68 | + } |
64 | 69 | } |
65 | 70 | } |
66 | 71 | } |
|
83 | 88 | function handlePaste(event: ClipboardEvent) { |
84 | 89 | if (!event.clipboardData) return; |
85 | 90 |
|
86 | | - // Handle pasted files |
87 | 91 | const files = Array.from(event.clipboardData.items) |
88 | 92 | .filter((item) => item.kind === 'file') |
89 | 93 | .map((item) => item.getAsFile()) |
|
95 | 99 | return; |
96 | 100 | } |
97 | 101 |
|
98 | | - // Handle long text conversion to file |
99 | 102 | const text = event.clipboardData.getData('text/plain'); |
100 | | - if (text.length > 0 && pasteLongTextToFileLen > 0 && text.length > pasteLongTextToFileLen) { |
| 103 | + if ( |
| 104 | + text.length > 0 && |
| 105 | + pasteLongTextToFileLength > 0 && |
| 106 | + text.length > pasteLongTextToFileLength |
| 107 | + ) { |
101 | 108 | event.preventDefault(); |
102 | 109 |
|
103 | | - // Create a text file from the pasted content |
104 | 110 | const textFile = new File([text], 'Pasted', { |
105 | 111 | type: 'text/plain' |
106 | 112 | }); |
|
110 | 116 | } |
111 | 117 | </script> |
112 | 118 |
|
113 | | -<!-- Hidden file input --> |
114 | 119 | <input |
115 | 120 | bind:this={fileInputElement} |
116 | 121 | type="file" |
|
0 commit comments