diff --git a/src/components/ChatInput.tsx b/src/components/ChatInput.tsx index 9ca8f13..f45ad97 100644 --- a/src/components/ChatInput.tsx +++ b/src/components/ChatInput.tsx @@ -1,6 +1,7 @@ import { useState, useRef, useEffect, useCallback, lazy, Suspense } from 'react'; import { Send, Square, Paperclip, X, FileText, Eye, EyeOff } from 'lucide-react'; import { useT } from '../hooks/useLocale'; +import { useSendShortcut } from '../hooks/useSendShortcut'; const ReactMarkdown = lazy(() => import('react-markdown')); const remarkGfm = import('remark-gfm').then(m => m.default); @@ -87,6 +88,7 @@ function formatSize(bytes: number): string { export function ChatInput({ onSend, onAbort, isGenerating, disabled, sessionKey }: Props) { const t = useT(); + const { sendOnEnter, toggle: toggleSendShortcut } = useSendShortcut(); const [text, setText] = useState(''); const [files, setFiles] = useState([]); const [isDragOver, setIsDragOver] = useState(false); @@ -179,9 +181,20 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled, sessionKey }; const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter' && !e.shiftKey) { - e.preventDefault(); - handleSubmit(); + if (e.key === 'Enter') { + if (sendOnEnter) { + // Enter sends, Shift+Enter for newline + if (!e.shiftKey && !e.ctrlKey && !e.metaKey) { + e.preventDefault(); + handleSubmit(); + } + } else { + // Ctrl+Enter (or Cmd+Enter on Mac) sends, Enter for newline + if (e.ctrlKey || e.metaKey) { + e.preventDefault(); + handleSubmit(); + } + } } }; @@ -305,6 +318,14 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled, sessionKey rows={1} className="flex-1 bg-transparent resize-none rounded-2xl border border-pc-border bg-pc-input/35 px-4 py-3 text-sm text-pc-text placeholder:text-pc-text-muted outline-none transition-all max-h-[200px]" /> + {/* Send shortcut toggle */} + {isGenerating ? (