From d7f83e294b7a72902d5131bf4e4a736ad7ee265a Mon Sep 17 00:00:00 2001 From: xuzuodong Date: Wed, 25 Sep 2024 18:19:05 +0800 Subject: [PATCH 1/4] style: svg preview --- web/app/components/base/svg-gallery/index.tsx | 13 ++++++------- .../components/workflow/panel/chat-record/index.tsx | 6 ++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/web/app/components/base/svg-gallery/index.tsx b/web/app/components/base/svg-gallery/index.tsx index 81e8e876550097..a1d46e24313320 100644 --- a/web/app/components/base/svg-gallery/index.tsx +++ b/web/app/components/base/svg-gallery/index.tsx @@ -29,7 +29,7 @@ export const SVGRenderer = ({ content }: { content: string }) => { if (svgRef.current) { try { svgRef.current.innerHTML = '' - const draw = SVG().addTo(svgRef.current).size('100%', '100%') + const draw = SVG().addTo(svgRef.current) const parser = new DOMParser() const svgDoc = parser.parseFromString(content, 'image/svg+xml') @@ -40,13 +40,9 @@ export const SVGRenderer = ({ content }: { content: string }) => { const originalWidth = parseInt(svgElement.getAttribute('width') || '400', 10) const originalHeight = parseInt(svgElement.getAttribute('height') || '600', 10) - const scale = Math.min(windowSize.width / originalWidth, windowSize.height / originalHeight, 1) - const scaledWidth = originalWidth * scale - const scaledHeight = originalHeight * scale - draw.size(scaledWidth, scaledHeight) + draw.viewbox(0, 0, originalWidth, originalHeight) const rootElement = draw.svg(content) - rootElement.scale(scale) rootElement.click(() => { setImagePreview(svgToDataURL(svgElement as Element)) @@ -54,7 +50,7 @@ export const SVGRenderer = ({ content }: { content: string }) => { } catch (error) { if (svgRef.current) - svgRef.current.innerHTML = 'Error rendering SVG. Wait for the image content to complete.' + svgRef.current.innerHTML = 'Error rendering SVG. Wait for the image content to complete.' } } }, [content, windowSize]) @@ -64,12 +60,15 @@ export const SVGRenderer = ({ content }: { content: string }) => {
{imagePreview && ( setImagePreview('')} />)} diff --git a/web/app/components/workflow/panel/chat-record/index.tsx b/web/app/components/workflow/panel/chat-record/index.tsx index 1bcfd6474d7c88..16d2c304a73c5e 100644 --- a/web/app/components/workflow/panel/chat-record/index.tsx +++ b/web/app/components/workflow/panel/chat-record/index.tsx @@ -90,7 +90,7 @@ const ChatRecord = () => { return (
{ supportCitationHitInfo: true, } as any} chatList={chatList} - chatContainerClassName='px-4' + chatContainerClassName='px-3' chatContainerInnerClassName='pt-6 w-full max-w-full mx-auto' chatFooterClassName='px-4 rounded-b-2xl' chatFooterInnerClassName='pb-4 w-full max-w-full mx-auto' @@ -129,6 +129,8 @@ const ChatRecord = () => { noChatInput allToolIcons={{}} showPromptLog + noSpacing + chatAnswerContainerInner='!pr-2' />
From 18a76112d92a15f083565de32796d81063d748b0 Mon Sep 17 00:00:00 2001 From: xuzuodong Date: Thu, 26 Sep 2024 14:57:10 +0800 Subject: [PATCH 2/4] update SVGRenderer style --- web/app/components/base/svg-gallery/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/web/app/components/base/svg-gallery/index.tsx b/web/app/components/base/svg-gallery/index.tsx index a1d46e24313320..4368df00e9d38d 100644 --- a/web/app/components/base/svg-gallery/index.tsx +++ b/web/app/components/base/svg-gallery/index.tsx @@ -42,6 +42,8 @@ export const SVGRenderer = ({ content }: { content: string }) => { const originalHeight = parseInt(svgElement.getAttribute('height') || '600', 10) draw.viewbox(0, 0, originalWidth, originalHeight) + svgRef.current.style.width = `${Math.min(originalWidth, 298)}px` + const rootElement = draw.svg(content) rootElement.click(() => { @@ -58,10 +60,6 @@ export const SVGRenderer = ({ content }: { content: string }) => { return ( <>
{ cursor: 'pointer', wordBreak: 'break-word', whiteSpace: 'normal', + margin: '0 auto', }} /> {imagePreview && ( setImagePreview('')} />)} From 70bd2201b369f397239ac0c47865570b6d2ce3f6 Mon Sep 17 00:00:00 2001 From: xuzuodong Date: Thu, 26 Sep 2024 15:24:14 +0800 Subject: [PATCH 3/4] chore: optimize CodeBlock component in markdown.tsx --- .../base/chat/chat/answer/index.tsx | 2 +- web/app/components/base/markdown.tsx | 115 ++++++++++-------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/web/app/components/base/chat/chat/answer/index.tsx b/web/app/components/base/chat/chat/answer/index.tsx index 705cd73ddf18d9..3957f5f9812a13 100644 --- a/web/app/components/base/chat/chat/answer/index.tsx +++ b/web/app/components/base/chat/chat/answer/index.tsx @@ -100,7 +100,7 @@ const Answer: FC = ({
{ !responding && ( diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index 443ee3410c4de4..104a98fd47a9ba 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -116,59 +116,78 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props } const match = /language-(\w+)/.exec(className || '') const language = match?.[1] const languageShowName = getCorrectCapitalizationLanguageName(language || '') - let chartData = JSON.parse(String('{"title":{"text":"ECharts error - Wrong JSON format."}}').replace(/\n$/, '')) - if (language === 'echarts') { - try { - chartData = JSON.parse(String(children).replace(/\n$/, '')) - } - catch (error) { + const chartData = useMemo(() => { + if (language === 'echarts') { + try { + return JSON.parse(String(children).replace(/\n$/, '')) + } + catch (error) {} } - } + return JSON.parse('{"title":{"text":"ECharts error - Wrong JSON format."}}') + }, [language, children]) - // Use `useMemo` to ensure that `SyntaxHighlighter` only re-renders when necessary - return useMemo(() => { - return (!inline && match) - ? ( -
-
{ + const content = String(children).replace(/\n$/, '') + switch (language) { + case 'mermaid': + return isSVG ? : null + case 'echarts': + return ( +
+ + + +
+ ) + case 'svg': + return ( + + + + ) + default: + return ( + -
{languageShowName}
-
- {language === 'mermaid' && } - -
-
- {(language === 'mermaid' && isSVG) - ? () - : (language === 'echarts' - ? (
) - : (language === 'svg' - ? () - : ( - {String(children).replace(/\n$/, '')} - )))} + {content} + + ) + } + }, [language, match, props, children, chartData, isSVG]) + + if (inline || !match) + return {children} + + return ( +
+
+
{languageShowName}
+
+ {language === 'mermaid' && } +
- ) - : ({children}) - }, [chartData, children, className, inline, isSVG, language, languageShowName, match, props]) +
+ {renderCodeContent} +
+ ) }) CodeBlock.displayName = 'CodeBlock' From b66f3dc78fb15235289cb79a4b85bbe640b821dc Mon Sep 17 00:00:00 2001 From: xuzuodong Date: Thu, 26 Sep 2024 16:15:10 +0800 Subject: [PATCH 4/4] update code --- .../base/chat/chat/answer/index.tsx | 15 ++++- web/app/components/base/markdown.tsx | 66 ++++++++++--------- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/web/app/components/base/chat/chat/answer/index.tsx b/web/app/components/base/chat/chat/answer/index.tsx index 3957f5f9812a13..8184967edc9820 100644 --- a/web/app/components/base/chat/chat/answer/index.tsx +++ b/web/app/components/base/chat/chat/answer/index.tsx @@ -85,6 +85,19 @@ const Answer: FC = ({ getContentWidth() }, [responding]) + // Recalculate contentWidth when content changes (e.g., SVG preview/source toggle) + useEffect(() => { + if (!containerRef.current) + return + const resizeObserver = new ResizeObserver(() => { + getContentWidth() + }) + resizeObserver.observe(containerRef.current) + return () => { + resizeObserver.disconnect() + } + }, []) + return (
@@ -100,7 +113,7 @@ const Answer: FC = ({
{ !responding && ( diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index 104a98fd47a9ba..39a399cc9f73c9 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -128,39 +128,41 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props } const renderCodeContent = useMemo(() => { const content = String(children).replace(/\n$/, '') - switch (language) { - case 'mermaid': - return isSVG ? : null - case 'echarts': - return ( -
- - - -
- ) - case 'svg': - return ( + if (language === 'mermaid' && isSVG) { + return + } + else if (language === 'echarts') { + return ( +
- + - ) - default: - return ( - - {content} - - ) +
+ ) + } + else if (language === 'svg' && isSVG) { + return ( + + + + ) + } + else { + return ( + + {content} + + ) } }, [language, match, props, children, chartData, isSVG]) @@ -177,7 +179,7 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props } >
{languageShowName}
- {language === 'mermaid' && } + {(['mermaid', 'svg']).includes(language!) && }