fix(ui): enforce must-watch seek lock after the seek settles

Resetting currentTime inside the seeking handler doesn't reliably stick
across sources (HLS re-buffering, emulated YouTube events, coalesced native
seeks), so the snackbar showed but playback continued ahead. The timeupdate
handler then ignored the large forward jump via its delta < 2 guard, making
the skip permanent.

Re-clamp in seeked once the position settles, and add a timeupdate backstop
that snaps back forward jumps (delta >= 2) landing past furthestSeconds.
This commit is contained in:
Rotimi Best
2026-06-22 10:00:56 +01:00
parent 75bd0f4b67
commit 9de0615e0f
@@ -116,6 +116,12 @@
const onSeeked = () => {
isSeeking = false;
// Re-enforce once the seek settles: setting currentTime during `seeking`
// doesn't always stick (HLS re-buffering can win the in-flight seek), so
// snap back here if the player still ended up ahead.
if (player.currentTime > furthestSeconds + seekTolerance) {
player.currentTime = furthestSeconds;
}
hasBlockedThisSeek = false;
lastValidTime = player.currentTime;
};
@@ -126,6 +132,14 @@
const current = player.currentTime;
const delta = current - lastValidTime;
// Backstop: a forward jump beyond normal playback that slipped past the
// `seeking`/`seeked` handlers. Clamp back so playback can't continue ahead.
if (delta >= 2 && current > furthestSeconds + seekTolerance) {
player.currentTime = furthestSeconds;
lastValidTime = furthestSeconds;
return;
}
if (delta > 0 && delta < 2) {
playedSeconds += delta;
furthestSeconds = Math.max(furthestSeconds, current);