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