diff --git a/components/files/files-list.js b/components/files/files-list.js index 66ffd8f..82791ee 100644 --- a/components/files/files-list.js +++ b/components/files/files-list.js @@ -1,4 +1,4 @@ -import {useState, useEffect} from 'react' +import {useState, useEffect, useRef} from 'react' import PropTypes from 'prop-types' import List from '@mui/material/List' import ListSubheader from '@mui/material/ListSubheader' @@ -54,6 +54,7 @@ export default function FilesList({files}) { const {mode} = useColorScheme() const [audioMeta, setAudioMeta] = useState(audioMetaCache) const [downloading, setDownloading] = useState({}) + const controllersRef = useRef({}) const musicFiles = files.filter(file => file.mime.startsWith('audio')) const pdfFiles = files.filter(file => file.mime === 'application/pdf') @@ -149,13 +150,20 @@ export default function FilesList({files}) { ) } + useEffect(() => () => { + Object.values(controllersRef.current).forEach(c => c.abort()) + }, []) + const handleClick = async (e, url, fileName, fileId) => { e.stopPropagation() if (fileId in downloading) return + const controller = new AbortController() + controllersRef.current[fileId] = controller + setDownloading(prev => ({...prev, [fileId]: 0})) try { - const response = await fetch(url) + const response = await fetch(url, {signal: controller.signal}) const contentLength = +response.headers.get('content-length') const reader = response.body.getReader() const chunks = [] @@ -178,7 +186,10 @@ export default function FilesList({files}) { a.download = fileName a.click() URL.revokeObjectURL(blobUrl) + } catch (error) { + if (error.name !== 'AbortError') throw error } finally { + delete controllersRef.current[fileId] setDownloading(prev => { const next = {...prev} delete next[fileId] @@ -187,6 +198,11 @@ export default function FilesList({files}) { } } + const handleCancel = (e, fileId) => { + e.stopPropagation() + controllersRef.current[fileId]?.abort() + } + return ( <> {musicFiles.length > 0 && ( @@ -232,9 +248,18 @@ export default function FilesList({files}) { variant={downloading[file.id] > 0 ? 'determinate' : 'indeterminate'} value={downloading[file.id]} /> - - {downloading[file.id]} % - + + + {downloading[file.id]} % + + handleCancel(e, file.id)} + > + Annuler + + )}