diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index dd3d0d4c663..3079e83ffad 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -1,7 +1,7 @@ import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react" import { useEvent } from "react-use" import DynamicTextArea from "react-textarea-autosize" -import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX } from "lucide-react" +import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX, ListEnd, Square } from "lucide-react" import type { ExtensionMessage } from "@roo-code/types" @@ -55,6 +55,10 @@ interface ChatTextAreaProps { // Browser session status isBrowserSessionActive?: boolean showBrowserDockToggle?: boolean + // Stop/Queue functionality + isStreaming?: boolean + onStop?: () => void + onEnqueueMessage?: () => void } export const ChatTextArea = forwardRef( @@ -77,6 +81,9 @@ export const ChatTextArea = forwardRef( onCancel, isBrowserSessionActive = false, showBrowserDockToggle = false, + isStreaming = false, + onStop, + onEnqueueMessage, }, ref, ) => { @@ -1185,30 +1192,68 @@ export const ChatTextArea = forwardRef( )} - - - + "focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder", + "active:bg-[rgba(255,255,255,0.1)]", + "cursor-pointer", + )}> + + + + )} + {/* Send/Stop button - morphs based on streaming state */} + {!isEditMode && ( + + + + )} {!inputValue && ( diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 709218c935f..89c4209b96d 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -142,7 +142,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction(false) const [primaryButtonText, setPrimaryButtonText] = useState(undefined) const [secondaryButtonText, setSecondaryButtonText] = useState(undefined) - const [didClickCancel, setDidClickCancel] = useState(false) + const [_didClickCancel, setDidClickCancel] = useState(false) const virtuosoRef = useRef(null) const [expandedRows, setExpandedRows] = useState>({}) const prevExpandedRowsRef = useRef>() @@ -661,6 +661,26 @@ const ChatViewComponent: React.ForwardRefRenderFunction vscode.postMessage({ type: "clearTask" }), []) + // Handle stop button click from textarea + const handleStopTask = useCallback(() => { + vscode.postMessage({ type: "cancelTask" }) + setDidClickCancel(true) + }, [setDidClickCancel]) + + // Handle enqueue button click from textarea + const handleEnqueueCurrentMessage = useCallback(() => { + const text = inputValue.trim() + if (text || selectedImages.length > 0) { + vscode.postMessage({ + type: "queueMessage", + text, + images: selectedImages, + }) + setInputValue("") + setSelectedImages([]) + } + }, [inputValue, selectedImages]) + // This logic depends on the useEffect[messages] above to set clineAsk, // after which buttons are shown and we then send an askResponse to the // extension. @@ -733,6 +753,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction {showScrollToBottom ? ( @@ -1513,7 +1531,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction ) : ( <> - {primaryButtonText && !isStreaming && ( + {primaryButtonText && ( )} - {(secondaryButtonText || isStreaming) && ( + {secondaryButtonText && ( )} @@ -1612,6 +1630,9 @@ const ChatViewComponent: React.ForwardRefRenderFunction {isProfileDisabled && ( diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index b583cf40d3c..ce02f42ed2a 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -82,10 +82,15 @@ "title": "Finalitzar", "tooltip": "Finalitza la tasca actual" }, + "stop": { + "title": "Atura", + "tooltip": "Atura la tasca actual" + }, "cancel": { "title": "Cancel·lar", "tooltip": "Cancel·la l'operació actual" }, + "enqueueMessage": "Afegeix el missatge a la cua (s'enviarà quan acabi la tasca actual)", "scrollToBottom": "Desplaça't al final del xat", "about": "Roo Code és tot un equip de desenvolupament d'IA al teu editor.", "docs": "Consulta els nostres documents per a més informació.", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 8e1826905fd..9e2762472c5 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -82,10 +82,15 @@ "title": "Beenden", "tooltip": "Aktuelle Aufgabe beenden" }, + "stop": { + "title": "Stoppen", + "tooltip": "Aktuelle Aufgabe stoppen" + }, "cancel": { "title": "Abbrechen", "tooltip": "Aktuelle Operation abbrechen" }, + "enqueueMessage": "Nachricht zur Warteschlange hinzufügen (wird nach Abschluss der aktuellen Aufgabe gesendet)", "scrollToBottom": "Zum Chat-Ende scrollen", "about": "Roo Code ist ein ganzes KI-Entwicklerteam in deinem Editor.", "docs": "Schau in unsere Dokumentation, um mehr zu erfahren.", diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 53ecf74da3a..9ce1ea34318 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -54,13 +54,13 @@ "reservedForResponse": "Reserved for model response: {{amount}} tokens" }, "reject": { - "title": "Reject", - "tooltip": "Reject this action" + "title": "Deny", + "tooltip": "Prevent this action from occurring" }, "completeSubtaskAndReturn": "Complete Subtask and Return", "approve": { "title": "Approve", - "tooltip": "Approve this action" + "tooltip": "Allow this action to happen" }, "read-batch": { "approve": { @@ -75,25 +75,30 @@ "tooltip": "Execute this command" }, "proceedWhileRunning": { - "title": "Proceed While Running", - "tooltip": "Continue despite warnings" + "title": "Continue While Running", + "tooltip": "Keep going despite warnings" }, "killCommand": { "title": "Kill Command", "tooltip": "Kill the current command" }, "resumeTask": { - "title": "Resume Task", - "tooltip": "Continue the current task" + "title": "Continue", + "tooltip": "Resume the current task" }, "terminate": { - "title": "Terminate", - "tooltip": "End the current task" + "title": "New task", + "tooltip": "Start a new task" }, "cancel": { "title": "Cancel", "tooltip": "Cancel the current operation" }, + "stop": { + "title": "Stop", + "tooltip": "Stop the current task" + }, + "enqueueMessage": "Add message to queue (will be sent after current task completes)", "editMessage": { "placeholder": "Edit your message..." }, diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index b3d285a3596..72fc9aeda06 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -82,10 +82,15 @@ "title": "Terminar", "tooltip": "Terminar la tarea actual" }, + "stop": { + "title": "Detener", + "tooltip": "Detener la tarea actual" + }, "cancel": { "title": "Cancelar", "tooltip": "Cancelar la operación actual" }, + "enqueueMessage": "Agregar mensaje a la cola (se enviará después de que termine la tarea actual)", "scrollToBottom": "Desplazarse al final del chat", "about": "Roo Code es todo un equipo de desarrollo de IA en tu editor.", "docs": "Consulta nuestra documentación para saber más.", diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 1deda1e9c8f..f56242a7ccf 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -82,10 +82,15 @@ "title": "Terminer", "tooltip": "Terminer la tâche actuelle" }, + "stop": { + "title": "Arrêter", + "tooltip": "Arrêter la tâche en cours" + }, "cancel": { "title": "Annuler", "tooltip": "Annuler l'opération actuelle" }, + "enqueueMessage": "Ajouter le message à la file d'attente (sera envoyé après la fin de la tâche en cours)", "scrollToBottom": "Défiler jusqu'au bas du chat", "about": "Roo Code est une équipe complète de développeurs IA dans votre éditeur.", "docs": "Consultez notre documentation pour en savoir plus.", diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 66e51859872..65068e36954 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -82,10 +82,15 @@ "title": "समाप्त करें", "tooltip": "वर्तमान कार्य समाप्त करें" }, + "stop": { + "title": "रोकें", + "tooltip": "वर्तमान कार्य रोकें" + }, "cancel": { "title": "रद्द करें", "tooltip": "वर्तमान ऑपरेशन रद्द करें" }, + "enqueueMessage": "संदेश को कतार में जोड़ें (वर्तमान कार्य पूरा होने के बाद भेजा जाएगा)", "scrollToBottom": "चैट के निचले हिस्से तक स्क्रॉल करें", "about": "Roo Code आपके संपादक में एक पूरी AI देव टीम है।", "docs": "और जानने के लिए हमारे दस्तावेज़ देखें।", diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index da795acc3ef..b7aead85cca 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -96,10 +96,15 @@ "title": "Hentikan", "tooltip": "Akhiri tugas saat ini" }, + "stop": { + "title": "Stop", + "tooltip": "Hentikan tugas saat ini" + }, "cancel": { "title": "Batal", "tooltip": "Batalkan operasi saat ini" }, + "enqueueMessage": "Tambahkan pesan ke antrean (akan dikirim setelah tugas saat ini selesai)", "scrollToBottom": "Gulir ke bawah chat", "about": "Roo Code adalah seluruh tim pengembang AI di editor Anda.", "docs": "Lihat dokumentasi kami untuk mempelajari lebih lanjut.", diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index 9629c2a5ad7..4423de26926 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -82,10 +82,15 @@ "title": "Termina", "tooltip": "Termina l'attività corrente" }, + "stop": { + "title": "Ferma", + "tooltip": "Ferma l'attività corrente" + }, "cancel": { "title": "Annulla", "tooltip": "Annulla l'operazione corrente" }, + "enqueueMessage": "Aggiungi il messaggio alla coda (sarà inviato dopo che l'attività corrente sarà terminata)", "scrollToBottom": "Scorri fino alla fine della chat", "about": "Roo Code è un intero team di sviluppo AI nel tuo editor.", "docs": "Consulta la nostra documentazione per saperne di più.", diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index b9981828173..f5ee7ccc5e5 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -82,10 +82,15 @@ "title": "終了", "tooltip": "現在のタスクを終了" }, + "stop": { + "title": "停止", + "tooltip": "現在のタスクを停止" + }, "cancel": { "title": "キャンセル", "tooltip": "現在の操作をキャンセル" }, + "enqueueMessage": "メッセージをキューに追加(現在のタスク完了後に送信されます)", "scrollToBottom": "チャットの最下部にスクロール", "about": "Roo Codeは、エディタに常駐するAI開発チームです。", "docs": "詳細については、ドキュメントをご確認ください。", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 0121586b548..eb7f8fff5b0 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -82,10 +82,15 @@ "title": "종료", "tooltip": "현재 작업 종료" }, + "stop": { + "title": "정지", + "tooltip": "현재 작업 정지" + }, "cancel": { "title": "취소", "tooltip": "현재 작업 취소" }, + "enqueueMessage": "메시지를 대기열에 추가 (현재 작업 완료 후 전송)", "scrollToBottom": "채팅 하단으로 스크롤", "about": "Roo Code는 편집기 안에 있는 전체 AI 개발팀입니다.", "docs": "더 알아보려면 문서를 확인하세요.", diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index a2032aa3e33..12bede2117b 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -82,10 +82,15 @@ "title": "Beëindigen", "tooltip": "Beëindig de huidige taak" }, + "stop": { + "title": "Stoppen", + "tooltip": "Stop de huidige taak" + }, "cancel": { "title": "Annuleren", "tooltip": "Annuleer de huidige bewerking" }, + "enqueueMessage": "Bericht aan de wachtrij toevoegen (wordt verzonden nadat de huidige taak is voltooid)", "scrollToBottom": "Scroll naar onderaan de chat", "about": "Roo Code is een heel AI-ontwikkelteam in je editor.", "docs": "Bekijk onze documentatie voor meer informatie.", diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 5c4183a0ac0..fcdf20e81b3 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -82,10 +82,15 @@ "title": "Zakończ", "tooltip": "Zakończ bieżące zadanie" }, + "stop": { + "title": "Zatrzymaj", + "tooltip": "Zatrzymaj bieżące zadanie" + }, "cancel": { "title": "Anuluj", "tooltip": "Anuluj bieżącą operację" }, + "enqueueMessage": "Dodaj wiadomość do kolejki (zostanie wysłana po zakończeniu bieżącego zadania)", "scrollToBottom": "Przewiń do dołu czatu", "about": "Roo Code to cały zespół deweloperów AI w Twoim edytorze.", "docs": "Sprawdź naszą dokumentację, aby dowiedzieć się więcej.", diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index eb2df5e8fc2..22ea71e34fa 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -82,10 +82,15 @@ "title": "Terminar", "tooltip": "Encerrar a tarefa atual" }, + "stop": { + "title": "Parar", + "tooltip": "Parar a tarefa atual" + }, "cancel": { "title": "Cancelar", "tooltip": "Cancelar a operação atual" }, + "enqueueMessage": "Adicionar mensagem à fila (será enviada após a conclusão da tarefa atual)", "scrollToBottom": "Rolar para o final do chat", "about": "Roo Code é uma equipe inteira de desenvolvimento de IA em seu editor.", "docs": "Confira nossa documentação para saber mais.", diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 85a144f31e9..e982fe3f0fd 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -82,10 +82,15 @@ "title": "Завершить", "tooltip": "Завершить текущую задачу" }, + "stop": { + "title": "Остановить", + "tooltip": "Остановить текущую задачу" + }, "cancel": { "title": "Отмена", "tooltip": "Отменить текущую операцию" }, + "enqueueMessage": "Добавить сообщение в очередь (будет отправлено после завершения текущей задачи)", "scrollToBottom": "Прокрутить чат вниз", "about": "Roo Code — это целая команда разработчиков ИИ в вашем редакторе.", "docs": "Ознакомьтесь с нашей документацией, чтобы узнать больше.", diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 8bfeffea22b..72896b3fbdc 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -82,10 +82,15 @@ "title": "Sonlandır", "tooltip": "Mevcut görevi sonlandır" }, + "stop": { + "title": "Durdur", + "tooltip": "Mevcut görevi durdur" + }, "cancel": { "title": "İptal", "tooltip": "Mevcut işlemi iptal et" }, + "enqueueMessage": "Mesajı kuyruğa ekle (mevcut görev tamamlandıktan sonra gönderilecek)", "scrollToBottom": "Sohbetin altına kaydır", "about": "Roo Code, düzenleyicinizdeki bütün bir yapay zeka geliştirme ekibidir.", "docs": "Daha fazla bilgi için belgelerimize göz atın.", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index 76483e19d58..d31a1147f64 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -82,10 +82,15 @@ "title": "Kết thúc", "tooltip": "Kết thúc nhiệm vụ hiện tại" }, + "stop": { + "title": "Dừng", + "tooltip": "Dừng nhiệm vụ hiện tại" + }, "cancel": { "title": "Hủy", "tooltip": "Hủy thao tác hiện tại" }, + "enqueueMessage": "Thêm tin nhắn vào hàng đợi (sẽ gửi sau khi nhiệm vụ hiện tại hoàn tất)", "scrollToBottom": "Cuộn xuống cuối cuộc trò chuyện", "about": "Roo Code là một đội ngũ phát triển AI đầy đủ trong trình chỉnh sửa của bạn.", "docs": "Kiểm tra tài liệu của chúng tôi để tìm hiểu thêm.", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 26b874c2b0d..cea7eaf7207 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -86,6 +86,11 @@ "title": "取消", "tooltip": "取消当前操作" }, + "stop": { + "title": "停止", + "tooltip": "停止当前任务" + }, + "enqueueMessage": "将消息加入队列(当前任务完成后发送)", "scrollToBottom": "滚动到聊天底部", "about": "Roo Code 是您编辑器中的整个 AI 开发团队。", "docs": "查看我们的 文档 了解更多信息。", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 0449b84a7ae..9c47f6eb488 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -94,6 +94,11 @@ "title": "取消", "tooltip": "取消目前操作" }, + "stop": { + "title": "停止", + "tooltip": "停止目前的工作" + }, + "enqueueMessage": "將訊息加入佇列(會在目前工作完成後傳送)", "editMessage": { "placeholder": "編輯您的訊息..." },