'use client' import {useState, useEffect, forwardRef} from 'react' import PropTypes from 'prop-types' import Fab from '@mui/material/Fab' import Dialog from '@mui/material/Dialog' import Slide from '@mui/material/Slide' import Box from '@mui/material/Box' import Skeleton from '@mui/material/Skeleton' import IconButton from '@mui/material/IconButton' import Typography from '@mui/material/Typography' import Tooltip from '@mui/material/Tooltip' import useMediaQuery from '@mui/material/useMediaQuery' import {useTheme, keyframes} from '@mui/material/styles' import MicIcon from '@mui/icons-material/Mic' import CloseIcon from '@mui/icons-material/Close' const pulse = keyframes` 0%, 100% { opacity: 0.18; transform: scale(1); } 50% { opacity: 0.55; transform: scale(1.2); } ` const SlideUp = forwardRef(function SlideUp(props, ref) { return }) function toEmbedUrl(url) { try { const u = new URL(url) const match = u.pathname.match(/\/(?:videos\/watch|w)\/([^/?#]+)/) if (match) { return `${u.origin}/videos/embed/${match[1]}?title=0&warningTitle=0&peertubeLink=0&controlBar=1` } return url } catch { return url } } export default function KaraokeModal({url, desktopUrl, titre, artistes}) { const [open, setOpen] = useState(false) const [loaded, setLoaded] = useState(false) const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down('sm')) const activeUrl = (!isMobile && desktopUrl) ? desktopUrl : url useEffect(() => { if (!open) setLoaded(false) }, [open]) return ( <> setOpen(true)} sx={{ position: 'fixed', bottom: {xs: 24, sm: 32}, right: {xs: 24, sm: 32}, zIndex: 1050, }} > setOpen(false)} slots={{transition: SlideUp}} maxWidth={false} sx={{ '& .MuiDialog-container': { alignItems: {xs: 'flex-end', sm: 'center'}, } }} slotProps={{ backdrop: {sx: {backdropFilter: 'blur(6px)', bgcolor: 'rgba(0,0,0,0.85)'}}, paper: { sx: { bgcolor: '#000', overflow: 'hidden', ...(isMobile ? { width: '100vw', height: '100dvh', maxWidth: 'none', maxHeight: 'none', m: 0, borderRadius: 0, boxShadow: 'none', } : { width: 'calc(80vh * 16 / 9)', height: '80vh', maxWidth: 'none', maxHeight: 'none', borderRadius: '16px', boxShadow: '0 24px 64px rgba(0,0,0,0.7)', }) } } }} > {/* Header superposé en gradient */} {titre && ( {titre} )} {artistes?.length > 0 && ( {artistes.map(a => a.alias).join(', ')} )} setOpen(false)} aria-label='fermer' sx={{ pointerEvents: 'auto', color: '#fff', bgcolor: 'rgba(255,255,255,0.15)', backdropFilter: 'blur(8px)', border: '1px solid rgba(255,255,255,0.12)', '&:hover': {bgcolor: 'rgba(255,255,255,0.25)'}, }} > {open && ( {!loaded && ( <> Chargement… )} {isMobile ? ( /* Vidéo verticale : scale le player 16:9 à la hauteur du portrait et croppe les côtés */