From d4c92572190fc73e6ccb832e4da6733349623084 Mon Sep 17 00:00:00 2001 From: kang-square <112981282+kang-square@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:51:26 -0500 Subject: [PATCH 1/3] shortcut and history message --- ui/desktop/src/components/ChatView.tsx | 11 +++++- ui/desktop/src/components/Input.tsx | 51 ++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/ui/desktop/src/components/ChatView.tsx b/ui/desktop/src/components/ChatView.tsx index c11430815d59..c2c02f1f73f9 100644 --- a/ui/desktop/src/components/ChatView.tsx +++ b/ui/desktop/src/components/ChatView.tsx @@ -278,7 +278,16 @@ export default function ChatView({
{isLoading && } - + isUserMessage(m)) + .map((m) => m.content.find((c) => c.type === 'text')?.text || '') + .filter((text) => text.trim()) + .reverse()} + />
diff --git a/ui/desktop/src/components/Input.tsx b/ui/desktop/src/components/Input.tsx index b330d163924c..d163cead92ef 100644 --- a/ui/desktop/src/components/Input.tsx +++ b/ui/desktop/src/components/Input.tsx @@ -7,12 +7,19 @@ interface InputProps { handleSubmit: (e: React.FormEvent) => void; isLoading?: boolean; onStop?: () => void; + commandHistory?: string[]; } -export default function Input({ handleSubmit, isLoading = false, onStop }: InputProps) { +export default function Input({ + handleSubmit, + isLoading = false, + onStop, + commandHistory = [], +}: InputProps) { const [value, setValue] = useState(''); - // State to track if the IME is composing (i.e., in the middle of Japanese IME input) const [isComposing, setIsComposing] = useState(false); + const [historyIndex, setHistoryIndex] = useState(-1); + const [savedInput, setSavedInput] = useState(''); const textAreaRef = useRef(null); useEffect(() => { @@ -51,6 +58,40 @@ export default function Input({ handleSubmit, isLoading = false, onStop }: Input }; const handleKeyDown = (evt: React.KeyboardEvent) => { + // Handle command history navigation + if ((evt.metaKey || evt.ctrlKey) && (evt.key === 'ArrowUp' || evt.key === 'ArrowDown')) { + evt.preventDefault(); + + // Save current input if we're just starting to navigate history + if (historyIndex === -1) { + setSavedInput(value); + } + + // Calculate new history index + let newIndex = historyIndex; + if (evt.key === 'ArrowUp') { + // Move backwards through history + if (historyIndex < commandHistory.length - 1) { + newIndex = historyIndex + 1; + } + } else { + // Move forwards through history + if (historyIndex > -1) { + newIndex = historyIndex - 1; + } + } + + // Update index and value + setHistoryIndex(newIndex); + if (newIndex === -1) { + // Restore saved input when going past the end of history + setValue(savedInput); + } else { + setValue(commandHistory[newIndex] || ''); + } + return; + } + if (evt.key === 'Enter') { // should not trigger submit on Enter if it's composing (IME input in progress) or shift is pressed if (evt.shiftKey || isComposing) { @@ -66,6 +107,8 @@ export default function Input({ handleSubmit, isLoading = false, onStop }: Input if (!isLoading && value.trim()) { handleSubmit(new CustomEvent('submit', { detail: { value } })); setValue(''); + setHistoryIndex(-1); + setSavedInput(''); } } }; @@ -75,6 +118,8 @@ export default function Input({ handleSubmit, isLoading = false, onStop }: Input if (value.trim() && !isLoading) { handleSubmit(new CustomEvent('submit', { detail: { value } })); setValue(''); + setHistoryIndex(-1); + setSavedInput(''); } }; @@ -94,7 +139,7 @@ export default function Input({ handleSubmit, isLoading = false, onStop }: Input