diff --git a/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx b/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx index 6477d1baa..eef77c1f6 100644 --- a/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx +++ b/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx @@ -249,6 +249,9 @@ export const MpvPlayerEngine = (props: MpvPlayerEngineProps) => { onPlayerPlay: () => { replaceMpvQueue(transcode); }, + onQueueCleared: () => { + console.log('queue cleared'); + }, }, [transcode], ); diff --git a/src/renderer/features/player/audio-player/hooks/use-player-events.ts b/src/renderer/features/player/audio-player/hooks/use-player-events.ts index b9b32b9c4..66d668623 100644 --- a/src/renderer/features/player/audio-player/hooks/use-player-events.ts +++ b/src/renderer/features/player/audio-player/hooks/use-player-events.ts @@ -13,6 +13,7 @@ import { subscribePlayerSpeed, subscribePlayerStatus, subscribePlayerVolume, + subscribeQueueCleared, } from '/@/renderer/store'; import { LibraryItem, QueueData, QueueSong, Song } from '/@/shared/types/domain-types'; import { PlayerRepeat, PlayerShuffle, PlayerStatus } from '/@/shared/types/types'; @@ -46,6 +47,7 @@ interface PlayerEventsCallbacks { onPlayerSpeed?: (properties: { speed: number }, prev: { speed: number }) => void; onPlayerStatus?: (properties: { status: PlayerStatus }, prev: { status: PlayerStatus }) => void; onPlayerVolume?: (properties: { volume: number }, prev: { volume: number }) => void; + onQueueCleared?: () => void; onQueueRestored?: (properties: { data: Song[]; index: number; position: number }) => void; onUserFavorite?: (properties: { favorite: boolean; @@ -99,6 +101,12 @@ function createPlayerEvents(callbacks: PlayerEventsCallbacks): PlayerEvents { unsubscribers.push(unsubscribe); } + // Subscribe to queue cleared events + if (callbacks.onQueueCleared) { + const unsubscribe = subscribeQueueCleared(callbacks.onQueueCleared); + unsubscribers.push(unsubscribe); + } + // Subscribe to seek events if (callbacks.onPlayerSeekToTimestamp) { const unsubscribe = subscribePlayerSeekToTimestamp(callbacks.onPlayerSeekToTimestamp); diff --git a/src/renderer/features/player/audio-player/mpv-player.tsx b/src/renderer/features/player/audio-player/mpv-player.tsx index 35cb973b2..f3bd85ac3 100644 --- a/src/renderer/features/player/audio-player/mpv-player.tsx +++ b/src/renderer/features/player/audio-player/mpv-player.tsx @@ -4,6 +4,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { MpvPlayerEngine, MpvPlayerEngineHandle } from './engine/mpv-player-engine'; import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events'; +import { usePlayer } from '/@/renderer/features/player/context/player-context'; import { usePlaybackSettings, usePlayerActions, @@ -97,6 +98,8 @@ export function MpvPlayer() { return playerData; }, [mediaAutoNext, volume, setIsTransitioning]); + const player = usePlayer(); + usePlayerEvents( { onPlayerSeekToTimestamp: (properties) => { @@ -125,6 +128,9 @@ export function MpvPlayer() { const volume = properties.volume; playerRef.current?.setVolume(volume); }, + onQueueCleared: () => { + player.mediaStop(); + }, }, [volume, fadeAndSetStatus, audioFadeOnStatusChange], ); diff --git a/src/renderer/features/player/audio-player/web-player.tsx b/src/renderer/features/player/audio-player/web-player.tsx index e4c9047f8..11b1436a2 100644 --- a/src/renderer/features/player/audio-player/web-player.tsx +++ b/src/renderer/features/player/audio-player/web-player.tsx @@ -10,6 +10,7 @@ import { import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events'; import { useSongUrl } from '/@/renderer/features/player/audio-player/hooks/use-stream-url'; import { PlayerOnProgressProps } from '/@/renderer/features/player/audio-player/types'; +import { usePlayer } from '/@/renderer/features/player/context/player-context'; import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio'; import { useMpvSettings, @@ -193,6 +194,8 @@ export function WebPlayer() { }); }, [mediaAutoNext, volume]); + const player = usePlayer(); + usePlayerEvents( { onCurrentSongChange: () => { @@ -266,6 +269,9 @@ export function WebPlayer() { const volume = properties.volume; playerRef.current?.setVolume(volume); }, + onQueueCleared: () => { + player.mediaStop(); + }, }, [volume, num, isTransitioning, transitionType, audioFadeOnStatusChange], ); diff --git a/src/renderer/store/player.store.ts b/src/renderer/store/player.store.ts index 730d726a2..1c76124a6 100644 --- a/src/renderer/store/player.store.ts +++ b/src/renderer/store/player.store.ts @@ -2538,6 +2538,21 @@ export const subscribePlayerShuffle = ( ); }; +export const subscribeQueueCleared = (onChange: () => void) => { + return usePlayerStoreBase.subscribe( + (state) => state.queue, + (queue, prevQueue) => { + // Detect if queue became empty + const wasNotEmpty = prevQueue.default.length > 0 || prevQueue.priority.length > 0; + const isEmpty = queue.default.length === 0 && queue.priority.length === 0; + + if (wasNotEmpty && isEmpty) { + onChange(); + } + }, + ); +}; + export const usePlayerProperties = () => { return usePlayerStoreBase( useShallow((state) => ({