From 645697367dc0802eb627aa8f20b9a5475c301d9a Mon Sep 17 00:00:00 2001 From: Kendall Garner <17521368+kgarner7@users.noreply.github.com> Date: Sun, 5 May 2024 13:25:05 -0700 Subject: [PATCH] [enhancement]: support serach on settings page --- .editorconfig | 2 +- .../components/general/draggable-items.tsx | 126 ++++++++++++++ .../components/general/general-tab.tsx | 16 +- .../components/general/home-settings.tsx | 109 ++---------- .../components/general/sidebar-reorder.tsx | 30 ++++ .../components/general/sidebar-settings.tsx | 160 ++++-------------- .../hotkeys/hotkey-manager-settings.tsx | 147 ++++++++-------- .../components/hotkeys/hotkeys-tab.tsx | 9 +- .../components/playback/audio-settings.tsx | 9 +- .../components/playback/lyric-settings.tsx | 7 +- .../components/playback/mpv-settings.tsx | 4 +- .../components/playback/playback-tab.tsx | 7 +- .../settings/components/settings-header.tsx | 39 +++-- .../settings/components/settings-section.tsx | 27 ++- .../components/window/cache-settngs.tsx | 81 +++++---- .../components/window/password-settings.tsx | 7 +- .../components/window/update-settings.tsx | 8 +- .../settings/components/window/window-tab.tsx | 5 +- .../settings/context/search-context.tsx | 8 + .../settings/routes/settings-route.tsx | 22 ++- src/renderer/store/settings.store.ts | 1 + 21 files changed, 439 insertions(+), 385 deletions(-) create mode 100644 src/renderer/features/settings/components/general/draggable-items.tsx create mode 100644 src/renderer/features/settings/components/general/sidebar-reorder.tsx create mode 100644 src/renderer/features/settings/context/search-context.tsx diff --git a/.editorconfig b/.editorconfig index 4a7ea303..779f99a1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,7 +2,7 @@ root = true [*] indent_style = space -indent_size = 2 +indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true diff --git a/src/renderer/features/settings/components/general/draggable-items.tsx b/src/renderer/features/settings/components/general/draggable-items.tsx new file mode 100644 index 00000000..01a3369a --- /dev/null +++ b/src/renderer/features/settings/components/general/draggable-items.tsx @@ -0,0 +1,126 @@ +import isEqual from 'lodash/isEqual'; +import { useCallback, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { SortableItem } from '/@/renderer/store'; +import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context'; +import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; +import { Button } from '/@/renderer/components'; +import { Reorder } from 'framer-motion'; +import { Divider } from '@mantine/core'; +import { DraggableItem } from '/@/renderer/features/settings/components/general/draggable-item'; + +export type DraggableItemsProps = { + description: string; + itemLabels: Array<[K, string]>; + setItems: (items: T[]) => void; + settings: T[]; + title: string; +}; + +export const DraggableItems = >({ + description, + itemLabels, + settings, + setItems, + title, +}: DraggableItemsProps) => { + const { t } = useTranslation(); + const keyword = useSettingSearchContext(); + const [open, setOpen] = useState(false); + + const translatedItemMap = useMemo( + () => + Object.fromEntries( + itemLabels.map((label) => [label[0], t(label[1], { postProcess: 'sentenceCase' })]), + ) as Record, + [itemLabels, t], + ); + + const [localItems, setLocalItems] = useState(settings); + + const handleChangeDisabled = useCallback((id: string, e: boolean) => { + setLocalItems((items) => + items.map((item) => { + if (item.id === id) { + return { + ...item, + disabled: !e, + }; + } + + return item; + }), + ); + }, []); + + const titleText = t(title, { postProcess: 'sentenceCase' }); + const descriptionText = t(description, { + context: 'description', + postProcess: 'sentenceCase', + }); + + const shouldShow = useMemo(() => { + return ( + keyword === '' || + title.toLocaleLowerCase().includes(keyword) || + description.toLocaleLowerCase().includes(keyword) + ); + }, [description, keyword, title]); + + if (!shouldShow) { + return <>; + } + + const isSaveButtonDisabled = isEqual(settings, localItems); + + const handleSave = () => { + setItems(localItems); + }; + + return ( + <> + + {open && ( + + )} + + + } + description={descriptionText} + title={titleText} + /> + {open && ( + + {localItems.map((item) => ( + + ))} + + )} + + + ); +}; diff --git a/src/renderer/features/settings/components/general/general-tab.tsx b/src/renderer/features/settings/components/general/general-tab.tsx index bae90101..c1f4bef8 100644 --- a/src/renderer/features/settings/components/general/general-tab.tsx +++ b/src/renderer/features/settings/components/general/general-tab.tsx @@ -1,4 +1,4 @@ -import { Divider, Stack } from '@mantine/core'; +import { Stack } from '@mantine/core'; import { ApplicationSettings } from '/@/renderer/features/settings/components/general/application-settings'; import { ControlSettings } from '/@/renderer/features/settings/components/general/control-settings'; import { SidebarSettings } from '/@/renderer/features/settings/components/general/sidebar-settings'; @@ -7,26 +7,18 @@ import { RemoteSettings } from '/@/renderer/features/settings/components/general import { CacheSettings } from '/@/renderer/features/settings/components/window/cache-settngs'; import isElectron from 'is-electron'; import { HomeSettings } from '/@/renderer/features/settings/components/general/home-settings'; +import { SidebarReorder } from '/@/renderer/features/settings/components/general/sidebar-reorder'; export const GeneralTab = () => { return ( - - - - + - {isElectron() && ( - <> - - - - )} - + {isElectron() && } ); diff --git a/src/renderer/features/settings/components/general/home-settings.tsx b/src/renderer/features/settings/components/general/home-settings.tsx index ca05bbce..70da0956 100644 --- a/src/renderer/features/settings/components/general/home-settings.tsx +++ b/src/renderer/features/settings/components/general/home-settings.tsx @@ -1,107 +1,28 @@ -import { useCallback, useMemo, useState } from 'react'; -import { Reorder } from 'framer-motion'; -import isEqual from 'lodash/isEqual'; -import { useTranslation } from 'react-i18next'; -import { Button } from '/@/renderer/components'; import { useSettingsStoreActions, useGeneralSettings, HomeItem, } from '../../../../store/settings.store'; -import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; -import { DraggableItem } from '/@/renderer/features/settings/components/general/draggable-item'; +import { DraggableItems } from '/@/renderer/features/settings/components/general/draggable-items'; + +const HOME_ITEMS: Array<[string, string]> = [ + [HomeItem.RANDOM, 'page.home.explore'], + [HomeItem.RECENTLY_PLAYED, 'page.home.recentlyPlayed'], + [HomeItem.RECENTLY_ADDED, 'page.home.newlyAdded'], + [HomeItem.MOST_PLAYED, 'page.home.mostPlayed'], +]; export const HomeSettings = () => { - const { t } = useTranslation(); const { homeItems } = useGeneralSettings(); const { setHomeItems } = useSettingsStoreActions(); - const [open, setOpen] = useState(false); - - const translatedSidebarItemMap = useMemo( - () => ({ - [HomeItem.RANDOM]: t('page.home.explore', { postProcess: 'sentenceCase' }), - [HomeItem.RECENTLY_PLAYED]: t('page.home.recentlyPlayed', { - postProcess: 'sentenceCase', - }), - [HomeItem.RECENTLY_ADDED]: t('page.home.newlyAdded', { postProcess: 'sentenceCase' }), - [HomeItem.MOST_PLAYED]: t('page.home.mostPlayed', { postProcess: 'sentenceCase' }), - }), - [t], - ); - - const [localHomeItems, setLocalHomeItems] = useState(homeItems); - - const handleSave = () => { - setHomeItems(localHomeItems); - }; - - const handleChangeDisabled = useCallback((id: string, e: boolean) => { - setLocalHomeItems((items) => - items.map((item) => { - if (item.id === id) { - return { - ...item, - disabled: !e, - }; - } - - return item; - }), - ); - }, []); - - const isSaveButtonDisabled = isEqual(homeItems, localHomeItems); return ( - <> - - {open && ( - - )} - - - } - description={t('setting.homeConfiguration', { - context: 'description', - postProcess: 'sentenceCase', - })} - title={t('setting.homeConfiguration', { postProcess: 'sentenceCase' })} - /> - {open && ( - - {localHomeItems.map((item) => ( - - ))} - - )} - + ); }; diff --git a/src/renderer/features/settings/components/general/sidebar-reorder.tsx b/src/renderer/features/settings/components/general/sidebar-reorder.tsx new file mode 100644 index 00000000..ee0fa68c --- /dev/null +++ b/src/renderer/features/settings/components/general/sidebar-reorder.tsx @@ -0,0 +1,30 @@ +import { DraggableItems } from '/@/renderer/features/settings/components/general/draggable-items'; +import { useGeneralSettings, useSettingsStoreActions } from '/@/renderer/store'; + +const SIDEBAR_ITEMS: Array<[string, string]> = [ + ['Albums', 'page.sidebar.albums'], + ['Artists', 'page.sidebar.artists'], + ['Folders', 'page.sidebar.folders'], + ['Genres', 'page.sidebar.genres'], + ['Home', 'page.sidebar.home'], + ['Now Playing', 'page.sidebar.nowPlaying'], + ['Playlists', 'page.sidebar.playlists'], + ['Search', 'page.sidebar.search'], + ['Settings', 'page.sidebar.settings'], + ['Tracks', 'page.sidebar.tracks'], +]; + +export const SidebarReorder = () => { + const { sidebarItems } = useGeneralSettings(); + const { setSidebarItems } = useSettingsStoreActions(); + + return ( + + ); +}; diff --git a/src/renderer/features/settings/components/general/sidebar-settings.tsx b/src/renderer/features/settings/components/general/sidebar-settings.tsx index 2529286b..1f6ee676 100644 --- a/src/renderer/features/settings/components/general/sidebar-settings.tsx +++ b/src/renderer/features/settings/components/general/sidebar-settings.tsx @@ -1,54 +1,16 @@ -import { ChangeEvent, useCallback, useMemo, useState } from 'react'; -import { Reorder } from 'framer-motion'; -import isEqual from 'lodash/isEqual'; +import { ChangeEvent } from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, Switch } from '/@/renderer/components'; +import { Switch } from '/@/renderer/components'; import { useSettingsStoreActions, useGeneralSettings } from '../../../../store/settings.store'; -import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; -import { DraggableItem } from '/@/renderer/features/settings/components/general/draggable-item'; +import { + SettingOption, + SettingsSection, +} from '/@/renderer/features/settings/components/settings-section'; export const SidebarSettings = () => { const { t } = useTranslation(); const settings = useGeneralSettings(); - const { setSidebarItems, setSettings } = useSettingsStoreActions(); - const [open, setOpen] = useState(false); - - const translatedSidebarItemMap = useMemo( - () => ({ - Albums: t('page.sidebar.albums', { postProcess: 'titleCase' }), - Artists: t('page.sidebar.artists', { postProcess: 'titleCase' }), - Folders: t('page.sidebar.folders', { postProcess: 'titleCase' }), - Genres: t('page.sidebar.genres', { postProcess: 'titleCase' }), - Home: t('page.sidebar.home', { postProcess: 'titleCase' }), - 'Now Playing': t('page.sidebar.nowPlaying', { postProcess: 'titleCase' }), - Playlists: t('page.sidebar.playlists', { postProcess: 'titleCase' }), - Search: t('page.sidebar.search', { postProcess: 'titleCase' }), - Settings: t('page.sidebar.settings', { postProcess: 'titleCase' }), - Tracks: t('page.sidebar.tracks', { postProcess: 'titleCase' }), - }), - [t], - ); - - const [localSidebarItems, setLocalSidebarItems] = useState(settings.sidebarItems); - - const handleSave = () => { - setSidebarItems(localSidebarItems); - }; - - const handleChangeDisabled = useCallback((id: string, e: boolean) => { - setLocalSidebarItems((items) => - items.map((item) => { - if (item.id === id) { - return { - ...item, - disabled: !e, - }; - } - - return item; - }), - ); - }, []); + const { setSettings } = useSettingsStoreActions(); const handleSetSidebarPlaylistList = (e: ChangeEvent) => { setSettings({ @@ -68,84 +30,34 @@ export const SidebarSettings = () => { }); }; - const isSaveButtonDisabled = isEqual(settings.sidebarItems, localSidebarItems); + const options: SettingOption[] = [ + { + control: ( + + ), + description: t('setting.sidebarPlaylistList', { + context: 'description', + postProcess: 'sentenceCase', + }), + title: t('setting.sidebarPlaylistList', { postProcess: 'sentenceCase' }), + }, + { + control: ( + + ), + description: t('setting.sidebarPlaylistList', { + context: 'description', + postProcess: 'sentenceCase', + }), + title: t('setting.sidebarCollapsedNavigation', { postProcess: 'sentenceCase' }), + }, + ]; - return ( - <> - - } - description={t('setting.sidebarPlaylistList', { - context: 'description', - postProcess: 'sentenceCase', - })} - title={t('setting.sidebarPlaylistList', { postProcess: 'sentenceCase' })} - /> - - } - description={t('setting.sidebarPlaylistList', { - context: 'description', - postProcess: 'sentenceCase', - })} - title={t('setting.sidebarCollapsedNavigation', { postProcess: 'sentenceCase' })} - /> - - {open && ( - - )} - - - } - description={t('setting.sidebarCollapsedNavigation', { - context: 'description', - postProcess: 'sentenceCase', - })} - title={t('setting.sidebarConfiguration', { postProcess: 'sentenceCase' })} - /> - {open && ( - - {localSidebarItems.map((item) => ( - - ))} - - )} - - ); + return ; }; diff --git a/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx b/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx index a84c7ff4..0bca5328 100644 --- a/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx +++ b/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx @@ -9,6 +9,7 @@ import { Button, TextInput, Checkbox } from '/@/renderer/components'; import { BindingActions, useHotkeySettings, useSettingsStoreActions } from '/@/renderer/store'; import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; import i18n from '/@/i18n/i18n'; +import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context'; const ipc = isElectron() ? window.electron.ipc : null; @@ -107,6 +108,7 @@ export const HotkeyManagerSettings = () => { const { bindings, globalMediaHotkeys } = useHotkeySettings(); const { setSettings } = useSettingsStoreActions(); const [selected, setSelected] = useState(null); + const keyword = useSettingSearchContext(); const debouncedSetHotkey = debounce( (binding: BindingActions, e: KeyboardEvent) => { @@ -216,6 +218,21 @@ export const HotkeyManagerSettings = () => { return duplicateKeys; }, [bindings]); + const filteredBindings = useMemo(() => { + const base = Object.keys(bindings); + + if (keyword === '') { + return base.filter((binding) => BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]); + } + + return base.filter((binding) => { + const item = BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]; + if (!item) return false; + + return item.toLocaleLowerCase().includes(keyword); + }); + }, [bindings, keyword]); + return ( <> { title={t('setting.applicationHotkeys', { postProcess: 'sentenceCase' })} /> - {Object.keys(bindings) - .filter((binding) => BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]) - .map((binding) => ( - - - } - id={`hotkey-${binding}`} + {filteredBindings.map((binding) => ( + + + } + id={`hotkey-${binding}`} + style={{ + opacity: selected === (binding as BindingActions) ? 0.8 : 1, + outline: duplicateHotkeyMap.includes( + bindings[binding as keyof typeof BINDINGS_MAP].hotkey!, + ) + ? '1px dashed red' + : undefined, + }} + value={bindings[binding as keyof typeof BINDINGS_MAP].hotkey} + onBlur={() => setSelected(null)} + onChange={() => {}} + onKeyDownCapture={(e) => { + if (selected !== (binding as BindingActions)) return; + handleSetHotkey(binding as BindingActions, e); + }} + /> + {isElectron() && ( + setSelected(null)} - onChange={() => {}} - onKeyDownCapture={(e) => { - if (selected !== (binding as BindingActions)) return; - handleSetHotkey(binding as BindingActions, e); + opacity: bindings[binding as keyof typeof BINDINGS_MAP] + .allowGlobal + ? 1 + : 0, }} + onChange={(e) => + handleSetGlobalHotkey(binding as BindingActions, e) + } /> - {isElectron() && ( - - handleSetGlobalHotkey(binding as BindingActions, e) - } - /> - )} - - - - ))} + )} + + + + ))} ); diff --git a/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx b/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx index 9cc89c5a..3580e9e3 100644 --- a/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx +++ b/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx @@ -1,4 +1,4 @@ -import { Divider, Stack } from '@mantine/core'; +import { Stack } from '@mantine/core'; import isElectron from 'is-electron'; import { WindowHotkeySettings } from './window-hotkey-settings'; import { HotkeyManagerSettings } from '/@/renderer/features/settings/components/hotkeys/hotkey-manager-settings'; @@ -6,12 +6,7 @@ import { HotkeyManagerSettings } from '/@/renderer/features/settings/components/ export const HotkeysTab = () => { return ( - {isElectron() && ( - <> - - - - )} + {isElectron() && } ); diff --git a/src/renderer/features/settings/components/playback/audio-settings.tsx b/src/renderer/features/settings/components/playback/audio-settings.tsx index 28575279..84cb6364 100644 --- a/src/renderer/features/settings/components/playback/audio-settings.tsx +++ b/src/renderer/features/settings/components/playback/audio-settings.tsx @@ -18,7 +18,7 @@ const getAudioDevice = async () => { return (devices || []).filter((dev: MediaDeviceInfo) => dev.kind === 'audiooutput'); }; -export const AudioSettings = () => { +export const AudioSettings = ({ hasFancyAudio }: { hasFancyAudio: boolean }) => { const { t } = useTranslation(); const settings = usePlaybackSettings(); const { setSettings } = useSettingsStoreActions(); @@ -201,5 +201,10 @@ export const AudioSettings = () => { }, ]; - return ; + return ( + + ); }; diff --git a/src/renderer/features/settings/components/playback/lyric-settings.tsx b/src/renderer/features/settings/components/playback/lyric-settings.tsx index 19b37392..15753666 100644 --- a/src/renderer/features/settings/components/playback/lyric-settings.tsx +++ b/src/renderer/features/settings/components/playback/lyric-settings.tsx @@ -118,5 +118,10 @@ export const LyricSettings = () => { }, ]; - return ; + return ( + + ); }; diff --git a/src/renderer/features/settings/components/playback/mpv-settings.tsx b/src/renderer/features/settings/components/playback/mpv-settings.tsx index aea2b3b1..716984cd 100644 --- a/src/renderer/features/settings/components/playback/mpv-settings.tsx +++ b/src/renderer/features/settings/components/playback/mpv-settings.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Divider, Group, Stack } from '@mantine/core'; +import { Group, Stack } from '@mantine/core'; import isElectron from 'is-electron'; import { FileInput, @@ -414,9 +414,7 @@ export const MpvSettings = () => { return ( <> - - ); diff --git a/src/renderer/features/settings/components/playback/playback-tab.tsx b/src/renderer/features/settings/components/playback/playback-tab.tsx index a9a240c1..c809dc6e 100644 --- a/src/renderer/features/settings/components/playback/playback-tab.tsx +++ b/src/renderer/features/settings/components/playback/playback-tab.tsx @@ -1,5 +1,5 @@ import { lazy, Suspense, useMemo } from 'react'; -import { Divider, Stack } from '@mantine/core'; +import { Stack } from '@mantine/core'; import { AudioSettings } from '/@/renderer/features/settings/components/playback/audio-settings'; import { ScrobbleSettings } from '/@/renderer/features/settings/components/playback/scrobble-settings'; import isElectron from 'is-electron'; @@ -15,13 +15,12 @@ export const PlaybackTab = () => { const hasFancyAudio = useMemo(() => { return isElectron() || 'AudioContext' in window; }, []); + return ( - + }>{hasFancyAudio && } - - ); diff --git a/src/renderer/features/settings/components/settings-header.tsx b/src/renderer/features/settings/components/settings-header.tsx index 01fef382..c7e355bd 100644 --- a/src/renderer/features/settings/components/settings-header.tsx +++ b/src/renderer/features/settings/components/settings-header.tsx @@ -2,13 +2,23 @@ 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 } from '/@/renderer/components'; +import { Button, ConfirmModal, PageHeader, SearchInput } from '/@/renderer/components'; import { LibraryHeaderBar } from '/@/renderer/features/shared'; import { useSettingsStoreActions } from '../../../store/settings.store'; +import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context'; +import { useContainerQuery } from '/@/renderer/hooks'; -export const SettingsHeader = () => { +export type SettingsHeaderProps = { + setSearch: (search: string) => void; +}; + +export const SettingsHeader = ({ setSearch }: SettingsHeaderProps) => { const { t } = useTranslation(); const { reset } = useSettingsStoreActions(); + const search = useSettingSearchContext(); + const cq = useContainerQuery(); + + console.log(cq); const handleResetToDefault = () => { reset(); @@ -27,7 +37,7 @@ export const SettingsHeader = () => { }; return ( - + { {t('common.setting', { count: 2, postProcess: 'titleCase' })} - + + + setSearch(event.target.value.toLocaleLowerCase()) + } + /> + + diff --git a/src/renderer/features/settings/components/settings-section.tsx b/src/renderer/features/settings/components/settings-section.tsx index cee5b526..aab8fd67 100644 --- a/src/renderer/features/settings/components/settings-section.tsx +++ b/src/renderer/features/settings/components/settings-section.tsx @@ -1,5 +1,7 @@ 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 '@mantine/core'; export type SettingOption = { control: ReactNode; @@ -10,20 +12,27 @@ export type SettingOption = { }; interface SettingsSectionProps { + divider?: boolean; options: SettingOption[]; } -export const SettingsSection = ({ options }: SettingsSectionProps) => { +export const SettingsSection = ({ divider, options }: SettingsSectionProps) => { + const keyword = useSettingSearchContext(); + const hasKeyword = keyword !== ''; + + const values = options.filter( + (o) => !o.isHidden && (!hasKeyword || o.title.toLocaleLowerCase().includes(keyword)), + ); + return ( <> - {options - .filter((o) => !o.isHidden) - .map((option) => ( - - ))} + {values.map((option) => ( + + ))} + {divider !== false && values.length > 0 && } ); }; diff --git a/src/renderer/features/settings/components/window/cache-settngs.tsx b/src/renderer/features/settings/components/window/cache-settngs.tsx index 310703f5..0fe68caa 100644 --- a/src/renderer/features/settings/components/window/cache-settngs.tsx +++ b/src/renderer/features/settings/components/window/cache-settngs.tsx @@ -3,8 +3,11 @@ import { useQueryClient } from '@tanstack/react-query'; import isElectron from 'is-electron'; import { useTranslation } from 'react-i18next'; import { Button, ConfirmModal, toast } from '/@/renderer/components'; -import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; import { useCallback, useState } from 'react'; +import { + SettingOption, + SettingsSection, +} from '/@/renderer/features/settings/components/settings-section'; const browser = isElectron() ? window.electron.browser : null; @@ -50,42 +53,46 @@ export const CacheSettings = () => { }); }; + const options: SettingOption[] = [ + { + control: ( + + ), + description: t('setting.clearQueryCache', { + context: 'description', + }), + title: t('setting.clearQueryCache'), + }, + { + control: ( + + ), + description: t('setting.clearCache', { + context: 'description', + }), + isHidden: !browser, + title: t('setting.clearCache'), + }, + ]; + return ( - <> - openResetConfirmModal(false)} - > - {t('common.clear', { postProcess: 'sentenceCase' })} - - } - description={t('setting.clearQueryCache', { - context: 'description', - })} - title={t('setting.clearQueryCache')} - /> - {browser && ( - openResetConfirmModal(true)} - > - {t('common.clear', { postProcess: 'sentenceCase' })} - - } - description={t('setting.clearCache', { - context: 'description', - })} - title={t('setting.clearCache')} - /> - )} - + ); }; diff --git a/src/renderer/features/settings/components/window/password-settings.tsx b/src/renderer/features/settings/components/window/password-settings.tsx index 9cfdf626..2d6d7467 100644 --- a/src/renderer/features/settings/components/window/password-settings.tsx +++ b/src/renderer/features/settings/components/window/password-settings.tsx @@ -52,5 +52,10 @@ export const PasswordSettings = () => { }, ]; - return ; + return ( + + ); }; diff --git a/src/renderer/features/settings/components/window/update-settings.tsx b/src/renderer/features/settings/components/window/update-settings.tsx index ddb94d31..41389bcc 100644 --- a/src/renderer/features/settings/components/window/update-settings.tsx +++ b/src/renderer/features/settings/components/window/update-settings.tsx @@ -8,6 +8,7 @@ import { import { Switch } from '/@/renderer/components'; const localSettings = isElectron() ? window.electron.localSettings : null; +const utils = isElectron() ? window.electron.utils : null; export const UpdateSettings = () => { const { t } = useTranslation(); @@ -42,5 +43,10 @@ export const UpdateSettings = () => { }, ]; - return ; + return ( + + ); }; diff --git a/src/renderer/features/settings/components/window/window-tab.tsx b/src/renderer/features/settings/components/window/window-tab.tsx index 23dc4e9c..14b5c6a4 100644 --- a/src/renderer/features/settings/components/window/window-tab.tsx +++ b/src/renderer/features/settings/components/window/window-tab.tsx @@ -1,4 +1,4 @@ -import { Divider, Stack } from '@mantine/core'; +import { Stack } from '@mantine/core'; import { UpdateSettings } from '/@/renderer/features/settings/components/window/update-settings'; import { WindowSettings } from '/@/renderer/features/settings/components/window/window-settings'; import { DiscordSettings } from '/@/renderer/features/settings/components/window/discord-settings'; @@ -11,13 +11,10 @@ export const WindowTab = () => { return ( - - {utils?.isLinux() && ( <> - )} diff --git a/src/renderer/features/settings/context/search-context.tsx b/src/renderer/features/settings/context/search-context.tsx new file mode 100644 index 00000000..71368578 --- /dev/null +++ b/src/renderer/features/settings/context/search-context.tsx @@ -0,0 +1,8 @@ +import { createContext, useContext } from 'react'; + +export const SettingSearchContext = createContext(''); + +export const useSettingSearchContext = () => { + const ctxValue = useContext(SettingSearchContext); + return ctxValue; +}; diff --git a/src/renderer/features/settings/routes/settings-route.tsx b/src/renderer/features/settings/routes/settings-route.tsx index ca633c77..54f402ce 100644 --- a/src/renderer/features/settings/routes/settings-route.tsx +++ b/src/renderer/features/settings/routes/settings-route.tsx @@ -2,18 +2,24 @@ import { Flex } from '@mantine/core'; import { SettingsContent } from '/@/renderer/features/settings/components/settings-content'; import { SettingsHeader } from '/@/renderer/features/settings/components/settings-header'; import { AnimatedPage } from '/@/renderer/features/shared'; +import { SettingSearchContext } from '/@/renderer/features/settings/context/search-context'; +import { useState } from 'react'; const SettingsRoute = () => { + const [search, setSearch] = useState(''); + return ( - - - - + + + + + + ); }; diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index fc88f71d..e3943204 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -282,6 +282,7 @@ export interface SettingsSlice extends SettingsState { actions: { reset: () => void; resetSampleRate: () => void; + setGenreBehavior: (target: GenreTarget) => void; setHomeItems: (item: SortableItem[]) => void; setSettings: (data: Partial) => void; setSidebarItems: (items: SidebarItemType[]) => void;