({
fileId,
filePath,
projectId,
ttlMs = 6000,
}: {
fileId?: string | null
filePath?: string | null
projectId?: string | null
ttlMs?: number
})
| 27 | } |
| 28 | |
| 29 | export function useFileDiffOverlay({ |
| 30 | fileId, |
| 31 | filePath, |
| 32 | projectId, |
| 33 | ttlMs = 6000, |
| 34 | }: { |
| 35 | fileId?: string | null |
| 36 | filePath?: string | null |
| 37 | projectId?: string | null |
| 38 | ttlMs?: number |
| 39 | }) { |
| 40 | const [diffEvent, setDiffEvent] = React.useState<FileDiffEventDetail | null>(null) |
| 41 | |
| 42 | React.useEffect(() => { |
| 43 | const handler = (event: Event) => { |
| 44 | const detail = (event as CustomEvent<FileDiffEventDetail>).detail |
| 45 | if (!detail?.diff) return |
| 46 | if (!matchesTarget(detail, { fileId: fileId || undefined, filePath: filePath || undefined, projectId: projectId || undefined })) { |
| 47 | return |
| 48 | } |
| 49 | setDiffEvent({ ...detail }) |
| 50 | } |
| 51 | |
| 52 | window.addEventListener('ds:file:diff', handler as EventListener) |
| 53 | return () => window.removeEventListener('ds:file:diff', handler as EventListener) |
| 54 | }, [fileId, filePath, projectId]) |
| 55 | |
| 56 | React.useEffect(() => { |
| 57 | const handler = () => { |
| 58 | if (!diffEvent) return |
| 59 | setDiffEvent(null) |
| 60 | } |
| 61 | window.addEventListener('ds:tool:call', handler as EventListener) |
| 62 | return () => window.removeEventListener('ds:tool:call', handler as EventListener) |
| 63 | }, [diffEvent]) |
| 64 | |
| 65 | React.useEffect(() => { |
| 66 | if (!diffEvent) return |
| 67 | const timer = window.setTimeout(() => setDiffEvent(null), ttlMs) |
| 68 | return () => window.clearTimeout(timer) |
| 69 | }, [diffEvent, ttlMs]) |
| 70 | |
| 71 | return { |
| 72 | diffEvent, |
| 73 | clearDiff: () => setDiffEvent(null), |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | export default useFileDiffOverlay |
no test coverage detected