diff --git a/ui/desktop/src/components/ChatInput.tsx b/ui/desktop/src/components/ChatInput.tsx index 63da447e0ce2..e2057fcbf0a9 100644 --- a/ui/desktop/src/components/ChatInput.tsx +++ b/ui/desktop/src/components/ChatInput.tsx @@ -122,6 +122,7 @@ export default function ChatInput({ const [displayValue, setDisplayValue] = useState(initialValue); // For immediate visual feedback const [isFocused, setIsFocused] = useState(false); const [pastedImages, setPastedImages] = useState([]); + const [isFileDialogOpen, setIsFileDialogOpen] = useState(false); // Derived state - chatState != Idle means we're in some form of loading state const isLoading = chatState !== ChatState.Idle; @@ -1014,13 +1015,21 @@ export default function ChatInput({ } }; + // Handle file selection with dialog state management const handleFileSelect = async () => { - const path = await window.electron.selectFileOrDirectory(); - if (path) { - const newValue = displayValue.trim() ? `${displayValue.trim()} ${path}` : path; - setDisplayValue(newValue); - setValue(newValue); - textAreaRef.current?.focus(); + if (isFileDialogOpen) return; // Prevent multiple dialogs + + setIsFileDialogOpen(true); + try { + const path = await window.electron.selectFileOrDirectory(); + if (path) { + const newValue = displayValue.trim() ? `${displayValue.trim()} ${path}` : path; + setDisplayValue(newValue); + setValue(newValue); + textAreaRef.current?.focus(); + } + } finally { + setIsFileDialogOpen(false); } }; @@ -1453,20 +1462,23 @@ export default function ChatInput({ {/* Directory path */}
- + - Attach file or directory + + {isFileDialogOpen ? 'Dialog open...' : 'Attach file or directory'} +
@@ -1562,4 +1574,4 @@ export default function ChatInput({
); -} +} \ No newline at end of file