From eecbcddea37b52a9c9179165f3cd0fd357b4e54c Mon Sep 17 00:00:00 2001 From: jeffvli Date: Thu, 30 Mar 2023 06:44:33 -0700 Subject: [PATCH] Refactor settings store and components --- .../components/audio-player/index.tsx | 2 +- .../components/card/card-controls.tsx | 4 +- src/renderer/components/page-header/index.tsx | 6 +- src/renderer/components/scroll-area/index.tsx | 4 +- .../grid-card/grid-card-controls.tsx | 6 +- .../hooks/use-fixed-table-header.tsx | 4 +- .../components/sidebar-play-queue.tsx | 4 +- .../player/components/center-controls.tsx | 2 +- .../features/player/components/playerbar.tsx | 2 +- .../player/hooks/use-center-controls.ts | 2 +- .../features/player/hooks/use-scrobble.ts | 4 +- .../settings/components/general-tab.tsx | 278 ---------- .../general/application-settings.tsx | 59 +++ .../components/general/control-settings.tsx | 176 +++++++ .../components/general/general-tab.tsx | 16 + .../components/general/theme-settings.tsx | 93 ++++ .../settings/components/playback-tab.tsx | 475 +----------------- .../components/playback/audio-settings.tsx | 262 ++++++++++ .../components/playback/scrobble-settings.tsx | 99 ++++ .../settings/components/settings-content.tsx | 29 +- .../settings/components/settings-section.tsx | 28 ++ .../components/window/window-settings.tsx | 45 ++ .../settings/components/window/window-tab.tsx | 10 + src/renderer/features/settings/index.ts | 1 - .../features/sidebar/components/sidebar.tsx | 4 +- src/renderer/layouts/default-layout.tsx | 8 +- .../layouts/default-layout/main-content.tsx | 4 +- src/renderer/layouts/window-bar.tsx | 4 +- src/renderer/router/titlebar-outlet.tsx | 4 +- src/renderer/store/settings.store.ts | 91 ++-- 30 files changed, 894 insertions(+), 832 deletions(-) delete mode 100644 src/renderer/features/settings/components/general-tab.tsx create mode 100644 src/renderer/features/settings/components/general/application-settings.tsx create mode 100644 src/renderer/features/settings/components/general/control-settings.tsx create mode 100644 src/renderer/features/settings/components/general/general-tab.tsx create mode 100644 src/renderer/features/settings/components/general/theme-settings.tsx create mode 100644 src/renderer/features/settings/components/playback/audio-settings.tsx create mode 100644 src/renderer/features/settings/components/playback/scrobble-settings.tsx create mode 100644 src/renderer/features/settings/components/settings-section.tsx create mode 100644 src/renderer/features/settings/components/window/window-settings.tsx create mode 100644 src/renderer/features/settings/components/window/window-tab.tsx delete mode 100644 src/renderer/features/settings/index.ts diff --git a/src/renderer/components/audio-player/index.tsx b/src/renderer/components/audio-player/index.tsx index 1a7ec311..f78a50c2 100644 --- a/src/renderer/components/audio-player/index.tsx +++ b/src/renderer/components/audio-player/index.tsx @@ -52,7 +52,7 @@ export const AudioPlayer = forwardRef( const player1Ref = useRef(null); const player2Ref = useRef(null); const [isTransitioning, setIsTransitioning] = useState(false); - const audioDeviceId = useSettingsStore((state) => state.player.audioDeviceId); + const audioDeviceId = useSettingsStore((state) => state.playback.audioDeviceId); useImperativeHandle(ref, () => ({ get player1() { diff --git a/src/renderer/components/card/card-controls.tsx b/src/renderer/components/card/card-controls.tsx index f320bc76..b299f589 100644 --- a/src/renderer/components/card/card-controls.tsx +++ b/src/renderer/components/card/card-controls.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; import { _Button } from '/@/renderer/components/button'; import type { PlayQueueAddOptions } from '/@/renderer/types'; import { Play } from '/@/renderer/types'; -import { useSettingsStore } from '/@/renderer/store/settings.store'; +import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { LibraryItem } from '/@/renderer/api/types'; import { useHandleGeneralContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu'; import { @@ -112,7 +112,7 @@ export const CardControls = ({ itemData: any; itemType: LibraryItem; }) => { - const playButtonBehavior = useSettingsStore((state) => state.player.playButtonBehavior); + const playButtonBehavior = usePlayButtonBehavior(); const handlePlay = (e: MouseEvent, playType?: Play) => { e.preventDefault(); diff --git a/src/renderer/components/page-header/index.tsx b/src/renderer/components/page-header/index.tsx index f6927e50..adef02d5 100644 --- a/src/renderer/components/page-header/index.tsx +++ b/src/renderer/components/page-header/index.tsx @@ -1,9 +1,9 @@ +import { useRef } from 'react'; import { Flex, FlexProps } from '@mantine/core'; import { AnimatePresence, motion, Variants } from 'framer-motion'; -import { useRef } from 'react'; import styled from 'styled-components'; import { useShouldPadTitlebar, useTheme } from '/@/renderer/hooks'; -import { useGeneralSettings } from '/@/renderer/store/settings.store'; +import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; const Container = styled(motion(Flex))<{ @@ -94,7 +94,7 @@ export const PageHeader = ({ }: PageHeaderProps) => { const ref = useRef(null); const padRight = useShouldPadTitlebar(); - const { windowBarStyle } = useGeneralSettings(); + const { windowBarStyle } = useWindowSettings(); const theme = useTheme(); return ( diff --git a/src/renderer/components/scroll-area/index.tsx b/src/renderer/components/scroll-area/index.tsx index 555b5823..db3a414e 100644 --- a/src/renderer/components/scroll-area/index.tsx +++ b/src/renderer/components/scroll-area/index.tsx @@ -5,7 +5,7 @@ import { useMergedRef, useTimeout } from '@mantine/hooks'; import { motion, useScroll } from 'framer-motion'; import styled from 'styled-components'; import { PageHeader, PageHeaderProps } from '/@/renderer/components/page-header'; -import { useGeneralSettings } from '/@/renderer/store/settings.store'; +import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; interface ScrollAreaProps extends MantineScrollAreaProps { @@ -78,7 +78,7 @@ export const NativeScrollArea = forwardRef( }: NativeScrollAreaProps, ref: Ref, ) => { - const { windowBarStyle } = useGeneralSettings(); + const { windowBarStyle } = useWindowSettings(); const [hideScrollbar, setHideScrollbar] = useState(false); const [hideHeader, setHideHeader] = useState(true); const { start, clear } = useTimeout( diff --git a/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx b/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx index 208a9aa2..07f49c55 100644 --- a/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx +++ b/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx @@ -6,7 +6,7 @@ import styled from 'styled-components'; import { _Button } from '/@/renderer/components/button'; import type { PlayQueueAddOptions } from '/@/renderer/types'; import { Play } from '/@/renderer/types'; -import { useSettingsStore } from '/@/renderer/store/settings.store'; +import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { LibraryItem } from '/@/renderer/api/types'; import { useHandleGeneralContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu'; import { @@ -105,7 +105,7 @@ export const GridCardControls = ({ itemData: any; itemType: LibraryItem; }) => { - const playButtonBehavior = useSettingsStore((state) => state.player.playButtonBehavior); + const playButtonBehavior = usePlayButtonBehavior(); const handlePlay = async (e: MouseEvent, playType?: Play) => { e.preventDefault(); @@ -144,7 +144,6 @@ export const GridCardControls = ({ @@ -161,7 +160,6 @@ export const GridCardControls = ({ { e.preventDefault(); diff --git a/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx index 78df4049..b645b939 100644 --- a/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx +++ b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx @@ -1,12 +1,12 @@ import { useEffect, useRef } from 'react'; import { useInView } from 'framer-motion'; -import { useGeneralSettings } from '/@/renderer/store/settings.store'; +import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; export const useFixedTableHeader = () => { const intersectRef = useRef(null); const tableContainerRef = useRef(null); - const { windowBarStyle } = useGeneralSettings(); + const { windowBarStyle } = useWindowSettings(); const isNotPastTableIntersection = useInView(intersectRef, { margin: windowBarStyle === Platform.WEB ? '-68px 0px 0px 0px' : '-98px 0px 0px 0px', diff --git a/src/renderer/features/now-playing/components/sidebar-play-queue.tsx b/src/renderer/features/now-playing/components/sidebar-play-queue.tsx index 27f213a1..eb9cdda2 100644 --- a/src/renderer/features/now-playing/components/sidebar-play-queue.tsx +++ b/src/renderer/features/now-playing/components/sidebar-play-queue.tsx @@ -5,12 +5,12 @@ import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queu import { PlayQueueListControls } from './play-queue-list-controls'; import { Song } from '/@/renderer/api/types'; import { PageHeader, Paper, VirtualGridContainer } from '/@/renderer/components'; -import { useGeneralSettings } from '/@/renderer/store/settings.store'; +import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; export const SidebarPlayQueue = () => { const queueRef = useRef<{ grid: AgGridReactType } | null>(null); - const { windowBarStyle } = useGeneralSettings(); + const { windowBarStyle } = useWindowSettings(); return ( diff --git a/src/renderer/features/player/components/center-controls.tsx b/src/renderer/features/player/components/center-controls.tsx index 3402ff47..0b74d082 100644 --- a/src/renderer/features/player/components/center-controls.tsx +++ b/src/renderer/features/player/components/center-controls.tsx @@ -69,7 +69,7 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => { const [isSeeking, setIsSeeking] = useState(false); const currentSong = useCurrentSong(); const songDuration = currentSong?.duration; - const skip = useSettingsStore((state) => state.player.skipButtons); + const skip = useSettingsStore((state) => state.general.skipButtons); const playerType = usePlayerType(); const player1 = playersRef?.current?.player1; const player2 = playersRef?.current?.player2; diff --git a/src/renderer/features/player/components/playerbar.tsx b/src/renderer/features/player/components/playerbar.tsx index 984c2ecc..458f0c2e 100644 --- a/src/renderer/features/player/components/playerbar.tsx +++ b/src/renderer/features/player/components/playerbar.tsx @@ -56,7 +56,7 @@ const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null; export const Playerbar = () => { const playersRef = useRef(); - const settings = useSettingsStore((state) => state.player); + const settings = useSettingsStore((state) => state.playback); const volume = useVolume(); const player1 = usePlayer1Data(); const player2 = usePlayer2Data(); diff --git a/src/renderer/features/player/hooks/use-center-controls.ts b/src/renderer/features/player/hooks/use-center-controls.ts index 18aaa55d..3b01d25f 100644 --- a/src/renderer/features/player/hooks/use-center-controls.ts +++ b/src/renderer/features/player/hooks/use-center-controls.ts @@ -25,7 +25,7 @@ const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null; export const useCenterControls = (args: { playersRef: any }) => { const { playersRef } = args; - const settings = useSettingsStore((state) => state.player); + const settings = useSettingsStore((state) => state.playback); const currentPlayer = useCurrentPlayer(); const { setShuffle, setRepeat, play, pause, previous, next, setCurrentIndex, autoNext } = usePlayerControls(); diff --git a/src/renderer/features/player/hooks/use-scrobble.ts b/src/renderer/features/player/hooks/use-scrobble.ts index f839f80d..7c8d7353 100644 --- a/src/renderer/features/player/hooks/use-scrobble.ts +++ b/src/renderer/features/player/hooks/use-scrobble.ts @@ -2,7 +2,7 @@ import { useEffect, useCallback, useState, useRef } from 'react'; import { QueueSong, ServerType } from '/@/renderer/api/types'; import { useSendScrobble } from '/@/renderer/features/player/mutations/scrobble-mutation'; import { useCurrentStatus, usePlayerStore } from '/@/renderer/store'; -import { usePlayerSettings } from '/@/renderer/store/settings.store'; +import { usePlaybackSettings } from '/@/renderer/store/settings.store'; import { PlayerStatus } from '/@/renderer/types'; /* @@ -49,7 +49,7 @@ const checkScrobbleConditions = (args: { export const useScrobble = () => { const status = useCurrentStatus(); - const scrobbleSettings = usePlayerSettings().scrobble; + const scrobbleSettings = usePlaybackSettings().scrobble; const isScrobbleEnabled = scrobbleSettings?.enabled; const sendScrobble = useSendScrobble(); diff --git a/src/renderer/features/settings/components/general-tab.tsx b/src/renderer/features/settings/components/general-tab.tsx deleted file mode 100644 index ceb3c636..00000000 --- a/src/renderer/features/settings/components/general-tab.tsx +++ /dev/null @@ -1,278 +0,0 @@ -import { Divider, Stack } from '@mantine/core'; -import { Select, Slider, Switch } from '/@/renderer/components'; -import isElectron from 'is-electron'; -import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; -import { THEME_DATA } from '/@/renderer/hooks'; -import { - useGeneralSettings, - useSettingsStoreActions, - SideQueueType, -} from '/@/renderer/store/settings.store'; -import { AppTheme } from '/@/renderer/themes/types'; -import { Platform } from '/@/renderer/types'; - -const FONT_OPTIONS = [ - { label: 'Archivo', value: 'Archivo' }, - { label: 'Fredoka', value: 'Fredoka' }, - { label: 'League Spartan', value: 'League Spartan' }, - { label: 'Lexend', value: 'Lexend' }, - { label: 'Poppins', value: 'Poppins' }, - { label: 'Raleway', value: 'Raleway' }, - { label: 'Sora', value: 'Sora' }, - { label: 'Work Sans', value: 'Work Sans' }, -]; - -const SIDE_QUEUE_OPTIONS = [ - { label: 'Fixed', value: 'sideQueue' }, - { label: 'Floating', value: 'sideDrawerQueue' }, -]; - -const WINDOW_BAR_OPTIONS = [ - { label: 'Web (hidden)', value: Platform.WEB }, - { label: 'Windows', value: Platform.WINDOWS }, - { label: 'macOS', value: Platform.MACOS }, -]; - -export const GeneralTab = () => { - const settings = useGeneralSettings(); - const { setSettings } = useSettingsStoreActions(); - - const options = [ - { - control: ( - - ), - description: 'Sets the application language', - isHidden: false, - title: 'Language', - }, - { - control: ( - { - setSettings({ - general: { - ...settings, - theme: e as AppTheme, - }, - }); - }} - /> - ), - description: 'Sets the default theme', - isHidden: settings.followSystemTheme, - title: 'Theme', - }, - { - control: ( - { - setSettings({ - general: { - ...settings, - themeLight: e as AppTheme, - }, - }); - }} - /> - ), - description: 'Sets the light theme', - isHidden: !settings.followSystemTheme, - title: 'Theme (light)', - }, - ]; - - const layoutOptions = [ - { - control: ( - + ), + description: 'Sets the application language', + isHidden: false, + title: 'Language', + }, + { + control: ( + + setSettings({ + general: { + ...settings, + playButtonBehavior: e as Play, + }, + }) + } + /> + ), + description: 'The default behavior of the play button when adding songs to the queue', + isHidden: false, + title: 'Play button behavior', + }, + { + control: ( + { + setSettings({ + general: { + ...settings, + theme: e as AppTheme, + }, + }); + }} + /> + ), + description: 'Sets the default theme', + isHidden: settings.followSystemTheme, + title: 'Theme', + }, + { + control: ( + { + setSettings({ + general: { + ...settings, + themeLight: e as AppTheme, + }, + }); + }} + /> + ), + description: 'Sets the light theme', + isHidden: !settings.followSystemTheme, + title: 'Theme (light)', + }, + ]; + + return ; +}; diff --git a/src/renderer/features/settings/components/playback-tab.tsx b/src/renderer/features/settings/components/playback-tab.tsx index bc79c4a4..16953d23 100644 --- a/src/renderer/features/settings/components/playback-tab.tsx +++ b/src/renderer/features/settings/components/playback-tab.tsx @@ -1,478 +1,13 @@ -import { useEffect, useState } from 'react'; -import { Divider, Group, SelectItem, Stack } from '@mantine/core'; -import { - FileInput, - NumberInput, - Select, - Slider, - Switch, - Textarea, - Tooltip, - toast, - Text, -} from '/@/renderer/components'; -import isElectron from 'is-electron'; -import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; -import { useCurrentStatus, usePlayerStore } from '/@/renderer/store'; -import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store'; -import { PlaybackType, PlayerStatus, PlaybackStyle, CrossfadeStyle, Play } from '/@/renderer/types'; - -const localSettings = isElectron() ? window.electron.localSettings : null; -const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; - -const getAudioDevice = async () => { - const devices = await navigator.mediaDevices.enumerateDevices(); - return (devices || []).filter((dev: MediaDeviceInfo) => dev.kind === 'audiooutput'); -}; +import { Divider, Stack } from '@mantine/core'; +import { AudioSettings } from '/@/renderer/features/settings/components/playback/audio-settings'; +import { ScrobbleSettings } from '/@/renderer/features/settings/components/playback/scrobble-settings'; export const PlaybackTab = () => { - const settings = useSettingsStore((state) => state.player); - const { setSettings } = useSettingsStoreActions(); - const status = useCurrentStatus(); - const [audioDevices, setAudioDevices] = useState([]); - const [mpvPath, setMpvPath] = useState(''); - const [mpvParameters, setMpvParameters] = useState(''); - - const handleSetMpvPath = (e: File) => { - localSettings.set('mpv_path', e.path); - }; - - useEffect(() => { - const getMpvPath = async () => { - if (!isElectron()) return setMpvPath(''); - const mpvPath = (await localSettings.get('mpv_path')) as string; - return setMpvPath(mpvPath); - }; - - const getMpvParameters = async () => { - if (!isElectron()) return setMpvPath(''); - const mpvParametersFromSettings = (await localSettings.get('mpv_parameters')) as string[]; - const mpvParameters = mpvParametersFromSettings?.join('\n'); - return setMpvParameters(mpvParameters); - }; - - getMpvPath(); - getMpvParameters(); - }, []); - - useEffect(() => { - const getAudioDevices = () => { - getAudioDevice() - .then((dev) => setAudioDevices(dev.map((d) => ({ label: d.label, value: d.deviceId })))) - .catch(() => toast.error({ message: 'Error fetching audio devices' })); - }; - - getAudioDevices(); - }, []); - - const playerOptions = [ - { - control: ( -