syncro lyrics on click

This commit is contained in:
Thomas Demirdjian
2025-10-03 16:39:40 +02:00
parent da5e648158
commit 487999e0f8
2 changed files with 49 additions and 0 deletions
+26
View File
@@ -189,6 +189,31 @@ const MusicDetails = ({ route }) => {
console.log("MusicDetails seekBy error", e?.message); console.log("MusicDetails seekBy error", e?.message);
} }
}; };
const handleLyricsSeek = React.useCallback(
async (timestampS) => {
if (!player || typeof timestampS !== "number" || Number.isNaN(timestampS))
return;
const seconds = Math.max(0, Number(timestampS) || 0);
const duration = Number(player?.duration || 0);
const bounded = duration > 0 ? Math.min(seconds, duration) : seconds;
try {
const wasPlaying = !!player?.playing;
await player.seekTo?.(bounded);
setProgressInfo((prev) => ({ ...prev, pos: bounded * 1000 }));
if (wasPlaying) {
if (!player?.playing) {
await player.play?.();
}
setIsPlaying(true);
}
} catch (e) {
console.log("MusicDetails lyrics seek error", e?.message);
}
},
[player]
);
const description = useMemo(() => { const description = useMemo(() => {
// Build a readable text from lyrics with section labels // Build a readable text from lyrics with section labels
if (Array.isArray(project?.lyrics)) { if (Array.isArray(project?.lyrics)) {
@@ -496,6 +521,7 @@ const MusicDetails = ({ route }) => {
? styles.karaokeWordActive ? styles.karaokeWordActive
: styles.karaokeWord : styles.karaokeWord
} }
onPress={() => handleLyricsSeek(w.startS)}
> >
{w.text} {w.text}
{j < (L.words?.length || 1) - 1 ? " " : ""} {j < (L.words?.length || 1) - 1 ? " " : ""}
+23
View File
@@ -289,6 +289,26 @@ const MusicDetails = ({ route }) => {
console.log("MusicDetails seekBy error", e?.message); console.log("MusicDetails seekBy error", e?.message);
} }
}; };
const handleLyricsSeek = React.useCallback(
async (timestampS) => {
if (typeof timestampS !== "number" || Number.isNaN(timestampS)) return;
const seconds = Math.max(0, Number(timestampS) || 0);
const durationS = durationMs > 0 ? durationMs / 1000 : null;
const bounded = durationS ? Math.min(seconds, durationS) : seconds;
try {
const wasPlaying = isPlaying;
seekAudio(bounded);
if (wasPlaying) {
await playAudio();
}
} catch (e) {
console.log("MusicDetails lyrics seek error", e?.message);
}
},
[durationMs, isPlaying, playAudio, seekAudio]
);
const description = useMemo(() => { const description = useMemo(() => {
// Build a readable text from lyrics with section labels // Build a readable text from lyrics with section labels
if (Array.isArray(project?.lyrics)) { if (Array.isArray(project?.lyrics)) {
@@ -644,6 +664,7 @@ const MusicDetails = ({ route }) => {
? styles.karaokeWordActive ? styles.karaokeWordActive
: styles.karaokeWord : styles.karaokeWord
} }
onPress={() => handleLyricsSeek(w.startS)}
> >
{w.text} {w.text}
{j < (L.words?.length || 1) - 1 ? " " : ""} {j < (L.words?.length || 1) - 1 ? " " : ""}
@@ -706,9 +727,11 @@ const styles = StyleSheet.create({
karaokeWord: { karaokeWord: {
color: Palette.white, color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular, fontFamily: FONT_FAMILY.InterRegular,
cursor: "pointer",
}, },
karaokeWordActive: { karaokeWordActive: {
color: Palette.primary, color: Palette.primary,
fontFamily: FONT_FAMILY.InterBold, fontFamily: FONT_FAMILY.InterBold,
cursor: "pointer",
}, },
}); });