fix(player): step correctly when seeking rapidly (#2084)

* fix(player): step correctly when seeking rapidly

mediaSkipBackward/mediaSkipForward compute the new target relative to
the timestamp store, which is only refreshed by a ~500ms engine poll.
Rapid presses within that window all read the same stale position and
recompute the same target, so the time appears stuck until the poll
catches up.

Update the timestamp store immediately when a seek is issued so
subsequent presses compute from the new position; the poll then just
reconciles to the same value. Also applied to mediaSeekToTimestamp so
absolute seeks reflect in the UI without the poll lag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(player): unify seek comments per review

Use one canonical explanation in mediaSkipBackward and have
mediaSeekToTimestamp/mediaSkipForward reference it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
fiso64
2026-06-03 01:11:21 +02:00
committed by GitHub
parent 515cadb916
commit 5ac0aaeec0
+11
View File
@@ -1185,6 +1185,9 @@ export const usePlayerStoreBase = createWithEqualityFn<PlayerState>()(
}); });
}, },
mediaSeekToTimestamp: (timestamp: number) => { mediaSeekToTimestamp: (timestamp: number) => {
// See mediaSkipBackward: update the timestamp store right away to
// avoid the stale-read left by the ~500ms engine poll.
setTimestampStore(timestamp);
set((state) => { set((state) => {
state.player.seekToTimestamp = uniqueSeekToTimestamp(timestamp); state.player.seekToTimestamp = uniqueSeekToTimestamp(timestamp);
}); });
@@ -1196,6 +1199,11 @@ export const usePlayerStoreBase = createWithEqualityFn<PlayerState>()(
const currentTimestamp = useTimestampStoreBase.getState().timestamp; const currentTimestamp = useTimestampStoreBase.getState().timestamp;
const newTimestamp = Math.max(0, currentTimestamp - timeToSkip); const newTimestamp = Math.max(0, currentTimestamp - timeToSkip);
// Update the timestamp store right away so the UI and any
// subsequent seek compute from the new position instead of the
// stale value left by the ~500ms engine poll (otherwise mashing
// the seek keys repeatedly lands on the same time).
setTimestampStore(newTimestamp);
set((state) => { set((state) => {
state.player.seekToTimestamp = uniqueSeekToTimestamp(newTimestamp); state.player.seekToTimestamp = uniqueSeekToTimestamp(newTimestamp);
}); });
@@ -1217,6 +1225,9 @@ export const usePlayerStoreBase = createWithEqualityFn<PlayerState>()(
const currentTimestamp = useTimestampStoreBase.getState().timestamp; const currentTimestamp = useTimestampStoreBase.getState().timestamp;
const newTimestamp = Math.min(duration - 1, currentTimestamp + timeToSkip); const newTimestamp = Math.min(duration - 1, currentTimestamp + timeToSkip);
// See mediaSkipBackward: update the timestamp store right away to
// avoid the stale-read left by the ~500ms engine poll.
setTimestampStore(newTimestamp);
set((state) => { set((state) => {
state.player.seekToTimestamp = uniqueSeekToTimestamp(newTimestamp); state.player.seekToTimestamp = uniqueSeekToTimestamp(newTimestamp);
}); });