mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-02 02:43:33 +00:00
Migrate to Mantine v8 and Design Changes (#961)
* mantine v8 migration * various design changes and improvements
This commit is contained in:
parent
bea55d48a8
commit
c1330d92b2
473 changed files with 12469 additions and 11607 deletions
|
|
@ -1,10 +1,9 @@
|
|||
import { Stack } from '@mantine/core';
|
||||
|
||||
import { StylesSettings } from '/@/renderer/features/settings/components/advanced/styles-settings';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
|
||||
export const AdvancedTab = () => {
|
||||
return (
|
||||
<Stack spacing="md">
|
||||
<Stack gap="md">
|
||||
<StylesSettings />
|
||||
</Stack>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
import { Code } from '@mantine/core';
|
||||
import { closeAllModals, openModal } from '@mantine/modals';
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button, ConfirmModal, Switch, Text, Textarea } from '/@/renderer/components';
|
||||
import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option';
|
||||
import { useCssSettings, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { sanitizeCss } from '/@/renderer/utils/sanitize';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { Code } from '/@/shared/components/code/code';
|
||||
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { Textarea } from '/@/shared/components/textarea/textarea';
|
||||
|
||||
export const StylesSettings = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
|
@ -82,8 +86,8 @@ export const StylesSettings = () => {
|
|||
<>
|
||||
{open && (
|
||||
<Button
|
||||
compact
|
||||
onClick={handleSave}
|
||||
size="compact-md"
|
||||
// disabled={isSaveButtonDisabled}
|
||||
variant="filled"
|
||||
>
|
||||
|
|
@ -91,8 +95,8 @@ export const StylesSettings = () => {
|
|||
</Button>
|
||||
)}
|
||||
<Button
|
||||
compact
|
||||
onClick={() => setOpen(!open)}
|
||||
size="compact-md"
|
||||
variant="filled"
|
||||
>
|
||||
{t(open ? 'common.close' : 'common.edit', {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { useCallback, useEffect, useState } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import i18n, { languages } from '/@/i18n/i18n';
|
||||
import { FileInput, NumberInput, Select, toast } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
|
|
@ -15,6 +14,10 @@ import {
|
|||
useGeneralSettings,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { FileInput } from '/@/shared/components/file-input/file-input';
|
||||
import { NumberInput } from '/@/shared/components/number-input/number-input';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { FontType } from '/@/shared/types/types';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
|
@ -148,7 +151,8 @@ export const ApplicationSettings = () => {
|
|||
getFonts();
|
||||
}, [fontSettings, localFonts, setSettings, t]);
|
||||
|
||||
const handleChangeLanguage = (e: string) => {
|
||||
const handleChangeLanguage = (e: null | string) => {
|
||||
if (!e) return;
|
||||
setSettings({
|
||||
general: {
|
||||
...settings,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
import { Divider, Stack } from '@mantine/core';
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button, Checkbox } from '/@/renderer/components';
|
||||
import {
|
||||
CONFIGURABLE_CONTEXT_MENU_ITEMS,
|
||||
CONTEXT_MENU_ITEM_MAPPING,
|
||||
} from '/@/renderer/features/context-menu';
|
||||
import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option';
|
||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { Checkbox } from '/@/shared/components/checkbox/checkbox';
|
||||
import { Divider } from '/@/shared/components/divider/divider';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
|
||||
export const ContextMenuSettings = () => {
|
||||
const disabledItems = useSettingsStore((state) => state.general.disabledContextMenu);
|
||||
|
|
@ -21,8 +23,8 @@ export const ContextMenuSettings = () => {
|
|||
<SettingsOptions
|
||||
control={
|
||||
<Button
|
||||
compact
|
||||
onClick={() => setOpen(!open)}
|
||||
size="compact-md"
|
||||
variant="filled"
|
||||
>
|
||||
{t(open ? 'common.close' : 'common.edit', { postProcess: 'titleCase' })}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { Group } from '@mantine/core';
|
||||
import { t } from 'i18next';
|
||||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { NumberInput, Select, Slider, Switch, Tooltip } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
|
|
@ -14,6 +12,13 @@ import {
|
|||
useGeneralSettings,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { NumberInput } from '/@/shared/components/number-input/number-input';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
import { Slider } from '/@/shared/components/slider/slider';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
||||
import { Play } from '/@/shared/types/types';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
|
@ -59,7 +64,7 @@ export const ControlSettings = () => {
|
|||
},
|
||||
});
|
||||
}}
|
||||
rightSection="px"
|
||||
rightSection={<Text size="sm">px</Text>}
|
||||
width={75}
|
||||
/>
|
||||
),
|
||||
|
|
@ -83,7 +88,7 @@ export const ControlSettings = () => {
|
|||
setSettings({ general: { ...settings, albumArtRes: newVal } });
|
||||
}}
|
||||
placeholder="0"
|
||||
rightSection="px"
|
||||
rightSection={<Text size="sm">px</Text>}
|
||||
value={settings.albumArtRes ?? 0}
|
||||
width={75}
|
||||
/>
|
||||
|
|
@ -346,7 +351,7 @@ export const ControlSettings = () => {
|
|||
});
|
||||
}}
|
||||
placeholder="0"
|
||||
rightSection="px"
|
||||
rightSection={<Text size="sm">px</Text>}
|
||||
width={75}
|
||||
/>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,15 +1,21 @@
|
|||
import { Group } from '@mantine/core';
|
||||
import { DragControls, Reorder, useDragControls } from 'framer-motion';
|
||||
import { MdDragIndicator } from 'react-icons/md';
|
||||
import { DragControls, Reorder, useDragControls } from 'motion/react';
|
||||
|
||||
import { Checkbox } from '/@/renderer/components';
|
||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||
import { Checkbox } from '/@/shared/components/checkbox/checkbox';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
|
||||
const DragHandle = ({ dragControls }: { dragControls: DragControls }) => {
|
||||
return (
|
||||
<MdDragIndicator
|
||||
color="white"
|
||||
<ActionIcon
|
||||
icon="dragVertical"
|
||||
iconProps={{
|
||||
size: 'md',
|
||||
}}
|
||||
onPointerDown={(event) => dragControls.start(event)}
|
||||
size="xs"
|
||||
style={{ cursor: 'grab' }}
|
||||
variant="transparent"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -36,16 +42,17 @@ export const DraggableItem = ({ handleChangeDisabled, item, value }: DraggableIt
|
|||
value={item}
|
||||
>
|
||||
<Group
|
||||
h="3rem"
|
||||
noWrap
|
||||
py="md"
|
||||
style={{ boxShadow: '0 1px 3px rgba(0,0,0,.1)' }}
|
||||
wrap="nowrap"
|
||||
>
|
||||
<Checkbox
|
||||
checked={!item.disabled}
|
||||
onChange={(e) => handleChangeDisabled(item.id, e.target.checked)}
|
||||
size="xs"
|
||||
/>
|
||||
<DragHandle dragControls={dragControls} />
|
||||
{value}
|
||||
<Text>{value}</Text>
|
||||
</Group>
|
||||
</Reorder.Item>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Divider } from '@mantine/core';
|
||||
import { Reorder } from 'framer-motion';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { Reorder } from 'motion/react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button } from '/@/renderer/components';
|
||||
import { DraggableItem } from '/@/renderer/features/settings/components/general/draggable-item';
|
||||
import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option';
|
||||
import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context';
|
||||
import { SortableItem } from '/@/renderer/store';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { Divider } from '/@/shared/components/divider/divider';
|
||||
|
||||
export type DraggableItemsProps<K, T> = {
|
||||
description: string;
|
||||
|
|
@ -85,18 +85,18 @@ export const DraggableItems = <K extends string, T extends SortableItem<K>>({
|
|||
<>
|
||||
{open && (
|
||||
<Button
|
||||
compact
|
||||
disabled={isSaveButtonDisabled}
|
||||
onClick={handleSave}
|
||||
size="compact-md"
|
||||
variant="filled"
|
||||
>
|
||||
{t('common.save', { postProcess: 'titleCase' })}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
compact
|
||||
onClick={() => setOpen(!open)}
|
||||
variant="filled"
|
||||
size="compact-md"
|
||||
variant={open ? 'subtle' : 'filled'}
|
||||
>
|
||||
{t(open ? 'common.close' : 'common.edit', { postProcess: 'titleCase' })}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { Stack } from '@mantine/core';
|
||||
import isElectron from 'is-electron';
|
||||
|
||||
import { ApplicationSettings } from '/@/renderer/features/settings/components/general/application-settings';
|
||||
|
|
@ -11,10 +10,11 @@ import { SidebarReorder } from '/@/renderer/features/settings/components/general
|
|||
import { SidebarSettings } from '/@/renderer/features/settings/components/general/sidebar-settings';
|
||||
import { ThemeSettings } from '/@/renderer/features/settings/components/general/theme-settings';
|
||||
import { CacheSettings } from '/@/renderer/features/settings/components/window/cache-settngs';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
|
||||
export const GeneralTab = () => {
|
||||
return (
|
||||
<Stack spacing="md">
|
||||
<Stack gap="md">
|
||||
<ApplicationSettings />
|
||||
<ThemeSettings />
|
||||
<ControlSettings />
|
||||
|
|
|
|||
|
|
@ -2,9 +2,13 @@ import isElectron from 'is-electron';
|
|||
import debounce from 'lodash/debounce';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { NumberInput, Switch, Text, TextInput, toast } from '/@/renderer/components';
|
||||
import { SettingsSection } from '/@/renderer/features/settings/components/settings-section';
|
||||
import { useRemoteSettings, useSettingsStoreActions } from '/@/renderer/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';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
|
||||
const remote = isElectron() ? window.api.remote : null;
|
||||
|
||||
|
|
@ -70,8 +74,8 @@ export const RemoteSettings = () => {
|
|||
),
|
||||
description: (
|
||||
<Text
|
||||
$noSelect
|
||||
$secondary
|
||||
isMuted
|
||||
isNoSelect
|
||||
size="sm"
|
||||
>
|
||||
{t('setting.enableRemote', {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Switch } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { useGeneralSettings, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
|
||||
export const SidebarSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
import { ColorInput, Stack } from '@mantine/core';
|
||||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Select, Switch } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { THEME_DATA } from '/@/renderer/hooks';
|
||||
import { useGeneralSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
import { AppTheme } from '/@/shared/types/domain-types';
|
||||
import { THEME_DATA, useSetColorScheme } from '/@/renderer/themes/use-app-theme';
|
||||
import { ColorInput } from '/@/shared/components/color-input/color-input';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { AppTheme } from '/@/shared/themes/app-theme-types';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
||||
|
|
@ -17,6 +19,7 @@ export const ThemeSettings = () => {
|
|||
const { t } = useTranslation();
|
||||
const settings = useGeneralSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
const { setColorScheme } = useSetColorScheme();
|
||||
|
||||
const themeOptions: SettingOption[] = [
|
||||
{
|
||||
|
|
@ -30,6 +33,7 @@ export const ThemeSettings = () => {
|
|||
followSystemTheme: e.currentTarget.checked,
|
||||
},
|
||||
});
|
||||
|
||||
if (localSettings) {
|
||||
localSettings.themeSet(
|
||||
e.currentTarget.checked
|
||||
|
|
@ -56,16 +60,20 @@ export const ThemeSettings = () => {
|
|||
defaultValue={settings.theme}
|
||||
onChange={(e) => {
|
||||
const theme = e as AppTheme;
|
||||
|
||||
setSettings({
|
||||
general: {
|
||||
...settings,
|
||||
theme,
|
||||
},
|
||||
});
|
||||
|
||||
const colorScheme = theme === AppTheme.DEFAULT_DARK ? 'dark' : 'light';
|
||||
|
||||
setColorScheme(colorScheme);
|
||||
|
||||
if (localSettings) {
|
||||
localSettings.themeSet(
|
||||
theme === AppTheme.DEFAULT_DARK ? 'dark' : 'light',
|
||||
);
|
||||
localSettings.themeSet(colorScheme);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
import { Group } from '@mantine/core';
|
||||
import isElectron from 'is-electron';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { ChangeEvent, KeyboardEvent, useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiDeleteBinLine, RiEditLine, RiKeyboardBoxLine } from 'react-icons/ri';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import styles from './hotkeys-manager-settings.module.css';
|
||||
|
||||
import i18n from '/@/i18n/i18n';
|
||||
import { Button, Checkbox, TextInput } from '/@/renderer/components';
|
||||
import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option';
|
||||
import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context';
|
||||
import { BindingActions, useHotkeySettings, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||
import { Checkbox } from '/@/shared/components/checkbox/checkbox';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { Icon } from '/@/shared/components/icon/icon';
|
||||
import { TextInput } from '/@/shared/components/text-input/text-input';
|
||||
|
||||
const ipc = isElectron() ? window.api.ipc : null;
|
||||
|
||||
|
|
@ -92,18 +95,6 @@ const BINDINGS_MAP: Record<BindingActions, string> = {
|
|||
zoomOut: i18n.t('setting.hotkey', { context: 'zoomOut', postProcess: 'sentenceCase' }),
|
||||
};
|
||||
|
||||
const HotkeysContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
button {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
export const HotkeyManagerSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const { bindings, globalMediaHotkeys } = useHotkeySettings();
|
||||
|
|
@ -247,11 +238,11 @@ export const HotkeyManagerSettings = () => {
|
|||
})}
|
||||
title={t('setting.applicationHotkeys', { postProcess: 'sentenceCase' })}
|
||||
/>
|
||||
<HotkeysContainer>
|
||||
<div className={styles.container}>
|
||||
{filteredBindings.map((binding) => (
|
||||
<Group
|
||||
key={`hotkey-${binding}`}
|
||||
noWrap
|
||||
wrap="nowrap"
|
||||
>
|
||||
<TextInput
|
||||
readOnly
|
||||
|
|
@ -259,8 +250,8 @@ export const HotkeyManagerSettings = () => {
|
|||
value={BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]}
|
||||
/>
|
||||
<TextInput
|
||||
icon={<RiKeyboardBoxLine />}
|
||||
id={`hotkey-${binding}`}
|
||||
leftSection={<Icon icon="keyboard" />}
|
||||
onBlur={() => setSelected(null)}
|
||||
onChange={() => {}}
|
||||
onKeyDownCapture={(e) => {
|
||||
|
|
@ -268,6 +259,16 @@ export const HotkeyManagerSettings = () => {
|
|||
handleSetHotkey(binding as BindingActions, e);
|
||||
}}
|
||||
readOnly
|
||||
rightSection={
|
||||
<ActionIcon
|
||||
icon="edit"
|
||||
onClick={() => {
|
||||
setSelected(binding as BindingActions);
|
||||
document.getElementById(`hotkey-${binding}`)?.focus();
|
||||
}}
|
||||
variant="transparent"
|
||||
/>
|
||||
}
|
||||
style={{
|
||||
opacity: selected === (binding as BindingActions) ? 0.8 : 1,
|
||||
outline: duplicateHotkeyMap.includes(
|
||||
|
|
@ -287,7 +288,7 @@ export const HotkeyManagerSettings = () => {
|
|||
onChange={(e) =>
|
||||
handleSetGlobalHotkey(binding as BindingActions, e)
|
||||
}
|
||||
size="xl"
|
||||
size="md"
|
||||
style={{
|
||||
opacity: bindings[binding as keyof typeof BINDINGS_MAP]
|
||||
.allowGlobal
|
||||
|
|
@ -296,25 +297,19 @@ export const HotkeyManagerSettings = () => {
|
|||
}}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
onClick={() => {
|
||||
setSelected(binding as BindingActions);
|
||||
document.getElementById(`hotkey-${binding}`)?.focus();
|
||||
}}
|
||||
variant="default"
|
||||
w={100}
|
||||
>
|
||||
<RiEditLine />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleClearHotkey(binding as BindingActions)}
|
||||
variant="default"
|
||||
>
|
||||
<RiDeleteBinLine />
|
||||
</Button>
|
||||
{bindings[binding as keyof typeof BINDINGS_MAP].hotkey && (
|
||||
<ActionIcon
|
||||
icon="x"
|
||||
iconProps={{
|
||||
color: 'error',
|
||||
}}
|
||||
onClick={() => handleClearHotkey(binding as BindingActions)}
|
||||
variant="transparent"
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
))}
|
||||
</HotkeysContainer>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--theme-spacing-md);
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import { Stack } from '@mantine/core';
|
||||
import isElectron from 'is-electron';
|
||||
|
||||
import { HotkeyManagerSettings } from '/@/renderer/features/settings/components/hotkeys/hotkey-manager-settings';
|
||||
import { WindowHotkeySettings } from '/@/renderer/features/settings/components/hotkeys/window-hotkey-settings';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
|
||||
export const HotkeysTab = () => {
|
||||
return (
|
||||
<Stack spacing="md">
|
||||
<Stack gap="md">
|
||||
{isElectron() && <WindowHotkeySettings />}
|
||||
<HotkeyManagerSettings />
|
||||
</Stack>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Switch } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { useHotkeySettings, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
});
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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 />
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import isElectron from 'is-electron';
|
||||
import { lazy } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Tabs } from '/@/renderer/components';
|
||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
import { Tabs } from '/@/shared/components/tabs/tabs';
|
||||
|
||||
const GeneralTab = lazy(() =>
|
||||
import('/@/renderer/features/settings/components/general/general-tab').then((module) => ({
|
||||
|
|
@ -36,23 +35,16 @@ const AdvancedTab = lazy(() =>
|
|||
})),
|
||||
);
|
||||
|
||||
const TabContainer = styled.div`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 1rem;
|
||||
overflow: scroll;
|
||||
`;
|
||||
|
||||
export const SettingsContent = () => {
|
||||
const { t } = useTranslation();
|
||||
const currentTab = useSettingsStore((state) => state.tab);
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
return (
|
||||
<TabContainer>
|
||||
<div style={{ height: '100%', overflow: 'scroll', padding: '1rem', width: '100%' }}>
|
||||
<Tabs
|
||||
keepMounted={false}
|
||||
onTabChange={(e) => e && setSettings({ tab: e })}
|
||||
onChange={(e) => e && setSettings({ tab: e })}
|
||||
orientation="horizontal"
|
||||
value={currentTab}
|
||||
variant="default"
|
||||
|
|
@ -94,6 +86,6 @@ export const SettingsContent = () => {
|
|||
<AdvancedTab />
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</TabContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
import { Flex, Group } from '@mantine/core';
|
||||
import { closeAllModals, openModal } from '@mantine/modals';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiSettings2Fill } from 'react-icons/ri';
|
||||
|
||||
import { Button, ConfirmModal, PageHeader, SearchInput } from '/@/renderer/components';
|
||||
import { PageHeader } from '/@/renderer/components/page-header/page-header';
|
||||
import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context';
|
||||
import { LibraryHeaderBar } from '/@/renderer/features/shared';
|
||||
import { SearchInput } from '/@/renderer/features/shared/components/search-input';
|
||||
import { useContainerQuery } from '/@/renderer/hooks';
|
||||
import { useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { Flex } from '/@/shared/components/flex/flex';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { Icon } from '/@/shared/components/icon/icon';
|
||||
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
|
||||
export type SettingsHeaderProps = {
|
||||
setSearch: (search: string) => void;
|
||||
|
|
@ -28,7 +33,7 @@ export const SettingsHeader = ({ setSearch }: SettingsHeaderProps) => {
|
|||
openModal({
|
||||
children: (
|
||||
<ConfirmModal onConfirm={handleResetToDefault}>
|
||||
{t('common.areYouSure', { postProcess: 'sentenceCase' })}
|
||||
<Text>{t('common.areYouSure', { postProcess: 'sentenceCase' })}</Text>
|
||||
</ConfirmModal>
|
||||
),
|
||||
title: t('common.resetToDefault', { postProcess: 'sentenceCase' }),
|
||||
|
|
@ -44,8 +49,11 @@ export const SettingsHeader = ({ setSearch }: SettingsHeaderProps) => {
|
|||
justify="space-between"
|
||||
w="100%"
|
||||
>
|
||||
<Group noWrap>
|
||||
<RiSettings2Fill size="2rem" />
|
||||
<Group wrap="nowrap">
|
||||
<Icon
|
||||
icon="settings"
|
||||
size="5xl"
|
||||
/>
|
||||
<LibraryHeaderBar.Title>
|
||||
{t('common.setting', { count: 2, postProcess: 'titleCase' })}
|
||||
</LibraryHeaderBar.Title>
|
||||
|
|
@ -56,10 +64,8 @@ export const SettingsHeader = ({ setSearch }: SettingsHeaderProps) => {
|
|||
onChange={(event) =>
|
||||
setSearch(event.target.value.toLocaleLowerCase())
|
||||
}
|
||||
openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150}
|
||||
/>
|
||||
<Button
|
||||
compact
|
||||
onClick={openResetConfirmModal}
|
||||
variant="default"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { Group, Stack } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { RiInformationLine } from 'react-icons/ri';
|
||||
|
||||
import { Text, Tooltip } from '/@/renderer/components';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { Icon } from '/@/shared/components/icon/icon';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
||||
|
||||
interface SettingsOptionProps {
|
||||
control: React.ReactNode;
|
||||
|
|
@ -15,13 +17,13 @@ export const SettingsOptions = ({ control, description, note, title }: SettingsO
|
|||
return (
|
||||
<>
|
||||
<Group
|
||||
noWrap
|
||||
position="apart"
|
||||
sx={{ alignItems: 'center' }}
|
||||
justify="space-between"
|
||||
style={{ alignItems: 'center' }}
|
||||
wrap="nowrap"
|
||||
>
|
||||
<Stack
|
||||
spacing="xs"
|
||||
sx={{
|
||||
gap="xs"
|
||||
style={{
|
||||
alignSelf: 'flex-start',
|
||||
display: 'flex',
|
||||
maxWidth: '50%',
|
||||
|
|
@ -29,7 +31,7 @@ export const SettingsOptions = ({ control, description, note, title }: SettingsO
|
|||
>
|
||||
<Group>
|
||||
<Text
|
||||
$noSelect
|
||||
isNoSelect
|
||||
size="md"
|
||||
>
|
||||
{title}
|
||||
|
|
@ -39,9 +41,7 @@ export const SettingsOptions = ({ control, description, note, title }: SettingsO
|
|||
label={note}
|
||||
openDelay={0}
|
||||
>
|
||||
<Group>
|
||||
<RiInformationLine size={15} />
|
||||
</Group>
|
||||
<Icon icon="info" />
|
||||
</Tooltip>
|
||||
)}
|
||||
</Group>
|
||||
|
|
@ -49,15 +49,15 @@ export const SettingsOptions = ({ control, description, note, title }: SettingsO
|
|||
description
|
||||
) : (
|
||||
<Text
|
||||
$noSelect
|
||||
$secondary
|
||||
isMuted
|
||||
isNoSelect
|
||||
size="sm"
|
||||
>
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
<Group position="right">{control}</Group>
|
||||
<Group justify="flex-end">{control}</Group>
|
||||
</Group>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { Divider } from '@mantine/core';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option';
|
||||
import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context';
|
||||
import { Divider } from '/@/shared/components/divider/divider';
|
||||
|
||||
export type SettingOption = {
|
||||
control: ReactNode;
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@ import isElectron from 'is-electron';
|
|||
import { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button, ConfirmModal, toast } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
|
||||
const browser = isElectron() ? window.api.browser : null;
|
||||
|
||||
|
|
@ -58,9 +60,9 @@ export const CacheSettings = () => {
|
|||
{
|
||||
control: (
|
||||
<Button
|
||||
compact
|
||||
disabled={isClearing}
|
||||
onClick={() => openResetConfirmModal(false)}
|
||||
size="compact-md"
|
||||
variant="filled"
|
||||
>
|
||||
{t('common.clear', { postProcess: 'sentenceCase' })}
|
||||
|
|
@ -75,9 +77,9 @@ export const CacheSettings = () => {
|
|||
{
|
||||
control: (
|
||||
<Button
|
||||
compact
|
||||
disabled={isClearing}
|
||||
onClick={() => openResetConfirmModal(true)}
|
||||
size="compact-md"
|
||||
variant="filled"
|
||||
>
|
||||
{t('common.clear', { postProcess: 'sentenceCase' })}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Switch, TextInput } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
|
|
@ -11,6 +10,8 @@ import {
|
|||
useGeneralSettings,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { TextInput } from '/@/shared/components/text-input/text-input';
|
||||
|
||||
export const DiscordSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
import { SelectItem } from '@mantine/core';
|
||||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Select } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { useGeneralSettings, useSettingsStoreActions } from '/@/renderer/store';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
|
||||
const PASSWORD_SETTINGS: SelectItem[] = [
|
||||
const PASSWORD_SETTINGS: { label: string; value: string }[] = [
|
||||
{ label: 'libsecret', value: 'gnome_libsecret' },
|
||||
{ label: 'KDE 4 (kwallet4)', value: 'kwallet' },
|
||||
{ label: 'KDE 5 (kwallet5)', value: 'kwallet5' },
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Switch } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { useSettingsStoreActions, useWindowSettings } from '/@/renderer/store';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
|
||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||
const utils = isElectron() ? window.api.utils : null;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Select, Switch, toast } from '/@/renderer/components';
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { useSettingsStoreActions, useWindowSettings } from '/@/renderer/store';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import { Platform } from '/@/shared/types/types';
|
||||
|
||||
const WINDOW_BAR_OPTIONS = [
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
import { Stack } from '@mantine/core';
|
||||
import isElectron from 'is-electron';
|
||||
|
||||
import { DiscordSettings } from '/@/renderer/features/settings/components/window/discord-settings';
|
||||
import { PasswordSettings } from '/@/renderer/features/settings/components/window/password-settings';
|
||||
import { UpdateSettings } from '/@/renderer/features/settings/components/window/update-settings';
|
||||
import { WindowSettings } from '/@/renderer/features/settings/components/window/window-settings';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
|
||||
const utils = isElectron() ? window.api.utils : null;
|
||||
|
||||
export const WindowTab = () => {
|
||||
return (
|
||||
<Stack spacing="md">
|
||||
<Stack gap="md">
|
||||
<WindowSettings />
|
||||
<DiscordSettings />
|
||||
<UpdateSettings />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue