Skip to content

Commit

Permalink
Add "Copy Message" function into a Chat. (#2986)
Browse files Browse the repository at this point in the history
As title says.
Resolves #2515

---------

Co-authored-by: notmd <[email protected]>
  • Loading branch information
echo0x22 and notmd authored May 1, 2023
1 parent deffd4e commit 590e317
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
1 change: 1 addition & 0 deletions website/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 11 additions & 2 deletions website/src/components/Chat/ChatMessageEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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<HTMLTextAreaElement>(null);
Expand Down Expand Up @@ -99,6 +101,8 @@ export const ChatMessageEntry = memo(function ChatMessageEntry({
[handleEditSubmit, setIsEditing]
);

const { onCopy, hasCopied } = useClipboard(message.content);

return (
<PendingMessageEntry ref={ref} {...props} isAssistant={isAssistant} content={isEditing ? "" : content!}>
{!isAssistant && parentId !== null && (
Expand Down Expand Up @@ -145,7 +149,12 @@ export const ChatMessageEntry = memo(function ChatMessageEntry({
)}
{state === "complete" && (
<>
{canRetry && <BaseMessageEmojiButton emoji={RotateCcw} onClick={handleRetry} />}
{canRetry && <BaseMessageEmojiButton emoji={RotateCcw} onClick={handleRetry} label={t("retry")} />}
{!hasCopied ? (
<BaseMessageEmojiButton emoji={Copy} onClick={onCopy} label={t("copy")} />
) : (
<BaseMessageEmojiButton emoji={Check} />
)}
<BaseMessageEmojiButton emoji={ThumbsUp} checked={score === 1} onClick={handleThumbsUp} />
<BaseMessageEmojiButton emoji={ThumbsDown} checked={score === -1} onClick={handleThumbsDown} />
</>
Expand Down
17 changes: 14 additions & 3 deletions website/src/components/Messages/MessageEmojiButton.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -47,6 +47,7 @@ type BaseMessageEmojiButtonProps = PropsWithChildren<{
onClick?: () => void;
isDisabled?: boolean;
sx?: ButtonProps["sx"];
label?: string;
}>;

export const BaseMessageEmojiButton = ({
Expand All @@ -56,10 +57,10 @@ export const BaseMessageEmojiButton = ({
isDisabled,
sx,
children,
label,
}: BaseMessageEmojiButtonProps) => {
const disabledColor = useColorModeValue("gray.500", "gray.400");

return (
const button = (
<Button
onClick={onClick}
variant={checked ? "solid" : "ghost"}
Expand All @@ -81,4 +82,14 @@ export const BaseMessageEmojiButton = ({
{children}
</Button>
);

if (!label) {
return button;
}

return (
<Tooltip label={label} placement="top">
{button}
</Tooltip>
);
};

0 comments on commit 590e317

Please sign in to comment.