fix: explicit download
Déploiement FRONT PROD / check (push) Successful in 2m10s
Déploiement FRONT PROD / deploy (push) Successful in 21s

This commit is contained in:
2026-06-01 00:52:41 +04:00
parent 7161070435
commit cd3cc2a697
+50 -5
View File
@@ -5,6 +5,7 @@ import ListSubheader from '@mui/material/ListSubheader'
import Typography from '@mui/material/Typography'
import Box from '@mui/material/Box'
import Skeleton from '@mui/material/Skeleton'
import LinearProgress from '@mui/material/LinearProgress'
import {useTheme, useColorScheme, styled} from '@mui/material/styles'
import Table from '@mui/material/Table'
import TableHead from '@mui/material/TableHead'
@@ -13,7 +14,6 @@ import TableCell, {tableCellClasses} from '@mui/material/TableCell'
import TableRow from '@mui/material/TableRow'
import TableContainer from '@mui/material/TableContainer'
import Paper from '@mui/material/Paper'
import FileSaver from 'file-saver'
import DescriptionIcon from '@mui/icons-material/Description'
import LibraryMusicIcon from '@mui/icons-material/LibraryMusic'
import {Link} from '@mui/material'
@@ -53,6 +53,7 @@ export default function FilesList({files}) {
const theme = useTheme()
const {mode} = useColorScheme()
const [audioMeta, setAudioMeta] = useState(audioMetaCache)
const [downloading, setDownloading] = useState({})
const musicFiles = files.filter(file => file.mime.startsWith('audio'))
const pdfFiles = files.filter(file => file.mime === 'application/pdf')
@@ -148,9 +149,42 @@ export default function FilesList({files}) {
)
}
const handleClick = (e, url, fileName) => {
const handleClick = async (e, url, fileName, fileId) => {
e.stopPropagation()
FileSaver.saveAs(url, fileName)
if (fileId in downloading) return
setDownloading(prev => ({...prev, [fileId]: 0}))
try {
const response = await fetch(url)
const contentLength = +response.headers.get('content-length')
const reader = response.body.getReader()
const chunks = []
let received = 0
while (true) {
const {done, value} = await reader.read()
if (done) break
chunks.push(value)
received += value.length
if (contentLength) {
setDownloading(prev => ({...prev, [fileId]: Math.round(received / contentLength * 100)}))
}
}
const blob = new Blob(chunks, {type: response.headers.get('content-type')})
const blobUrl = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = blobUrl
a.download = fileName
a.click()
URL.revokeObjectURL(blobUrl)
} finally {
setDownloading(prev => {
const next = {...prev}
delete next[fileId]
return next
})
}
}
return (
@@ -185,13 +219,24 @@ export default function FilesList({files}) {
<Link
href='#'
underline='hover'
sx={{fontWeight: 'bold'}}
sx={{fontWeight: 'bold', pointerEvents: file.id in downloading ? 'none' : 'auto'}}
aria-label='download'
onClick={e => handleClick(e, `${apiUrl}${file.url}`, file.name)}
onClick={e => handleClick(e, `${apiUrl}${file.url}`, file.name, file.id)}
>
{file.name}
</Link>
<small style={{marginLeft: 3}}>({formatSize(file.size)})</small>
{file.id in downloading && (
<Box sx={{mt: 0.5}}>
<LinearProgress
variant={downloading[file.id] > 0 ? 'determinate' : 'indeterminate'}
value={downloading[file.id]}
/>
<Typography variant='caption' sx={{color: 'text.secondary'}}>
{downloading[file.id]} %
</Typography>
</Box>
)}
</StyledTableCell>
</StyledTableRow>
))}