"use client"; import { memo, useEffect, useRef } from "react"; type MessageHTMLProps = { html: string; className?: string; onImageSettled?: () => void; onImageClick?: (src: string, alt?: string) => void; }; function MessageHTMLComponent({ html, className = "", onImageSettled, onImageClick, }: MessageHTMLProps) { const containerRef = useRef(null); const onImageSettledRef = useRef(onImageSettled); const onImageClickRef = useRef(onImageClick); useEffect(() => { onImageSettledRef.current = onImageSettled; }, [onImageSettled]); useEffect(() => { onImageClickRef.current = onImageClick; }, [onImageClick]); useEffect(() => { const container = containerRef.current; if (!container) { return; } const images = Array.from(container.querySelectorAll("img")); if (images.length === 0) { return; } const cleanups = images.map((image) => { const handleSettled = () => onImageSettledRef.current?.(); const handleClick = () => { const src = image.getAttribute("src"); if (src) { const alt = image.getAttribute("alt") ?? undefined; onImageClickRef.current?.(src, alt); } }; image.addEventListener("load", handleSettled); image.addEventListener("error", handleSettled); image.addEventListener("click", handleClick); if (image.complete) { onImageSettledRef.current?.(); } image.classList.add("cursor-zoom-in"); return () => { image.removeEventListener("load", handleSettled); image.removeEventListener("error", handleSettled); image.removeEventListener("click", handleClick); }; }); return () => { cleanups.forEach((cleanup) => cleanup()); }; }, [html, onImageSettled, onImageClick]); return (
); } export const MessageHTML = memo( MessageHTMLComponent, (prevProps, nextProps) => prevProps.html === nextProps.html && prevProps.className === nextProps.className && prevProps.onImageSettled === nextProps.onImageSettled && prevProps.onImageClick === nextProps.onImageClick, );