From 51576b0309d607caa37baf62664e88bae6a202a5 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Thu, 27 Apr 2023 18:43:47 +0600 Subject: [PATCH] added settings persistance --- .../settings/hooks/usePersistSettings.ts | 40 +++++++++++++++++++ .../providers/SettingsProvider/index.tsx | 32 ++++----------- 2 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 src/modules/settings/hooks/usePersistSettings.ts diff --git a/src/modules/settings/hooks/usePersistSettings.ts b/src/modules/settings/hooks/usePersistSettings.ts new file mode 100644 index 0000000..0a0bba2 --- /dev/null +++ b/src/modules/settings/hooks/usePersistSettings.ts @@ -0,0 +1,40 @@ +import { useCallback, useState } from "react"; +import { defaultSettings } from "../context/SettingsContext"; +import { + Theme, + defaultDarkTheme, + defaultLightTheme, +} from "~/modules/theme/constants/theme"; +import { useDetectTheme } from "~/modules/theme/hooks/useDetectTheme"; +import { SettingsValue } from "~/modules/settings/context/SettingsContext"; + +const getLocalStorageSettings = (defaultValue: SettingsValue) => { + try { + const raw = localStorage.getItem("settings"); + const parsed = JSON.parse(raw ?? ""); + + return parsed ? { ...defaultValue, ...parsed } : defaultValue; + } catch (error) { + return defaultValue; + } +}; + +export const usePersistSettings = () => { + const theme = useDetectTheme(); + const defaultColors = + theme === Theme.Dark ? defaultDarkTheme : defaultLightTheme; + + const [settings, setSettings] = useState( + getLocalStorageSettings({ ...defaultSettings, ...defaultColors }) + ); + + const update = useCallback((val: Partial) => { + setSettings((v) => { + const updatedValue = { ...v, ...val }; + localStorage.setItem("settings", JSON.stringify(updatedValue)); + return updatedValue; + }); + }, []); + + return { settings, update }; +}; diff --git a/src/modules/settings/providers/SettingsProvider/index.tsx b/src/modules/settings/providers/SettingsProvider/index.tsx index 9565c25..156b5c8 100644 --- a/src/modules/settings/providers/SettingsProvider/index.tsx +++ b/src/modules/settings/providers/SettingsProvider/index.tsx @@ -1,40 +1,22 @@ import { FC, PropsWithChildren, useCallback, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Button } from "~/components/buttons/Button"; +import { ModalPage } from "~/modules/modal/components/ModalPage"; import { Modal } from "~/modules/modal/containers/Modal"; import { SettingsContainer } from "../../containers/SettingsContainer"; -import { - SettingsContext, - SettingsValue, - defaultSettings, -} from "../../context/SettingsContext"; -import { ModalPage } from "~/modules/modal/components/ModalPage"; -import { useDetectTheme } from "~/modules/theme/hooks/useDetectTheme"; -import { - Theme, - defaultDarkTheme, - defaultLightTheme, -} from "~/modules/theme/constants/theme"; -import { Button } from "~/components/buttons/Button"; -import { useTranslation } from "react-i18next"; +import { SettingsContext } from "../../context/SettingsContext"; +import { usePersistSettings } from "../../hooks/usePersistSettings"; import styles from "./styles.module.scss"; const SettingsProvider: FC = ({ children }) => { const { t } = useTranslation(); - const theme = useDetectTheme(); - const defaultColors = - theme === Theme.Dark ? defaultDarkTheme : defaultLightTheme; - const [settings, setSettings] = useState({ - ...defaultSettings, - ...defaultColors, - }); + const { settings, update } = usePersistSettings(); + const [settingsModalVisible, setSettingsModalVisible] = useState(false); const show = useCallback(() => setSettingsModalVisible(true), []); const hide = useCallback(() => setSettingsModalVisible(false), []); - const update = useCallback( - (val: Partial) => setSettings((v) => ({ ...v, ...val })), - [] - ); return (