mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 18:33:33 +00:00
Move settings to route instead of modal
This commit is contained in:
parent
0c13b09029
commit
bc5f1f13f0
11 changed files with 159 additions and 151 deletions
|
|
@ -27,7 +27,7 @@ const SIDE_QUEUE_OPTIONS = [
|
|||
{ label: 'Floating', value: 'sideDrawerQueue' },
|
||||
];
|
||||
|
||||
const WINDOWBAR_OPTIONS = [
|
||||
const WINDOW_BAR_OPTIONS = [
|
||||
{ label: 'Web (hidden)', value: Platform.WEB },
|
||||
{ label: 'Windows', value: Platform.WINDOWS },
|
||||
{ label: 'macOS', value: Platform.MACOS },
|
||||
|
|
@ -41,7 +41,7 @@ export const GeneralTab = () => {
|
|||
{
|
||||
control: (
|
||||
<Select
|
||||
data={WINDOWBAR_OPTIONS}
|
||||
data={WINDOW_BAR_OPTIONS}
|
||||
disabled={!isElectron()}
|
||||
value={settings.windowBarStyle}
|
||||
onChange={(e) => {
|
||||
|
|
@ -55,9 +55,9 @@ export const GeneralTab = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Adjust the style of the windowbar',
|
||||
description: 'Adjust the style of the application window bar',
|
||||
isHidden: !isElectron(),
|
||||
title: 'Windowbar style',
|
||||
title: 'Window bar style',
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { Divider, Group, SelectItem, Stack } from '@mantine/core';
|
|||
import {
|
||||
FileInput,
|
||||
NumberInput,
|
||||
SegmentedControl,
|
||||
Select,
|
||||
Slider,
|
||||
Switch,
|
||||
|
|
@ -69,7 +68,7 @@ export const PlaybackTab = () => {
|
|||
const playerOptions = [
|
||||
{
|
||||
control: (
|
||||
<SegmentedControl
|
||||
<Select
|
||||
data={[
|
||||
{
|
||||
disabled: !isElectron(),
|
||||
|
|
@ -98,7 +97,6 @@ export const PlaybackTab = () => {
|
|||
control: (
|
||||
<FileInput
|
||||
placeholder={mpvPath}
|
||||
size="sm"
|
||||
width={225}
|
||||
onChange={handleSetMpvPath}
|
||||
/>
|
||||
|
|
@ -115,9 +113,7 @@ export const PlaybackTab = () => {
|
|||
autosize
|
||||
defaultValue={mpvParameters}
|
||||
minRows={4}
|
||||
placeholder={
|
||||
'Default parameters (one per line):\n--gapless-audio=weak\n--prefetch-playlist=yes'
|
||||
}
|
||||
placeholder={'(Add one per line):\n--gapless-audio=weak\n--prefetch-playlist=yes'}
|
||||
width={225}
|
||||
onBlur={(e) => {
|
||||
if (isElectron()) {
|
||||
|
|
@ -128,20 +124,23 @@ export const PlaybackTab = () => {
|
|||
</Stack>
|
||||
),
|
||||
description: (
|
||||
<Text
|
||||
$noSelect
|
||||
$secondary
|
||||
size="sm"
|
||||
>
|
||||
Options to pass to the player{' '}
|
||||
<a
|
||||
href="https://mpv.io/manual/stable/#audio"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
<Stack spacing={0}>
|
||||
<Text
|
||||
$noSelect
|
||||
$secondary
|
||||
>
|
||||
https://mpv.io/manual/stable/#audio
|
||||
</a>
|
||||
</Text>
|
||||
Options to pass to the player
|
||||
</Text>
|
||||
<Text>
|
||||
<a
|
||||
href="https://mpv.io/manual/stable/#audio"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
https://mpv.io/manual/stable/#audio
|
||||
</a>
|
||||
</Text>
|
||||
</Stack>
|
||||
),
|
||||
isHidden: settings.type !== PlaybackType.LOCAL,
|
||||
note: 'Restart required.',
|
||||
|
|
@ -163,7 +162,7 @@ export const PlaybackTab = () => {
|
|||
},
|
||||
{
|
||||
control: (
|
||||
<SegmentedControl
|
||||
<Select
|
||||
data={[
|
||||
{ label: 'Normal', value: PlaybackStyle.GAPLESS },
|
||||
{ label: 'Crossfade', value: PlaybackStyle.CROSSFADE },
|
||||
|
|
@ -346,7 +345,7 @@ export const PlaybackTab = () => {
|
|||
const otherOptions = [
|
||||
{
|
||||
control: (
|
||||
<SegmentedControl
|
||||
<Select
|
||||
data={[
|
||||
{ label: 'Now', value: Play.NOW },
|
||||
{ label: 'Next', value: Play.NEXT },
|
||||
|
|
@ -367,28 +366,6 @@ export const PlaybackTab = () => {
|
|||
isHidden: false,
|
||||
title: 'Play button behavior',
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Toggle skip buttons"
|
||||
defaultChecked={settings.skipButtons?.enabled}
|
||||
onChange={(e) =>
|
||||
setSettings({
|
||||
player: {
|
||||
...settings,
|
||||
skipButtons: {
|
||||
...settings.skipButtons,
|
||||
enabled: e.currentTarget.checked,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
),
|
||||
description: 'Show or hide the skip buttons on the playerbar',
|
||||
isHidden: false,
|
||||
title: 'Show skip buttons',
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Group>
|
||||
|
|
@ -437,6 +414,28 @@ export const PlaybackTab = () => {
|
|||
isHidden: false,
|
||||
title: 'Skip duration',
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Toggle skip buttons"
|
||||
defaultChecked={settings.skipButtons?.enabled}
|
||||
onChange={(e) =>
|
||||
setSettings({
|
||||
player: {
|
||||
...settings,
|
||||
skipButtons: {
|
||||
...settings.skipButtons,
|
||||
enabled: e.currentTarget.checked,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
),
|
||||
description: 'Show or hide the skip buttons on the playerbar',
|
||||
isHidden: false,
|
||||
title: 'Show skip buttons',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
@ -461,7 +460,7 @@ export const PlaybackTab = () => {
|
|||
))}
|
||||
<Text
|
||||
$secondary
|
||||
size="xs"
|
||||
size="sm"
|
||||
>
|
||||
*The scrobble will be submitted if one or more of the above conditions is met
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
import { lazy } from 'react';
|
||||
import { Box } from '@mantine/core';
|
||||
import { Tabs } from '/@/renderer/components';
|
||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
|
||||
const GeneralTab = lazy(() =>
|
||||
import('/@/renderer/features/settings/components/general-tab').then((module) => ({
|
||||
default: module.GeneralTab,
|
||||
})),
|
||||
);
|
||||
|
||||
const PlaybackTab = lazy(() =>
|
||||
import('/@/renderer/features/settings/components/playback-tab').then((module) => ({
|
||||
default: module.PlaybackTab,
|
||||
})),
|
||||
);
|
||||
|
||||
export const SettingsContent = () => {
|
||||
const currentTab = useSettingsStore((state) => state.tab);
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
return (
|
||||
<Box
|
||||
h="100%"
|
||||
p="1rem"
|
||||
sx={{ overflow: 'scroll' }}
|
||||
>
|
||||
<Tabs
|
||||
keepMounted={false}
|
||||
orientation="horizontal"
|
||||
value={currentTab}
|
||||
variant="default"
|
||||
onTabChange={(e) => e && setSettings({ tab: e })}
|
||||
>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="general">General</Tabs.Tab>
|
||||
<Tabs.Tab value="playback">Playback</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel value="general">
|
||||
<GeneralTab />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="playback">
|
||||
<PlaybackTab />
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { RiSettings2Fill } from 'react-icons/ri';
|
||||
import { PageHeader } from '/@/renderer/components';
|
||||
import { LibraryHeaderBar } from '/@/renderer/features/shared';
|
||||
|
||||
export const SettingsHeader = () => {
|
||||
return (
|
||||
<PageHeader>
|
||||
<LibraryHeaderBar>
|
||||
<RiSettings2Fill size="2rem" />
|
||||
<LibraryHeaderBar.Title>Settings</LibraryHeaderBar.Title>
|
||||
</LibraryHeaderBar>
|
||||
</PageHeader>
|
||||
);
|
||||
};
|
||||
|
|
@ -29,7 +29,7 @@ export const SettingsOptions = ({ title, description, control, note }: SettingsO
|
|||
<Group>
|
||||
<Text
|
||||
$noSelect
|
||||
size="sm"
|
||||
size="md"
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
import { Box } from '@mantine/core';
|
||||
import { Tabs } from '/@/renderer/components';
|
||||
import type { Variants } from 'framer-motion';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { GeneralTab } from '/@/renderer/features/settings/components/general-tab';
|
||||
import { PlaybackTab } from '/@/renderer/features/settings/components/playback-tab';
|
||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
|
||||
export const Settings = () => {
|
||||
const currentTab = useSettingsStore((state) => state.tab);
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
const tabVariants: Variants = {
|
||||
in: {
|
||||
opacity: 1,
|
||||
transition: {
|
||||
duration: 0.3,
|
||||
},
|
||||
x: 0,
|
||||
},
|
||||
out: {
|
||||
opacity: 0,
|
||||
x: 50,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
m={5}
|
||||
sx={{ height: '50vh', maxHeight: '500px', overflowX: 'hidden' }}
|
||||
>
|
||||
<AnimatePresence initial={false}>
|
||||
<Tabs
|
||||
keepMounted={false}
|
||||
orientation="vertical"
|
||||
styles={{
|
||||
tab: {
|
||||
fontSize: '1rem',
|
||||
padding: '0.5rem 1rem',
|
||||
},
|
||||
}}
|
||||
value={currentTab}
|
||||
variant="pills"
|
||||
onTabChange={(e) => e && setSettings({ tab: e })}
|
||||
>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="general">General</Tabs.Tab>
|
||||
<Tabs.Tab value="playback">Playback</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel value="general">
|
||||
<motion.div
|
||||
animate="in"
|
||||
initial="out"
|
||||
variants={tabVariants}
|
||||
>
|
||||
<GeneralTab />
|
||||
</motion.div>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="playback">
|
||||
<motion.div
|
||||
animate="in"
|
||||
initial="out"
|
||||
variants={tabVariants}
|
||||
>
|
||||
<PlaybackTab />
|
||||
</motion.div>
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</AnimatePresence>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue