mirror of
https://github.com/jeffvli/feishin.git
synced 2026-07-05 10:09:58 +02:00
add "stopped" playback state and event handlers
This commit is contained in:
@@ -124,7 +124,12 @@ ipcMain.on('update-volume', (_event, volume) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('update-playback', (_event, status: PlayerStatus) => {
|
ipcMain.on('update-playback', (_event, status: PlayerStatus) => {
|
||||||
mprisPlayer.playbackStatus = status === PlayerStatus.PLAYING ? 'Playing' : 'Paused';
|
mprisPlayer.playbackStatus =
|
||||||
|
status === PlayerStatus.PLAYING
|
||||||
|
? 'Playing'
|
||||||
|
: status === PlayerStatus.STOPPED
|
||||||
|
? 'Stopped'
|
||||||
|
: 'Paused';
|
||||||
});
|
});
|
||||||
|
|
||||||
const REPEAT_TO_MPRIS: Record<PlayerRepeat, string> = {
|
const REPEAT_TO_MPRIS: Record<PlayerRepeat, string> = {
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export const RemoteContainer = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (status === PlayerStatus.PLAYING) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
send({ event: 'pause' });
|
send({ event: 'pause' });
|
||||||
} else if (status === PlayerStatus.PAUSED) {
|
} else {
|
||||||
send({ event: 'play' });
|
send({ event: 'play' });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export type EventMap = {
|
|||||||
MPV_RELOAD: MpvReloadEventPayload;
|
MPV_RELOAD: MpvReloadEventPayload;
|
||||||
PLAYER_PLAY: PlayerPlayEventPayload;
|
PLAYER_PLAY: PlayerPlayEventPayload;
|
||||||
PLAYER_REPEATED: PlayerRepeatedEventPayload;
|
PLAYER_REPEATED: PlayerRepeatedEventPayload;
|
||||||
|
PLAYER_STOP: PlayerStopEventPayload;
|
||||||
PLAYLIST_MOVE_DOWN: PlaylistMoveEventPayload;
|
PLAYLIST_MOVE_DOWN: PlaylistMoveEventPayload;
|
||||||
PLAYLIST_MOVE_TO_BOTTOM: PlaylistMoveEventPayload;
|
PLAYLIST_MOVE_TO_BOTTOM: PlaylistMoveEventPayload;
|
||||||
PLAYLIST_MOVE_TO_TOP: PlaylistMoveEventPayload;
|
PLAYLIST_MOVE_TO_TOP: PlaylistMoveEventPayload;
|
||||||
@@ -54,6 +55,12 @@ export type PlayerRepeatedEventPayload = {
|
|||||||
index: number;
|
index: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type PlayerStopEventPayload = {
|
||||||
|
id?: string;
|
||||||
|
index?: number;
|
||||||
|
reset: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export type PlaylistMoveEventPayload = {
|
export type PlaylistMoveEventPayload = {
|
||||||
playlistId: string;
|
playlistId: string;
|
||||||
sourceIds: string[];
|
sourceIds: string[];
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ export const MpvPlayerEngine = (props: MpvPlayerEngineProps) => {
|
|||||||
|
|
||||||
if (playerStatus === PlayerStatus.PLAYING) {
|
if (playerStatus === PlayerStatus.PLAYING) {
|
||||||
mpvPlayer.play();
|
mpvPlayer.play();
|
||||||
} else if (playerStatus === PlayerStatus.PAUSED) {
|
} else {
|
||||||
mpvPlayer.pause();
|
mpvPlayer.pause();
|
||||||
}
|
}
|
||||||
}, [playerStatus]);
|
}, [playerStatus]);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ interface PlayerEventsCallbacks {
|
|||||||
) => void;
|
) => void;
|
||||||
onPlayerSpeed?: (properties: { speed: number }, prev: { speed: number }) => void;
|
onPlayerSpeed?: (properties: { speed: number }, prev: { speed: number }) => void;
|
||||||
onPlayerStatus?: (properties: { status: PlayerStatus }, prev: { status: PlayerStatus }) => void;
|
onPlayerStatus?: (properties: { status: PlayerStatus }, prev: { status: PlayerStatus }) => void;
|
||||||
|
onPlayerStop?: (properties: { id?: string; index?: number; reset: boolean }) => void;
|
||||||
onPlayerVolume?: (properties: { volume: number }, prev: { volume: number }) => void;
|
onPlayerVolume?: (properties: { volume: number }, prev: { volume: number }) => void;
|
||||||
onQueueCleared?: () => void;
|
onQueueCleared?: () => void;
|
||||||
onQueueRestored?: (properties: { data: Song[]; index: number; position: number }) => void;
|
onQueueRestored?: (properties: { data: Song[]; index: number; position: number }) => void;
|
||||||
@@ -166,6 +167,10 @@ function createPlayerEvents(callbacks: PlayerEventsCallbacks): PlayerEvents {
|
|||||||
eventEmitter.on('PLAYER_REPEATED', callbacks.onPlayerRepeated);
|
eventEmitter.on('PLAYER_REPEATED', callbacks.onPlayerRepeated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (callbacks.onPlayerStop) {
|
||||||
|
eventEmitter.on('PLAYER_STOP', callbacks.onPlayerStop);
|
||||||
|
}
|
||||||
|
|
||||||
if (callbacks.onQueueRestored) {
|
if (callbacks.onQueueRestored) {
|
||||||
eventEmitter.on('QUEUE_RESTORED', callbacks.onQueueRestored);
|
eventEmitter.on('QUEUE_RESTORED', callbacks.onQueueRestored);
|
||||||
}
|
}
|
||||||
@@ -193,6 +198,9 @@ function createPlayerEvents(callbacks: PlayerEventsCallbacks): PlayerEvents {
|
|||||||
if (callbacks.onPlayerRepeated) {
|
if (callbacks.onPlayerRepeated) {
|
||||||
eventEmitter.off('PLAYER_REPEATED', callbacks.onPlayerRepeated);
|
eventEmitter.off('PLAYER_REPEATED', callbacks.onPlayerRepeated);
|
||||||
}
|
}
|
||||||
|
if (callbacks.onPlayerStop) {
|
||||||
|
eventEmitter.off('PLAYER_STOP', callbacks.onPlayerStop);
|
||||||
|
}
|
||||||
if (callbacks.onQueueRestored) {
|
if (callbacks.onQueueRestored) {
|
||||||
eventEmitter.off('QUEUE_RESTORED', callbacks.onQueueRestored);
|
eventEmitter.off('QUEUE_RESTORED', callbacks.onQueueRestored);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,12 +69,12 @@ export function MpvPlayer() {
|
|||||||
}, PLAY_PAUSE_FADE_INTERVAL);
|
}, PLAY_PAUSE_FADE_INTERVAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
await promise;
|
|
||||||
setLocalPlayerStatus(status);
|
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
setLocalPlayerStatus(status);
|
setLocalPlayerStatus(status);
|
||||||
await promise;
|
await promise;
|
||||||
|
} else {
|
||||||
|
await promise;
|
||||||
|
setLocalPlayerStatus(status);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
@@ -111,18 +111,18 @@ export function MpvPlayer() {
|
|||||||
const status = properties.status;
|
const status = properties.status;
|
||||||
const volume = usePlayerStore.getState().player.volume;
|
const volume = usePlayerStore.getState().player.volume;
|
||||||
if (audioFadeOnStatusChange) {
|
if (audioFadeOnStatusChange) {
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
fadeAndSetStatus(volume, 0, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PAUSED);
|
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
fadeAndSetStatus(0, volume, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PLAYING);
|
fadeAndSetStatus(0, volume, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PLAYING);
|
||||||
|
} else {
|
||||||
|
fadeAndSetStatus(volume, 0, PLAY_PAUSE_FADE_DURATION, status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
playerRef.current?.setVolume(0);
|
|
||||||
setLocalPlayerStatus(PlayerStatus.PAUSED);
|
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
playerRef.current?.setVolume(volume);
|
playerRef.current?.setVolume(volume);
|
||||||
setLocalPlayerStatus(PlayerStatus.PLAYING);
|
setLocalPlayerStatus(PlayerStatus.PLAYING);
|
||||||
|
} else {
|
||||||
|
playerRef.current?.setVolume(0);
|
||||||
|
setLocalPlayerStatus(status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ export function WaveSurferPlayer() {
|
|||||||
}, PLAY_PAUSE_FADE_INTERVAL);
|
}, PLAY_PAUSE_FADE_INTERVAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
await promise;
|
|
||||||
setLocalPlayerStatus(status);
|
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
setLocalPlayerStatus(status);
|
setLocalPlayerStatus(status);
|
||||||
await promise;
|
await promise;
|
||||||
|
} else {
|
||||||
|
await promise;
|
||||||
|
setLocalPlayerStatus(status);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isTransitioning],
|
[isTransitioning],
|
||||||
@@ -190,10 +190,10 @@ export function WaveSurferPlayer() {
|
|||||||
},
|
},
|
||||||
onPlayerStatus: async (properties) => {
|
onPlayerStatus: async (properties) => {
|
||||||
const status = properties.status;
|
const status = properties.status;
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
fadeAndSetStatus(volume, 0, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PAUSED);
|
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
fadeAndSetStatus(0, volume, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PLAYING);
|
fadeAndSetStatus(0, volume, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PLAYING);
|
||||||
|
} else {
|
||||||
|
fadeAndSetStatus(volume, 0, PLAY_PAUSE_FADE_DURATION, status);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onPlayerVolume: (properties) => {
|
onPlayerVolume: (properties) => {
|
||||||
|
|||||||
@@ -89,13 +89,13 @@ export function WebPlayer() {
|
|||||||
}, PLAY_PAUSE_FADE_INTERVAL);
|
}, PLAY_PAUSE_FADE_INTERVAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
|
setLocalPlayerStatus(status);
|
||||||
|
await promise;
|
||||||
|
} else {
|
||||||
await promise;
|
await promise;
|
||||||
setLocalPlayerStatus(status);
|
setLocalPlayerStatus(status);
|
||||||
playerRef.current?.setVolume(startVolume);
|
playerRef.current?.setVolume(startVolume);
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
setLocalPlayerStatus(status);
|
|
||||||
await promise;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
@@ -241,7 +241,7 @@ export function WebPlayer() {
|
|||||||
// If mediaAutoNext resulted in a paused state (e.g. end of queue,
|
// If mediaAutoNext resulted in a paused state (e.g. end of queue,
|
||||||
// or pauseOnNextSongEnd flag), stop all audio instead of restoring volume.
|
// or pauseOnNextSongEnd flag), stop all audio instead of restoring volume.
|
||||||
const currentStatus = usePlayerStoreBase.getState().player.status;
|
const currentStatus = usePlayerStoreBase.getState().player.status;
|
||||||
if (currentStatus === PlayerStatus.PAUSED) {
|
if (currentStatus !== PlayerStatus.PLAYING) {
|
||||||
playerRef.current?.pause();
|
playerRef.current?.pause();
|
||||||
} else {
|
} else {
|
||||||
playerRef.current?.setVolume(volume);
|
playerRef.current?.setVolume(volume);
|
||||||
@@ -260,7 +260,7 @@ export function WebPlayer() {
|
|||||||
playerRef.current?.player2()?.ref?.getInternalPlayer().pause();
|
playerRef.current?.player2()?.ref?.getInternalPlayer().pause();
|
||||||
|
|
||||||
const currentStatus = usePlayerStoreBase.getState().player.status;
|
const currentStatus = usePlayerStoreBase.getState().player.status;
|
||||||
if (currentStatus === PlayerStatus.PAUSED) {
|
if (currentStatus !== PlayerStatus.PLAYING) {
|
||||||
playerRef.current?.pause();
|
playerRef.current?.pause();
|
||||||
} else {
|
} else {
|
||||||
playerRef.current?.setVolume(volume);
|
playerRef.current?.setVolume(volume);
|
||||||
@@ -313,9 +313,9 @@ export function WebPlayer() {
|
|||||||
|
|
||||||
const status = properties.status;
|
const status = properties.status;
|
||||||
|
|
||||||
// Reset crossfade transition if paused during a crossfade transition
|
// Reset crossfade transition if paused/stopped during a crossfade transition
|
||||||
if (
|
if (
|
||||||
status === PlayerStatus.PAUSED &&
|
status !== PlayerStatus.PLAYING &&
|
||||||
isTransitioning &&
|
isTransitioning &&
|
||||||
transitionType === PlayerStyle.CROSSFADE
|
transitionType === PlayerStyle.CROSSFADE
|
||||||
) {
|
) {
|
||||||
@@ -331,18 +331,18 @@ export function WebPlayer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (audioFadeOnStatusChange) {
|
if (audioFadeOnStatusChange) {
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
fadeAndSetStatus(volume, 0, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PAUSED);
|
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
fadeAndSetStatus(0, volume, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PLAYING);
|
fadeAndSetStatus(0, volume, PLAY_PAUSE_FADE_DURATION, PlayerStatus.PLAYING);
|
||||||
|
} else {
|
||||||
|
fadeAndSetStatus(volume, 0, PLAY_PAUSE_FADE_DURATION, status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (status === PlayerStatus.PAUSED) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
playerRef.current?.setVolume(volume);
|
|
||||||
setLocalPlayerStatus(PlayerStatus.PAUSED);
|
|
||||||
} else if (status === PlayerStatus.PLAYING) {
|
|
||||||
playerRef.current?.setVolume(volume);
|
playerRef.current?.setVolume(volume);
|
||||||
setLocalPlayerStatus(PlayerStatus.PLAYING);
|
setLocalPlayerStatus(PlayerStatus.PLAYING);
|
||||||
|
} else {
|
||||||
|
playerRef.current?.setVolume(volume);
|
||||||
|
setLocalPlayerStatus(status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ const CenterPlayButton = ({ disabled }: { disabled?: boolean }) => {
|
|||||||
return (
|
return (
|
||||||
<MainPlayButton
|
<MainPlayButton
|
||||||
disabled={disabled || currentSongId === undefined}
|
disabled={disabled || currentSongId === undefined}
|
||||||
isPaused={status === PlayerStatus.PAUSED}
|
isPaused={status !== PlayerStatus.PLAYING}
|
||||||
onClick={mediaTogglePlayPause}
|
onClick={mediaTogglePlayPause}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export const MobileFullscreenPlayerControls = memo(
|
|||||||
/>
|
/>
|
||||||
<MainPlayButton
|
<MainPlayButton
|
||||||
disabled={currentSongId === undefined}
|
disabled={currentSongId === undefined}
|
||||||
isPaused={status === PlayerStatus.PAUSED}
|
isPaused={status !== PlayerStatus.PLAYING}
|
||||||
onClick={mediaTogglePlayPause}
|
onClick={mediaTogglePlayPause}
|
||||||
style={{
|
style={{
|
||||||
height: '50px',
|
height: '50px',
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ export const MobilePlayerbar = () => {
|
|||||||
/>
|
/>
|
||||||
<MainPlayButton
|
<MainPlayButton
|
||||||
disabled={currentSong?.id === undefined}
|
disabled={currentSong?.id === undefined}
|
||||||
isPaused={status === PlayerStatus.PAUSED}
|
isPaused={status !== PlayerStatus.PLAYING}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
mediaTogglePlayPause();
|
mediaTogglePlayPause();
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ export const useScrobble = () => {
|
|||||||
const previousSongRef = useRef<QueueSong | undefined>(undefined);
|
const previousSongRef = useRef<QueueSong | undefined>(undefined);
|
||||||
const previousTimestampRef = useRef<number>(0);
|
const previousTimestampRef = useRef<number>(0);
|
||||||
const stopPositionRef = useRef<number>(0);
|
const stopPositionRef = useRef<number>(0);
|
||||||
|
const stoppedSongIdRef = useRef<string | undefined>(undefined);
|
||||||
const lastProgressEventRef = useRef<number>(0);
|
const lastProgressEventRef = useRef<number>(0);
|
||||||
const lastSeekEventRef = useRef<number>(0);
|
const lastSeekEventRef = useRef<number>(0);
|
||||||
const songChangeTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
const songChangeTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||||
@@ -499,6 +500,12 @@ export const useScrobble = () => {
|
|||||||
|
|
||||||
const currentStatus = usePlayerStore.getState().player.status;
|
const currentStatus = usePlayerStore.getState().player.status;
|
||||||
|
|
||||||
|
// Stop resets seek position; the stop event is reported by handleScrobbleFromStatus.
|
||||||
|
if (currentStatus === PlayerStatus.STOPPED) {
|
||||||
|
flushScrobbleDebug();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sendScrobble.mutate(
|
sendScrobble.mutate(
|
||||||
{
|
{
|
||||||
apiClientProps: { serverId: currentSong._serverId || '' },
|
apiClientProps: { serverId: currentSong._serverId || '' },
|
||||||
@@ -608,6 +615,71 @@ export const useScrobble = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send start event when resuming the same song that was stopped.
|
||||||
|
if (
|
||||||
|
properties.status === PlayerStatus.PLAYING &&
|
||||||
|
prev.status === PlayerStatus.STOPPED &&
|
||||||
|
stoppedSongIdRef.current === currentSong._uniqueId
|
||||||
|
) {
|
||||||
|
stoppedSongIdRef.current = undefined;
|
||||||
|
sendScrobble.mutate(
|
||||||
|
{
|
||||||
|
apiClientProps: { serverId: currentSong._serverId || '' },
|
||||||
|
query: {
|
||||||
|
albumId: currentSong.albumId,
|
||||||
|
event: 'start',
|
||||||
|
id: currentSong.id,
|
||||||
|
mediaType: mediaType,
|
||||||
|
playbackRate: playbackRate,
|
||||||
|
position: getPositionValue(currentTimestamp, useTicks),
|
||||||
|
submission: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
logFn.debug(logMsg[LogCategory.SCROBBLE].scrobbledStart, {
|
||||||
|
category: LogCategory.SCROBBLE,
|
||||||
|
meta: {
|
||||||
|
id: currentSong.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send stop event when status changes to stopped (from an active state)
|
||||||
|
if (
|
||||||
|
properties.status === PlayerStatus.STOPPED &&
|
||||||
|
prev.status !== PlayerStatus.STOPPED
|
||||||
|
) {
|
||||||
|
stoppedSongIdRef.current = currentSong._uniqueId;
|
||||||
|
sendScrobble.mutate(
|
||||||
|
{
|
||||||
|
apiClientProps: { serverId: currentSong._serverId || '' },
|
||||||
|
query: {
|
||||||
|
albumId: currentSong.albumId,
|
||||||
|
event: 'stop',
|
||||||
|
id: currentSong.id,
|
||||||
|
mediaType: mediaType,
|
||||||
|
playbackRate: playbackRate,
|
||||||
|
position: getPositionValue(currentTimestamp, useTicks),
|
||||||
|
submission: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
logFn.debug(logMsg[LogCategory.SCROBBLE].scrobbledStop, {
|
||||||
|
category: LogCategory.SCROBBLE,
|
||||||
|
meta: {
|
||||||
|
id: currentSong.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
flushScrobbleDebug();
|
flushScrobbleDebug();
|
||||||
},
|
},
|
||||||
[isScrobbleEnabled, isPrivateModeEnabled, flushScrobbleDebug, sendScrobble, playbackRate],
|
[isScrobbleEnabled, isPrivateModeEnabled, flushScrobbleDebug, sendScrobble, playbackRate],
|
||||||
|
|||||||
@@ -1235,12 +1235,26 @@ export const usePlayerStoreBase = createWithEqualityFn<PlayerState>()(
|
|||||||
mediaStop: (options?: { reset?: boolean }) => {
|
mediaStop: (options?: { reset?: boolean }) => {
|
||||||
const reset = options?.reset !== false;
|
const reset = options?.reset !== false;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.player.status = PlayerStatus.PAUSED;
|
state.player.status = PlayerStatus.STOPPED;
|
||||||
setTimestampStore(0);
|
setTimestampStore(0);
|
||||||
if (reset) {
|
if (reset) {
|
||||||
state.player.seekToTimestamp = uniqueSeekToTimestamp(0);
|
state.player.seekToTimestamp = uniqueSeekToTimestamp(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const currentState = get();
|
||||||
|
const queue = currentState.getQueue();
|
||||||
|
const currentIndex = currentState.player.index;
|
||||||
|
const currentSong = queue.items[currentIndex];
|
||||||
|
|
||||||
|
eventEmitter.emit('PLAYER_STOP', {
|
||||||
|
id: currentSong?._uniqueId,
|
||||||
|
index:
|
||||||
|
currentIndex !== undefined && currentIndex >= 0
|
||||||
|
? currentIndex
|
||||||
|
: undefined,
|
||||||
|
reset,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
mediaToggleMute: () => {
|
mediaToggleMute: () => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ export enum PlayerShuffle {
|
|||||||
export enum PlayerStatus {
|
export enum PlayerStatus {
|
||||||
PAUSED = 'paused',
|
PAUSED = 'paused',
|
||||||
PLAYING = 'playing',
|
PLAYING = 'playing',
|
||||||
|
STOPPED = 'stopped',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum PlayerStyle {
|
export enum PlayerStyle {
|
||||||
|
|||||||
Reference in New Issue
Block a user