forked from XiaoMo/ChatGPT-Next-Web
feat: close #680 lazy load markdown dom
This commit is contained in:
parent
9146b98285
commit
d790b0b372
@ -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"]}>
|
||||||
|
@ -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
13
app/global.d.ts
vendored
@ -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";
|
||||||
|
Loading…
Reference in New Issue
Block a user