From e4b5cf36e1d094e09eb2eb4c02b443986a447551 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Fri, 26 Dec 2025 14:49:06 -0800 Subject: [PATCH] fix duplicate PLAYER_PLAY event causing race condition in mpv --- src/renderer/store/player.store.ts | 209 +++++++++-------------------- 1 file changed, 67 insertions(+), 142 deletions(-) diff --git a/src/renderer/store/player.store.ts b/src/renderer/store/player.store.ts index 1c76124a6..9b6ce0c9a 100644 --- a/src/renderer/store/player.store.ts +++ b/src/renderer/store/player.store.ts @@ -209,6 +209,68 @@ function calculateNextIndex( } } +function emitPlayerPlayEvent( + targetSongUniqueId: string | undefined, + set: (fn: (state: PlayerState) => void) => void, + get: () => PlayerState, +): void { + // If playSongId is provided, find the song and start playback on it + if (targetSongUniqueId) { + let playIndex: number | undefined; + set((state) => { + const queue = state.getQueue(); + const queueIndex = queue.items.findIndex( + (item) => item._uniqueId === targetSongUniqueId, + ); + + if (queueIndex !== -1) { + if ( + state.player.shuffle === PlayerShuffle.TRACK && + state.queue.shuffled.length > 0 + ) { + // Find the shuffled position for this queue index + const shuffledPosition = state.queue.shuffled.findIndex( + (idx) => idx === queueIndex, + ); + if (shuffledPosition !== -1) { + state.player.index = shuffledPosition; + playIndex = shuffledPosition; + } else { + state.player.index = queueIndex; + playIndex = queueIndex; + } + } else { + state.player.index = queueIndex; + playIndex = queueIndex; + } + state.player.status = PlayerStatus.PLAYING; + setTimestampStore(0); + } + }); + + // Emit PLAYER_PLAY event if playback was started + if (playIndex !== undefined) { + eventEmitter.emit('PLAYER_PLAY', { + id: targetSongUniqueId, + index: playIndex, + }); + } + } else { + // Otherwise, emit PLAYER_PLAY event for current song if available + const currentState = get(); + const queue = currentState.getQueue(); + const currentIndex = currentState.player.index; + const currentSong = queue.items[currentIndex]; + + if (currentSong && currentIndex !== undefined && currentIndex >= 0) { + eventEmitter.emit('PLAYER_PLAY', { + id: currentSong._uniqueId, + index: currentIndex, + }); + } + } +} + // Helper function to find shuffled position for a given queue index function findShuffledPositionForQueueIndex( queueIndex: number, @@ -502,21 +564,7 @@ export const usePlayerStoreBase = createWithEqualityFn()( } }); - const currentState = get(); - const queue = currentState.getQueue(); - const currentIndex = currentState.player.index; - const currentSong = queue.items[currentIndex]; - - if ( - currentSong && - currentIndex !== undefined && - currentIndex >= 0 - ) { - eventEmitter.emit('PLAYER_PLAY', { - id: currentSong._uniqueId, - index: currentIndex, - }); - } + emitPlayerPlayEvent(targetSongUniqueId, set, get); break; } case Play.SHUFFLE: { @@ -543,22 +591,7 @@ export const usePlayerStoreBase = createWithEqualityFn()( } }); - // Emit PLAYER_PLAY event after state is updated - const currentState = get(); - const queue = currentState.getQueue(); - const currentIndex = currentState.player.index; - const currentSong = queue.items[currentIndex]; - - if ( - currentSong && - currentIndex !== undefined && - currentIndex >= 0 - ) { - eventEmitter.emit('PLAYER_PLAY', { - id: currentSong._uniqueId, - index: currentIndex, - }); - } + emitPlayerPlayEvent(targetSongUniqueId, set, get); break; } } @@ -802,21 +835,7 @@ export const usePlayerStoreBase = createWithEqualityFn()( } }); - const currentState = get(); - const queue = currentState.getQueue(); - const currentIndex = currentState.player.index; - const currentSong = queue.items[currentIndex]; - - if ( - currentSong && - currentIndex !== undefined && - currentIndex >= 0 - ) { - eventEmitter.emit('PLAYER_PLAY', { - id: currentSong._uniqueId, - index: currentIndex, - }); - } + emitPlayerPlayEvent(targetSongUniqueId, set, get); break; } case Play.SHUFFLE: { @@ -846,66 +865,13 @@ export const usePlayerStoreBase = createWithEqualityFn()( ); }); - // Emit PLAYER_PLAY event after state is updated - const currentState = get(); - const queue = currentState.getQueue(); - const currentIndex = currentState.player.index; - const currentSong = queue.items[currentIndex]; - if (currentSong && currentIndex !== undefined) { - eventEmitter.emit('PLAYER_PLAY', { - id: currentSong._uniqueId, - index: currentIndex, - }); - } + emitPlayerPlayEvent(targetSongUniqueId, set, get); break; } } break; } } - - // If playSongId is provided, find the song and start playback on it - if (targetSongUniqueId) { - let playIndex: number | undefined; - set((state) => { - const queue = state.getQueue(); - const queueIndex = queue.items.findIndex( - (item) => item._uniqueId === targetSongUniqueId, - ); - - if (queueIndex !== -1) { - if ( - state.player.shuffle === PlayerShuffle.TRACK && - state.queue.shuffled.length > 0 - ) { - // Find the shuffled position for this queue index - const shuffledPosition = state.queue.shuffled.findIndex( - (idx) => idx === queueIndex, - ); - if (shuffledPosition !== -1) { - state.player.index = shuffledPosition; - playIndex = shuffledPosition; - } else { - state.player.index = queueIndex; - playIndex = queueIndex; - } - } else { - state.player.index = queueIndex; - playIndex = queueIndex; - } - state.player.status = PlayerStatus.PLAYING; - setTimestampStore(0); - } - }); - - // Emit PLAYER_PLAY event if playback was started - if (playIndex !== undefined) { - eventEmitter.emit('PLAYER_PLAY', { - id: targetSongUniqueId, - index: playIndex, - }); - } - } }, addToQueueByUniqueId: (items, uniqueId, edge, playSongId) => { const newItems = items.map(toQueueSong); @@ -1099,48 +1065,7 @@ export const usePlayerStoreBase = createWithEqualityFn()( } }); - // If playSongId is provided, find the song and start playback on it - if (targetSongUniqueId) { - let playIndex: number | undefined; - set((state) => { - const queue = state.getQueue(); - const queueIndex = queue.items.findIndex( - (item) => item._uniqueId === targetSongUniqueId, - ); - - if (queueIndex !== -1) { - if ( - state.player.shuffle === PlayerShuffle.TRACK && - state.queue.shuffled.length > 0 - ) { - // Find the shuffled position for this queue index - const shuffledPosition = state.queue.shuffled.findIndex( - (idx) => idx === queueIndex, - ); - if (shuffledPosition !== -1) { - state.player.index = shuffledPosition; - playIndex = shuffledPosition; - } else { - state.player.index = queueIndex; - playIndex = queueIndex; - } - } else { - state.player.index = queueIndex; - playIndex = queueIndex; - } - state.player.status = PlayerStatus.PLAYING; - setTimestampStore(0); - } - }); - - // Emit PLAYER_PLAY event if playback was started - if (playIndex !== undefined) { - eventEmitter.emit('PLAYER_PLAY', { - id: targetSongUniqueId, - index: playIndex, - }); - } - } + emitPlayerPlayEvent(targetSongUniqueId, set, get); }, clearQueue: () => { set((state) => {