feat: improve download
This commit is contained in:
@@ -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]}
|
||||
/>
|
||||
<Box display='flex' justifyContent='space-between' alignItems='center'>
|
||||
<Typography variant='caption' sx={{color: 'text.secondary'}}>
|
||||
{downloading[file.id]} %
|
||||
</Typography>
|
||||
<Typography
|
||||
variant='caption'
|
||||
sx={{color: 'error.main', cursor: 'pointer'}}
|
||||
onClick={e => handleCancel(e, file.id)}
|
||||
>
|
||||
Annuler
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</StyledTableCell>
|
||||
|
||||
Reference in New Issue
Block a user