Files
superwork/vscode/webview-ui/src/codeReader/useRepoImages.ts
T

52 lines
1.7 KiB
TypeScript

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<HTMLElement>('.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<HTMLElement>('.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])
}