diff --git a/website/public/locales/en/common.json b/website/public/locales/en/common.json index c83f4f01aa..306158504f 100644 --- a/website/public/locales/en/common.json +++ b/website/public/locales/en/common.json @@ -11,6 +11,7 @@ "connect": "Connect", "conversational": "Conversational AI for everyone.", "copied": "Copied", + "copy": "Copy", "create_chat": "Create a new chat", "dark_mode": "Dark Mode", "dashboard": "Dashboard", diff --git a/website/src/components/Chat/ChatMessageEntry.tsx b/website/src/components/Chat/ChatMessageEntry.tsx index 0a290dc9a4..129d67009f 100644 --- a/website/src/components/Chat/ChatMessageEntry.tsx +++ b/website/src/components/Chat/ChatMessageEntry.tsx @@ -7,10 +7,11 @@ import { Text, Textarea, useBoolean, + useClipboard, useColorModeValue, useOutsideClick, } from "@chakra-ui/react"; -import { Check, Edit, RotateCcw, ThumbsUp, X, XCircle } from "lucide-react"; +import { Check, Copy, Edit, RotateCcw, ThumbsUp, X, XCircle } from "lucide-react"; import { ThumbsDown } from "lucide-react"; import { useSession } from "next-auth/react"; import { useTranslation } from "next-i18next"; @@ -69,6 +70,7 @@ export const ChatMessageEntry = memo(function ChatMessageEntry({ onRetry({ parentId, chatId }); } }, [chatId, onRetry, parentId]); + const isAssistant = message.role === "assistant"; const [isEditing, setIsEditing] = useBoolean(false); const inputRef = useRef(null); @@ -99,6 +101,8 @@ export const ChatMessageEntry = memo(function ChatMessageEntry({ [handleEditSubmit, setIsEditing] ); + const { onCopy, hasCopied } = useClipboard(message.content); + return ( {!isAssistant && parentId !== null && ( @@ -145,7 +149,12 @@ export const ChatMessageEntry = memo(function ChatMessageEntry({ )} {state === "complete" && ( <> - {canRetry && } + {canRetry && } + {!hasCopied ? ( + + ) : ( + + )} diff --git a/website/src/components/Messages/MessageEmojiButton.tsx b/website/src/components/Messages/MessageEmojiButton.tsx index 6191ada9c5..59e53988ce 100644 --- a/website/src/components/Messages/MessageEmojiButton.tsx +++ b/website/src/components/Messages/MessageEmojiButton.tsx @@ -1,4 +1,4 @@ -import { Button, ButtonProps, useColorModeValue } from "@chakra-ui/react"; +import { Button, ButtonProps, Tooltip, useColorModeValue } from "@chakra-ui/react"; import { ElementType, PropsWithChildren } from "react"; import { useHasAnyRole } from "src/hooks/auth/useHasAnyRole"; import { MessageEmoji } from "src/types/Conversation"; @@ -47,6 +47,7 @@ type BaseMessageEmojiButtonProps = PropsWithChildren<{ onClick?: () => void; isDisabled?: boolean; sx?: ButtonProps["sx"]; + label?: string; }>; export const BaseMessageEmojiButton = ({ @@ -56,10 +57,10 @@ export const BaseMessageEmojiButton = ({ isDisabled, sx, children, + label, }: BaseMessageEmojiButtonProps) => { const disabledColor = useColorModeValue("gray.500", "gray.400"); - - return ( + const button = (