From 85df66265d3954fb0841a4ead8ffd183fc93a44c Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Thu, 22 Aug 2024 18:15:27 -0400 Subject: [PATCH] chore: revert markdown to original component + new artifacts rendering --- .../Chat/Messages/Content/Markdown.tsx | 183 +++++++----------- 1 file changed, 71 insertions(+), 112 deletions(-) diff --git a/client/src/components/Chat/Messages/Content/Markdown.tsx b/client/src/components/Chat/Messages/Content/Markdown.tsx index 2f7e5e87e1..a669ccd66e 100644 --- a/client/src/components/Chat/Messages/Content/Markdown.tsx +++ b/client/src/components/Chat/Messages/Content/Markdown.tsx @@ -1,10 +1,9 @@ -import React, { memo, RefObject, useMemo, useRef } from 'react'; +import React, { memo, useMemo } from 'react'; import remarkGfm from 'remark-gfm'; import remarkMath from 'remark-math'; import supersub from 'remark-supersub'; import rehypeKatex from 'rehype-katex'; import { useRecoilValue } from 'recoil'; -import { visit } from 'unist-util-visit'; import ReactMarkdown from 'react-markdown'; import rehypeHighlight from 'rehype-highlight'; import remarkDirective from 'remark-directive'; @@ -14,7 +13,6 @@ import { CodeBlockArtifact, CodeMarkdown } from '~/components/Artifacts/Code'; import { artifact, artifactPlugin } from '~/components/Artifacts/Artifact'; import CodeBlock from '~/components/Messages/Content/CodeBlock'; import { useFileDownload } from '~/data-provider'; -import { filenameMap } from '~/utils/artifacts'; import useLocalize from '~/hooks/useLocalize'; import { useToastContext } from '~/Providers'; import store from '~/store'; @@ -23,14 +21,9 @@ type TCodeProps = { inline: boolean; className?: string; children: React.ReactNode; - isLatestMessage: boolean; - showCursor?: boolean; - artifactId: string; - codeBlocksRef: RefObject; }; -export const code: React.ElementType = memo(({ inline, className, children, ...props }: TCodeProps) => { - const codeArtifacts = useRecoilValue(store.codeArtifacts); +export const code: React.ElementType = memo(({ inline, className, children }: TCodeProps) => { const match = /language-(\w+)/.exec(className ?? ''); const lang = match && match[1]; @@ -40,104 +33,83 @@ export const code: React.ElementType = memo(({ inline, className, children, ...p {children} ); + } else { + return ; } - - const codeString = Array.isArray(children) ? children.join('') : children; - console.log('code lang, children, props', lang, children, props); - const isNonArtifact = filenameMap[lang ?? ''] === undefined; - - if (codeArtifacts && typeof codeString === 'string' && isNonArtifact) { - return ; - } else if (codeArtifacts && typeof codeString === 'string') { - return ; - } - - return ; }); -export const a: React.ElementType = memo(({ href, children }: { href: string; children: React.ReactNode }) => { - const user = useRecoilValue(store.user); - const { showToast } = useToastContext(); - const localize = useLocalize(); +export const a: React.ElementType = memo( + ({ href, children }: { href: string; children: React.ReactNode }) => { + const user = useRecoilValue(store.user); + const { showToast } = useToastContext(); + const localize = useLocalize(); - const { file_id, filename, filepath } = useMemo(() => { - const pattern = new RegExp(`(?:files|outputs)/${user?.id}/([^\\s]+)`); - const match = href.match(pattern); - if (match && match[0]) { - const path = match[0]; - const parts = path.split('/'); - const name = parts.pop(); - const file_id = parts.pop(); - return { file_id, filename: name, filepath: path }; + const { file_id, filename, filepath } = useMemo(() => { + const pattern = new RegExp(`(?:files|outputs)/${user?.id}/([^\\s]+)`); + const match = href.match(pattern); + if (match && match[0]) { + const path = match[0]; + const parts = path.split('/'); + const name = parts.pop(); + const file_id = parts.pop(); + return { file_id, filename: name, filepath: path }; + } + return { file_id: '', filename: '', filepath: '' }; + }, [user?.id, href]); + + const { refetch: downloadFile } = useFileDownload(user?.id ?? '', file_id); + const props: { target?: string; onClick?: React.MouseEventHandler } = { target: '_new' }; + + if (!file_id || !filename) { + return ( + + {children} + + ); } - return { file_id: '', filename: '', filepath: '' }; - }, [user?.id, href]); - const { refetch: downloadFile } = useFileDownload(user?.id ?? '', file_id); - const props: { target?: string; onClick?: React.MouseEventHandler } = { target: '_new' }; + const handleDownload = async (event: React.MouseEvent) => { + event.preventDefault(); + try { + const stream = await downloadFile(); + if (stream.data == null || stream.data === '') { + console.error('Error downloading file: No data found'); + showToast({ + status: 'error', + message: localize('com_ui_download_error'), + }); + return; + } + const link = document.createElement('a'); + link.href = stream.data; + link.setAttribute('download', filename); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(stream.data); + } catch (error) { + console.error('Error downloading file:', error); + } + }; + + props.onClick = handleDownload; + props.target = '_blank'; - if (!file_id || !filename) { return ( - + {children} ); - } - - const handleDownload = async (event: React.MouseEvent) => { - event.preventDefault(); - try { - const stream = await downloadFile(); - if (!stream.data) { - console.error('Error downloading file: No data found'); - showToast({ - status: 'error', - message: localize('com_ui_download_error'), - }); - return; - } - const link = document.createElement('a'); - link.href = stream.data; - link.setAttribute('download', filename); - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - window.URL.revokeObjectURL(stream.data); - } catch (error) { - console.error('Error downloading file:', error); - } - }; - - props.onClick = handleDownload; - props.target = '_blank'; - - return ( - - {children} - - ); -}); + }, +); export const p: React.ElementType = memo(({ children }: { children: React.ReactNode }) => { return

{children}

; }); -export const div: React.ElementType = memo(({ node, ...props }) => { - if (props.className === 'artifact') { - return ( -
-

{props['data-identifier']}

-

Type: {props['data-type']}

- {props.children} -
- ); - } - return
; -}); - const cursor = ' '; type TContentProps = { @@ -150,7 +122,6 @@ const Markdown = memo(({ content = '', showCursor, isLatestMessage }: TContentPr const artifactIdRef = useRef(null); const codeBlocksRef = useRef(null); const LaTeXParsing = useRecoilValue(store.LaTeXParsing); - const codeArtifacts = useRecoilValue(store.codeArtifacts); const isInitializing = content === ''; @@ -160,25 +131,7 @@ const Markdown = memo(({ content = '', showCursor, isLatestMessage }: TContentPr currentContent = LaTeXParsing ? preprocessLaTeX(currentContent) : currentContent; } - if (artifactIdRef.current === null) { - artifactIdRef.current = new Date().toISOString(); - } - - const codePlugin: Pluggable = () => { - return (tree) => { - visit(tree, { tagName: 'code' }, (node) => { - node.properties = { - ...node.properties, - isLatestMessage, - showCursor, - artifactId: artifactIdRef.current, - codeBlocksRef: codeBlocksRef.current, - }; - }); - }; - }; - - const rehypePlugins: PluggableList = codeArtifacts ? [[rehypeKatex, { output: 'mathml' }], [codePlugin], [rehypeRaw]] : [ + const rehypePlugins = [ [rehypeKatex, { output: 'mathml' }], [ rehypeHighlight, @@ -203,10 +156,14 @@ const Markdown = memo(({ content = '', showCursor, isLatestMessage }: TContentPr return (