mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 21:12:49 +08:00
fix(web): tick player time every frame and keep lyrics in sync (#107)
`store.elapsed` is a Pinia getter (a cached Vue computed) that interpolates with `Date.now()`. Because `Date.now()` is not a reactive dependency, the computed only re-ran on WebSocket pushes / the 3s server poll, so the bottom progress bar jumped ~3s at a time and lyric highlighting lagged ~half a line — even though the consumers read it from a 60fps requestAnimationFrame loop. Add a pure `interpolateElapsed()` helper and a non-cached `liveElapsed()` store action. The per-frame consumers now call `liveElapsed()` so the value advances every frame instead of returning a frozen cache: - web/src/components/Player.vue (desktop progress bar, rAF) - web/src/App.vue (mobile progress bar, rAF) - web/src/views/Lyrics.vue (lyric highlight, 500ms interval) pause() now freezes at the live value rather than a possibly-stale cached one. The `elapsed` getter is refactored onto the same helper (behaviour unchanged). Adds web/src/stores/elapsed.test.ts covering the time-advancing interpolation, paused freeze, no-anchor, and duration-clamp cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
ea6820204d
commit
45f5d236c1
5 files changed
+107
-11
No files matched your search
@@ -136,7 +136,9 @@ function scrollToActiveLine(idx: number) {
|
||||
|
||||
function syncLyrics() {
|
||||
if (!store.isPlaying || lines.value.length === 0) return;
|
||||
const elapsed = store.elapsed;
|
||||
// liveElapsed() (action) is recomputed now; the cached `elapsed` getter only
|
||||
// refreshed on server pushes, leaving highlights ~half a line behind (#107).
|
||||
const elapsed = store.liveElapsed();
|
||||
const idx = findActiveLine(elapsed);
|
||||
// Only update when the active line actually changes
|
||||
if (idx !== activeLine.value && idx >= 0) {
|
||||
|
||||
Reference in new issue
Block a user