From 34e0c4bd4aea3503c5c11d36b7fe9267449d1576 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Fri, 1 May 2026 21:33:40 -0700 Subject: [PATCH] prevent first lyric line highlight before timestamp (#1965) --- .../features/lyrics/synchronized-lyrics.tsx | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/renderer/features/lyrics/synchronized-lyrics.tsx b/src/renderer/features/lyrics/synchronized-lyrics.tsx index 26abb3712..9ca81c6e6 100644 --- a/src/renderer/features/lyrics/synchronized-lyrics.tsx +++ b/src/renderer/features/lyrics/synchronized-lyrics.tsx @@ -95,18 +95,20 @@ export const SynchronizedLyrics = ({ const programmaticScrollRef = useRef(false); const getCurrentLyric = (timeInMs: number) => { - if (lyricRef.current) { - const activeLyrics = lyricRef.current; - for (let idx = 0; idx < activeLyrics.length; idx += 1) { - if (timeInMs <= activeLyrics[idx][0]) { - return idx === 0 ? idx : idx - 1; - } - } - - return activeLyrics.length - 1; + const activeLyrics = lyricRef.current; + if (!activeLyrics?.length) { + return -1; } - return -1; + let index = -1; + for (let idx = 0; idx < activeLyrics.length; idx += 1) { + if (timeInMs < activeLyrics[idx][0]) { + break; + } + index = idx; + } + + return index; }; const setCurrentLyricRef = useRef< @@ -141,7 +143,20 @@ export const SynchronizedLyrics = ({ .forEach((node) => node.classList.remove('active')); if (index === -1) { - lyricRef.current = null; + const activeLyrics = lyricRef.current; + if (!activeLyrics?.length) { + return; + } + + const firstTime = activeLyrics[0][0]; + if (timeInMs < firstTime) { + const elapsed = performance.now() - start; + const delay = Math.max(0, firstTime - timeInMs - elapsed); + lyricTimer.current = setTimeout(() => { + setCurrentLyricRef.current(firstTime, nextEpoch, 0); + }, delay); + } + return; } @@ -153,7 +168,6 @@ export const SynchronizedLyrics = ({ const offsetTop = currentLyric?.offsetTop - doc?.clientHeight / 2 || 0; if (currentLyric === null) { - lyricRef.current = null; return; }