import { useEffect, useState } from 'react'; import { ipcChannels } from '../../../shared/ipc/contracts'; import type { TokenId } from '../../../shared/types'; import { getDndApi } from '../dndApi'; const cache = new Map(); export function useTokenImageUrl(tokenId: TokenId | null | undefined): string | null { const api = getDndApi(); const [url, setUrl] = useState(() => tokenId ? (cache.get(tokenId) ?? null) : null, ); useEffect(() => { if (!tokenId) { setUrl(null); return; } const cached = cache.get(tokenId); if (cached !== undefined) { setUrl(cached); return; } let cancelled = false; void api.invoke(ipcChannels.tokens.imageUrl, { id: tokenId }).then(({ url: next }) => { cache.set(tokenId, next); if (!cancelled) setUrl(next); }); return () => { cancelled = true; }; }, [api, tokenId]); useEffect(() => { return api.on(ipcChannels.tokens.stateChanged, ({ tokens }) => { for (const t of tokens) { cache.delete(t.id); } if (tokenId) { void api.invoke(ipcChannels.tokens.imageUrl, { id: tokenId }).then(({ url: next }) => { cache.set(tokenId, next); setUrl(next); }); } }); }, [api, tokenId]); return url; }