From 7f611dfae05dfbbd4293185def5ef8d64346029a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20FAMIBELLE-PRONZOLA?= Date: Wed, 17 Apr 2024 06:58:50 +0400 Subject: [PATCH] Enable file downloading --- components/files/files-dialog.js | 52 +++++++ components/files/files-list.js | 248 +++++++++++++++++++++++++++++++ components/teks/teks.js | 4 + 3 files changed, 304 insertions(+) create mode 100644 components/files/files-dialog.js create mode 100644 components/files/files-list.js diff --git a/components/files/files-dialog.js b/components/files/files-dialog.js new file mode 100644 index 0000000..59d70aa --- /dev/null +++ b/components/files/files-dialog.js @@ -0,0 +1,52 @@ +import {useState} from 'react' +import PropTypes from 'prop-types' +import Button from '@mui/material/Button' +import Dialog from '@mui/material/Dialog' +import DialogActions from '@mui/material/DialogActions' +import DialogContent from '@mui/material/DialogContent' +import useMediaQuery from '@mui/material/useMediaQuery' +import {useTheme} from '@mui/material/styles' + +import DownloadForOfflineIcon from '@mui/icons-material/DownloadForOffline' +import FilesList from './files-list' + +export default function FilesDialog({files}) { + const [open, setOpen] = useState(false) + const theme = useTheme() + const fullScreen = useMediaQuery(theme.breakpoints.down('md')) + + const handleClickOpen = () => { + setOpen(true) + } + + const handleClose = () => { + setOpen(false) + } + + return ( + <> + + + + + + + + + + + ) +} + +FilesDialog.propTypes = { + files: PropTypes.array.isRequired +} diff --git a/components/files/files-list.js b/components/files/files-list.js new file mode 100644 index 0000000..3c0ba78 --- /dev/null +++ b/components/files/files-list.js @@ -0,0 +1,248 @@ +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() + + const musicFiles = files.filter(file => file.attributes.mime.startsWith('audio')) + const pdfFiles = files.filter(file => file.attributes.mime === 'application/pdf') + + const sortedMusicFiles = musicFiles.sort((a, b) => { + const extensionOrder = { + '.flac': 0, + '.ogg': 1, + '.aac': 2, + '.mp3': 3 + } + return extensionOrder[a.attributes.ext.toLowerCase()] - extensionOrder[b.attributes.ext.toLowerCase()] + }) + + const handleClick = (e, url, fileName) => { + e.stopPropagation() + FileSaver.saveAs(url, fileName) + } + + const getQuality = (extension, caption) => { + switch (extension) { + case '.ogg': + case '.aac': + case '.mp3': + return ( + Faible + ) + case '.flac': + if (caption === 'MAX') { + return ( + {caption} + ) + } + + if (caption === 'HAUTE') { + return ( + {caption} + ) + } + + return ( + Haute + ) + + default: + return + } + } + + return ( + <> + {musicFiles.length > 0 && ( + + + + + Musiques + + + + + + + + QUALITÉ + + + + + {sortedMusicFiles.map(file => ( + + + {getQuality(file.attributes.ext.toLowerCase(), file?.attributes?.caption?.toUpperCase())} + + + handleClick(e, `${apiUrl}${file.attributes.url}`, file.attributes.name)} + > + {file.attributes.name} + + ({formatSize(file.attributes.size)}) + + + ))} + +
MAX : Jusqu’à 24-bit, 96 kHz, ≃ 3000 kbps (flac)
HAUTE : 16 bits, ≃ 900 kbps (flac)

FAIBLE : 320 kbps (ogg / aac / mp3)
+
+
+ )} + + {pdfFiles.length > 0 && ( + + + + + Paroles + + + + + + + LANGUE + + + + + {pdfFiles.map(file => ( + + + + {file.attributes.caption} + + + + handleClick(e, `${apiUrl}${file.attributes.url}`, file.attributes.name)} + > + {file.attributes.name} + + ({formatSize(file.attributes.size)}) + + + ))} + +
+
+
+ )} + + ) +} + +FilesList.propTypes = { + files: PropTypes.array.isRequired +} diff --git a/components/teks/teks.js b/components/teks/teks.js index 515fcf3..6dc349e 100644 --- a/components/teks/teks.js +++ b/components/teks/teks.js @@ -16,6 +16,7 @@ import ExplicitIcon from '@mui/icons-material/Explicit' import {formatJsonString, getAlias} from '../../lib/utils/format' import LicenseModal from '../cc/license-modal' +import FilesDialog from '../files/files-dialog' import EntegreMizik from './entegre-mizik' import OkiMizik from './oki-mizik' import DiferansDialog from './diferans-dialog' @@ -183,6 +184,9 @@ export default function Teks({parole}) { )} + {parole?.files?.data && ( + + )} {(parole.okiMizikID || parole.streamAudio.length > 0 || parole.gadeEmbed) && (