diff --git a/components/ai-chat.tsx b/components/ai-chat.tsx index 346204e..c9c0726 100644 --- a/components/ai-chat.tsx +++ b/components/ai-chat.tsx @@ -155,6 +155,7 @@ export function AIChat({ const followUpQuestionsRef = useRef([]); const followUpRequestIdRef = useRef(0); const isComposingRef = useRef(false); + const compositionTimeoutRef = useRef>(undefined); useEffect(() => { const viewport = scrollViewportRef.current; @@ -1088,7 +1089,7 @@ export function AIChat({ }, [isLoading, sendMessage, followUpQuestions]); const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "Enter" && !e.shiftKey && !isComposingRef.current) { + if (e.key === "Enter" && !e.shiftKey && !isComposingRef.current && !e.nativeEvent.isComposing) { e.preventDefault(); sendMessage(); } @@ -1269,10 +1270,18 @@ export function AIChat({ onChange={(e) => setInput(e.target.value)} onKeyDown={handleKeyDown} onCompositionStart={() => { + clearTimeout(compositionTimeoutRef.current); isComposingRef.current = true; }} onCompositionEnd={() => { - isComposingRef.current = false; + // Delay resetting the flag so the keydown handler for the + // same Enter keystroke still sees isComposing as true. + // In some browsers (e.g. Chrome with Chinese IME), + // compositionend fires before keydown for the Enter key + // that confirms the composition. + compositionTimeoutRef.current = setTimeout(() => { + isComposingRef.current = false; + }, 0); }} placeholder="Ask about the video..." className="resize-none rounded-[20px] text-xs bg-neutral-100 border-[#ebecee] pr-11" diff --git a/components/note-editor.tsx b/components/note-editor.tsx index 6978efd..1c41c2b 100644 --- a/components/note-editor.tsx +++ b/components/note-editor.tsx @@ -104,7 +104,7 @@ export function NoteEditor({ selectedText, metadata, currentTime, onSave }: Note }, [originalQuote]); const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { + if (e.key === "Enter" && (e.metaKey || e.ctrlKey) && !e.nativeEvent.isComposing) { e.preventDefault(); handleSave(); } diff --git a/components/transcript-viewer.tsx b/components/transcript-viewer.tsx index b55a71f..14b697d 100644 --- a/components/transcript-viewer.tsx +++ b/components/transcript-viewer.tsx @@ -578,7 +578,7 @@ export function TranscriptViewer({ value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} onKeyDown={(e) => { - if (e.key === 'Enter') navigateSearch('next'); + if (e.key === 'Enter' && !e.nativeEvent.isComposing) navigateSearch('next'); if (e.key === 'Escape') { setIsSearchOpen(false); setSearchQuery("");