From 48148e38d982f25c375c48cc7f84ea94e78f1389 Mon Sep 17 00:00:00 2001 From: Sam Hoang Van Date: Mon, 31 Mar 2025 10:35:02 +0700 Subject: [PATCH] feat: Add shift-click to append suggestions to text area (#2081) * feat: Add shift-click to append suggestions to text area When a user shift-clicks a suggestion, the text is now appended to the current text area content instead of being sent immediately. This allows users to: - Build complex prompts by combining multiple suggestions - Edit suggestions before sending them - Reuse parts of previous suggestions The implementation passes the mouse event through the component chain and checks for the shift key before deciding whether to append or send the message. * Tweak icon and internationalize --------- Co-authored-by: Matt Rubens --- webview-ui/src/__mocks__/lucide-react.ts | 1 + webview-ui/src/components/chat/ChatRow.tsx | 2 +- webview-ui/src/components/chat/ChatView.tsx | 11 +++++-- .../src/components/chat/FollowUpSuggest.tsx | 30 +++++++++++++++---- webview-ui/src/i18n/locales/ca/chat.json | 3 ++ webview-ui/src/i18n/locales/de/chat.json | 3 ++ webview-ui/src/i18n/locales/en/chat.json | 3 ++ webview-ui/src/i18n/locales/es/chat.json | 3 ++ webview-ui/src/i18n/locales/fr/chat.json | 3 ++ webview-ui/src/i18n/locales/hi/chat.json | 3 ++ webview-ui/src/i18n/locales/it/chat.json | 3 ++ webview-ui/src/i18n/locales/ja/chat.json | 3 ++ webview-ui/src/i18n/locales/ko/chat.json | 3 ++ webview-ui/src/i18n/locales/pl/chat.json | 3 ++ webview-ui/src/i18n/locales/pt-BR/chat.json | 3 ++ webview-ui/src/i18n/locales/tr/chat.json | 3 ++ webview-ui/src/i18n/locales/vi/chat.json | 3 ++ webview-ui/src/i18n/locales/zh-CN/chat.json | 3 ++ webview-ui/src/i18n/locales/zh-TW/chat.json | 3 ++ 19 files changed, 80 insertions(+), 9 deletions(-) diff --git a/webview-ui/src/__mocks__/lucide-react.ts b/webview-ui/src/__mocks__/lucide-react.ts index 64ab05eb34..e22005eff3 100644 --- a/webview-ui/src/__mocks__/lucide-react.ts +++ b/webview-ui/src/__mocks__/lucide-react.ts @@ -4,4 +4,5 @@ export const Check = () => React.createElement("div") export const ChevronsUpDown = () => React.createElement("div") export const Loader = () => React.createElement("div") export const X = () => React.createElement("div") +export const Edit = () => React.createElement("div") export const Database = (props: any) => React.createElement("span", { "data-testid": "database-icon", ...props }) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 7fe200c3e9..c09ae23783 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -33,7 +33,7 @@ interface ChatRowProps { isStreaming: boolean onToggleExpand: () => void onHeightChange: (isTaller: boolean) => void - onSuggestionClick?: (answer: string) => void + onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void } interface ChatRowContentProps extends Omit {} diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 4075485732..5f913c82f4 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -1055,8 +1055,15 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie isLast={index === groupedMessages.length - 1} onHeightChange={handleRowHeightChange} isStreaming={isStreaming} - onSuggestionClick={(answer: string) => { - handleSendMessage(answer, []) + onSuggestionClick={(answer: string, event?: React.MouseEvent) => { + if (event?.shiftKey) { + // Always append to existing text, don't overwrite + setInputValue((currentValue) => { + return currentValue !== "" ? `${currentValue} \n${answer}` : answer + }) + } else { + handleSendMessage(answer, []) + } }} /> ) diff --git a/webview-ui/src/components/chat/FollowUpSuggest.tsx b/webview-ui/src/components/chat/FollowUpSuggest.tsx index 24dc42ca7d..25371dc502 100644 --- a/webview-ui/src/components/chat/FollowUpSuggest.tsx +++ b/webview-ui/src/components/chat/FollowUpSuggest.tsx @@ -1,17 +1,20 @@ import { useCallback } from "react" import { cn } from "../../lib/utils" import { Button } from "../ui/button" +import { Edit } from "lucide-react" +import { useAppTranslation } from "../../i18n/TranslationContext" interface FollowUpSuggestProps { suggestions?: string[] - onSuggestionClick?: (answer: string) => void + onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void ts: number } const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: FollowUpSuggestProps) => { + const { t } = useAppTranslation() const handleSuggestionClick = useCallback( - (suggestion: string) => { - onSuggestionClick?.(suggestion) + (suggestion: string, event: React.MouseEvent) => { + onSuggestionClick?.(suggestion, event) }, [onSuggestionClick], ) @@ -26,14 +29,29 @@ const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }: Follow
{suggestions.map((suggestion) => ( -
+
+
{ + e.stopPropagation() + // Simulate shift-click by directly calling the handler with shiftKey=true + onSuggestionClick?.(suggestion, { ...e, shiftKey: true }) + }} + title={t("chat:followUpSuggest.copyToInput")}> + +
))}
diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 537667e2ff..45e11cb734 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -207,6 +207,9 @@ "thinking": "Pensant", "seconds": "{{count}}s" }, + "followUpSuggest": { + "copyToInput": "Copiar a l'entrada (o Shift + clic)" + }, "announcement": { "title": "🎉 Roo Code 3.10 publicat", "description": "Roo Code 3.10 aporta potents millores de productivitat!", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index ab12622a0a..71b08f93df 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -207,6 +207,9 @@ "thinking": "Denke nach", "seconds": "{{count}}s" }, + "followUpSuggest": { + "copyToInput": "In Eingabefeld kopieren (oder Shift + Klick)" + }, "announcement": { "title": "🎉 Roo Code 3.10 veröffentlicht", "description": "Roo Code 3.10 bringt leistungsstarke Produktivitätsverbesserungen!", diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index c8ecead7eb..4fd2c83931 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -219,6 +219,9 @@ "thinking": "Thinking", "seconds": "{{count}}s" }, + "followUpSuggest": { + "copyToInput": "Copy to input (same as shift + click)" + }, "browser": { "rooWantsToUse": "Roo wants to use the browser:", "consoleLogs": "Console Logs", diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index e0fe258fb3..a4b34aeccc 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -207,6 +207,9 @@ "thinking": "Pensando", "seconds": "{{count}}s" }, + "followUpSuggest": { + "copyToInput": "Copiar a la entrada (o Shift + clic)" + }, "announcement": { "title": "🎉 Roo Code 3.10 publicado", "description": "¡Roo Code 3.10 trae potentes mejoras de productividad!", diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 237fa8ec88..f995d2c5b7 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -207,6 +207,9 @@ "thinking": "Réflexion", "seconds": "{{count}}s" }, + "followUpSuggest": { + "copyToInput": "Copier vers l'entrée (ou Shift + clic)" + }, "announcement": { "title": "🎉 Roo Code 3.10 est sortie", "description": "Roo Code 3.10 apporte de puissantes améliorations de productivité !", diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 821a644bd4..e92555e4e8 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -207,6 +207,9 @@ "thinking": "विचार कर रहा है", "seconds": "{{count}} सेकंड" }, + "followUpSuggest": { + "copyToInput": "इनपुट में कॉपी करें (या Shift + क्लिक)" + }, "announcement": { "title": "🎉 Roo Code 3.10 रिलीज़ हुआ", "description": "Roo Code 3.10 शक्तिशाली उत्पादकता सुधार लाता है!", diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index 00c0b76636..c80f27c756 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -207,6 +207,9 @@ "thinking": "Sto pensando", "seconds": "{{count}}s" }, + "followUpSuggest": { + "copyToInput": "Copia nell'input (o Shift + clic)" + }, "announcement": { "title": "🎉 Rilasciato Roo Code 3.10", "description": "Roo Code 3.10 porta potenti miglioramenti di produttività!", diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index cb211068b9..ec0bab308d 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -207,6 +207,9 @@ "thinking": "考え中", "seconds": "{{count}}秒" }, + "followUpSuggest": { + "copyToInput": "入力欄にコピー(またはShift + クリック)" + }, "announcement": { "title": "🎉 Roo Code 3.10 リリース", "description": "Roo Code 3.10は強力な生産性向上機能をもたらします!", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 669221e7d1..1632ae4859 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -207,6 +207,9 @@ "thinking": "생각 중", "seconds": "{{count}}초" }, + "followUpSuggest": { + "copyToInput": "입력창에 복사 (또는 Shift + 클릭)" + }, "announcement": { "title": "🎉 Roo Code 3.10 출시", "description": "Roo Code 3.10이 강력한 생산성 향상 기능을 제공합니다!", diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 2e996f3639..3171a44258 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -207,6 +207,9 @@ "thinking": "Myślenie", "seconds": "{{count}} s" }, + "followUpSuggest": { + "copyToInput": "Kopiuj do pola wprowadzania (lub Shift + kliknięcie)" + }, "announcement": { "title": "🎉 Roo Code 3.10 wydany", "description": "Roo Code 3.10 przynosi potężne usprawnienia produktywności!", diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index 0b0a903a0f..437939ad0c 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -207,6 +207,9 @@ "thinking": "Pensando", "seconds": "{{count}}s" }, + "followUpSuggest": { + "copyToInput": "Copiar para entrada (ou Shift + clique)" + }, "announcement": { "title": "🎉 Roo Code 3.10 Lançado", "description": "Roo Code 3.10 traz poderosas melhorias de produtividade!", diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 2f74eb031d..7d3541569c 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -207,6 +207,9 @@ "thinking": "Düşünüyor", "seconds": "{{count}}sn" }, + "followUpSuggest": { + "copyToInput": "Giriş alanına kopyala (veya Shift + tıklama)" + }, "announcement": { "title": "🎉 Roo Code 3.10 Yayınlandı", "description": "Roo Code 3.10 güçlü üretkenlik iyileştirmeleri getiriyor!", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index da642cc64d..bcbe4e4efb 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -207,6 +207,9 @@ "thinking": "Đang suy nghĩ", "seconds": "{{count}} giây" }, + "followUpSuggest": { + "copyToInput": "Sao chép vào ô nhập liệu (hoặc Shift + nhấp chuột)" + }, "announcement": { "title": "🎉 Roo Code 3.10 Đã phát hành", "description": "Roo Code 3.10 mang đến những cải tiến năng suất mạnh mẽ!", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index eb86f94529..ccde65e402 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -207,6 +207,9 @@ "thinking": "思考中", "seconds": "{{count}}秒" }, + "followUpSuggest": { + "copyToInput": "复制到输入框(或按住Shift点击)" + }, "announcement": { "title": "🎉 Roo Code 3.10 已发布", "description": "Roo Code 3.10带来强大的生产力提升!", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 13c1e81745..8bf7b33f21 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -207,6 +207,9 @@ "thinking": "思考中", "seconds": "{{count}}秒" }, + "followUpSuggest": { + "copyToInput": "複製到輸入框(或按住Shift點擊)" + }, "announcement": { "title": "🎉 Roo Code 3.10 已發布", "description": "Roo Code 3.10帶來強大的生產力提升!",