mirror of
https://github.com/jeffvli/feishin.git
synced 2026-08-08 13:23:16 +02:00
support sidebar player in now playing route (#2134)
- add toggle to show/hide the queue in the sidebarplayer
This commit is contained in:
@@ -6,7 +6,10 @@ import {
|
||||
getDefaultAudioDevice,
|
||||
useAudioDevices,
|
||||
} from '/@/renderer/features/settings/components/playback/audio-settings';
|
||||
import { ListConfigTable } from '/@/renderer/features/shared/components/list-config-menu';
|
||||
import {
|
||||
ListConfigBooleanControl,
|
||||
ListConfigTable,
|
||||
} from '/@/renderer/features/shared/components/list-config-menu';
|
||||
import {
|
||||
usePlaybackType,
|
||||
usePlayerActions,
|
||||
@@ -22,16 +25,18 @@ import {
|
||||
useSettingsStore,
|
||||
useSettingsStoreActions,
|
||||
useShowLyricsInSidebar,
|
||||
useShowQueueInSidebar,
|
||||
useShowVisualizerInSidebar,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { Paper } from '/@/shared/components/paper/paper';
|
||||
import { Popover } from '/@/shared/components/popover/popover';
|
||||
import { SegmentedControl } from '/@/shared/components/segmented-control/segmented-control';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
import { Slider } from '/@/shared/components/slider/slider';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { CrossfadeStyle, PlayerStatus, PlayerStyle, PlayerType } from '/@/shared/types/types';
|
||||
|
||||
@@ -41,8 +46,10 @@ export const PlayerConfig = () => {
|
||||
const { t } = useTranslation();
|
||||
const preservePitch = useSettingsStore((state) => state.playback.preservePitch);
|
||||
const showLyricsInSidebar = useShowLyricsInSidebar();
|
||||
const showQueueInSidebar = useShowQueueInSidebar();
|
||||
const showVisualizerInSidebar = useShowVisualizerInSidebar();
|
||||
const combinedLyricsAndVisualizer = useCombinedLyricsAndVisualizer();
|
||||
const { transitionType } = usePlayerProperties();
|
||||
|
||||
const playbackSettings = usePlaybackSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
@@ -56,8 +63,8 @@ export const PlayerConfig = () => {
|
||||
[playbackSettings, setSettings],
|
||||
);
|
||||
|
||||
const options = useMemo(() => {
|
||||
const allOptions = [
|
||||
const audioOptions = useMemo(
|
||||
() => [
|
||||
{
|
||||
component: <AudioPlayerTypeConfig />,
|
||||
id: 'audioPlayerType',
|
||||
@@ -68,12 +75,12 @@ export const PlayerConfig = () => {
|
||||
id: 'audioDevice',
|
||||
label: t('setting.audioDevice'),
|
||||
},
|
||||
{
|
||||
component: null,
|
||||
id: 'divider-1',
|
||||
isDivider: true,
|
||||
label: '',
|
||||
},
|
||||
],
|
||||
[t],
|
||||
);
|
||||
|
||||
const transitionOptions = useMemo(
|
||||
() => [
|
||||
{
|
||||
component: <TransitionTypeConfig />,
|
||||
id: 'transitionType',
|
||||
@@ -82,19 +89,21 @@ export const PlayerConfig = () => {
|
||||
{
|
||||
component: <CrossfadeStyleConfig />,
|
||||
id: 'crossfadeStyle',
|
||||
isHidden: transitionType !== PlayerStyle.CROSSFADE,
|
||||
label: t('setting.crossfadeStyle'),
|
||||
},
|
||||
{
|
||||
component: <CrossfadeDurationConfig />,
|
||||
id: 'crossfadeDuration',
|
||||
isHidden: transitionType !== PlayerStyle.CROSSFADE,
|
||||
label: t('setting.crossfadeDuration'),
|
||||
},
|
||||
{
|
||||
component: null,
|
||||
id: 'divider-2',
|
||||
isDivider: true,
|
||||
label: '',
|
||||
},
|
||||
],
|
||||
[t, transitionType],
|
||||
);
|
||||
|
||||
const playbackOptions = useMemo(
|
||||
() => [
|
||||
{
|
||||
component: <PlaybackSpeedSlider />,
|
||||
id: 'playbackSpeed',
|
||||
@@ -107,31 +116,44 @@ export const PlayerConfig = () => {
|
||||
},
|
||||
{
|
||||
component: (
|
||||
<Switch
|
||||
defaultChecked={preservePitch}
|
||||
onChange={(e) => setPreservePitch(e.currentTarget.checked)}
|
||||
/>
|
||||
<ListConfigBooleanControl onChange={setPreservePitch} value={preservePitch} />
|
||||
),
|
||||
id: 'preservePitch',
|
||||
label: t('setting.preservePitch'),
|
||||
},
|
||||
{
|
||||
component: null,
|
||||
id: 'divider-3',
|
||||
isDivider: true,
|
||||
label: '',
|
||||
},
|
||||
],
|
||||
[preservePitch, setPreservePitch, t],
|
||||
);
|
||||
|
||||
const sidebarOptions = useMemo(
|
||||
() => [
|
||||
{
|
||||
component: (
|
||||
<Switch
|
||||
defaultChecked={showLyricsInSidebar}
|
||||
onChange={(e) => {
|
||||
<ListConfigBooleanControl
|
||||
onChange={(value) => {
|
||||
setSettings({
|
||||
general: {
|
||||
showLyricsInSidebar: e.currentTarget.checked,
|
||||
showQueueInSidebar: value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
value={showQueueInSidebar}
|
||||
/>
|
||||
),
|
||||
id: 'showQueueInSidebar',
|
||||
label: t('setting.showQueueInSidebar'),
|
||||
},
|
||||
{
|
||||
component: (
|
||||
<ListConfigBooleanControl
|
||||
onChange={(value) => {
|
||||
setSettings({
|
||||
general: {
|
||||
showLyricsInSidebar: value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
value={showLyricsInSidebar}
|
||||
/>
|
||||
),
|
||||
id: 'showLyricsInSidebar',
|
||||
@@ -139,15 +161,15 @@ export const PlayerConfig = () => {
|
||||
},
|
||||
{
|
||||
component: (
|
||||
<Switch
|
||||
defaultChecked={showVisualizerInSidebar}
|
||||
onChange={(e) => {
|
||||
<ListConfigBooleanControl
|
||||
onChange={(value) => {
|
||||
setSettings({
|
||||
general: {
|
||||
showVisualizerInSidebar: e.currentTarget.checked,
|
||||
showVisualizerInSidebar: value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
value={showVisualizerInSidebar}
|
||||
/>
|
||||
),
|
||||
id: 'showVisualizerInSidebar',
|
||||
@@ -155,35 +177,33 @@ export const PlayerConfig = () => {
|
||||
},
|
||||
{
|
||||
component: (
|
||||
<Switch
|
||||
defaultChecked={combinedLyricsAndVisualizer}
|
||||
onChange={(e) => {
|
||||
<ListConfigBooleanControl
|
||||
onChange={(value) => {
|
||||
setSettings({
|
||||
general: {
|
||||
combinedLyricsAndVisualizer: e.currentTarget.checked,
|
||||
combinedLyricsAndVisualizer: value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
value={combinedLyricsAndVisualizer}
|
||||
/>
|
||||
),
|
||||
id: 'combinedLyricsAndVisualizer',
|
||||
label: t('setting.combinedLyricsAndVisualizer'),
|
||||
},
|
||||
];
|
||||
|
||||
return allOptions;
|
||||
}, [
|
||||
t,
|
||||
preservePitch,
|
||||
setSettings,
|
||||
setPreservePitch,
|
||||
showLyricsInSidebar,
|
||||
showVisualizerInSidebar,
|
||||
combinedLyricsAndVisualizer,
|
||||
]);
|
||||
],
|
||||
[
|
||||
combinedLyricsAndVisualizer,
|
||||
setSettings,
|
||||
showLyricsInSidebar,
|
||||
showQueueInSidebar,
|
||||
showVisualizerInSidebar,
|
||||
t,
|
||||
],
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover position="top" width={500}>
|
||||
<Popover position="top" withArrow>
|
||||
<Popover.Target>
|
||||
<ActionIcon
|
||||
icon="mediaSettings"
|
||||
@@ -199,8 +219,21 @@ export const PlayerConfig = () => {
|
||||
variant="subtle"
|
||||
/>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
<ListConfigTable options={options} />
|
||||
<Popover.Dropdown maw={500} miw={320} onClick={(e) => e.stopPropagation()} p="sm">
|
||||
<Stack gap="sm">
|
||||
<Paper p="md" radius="md">
|
||||
<ListConfigTable options={audioOptions} />
|
||||
</Paper>
|
||||
<Paper p="md" radius="md">
|
||||
<ListConfigTable options={transitionOptions} />
|
||||
</Paper>
|
||||
<Paper p="md" radius="md">
|
||||
<ListConfigTable options={playbackOptions} />
|
||||
</Paper>
|
||||
<Paper p="md" radius="md">
|
||||
<ListConfigTable options={sidebarOptions} />
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
);
|
||||
@@ -234,6 +267,7 @@ const AudioPlayerTypeConfig = () => {
|
||||
value: e,
|
||||
});
|
||||
}}
|
||||
variant="filled"
|
||||
width="100%"
|
||||
/>
|
||||
);
|
||||
@@ -268,6 +302,7 @@ const AudioDeviceConfig = () => {
|
||||
});
|
||||
}}
|
||||
value={audioDeviceId ?? getDefaultAudioDevice(audioDevices, playbackType)}
|
||||
variant="filled"
|
||||
width="100%"
|
||||
/>
|
||||
);
|
||||
@@ -331,6 +366,7 @@ const CrossfadeStyleConfig = () => {
|
||||
setCrossfadeStyle(e as CrossfadeStyle);
|
||||
}
|
||||
}}
|
||||
variant="filled"
|
||||
width="100%"
|
||||
/>
|
||||
);
|
||||
@@ -406,7 +442,7 @@ export const PlaybackSpeedSlider = () => {
|
||||
root: {},
|
||||
}}
|
||||
value={speed}
|
||||
w="100%"
|
||||
w="240px"
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -435,8 +471,9 @@ export const PitchControls = () => {
|
||||
<Button
|
||||
aria-label="-1 semitone"
|
||||
fullWidth
|
||||
fw={400}
|
||||
onClick={() => adjustMusicalSpeed(-1)}
|
||||
size="compact-xs"
|
||||
size="compact-sm"
|
||||
>
|
||||
-1st
|
||||
</Button>
|
||||
@@ -444,13 +481,14 @@ export const PitchControls = () => {
|
||||
<Button
|
||||
aria-label="-10 cents"
|
||||
fullWidth
|
||||
fw={400}
|
||||
onClick={() => adjustMusicalSpeed(-0.1)}
|
||||
size="compact-xs"
|
||||
size="compact-sm"
|
||||
>
|
||||
-10ct
|
||||
</Button>
|
||||
)}
|
||||
<Text size="xs" style={{ fontFamily: 'monospace' }} ta="center" w="60px">
|
||||
<Text size="sm" style={{ fontFamily: 'monospace' }} ta="center">
|
||||
{speed.toFixed(2)}x {speedToPitch(speed) > 0 && '+'}
|
||||
{speedToPitch(speed) == 0 && '±'}
|
||||
{speedToPitch(speed).toFixed(2)}st
|
||||
@@ -459,8 +497,9 @@ export const PitchControls = () => {
|
||||
<Button
|
||||
aria-label="+10 cents"
|
||||
fullWidth
|
||||
fw={400}
|
||||
onClick={() => adjustMusicalSpeed(0.1)}
|
||||
size="compact-xs"
|
||||
size="compact-sm"
|
||||
>
|
||||
+10ct
|
||||
</Button>
|
||||
@@ -468,8 +507,9 @@ export const PitchControls = () => {
|
||||
<Button
|
||||
aria-label="+1 semitone"
|
||||
fullWidth
|
||||
fw={400}
|
||||
onClick={() => adjustMusicalSpeed(1)}
|
||||
size="compact-xs"
|
||||
size="compact-sm"
|
||||
>
|
||||
+1st
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user