Files
pawol.nu/components/files/files-list.js
T

249 lines
8.4 KiB
JavaScript
Raw Normal View History

2024-04-17 06:58:50 +04:00
import PropTypes from 'prop-types'
import List from '@mui/material/List'
import ListSubheader from '@mui/material/ListSubheader'
import Typography from '@mui/material/Typography'
import Box from '@mui/material/Box'
import {useTheme, useColorScheme, styled} from '@mui/material/styles'
import Table from '@mui/material/Table'
import TableHead from '@mui/material/TableHead'
import TableBody from '@mui/material/TableBody'
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'
const apiUrl = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
const StyledTableCell = styled(TableCell)(({theme}) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
[`&.${tableCellClasses.body}`]: {
fontSize: 14,
},
}))
const StyledTableRow = styled(TableRow)(({theme}) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover,
},
'&:last-child td, &:last-child th': {
border: 0,
},
}))
function formatSize(size) {
if (size < 1000) {
return Math.round(size) + ' Kb'
}
const mbSize = size / 1000
return Math.round(mbSize) + ' Mb'
}
export default function FilesList({files}) {
const theme = useTheme()
const {mode} = useColorScheme()
2026-04-21 19:16:11 +04:00
const musicFiles = files.filter(file => file.mime.startsWith('audio'))
const pdfFiles = files.filter(file => file.mime === 'application/pdf')
2024-04-17 06:58:50 +04:00
const sortedMusicFiles = musicFiles.sort((a, b) => {
const extensionOrder = {
'.flac': 0,
'.ogg': 1,
'.aac': 2,
'.mp3': 3
}
2026-04-21 19:16:11 +04:00
return extensionOrder[a.ext.toLowerCase()] - extensionOrder[b.ext.toLowerCase()]
2024-04-17 06:58:50 +04:00
})
const handleClick = (e, url, fileName) => {
e.stopPropagation()
FileSaver.saveAs(url, fileName)
}
const getQuality = (extension, caption) => {
switch (extension) {
case '.ogg':
case '.aac':
case '.mp3':
return (
<Typography sx={{
backgroundColor: '#393940',
color: '#fff',
borderRadius: '0.66rem',
border: mode === 'dark' ? '1px solid #fff' : 'none',
fontSize: '0.75rem',
letterSpacing: '0.1rem',
padding: '0.2515rem 0.6707rem',
textTransform: 'uppercase',
fontWeight: 'bold'
}}
>Faible</Typography>
)
case '.flac':
if (caption === 'MAX') {
return (
<Typography sx={{
backgroundColor: '#332619',
color: '#ffbe7d',
borderRadius: '0.66rem',
border: mode === 'dark' ? '1px solid #ffbe7d' : 'none',
fontSize: '0.75rem',
letterSpacing: '0.1rem',
padding: '0.2515rem 0.6707rem',
textTransform: 'uppercase',
fontWeight: 'bold',
textAlign: 'center'
}}
>{caption}</Typography>
)
}
if (caption === 'HAUTE') {
return (
<Typography sx={{
backgroundColor: '#07332f',
color: '#21feec',
borderRadius: '0.66rem',
border: mode === 'dark' ? '1px solid #21feec' : 'none',
fontSize: '0.75rem',
letterSpacing: '0.1rem',
padding: '0.2515rem 0.6707rem',
textTransform: 'uppercase',
fontWeight: 'bold'
}}
>{caption}</Typography>
)
}
return (
<Typography sx={{
backgroundColor: '#07332f',
color: '#21feec',
borderRadius: '0.66rem',
border: mode === 'dark' ? '1px solid #21feec' : 'none',
fontSize: '0.75rem',
letterSpacing: '0.1rem',
padding: '0.2515rem 0.6707rem',
textTransform: 'uppercase',
fontWeight: 'bold'
}}
>Haute</Typography>
)
default:
return <DescriptionIcon sx={{marginRight: 1}} />
}
}
return (
<>
{musicFiles.length > 0 && (
<List
sx={{width: '100%', maxWidth: 800}}
component='nav'
aria-labelledby='nested-list-subheader'
>
<ListSubheader disableSticky sx={{backgroundColor: mode === 'light' ? theme.palette.grey[100] : theme.palette.background.default}} color='primary'>
<Box paddingBlock={1} display='flex' justifyContent='center'>
<LibraryMusicIcon />
<Typography gutterBottom marginLeft={1} variant='button'>Musiques</Typography>
</Box>
</ListSubheader>
<TableContainer component={Paper}>
<Table size='small' aria-label='Musiques'>
<caption><small><strong>MAX</strong> : <i>Jusqu’à 24-bit, 96 kHz, ≃ 3000 kbps (flac)</i><br /> <strong>HAUTE</strong> : <i>16 bits, ≃ 900 kbps (flac)</i></small><br /> <small><strong>FAIBLE</strong> : <i>320 kbps (ogg / aac / mp3)</i></small></caption>
<TableHead>
<TableRow>
<StyledTableCell align='center'>QUALITÉ</StyledTableCell>
<StyledTableCell />
</TableRow>
</TableHead>
<TableBody>
{sortedMusicFiles.map(file => (
<StyledTableRow key={file.id}>
<StyledTableCell>
2026-04-21 19:16:11 +04:00
{getQuality(file.ext.toLowerCase(), file?.caption?.toUpperCase())}
2024-04-17 06:58:50 +04:00
</StyledTableCell>
<StyledTableCell align='left'>
<Link
href='#'
underline='hover'
sx={{fontWeight: 'bold'}}
aria-label='download'
2026-04-21 19:16:11 +04:00
onClick={e => handleClick(e, `${apiUrl}${file.url}`, file.name)}
2024-04-17 06:58:50 +04:00
>
2026-04-21 19:16:11 +04:00
{file.name}
2024-04-17 06:58:50 +04:00
</Link>
2026-04-21 19:16:11 +04:00
<small style={{marginLeft: 3}}>({formatSize(file.size)})</small>
2024-04-17 06:58:50 +04:00
</StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</List>
)}
{pdfFiles.length > 0 && (
<List
sx={{width: '100%', maxWidth: 800}}
component='nav'
aria-labelledby='nested-list-subheader'
>
<ListSubheader disableSticky sx={{marginTop: 2, backgroundColor: mode === 'light' ? theme.palette.grey[100] : theme.palette.background.default}} color='primary'>
<Box paddingBlock={1} display='flex' justifyContent='center' alignSelf='center'>
<DescriptionIcon />
<Typography gutterBottom marginLeft={1} variant='button'>Paroles</Typography>
</Box>
</ListSubheader>
<TableContainer component={Paper}>
<Table size='small' aria-label='Paroles'>
<TableHead>
<TableRow>
<StyledTableCell>LANGUE</StyledTableCell>
<StyledTableCell />
</TableRow>
</TableHead>
<TableBody>
{pdfFiles.map(file => (
<StyledTableRow key={file.id}>
<StyledTableCell>
<strong>
2026-04-21 19:16:11 +04:00
{file.caption}
2024-04-17 06:58:50 +04:00
</strong>
</StyledTableCell>
<StyledTableCell align='left'>
<Link
href='#'
underline='hover'
sx={{fontWeight: 'bold'}}
aria-label='download'
2026-04-21 19:16:11 +04:00
onClick={e => handleClick(e, `${apiUrl}${file.url}`, file.name)}
2024-04-17 06:58:50 +04:00
>
2026-04-21 19:16:11 +04:00
{file.name}
2024-04-17 06:58:50 +04:00
</Link>
2026-04-21 19:16:11 +04:00
<small style={{marginLeft: 3}}>({formatSize(file.size)})</small>
2024-04-17 06:58:50 +04:00
</StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</List>
)}
</>
)
}
FilesList.propTypes = {
files: PropTypes.array.isRequired
}