Provider hell be gone
This commit is contained in:
parent
0c4d43b891
commit
8456268270
@ -13,7 +13,7 @@ import { prettyLanguage } from "helpers/formatters";
|
|||||||
import { filterHasAttributes, isDefined } from "helpers/others";
|
import { filterHasAttributes, isDefined } from "helpers/others";
|
||||||
import { atoms } from "contexts/atoms";
|
import { atoms } from "contexts/atoms";
|
||||||
import { useAtomGetter, useAtomPair } from "helpers/atoms";
|
import { useAtomGetter, useAtomPair } from "helpers/atoms";
|
||||||
import { ThemeMode } from "contexts/SettingsProvider";
|
import { ThemeMode } from "contexts/settings";
|
||||||
|
|
||||||
export const SettingsPopup = (): JSX.Element => {
|
export const SettingsPopup = (): JSX.Element => {
|
||||||
const [preferredLanguages, setPreferredLanguages] = useAtomPair(
|
const [preferredLanguages, setPreferredLanguages] = useAtomPair(
|
||||||
|
@ -1,17 +1,28 @@
|
|||||||
import React, { useCallback, useState } from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
import { useEffectOnce } from "usehooks-ts";
|
import { useEffectOnce } from "usehooks-ts";
|
||||||
|
import { atom } from "jotai";
|
||||||
import { UploadImageFragment } from "graphql/generated";
|
import { UploadImageFragment } from "graphql/generated";
|
||||||
import { LightBox } from "components/LightBox";
|
import { LightBox } from "components/LightBox";
|
||||||
import { filterDefined } from "helpers/others";
|
import { filterDefined } from "helpers/others";
|
||||||
import { useAtomSetter } from "helpers/atoms";
|
import { atomPairing, useAtomSetter } from "helpers/atoms";
|
||||||
import { lightBox } from "contexts/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 [isLightBoxVisible, setLightBoxVisibility] = useState(false);
|
||||||
const [lightBoxImages, setLightBoxImages] = useState<(UploadImageFragment | string)[]>([]);
|
const [lightBoxImages, setLightBoxImages] = useState<(UploadImageFragment | string)[]>([]);
|
||||||
const [lightBoxIndex, setLightBoxIndex] = useState(0);
|
const [lightBoxIndex, setLightBoxIndex] = useState(0);
|
||||||
|
|
||||||
const setShowLightBox = useAtomSetter(lightBox);
|
const setShowLightBox = useAtomSetter(lightBoxAtom);
|
||||||
|
|
||||||
useEffectOnce(() =>
|
useEffectOnce(() =>
|
||||||
setShowLightBox({
|
setShowLightBox({
|
||||||
@ -30,17 +41,14 @@ export const LightBoxProvider = ({ children }: { children: React.ReactNode }): J
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<LightBox
|
||||||
<LightBox
|
isVisible={isLightBoxVisible}
|
||||||
isVisible={isLightBoxVisible}
|
onCloseRequest={closeLightBox}
|
||||||
onCloseRequest={closeLightBox}
|
image={lightBoxImages[lightBoxIndex]}
|
||||||
image={lightBoxImages[lightBoxIndex]}
|
isNextImageAvailable={lightBoxIndex < lightBoxImages.length - 1}
|
||||||
isNextImageAvailable={lightBoxIndex < lightBoxImages.length - 1}
|
isPreviousImageAvailable={lightBoxIndex > 0}
|
||||||
isPreviousImageAvailable={lightBoxIndex > 0}
|
onPressNext={() => setLightBoxIndex((current) => current + 1)}
|
||||||
onPressNext={() => setLightBoxIndex((current) => current + 1)}
|
onPressPrevious={() => setLightBoxIndex((current) => current - 1)}
|
||||||
onPressPrevious={() => setLightBoxIndex((current) => current - 1)}
|
/>
|
||||||
/>
|
|
||||||
{children}
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ import { useScrollIntoView } from "hooks/useScrollIntoView";
|
|||||||
import { useAtomSetter } from "helpers/atoms";
|
import { useAtomSetter } from "helpers/atoms";
|
||||||
import { atoms } from "contexts/atoms";
|
import { atoms } from "contexts/atoms";
|
||||||
|
|
||||||
export const AppLayoutProvider = ({ children }: { children: React.ReactNode }): JSX.Element => {
|
export const useAppLayout = (): void => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const setSettingsOpened = useAtomSetter(atoms.layout.settingsOpened);
|
const setSettingsOpened = useAtomSetter(atoms.layout.settingsOpened);
|
||||||
@ -26,6 +26,4 @@ export const AppLayoutProvider = ({ children }: { children: React.ReactNode }):
|
|||||||
}, [router, setSettingsOpened, setMainPanelOpened, setSubPanelOpened]);
|
}, [router, setSettingsOpened, setMainPanelOpened, setSubPanelOpened]);
|
||||||
|
|
||||||
useScrollIntoView();
|
useScrollIntoView();
|
||||||
|
|
||||||
return <>{children}</>;
|
|
||||||
};
|
};
|
@ -1,12 +1,17 @@
|
|||||||
import { atomWithStorage } from "jotai/utils";
|
|
||||||
import { atom } from "jotai";
|
import { atom } from "jotai";
|
||||||
import { localData } from "contexts/LocalDataProvider";
|
import { atomWithStorage } from "jotai/utils";
|
||||||
import { containerQueries } from "contexts/ContainerQueriesProvider";
|
import { localData } from "contexts/localData";
|
||||||
|
import { containerQueries } from "contexts/containerQueries";
|
||||||
import { atomPairing } from "helpers/atoms";
|
import { atomPairing } from "helpers/atoms";
|
||||||
import { UploadImageFragment } from "graphql/generated";
|
import { settings } from "contexts/settings";
|
||||||
import { ThemeMode } from "contexts/SettingsProvider";
|
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 mainPanelReduced = atomPairing(atomWithStorage("isMainPanelReduced", false));
|
||||||
const settingsOpened = atomPairing(atomWithStorage("isSettingsOpened", false));
|
const settingsOpened = atomPairing(atomWithStorage("isSettingsOpened", false));
|
||||||
@ -24,37 +29,6 @@ const layout = {
|
|||||||
terminalMode,
|
terminalMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* [ SETTINGS ATOMS ] */
|
|
||||||
|
|
||||||
const preferredLanguagesAtom = atomPairing(atomWithStorage<string[]>("preferredLanguages", []));
|
|
||||||
const themeModeAtom = atomPairing(atomWithStorage<ThemeMode>("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 ] */
|
/* [ TERMINAL ATOMS ] */
|
||||||
|
|
||||||
const previousLines = atomPairing(atom<string[]>([]));
|
const previousLines = atomPairing(atom<string[]>([]));
|
||||||
@ -66,10 +40,10 @@ const terminal = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const atoms = {
|
export const atoms = {
|
||||||
|
settings,
|
||||||
layout,
|
layout,
|
||||||
terminal,
|
terminal,
|
||||||
localData,
|
localData,
|
||||||
lightBox: lightBox[0],
|
lightBox,
|
||||||
containerQueries,
|
containerQueries,
|
||||||
settings,
|
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@ import { atom, Getter } from "jotai";
|
|||||||
import { atomPairing, useAtomSetter } from "helpers/atoms";
|
import { atomPairing, useAtomSetter } from "helpers/atoms";
|
||||||
import { useOnResize } from "hooks/useOnResize";
|
import { useOnResize } from "hooks/useOnResize";
|
||||||
import { Ids } from "types/ids";
|
import { Ids } from "types/ids";
|
||||||
import { settings } from "contexts/atoms";
|
import { settings } from "contexts/settings";
|
||||||
|
|
||||||
type Size =
|
type Size =
|
||||||
| "2xl"
|
| "2xl"
|
||||||
@ -135,11 +135,7 @@ export const containerQueries = {
|
|||||||
isSubPanelAtLeast7xl,
|
isSubPanelAtLeast7xl,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ContainerQueriesContextProvider = ({
|
export const useContainerQueries = (): void => {
|
||||||
children,
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}): JSX.Element => {
|
|
||||||
const setScreenWidth = useAtomSetter(screenWidth);
|
const setScreenWidth = useAtomSetter(screenWidth);
|
||||||
const setContentPanelWidth = useAtomSetter(contentPanelWidth);
|
const setContentPanelWidth = useAtomSetter(contentPanelWidth);
|
||||||
const setSubPanelWidth = useAtomSetter(subPanelWidth);
|
const setSubPanelWidth = useAtomSetter(subPanelWidth);
|
||||||
@ -147,6 +143,4 @@ export const ContainerQueriesContextProvider = ({
|
|||||||
useOnResize(Ids.Body, (width) => setScreenWidth(width));
|
useOnResize(Ids.Body, (width) => setScreenWidth(width));
|
||||||
useOnResize(Ids.ContentPanel, (width) => setContentPanelWidth(width));
|
useOnResize(Ids.ContentPanel, (width) => setContentPanelWidth(width));
|
||||||
useOnResize(Ids.SubPanel, (width) => setSubPanelWidth(width));
|
useOnResize(Ids.SubPanel, (width) => setSubPanelWidth(width));
|
||||||
|
|
||||||
return <>{children}</>;
|
|
||||||
};
|
};
|
@ -30,7 +30,7 @@ export const localData = {
|
|||||||
|
|
||||||
const getFileName = (name: LocalDataFile): string => `/local-data/${name}.json`;
|
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 setLanguages = useAtomSetter(languages);
|
||||||
const setCurrencies = useAtomSetter(currencies);
|
const setCurrencies = useAtomSetter(currencies);
|
||||||
const setLangui = useAtomSetter(langui);
|
const setLangui = useAtomSetter(langui);
|
||||||
@ -56,6 +56,4 @@ export const LocalDataProvider = ({ children }: { children: React.ReactNode }):
|
|||||||
console.log("[useLocalData] Refresh langui");
|
console.log("[useLocalData] Refresh langui");
|
||||||
setLangui(processLangui(rawLangui, locale));
|
setLangui(processLangui(rawLangui, locale));
|
||||||
}, [locale, rawLangui, setLangui]);
|
}, [locale, rawLangui, setLangui]);
|
||||||
|
|
||||||
return <>{children}</>;
|
|
||||||
};
|
};
|
@ -1,11 +1,11 @@
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useLayoutEffect, useEffect } from "react";
|
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 { getDefaultPreferredLanguages } from "helpers/locales";
|
||||||
import { isDefined, isDefinedAndNotEmpty } from "helpers/others";
|
import { isDefined, isDefinedAndNotEmpty } from "helpers/others";
|
||||||
import { usePrefersDarkMode } from "hooks/useMediaQuery";
|
import { usePrefersDarkMode } from "hooks/useMediaQuery";
|
||||||
import { SettingsPopup } from "components/Panels/SettingsPopup";
|
|
||||||
import { settings } from "contexts/atoms";
|
|
||||||
|
|
||||||
export enum ThemeMode {
|
export enum ThemeMode {
|
||||||
Dark = "dark",
|
Dark = "dark",
|
||||||
@ -13,13 +13,31 @@ export enum ThemeMode {
|
|||||||
Light = "light",
|
Light = "light",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SettingsProvider = ({ children }: { children: React.ReactNode }): JSX.Element => {
|
const preferredLanguagesAtom = atomPairing(atomWithStorage<string[]>("preferredLanguages", []));
|
||||||
|
const themeModeAtom = atomPairing(atomWithStorage<ThemeMode>("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 router = useRouter();
|
||||||
const [preferredLanguages, setPreferredLanguages] = useAtomPair(settings.preferredLanguages);
|
const [preferredLanguages, setPreferredLanguages] = useAtomPair(preferredLanguagesAtom);
|
||||||
const fontSize = useAtomGetter(settings.fontSize);
|
const fontSize = useAtomGetter(fontSizeAtom);
|
||||||
const isDyslexic = useAtomGetter(settings.dyslexic);
|
const isDyslexic = useAtomGetter(dyslexicAtom);
|
||||||
const [isDarkMode, setDarkMode] = useAtomPair(settings.darkMode);
|
const [isDarkMode, setDarkMode] = useAtomPair(darkModeAtom);
|
||||||
const themeMode = useAtomGetter(settings.themeMode);
|
const themeMode = useAtomGetter(themeModeAtom);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const html = document.getElementsByTagName("html")[0];
|
const html = document.getElementsByTagName("html")[0];
|
||||||
@ -82,11 +100,4 @@ export const SettingsProvider = ({ children }: { children: React.ReactNode }): J
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [preferredLanguages, router, setPreferredLanguages]);
|
}, [preferredLanguages, router, setPreferredLanguages]);
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<SettingsPopup />
|
|
||||||
{children}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
@ -16,29 +16,31 @@ import "styles/others.css";
|
|||||||
import "styles/rc-slider.css";
|
import "styles/rc-slider.css";
|
||||||
import "styles/tippy.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 { LightBoxProvider } from "contexts/LightBoxProvider";
|
||||||
import { AppLayoutProvider } from "contexts/AppLayoutProvider";
|
import { SettingsPopup } from "components/Panels/SettingsPopup";
|
||||||
import { SettingsProvider } from "contexts/SettingsProvider";
|
import { useSettings } from "contexts/settings";
|
||||||
import { ContainerQueriesContextProvider } from "contexts/ContainerQueriesProvider";
|
import { useContainerQueries } from "contexts/containerQueries";
|
||||||
|
|
||||||
const AccordsLibraryApp = (props: AppProps): JSX.Element => (
|
const AccordsLibraryApp = (props: AppProps): JSX.Element => {
|
||||||
<LocalDataProvider>
|
useLocalData();
|
||||||
<SettingsProvider>
|
useAppLayout();
|
||||||
<AppLayoutProvider>
|
useSettings();
|
||||||
<ContainerQueriesContextProvider>
|
useContainerQueries();
|
||||||
<LightBoxProvider>
|
|
||||||
<Script
|
return (
|
||||||
async
|
<>
|
||||||
defer
|
<SettingsPopup />
|
||||||
data-website-id={process.env.NEXT_PUBLIC_UMAMI_ID}
|
<LightBoxProvider />
|
||||||
src={`${process.env.NEXT_PUBLIC_UMAMI_URL}/umami.js`}
|
<Script
|
||||||
/>
|
async
|
||||||
<props.Component {...props.pageProps} />
|
defer
|
||||||
</LightBoxProvider>
|
data-website-id={process.env.NEXT_PUBLIC_UMAMI_ID}
|
||||||
</ContainerQueriesContextProvider>
|
src={`${process.env.NEXT_PUBLIC_UMAMI_URL}/umami.js`}
|
||||||
</AppLayoutProvider>
|
/>
|
||||||
</SettingsProvider>
|
<props.Component {...props.pageProps} />
|
||||||
</LocalDataProvider>
|
</>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
export default AccordsLibraryApp;
|
export default AccordsLibraryApp;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user