import { useEffect, useMemo, useRef, useState } from "react"; import { useFileUpload } from "./useFileUpload"; import { getSoundFileURL } from "../utils/utils"; import type { SoundUploadValue } from "../types/types"; import { resolveSoundSource } from "../utils/soundResolver"; export function useCachedSoundSrc( selected: string | undefined, soundOptions: SoundUploadValue[] | undefined, fallbackUrl: string ) { const isUploaded = !!selected && (selected.endsWith(".mp3") || selected.endsWith(".wav")); const resolved = resolveSoundSource(selected, soundOptions); const { query } = useFileUpload({ queryKey: resolved?.type === "uploaded" ? [resolved?.url] : undefined, }); const [objectUrl, setObjectUrl] = useState(); const objRef = useRef(null); useEffect(() => { const blob = query?.data; if (blob instanceof Blob) { if (objRef.current) URL.revokeObjectURL(objRef.current); const url = URL.createObjectURL(blob); objRef.current = url; setObjectUrl(url); } else { if (objRef.current) URL.revokeObjectURL(objRef.current); objRef.current = null; setObjectUrl(undefined); } }, [query?.data]); useEffect(() => { return () => { if (objRef.current) URL.revokeObjectURL(objRef.current); }; }, []); const src = useMemo(() => { if (isUploaded && objectUrl) return objectUrl; if (!selected) return fallbackUrl; return getSoundFileURL(selected) ?? fallbackUrl; }, [isUploaded, objectUrl, selected, fallbackUrl]); return { src, isUploaded, isLoading: !!query?.isLoading, error: (query?.error as Error) || undefined, }; }