From 76409f79e075f03fa521d8b0363ce025f97b898f Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 16 Feb 2026 19:20:14 -0700 Subject: [PATCH] Add copy button --- web/public/locales/en/common.json | 1 + web/src/components/chat/ChatMessage.tsx | 49 ++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/web/public/locales/en/common.json b/web/public/locales/en/common.json index 7b3d48eb9..691cff5f3 100644 --- a/web/public/locales/en/common.json +++ b/web/public/locales/en/common.json @@ -127,6 +127,7 @@ "cancel": "Cancel", "close": "Close", "copy": "Copy", + "copiedToClipboard": "Copied to clipboard", "back": "Back", "history": "History", "fullscreen": "Fullscreen", diff --git a/web/src/components/chat/ChatMessage.tsx b/web/src/components/chat/ChatMessage.tsx index 48117221f..3e87a495e 100644 --- a/web/src/components/chat/ChatMessage.tsx +++ b/web/src/components/chat/ChatMessage.tsx @@ -1,4 +1,14 @@ import ReactMarkdown from "react-markdown"; +import { useTranslation } from "react-i18next"; +import copy from "copy-to-clipboard"; +import { toast } from "sonner"; +import { FaCopy } from "react-icons/fa"; +import { Button } from "@/components/ui/button"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; type MessageBubbleProps = { @@ -7,18 +17,47 @@ type MessageBubbleProps = { }; export function MessageBubble({ role, content }: MessageBubbleProps) { + const { t } = useTranslation(["views/chat", "common"]); const isUser = role === "user"; + const handleCopy = () => { + const text = content?.trim() || ""; + if (!text) return; + if (copy(text)) { + toast.success(t("button.copiedToClipboard", { ns: "common" })); + } + }; + return (
- {isUser ? content : {content}} +
+ {isUser ? content : {content}} +
+ + + + + {t("button.copy", { ns: "common" })} +
); }