diff --git a/src/locales/de/translation.json b/src/locales/de/translation.json index 47c9223a..af574970 100644 --- a/src/locales/de/translation.json +++ b/src/locales/de/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Link-URL kopieren", "edit": "Bearbeiten", "editDescription": "Das Bearbeiten dieser Nachricht erzeugt eine neue Antwort", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Abbrechen", "save": "Speichern", "toolCalls": "🛠 {{name}} Werkzeugaufruf-Ergebnis", diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 305ccfe4..2224ecfb 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Copy link URL", "edit": "Edit", "editDescription": "Editing this message will generate a new response", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Cancel", "save": "Save", "toolCalls": "🛠 {{name}} Tool Call Result", diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index 130a2728..fa37cd38 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Copiar URL del enlace", "edit": "Editar", "editDescription": "Editar este mensaje generará una nueva respuesta", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Cancelar", "save": "Guardar", "toolCalls": "🛠 Resultado de la llamada a la herramienta {{name}}", diff --git a/src/locales/fi/translation.json b/src/locales/fi/translation.json index 65f68463..dd310481 100644 --- a/src/locales/fi/translation.json +++ b/src/locales/fi/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Kopioi linkin URL", "edit": "Muokkaa", "editDescription": "Tämän viestin muokkaaminen luo uuden vastauksen", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Peruuta", "save": "Tallenna", "toolCalls": "🛠 {{name}} työkalukutsun tulos", diff --git a/src/locales/fil/translation.json b/src/locales/fil/translation.json index 0d1e530f..ab6174e1 100644 --- a/src/locales/fil/translation.json +++ b/src/locales/fil/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Kopyahin ang URL ng link", "edit": "I-edit", "editDescription": "Ang pag-edit ng mensaheng ito ay bubuo ng bagong tugon", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Kanselahin", "save": "I-save", "toolCalls": "🛠 {{name}} Resulta ng Tool Call", diff --git a/src/locales/fr/translation.json b/src/locales/fr/translation.json index 3a1f0101..30920ad5 100644 --- a/src/locales/fr/translation.json +++ b/src/locales/fr/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Copier l'URL du lien", "edit": "Modifier", "editDescription": "La modification de ce message générera une nouvelle réponse", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Annuler", "save": "Enregistrer", "toolCalls": "🛠 Résultat de l'appel d'outil {{name}}", diff --git a/src/locales/id/translation.json b/src/locales/id/translation.json index 8dfa7d85..aea43bed 100644 --- a/src/locales/id/translation.json +++ b/src/locales/id/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Salin URL tautan", "edit": "Edit", "editDescription": "Mengedit pesan ini akan menghasilkan respons baru", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Batal", "save": "Simpan", "toolCalls": "🛠 Hasil Panggilan Alat {{name}}", diff --git a/src/locales/it/translation.json b/src/locales/it/translation.json index 97fc86d8..bfd2593f 100644 --- a/src/locales/it/translation.json +++ b/src/locales/it/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Copia URL del collegamento", "edit": "Modifica", "editDescription": "La modifica di questo messaggio genererà una nuova risposta", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Annulla", "save": "Salva", "toolCalls": "🛠 Risultato chiamata strumento {{name}}", diff --git a/src/locales/ja/translation.json b/src/locales/ja/translation.json index f952c678..cc688dda 100644 --- a/src/locales/ja/translation.json +++ b/src/locales/ja/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "リンクのURLをコピー", "edit": "編集", "editDescription": "このメッセージを編集すると、新しい応答が生成されます", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "キャンセル", "save": "保存", "toolCalls": "🛠 {{name}} ツール呼び出し結果", diff --git a/src/locales/ko/translation.json b/src/locales/ko/translation.json index afeeb45e..e3f55997 100644 --- a/src/locales/ko/translation.json +++ b/src/locales/ko/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "링크 URL 복사", "edit": "편집", "editDescription": "이 메시지를 수정하면 새 응답이 생성됩니다", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "취소", "save": "저장", "toolCalls": "🛠 {{name}} 도구 호출 결과", diff --git a/src/locales/lo/translation.json b/src/locales/lo/translation.json index cc5ef68b..a9c2c8e1 100644 --- a/src/locales/lo/translation.json +++ b/src/locales/lo/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "ສຳເນົາ URL ລິງ", "edit": "ແກ້ໄຂ", "editDescription": "ການແກ້ໄຂຂໍ້ຄວາມນີ້ຈະສ້າງຄຳຕອບໃໝ່", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "ຍົກເລີກ", "save": "ບັນທຶກ", "toolCalls": "🛠 ຜົນການເອີ້ນໃຊ້ເຄື່ອງມື {{name}}", diff --git a/src/locales/no/translation.json b/src/locales/no/translation.json index 98bee7e3..b949cc42 100644 --- a/src/locales/no/translation.json +++ b/src/locales/no/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Kopier lenke-URL", "edit": "Rediger", "editDescription": "Å redigere denne meldingen vil generere et nytt svar", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Avbryt", "save": "Lagre", "toolCalls": "🛠 {{name}} Verktøyanrop resultat", diff --git a/src/locales/pl/translation.json b/src/locales/pl/translation.json index 587e168e..78249e9d 100644 --- a/src/locales/pl/translation.json +++ b/src/locales/pl/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Kopiuj adres URL linku", "edit": "Edytuj", "editDescription": "Edycja tej wiadomości wygeneruje nową odpowiedź", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Anuluj", "save": "Zapisz", "toolCalls": "🛠 Wynik wywołania narzędzia {{name}}", diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json index 5808196e..087e4e66 100644 --- a/src/locales/pt/translation.json +++ b/src/locales/pt/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Copiar URL do link", "edit": "Editar", "editDescription": "Editar esta mensagem gerará uma nova resposta", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Cancelar", "save": "Salvar", "toolCalls": "🛠 Resultado da Chamada da Ferramenta {{name}}", diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index 11d57f7e..3e477fb0 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Скопировать URL ссылки", "edit": "Редактировать", "editDescription": "Редактирование этого сообщения создаст новый ответ", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Отменить", "save": "Сохранить", "toolCalls": "🛠 Результат вызова инструмента {{name}}", diff --git a/src/locales/sv/translation.json b/src/locales/sv/translation.json index 9a0fe536..37b82e72 100644 --- a/src/locales/sv/translation.json +++ b/src/locales/sv/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Kopiera länk-URL", "edit": "Redigera", "editDescription": "Att redigera detta meddelande kommer att generera ett nytt svar", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Avbryt", "save": "Spara", "toolCalls": "🛠 {{name}} Verktygsanrop resultat", diff --git a/src/locales/th/translation.json b/src/locales/th/translation.json index faa6a614..13c16820 100644 --- a/src/locales/th/translation.json +++ b/src/locales/th/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "คัดลอก URL ลิงก์", "edit": "แก้ไข", "editDescription": "การแก้ไขข้อความนี้จะสร้างคำตอบใหม่", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "ยกเลิก", "save": "บันทึก", "toolCalls": "🛠 ผลลัพธ์การเรียกเครื่องมือ {{name}}", diff --git a/src/locales/tr/translation.json b/src/locales/tr/translation.json index 0eb69bd0..0e5d32a8 100644 --- a/src/locales/tr/translation.json +++ b/src/locales/tr/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Bağlantı URL'sini kopyala", "edit": "Düzenle", "editDescription": "Bu mesajı düzenlemek yeni bir yanıt oluşturacak", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "İptal", "save": "Kaydet", "toolCalls": "🛠 {{name}} Araç Çağrısı Sonucu", diff --git a/src/locales/uk/translation.json b/src/locales/uk/translation.json index 338bb2e4..07bb54fb 100644 --- a/src/locales/uk/translation.json +++ b/src/locales/uk/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Копіювати URL посилання", "edit": "Редагувати", "editDescription": "Редагування цього повідомлення створить нову відповідь", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Скасувати", "save": "Зберегти", "toolCalls": "🛠 Результат виклику інструмента {{name}}", diff --git a/src/locales/vi/translation.json b/src/locales/vi/translation.json index 8c9782b7..ac1f05cc 100644 --- a/src/locales/vi/translation.json +++ b/src/locales/vi/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "Sao chép URL liên kết", "edit": "Chỉnh sửa", "editDescription": "Chỉnh sửa tin nhắn này sẽ tạo phản hồi mới", + "deleteMessage": "Delete", + "confirmDeleteMessage": "Delete Message", + "confirmDeleteMessageDescription": "This will delete the message and its response. This action cannot be undone.", + "deleteMessageSuccess": "Message deleted", + "deleteMessageFailed": "Failed to delete message", "cancel": "Hủy", "save": "Lưu", "toolCalls": "🛠 Kết quả gọi công cụ {{name}}", diff --git a/src/locales/zh-CN/translation.json b/src/locales/zh-CN/translation.json index c34f1941..aa50b6db 100644 --- a/src/locales/zh-CN/translation.json +++ b/src/locales/zh-CN/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "复制链接网址", "edit": "编辑", "editDescription": "编辑此消息将会重新生成一个新的回应", + "deleteMessage": "删除", + "confirmDeleteMessage": "删除消息", + "confirmDeleteMessageDescription": "此操作将删除该消息及其回应,且无法撤销。", + "deleteMessageSuccess": "消息已删除", + "deleteMessageFailed": "删除消息失败", "cancel": "取消", "save": "保存", "toolCalls": "🛠 调用 {{name}} 工具结果", diff --git a/src/locales/zh-TW/translation.json b/src/locales/zh-TW/translation.json index a40c0719..8868a8a5 100644 --- a/src/locales/zh-TW/translation.json +++ b/src/locales/zh-TW/translation.json @@ -41,6 +41,11 @@ "copyLinkUrl": "複製連結網址", "edit": "編輯", "editDescription": "編輯此訊息將會重新生成一個新的回應", + "deleteMessage": "刪除", + "confirmDeleteMessage": "刪除訊息", + "confirmDeleteMessageDescription": "此操作將刪除該訊息及其回應,且無法復原。", + "deleteMessageSuccess": "訊息已刪除", + "deleteMessageFailed": "刪除訊息失敗", "cancel": "取消", "save": "儲存", "toolCalls": "🛠 呼叫 {{name}} 工具結果", diff --git a/src/views/Chat/ChatMessages.tsx b/src/views/Chat/ChatMessages.tsx index 6d206cf4..c1c0df53 100644 --- a/src/views/Chat/ChatMessages.tsx +++ b/src/views/Chat/ChatMessages.tsx @@ -23,6 +23,7 @@ interface Props { isLoadingMessages?: boolean onRetry: (messageId: string) => void onEdit: (messageId: string, newText: string) => void + onDelete: (messageId: string) => void activeToolCalls?: Map } @@ -31,7 +32,7 @@ export interface ChatMessagesRef { scrollToMessage: (messageId: string) => void } -const ChatMessages = forwardRef(({ messages, isLoading, isLoadingMessages, onRetry, onEdit, activeToolCalls }, ref) => { +const ChatMessages = forwardRef(({ messages, isLoading, isLoadingMessages, onRetry, onEdit, onDelete, activeToolCalls }, ref) => { const messagesEndRef = useRef(null) const [showScrollButton, setShowScrollButton] = useState(false) const mouseWheelRef = useRef(false) @@ -224,6 +225,7 @@ const ChatMessages = forwardRef(({ messages, isLoading, messageId={message.id} onRetry={() => onRetry(message.id)} onEdit={(newText: string) => onEdit(message.id, newText)} + onDelete={() => onDelete(message.id)} resourceUsage={message.resourceUsage} /> diff --git a/src/views/Chat/Message.tsx b/src/views/Chat/Message.tsx index 81ecba5f..e3a84cca 100644 --- a/src/views/Chat/Message.tsx +++ b/src/views/Chat/Message.tsx @@ -68,9 +68,10 @@ interface MessageProps { resourceUsage?: ResourceUsage onRetry: () => void onEdit: (editedText: string) => void + onDelete: () => void } -const Message = ({ messageId, text, isSent, files, isError, isLoading, isRateLimitExceeded, onRetry, onEdit, resourceUsage }: MessageProps) => { +const Message = ({ messageId, text, isSent, files, isError, isLoading, isRateLimitExceeded, onRetry, onEdit, onDelete, resourceUsage }: MessageProps) => { const { t } = useTranslation() const [theme] = useAtom(themeAtom) const updateStreamingCode = useSetAtom(codeStreamingAtom) @@ -642,6 +643,23 @@ const Message = ({ messageId, text, isSent, files, isError, isLoading, isRateLim {t("chat.edit")} + : <> diff --git a/src/views/Chat/index.tsx b/src/views/Chat/index.tsx index c715db79..e80dc6c5 100644 --- a/src/views/Chat/index.tsx +++ b/src/views/Chat/index.tsx @@ -90,6 +90,7 @@ const ChatWindow = () => { const [isLoadingChat, setIsLoadingChat] = useAtom(isLoadingChatAtom) const forceRestartMcpConfig = useSetAtom(forceRestartMcpConfigAtom) const [isLoading, setIsLoading] = useState(false) + const [deletingMessageId, setDeletingMessageId] = useState(null) const addElicitationRequest = useSetAtom(addElicitationRequestAtom) const loadTools = useSetAtom(loadToolsAtom) @@ -525,6 +526,45 @@ const ChatWindow = () => { handlePost(body, "formData", "/api/chat/edit", targetChatId) }, [isChatStreaming, currentChatIdRef.current, updateMessagesForChat, setChatStreamingStatus, scrollToMessage]) + const onDelete = useCallback((messageId: string) => { + if (isChatStreaming || !currentChatIdRef.current) + return + setDeletingMessageId(messageId) + }, [isChatStreaming]) + + const confirmDelete = useCallback(async () => { + if (!deletingMessageId || !currentChatIdRef.current) + return + + const targetChatId = currentChatIdRef.current + const messageId = deletingMessageId + setDeletingMessageId(null) + + try { + const response = await fetch(`/api/chat/${targetChatId}/messages/${messageId}`, { + method: "DELETE" + }) + + if (response.ok) { + updateMessagesForChat(targetChatId, prev => { + const messageIndex = prev.findIndex(msg => msg.id === messageId) + if (messageIndex === -1) + return prev + const newMessages = [...prev] + // Remove the user message and the next LLM message (if exists) + const removeCount = (messageIndex + 1 < newMessages.length && !newMessages[messageIndex + 1].isSent) ? 2 : 1 + newMessages.splice(messageIndex, removeCount) + return newMessages + }) + showToast({ message: t("chat.deleteMessageSuccess"), type: "success" }) + } else { + showToast({ message: t("chat.deleteMessageFailed"), type: "error" }) + } + } catch { + showToast({ message: t("chat.deleteMessageFailed"), type: "error" }) + } + }, [deletingMessageId, updateMessagesForChat, showToast, t]) + const handlePost = useCallback(async (body: any, type: "json" | "formData", url: string, initialChatId: string) => { // Use a ref to track the current chatId (may change when chat_info is received) let targetChatId = initialChatId @@ -971,6 +1011,7 @@ const ChatWindow = () => { isLoadingMessages={isLoadingChat} onRetry={onRetry} onEdit={onEdit} + onDelete={onDelete} /> { /> + {deletingMessageId && ( + setDeletingMessageId(null)} + > +

{t("chat.confirmDeleteMessageDescription")}

+
+ )} {showAuthorizePopup && currentTool && (