Migrate to Mantine v8 and Design Changes (#961)

* mantine v8 migration

* various design changes and improvements
This commit is contained in:
Jeff 2025-06-24 00:04:36 -07:00 committed by GitHub
parent bea55d48a8
commit c1330d92b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
473 changed files with 12469 additions and 11607 deletions

View file

@ -1,9 +1,7 @@
import { SelectItem } from '@mantine/core';
import isElectron from 'is-electron';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Select, Slider, Switch, toast } from '/@/renderer/components';
import {
SettingOption,
SettingsSection,
@ -11,6 +9,10 @@ import {
import { useCurrentStatus, usePlayerStore } from '/@/renderer/store';
import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store';
import { setQueue } from '/@/renderer/utils/set-transcoded-queue-data';
import { Select } from '/@/shared/components/select/select';
import { Slider } from '/@/shared/components/slider/slider';
import { Switch } from '/@/shared/components/switch/switch';
import { toast } from '/@/shared/components/toast/toast';
import { CrossfadeStyle, PlaybackStyle, PlaybackType, PlayerStatus } from '/@/shared/types/types';
const getAudioDevice = async () => {
@ -24,7 +26,7 @@ export const AudioSettings = ({ hasFancyAudio }: { hasFancyAudio: boolean }) =>
const { setSettings } = useSettingsStoreActions();
const status = useCurrentStatus();
const [audioDevices, setAudioDevices] = useState<SelectItem[]>([]);
const [audioDevices, setAudioDevices] = useState<{ label: string; value: string }[]>([]);
useEffect(() => {
const getAudioDevices = () => {

View file

@ -1,31 +1,21 @@
import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { languages } from '/@/i18n/i18n';
import {
MultiSelect,
MultiSelectProps,
NumberInput,
Select,
Switch,
TextInput,
} from '/@/renderer/components';
import {
SettingOption,
SettingsSection,
} from '/@/renderer/features/settings/components/settings-section';
import { useLyricsSettings, useSettingsStoreActions } from '/@/renderer/store';
import { MultiSelect } from '/@/shared/components/multi-select/multi-select';
import { NumberInput } from '/@/shared/components/number-input/number-input';
import { Select } from '/@/shared/components/select/select';
import { Switch } from '/@/shared/components/switch/switch';
import { TextInput } from '/@/shared/components/text-input/text-input';
import { LyricSource } from '/@/shared/types/domain-types';
const localSettings = isElectron() ? window.api.localSettings : null;
const WorkingButtonSelect = styled(MultiSelect)<MultiSelectProps>`
& button {
padding: 0;
}
`;
export const LyricSettings = () => {
const { t } = useTranslation();
const settings = useLyricsSettings();
@ -77,17 +67,17 @@ export const LyricSettings = () => {
},
{
control: (
<WorkingButtonSelect
<MultiSelect
aria-label="Lyric providers"
clearable
data={Object.values(LyricSource)}
defaultValue={settings.sources}
onChange={(e: LyricSource[]) => {
onChange={(e: string[]) => {
localSettings?.set('lyrics', e);
setSettings({
lyrics: {
...settings,
sources: e,
sources: e.map((source) => source as LyricSource),
},
});
}}

View file

@ -1,18 +1,7 @@
import { Group, Stack } from '@mantine/core';
import isElectron from 'is-electron';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { RiCloseLine, RiRestartLine } from 'react-icons/ri';
import {
Button,
NumberInput,
Select,
Switch,
Text,
Textarea,
TextInput,
} from '/@/renderer/components';
import {
SettingOption,
SettingsSection,
@ -24,6 +13,15 @@ import {
useSettingsStore,
useSettingsStoreActions,
} from '/@/renderer/store/settings.store';
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
import { Group } from '/@/shared/components/group/group';
import { NumberInput } from '/@/shared/components/number-input/number-input';
import { Select } from '/@/shared/components/select/select';
import { Stack } from '/@/shared/components/stack/stack';
import { Switch } from '/@/shared/components/switch/switch';
import { TextInput } from '/@/shared/components/text-input/text-input';
import { Text } from '/@/shared/components/text/text';
import { Textarea } from '/@/shared/components/textarea/textarea';
import { PlaybackType } from '/@/shared/types/types';
const localSettings = isElectron() ? window.api.localSettings : null;
@ -79,7 +77,9 @@ export const MpvSettings = () => {
const { pause } = usePlayerControls();
const { clearQueue } = useQueueControls();
const [mpvPath, setMpvPath] = useState('');
const [mpvPath, setMpvPath] = useState(
(localSettings?.get('mpv_path') as string | undefined) || '',
);
const handleSetMpvPath = async (clear?: boolean) => {
if (clear) {
@ -157,35 +157,34 @@ export const MpvSettings = () => {
const options: SettingOption[] = [
{
control: (
<Group spacing="sm">
<Button
<Group gap="sm">
<ActionIcon
icon="refresh"
onClick={handleReloadMpv}
tooltip={{
label: t('common.reload', { postProcess: 'titleCase' }),
openDelay: 0,
}}
variant="subtle"
>
<RiRestartLine />
</Button>
/>
<TextInput
onChange={(e) => {
setMpvPath(e.currentTarget.value);
// Transform backslashes to forward slashes
const transformedValue = e.currentTarget.value.replace(/\\/g, '/');
localSettings?.set('mpv_path', transformedValue);
}}
onClick={() => handleSetMpvPath()}
rightSection={
mpvPath && (
<Button
compact
<ActionIcon
icon="x"
onClick={() => handleSetMpvPath(true)}
tooltip={{
label: t('common.clear', { postProcess: 'titleCase' }),
openDelay: 0,
}}
variant="subtle"
>
<RiCloseLine />
</Button>
variant="transparent"
/>
)
}
type="button"
value={mpvPath}
width={200}
/>
@ -201,7 +200,7 @@ export const MpvSettings = () => {
},
{
control: (
<Stack spacing="xs">
<Stack gap="xs">
<Textarea
autosize
defaultValue={settings.mpvExtraParameters.join('\n')}
@ -218,10 +217,10 @@ export const MpvSettings = () => {
</Stack>
),
description: (
<Stack spacing={0}>
<Stack gap={0}>
<Text
$noSelect
$secondary
isMuted
isNoSelect
size="sm"
>
{t('setting.mpvExtraParameters', {
@ -288,7 +287,7 @@ export const MpvSettings = () => {
handleSetMpvProperty('audioSampleRateHz', value >= 8000 ? value : value);
}}
placeholder="48000"
rightSection="Hz"
rightSection={<Text size="xs">Hz</Text>}
width={100}
/>
),

View file

@ -1,4 +1,3 @@
import { Stack } from '@mantine/core';
import isElectron from 'is-electron';
import { lazy, Suspense, useMemo } from 'react';
@ -7,6 +6,7 @@ import { LyricSettings } from '/@/renderer/features/settings/components/playback
import { ScrobbleSettings } from '/@/renderer/features/settings/components/playback/scrobble-settings';
import { TranscodeSettings } from '/@/renderer/features/settings/components/playback/transcode-settings';
import { useSettingsStore } from '/@/renderer/store';
import { Stack } from '/@/shared/components/stack/stack';
import { PlaybackType } from '/@/shared/types/types';
const MpvSettings = lazy(() =>
@ -27,7 +27,7 @@ export const PlaybackTab = () => {
}, [audioType, useWebAudio]);
return (
<Stack spacing="md">
<Stack gap="md">
<AudioSettings hasFancyAudio={hasFancyAudio} />
<Suspense fallback={<></>}>{hasFancyAudio && <MpvSettings />}</Suspense>
<TranscodeSettings />

View file

@ -1,11 +1,13 @@
import { useTranslation } from 'react-i18next';
import { NumberInput, Slider, Switch } from '/@/renderer/components';
import {
SettingOption,
SettingsSection,
} from '/@/renderer/features/settings/components/settings-section';
import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store';
import { NumberInput } from '/@/shared/components/number-input/number-input';
import { Slider } from '/@/shared/components/slider/slider';
import { Switch } from '/@/shared/components/switch/switch';
export const ScrobbleSettings = () => {
const { t } = useTranslation();
@ -79,7 +81,7 @@ export const ScrobbleSettings = () => {
...settings,
scrobble: {
...settings.scrobble,
scrobbleAtDuration: e,
scrobbleAtDuration: Number(e),
},
},
});

View file

@ -1,11 +1,13 @@
import { useTranslation } from 'react-i18next';
import { NumberInput, Switch, TextInput } from '/@/renderer/components';
import {
SettingOption,
SettingsSection,
} from '/@/renderer/features/settings/components/settings-section';
import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store';
import { NumberInput } from '/@/shared/components/number-input/number-input';
import { Switch } from '/@/shared/components/switch/switch';
import { TextInput } from '/@/shared/components/text-input/text-input';
export const TranscodeSettings = () => {
const { t } = useTranslation();