mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 02:13:33 +00:00
Add localization support (#333)
* Add updated i18n config and en locale
This commit is contained in:
parent
11863fd4c1
commit
8430b1ec95
90 changed files with 2679 additions and 908 deletions
|
|
@ -10,8 +10,10 @@ import {
|
|||
useGeneralSettings,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { FontType } from '/@/renderer/types';
|
||||
import i18n, { languages } from '/@/i18n/i18n';
|
||||
|
||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||
const ipc = isElectron() ? window.electron.ipc : null;
|
||||
|
|
@ -33,17 +35,32 @@ const FONT_OPTIONS: Font[] = [
|
|||
{ label: 'Work Sans', value: 'Work Sans' },
|
||||
];
|
||||
|
||||
const FONT_TYPES: Font[] = [{ label: 'Built-in font', value: FontType.BUILT_IN }];
|
||||
const FONT_TYPES: Font[] = [
|
||||
{
|
||||
label: i18n.t('setting.fontType', {
|
||||
context: 'optionBuiltIn',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
value: FontType.BUILT_IN,
|
||||
},
|
||||
];
|
||||
|
||||
if (window.queryLocalFonts) {
|
||||
FONT_TYPES.push({ label: 'System font', value: FontType.SYSTEM });
|
||||
FONT_TYPES.push({
|
||||
label: i18n.t('setting.fontType', { context: 'optionSystem', postProcess: 'sentenceCase' }),
|
||||
value: FontType.SYSTEM,
|
||||
});
|
||||
}
|
||||
|
||||
if (isElectron()) {
|
||||
FONT_TYPES.push({ label: 'Custom font', value: FontType.CUSTOM });
|
||||
FONT_TYPES.push({
|
||||
label: i18n.t('setting.fontType', { context: 'optionCustom', postProcess: 'sentenceCase' }),
|
||||
value: FontType.CUSTOM,
|
||||
});
|
||||
}
|
||||
|
||||
export const ApplicationSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const settings = useGeneralSettings();
|
||||
const fontSettings = useFontSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
|
@ -100,7 +117,9 @@ export const ApplicationSettings = () => {
|
|||
const status = await navigator.permissions.query({ name: 'local-fonts' });
|
||||
|
||||
if (status.state === 'denied') {
|
||||
throw new Error('Access denied to local fonts');
|
||||
throw new Error(
|
||||
t('error.localFontAccessDenied', { postProcess: 'sentenceCase' }),
|
||||
);
|
||||
}
|
||||
|
||||
const data = await window.queryLocalFonts();
|
||||
|
|
@ -112,7 +131,7 @@ export const ApplicationSettings = () => {
|
|||
);
|
||||
} catch (error) {
|
||||
toast.error({
|
||||
message: 'An error occurred when trying to get system fonts',
|
||||
message: t('error.systemFontError', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
|
||||
setSettings({
|
||||
|
|
@ -125,19 +144,32 @@ export const ApplicationSettings = () => {
|
|||
}
|
||||
};
|
||||
getFonts();
|
||||
}, [fontSettings, localFonts, setSettings]);
|
||||
}, [fontSettings, localFonts, setSettings, t]);
|
||||
|
||||
const handleChangeLanguage = (e: string) => {
|
||||
setSettings({
|
||||
general: {
|
||||
...settings,
|
||||
language: e,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const options: SettingOption[] = [
|
||||
{
|
||||
control: (
|
||||
<Select
|
||||
disabled
|
||||
data={[]}
|
||||
data={languages}
|
||||
value={settings.language}
|
||||
onChange={handleChangeLanguage}
|
||||
/>
|
||||
),
|
||||
description: 'Sets the application language',
|
||||
description: t('setting.language', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Language',
|
||||
title: t('setting.language', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -155,10 +187,12 @@ export const ApplicationSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
'What font to use. Built-in font selects one of the fonts provided by Feishin. System font allows you to select any font provided by your OS. Custom allows you to provide your own font',
|
||||
description: t('setting.fontType', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: FONT_TYPES.length === 1,
|
||||
title: 'Use system font',
|
||||
title: t('setting.fontType', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -177,9 +211,9 @@ export const ApplicationSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Sets the application content font',
|
||||
description: t('setting.font', { context: 'description', postProcess: 'sentenceCase' }),
|
||||
isHidden: localFonts && fontSettings.type !== FontType.BUILT_IN,
|
||||
title: 'Font (Content)',
|
||||
title: t('setting.font', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -199,9 +233,9 @@ export const ApplicationSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Sets the application content font',
|
||||
description: t('setting.font', { context: 'description', postProcess: 'sentenceCase' }),
|
||||
isHidden: !localFonts || fontSettings.type !== FontType.SYSTEM,
|
||||
title: 'Font (Content)',
|
||||
title: t('setting.font', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -219,9 +253,12 @@ export const ApplicationSettings = () => {
|
|||
}
|
||||
/>
|
||||
),
|
||||
description: 'Path to custom font',
|
||||
description: t('setting.customFontPath', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: fontSettings.type !== FontType.CUSTOM,
|
||||
title: 'Path to custom font',
|
||||
title: t('setting.customFontPath', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -244,9 +281,14 @@ export const ApplicationSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Sets the application zoom factor in percent',
|
||||
description: t('setting.zoom', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: 'Zoom factor',
|
||||
title: t('setting.zoom', {
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import isElectron from 'is-electron';
|
||||
import { Group } from '@mantine/core';
|
||||
import { t } from 'i18next';
|
||||
import isElectron from 'is-electron';
|
||||
import { Select, Tooltip, NumberInput, Switch, Slider } from '/@/renderer/components';
|
||||
import { SettingsSection } from '/@/renderer/features/settings/components/settings-section';
|
||||
import {
|
||||
|
|
@ -8,15 +9,29 @@ import {
|
|||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { Play } from '/@/renderer/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||
|
||||
const SIDE_QUEUE_OPTIONS = [
|
||||
{ label: 'Fixed', value: 'sideQueue' },
|
||||
{ label: 'Floating', value: 'sideDrawerQueue' },
|
||||
{
|
||||
label: t('setting.sidePlayQueueStyle', {
|
||||
context: 'optionAttached',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
value: 'sideQueue',
|
||||
},
|
||||
{
|
||||
label: t('setting.sidePlayQueueStyle', {
|
||||
context: 'optionDetached',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
value: 'sideDrawerQueue',
|
||||
},
|
||||
];
|
||||
|
||||
export const ControlSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const settings = useGeneralSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
|
|
@ -39,14 +54,17 @@ export const ControlSettings = () => {
|
|||
}
|
||||
/>
|
||||
),
|
||||
description: 'Show or hide the skip buttons on the playerbar',
|
||||
description: t('setting.showSkipButtons', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Show skip buttons',
|
||||
title: t('setting.showSkipButtons', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Group>
|
||||
<Tooltip label="Backward">
|
||||
<Tooltip label={t('common.backward', { postProcess: 'titleCase' })}>
|
||||
<NumberInput
|
||||
defaultValue={settings.skipButtons.skipBackwardSeconds}
|
||||
min={0}
|
||||
|
|
@ -66,7 +84,7 @@ export const ControlSettings = () => {
|
|||
}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip label="Forward">
|
||||
<Tooltip label={t('common.forward', { postProcess: 'titleCase' })}>
|
||||
<NumberInput
|
||||
defaultValue={settings.skipButtons.skipForwardSeconds}
|
||||
min={0}
|
||||
|
|
@ -88,18 +106,38 @@ export const ControlSettings = () => {
|
|||
</Tooltip>
|
||||
</Group>
|
||||
),
|
||||
description:
|
||||
'The number (in seconds) to skip forward or backward when using the skip buttons',
|
||||
description: t('setting.skipDuration', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Skip duration',
|
||||
title: t('setting.skipDuration', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Select
|
||||
data={[
|
||||
{ label: 'Now', value: Play.NOW },
|
||||
{ label: 'Next', value: Play.NEXT },
|
||||
{ label: 'Last', value: Play.LAST },
|
||||
{
|
||||
label: t('setting.playButtonBehavior', {
|
||||
context: 'optionPlay',
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: Play.NOW,
|
||||
},
|
||||
{
|
||||
label: t('setting.playButtonBehavior', {
|
||||
context: 'optionAddNext',
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: Play.NEXT,
|
||||
},
|
||||
{
|
||||
label: t('setting.playButtonBehavior', {
|
||||
context: 'optionAddLast',
|
||||
postProcess: 'titleCase',
|
||||
}),
|
||||
value: Play.LAST,
|
||||
},
|
||||
]}
|
||||
defaultValue={settings.playButtonBehavior}
|
||||
onChange={(e) =>
|
||||
|
|
@ -112,9 +150,12 @@ export const ControlSettings = () => {
|
|||
}
|
||||
/>
|
||||
),
|
||||
description: 'The default behavior of the play button when adding songs to the queue',
|
||||
description: t('setting.playButtonBehavior', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Play button behavior',
|
||||
title: t('setting.playButtonBehavior', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -131,9 +172,12 @@ export const ControlSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'The style of the sidebar play queue',
|
||||
description: t('setting.sidePlayQueueStyle', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Side play queue style',
|
||||
title: t('setting.sidePlayQueueStyle', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -149,10 +193,12 @@ export const ControlSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
'Display a hover icon on the right side of the application view the play queue',
|
||||
description: t('setting.sidePlayQueueStyle', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Show floating queue hover area',
|
||||
title: t('setting.floatingQueueArea', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -171,10 +217,12 @@ export const ControlSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
'The amount of volume to change when scrolling the mouse wheel on the volume slider',
|
||||
description: t('setting.volumeWheelStep', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Volume wheel step',
|
||||
title: t('setting.volumeWheelStep', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -191,9 +239,12 @@ export const ControlSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'When exiting, save the current play queue and restore it when reopening',
|
||||
description: t('setting.savePlayQueue', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !isElectron(),
|
||||
title: 'Save play queue',
|
||||
title: t('setting.savePlayQueue', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -210,10 +261,12 @@ export const ControlSettings = () => {
|
|||
}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
'When navigating to a playlist, go to the playlist song list page instead of the default page',
|
||||
description: t('setting.skipPlaylistPage', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Go to playlist songs page by default',
|
||||
title: t('setting.skipPlaylistPage', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@ import { SettingsSection } from '/@/renderer/features/settings/components/settin
|
|||
import { useRemoteSettings, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { NumberInput, Switch, Text, TextInput, toast } from '/@/renderer/components';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const remote = isElectron() ? window.electron.remote : null;
|
||||
|
||||
export const RemoteSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const settings = useRemoteSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
|
|
@ -25,7 +27,9 @@ export const RemoteSettings = () => {
|
|||
} else {
|
||||
toast.error({
|
||||
message: errorMsg,
|
||||
title: enabled ? 'Error enabling remote' : 'Error disabling remote',
|
||||
title: enabled
|
||||
? t('error.remoteEnableError', { postProcess: 'sentenceCase' })
|
||||
: t('error.remoteDisableError', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
}
|
||||
}, 50);
|
||||
|
|
@ -40,12 +44,12 @@ export const RemoteSettings = () => {
|
|||
},
|
||||
});
|
||||
toast.warn({
|
||||
message: 'To have your port change take effect, stop and restart the server',
|
||||
message: t('error.remotePortWarning', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
} else {
|
||||
toast.error({
|
||||
message: errorMsg,
|
||||
title: 'Error setting port',
|
||||
title: t('error.remotePortError', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
|
|
@ -56,7 +60,6 @@ export const RemoteSettings = () => {
|
|||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Enable remote control server"
|
||||
defaultChecked={settings.enabled}
|
||||
onChange={async (e) => {
|
||||
const enabled = e.currentTarget.checked;
|
||||
|
|
@ -65,8 +68,15 @@ export const RemoteSettings = () => {
|
|||
/>
|
||||
),
|
||||
description: (
|
||||
<div>
|
||||
Start an HTTP server to remotely control Feishin. This will listen on{' '}
|
||||
<Text
|
||||
$noSelect
|
||||
$secondary
|
||||
size="sm"
|
||||
>
|
||||
{t('setting.enableRemote', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
})}{' '}
|
||||
<a
|
||||
href={url}
|
||||
rel="noreferrer noopener"
|
||||
|
|
@ -74,15 +84,14 @@ export const RemoteSettings = () => {
|
|||
>
|
||||
{url}
|
||||
</a>
|
||||
</div>
|
||||
</Text>
|
||||
),
|
||||
isHidden,
|
||||
title: 'Enable remote control',
|
||||
title: t('setting.enableRemote', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<NumberInput
|
||||
aria-label="Set remote port"
|
||||
max={65535}
|
||||
value={settings.port}
|
||||
onBlur={async (e) => {
|
||||
|
|
@ -92,15 +101,16 @@ export const RemoteSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
'Remote server port. Changes here only take effect when you enable the remote',
|
||||
description: t('setting.remotePort', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden,
|
||||
title: 'Remove server port',
|
||||
title: t('setting.remotePort', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<TextInput
|
||||
aria-label="Set remote username"
|
||||
defaultValue={settings.username}
|
||||
onBlur={(e) => {
|
||||
const username = e.currentTarget.value;
|
||||
|
|
@ -115,15 +125,16 @@ export const RemoteSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
'Username that must be provided to access remote. If both username and password are empty, disable authentication',
|
||||
description: t('setting.remoteUsername', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden,
|
||||
title: 'Remote username',
|
||||
title: t('setting.remoteUsername', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<TextInput
|
||||
aria-label="Set remote password"
|
||||
defaultValue={settings.password}
|
||||
onBlur={(e) => {
|
||||
const password = e.currentTarget.value;
|
||||
|
|
@ -138,22 +149,14 @@ export const RemoteSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Password to access remote',
|
||||
description: t('setting.remotePassword', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden,
|
||||
title: 'Remote password',
|
||||
title: t('setting.remotePassword', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingsSection options={controlOptions} />
|
||||
<Text size="lg">
|
||||
<b>
|
||||
NOTE: these credentials are by default transferred insecurely. Do not use a
|
||||
password you care about. Changing username/password will disconnect clients and
|
||||
require them to reauthenticate
|
||||
</b>
|
||||
</Text>
|
||||
</>
|
||||
);
|
||||
return <SettingsSection options={controlOptions} />;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { ChangeEvent, useCallback, useState } from 'react';
|
|||
import { Group } from '@mantine/core';
|
||||
import { Reorder, useDragControls } from 'framer-motion';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { MdDragIndicator } from 'react-icons/md';
|
||||
import { Button, Checkbox, Switch } from '/@/renderer/components';
|
||||
import { useSettingsStoreActions, useGeneralSettings } from '../../../../store/settings.store';
|
||||
|
|
@ -54,6 +55,7 @@ const DraggableSidebarItem = ({ item, handleChangeDisabled }: DraggableSidebarIt
|
|||
};
|
||||
|
||||
export const SidebarSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const settings = useGeneralSettings();
|
||||
const { setSidebarItems, setSettings } = useSettingsStoreActions();
|
||||
|
||||
|
|
@ -107,8 +109,11 @@ export const SidebarSettings = () => {
|
|||
onChange={handleSetSidebarPlaylistList}
|
||||
/>
|
||||
}
|
||||
description="Show playlist list in sidebar"
|
||||
title="Sidebar playlist list"
|
||||
description={t('setting.sidebarPlaylistList', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
title={t('setting.sidebarPlaylistList', { postProcess: 'sentenceCase' })}
|
||||
/>
|
||||
<SettingsOptions
|
||||
control={
|
||||
|
|
@ -117,8 +122,11 @@ export const SidebarSettings = () => {
|
|||
onChange={handleSetSidebarCollapsedNavigation}
|
||||
/>
|
||||
}
|
||||
description="Show navigation buttons in the collapsed sidebar"
|
||||
title="Sidebar (collapsed) navigation"
|
||||
description={t('setting.sidebarPlaylistList', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
title={t('setting.sidebarCollapsedNavigation', { postProcess: 'sentenceCase' })}
|
||||
/>
|
||||
<SettingsOptions
|
||||
control={
|
||||
|
|
@ -128,11 +136,14 @@ export const SidebarSettings = () => {
|
|||
variant="filled"
|
||||
onClick={handleSave}
|
||||
>
|
||||
Save sidebar configuration
|
||||
{t('common.save', { postProcess: 'titleCase' })}
|
||||
</Button>
|
||||
}
|
||||
description="Select the items and order in which they appear in the sidebar"
|
||||
title="Sidebar configuration"
|
||||
description={t('setting.sidebarCollapsedNavigation', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
title={t('setting.sidebarConfiguration', { postProcess: 'sentenceCase' })}
|
||||
/>
|
||||
<Reorder.Group
|
||||
axis="y"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ import {
|
|||
import { THEME_DATA } from '/@/renderer/hooks';
|
||||
import { useGeneralSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
import { AppTheme } from '/@/renderer/themes/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const ThemeSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const settings = useGeneralSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
|
|
@ -27,9 +29,12 @@ export const ThemeSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Follows the system-defined light or dark preference',
|
||||
description: t('setting.useSystemTheme', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: 'Use system theme',
|
||||
title: t('setting.useSystemTheme', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -46,9 +51,12 @@ export const ThemeSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Sets the default theme',
|
||||
description: t('setting.theme', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: settings.followSystemTheme,
|
||||
title: 'Theme',
|
||||
title: t('setting.theme', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -65,9 +73,12 @@ export const ThemeSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Sets the dark theme',
|
||||
description: t('setting.themeDark', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !settings.followSystemTheme,
|
||||
title: 'Theme (dark)',
|
||||
title: t('setting.themeDark', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -84,9 +95,12 @@ export const ThemeSettings = () => {
|
|||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Sets the light theme',
|
||||
description: t('setting.themeLight', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !settings.followSystemTheme,
|
||||
title: 'Theme (light)',
|
||||
title: t('setting.themeLight', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
|
|
@ -114,8 +128,11 @@ export const ThemeSettings = () => {
|
|||
<Text>{settings.accent}</Text>
|
||||
</Stack>
|
||||
),
|
||||
description: 'Sets the accent color',
|
||||
title: 'Accent color',
|
||||
description: t('setting.accentColor', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('setting.accentColor', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue