mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +02:00
refactor feature hooks to be conditionally initialized
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { SetActivity, StatusDisplayType } from '@xhayper/discord-rpc';
|
||||
import isElectron from 'is-electron';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { useItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
useLastfmApiKey,
|
||||
usePlayerSong,
|
||||
usePlayerStore,
|
||||
useSettingsStore,
|
||||
useTimestampStoreBase,
|
||||
} from '/@/renderer/store';
|
||||
import { sentenceCase } from '/@/renderer/utils';
|
||||
@@ -410,3 +411,21 @@ export const useDiscordRpc = () => {
|
||||
setActivity,
|
||||
]);
|
||||
};
|
||||
|
||||
const DiscordRpcHookInner = () => {
|
||||
useDiscordRpc();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const DiscordRpcHook = () => {
|
||||
const isElectronEnv = isElectron();
|
||||
const isDiscordRpcEnabled = useSettingsStore((state) => state.discord.enabled);
|
||||
const isPrivateMode = useAppStore((state) => state.privateMode);
|
||||
const discordRpc = isElectronEnv ? window.api.discordRpc : null;
|
||||
|
||||
if (!isElectronEnv || !discordRpc || !isDiscordRpcEnabled || isPrivateMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(DiscordRpcHookInner);
|
||||
};
|
||||
|
||||
@@ -150,3 +150,19 @@ export const useMainPlayerListener = () => {
|
||||
toggleShuffle,
|
||||
]);
|
||||
};
|
||||
|
||||
const MainPlayerListenerHookInner = () => {
|
||||
useMainPlayerListener();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const MainPlayerListenerHook = () => {
|
||||
const isElectronEnv = isElectron();
|
||||
const mpvPlayerListener = isElectronEnv ? window.api.mpvPlayerListener : null;
|
||||
|
||||
if (mpvPlayerListener === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <MainPlayerListenerHookInner />;
|
||||
};
|
||||
|
||||
@@ -3,24 +3,24 @@ import { useEffect } from 'react';
|
||||
|
||||
import { eventEmitter } from '/@/renderer/events/event-emitter';
|
||||
import { UserFavoriteEventPayload, UserRatingEventPayload } from '/@/renderer/events/events';
|
||||
import { useDiscordRpc } from '/@/renderer/features/discord-rpc/use-discord-rpc';
|
||||
import { useMainPlayerListener } from '/@/renderer/features/player/audio-player/hooks/use-main-player-listener';
|
||||
import { DiscordRpcHook } from '/@/renderer/features/discord-rpc/use-discord-rpc';
|
||||
import { MainPlayerListenerHook } from '/@/renderer/features/player/audio-player/hooks/use-main-player-listener';
|
||||
import { MpvPlayer } from '/@/renderer/features/player/audio-player/mpv-player';
|
||||
import { WebPlayer } from '/@/renderer/features/player/audio-player/web-player';
|
||||
import { useAutoDJ } from '/@/renderer/features/player/hooks/use-auto-dj';
|
||||
import { useMediaSession } from '/@/renderer/features/player/hooks/use-media-session';
|
||||
import { useMPRIS } from '/@/renderer/features/player/hooks/use-mpris';
|
||||
import { usePlaybackHotkeys } from '/@/renderer/features/player/hooks/use-playback-hotkeys';
|
||||
import { usePowerSaveBlocker } from '/@/renderer/features/player/hooks/use-power-save-blocker';
|
||||
import { useQueueRestoreTimestamp } from '/@/renderer/features/player/hooks/use-queue-restore';
|
||||
import { useScrobble } from '/@/renderer/features/player/hooks/use-scrobble';
|
||||
import { useUpdateCurrentSong } from '/@/renderer/features/player/hooks/use-update-current-song';
|
||||
import { AutoDJHook } from '/@/renderer/features/player/hooks/use-auto-dj';
|
||||
import { MediaSessionHook } from '/@/renderer/features/player/hooks/use-media-session';
|
||||
import { MPRISHook } from '/@/renderer/features/player/hooks/use-mpris';
|
||||
import { PlaybackHotkeysHook } from '/@/renderer/features/player/hooks/use-playback-hotkeys';
|
||||
import { PowerSaveBlockerHook } from '/@/renderer/features/player/hooks/use-power-save-blocker';
|
||||
import { QueueRestoreTimestampHook } from '/@/renderer/features/player/hooks/use-queue-restore';
|
||||
import { ScrobbleHook } from '/@/renderer/features/player/hooks/use-scrobble';
|
||||
import { UpdateCurrentSongHook } from '/@/renderer/features/player/hooks/use-update-current-song';
|
||||
import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio';
|
||||
import { RadioWebPlayer } from '/@/renderer/features/radio/components/radio-web-player';
|
||||
import {
|
||||
RadioAudioInstanceHook,
|
||||
RadioMetadataHook,
|
||||
useIsRadioActive,
|
||||
useRadioAudioInstance,
|
||||
useRadioMetadata,
|
||||
} from '/@/renderer/features/radio/hooks/use-radio-player';
|
||||
import {
|
||||
updateQueueFavorites,
|
||||
@@ -46,19 +46,54 @@ export const AudioPlayers = () => {
|
||||
} = usePlaybackSettings();
|
||||
const { setWebAudio, webAudio: audioContext } = useWebAudio();
|
||||
|
||||
useScrobble();
|
||||
usePowerSaveBlocker();
|
||||
useDiscordRpc();
|
||||
useMPRIS();
|
||||
useMainPlayerListener();
|
||||
useMediaSession();
|
||||
usePlaybackHotkeys();
|
||||
useAutoDJ();
|
||||
useQueueRestoreTimestamp();
|
||||
useUpdateCurrentSong();
|
||||
return (
|
||||
<>
|
||||
<ScrobbleHook />
|
||||
<PowerSaveBlockerHook />
|
||||
<DiscordRpcHook />
|
||||
<MPRISHook />
|
||||
<MainPlayerListenerHook />
|
||||
<MediaSessionHook />
|
||||
<PlaybackHotkeysHook />
|
||||
<AutoDJHook />
|
||||
<QueueRestoreTimestampHook />
|
||||
<UpdateCurrentSongHook />
|
||||
<RadioAudioInstanceHook />
|
||||
<RadioMetadataHook />
|
||||
<AudioPlayersContent
|
||||
audioContext={audioContext}
|
||||
audioDeviceId={audioDeviceId}
|
||||
audioSampleRateHz={audioSampleRateHz}
|
||||
playbackType={playbackType}
|
||||
resetSampleRate={resetSampleRate}
|
||||
serverId={serverId}
|
||||
setWebAudio={setWebAudio}
|
||||
webAudio={webAudio}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
useRadioAudioInstance();
|
||||
useRadioMetadata();
|
||||
const AudioPlayersContent = ({
|
||||
audioContext,
|
||||
audioDeviceId,
|
||||
audioSampleRateHz,
|
||||
playbackType,
|
||||
resetSampleRate,
|
||||
serverId,
|
||||
setWebAudio,
|
||||
webAudio,
|
||||
}: {
|
||||
audioContext: ReturnType<typeof useWebAudio>['webAudio'];
|
||||
audioDeviceId: null | string | undefined;
|
||||
audioSampleRateHz: number | undefined;
|
||||
playbackType: PlayerType;
|
||||
resetSampleRate: ReturnType<typeof useSettingsStoreActions>['resetSampleRate'];
|
||||
serverId: null | string;
|
||||
setWebAudio: ReturnType<typeof useWebAudio>['setWebAudio'];
|
||||
webAudio: boolean;
|
||||
}) => {
|
||||
const isRadioActive = useIsRadioActive();
|
||||
|
||||
useEffect(() => {
|
||||
if (webAudio && 'AudioContext' in window) {
|
||||
@@ -143,8 +178,6 @@ export const AudioPlayers = () => {
|
||||
};
|
||||
}, [serverId]);
|
||||
|
||||
const isRadioActive = useIsRadioActive();
|
||||
|
||||
if (isRadioActive && playbackType === PlayerType.LOCAL) {
|
||||
return <MpvPlayer />;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { useEffect } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { eventEmitter } from '/@/renderer/events/event-emitter';
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
useCurrentServerId,
|
||||
usePlayerStore,
|
||||
usePlayerStoreBase,
|
||||
useSettingsStore,
|
||||
} from '/@/renderer/store';
|
||||
import { LogCategory, logFn } from '/@/renderer/utils/logger';
|
||||
import { logMsg } from '/@/renderer/utils/logger-message';
|
||||
@@ -232,3 +233,18 @@ export const useAutoDJ = () => {
|
||||
settings.timing,
|
||||
]);
|
||||
};
|
||||
|
||||
const AutoDJHookInner = () => {
|
||||
useAutoDJ();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const AutoDJHook = () => {
|
||||
const isAutoDJEnabled = useSettingsStore((state) => state.autoDJ.enabled);
|
||||
|
||||
if (!isAutoDJEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(AutoDJHookInner);
|
||||
};
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import isElectron from 'is-electron';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import React, { 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,
|
||||
usePlaybackType,
|
||||
usePlayerStore,
|
||||
useSettingsStore,
|
||||
useSkipButtons,
|
||||
@@ -143,3 +144,25 @@ export const useMediaSession = () => {
|
||||
[isMediaSessionEnabled, mediaSession],
|
||||
);
|
||||
};
|
||||
|
||||
const MediaSessionHookInner = () => {
|
||||
useMediaSession();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const MediaSessionHook = () => {
|
||||
const isElectronEnv = isElectron();
|
||||
const playbackType = usePlaybackType();
|
||||
const isMediaSessionEnabled = useSettingsStore((state) => state.playback.mediaSession);
|
||||
|
||||
// We always want to enable media session when on web
|
||||
// Otherwise, only enable if it is explicitly enabled in the settings AND using the web player
|
||||
const shouldUseMediaSession =
|
||||
!isElectronEnv || (isMediaSessionEnabled && playbackType === PlayerType.WEB);
|
||||
|
||||
if (!shouldUseMediaSession) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(MediaSessionHookInner);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import isElectron from 'is-electron';
|
||||
import { useEffect } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { useItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
||||
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
||||
@@ -119,3 +119,20 @@ export const useMPRIS = () => {
|
||||
[],
|
||||
);
|
||||
};
|
||||
|
||||
const MPRISHookInner = () => {
|
||||
useMPRIS();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const MPRISHook = () => {
|
||||
const isElectronEnv = isElectron();
|
||||
const utils = isElectronEnv ? window.api.utils : null;
|
||||
const mpris = isElectronEnv && utils?.isLinux() ? window.api.mpris : null;
|
||||
|
||||
if (mpris === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(MPRISHookInner);
|
||||
};
|
||||
|
||||
@@ -38,3 +38,8 @@ export const usePlaybackHotkeys = () => {
|
||||
|
||||
useHotkeys(playbackHotkeysItems);
|
||||
};
|
||||
|
||||
export const PlaybackHotkeysHook = () => {
|
||||
usePlaybackHotkeys();
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import isElectron from 'is-electron';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
|
||||
import { usePlayerStatus } from '/@/renderer/store';
|
||||
import { useWindowSettings } from '/@/renderer/store';
|
||||
import { usePlayerStatus, useSettingsStore, useWindowSettings } from '/@/renderer/store';
|
||||
import { PlayerStatus } from '/@/shared/types/types';
|
||||
|
||||
const ipc = isElectron() ? window.api.ipc : null;
|
||||
@@ -48,3 +47,19 @@ export const usePowerSaveBlocker = () => {
|
||||
};
|
||||
}, [stopPowerSaveBlocker]);
|
||||
};
|
||||
|
||||
const PowerSaveBlockerHookInner = () => {
|
||||
usePowerSaveBlocker();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const PowerSaveBlockerHook = () => {
|
||||
const isElectronEnv = isElectron();
|
||||
const preventSleepOnPlayback = useSettingsStore((state) => state.window.preventSleepOnPlayback);
|
||||
|
||||
if (!isElectronEnv || !preventSleepOnPlayback) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(PowerSaveBlockerHookInner);
|
||||
};
|
||||
|
||||
@@ -32,6 +32,11 @@ export const useQueueRestoreTimestamp = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const QueueRestoreTimestampHook = () => {
|
||||
useQueueRestoreTimestamp();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const useSaveQueue = () => {
|
||||
const serverId = useCurrentServerId();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { useItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
||||
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
usePlaybackSettings,
|
||||
usePlayerSong,
|
||||
usePlayerStore,
|
||||
useSettingsStore,
|
||||
useTimestampStoreBase,
|
||||
} from '/@/renderer/store';
|
||||
import { LogCategory, logFn } from '/@/renderer/utils/logger';
|
||||
@@ -425,3 +426,19 @@ export const useScrobble = () => {
|
||||
[handleScrobbleFromSongChange, handleProgressUpdate, handleScrobbleFromSeek],
|
||||
);
|
||||
};
|
||||
|
||||
const ScrobbleHookInner = () => {
|
||||
useScrobble();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const ScrobbleHook = () => {
|
||||
const isScrobbleEnabled = useSettingsStore((state) => state.playback.scrobble.enabled);
|
||||
const privateMode = useAppStore((state) => state.privateMode);
|
||||
|
||||
if (!isScrobbleEnabled || privateMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(ScrobbleHookInner);
|
||||
};
|
||||
|
||||
@@ -80,3 +80,8 @@ export const useUpdateCurrentSong = () => {
|
||||
[handleSongChange],
|
||||
);
|
||||
};
|
||||
|
||||
export const UpdateCurrentSongHook = () => {
|
||||
useUpdateCurrentSong();
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import IcecastMetadataStats from 'icecast-metadata-stats';
|
||||
import isElectron from 'is-electron';
|
||||
import { useEffect } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { createWithEqualityFn } from 'zustand/traditional';
|
||||
|
||||
import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events';
|
||||
@@ -287,3 +287,33 @@ export const useRadioMetadata = () => {
|
||||
};
|
||||
}, [currentStreamUrl, setMetadata, isUsingMpv]);
|
||||
};
|
||||
|
||||
const RadioAudioInstanceHookInner = () => {
|
||||
useRadioAudioInstance();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const RadioAudioInstanceHook = () => {
|
||||
const isRadioActive = useIsRadioActive();
|
||||
|
||||
if (!isRadioActive) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(RadioAudioInstanceHookInner);
|
||||
};
|
||||
|
||||
const RadioMetadataHookInner = () => {
|
||||
useRadioMetadata();
|
||||
return null;
|
||||
};
|
||||
|
||||
export const RadioMetadataHook = () => {
|
||||
const isRadioActive = useIsRadioActive();
|
||||
|
||||
if (!isRadioActive) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return React.createElement(RadioMetadataHookInner);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user