From 889a050f25b5f14e102b3bce38b844eb16f23719 Mon Sep 17 00:00:00 2001 From: jang_yoonsu Date: Thu, 16 May 2024 23:23:06 +0900 Subject: [PATCH 1/4] feat : add copy button component --- frontend/src/components/CopyButton.tsx | 45 ++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 frontend/src/components/CopyButton.tsx diff --git a/frontend/src/components/CopyButton.tsx b/frontend/src/components/CopyButton.tsx new file mode 100644 index 00000000..e28fdcaf --- /dev/null +++ b/frontend/src/components/CopyButton.tsx @@ -0,0 +1,45 @@ +import { useState } from 'react'; +import Copy from './../assets/copy.svg?react'; +import CheckMark from './../assets/checkmark.svg?react'; +import copy from 'copy-to-clipboard'; + +export default function CoppyButton({ text }: { text: string }) { + const [copied, setCopied] = useState(false); + const [isCopyHovered, setIsCopyHovered] = useState(false); + + const handleCopyClick = (text: string) => { + copy(text); + setCopied(true); + // Reset copied to false after a few seconds + setTimeout(() => { + setCopied(false); + }, 3000); + }; + + return ( +
+ {copied ? ( + setIsCopyHovered(true)} + onMouseLeave={() => setIsCopyHovered(false)} + /> + ) : ( + { + handleCopyClick(text); + }} + onMouseEnter={() => setIsCopyHovered(true)} + onMouseLeave={() => setIsCopyHovered(false)} + /> + )} +
+ ); +} From 3767d14e5c445a1f004f3a6761efebb604192772 Mon Sep 17 00:00:00 2001 From: jang_yoonsu Date: Thu, 16 May 2024 23:23:46 +0900 Subject: [PATCH 2/4] feat: add copy button in code snippet --- .../src/conversation/ConversationBubble.tsx | 82 +++++++------------ 1 file changed, 28 insertions(+), 54 deletions(-) diff --git a/frontend/src/conversation/ConversationBubble.tsx b/frontend/src/conversation/ConversationBubble.tsx index bce831f7..c0f6cd70 100644 --- a/frontend/src/conversation/ConversationBubble.tsx +++ b/frontend/src/conversation/ConversationBubble.tsx @@ -1,15 +1,14 @@ import { forwardRef, useState } from 'react'; import Avatar from '../components/Avatar'; +import CoppyButton from '../components/CopyButton'; import remarkGfm from 'remark-gfm'; import { FEEDBACK, MESSAGE_TYPE } from './conversationModels'; import classes from './ConversationBubble.module.css'; import Alert from './../assets/alert.svg'; import Like from './../assets/like.svg?react'; import Dislike from './../assets/dislike.svg?react'; -import Copy from './../assets/copy.svg?react'; -import CheckMark from './../assets/checkmark.svg?react'; + import ReactMarkdown from 'react-markdown'; -import copy from 'copy-to-clipboard'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism'; import DocsGPT3 from '../assets/cute_docsgpt3.svg'; @@ -30,29 +29,19 @@ const ConversationBubble = forwardRef< ref, ) { const [openSource, setOpenSource] = useState(null); - const [copied, setCopied] = useState(false); - const handleCopyClick = (text: string) => { - copy(text); - setCopied(true); - // Reset copied to false after a few seconds - setTimeout(() => { - setCopied(false); - }, 3000); - }; - const [isCopyHovered, setIsCopyHovered] = useState(false); const [isLikeHovered, setIsLikeHovered] = useState(false); const [isDislikeHovered, setIsDislikeHovered] = useState(false); const [isLikeClicked, setIsLikeClicked] = useState(false); const [isDislikeClicked, setIsDislikeClicked] = useState(false); let bubble; - + if (type === 'QUESTION') { bubble = (
-
+
{message} @@ -94,19 +83,28 @@ const ConversationBubble = forwardRef< code({ node, inline, className, children, ...props }) { const match = /language-(\w+)/.exec(className || ''); - return !inline && match ? ( - - {String(children).replace(/\n$/, '')} - - ) : ( - - {children} - + return ( +
+ {!inline && match ? ( + + {String(children).replace(/\n$/, '')} + + ) : ( + + {children} + + )} +
+ +
+
); }, ul({ children }) { @@ -172,7 +170,7 @@ const ConversationBubble = forwardRef< {sources?.map((source, index) => (
-
- {copied ? ( - setIsCopyHovered(true)} - onMouseLeave={() => setIsCopyHovered(false)} - /> - ) : ( - { - handleCopyClick(message); - }} - onMouseEnter={() => setIsCopyHovered(true)} - onMouseLeave={() => setIsCopyHovered(false)} - > - )} -
+
Date: Thu, 16 May 2024 23:29:33 +0900 Subject: [PATCH 3/4] design : add style invisible when lg and visible when hover --- frontend/src/conversation/ConversationBubble.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/conversation/ConversationBubble.tsx b/frontend/src/conversation/ConversationBubble.tsx index c0f6cd70..db26d55d 100644 --- a/frontend/src/conversation/ConversationBubble.tsx +++ b/frontend/src/conversation/ConversationBubble.tsx @@ -99,7 +99,10 @@ const ConversationBubble = forwardRef< {children} )} -
+
From 149ca0102930ddea224877ac81682304ae7b3324 Mon Sep 17 00:00:00 2001 From: jang_yoonsu Date: Sat, 18 May 2024 20:43:13 +0900 Subject: [PATCH 4/4] fix : Add group property to code block parent element and add copy button condition --- .../src/conversation/ConversationBubble.tsx | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/frontend/src/conversation/ConversationBubble.tsx b/frontend/src/conversation/ConversationBubble.tsx index db26d55d..9877db66 100644 --- a/frontend/src/conversation/ConversationBubble.tsx +++ b/frontend/src/conversation/ConversationBubble.tsx @@ -83,22 +83,16 @@ const ConversationBubble = forwardRef< code({ node, inline, className, children, ...props }) { const match = /language-(\w+)/.exec(className || ''); - return ( -
- {!inline && match ? ( - - {String(children).replace(/\n$/, '')} - - ) : ( - - {children} - - )} + return !inline && match ? ( +
+ + {String(children).replace(/\n$/, '')} +
+ ) : ( + + {children} + ); }, ul({ children }) {