fix(ui): preserve pending track selection through queue sync and premature callbacks

When clicking a song while another was playing, PLAYER_SYNC_QUEUE and
PLAYER_CURRENT would fire before the music player switched tracks,
wiping the playIndex set by PLAYER_PLAY_TRACKS. This caused the player
to stay on the old track instead of switching to the clicked one.

Now reduceSyncQueue and reduceCurrent preserve a pending playIndex until
the music player confirms it actually reached the requested track.
This commit is contained in:
Deluan
2026-03-09 12:44:19 -04:00
parent 09e1cf6ae7
commit e08d4bef16
2 changed files with 107 additions and 5 deletions
+13 -4
View File
@@ -173,8 +173,11 @@ const reduceSyncQueue = (state, { data: { audioInfo, audioLists } }) => {
return {
...state,
queue: audioLists,
clear: false,
playIndex: undefined,
// Keep clear and playIndex alive so the music player can still
// pick up a pending track selection set by PLAYER_PLAY_TRACKS.
// They will be consumed by the next PLAYER_CURRENT dispatch.
clear: state.playIndex != null ? state.clear : false,
playIndex: state.playIndex != null ? state.playIndex : undefined,
}
}
@@ -183,11 +186,17 @@ const reduceCurrent = (state, { data }) => {
const savedPlayIndex = state.queue.findIndex(
(item) => item.uuid === current.uuid,
)
// When a track selection is pending (playIndex is set), keep it alive
// until the music player confirms it actually switched to the requested
// track. Without this, a premature onAudioPlay callback for the
// still-playing old track would overwrite the pending selection.
const pending = state.playIndex != null && savedPlayIndex !== state.playIndex
return {
...state,
current,
playIndex: undefined,
savedPlayIndex,
playIndex: pending ? state.playIndex : undefined,
clear: pending ? state.clear : false,
savedPlayIndex: pending ? state.savedPlayIndex : savedPlayIndex,
volume: data.volume,
}
}