52 lines
1.7 KiB
TypeScript
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])
|
|
}
|