forked from XiaoMo/ChatGPT-Next-Web
fix: #2055 should render mermaid completely
This commit is contained in:
parent
0a2cccfd6e
commit
3c38b9c93b
@ -11,19 +11,21 @@ import mermaid from "mermaid";
|
|||||||
|
|
||||||
import LoadingIcon from "../icons/three-dots.svg";
|
import LoadingIcon from "../icons/three-dots.svg";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useThrottledCallback } from "use-debounce";
|
import { useDebouncedCallback, useThrottledCallback } from "use-debounce";
|
||||||
|
|
||||||
export function Mermaid(props: { code: string; onError: () => void }) {
|
export function Mermaid(props: { code: string }) {
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const [hasError, setHasError] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.code && ref.current) {
|
if (props.code && ref.current) {
|
||||||
mermaid
|
mermaid
|
||||||
.run({
|
.run({
|
||||||
nodes: [ref.current],
|
nodes: [ref.current],
|
||||||
|
suppressErrors: true,
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
props.onError();
|
setHasError(true);
|
||||||
console.error("[Mermaid] ", e.message);
|
console.error("[Mermaid] ", e.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -42,10 +44,17 @@ export function Mermaid(props: { code: string; onError: () => void }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasError) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="no-dark"
|
className="no-dark mermaid"
|
||||||
style={{ cursor: "pointer", overflow: "auto" }}
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
overflow: "auto",
|
||||||
|
}}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
onClick={() => viewSvgInNewWindow()}
|
onClick={() => viewSvgInNewWindow()}
|
||||||
>
|
>
|
||||||
@ -56,33 +65,40 @@ export function Mermaid(props: { code: string; onError: () => void }) {
|
|||||||
|
|
||||||
export function PreCode(props: { children: any }) {
|
export function PreCode(props: { children: any }) {
|
||||||
const ref = useRef<HTMLPreElement>(null);
|
const ref = useRef<HTMLPreElement>(null);
|
||||||
|
const refText = ref.current?.innerText;
|
||||||
const [mermaidCode, setMermaidCode] = useState("");
|
const [mermaidCode, setMermaidCode] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
const renderMermaid = useDebouncedCallback(() => {
|
||||||
if (!ref.current) return;
|
if (!ref.current) return;
|
||||||
const mermaidDom = ref.current.querySelector("code.language-mermaid");
|
const mermaidDom = ref.current.querySelector("code.language-mermaid");
|
||||||
if (mermaidDom) {
|
if (mermaidDom) {
|
||||||
setMermaidCode((mermaidDom as HTMLElement).innerText);
|
setMermaidCode((mermaidDom as HTMLElement).innerText);
|
||||||
}
|
}
|
||||||
}, [props.children]);
|
}, 600);
|
||||||
|
|
||||||
if (mermaidCode) {
|
useEffect(() => {
|
||||||
return <Mermaid code={mermaidCode} onError={() => setMermaidCode("")} />;
|
setTimeout(renderMermaid, 1);
|
||||||
}
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [refText]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<pre ref={ref}>
|
<>
|
||||||
<span
|
{mermaidCode.length > 0 && (
|
||||||
className="copy-code-button"
|
<Mermaid code={mermaidCode} key={mermaidCode} />
|
||||||
onClick={() => {
|
)}
|
||||||
if (ref.current) {
|
<pre ref={ref}>
|
||||||
const code = ref.current.innerText;
|
<span
|
||||||
copyToClipboard(code);
|
className="copy-code-button"
|
||||||
}
|
onClick={() => {
|
||||||
}}
|
if (ref.current) {
|
||||||
></span>
|
const code = ref.current.innerText;
|
||||||
{props.children}
|
copyToClipboard(code);
|
||||||
</pre>
|
}
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
{props.children}
|
||||||
|
</pre>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1117,3 +1117,15 @@
|
|||||||
.markdown-body ::-webkit-calendar-picker-indicator {
|
.markdown-body ::-webkit-calendar-picker-indicator {
|
||||||
filter: invert(50%);
|
filter: invert(50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.markdown-body .mermaid {
|
||||||
|
border: var(--border-in-light);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
#dmermaid {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user