From 845626827094ce088973759af88a18000568fd88 Mon Sep 17 00:00:00 2001 From: DrMint Date: Fri, 4 Nov 2022 01:48:00 +0100 Subject: [PATCH] Provider hell be gone --- src/components/Panels/SettingsPopup.tsx | 2 +- src/contexts/LightBoxProvider.tsx | 40 ++++++++------ .../{AppLayoutProvider.tsx => appLayout.ts} | 4 +- src/contexts/atoms.ts | 52 +++++-------------- ...ueriesProvider.tsx => containerQueries.ts} | 10 +--- .../{LocalDataProvider.tsx => localData.ts} | 4 +- .../{SettingsProvider.tsx => settings.ts} | 43 +++++++++------ src/pages/_app.tsx | 48 +++++++++-------- 8 files changed, 94 insertions(+), 109 deletions(-) rename src/contexts/{AppLayoutProvider.tsx => appLayout.ts} (86%) rename src/contexts/{ContainerQueriesProvider.tsx => containerQueries.ts} (93%) rename src/contexts/{LocalDataProvider.tsx => localData.ts} (90%) rename src/contexts/{SettingsProvider.tsx => settings.ts} (65%) diff --git a/src/components/Panels/SettingsPopup.tsx b/src/components/Panels/SettingsPopup.tsx index 45917e1..3d27986 100644 --- a/src/components/Panels/SettingsPopup.tsx +++ b/src/components/Panels/SettingsPopup.tsx @@ -13,7 +13,7 @@ import { prettyLanguage } from "helpers/formatters"; import { filterHasAttributes, isDefined } from "helpers/others"; import { atoms } from "contexts/atoms"; import { useAtomGetter, useAtomPair } from "helpers/atoms"; -import { ThemeMode } from "contexts/SettingsProvider"; +import { ThemeMode } from "contexts/settings"; export const SettingsPopup = (): JSX.Element => { const [preferredLanguages, setPreferredLanguages] = useAtomPair( diff --git a/src/contexts/LightBoxProvider.tsx b/src/contexts/LightBoxProvider.tsx index b313f1f..a0b5e97 100644 --- a/src/contexts/LightBoxProvider.tsx +++ b/src/contexts/LightBoxProvider.tsx @@ -1,17 +1,28 @@ import React, { useCallback, useState } from "react"; import { useEffectOnce } from "usehooks-ts"; +import { atom } from "jotai"; import { UploadImageFragment } from "graphql/generated"; import { LightBox } from "components/LightBox"; import { filterDefined } from "helpers/others"; -import { useAtomSetter } from "helpers/atoms"; -import { lightBox } from "contexts/atoms"; +import { atomPairing, useAtomSetter } from "helpers/atoms"; -export const LightBoxProvider = ({ children }: { children: React.ReactNode }): JSX.Element => { +export const lightBoxAtom = atomPairing( + atom<{ + showLightBox: ( + images: (UploadImageFragment | string | null | undefined)[], + index?: number + ) => void; + }>({ showLightBox: () => null }) +); + +export const lightBox = lightBoxAtom[0] + +export const LightBoxProvider = (): JSX.Element => { const [isLightBoxVisible, setLightBoxVisibility] = useState(false); const [lightBoxImages, setLightBoxImages] = useState<(UploadImageFragment | string)[]>([]); const [lightBoxIndex, setLightBoxIndex] = useState(0); - const setShowLightBox = useAtomSetter(lightBox); + const setShowLightBox = useAtomSetter(lightBoxAtom); useEffectOnce(() => setShowLightBox({ @@ -30,17 +41,14 @@ export const LightBoxProvider = ({ children }: { children: React.ReactNode }): J }, []); return ( - <> - 0} - onPressNext={() => setLightBoxIndex((current) => current + 1)} - onPressPrevious={() => setLightBoxIndex((current) => current - 1)} - /> - {children} - + 0} + onPressNext={() => setLightBoxIndex((current) => current + 1)} + onPressPrevious={() => setLightBoxIndex((current) => current - 1)} + /> ); }; diff --git a/src/contexts/AppLayoutProvider.tsx b/src/contexts/appLayout.ts similarity index 86% rename from src/contexts/AppLayoutProvider.tsx rename to src/contexts/appLayout.ts index 05dd025..506ccdf 100644 --- a/src/contexts/AppLayoutProvider.tsx +++ b/src/contexts/appLayout.ts @@ -4,7 +4,7 @@ import { useScrollIntoView } from "hooks/useScrollIntoView"; import { useAtomSetter } from "helpers/atoms"; import { atoms } from "contexts/atoms"; -export const AppLayoutProvider = ({ children }: { children: React.ReactNode }): JSX.Element => { +export const useAppLayout = (): void => { const router = useRouter(); const setSettingsOpened = useAtomSetter(atoms.layout.settingsOpened); @@ -26,6 +26,4 @@ export const AppLayoutProvider = ({ children }: { children: React.ReactNode }): }, [router, setSettingsOpened, setMainPanelOpened, setSubPanelOpened]); useScrollIntoView(); - - return <>{children}; }; diff --git a/src/contexts/atoms.ts b/src/contexts/atoms.ts index 03213df..0f75d64 100644 --- a/src/contexts/atoms.ts +++ b/src/contexts/atoms.ts @@ -1,12 +1,17 @@ -import { atomWithStorage } from "jotai/utils"; import { atom } from "jotai"; -import { localData } from "contexts/LocalDataProvider"; -import { containerQueries } from "contexts/ContainerQueriesProvider"; +import { atomWithStorage } from "jotai/utils"; +import { localData } from "contexts/localData"; +import { containerQueries } from "contexts/containerQueries"; import { atomPairing } from "helpers/atoms"; -import { UploadImageFragment } from "graphql/generated"; -import { ThemeMode } from "contexts/SettingsProvider"; +import { settings } from "contexts/settings"; +import { lightBox } from "contexts/LightBoxProvider"; -/* [ LAYOUT ATOMS ] */ +/* + * I'm getting a weird error if I put those atoms in appLayout.ts + * So I'm putting the atoms here. Sucks, I know. + */ + +/* [ APPLAYOUT ATOMS ] */ const mainPanelReduced = atomPairing(atomWithStorage("isMainPanelReduced", false)); const settingsOpened = atomPairing(atomWithStorage("isSettingsOpened", false)); @@ -24,37 +29,6 @@ const layout = { terminalMode, }; -/* [ SETTINGS ATOMS ] */ - -const preferredLanguagesAtom = atomPairing(atomWithStorage("preferredLanguages", [])); -const themeModeAtom = atomPairing(atomWithStorage("themeMode", ThemeMode.Auto)); -const darkModeAtom = atomPairing(atom(false)); -const fontSizeAtom = atomPairing(atomWithStorage("fontSize", 1)); -const dyslexicAtom = atomPairing(atomWithStorage("isDyslexic", false)); -const currencyAtom = atomPairing(atomWithStorage("currency", "USD")); -const playerNameAtom = atomPairing(atomWithStorage("playerName", "")); - -export const settings = { - preferredLanguages: preferredLanguagesAtom, - themeMode: themeModeAtom, - darkMode: darkModeAtom, - fontSize: fontSizeAtom, - dyslexic: dyslexicAtom, - currency: currencyAtom, - playerName: playerNameAtom, -}; - -/* [ LIGHTBOX ATOMS ] */ - -export const lightBox = atomPairing( - atom<{ - showLightBox: ( - images: (UploadImageFragment | string | null | undefined)[], - index?: number - ) => void; - }>({ showLightBox: () => null }) -); - /* [ TERMINAL ATOMS ] */ const previousLines = atomPairing(atom([])); @@ -66,10 +40,10 @@ const terminal = { }; export const atoms = { + settings, layout, terminal, localData, - lightBox: lightBox[0], + lightBox, containerQueries, - settings, }; diff --git a/src/contexts/ContainerQueriesProvider.tsx b/src/contexts/containerQueries.ts similarity index 93% rename from src/contexts/ContainerQueriesProvider.tsx rename to src/contexts/containerQueries.ts index 43fd0e1..0e42c75 100644 --- a/src/contexts/ContainerQueriesProvider.tsx +++ b/src/contexts/containerQueries.ts @@ -2,7 +2,7 @@ import { atom, Getter } from "jotai"; import { atomPairing, useAtomSetter } from "helpers/atoms"; import { useOnResize } from "hooks/useOnResize"; import { Ids } from "types/ids"; -import { settings } from "contexts/atoms"; +import { settings } from "contexts/settings"; type Size = | "2xl" @@ -135,11 +135,7 @@ export const containerQueries = { isSubPanelAtLeast7xl, }; -export const ContainerQueriesContextProvider = ({ - children, -}: { - children: React.ReactNode; -}): JSX.Element => { +export const useContainerQueries = (): void => { const setScreenWidth = useAtomSetter(screenWidth); const setContentPanelWidth = useAtomSetter(contentPanelWidth); const setSubPanelWidth = useAtomSetter(subPanelWidth); @@ -147,6 +143,4 @@ export const ContainerQueriesContextProvider = ({ useOnResize(Ids.Body, (width) => setScreenWidth(width)); useOnResize(Ids.ContentPanel, (width) => setContentPanelWidth(width)); useOnResize(Ids.SubPanel, (width) => setSubPanelWidth(width)); - - return <>{children}; }; diff --git a/src/contexts/LocalDataProvider.tsx b/src/contexts/localData.ts similarity index 90% rename from src/contexts/LocalDataProvider.tsx rename to src/contexts/localData.ts index 498259d..1654857 100644 --- a/src/contexts/LocalDataProvider.tsx +++ b/src/contexts/localData.ts @@ -30,7 +30,7 @@ export const localData = { const getFileName = (name: LocalDataFile): string => `/local-data/${name}.json`; -export const LocalDataProvider = ({ children }: { children: React.ReactNode }): JSX.Element => { +export const useLocalData = (): void => { const setLanguages = useAtomSetter(languages); const setCurrencies = useAtomSetter(currencies); const setLangui = useAtomSetter(langui); @@ -56,6 +56,4 @@ export const LocalDataProvider = ({ children }: { children: React.ReactNode }): console.log("[useLocalData] Refresh langui"); setLangui(processLangui(rawLangui, locale)); }, [locale, rawLangui, setLangui]); - - return <>{children}; }; diff --git a/src/contexts/SettingsProvider.tsx b/src/contexts/settings.ts similarity index 65% rename from src/contexts/SettingsProvider.tsx rename to src/contexts/settings.ts index c8d5a97..fe98769 100644 --- a/src/contexts/SettingsProvider.tsx +++ b/src/contexts/settings.ts @@ -1,11 +1,11 @@ import { useRouter } from "next/router"; import { useLayoutEffect, useEffect } from "react"; -import { useAtomGetter, useAtomPair } from "helpers/atoms"; +import { atom } from "jotai"; +import { atomWithStorage } from "jotai/utils"; +import { atomPairing, useAtomGetter, useAtomPair } from "helpers/atoms"; import { getDefaultPreferredLanguages } from "helpers/locales"; import { isDefined, isDefinedAndNotEmpty } from "helpers/others"; import { usePrefersDarkMode } from "hooks/useMediaQuery"; -import { SettingsPopup } from "components/Panels/SettingsPopup"; -import { settings } from "contexts/atoms"; export enum ThemeMode { Dark = "dark", @@ -13,13 +13,31 @@ export enum ThemeMode { Light = "light", } -export const SettingsProvider = ({ children }: { children: React.ReactNode }): JSX.Element => { +const preferredLanguagesAtom = atomPairing(atomWithStorage("preferredLanguages", [])); +const themeModeAtom = atomPairing(atomWithStorage("themeMode", ThemeMode.Auto)); +const darkModeAtom = atomPairing(atom(false)); +const fontSizeAtom = atomPairing(atomWithStorage("fontSize", 1)); +const dyslexicAtom = atomPairing(atomWithStorage("isDyslexic", false)); +const currencyAtom = atomPairing(atomWithStorage("currency", "USD")); +const playerNameAtom = atomPairing(atomWithStorage("playerName", "")); + +export const settings = { + preferredLanguages: preferredLanguagesAtom, + themeMode: themeModeAtom, + darkMode: darkModeAtom, + fontSize: fontSizeAtom, + dyslexic: dyslexicAtom, + currency: currencyAtom, + playerName: playerNameAtom, +}; + +export const useSettings = (): void => { const router = useRouter(); - const [preferredLanguages, setPreferredLanguages] = useAtomPair(settings.preferredLanguages); - const fontSize = useAtomGetter(settings.fontSize); - const isDyslexic = useAtomGetter(settings.dyslexic); - const [isDarkMode, setDarkMode] = useAtomPair(settings.darkMode); - const themeMode = useAtomGetter(settings.themeMode); + const [preferredLanguages, setPreferredLanguages] = useAtomPair(preferredLanguagesAtom); + const fontSize = useAtomGetter(fontSizeAtom); + const isDyslexic = useAtomGetter(dyslexicAtom); + const [isDarkMode, setDarkMode] = useAtomPair(darkModeAtom); + const themeMode = useAtomGetter(themeModeAtom); useLayoutEffect(() => { const html = document.getElementsByTagName("html")[0]; @@ -82,11 +100,4 @@ export const SettingsProvider = ({ children }: { children: React.ReactNode }): J ); } }, [preferredLanguages, router, setPreferredLanguages]); - - return ( - <> - - {children} - - ); }; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 1233a7d..0121a98 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -16,29 +16,31 @@ import "styles/others.css"; import "styles/rc-slider.css"; import "styles/tippy.css"; -import { LocalDataProvider } from "contexts/LocalDataProvider"; +import { useLocalData } from "contexts/localData"; +import { useAppLayout } from "contexts/appLayout"; import { LightBoxProvider } from "contexts/LightBoxProvider"; -import { AppLayoutProvider } from "contexts/AppLayoutProvider"; -import { SettingsProvider } from "contexts/SettingsProvider"; -import { ContainerQueriesContextProvider } from "contexts/ContainerQueriesProvider"; +import { SettingsPopup } from "components/Panels/SettingsPopup"; +import { useSettings } from "contexts/settings"; +import { useContainerQueries } from "contexts/containerQueries"; -const AccordsLibraryApp = (props: AppProps): JSX.Element => ( - - - - - -