mirror of
https://github.com/Yidadaa/ChatGPT-Next-Web.git
synced 2025-08-09 00:15:38 +08:00
feat: close #2545 improve lazy load message list
This commit is contained in:
@@ -146,70 +146,23 @@ export function Markdown(
|
||||
} & React.DOMAttributes<HTMLDivElement>,
|
||||
) {
|
||||
const mdRef = useRef<HTMLDivElement>(null);
|
||||
const renderedHeight = useRef(0);
|
||||
const renderedWidth = useRef(0);
|
||||
const inView = useRef(!!props.defaultShow);
|
||||
const [_, triggerRender] = useState(0);
|
||||
const checkInView = useThrottledCallback(
|
||||
() => {
|
||||
const parent = props.parentRef?.current;
|
||||
const md = mdRef.current;
|
||||
if (parent && md && !props.defaultShow) {
|
||||
const parentBounds = parent.getBoundingClientRect();
|
||||
const twoScreenHeight = Math.max(500, parentBounds.height * 2);
|
||||
const mdBounds = md.getBoundingClientRect();
|
||||
const parentTop = parentBounds.top - twoScreenHeight;
|
||||
const parentBottom = parentBounds.bottom + twoScreenHeight;
|
||||
const isOverlap =
|
||||
Math.max(parentTop, mdBounds.top) <=
|
||||
Math.min(parentBottom, mdBounds.bottom);
|
||||
inView.current = isOverlap;
|
||||
triggerRender(Date.now());
|
||||
}
|
||||
|
||||
if (inView.current && md) {
|
||||
const rect = md.getBoundingClientRect();
|
||||
renderedHeight.current = Math.max(renderedHeight.current, rect.height);
|
||||
renderedWidth.current = Math.max(renderedWidth.current, rect.width);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
},
|
||||
300,
|
||||
{
|
||||
leading: true,
|
||||
trailing: true,
|
||||
},
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
props.parentRef?.current?.addEventListener("scroll", checkInView);
|
||||
checkInView();
|
||||
return () =>
|
||||
props.parentRef?.current?.removeEventListener("scroll", checkInView);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const getSize = (x: number) => (!inView.current && x > 0 ? x : "auto");
|
||||
|
||||
return (
|
||||
<div
|
||||
className="markdown-body"
|
||||
style={{
|
||||
fontSize: `${props.fontSize ?? 14}px`,
|
||||
height: getSize(renderedHeight.current),
|
||||
width: getSize(renderedWidth.current),
|
||||
direction: /[\u0600-\u06FF]/.test(props.content) ? "rtl" : "ltr",
|
||||
}}
|
||||
ref={mdRef}
|
||||
onContextMenu={props.onContextMenu}
|
||||
onDoubleClickCapture={props.onDoubleClickCapture}
|
||||
>
|
||||
{inView.current &&
|
||||
(props.loading ? (
|
||||
<LoadingIcon />
|
||||
) : (
|
||||
<MarkdownContent content={props.content} />
|
||||
))}
|
||||
{props.loading ? (
|
||||
<LoadingIcon />
|
||||
) : (
|
||||
<MarkdownContent content={props.content} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user