mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-08 13:00:13 +02:00
304 lines
11 KiB
TypeScript
304 lines
11 KiB
TypeScript
import isElectron from 'is-electron';
|
|
import { useEffect, useRef } from 'react';
|
|
|
|
import { getItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
|
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
|
import { useCreateFavorite } from '/@/renderer/features/shared/mutations/create-favorite-mutation';
|
|
import { useDeleteFavorite } from '/@/renderer/features/shared/mutations/delete-favorite-mutation';
|
|
import { useSetRating } from '/@/renderer/features/shared/mutations/set-rating-mutation';
|
|
import { usePlayerActions, usePlayerStore, useRemoteSettings } from '/@/renderer/store';
|
|
import { LogCategory, logFn } from '/@/renderer/utils/logger';
|
|
import { logMsg } from '/@/renderer/utils/logger-message';
|
|
import { toast } from '/@/shared/components/toast/toast';
|
|
import { LibraryItem } from '/@/shared/types/domain-types';
|
|
import { PlayerShuffle } from '/@/shared/types/types';
|
|
|
|
const remote = isElectron() ? window.api.remote : null;
|
|
const ipc = isElectron() ? window.api.ipc : null;
|
|
|
|
export const useRemote = () => {
|
|
const { mediaSkipForward, setVolume } = usePlayerActions();
|
|
const player = usePlayerStore();
|
|
|
|
const remoteSettings = useRemoteSettings();
|
|
const updateRatingMutation = useSetRating({});
|
|
const addToFavoritesMutation = useCreateFavorite({});
|
|
const removeFromFavoritesMutation = useDeleteFavorite({});
|
|
|
|
const isRemoteEnabled = remoteSettings.enabled;
|
|
|
|
// Initialize the remote
|
|
useEffect(() => {
|
|
if (!isRemoteEnabled) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].initializingRemoteSettings, {
|
|
category: LogCategory.REMOTE,
|
|
meta: {
|
|
enabled: remoteSettings.enabled,
|
|
port: remoteSettings.port,
|
|
username: remoteSettings.username,
|
|
},
|
|
});
|
|
|
|
remote
|
|
?.updateSetting(
|
|
remoteSettings.enabled,
|
|
remoteSettings.port,
|
|
remoteSettings.username,
|
|
remoteSettings.password,
|
|
)
|
|
.catch((error) => {
|
|
logFn.error(logMsg[LogCategory.REMOTE].failedToEnableRemote, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { error },
|
|
});
|
|
toast.warn({ message: error, title: 'Failed to enable remote' });
|
|
});
|
|
// We only want to fire this once
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
remote.requestPosition((_e: unknown, data: { position: number }) => {
|
|
logFn.debug(logMsg[LogCategory.REMOTE].requestPositionReceived, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { position: data.position },
|
|
});
|
|
const newTime = data.position;
|
|
player.mediaSeekToTimestamp(newTime);
|
|
});
|
|
|
|
remote.requestSeek((_e: unknown, data: { offset: number }) => {
|
|
logFn.debug(logMsg[LogCategory.REMOTE].requestSeekReceived, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { offset: data.offset },
|
|
});
|
|
mediaSkipForward(data.offset);
|
|
});
|
|
|
|
remote.requestRating(
|
|
(_e: unknown, data: { id: string; rating: number; serverId: string }) => {
|
|
logFn.debug(logMsg[LogCategory.REMOTE].requestRatingReceived, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { id: data.id, rating: data.rating, serverId: data.serverId },
|
|
});
|
|
updateRatingMutation.mutate({
|
|
apiClientProps: { serverId: data.serverId },
|
|
query: {
|
|
id: [data.id],
|
|
rating: data.rating,
|
|
type: LibraryItem.SONG,
|
|
},
|
|
});
|
|
},
|
|
);
|
|
|
|
remote.requestVolume((_e: unknown, data: { volume: number }) => {
|
|
logFn.debug(logMsg[LogCategory.REMOTE].requestVolumeReceived, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { volume: data.volume },
|
|
});
|
|
setVolume(data.volume);
|
|
});
|
|
|
|
remote.requestFavorite(
|
|
(_e: unknown, data: { favorite: boolean; id: string; serverId: string }) => {
|
|
logFn.debug(logMsg[LogCategory.REMOTE].requestFavoriteReceived, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { favorite: data.favorite, id: data.id, serverId: data.serverId },
|
|
});
|
|
const mutator = data.favorite
|
|
? addToFavoritesMutation
|
|
: removeFromFavoritesMutation;
|
|
mutator.mutate({
|
|
apiClientProps: { serverId: data.serverId },
|
|
query: {
|
|
id: [data.id],
|
|
type: LibraryItem.SONG,
|
|
},
|
|
});
|
|
},
|
|
);
|
|
|
|
return () => {
|
|
ipc?.removeAllListeners('request-position');
|
|
ipc?.removeAllListeners('request-seek');
|
|
ipc?.removeAllListeners('request-volume');
|
|
ipc?.removeAllListeners('request-favorite');
|
|
ipc?.removeAllListeners('request-rating');
|
|
};
|
|
}, [
|
|
addToFavoritesMutation,
|
|
isRemoteEnabled,
|
|
mediaSkipForward,
|
|
player,
|
|
removeFromFavoritesMutation,
|
|
setVolume,
|
|
updateRatingMutation,
|
|
]);
|
|
|
|
// Send initial song if one is already playing
|
|
const isInitializedRef = useRef(false);
|
|
useEffect(() => {
|
|
if (isInitializedRef.current || !isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
isInitializedRef.current = true;
|
|
|
|
const currentSong = player.getCurrentSong();
|
|
|
|
if (currentSong) {
|
|
logFn.debug(logMsg[LogCategory.REMOTE].sendingInitialSong, {
|
|
category: LogCategory.REMOTE,
|
|
meta: {
|
|
artistName: currentSong.artistName,
|
|
id: currentSong.id,
|
|
name: currentSong.name,
|
|
},
|
|
});
|
|
|
|
const imageUrl =
|
|
getItemImageUrl({
|
|
id: currentSong.id,
|
|
imageUrl: currentSong.imageUrl,
|
|
itemType: LibraryItem.SONG,
|
|
serverId: currentSong._serverId,
|
|
type: 'itemCard',
|
|
useRemoteUrl: true,
|
|
}) || null;
|
|
|
|
remote.updateSong(currentSong, imageUrl);
|
|
}
|
|
}, [isRemoteEnabled, player]);
|
|
|
|
usePlayerEvents(
|
|
{
|
|
onCurrentSongChange: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updateSongSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: {
|
|
artistName: properties.song?.artistName,
|
|
id: properties.song?.id,
|
|
index: properties.index,
|
|
name: properties.song?.name,
|
|
},
|
|
});
|
|
if (properties.song) {
|
|
const song = properties.song;
|
|
const imageUrl =
|
|
getItemImageUrl({
|
|
id: song.id,
|
|
imageUrl: song.imageUrl,
|
|
itemType: LibraryItem.SONG,
|
|
serverId: song._serverId,
|
|
type: 'itemCard',
|
|
useRemoteUrl: true,
|
|
}) || null;
|
|
|
|
remote.updateSong(song, imageUrl);
|
|
} else {
|
|
remote.updateSong(undefined);
|
|
}
|
|
},
|
|
onPlayerProgress: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updatePositionSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { timestamp: properties.timestamp },
|
|
});
|
|
remote.updatePosition(properties.timestamp);
|
|
},
|
|
onPlayerRepeat: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updateRepeatSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { repeat: properties.repeat },
|
|
});
|
|
remote.updateRepeat(properties.repeat);
|
|
},
|
|
onPlayerShuffle: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
const isShuffleEnabled = properties.shuffle !== PlayerShuffle.NONE;
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updateShuffleSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { isShuffleEnabled, shuffle: properties.shuffle },
|
|
});
|
|
remote.updateShuffle(isShuffleEnabled);
|
|
},
|
|
onPlayerStatus: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updatePlaybackSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { status: properties.status },
|
|
});
|
|
remote.updatePlayback(properties.status);
|
|
},
|
|
onPlayerVolume: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updateVolumeSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: { volume: properties.volume },
|
|
});
|
|
remote.updateVolume(properties.volume);
|
|
},
|
|
onUserFavorite: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updateFavoriteSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: {
|
|
favorite: properties.favorite,
|
|
id: properties.id,
|
|
serverId: properties.serverId,
|
|
},
|
|
});
|
|
remote.updateFavorite(properties.favorite, properties.serverId, properties.id);
|
|
},
|
|
onUserRating: (properties) => {
|
|
if (!isRemoteEnabled || !remote) {
|
|
return;
|
|
}
|
|
|
|
logFn.debug(logMsg[LogCategory.REMOTE].updateRatingSent, {
|
|
category: LogCategory.REMOTE,
|
|
meta: {
|
|
id: properties.id,
|
|
rating: properties.rating || 0,
|
|
serverId: properties.serverId,
|
|
},
|
|
});
|
|
remote.updateRating(properties.rating || 0, properties.serverId, properties.id);
|
|
},
|
|
},
|
|
[],
|
|
);
|
|
};
|