diff --git a/manifest.config.ts b/manifest.config.ts index fdeb55b9..fa5e22d7 100644 --- a/manifest.config.ts +++ b/manifest.config.ts @@ -41,6 +41,7 @@ export default defineManifest(async (env) => ({ 'contextMenus', 'tabs', 'activeTab', + 'clipboardWrite', ], background: { service_worker: 'src/pages/background/index.ts', diff --git a/src/components/Sidebar/chat/ChatList.tsx b/src/components/Sidebar/chat/ChatList.tsx index 9b6b7462..c24a03ec 100644 --- a/src/components/Sidebar/chat/ChatList.tsx +++ b/src/components/Sidebar/chat/ChatList.tsx @@ -1,5 +1,10 @@ import { useEffect, useRef } from 'react' -import { RiCloseLine, RiErrorWarningLine, RiLoader4Line } from 'react-icons/ri' +import { + RiCloseLine, + RiErrorWarningLine, + RiLoader4Line, + RiFileCopyLine, +} from 'react-icons/ri' import { ReactMarkdown } from 'react-markdown/lib/react-markdown' import rehypeRaw from 'rehype-raw' import remarkBreaks from 'remark-breaks' @@ -33,6 +38,20 @@ const ChatList = ({ const filteredMsgs = messages.filter((msg) => msg.role !== ChatRole.SYSTEM) + const formatContent = (content: string) => { + return content.replace(/(?<=\n\n)(?![*-])\n/gi, ' \n ') + } + + const handleCopyMessage = (content: string) => { + window.parent.postMessage( + { + action: 'copy-to-clipboard', + _payload: { content }, + }, + '*', + ) + } + return (
)} + {msg.role === ChatRole.ASSISTANT && ( + + )} - {msg.content.replace(/(?<=\n\n)(?![*-])\n/gi, ' \n ')} + {formatContent(msg.content)} {msg.files && }
diff --git a/src/pages/content/sidebar.tsx b/src/pages/content/sidebar.tsx index a976a79a..46a95b59 100644 --- a/src/pages/content/sidebar.tsx +++ b/src/pages/content/sidebar.tsx @@ -56,6 +56,14 @@ window.addEventListener('message', async (event) => { ) } + // ACTION: copy-to-clipboard ============================= + if (action === 'copy-to-clipboard') { + const { content } = _payload as { content: string } + navigator.clipboard.writeText(content).catch((err) => { + console.error('Clipboard write failed', err) + }) + } + // ACTION: get-screenshot-image =========================== if (action === 'get-screenshot-image') { iframe.style.width = '0px'