import { useEffect, useState } from 'react' import { repoImageInner, RepoImages } from './repoImage' import { onMessage, postMessage } from './vscode' /** 按已经问到的结果把占位换成图片或「找不到图片」。还没问到的保持路径文字。 */ function paint(images: RepoImages): void { for (const node of document.querySelectorAll('.cr-markdown .cr-repo-image')) { const path = node.dataset.path if (!path) continue const next = repoImageInner(path, node.dataset.alt ?? '', images.state(path)) if (node.dataset.shown === next) continue node.innerHTML = next node.dataset.shown = next } } /** * 注释、说明、问 AI 的回答里的仓库图片,走同一条:画出来之后把路径发去问在不在。 * 点图片打开原图靠里面的仓库链接,不另做点击。 */ export function useRepoImages(): void { const [images] = useState(() => new RepoImages(postMessage)) useEffect(() => { const off = onMessage((msg) => { if (msg.type !== 'repoImagesChecked') return if (images.checked(msg.id, msg.images)) paint(images) }) let timer = 0 const scan = (): void => { window.clearTimeout(timer) timer = window.setTimeout(() => { const nodes = [...document.querySelectorAll('.cr-markdown .cr-repo-image')] paint(images) images.scan(nodes.flatMap(node => node.dataset.path ? [node.dataset.path] : [])) }, 50) } const observer = new MutationObserver(scan) observer.observe(document.body, { childList: true, subtree: true }) scan() return () => { off() observer.disconnect() window.clearTimeout(timer) } }, [images]) }