feat: close #680 lazy load markdown dom

This commit is contained in:
Yidadaa 2023-04-12 23:27:28 +08:00
parent 9146b98285
commit d790b0b372
3 changed files with 59 additions and 43 deletions

View File

@ -672,22 +672,18 @@ export function Chat(props: {
</div> </div>
</div> </div>
)} )}
{(message.preview || message.content.length === 0) && <Markdown
!isUser ? ( content={message.content}
<LoadingIcon /> loading={
) : ( (message.preview || message.content.length === 0) &&
<div !isUser
className="markdown-body" }
style={{ fontSize: `${fontSize}px` }} onContextMenu={(e) => onRightClick(e, message)}
onContextMenu={(e) => onRightClick(e, message)} onDoubleClickCapture={() => {
onDoubleClickCapture={() => { if (!isMobileScreen()) return;
if (!isMobileScreen()) return; setUserInput(message.content);
setUserInput(message.content); }}
}} />
>
<Markdown content={message.content} />
</div>
)}
</div> </div>
{!isUser && !message.preview && ( {!isUser && !message.preview && (
<div className={styles["chat-message-actions"]}> <div className={styles["chat-message-actions"]}>

View File

@ -8,6 +8,8 @@ import RehypeHighlight from "rehype-highlight";
import { useRef, useState, RefObject, useEffect } from "react"; import { useRef, useState, RefObject, useEffect } from "react";
import { copyToClipboard } from "../utils"; import { copyToClipboard } from "../utils";
import LoadingIcon from "../icons/three-dots.svg";
export function PreCode(props: { children: any }) { export function PreCode(props: { children: any }) {
const ref = useRef<HTMLPreElement>(null); const ref = useRef<HTMLPreElement>(null);
@ -50,26 +52,47 @@ const useLazyLoad = (ref: RefObject<Element>): boolean => {
return isIntersecting; return isIntersecting;
}; };
export function Markdown(props: { content: string }) { export function Markdown(
props: {
content: string;
loading?: boolean;
fontSize?: number;
} & React.DOMAttributes<HTMLDivElement>,
) {
const mdRef = useRef(null);
const shouldRender = useLazyLoad(mdRef);
const shouldLoading = props.loading || !shouldRender;
return ( return (
<ReactMarkdown <div
remarkPlugins={[RemarkMath, RemarkGfm, RemarkBreaks]} className="markdown-body"
rehypePlugins={[ style={{ fontSize: `${props.fontSize ?? 14}px` }}
RehypeKatex, {...props}
[ ref={mdRef}
RehypeHighlight,
{
detect: false,
ignoreMissing: true,
},
],
]}
components={{
pre: PreCode,
}}
linkTarget={"_blank"}
> >
{props.content} {shouldLoading ? (
</ReactMarkdown> <LoadingIcon />
) : (
<ReactMarkdown
remarkPlugins={[RemarkMath, RemarkGfm, RemarkBreaks]}
rehypePlugins={[
RehypeKatex,
[
RehypeHighlight,
{
detect: false,
ignoreMissing: true,
},
],
]}
components={{
pre: PreCode,
}}
linkTarget={"_blank"}
>
{props.content}
</ReactMarkdown>
)}
</div>
); );
} }

13
app/global.d.ts vendored
View File

@ -3,12 +3,9 @@ declare module "*.png";
declare module "*.woff2"; declare module "*.woff2";
declare module "*.woff"; declare module "*.woff";
declare module "*.ttf"; declare module "*.ttf";
declare module "*.scss"; declare module "*.scss" {
const content: Record<string, string>;
declare module "*.svg" { export default content;
import React = require("react");
export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
} }
declare module "*.svg";