mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-02 22:01:05 +02:00
fix: add AbortController to fetch call in audio download
Abort in-flight download when the component unmounts or a new download starts, preventing wasted bandwidth on navigation. Closes #919
This commit is contained in:
parent
c41e79860f
commit
a3b3852452
1 changed files with 12 additions and 1 deletions
|
|
@ -27,6 +27,7 @@ function formatTime(seconds: number): string {
|
||||||
|
|
||||||
export function Audio({ id, src, title, description, artwork, durationMs, className }: AudioProps) {
|
export function Audio({ id, src, title, description, artwork, durationMs, className }: AudioProps) {
|
||||||
const audioRef = useRef<HTMLAudioElement>(null);
|
const audioRef = useRef<HTMLAudioElement>(null);
|
||||||
|
const downloadControllerRef = useRef<AbortController | null>(null);
|
||||||
const [isPlaying, setIsPlaying] = useState(false);
|
const [isPlaying, setIsPlaying] = useState(false);
|
||||||
const [currentTime, setCurrentTime] = useState(0);
|
const [currentTime, setCurrentTime] = useState(0);
|
||||||
const [duration, setDuration] = useState(durationMs ? durationMs / 1000 : 0);
|
const [duration, setDuration] = useState(durationMs ? durationMs / 1000 : 0);
|
||||||
|
|
@ -84,8 +85,12 @@ export function Audio({ id, src, title, description, artwork, durationMs, classN
|
||||||
|
|
||||||
// Handle download
|
// Handle download
|
||||||
const handleDownload = useCallback(async () => {
|
const handleDownload = useCallback(async () => {
|
||||||
|
downloadControllerRef.current?.abort();
|
||||||
|
const controller = new AbortController();
|
||||||
|
downloadControllerRef.current = controller;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(src);
|
const response = await fetch(src, { signal: controller.signal });
|
||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
const url = window.URL.createObjectURL(blob);
|
const url = window.URL.createObjectURL(blob);
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
|
|
@ -96,10 +101,16 @@ export function Audio({ id, src, title, description, artwork, durationMs, classN
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
window.URL.revokeObjectURL(url);
|
window.URL.revokeObjectURL(url);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (err instanceof DOMException && err.name === "AbortError") return;
|
||||||
console.error("Error downloading audio:", err);
|
console.error("Error downloading audio:", err);
|
||||||
}
|
}
|
||||||
}, [src, title]);
|
}, [src, title]);
|
||||||
|
|
||||||
|
// Abort in-flight download on unmount
|
||||||
|
useEffect(() => {
|
||||||
|
return () => downloadControllerRef.current?.abort();
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Set up audio event listeners
|
// Set up audio event listeners
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const audio = audioRef.current;
|
const audio = audioRef.current;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue