diff --git a/web-app/package.json b/web-app/package.json index 4874b310c..7069fb910 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -45,6 +45,7 @@ "fzf": "^0.5.2", "i18next": "^25.0.1", "katex": "^0.16.22", + "lodash.clonedeep": "^4.5.0", "lodash.debounce": "^4.0.8", "lucide-react": "^0.522.0", "motion": "^12.10.5", @@ -77,6 +78,7 @@ "@eslint/js": "^9.22.0", "@tanstack/router-plugin": "^1.116.1", "@types/culori": "^2.1.1", + "@types/lodash.clonedeep": "^4", "@types/lodash.debounce": "^4", "@types/node": "^22.14.1", "@types/react": "^19.0.10", diff --git a/web-app/src/containers/ThreadContent.tsx b/web-app/src/containers/ThreadContent.tsx index 80a864c67..69f4402fd 100644 --- a/web-app/src/containers/ThreadContent.tsx +++ b/web-app/src/containers/ThreadContent.tsx @@ -26,7 +26,6 @@ import { } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Textarea } from '@/components/ui/textarea' -import { toast } from 'sonner' import { Tooltip, TooltipContent, @@ -75,6 +74,69 @@ const CopyButton = ({ text }: { text: string }) => { ) } +const EditDialog = ({ + message, + setMessage, +}: { + message: string + setMessage: (message: string) => void +}) => { + const { t } = useTranslation() + const [draft, setDraft] = useState(message) + + const handleSave = () => { + if (draft !== message) { + setMessage(draft) + } + } + + return ( + + ) +} + // Use memo to prevent unnecessary re-renders, but allow re-renders when props change export const ThreadContent = memo( ( @@ -85,9 +147,9 @@ export const ThreadContent = memo( // eslint-disable-next-line @typescript-eslint/no-explicit-any streamTools?: any contextOverflowModal?: React.ReactNode | null + updateMessage?: (item: ThreadMessage, message: string) => void } ) => { - const [message, setMessage] = useState(item.content?.[0]?.text?.value || '') const { t } = useTranslation() // Use useMemo to stabilize the components prop @@ -166,23 +228,6 @@ export const ThreadContent = memo( } }, [deleteMessage, getMessages, item]) - const editMessage = useCallback( - (messageId: string) => { - const threadMessages = getMessages(item.thread_id) - - const index = threadMessages.findIndex((msg) => msg.id === messageId) - if (index === -1) return - - // Delete all messages after the edited message - for (let i = threadMessages.length - 1; i >= index; i--) { - deleteMessage(threadMessages[i].thread_id, threadMessages[i].id) - } - - sendMessage(message) - }, - [deleteMessage, getMessages, item.thread_id, message, sendMessage] - ) - const isToolCalls = item.metadata && 'tool_calls' in item.metadata && @@ -209,61 +254,14 @@ export const ThreadContent = memo(