mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
resend mediasession on player repeat (#1472)
This commit is contained in:
@@ -11,6 +11,7 @@ export type EventMap = {
|
|||||||
MEDIA_NEXT: MediaNextEventPayload;
|
MEDIA_NEXT: MediaNextEventPayload;
|
||||||
MEDIA_PREV: MediaPrevEventPayload;
|
MEDIA_PREV: MediaPrevEventPayload;
|
||||||
PLAYER_PLAY: PlayerPlayEventPayload;
|
PLAYER_PLAY: PlayerPlayEventPayload;
|
||||||
|
PLAYER_REPEATED: PlayerRepeatedEventPayload;
|
||||||
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;
|
||||||
@@ -46,6 +47,10 @@ export type PlayerPlayEventPayload = {
|
|||||||
index: number;
|
index: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type PlayerRepeatedEventPayload = {
|
||||||
|
index: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type PlaylistMoveEventPayload = {
|
export type PlaylistMoveEventPayload = {
|
||||||
playlistId: string;
|
playlistId: string;
|
||||||
sourceIds: string[];
|
sourceIds: string[];
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ interface PlayerEventsCallbacks {
|
|||||||
onPlayerProgress?: (properties: { timestamp: number }, prev: { timestamp: number }) => void;
|
onPlayerProgress?: (properties: { timestamp: number }, prev: { timestamp: number }) => void;
|
||||||
onPlayerQueueChange?: (queue: QueueData, prev: QueueData) => void;
|
onPlayerQueueChange?: (queue: QueueData, prev: QueueData) => void;
|
||||||
onPlayerRepeat?: (properties: { repeat: PlayerRepeat }, prev: { repeat: PlayerRepeat }) => void;
|
onPlayerRepeat?: (properties: { repeat: PlayerRepeat }, prev: { repeat: PlayerRepeat }) => void;
|
||||||
|
onPlayerRepeated?: (properties: { index: number }) => void;
|
||||||
onPlayerSeek?: (properties: { seconds: number }, prev: { seconds: number }) => void;
|
onPlayerSeek?: (properties: { seconds: number }, prev: { seconds: number }) => void;
|
||||||
onPlayerSeekToTimestamp?: (
|
onPlayerSeekToTimestamp?: (
|
||||||
properties: { timestamp: number },
|
properties: { timestamp: number },
|
||||||
@@ -161,6 +162,10 @@ function createPlayerEvents(callbacks: PlayerEventsCallbacks): PlayerEvents {
|
|||||||
eventEmitter.on('PLAYER_PLAY', callbacks.onPlayerPlay);
|
eventEmitter.on('PLAYER_PLAY', callbacks.onPlayerPlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (callbacks.onPlayerRepeated) {
|
||||||
|
eventEmitter.on('PLAYER_REPEATED', callbacks.onPlayerRepeated);
|
||||||
|
}
|
||||||
|
|
||||||
if (callbacks.onQueueRestored) {
|
if (callbacks.onQueueRestored) {
|
||||||
eventEmitter.on('QUEUE_RESTORED', callbacks.onQueueRestored);
|
eventEmitter.on('QUEUE_RESTORED', callbacks.onQueueRestored);
|
||||||
}
|
}
|
||||||
@@ -185,6 +190,9 @@ function createPlayerEvents(callbacks: PlayerEventsCallbacks): PlayerEvents {
|
|||||||
if (callbacks.onPlayerPlay) {
|
if (callbacks.onPlayerPlay) {
|
||||||
eventEmitter.off('PLAYER_PLAY', callbacks.onPlayerPlay);
|
eventEmitter.off('PLAYER_PLAY', callbacks.onPlayerPlay);
|
||||||
}
|
}
|
||||||
|
if (callbacks.onPlayerRepeated) {
|
||||||
|
eventEmitter.off('PLAYER_REPEATED', callbacks.onPlayerRepeated);
|
||||||
|
}
|
||||||
if (callbacks.onQueueRestored) {
|
if (callbacks.onQueueRestored) {
|
||||||
eventEmitter.off('QUEUE_RESTORED', callbacks.onQueueRestored);
|
eventEmitter.off('QUEUE_RESTORED', callbacks.onQueueRestored);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
import isElectron from 'is-electron';
|
import isElectron from 'is-electron';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useCallback, useEffect, useMemo } from 'react';
|
||||||
|
|
||||||
import { getItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
import { getItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
||||||
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
||||||
import { usePlayer } from '/@/renderer/features/player/context/player-context';
|
import { usePlayer } from '/@/renderer/features/player/context/player-context';
|
||||||
import { usePlaybackSettings, useSettingsStore, useTimestampStoreBase } from '/@/renderer/store';
|
import {
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
usePlaybackSettings,
|
||||||
|
usePlayerStore,
|
||||||
|
useSettingsStore,
|
||||||
|
useTimestampStoreBase,
|
||||||
|
} from '/@/renderer/store';
|
||||||
|
import { LibraryItem, QueueSong } from '/@/shared/types/domain-types';
|
||||||
import { PlayerStatus, PlayerType } from '/@/shared/types/types';
|
import { PlayerStatus, PlayerType } from '/@/shared/types/types';
|
||||||
|
|
||||||
const mediaSession = navigator.mediaSession;
|
const mediaSession = navigator.mediaSession;
|
||||||
@@ -85,14 +90,12 @@ export const useMediaSession = () => {
|
|||||||
};
|
};
|
||||||
}, [player, skip?.skipBackwardSeconds, skip?.skipForwardSeconds, isMediaSessionEnabled]);
|
}, [player, skip?.skipBackwardSeconds, skip?.skipForwardSeconds, isMediaSessionEnabled]);
|
||||||
|
|
||||||
usePlayerEvents(
|
const updateMediaSessionMetadata = useCallback(
|
||||||
{
|
(song: QueueSong | undefined) => {
|
||||||
onCurrentSongChange: (properties) => {
|
if (!isMediaSessionEnabled || !song) {
|
||||||
if (!isMediaSessionEnabled) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const song = properties.song;
|
|
||||||
const imageUrl = getItemImageUrl({
|
const imageUrl = getItemImageUrl({
|
||||||
id: song?.imageId || undefined,
|
id: song?.imageId || undefined,
|
||||||
imageUrl: song?.imageUrl,
|
imageUrl: song?.imageUrl,
|
||||||
@@ -107,6 +110,26 @@ export const useMediaSession = () => {
|
|||||||
title: song?.name ?? '',
|
title: song?.name ?? '',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
[isMediaSessionEnabled],
|
||||||
|
);
|
||||||
|
|
||||||
|
usePlayerEvents(
|
||||||
|
{
|
||||||
|
onCurrentSongChange: (properties) => {
|
||||||
|
if (!isMediaSessionEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMediaSessionMetadata(properties.song);
|
||||||
|
},
|
||||||
|
onPlayerRepeated: () => {
|
||||||
|
if (!isMediaSessionEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentSong = usePlayerStore.getState().getCurrentSong();
|
||||||
|
updateMediaSessionMetadata(currentSong);
|
||||||
|
},
|
||||||
onPlayerStatus: (properties) => {
|
onPlayerStatus: (properties) => {
|
||||||
if (!isMediaSessionEnabled) {
|
if (!isMediaSessionEnabled) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1367,6 +1367,12 @@ export const usePlayerStoreBase = createWithEqualityFn<PlayerState>()(
|
|||||||
state.player.status = newStatus;
|
state.player.status = newStatus;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (repeat === PlayerRepeat.ONE && nextIndex === currentIndex) {
|
||||||
|
eventEmitter.emit('PLAYER_REPEATED', {
|
||||||
|
index: nextIndex,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const nextSong = calculateNextSong(nextIndex, queue.items, repeat);
|
const nextSong = calculateNextSong(nextIndex, queue.items, repeat);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user