49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
|
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||
|
|
import { useFileUpload } from "./useFileUpload";
|
||
|
|
import { getSoundFileURL } from "../utils/utils";
|
||
|
|
|
||
|
|
export function useCachedSoundSrc(selected: string | undefined, fallbackUrl: string) {
|
||
|
|
const isUploaded = !!selected && (selected.endsWith(".mp3") || selected.endsWith(".wav"));
|
||
|
|
const fileName = isUploaded ? selected : undefined;
|
||
|
|
|
||
|
|
const { query } = useFileUpload({
|
||
|
|
queryKey: fileName ? [fileName] : undefined,
|
||
|
|
});
|
||
|
|
|
||
|
|
const [objectUrl, setObjectUrl] = useState<string>();
|
||
|
|
const objRef = useRef<string | null>(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,
|
||
|
|
};
|
||
|
|
}
|