feat: add pawol to player
This commit is contained in:
@@ -20,6 +20,18 @@ import {getAlias} from '../../lib/utils/format'
|
|||||||
|
|
||||||
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
|
const IMAGE_URL = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
|
||||||
|
|
||||||
|
function parseLrc(text) {
|
||||||
|
const lines = []
|
||||||
|
for (const raw of text.split('\n')) {
|
||||||
|
const match = raw.match(/^\[(\d{2}):(\d{2})[.:]\d+\](.*)$/)
|
||||||
|
if (match) {
|
||||||
|
lines.push({time: parseInt(match[1]) * 60 + parseInt(match[2]), text: match[3].trim()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.sort((a, b) => a.time - b.time).filter(l => l.text)
|
||||||
|
}
|
||||||
|
|
||||||
const Widget = styled('div')(({theme}) => ({
|
const Widget = styled('div')(({theme}) => ({
|
||||||
padding: 16,
|
padding: 16,
|
||||||
borderRadius: 16,
|
borderRadius: 16,
|
||||||
@@ -64,6 +76,7 @@ export default function Lekte({audio, url, parole}) {
|
|||||||
const [position, setPosition] = useState(0)
|
const [position, setPosition] = useState(0)
|
||||||
const [volume, setVolume] = useState(100)
|
const [volume, setVolume] = useState(100)
|
||||||
const [isPlaying, setIsPlaying] = useState(false)
|
const [isPlaying, setIsPlaying] = useState(false)
|
||||||
|
const [lrcLines, setLrcLines] = useState(null)
|
||||||
const alias = getAlias(parole.artistes, parole.prioriteArtistes)
|
const alias = getAlias(parole.artistes, parole.prioriteArtistes)
|
||||||
|
|
||||||
function formatDuration(value) {
|
function formatDuration(value) {
|
||||||
@@ -127,6 +140,18 @@ export default function Lekte({audio, url, parole}) {
|
|||||||
setPosition(0)
|
setPosition(0)
|
||||||
}, [audio])
|
}, [audio])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!parole?.pawol?.url) return
|
||||||
|
fetch(new URL(parole.pawol.url, IMAGE_URL).toString())
|
||||||
|
.then(r => r.text())
|
||||||
|
.then(text => setLrcLines(parseLrc(text)))
|
||||||
|
.catch(() => setLrcLines([]))
|
||||||
|
}, [parole?.pawol?.url])
|
||||||
|
|
||||||
|
const activeIndex = lrcLines
|
||||||
|
? lrcLines.reduce((last, line, i) => line.time <= position ? i : last, -1)
|
||||||
|
: -1
|
||||||
|
|
||||||
const handleChangePosition = value => {
|
const handleChangePosition = value => {
|
||||||
setPosition(value)
|
setPosition(value)
|
||||||
audioRef.current.currentTime = value
|
audioRef.current.currentTime = value
|
||||||
@@ -273,6 +298,31 @@ export default function Lekte({audio, url, parole}) {
|
|||||||
/>
|
/>
|
||||||
<VolumeUpRounded htmlColor={lightIconColor} />
|
<VolumeUpRounded htmlColor={lightIconColor} />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
{lrcLines && lrcLines.length > 0 && (
|
||||||
|
<Box sx={{mt: 1.5, textAlign: 'center', minHeight: 64}}>
|
||||||
|
{[-1, 0, 1].map(offset => {
|
||||||
|
const idx = activeIndex + offset
|
||||||
|
const line = lrcLines[idx]
|
||||||
|
if (!line) return <Box key={offset} sx={{height: offset === 0 ? 28 : 20}} />
|
||||||
|
return (
|
||||||
|
<Typography
|
||||||
|
key={offset}
|
||||||
|
variant={offset === 0 ? 'body2' : 'caption'}
|
||||||
|
sx={{
|
||||||
|
display: 'block',
|
||||||
|
fontWeight: offset === 0 ? 'bold' : 'normal',
|
||||||
|
color: offset === 0 ? 'text.primary' : 'text.secondary',
|
||||||
|
opacity: offset === 0 ? 1 : 0.45,
|
||||||
|
transition: 'all 0.3s ease',
|
||||||
|
lineHeight: offset === 0 ? 1.6 : 1.4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{line.text}
|
||||||
|
</Typography>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Widget>
|
</Widget>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ export async function jwennTeksEpiSlug(slug) {
|
|||||||
},
|
},
|
||||||
traductions: {
|
traductions: {
|
||||||
populate: '*'
|
populate: '*'
|
||||||
|
},
|
||||||
|
pawol: {
|
||||||
|
populate: '*'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
|
|||||||
Reference in New Issue
Block a user