diff --git a/src/components/AnchorShare.tsx b/src/components/AnchorShare.tsx index b5ea5c7..4e4dac9 100644 --- a/src/components/AnchorShare.tsx +++ b/src/components/AnchorShare.tsx @@ -1,7 +1,7 @@ import { Ico, Icon } from "./Ico"; import { ToolTip } from "./ToolTip"; import { cJoin } from "helpers/className"; -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -16,7 +16,7 @@ interface Props { // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ export const AnchorShare = ({ id, className }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index c8a9615..f3185c7 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -23,6 +23,9 @@ import { useIs1ColumnLayout, useIsScreenAtLeast } from "hooks/useContainerQuery" import { useOnResize } from "hooks/useOnResize"; import { Ids } from "types/ids"; import { sendAnalytics } from "helpers/analytics"; +import { useUserSettings } from "contexts/UserSettingsContext"; +import { useLocalData } from "contexts/LocalDataContext"; +import { useContainerQueries } from "contexts/ContainerQueriesContext"; /* * ╭─────────────╮ @@ -58,38 +61,39 @@ export const AppLayout = ({ }: Props): JSX.Element => { const { configPanelOpen, - currency, - darkMode, - dyslexic, - fontSize, mainPanelOpen, mainPanelReduced, menuGestures, - playerName, - preferredLanguages, - selectedThemeMode, subPanelOpen, hasDisgardedSafariWarning, setHasDisgardedSafariWarning, setConfigPanelOpen, + setMainPanelOpen, + setSubPanelOpen, + toggleMainPanelOpen, + toggleSubPanelOpen, + } = useAppLayout(); + + const { setScreenWidth, setContentPanelWidth, setSubPanelWidth } = useContainerQueries(); + + const { langui, currencies, languages } = useLocalData(); + + const { + currency, + darkMode, + dyslexic, + fontSize, + playerName, + preferredLanguages, + selectedThemeMode, setCurrency, setDarkMode, setDyslexic, setFontSize, - setMainPanelOpen, setPlayerName, setPreferredLanguages, setSelectedThemeMode, - setSubPanelOpen, - toggleMainPanelOpen, - toggleSubPanelOpen, - setScreenWidth, - setContentPanelWidth, - setSubPanelWidth, - langui, - currencies, - languages, - } = useAppLayout(); + } = useUserSettings(); const router = useRouter(); const is1ColumnLayout = useIs1ColumnLayout(); diff --git a/src/components/Cli/Terminal.tsx b/src/components/Cli/Terminal.tsx index 4af731f..0e7b793 100644 --- a/src/components/Cli/Terminal.tsx +++ b/src/components/Cli/Terminal.tsx @@ -1,9 +1,9 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useRouter } from "next/router"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { cJoin, cIf } from "helpers/className"; import { useTerminalContext } from "contexts/TerminalContext"; import { isDefined, isDefinedAndNotEmpty } from "helpers/others"; +import { useUserSettings } from "contexts/UserSettingsContext"; /* * ╭─────────────╮ @@ -31,7 +31,7 @@ export const Terminal = ({ content, }: Props): JSX.Element => { const [childrenPaths, setChildrenPaths] = useState(propsChildrenPaths); - const { darkMode } = useAppLayout(); + const { darkMode, setPlayerName } = useUserSettings(); const { previousCommands, previousLines, setPreviousCommands, setPreviousLines } = useTerminalContext(); const [line, setLine] = useState(""); @@ -39,7 +39,6 @@ export const Terminal = ({ const [previousCommandIndex, setPreviousCommandIndex] = useState(0); const [carretPosition, setCarretPosition] = useState(0); const router = useRouter(); - const { setPlayerName } = useAppLayout(); const [isTextAreaFocused, setIsTextAreaFocused] = useState(false); const terminalInputRef = useRef(null); diff --git a/src/components/Inputs/LanguageSwitcher.tsx b/src/components/Inputs/LanguageSwitcher.tsx index b63150e..4229428 100644 --- a/src/components/Inputs/LanguageSwitcher.tsx +++ b/src/components/Inputs/LanguageSwitcher.tsx @@ -5,8 +5,8 @@ import { Icon } from "components/Ico"; import { cJoin } from "helpers/className"; import { prettyLanguage } from "helpers/formatters"; import { iterateMap } from "helpers/others"; -import { useLanguages } from "hooks/useLocalData"; import { sendAnalytics } from "helpers/analytics"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -32,7 +32,7 @@ export const LanguageSwitcher = ({ onLanguageChanged, showBadge = true, }: Props): JSX.Element => { - const languages = useLanguages(); + const { languages } = useLocalData(); return ( { - const { libraryItemUserStatus, setLibraryItemUserStatus, langui } = useAppLayout(); + const { libraryItemUserStatus, setLibraryItemUserStatus } = useLibraryItemUserStatus(); + const { langui } = useLocalData(); + return (
{ - const { playerName } = useAppLayout(); + const { playerName } = useUserSettings(); const router = useRouter(); const isContentPanelAtLeastLg = useIsContentPanelAtLeast("lg"); const [openLightBox, LightBox] = useLightBox(); @@ -236,7 +237,7 @@ export const TableOfContents = ({ horizontalLine = false, }: TableOfContentsProps): JSX.Element => { const router = useRouter(); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const toc = useMemo(() => getTocFromMarkdawn(preprocessMarkDawn(text), title), [text, title]); return ( diff --git a/src/components/PanelComponents/ReturnButton.tsx b/src/components/PanelComponents/ReturnButton.tsx index f294355..b78d49d 100644 --- a/src/components/PanelComponents/ReturnButton.tsx +++ b/src/components/PanelComponents/ReturnButton.tsx @@ -6,6 +6,7 @@ import { TranslatedProps } from "types/TranslatedProps"; import { useSmartLanguage } from "hooks/useSmartLanguage"; import { useIs3ColumnsLayout } from "hooks/useContainerQuery"; import { isDefined } from "helpers/others"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -23,7 +24,8 @@ interface Props { // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ export const ReturnButton = ({ href, title, displayOnlyOn, className }: Props): JSX.Element => { - const { setSubPanelOpen, langui } = useAppLayout(); + const { setSubPanelOpen } = useAppLayout(); + const { langui } = useLocalData(); const is3ColumnsLayout = useIs3ColumnsLayout(); return ( diff --git a/src/components/Panels/MainPanel.tsx b/src/components/Panels/MainPanel.tsx index 091ccf1..bb96a67 100644 --- a/src/components/Panels/MainPanel.tsx +++ b/src/components/Panels/MainPanel.tsx @@ -10,6 +10,7 @@ import { isDefinedAndNotEmpty } from "helpers/others"; import { Link } from "components/Inputs/Link"; import { useIs3ColumnsLayout } from "hooks/useContainerQuery"; import { sendAnalytics } from "helpers/analytics"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -18,12 +19,8 @@ import { sendAnalytics } from "helpers/analytics"; export const MainPanel = (): JSX.Element => { const is3ColumnsLayout = useIs3ColumnsLayout(); - const { - mainPanelReduced = false, - toggleMainPanelReduced, - setConfigPanelOpen, - langui, - } = useAppLayout(); + const { mainPanelReduced = false, toggleMainPanelReduced, setConfigPanelOpen } = useAppLayout(); + const { langui } = useLocalData(); return (
{ } toggleMainPanelReduced(); }} - className="bg-light !px-2" + className="z-50 bg-light !px-2" icon={mainPanelReduced ? Icon.ChevronRight : Icon.ChevronLeft} />
diff --git a/src/components/PostPage.tsx b/src/components/PostPage.tsx index 0d1a06d..05e7f45 100644 --- a/src/components/PostPage.tsx +++ b/src/components/PostPage.tsx @@ -13,7 +13,7 @@ import { useSmartLanguage } from "hooks/useSmartLanguage"; import { PostWithTranslations } from "types/types"; import { filterHasAttributes, getStatusDescription } from "helpers/others"; import { prettySlug } from "helpers/formatters"; -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -48,7 +48,7 @@ export const PostPage = ({ displayTitle = true, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ items: post.translations, languageExtractor: useCallback( diff --git a/src/components/PreviewCard.tsx b/src/components/PreviewCard.tsx index 8ab3989..ad58efa 100644 --- a/src/components/PreviewCard.tsx +++ b/src/components/PreviewCard.tsx @@ -4,7 +4,6 @@ import { Chip } from "./Chip"; import { Ico, Icon } from "./Ico"; import { Img } from "./Img"; import { Link } from "./Inputs/Link"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { DatePickerFragment, PricePickerFragment, UploadImageFragment } from "graphql/generated"; import { cIf, cJoin } from "helpers/className"; import { prettyDate, prettyDuration, prettyPrice, prettyShortenNumber } from "helpers/formatters"; @@ -12,7 +11,8 @@ import { ImageQuality } from "helpers/img"; import { useDeviceSupportsHover } from "hooks/useMediaQuery"; import { useSmartLanguage } from "hooks/useSmartLanguage"; import { TranslatedProps } from "types/TranslatedProps"; -import { useCurrencies } from "hooks/useLocalData"; +import { useUserSettings } from "contexts/UserSettingsContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -70,10 +70,10 @@ export const PreviewCard = ({ hoverlay, infoAppend, }: Props): JSX.Element => { - const { currency } = useAppLayout(); + const { currency } = useUserSettings(); + const { currencies } = useLocalData(); const isHoverable = useDeviceSupportsHover(); const router = useRouter(); - const currencies = useCurrencies(); const metadataJSX = useMemo( () => ( diff --git a/src/components/RecorderChip.tsx b/src/components/RecorderChip.tsx index 3832ac1..bb0dc51 100644 --- a/src/components/RecorderChip.tsx +++ b/src/components/RecorderChip.tsx @@ -6,7 +6,7 @@ import { Chip } from "components/Chip"; import { RecorderChipFragment } from "graphql/generated"; import { ImageQuality } from "helpers/img"; import { filterHasAttributes } from "helpers/others"; -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -21,7 +21,7 @@ interface Props { // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ export const RecorderChip = ({ recorder }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( { name: string; @@ -70,7 +70,7 @@ export const SmartList = ({ className, }: Props): JSX.Element => { const [page, setPage] = useState(0); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); useScrollTopOnChange(Ids.ContentPanel, [page], paginationScroolTop); useEffect(() => setPage(0), [searchingTerm, groupingFunction, groupSortingFunction, items]); @@ -223,7 +223,7 @@ export const SmartList = ({ const DefaultRenderWhenEmpty = () => { const is3ColumnsLayout = useIs3ColumnsLayout(); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return (
{ const [openLightBox, LightBox] = useLightBox(); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( <> diff --git a/src/components/Wiki/DefinitionCard.tsx b/src/components/Wiki/DefinitionCard.tsx index 908d797..dccddb5 100644 --- a/src/components/Wiki/DefinitionCard.tsx +++ b/src/components/Wiki/DefinitionCard.tsx @@ -6,7 +6,7 @@ import { useSmartLanguage } from "hooks/useSmartLanguage"; import { Button } from "components/Inputs/Button"; import { useIsContentPanelNoMoreThan } from "hooks/useContainerQuery"; import { cIf, cJoin } from "helpers/className"; -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -31,7 +31,7 @@ interface Props { const DefinitionCard = ({ source, translations = [], index, categories }: Props): JSX.Element => { const isContentPanelNoMoreThanMd = useIsContentPanelNoMoreThan("md"); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ items: translations, languageExtractor: useCallback((item: Props["translations"][number]) => item.language, []), diff --git a/src/contexts/AppLayoutContext.tsx b/src/contexts/AppLayoutContext.tsx index be02a89..a94b214 100644 --- a/src/contexts/AppLayoutContext.tsx +++ b/src/contexts/AppLayoutContext.tsx @@ -1,12 +1,8 @@ -import React, { ReactNode, useContext, useEffect, useLayoutEffect, useState } from "react"; +import React, { ReactNode, useContext, useEffect, useState } from "react"; import { useRouter } from "next/router"; import { useLocalStorage, useSessionStorage } from "usehooks-ts"; -import { isDefined, isDefinedAndNotEmpty } from "helpers/others"; -import { LibraryItemUserStatus, RequiredNonNullable } from "types/types"; -import { useDarkMode } from "hooks/useDarkMode"; -import { Currencies, Languages, Langui } from "helpers/localData"; -import { useCurrencies, useLanguages, useLangui } from "hooks/useLocalData"; -import { getDefaultPreferredLanguages } from "helpers/locales"; +import { isDefined } from "helpers/others"; +import { RequiredNonNullable } from "types/types"; import { useStateWithLocalStorage } from "hooks/useStateWithLocalStorage"; import { useScrollIntoView } from "hooks/useScrollIntoView"; @@ -27,52 +23,10 @@ interface AppLayoutState { toggleMainPanelOpen: () => void; setMainPanelOpen: React.Dispatch>; - darkMode: boolean; - toggleDarkMode: () => void; - setDarkMode: React.Dispatch>; - - selectedThemeMode: boolean; - toggleSelectedThemeMode: () => void; - setSelectedThemeMode: React.Dispatch>; - - fontSize: number; - setFontSize: React.Dispatch>; - - dyslexic: boolean; - toggleDyslexic: () => void; - setDyslexic: React.Dispatch>; - - currency: string; - setCurrency: React.Dispatch>; - - playerName: string; - setPlayerName: React.Dispatch>; - - preferredLanguages: string[]; - setPreferredLanguages: React.Dispatch>; - menuGestures: boolean; toggleMenuGestures: () => void; setMenuGestures: React.Dispatch>; - libraryItemUserStatus: Record; - setLibraryItemUserStatus: React.Dispatch< - React.SetStateAction - >; - - screenWidth: number; - setScreenWidth: React.Dispatch>; - - contentPanelWidth: number; - setContentPanelWidth: React.Dispatch>; - - subPanelWidth: number; - setSubPanelWidth: React.Dispatch>; - - langui: Langui; - languages: Languages; - currencies: Currencies; - hasDisgardedSafariWarning: boolean; setHasDisgardedSafariWarning: React.Dispatch< React.SetStateAction @@ -96,63 +50,23 @@ const initialState: RequiredNonNullable = { toggleMainPanelOpen: () => null, setMainPanelOpen: () => null, - darkMode: false, - toggleDarkMode: () => null, - setDarkMode: () => null, - - selectedThemeMode: false, - toggleSelectedThemeMode: () => null, - setSelectedThemeMode: () => null, - - fontSize: 1, - setFontSize: () => null, - - dyslexic: false, - toggleDyslexic: () => null, - setDyslexic: () => null, - - currency: "USD", - setCurrency: () => null, - - playerName: "", - setPlayerName: () => null, - - preferredLanguages: [], - setPreferredLanguages: () => null, - menuGestures: true, toggleMenuGestures: () => null, setMenuGestures: () => null, - libraryItemUserStatus: {}, - setLibraryItemUserStatus: () => null, - - screenWidth: 0, - setScreenWidth: () => null, - - contentPanelWidth: 0, - setContentPanelWidth: () => null, - - subPanelWidth: 0, - setSubPanelWidth: () => null, - - currencies: [], - languages: [], - langui: {}, - hasDisgardedSafariWarning: false, setHasDisgardedSafariWarning: () => null, }; -const AppContext = React.createContext(initialState); +const AppLayoutContext = React.createContext(initialState); -export const useAppLayout = (): AppLayoutState => useContext(AppContext); +export const useAppLayout = (): AppLayoutState => useContext(AppLayoutContext); interface Props { children: ReactNode; } -export const AppContextProvider = (props: Props): JSX.Element => { +export const AppContextProvider = ({ children }: Props): JSX.Element => { const router = useRouter(); const [subPanelOpen, setSubPanelOpen] = useStateWithLocalStorage( @@ -175,31 +89,8 @@ export const AppContextProvider = (props: Props): JSX.Element => { initialState.mainPanelOpen ); - const [darkMode, selectedThemeMode, setDarkMode, setSelectedThemeMode] = useDarkMode( - "darkMode", - initialState.darkMode - ); - - const [fontSize, setFontSize] = useLocalStorage("fontSize", initialState.fontSize); - - const [dyslexic, setDyslexic] = useLocalStorage("dyslexic", initialState.dyslexic); - - const [currency, setCurrency] = useLocalStorage("currency", initialState.currency); - - const [playerName, setPlayerName] = useLocalStorage("playerName", initialState.playerName); - - const [preferredLanguages, setPreferredLanguages] = useLocalStorage( - "preferredLanguages", - initialState.preferredLanguages - ); - const [menuGestures, setMenuGestures] = useState(false); - const [libraryItemUserStatus, setLibraryItemUserStatus] = useLocalStorage( - "libraryItemUserStatus", - initialState.libraryItemUserStatus - ); - const [hasDisgardedSafariWarning, setHasDisgardedSafariWarning] = useSessionStorage( "hasDisgardedSafariWarning", initialState.hasDisgardedSafariWarning @@ -221,50 +112,10 @@ export const AppContextProvider = (props: Props): JSX.Element => { setMainPanelOpen((current) => (isDefined(current) ? !current : current)); }; - const toggleDarkMode = () => { - setDarkMode((current) => (isDefined(current) ? !current : current)); - }; - const toggleMenuGestures = () => { setMenuGestures((current) => !current); }; - const toggleSelectedThemeMode = () => { - setSelectedThemeMode((current) => (isDefined(current) ? !current : current)); - }; - - const toggleDyslexic = () => { - setDyslexic((current) => (isDefined(current) ? !current : current)); - }; - - const [screenWidth, setScreenWidth] = useState(0); - const [contentPanelWidth, setContentPanelWidth] = useState(0); - const [subPanelWidth, setSubPanelWidth] = useState(0); - - const langui = useLangui(); - const languages = useLanguages(); - const currencies = useCurrencies(); - - useEffect(() => { - if (preferredLanguages.length === 0) { - if (isDefinedAndNotEmpty(router.locale) && router.locales) { - setPreferredLanguages(getDefaultPreferredLanguages(router.locale, router.locales)); - } - } else if (router.locale !== preferredLanguages[0]) { - /* - * Using a timeout to the code getting stuck into a loop when reaching the website with a - * different preferredLanguages[0] from router.locale - */ - setTimeout( - async () => - router.replace(router.asPath, router.asPath, { - locale: preferredLanguages[0], - }), - 250 - ); - } - }, [preferredLanguages, router, router.locale, router.locales, setPreferredLanguages]); - useEffect(() => { router.events.on("routeChangeStart", () => { console.log("[Router Events] on routeChangeStart"); @@ -279,65 +130,30 @@ export const AppContextProvider = (props: Props): JSX.Element => { }); }, [router.events, setConfigPanelOpen, setMainPanelOpen, setSubPanelOpen]); - useLayoutEffect(() => { - const html = document.getElementsByTagName("html")[0]; - if (isDefined(html)) { - html.style.fontSize = `${fontSize * 100}%`; - } - }, [fontSize]); - useScrollIntoView(); return ( - - {props.children} - + {children} + ); }; diff --git a/src/contexts/ContainerQueriesContext.tsx b/src/contexts/ContainerQueriesContext.tsx new file mode 100644 index 0000000..8bdc61a --- /dev/null +++ b/src/contexts/ContainerQueriesContext.tsx @@ -0,0 +1,54 @@ +import React, { ReactNode, useContext, useState } from "react"; +import { RequiredNonNullable } from "types/types"; + +interface ContainerQueriesState { + screenWidth: number; + setScreenWidth: React.Dispatch>; + + contentPanelWidth: number; + setContentPanelWidth: React.Dispatch< + React.SetStateAction + >; + + subPanelWidth: number; + setSubPanelWidth: React.Dispatch>; +} + +const initialState: RequiredNonNullable = { + screenWidth: 0, + setScreenWidth: () => null, + + contentPanelWidth: 0, + setContentPanelWidth: () => null, + + subPanelWidth: 0, + setSubPanelWidth: () => null, +}; + +const ContainerQueriesContext = React.createContext(initialState); + +export const useContainerQueries = (): ContainerQueriesState => useContext(ContainerQueriesContext); + +interface Props { + children: ReactNode; +} + +export const ContainerQueriesContextProvider = ({ children }: Props): JSX.Element => { + const [screenWidth, setScreenWidth] = useState(0); + const [contentPanelWidth, setContentPanelWidth] = useState(0); + const [subPanelWidth, setSubPanelWidth] = useState(0); + + return ( + + {children} + + ); +}; diff --git a/src/contexts/LocalDataContext.tsx b/src/contexts/LocalDataContext.tsx new file mode 100644 index 0000000..f3e1b72 --- /dev/null +++ b/src/contexts/LocalDataContext.tsx @@ -0,0 +1,70 @@ +import React, { ReactNode, useContext, useMemo } from "react"; +import { useRouter } from "next/router"; +import { useFetch } from "usehooks-ts"; +import { + Langui, + Languages, + Currencies, + processCurrencies, + processLanguages, + processLangui, +} from "helpers/localData"; +import { RequiredNonNullable } from "types/types"; +import { LocalDataFile } from "graphql/fetchLocalData"; +import { + LocalDataGetCurrenciesQuery, + LocalDataGetLanguagesQuery, + LocalDataGetWebsiteInterfacesQuery, +} from "graphql/generated"; + +interface LocalDataState { + langui: Langui; + languages: Languages; + currencies: Currencies; +} + +const initialState: RequiredNonNullable = { + currencies: [], + languages: [], + langui: {}, +}; + +const LocalDataContext = React.createContext(initialState); + +export const useLocalData = (): LocalDataState => useContext(LocalDataContext); + +interface Props { + children: ReactNode; +} + +export const LocalDataContextProvider = ({ children }: Props): JSX.Element => { + const langui = useLangui(); + const languages = useLanguages(); + const currencies = useCurrencies(); + + return ( + + {children} + + ); +}; + +const getFileName = (name: LocalDataFile): string => `/local-data/${name}.json`; + +const useLangui = (): Langui => { + const { locale } = useRouter(); + const { data: websiteInterfaces } = useFetch( + getFileName("websiteInterfaces") + ); + return useMemo(() => processLangui(websiteInterfaces, locale), [websiteInterfaces, locale]); +}; + +const useCurrencies = (): Currencies => { + const { data: currencies } = useFetch(getFileName("currencies")); + return useMemo(() => processCurrencies(currencies), [currencies]); +}; + +const useLanguages = (): Languages => { + const { data: languages } = useFetch(getFileName("languages")); + return useMemo(() => processLanguages(languages), [languages]); +}; diff --git a/src/contexts/UserSettingsContext.tsx b/src/contexts/UserSettingsContext.tsx new file mode 100644 index 0000000..5fd144d --- /dev/null +++ b/src/contexts/UserSettingsContext.tsx @@ -0,0 +1,157 @@ +import { useLocalStorage } from "usehooks-ts"; +import React, { ReactNode, useContext, useEffect, useLayoutEffect } from "react"; +import { useRouter } from "next/router"; +import { isDefined, isDefinedAndNotEmpty } from "helpers/others"; +import { RequiredNonNullable } from "types/types"; +import { getDefaultPreferredLanguages } from "helpers/locales"; +import { useDarkMode } from "hooks/useDarkMode"; + +interface UserSettingsState { + fontSize: number; + setFontSize: React.Dispatch>; + + darkMode: boolean; + toggleDarkMode: () => void; + setDarkMode: React.Dispatch>; + + selectedThemeMode: boolean; + toggleSelectedThemeMode: () => void; + setSelectedThemeMode: React.Dispatch< + React.SetStateAction + >; + + dyslexic: boolean; + toggleDyslexic: () => void; + setDyslexic: React.Dispatch>; + + currency: string; + setCurrency: React.Dispatch>; + + playerName: string; + setPlayerName: React.Dispatch>; + + preferredLanguages: string[]; + setPreferredLanguages: React.Dispatch< + React.SetStateAction + >; +} + +const initialState: RequiredNonNullable = { + fontSize: 1, + setFontSize: () => null, + + darkMode: false, + toggleDarkMode: () => null, + setDarkMode: () => null, + + selectedThemeMode: false, + toggleSelectedThemeMode: () => null, + setSelectedThemeMode: () => null, + + dyslexic: false, + toggleDyslexic: () => null, + setDyslexic: () => null, + + currency: "USD", + setCurrency: () => null, + + playerName: "", + setPlayerName: () => null, + + preferredLanguages: [], + setPreferredLanguages: () => null, +}; + +const UserSettingsContext = React.createContext(initialState); + +export const useUserSettings = (): UserSettingsState => useContext(UserSettingsContext); + +interface Props { + children: ReactNode; +} + +export const UserSettingsProvider = ({ children }: Props): JSX.Element => { + const router = useRouter(); + + const [fontSize, setFontSize] = useLocalStorage("fontSize", initialState.fontSize); + + const [darkMode, selectedThemeMode, setDarkMode, setSelectedThemeMode] = useDarkMode( + "darkMode", + initialState.darkMode + ); + + const [dyslexic, setDyslexic] = useLocalStorage("dyslexic", initialState.dyslexic); + + const [currency, setCurrency] = useLocalStorage("currency", initialState.currency); + + const [playerName, setPlayerName] = useLocalStorage("playerName", initialState.playerName); + + const [preferredLanguages, setPreferredLanguages] = useLocalStorage( + "preferredLanguages", + initialState.preferredLanguages + ); + + const toggleDarkMode = () => { + setDarkMode((current) => (isDefined(current) ? !current : current)); + }; + + const toggleSelectedThemeMode = () => { + setSelectedThemeMode((current) => (isDefined(current) ? !current : current)); + }; + + const toggleDyslexic = () => { + setDyslexic((current) => (isDefined(current) ? !current : current)); + }; + + useEffect(() => { + if (preferredLanguages.length === 0) { + if (isDefinedAndNotEmpty(router.locale) && router.locales) { + setPreferredLanguages(getDefaultPreferredLanguages(router.locale, router.locales)); + } + } else if (router.locale !== preferredLanguages[0]) { + /* + * Using a timeout to the code getting stuck into a loop when reaching the website with a + * different preferredLanguages[0] from router.locale + */ + setTimeout( + async () => + router.replace(router.asPath, router.asPath, { + locale: preferredLanguages[0], + }), + 250 + ); + } + }, [preferredLanguages, router, router.locale, router.locales, setPreferredLanguages]); + + useLayoutEffect(() => { + const html = document.getElementsByTagName("html")[0]; + if (isDefined(html)) { + html.style.fontSize = `${fontSize * 100}%`; + } + }, [fontSize]); + + return ( + + {children} + + ); +}; diff --git a/src/hooks/useContainerQuery.ts b/src/hooks/useContainerQuery.ts index bed97cc..4a3f131 100644 --- a/src/hooks/useContainerQuery.ts +++ b/src/hooks/useContainerQuery.ts @@ -1,4 +1,5 @@ -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useContainerQueries } from "contexts/ContainerQueriesContext"; +import { useUserSettings } from "contexts/UserSettingsContext"; type MediaQuery = { value: number; unit: "px" | "rem"; rule: "max" | "min" }; @@ -32,7 +33,7 @@ const sizes: Record = { }; export const useIsScreenAtLeast = (size: Size): boolean => { - const { screenWidth } = useAppLayout(); + const { screenWidth } = useContainerQueries(); return useApplyContainerQuery(screenWidth, { value: sizes[size], unit: "rem", @@ -42,7 +43,7 @@ export const useIsScreenAtLeast = (size: Size): boolean => { // ts-unused-exports:disable-next-line export const useIsScreenNoMoreThan = (size: Size): boolean => { - const { screenWidth } = useAppLayout(); + const { screenWidth } = useContainerQueries(); return useApplyContainerQuery(screenWidth, { value: sizes[size], unit: "rem", @@ -51,7 +52,7 @@ export const useIsScreenNoMoreThan = (size: Size): boolean => { }; export const useIsContentPanelAtLeast = (size: Size): boolean => { - const { contentPanelWidth } = useAppLayout(); + const { contentPanelWidth } = useContainerQueries(); return useApplyContainerQuery(contentPanelWidth, { value: sizes[size], unit: "rem", @@ -60,7 +61,7 @@ export const useIsContentPanelAtLeast = (size: Size): boolean => { }; export const useIsContentPanelNoMoreThan = (size: Size): boolean => { - const { contentPanelWidth } = useAppLayout(); + const { contentPanelWidth } = useContainerQueries(); return useApplyContainerQuery(contentPanelWidth, { value: sizes[size], unit: "rem", @@ -69,7 +70,7 @@ export const useIsContentPanelNoMoreThan = (size: Size): boolean => { }; export const useIsSubPanelAtLeast = (size: Size): boolean => { - const { subPanelWidth } = useAppLayout(); + const { subPanelWidth } = useContainerQueries(); return useApplyContainerQuery(subPanelWidth, { value: sizes[size], unit: "rem", @@ -79,7 +80,7 @@ export const useIsSubPanelAtLeast = (size: Size): boolean => { // ts-unused-exports:disable-next-line export const useIsSubPanelNoMoreThan = (size: Size): boolean => { - const { subPanelWidth } = useAppLayout(); + const { subPanelWidth } = useContainerQueries(); return useApplyContainerQuery(subPanelWidth, { value: sizes[size], unit: "rem", @@ -88,7 +89,7 @@ export const useIsSubPanelNoMoreThan = (size: Size): boolean => { }; export const useIs3ColumnsLayout = (): boolean => { - const { screenWidth } = useAppLayout(); + const { screenWidth } = useContainerQueries(); return useApplyContainerQuery(screenWidth, { value: sizes["5xl"], unit: "rem", @@ -97,7 +98,7 @@ export const useIs3ColumnsLayout = (): boolean => { }; export const useIs1ColumnLayout = (): boolean => { - const { screenWidth } = useAppLayout(); + const { screenWidth } = useContainerQueries(); return useApplyContainerQuery(screenWidth, { value: sizes["5xl"], unit: "rem", @@ -106,7 +107,7 @@ export const useIs1ColumnLayout = (): boolean => { }; const useApplyContainerQuery = (width: number, query: MediaQuery) => { - const { fontSize } = useAppLayout(); + const { fontSize } = useUserSettings(); const breakpoint = query.value * (query.unit === "rem" ? 16 : 1) * fontSize; return query.rule === "min" ? width >= breakpoint : width < breakpoint; }; diff --git a/src/hooks/useIsTerminalMode.ts b/src/hooks/useIsTerminalMode.ts index 3cff725..4ba8112 100644 --- a/src/hooks/useIsTerminalMode.ts +++ b/src/hooks/useIsTerminalMode.ts @@ -1,6 +1,6 @@ -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useUserSettings } from "contexts/UserSettingsContext"; export const useIsTerminalMode = (): boolean => { - const { playerName } = useAppLayout(); + const { playerName } = useUserSettings(); return playerName === "root"; }; diff --git a/src/hooks/useLibraryItemUserStatus.ts b/src/hooks/useLibraryItemUserStatus.ts new file mode 100644 index 0000000..4900299 --- /dev/null +++ b/src/hooks/useLibraryItemUserStatus.ts @@ -0,0 +1,15 @@ +import { useLocalStorage } from "usehooks-ts"; +import { LibraryItemUserStatus } from "types/types"; + +export const useLibraryItemUserStatus = (): { + libraryItemUserStatus: Record; + setLibraryItemUserStatus: React.Dispatch< + React.SetStateAction> + >; +} => { + const [libraryItemUserStatus, setLibraryItemUserStatus] = useLocalStorage( + "libraryItemUserStatus", + {} + ); + return { libraryItemUserStatus, setLibraryItemUserStatus }; +}; diff --git a/src/hooks/useLocalData.ts b/src/hooks/useLocalData.ts deleted file mode 100644 index 93c65d5..0000000 --- a/src/hooks/useLocalData.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { useFetch } from "usehooks-ts"; -import { useRouter } from "next/router"; -import { useMemo } from "react"; -import { LocalDataGetWebsiteInterfacesQuery } from "graphql/generated"; -import { - Currencies, - Languages, - Langui, - processCurrencies, - processLanguages, - processLangui, -} from "helpers/localData"; -import { LocalDataFile } from "graphql/fetchLocalData"; - -const useFetchLocalData = (name: LocalDataFile) => - useFetch(`/local-data/${name}.json`); - -export const useLangui = (): Langui => { - const { locale } = useRouter(); - const { data: websiteInterfaces } = useFetchLocalData("websiteInterfaces"); - return useMemo(() => processLangui(websiteInterfaces, locale), [websiteInterfaces, locale]); -}; - -export const useCurrencies = (): Currencies => { - const { data: currencies } = useFetchLocalData("currencies"); - return useMemo(() => processCurrencies(currencies), [currencies]); -}; - -export const useLanguages = (): Languages => { - const { data: languages } = useFetchLocalData("languages"); - return useMemo(() => processLanguages(languages), [languages]); -}; diff --git a/src/hooks/useSmartLanguage.ts b/src/hooks/useSmartLanguage.ts index ef9d137..0b27421 100644 --- a/src/hooks/useSmartLanguage.ts +++ b/src/hooks/useSmartLanguage.ts @@ -1,10 +1,10 @@ import { useRouter } from "next/router"; import { useEffect, useMemo, useState } from "react"; -import { useLanguages } from "./useLocalData"; import { LanguageSwitcher } from "components/Inputs/LanguageSwitcher"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { filterDefined, isDefined } from "helpers/others"; import { getPreferredLanguage } from "helpers/locales"; +import { useUserSettings } from "contexts/UserSettingsContext"; +import { useLocalData } from "contexts/LocalDataContext"; interface Props { items: T[]; @@ -17,8 +17,8 @@ export const useSmartLanguage = ({ languageExtractor, transform = (item) => item, }: Props): [T | undefined, typeof LanguageSwitcher, Parameters[0]] => { - const { preferredLanguages } = useAppLayout(); - const languages = useLanguages(); + const { preferredLanguages } = useUserSettings(); + const { languages } = useLocalData(); const router = useRouter(); const availableLocales = useMemo(() => { diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 686f8b0..a7c3d4e 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -5,7 +5,7 @@ import { ContentPanel } from "components/Panels/ContentPanel"; import { getOpenGraph } from "helpers/openGraph"; import { getLangui } from "graphql/fetchLocalData"; import { Img } from "components/Img"; -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -15,7 +15,7 @@ import { useAppLayout } from "contexts/AppLayoutContext"; interface Props extends AppLayoutRequired {} const FourOhFour = ({ openGraph, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( ( - - - + + + + + + + + + ); export default AccordsLibraryApp; diff --git a/src/pages/about-us/accords-handbook.tsx b/src/pages/about-us/accords-handbook.tsx index 5be6d71..54fbcd7 100644 --- a/src/pages/about-us/accords-handbook.tsx +++ b/src/pages/about-us/accords-handbook.tsx @@ -1,6 +1,6 @@ import { PostPage } from "components/PostPage"; import { getPostStaticProps, PostStaticProps } from "graphql/getPostStaticProps"; -import { useAppLayout } from "contexts/AppLayoutContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -8,7 +8,7 @@ import { useAppLayout } from "contexts/AppLayoutContext"; */ const AccordsHandbook = (props: PostStaticProps): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( { const router = useRouter(); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const is1ColumnLayout = useIs1ColumnLayout(); const [formResponse, setFormResponse] = useState(""); const [formState, setFormState] = useState<"completed" | "ongoing" | "stale">("stale"); diff --git a/src/pages/about-us/index.tsx b/src/pages/about-us/index.tsx index 6e608cf..98fd454 100644 --- a/src/pages/about-us/index.tsx +++ b/src/pages/about-us/index.tsx @@ -6,8 +6,8 @@ import { PanelHeader } from "components/PanelComponents/PanelHeader"; import { SubPanel } from "components/Panels/SubPanel"; import { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -17,7 +17,7 @@ import { getLangui } from "graphql/fetchLocalData"; interface Props extends AppLayoutRequired {} const AboutUs = (props: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const subPanel = useMemo( () => ( diff --git a/src/pages/archives/videos/c/[uid].tsx b/src/pages/archives/videos/c/[uid].tsx index d0c41d4..706e873 100644 --- a/src/pages/archives/videos/c/[uid].tsx +++ b/src/pages/archives/videos/c/[uid].tsx @@ -22,8 +22,8 @@ import { SmartList } from "components/SmartList"; import { cIf } from "helpers/className"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { TextInput } from "components/Inputs/TextInput"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -45,7 +45,7 @@ interface Props extends AppLayoutRequired { const Channel = ({ channel, ...otherProps }: Props): JSX.Element => { const { value: keepInfoVisible, toggle: toggleKeepInfoVisible } = useBoolean(true); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const hoverable = useDeviceSupportsHover(); const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); diff --git a/src/pages/archives/videos/index.tsx b/src/pages/archives/videos/index.tsx index abaa096..9f6cc2c 100644 --- a/src/pages/archives/videos/index.tsx +++ b/src/pages/archives/videos/index.tsx @@ -22,8 +22,8 @@ import { compareDate } from "helpers/date"; import { HorizontalLine } from "components/HorizontalLine"; import { cIf } from "helpers/className"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -44,7 +44,7 @@ interface Props extends AppLayoutRequired { } const Videos = ({ videos, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const hoverable = useDeviceSupportsHover(); const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); diff --git a/src/pages/archives/videos/v/[uid].tsx b/src/pages/archives/videos/v/[uid].tsx index 0b5feb0..a1068f8 100644 --- a/src/pages/archives/videos/v/[uid].tsx +++ b/src/pages/archives/videos/v/[uid].tsx @@ -19,6 +19,7 @@ import { getVideoFile } from "helpers/videos"; import { getOpenGraph } from "helpers/openGraph"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -31,7 +32,8 @@ interface Props extends AppLayoutRequired { const Video = ({ video, ...otherProps }: Props): JSX.Element => { const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); - const { setSubPanelOpen, langui } = useAppLayout(); + const { setSubPanelOpen } = useAppLayout(); + const { langui } = useLocalData(); const router = useRouter(); const subPanel = useMemo( diff --git a/src/pages/chronicles/[slug]/index.tsx b/src/pages/chronicles/[slug]/index.tsx index 2a15231..b1a04be 100644 --- a/src/pages/chronicles/[slug]/index.tsx +++ b/src/pages/chronicles/[slug]/index.tsx @@ -18,8 +18,8 @@ import { getOpenGraph } from "helpers/openGraph"; import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales"; import { getDescription } from "helpers/description"; import { TranslatedChroniclesList } from "components/Chronicles/ChroniclesList"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -32,7 +32,7 @@ interface Props extends AppLayoutRequired { } const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ items: chronicle.translations, languageExtractor: useCallback( diff --git a/src/pages/chronicles/index.tsx b/src/pages/chronicles/index.tsx index 19baf19..b0a54ce 100644 --- a/src/pages/chronicles/index.tsx +++ b/src/pages/chronicles/index.tsx @@ -11,8 +11,8 @@ import { prettySlug } from "helpers/formatters"; import { getOpenGraph } from "helpers/openGraph"; import { TranslatedChroniclesList } from "components/Chronicles/ChroniclesList"; import { HorizontalLine } from "components/HorizontalLine"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -24,7 +24,7 @@ interface Props extends AppLayoutRequired { } const Chronicles = ({ chapters, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const subPanel = useMemo( () => ( diff --git a/src/pages/contents/[slug].tsx b/src/pages/contents/[slug].tsx index 8403cfb..930bd83 100644 --- a/src/pages/contents/[slug].tsx +++ b/src/pages/contents/[slug].tsx @@ -32,8 +32,8 @@ import { TranslatedPreviewLine } from "components/PreviewLine"; import { useIs1ColumnLayout, useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { cIf } from "helpers/className"; import { getLangui } from "graphql/fetchLocalData"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { Ids } from "types/ids"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -47,7 +47,7 @@ interface Props extends AppLayoutRequired { const Content = ({ content, ...otherProps }: Props): JSX.Element => { const isContentPanelAtLeast2xl = useIsContentPanelAtLeast("2xl"); const is1ColumnLayout = useIs1ColumnLayout(); - const { langui, languages } = useAppLayout(); + const { langui, languages } = useLocalData(); const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ items: content.translations, diff --git a/src/pages/contents/all.tsx b/src/pages/contents/all.tsx index b54e3c4..78ba723 100644 --- a/src/pages/contents/all.tsx +++ b/src/pages/contents/all.tsx @@ -24,9 +24,9 @@ import { HorizontalLine } from "components/HorizontalLine"; import { TranslatedPreviewCard } from "components/PreviewCard"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { cJoin, cIf } from "helpers/className"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -50,7 +50,7 @@ interface Props extends AppLayoutRequired { const Contents = ({ contents, ...otherProps }: Props): JSX.Element => { const hoverable = useDeviceSupportsHover(); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); const [groupingMethod, setGroupingMethod] = useState( diff --git a/src/pages/contents/folder/[slug].tsx b/src/pages/contents/folder/[slug].tsx index 7dbf261..fe25a66 100644 --- a/src/pages/contents/folder/[slug].tsx +++ b/src/pages/contents/folder/[slug].tsx @@ -21,8 +21,8 @@ import { TranslatedPreviewCard } from "components/PreviewCard"; import { HorizontalLine } from "components/HorizontalLine"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { cJoin, cIf } from "helpers/className"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -36,7 +36,7 @@ interface Props extends AppLayoutRequired { } const ContentsFolder = ({ openGraph, folder, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); const subPanel = useMemo( @@ -305,7 +305,7 @@ const TranslatedPreviewFolder = ({ // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ const NoContentNorFolderMessage = () => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return (
{ - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const isTerminalMode = useIsTerminalMode(); if (isTerminalMode) { diff --git a/src/pages/library/[slug]/index.tsx b/src/pages/library/[slug]/index.tsx index c0557bb..cd51d09 100644 --- a/src/pages/library/[slug]/index.tsx +++ b/src/pages/library/[slug]/index.tsx @@ -14,7 +14,6 @@ import { ReturnButton } from "components/PanelComponents/ReturnButton"; import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel"; import { SubPanel } from "components/Panels/SubPanel"; import { PreviewCard } from "components/PreviewCard"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { Enum_Componentmetadatabooks_Binding_Type, Enum_Componentmetadatabooks_Page_Order, @@ -52,9 +51,10 @@ import { getDescription } from "helpers/description"; import { useIntersectionList } from "hooks/useIntersectionList"; import { HorizontalLine } from "components/HorizontalLine"; import { useIsContentPanelNoMoreThan } from "hooks/useContainerQuery"; -import { useCurrencies } from "hooks/useLocalData"; import { getLangui } from "graphql/fetchLocalData"; import { Ids } from "types/ids"; +import { useUserSettings } from "contexts/UserSettingsContext"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -74,9 +74,8 @@ interface Props extends AppLayoutRequired { } const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => { - const { currency } = useAppLayout(); - const { langui } = useAppLayout(); - const currencies = useCurrencies(); + const { currency } = useUserSettings(); + const { langui, currencies } = useLocalData(); const isContentPanelNoMoreThan3xl = useIsContentPanelNoMoreThan("3xl"); const isContentPanelNoMoreThanSm = useIsContentPanelNoMoreThan("sm"); const hoverable = useDeviceSupportsHover(); @@ -698,7 +697,7 @@ const ContentLine = ({ parentSlug, condensed, }: ContentLineProps): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const { value: isOpened, toggle: toggleOpened } = useBoolean(false); const [selectedTranslation] = useSmartLanguage({ items: content?.translations ?? [], diff --git a/src/pages/library/[slug]/reader.tsx b/src/pages/library/[slug]/reader.tsx index 16b0d09..8689303 100644 --- a/src/pages/library/[slug]/reader.tsx +++ b/src/pages/library/[slug]/reader.tsx @@ -27,7 +27,6 @@ import { getAssetFilename, ImageQuality } from "helpers/img"; import { useIs1ColumnLayout, useIsContentPanelNoMoreThan } from "hooks/useContainerQuery"; import { cIf, cJoin } from "helpers/className"; import { clamp, isInteger } from "helpers/numbers"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { SubPanel } from "components/Panels/SubPanel"; import { Button } from "components/Inputs/Button"; import { Icon } from "components/Ico"; @@ -44,6 +43,8 @@ import { useSmartLanguage } from "hooks/useSmartLanguage"; import { TranslatedProps } from "types/TranslatedProps"; import { prettyInlineTitle, prettySlug } from "helpers/formatters"; import { useFullscreen } from "hooks/useFullscreen"; +import { useUserSettings } from "contexts/UserSettingsContext"; +import { useLocalData } from "contexts/LocalDataContext"; const CUSTOM_DARK_DROPSHADOW = ` drop-shadow(0 0 0.5em rgb(var(--theme-color-shade) / 30%)) @@ -110,8 +111,8 @@ const LibrarySlug = ({ ...otherProps }: Props): JSX.Element => { const is1ColumnLayout = useIs1ColumnLayout(); - const { langui } = useAppLayout(); - const { darkMode } = useAppLayout(); + const { langui } = useLocalData(); + const { darkMode } = useUserSettings(); const [currentPageIndex, setCurrentPageIndex] = useState(0); const [currentZoom, setCurrentZoom] = useState(1); const [isGalleryMode, setIsGalleryMode] = useState(false); @@ -814,7 +815,7 @@ interface PageFiltersProps { } const PageFilters = ({ page, bookType, options }: PageFiltersProps) => { - const { darkMode } = useAppLayout(); + const { darkMode } = useUserSettings(); const commonCss = useMemo( () => cJoin("absolute inset-0", cIf(page === "right", "[background-position-x:-100%]")), [page] @@ -906,7 +907,7 @@ interface ScanSetProps { const ScanSet = ({ onClickOnImage, scanSet, id, title, content }: ScanSetProps): JSX.Element => { const is1ColumnLayout = useIsContentPanelNoMoreThan("2xl"); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const [selectedScan, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ items: scanSet, languageExtractor: useCallback( diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx index 251b5c3..4799ccc 100644 --- a/src/pages/library/index.tsx +++ b/src/pages/library/index.tsx @@ -22,7 +22,6 @@ import { PreviewCard } from "components/PreviewCard"; import { useDeviceSupportsHover } from "hooks/useMediaQuery"; import { ButtonGroup } from "components/Inputs/ButtonGroup"; import { filterHasAttributes, isDefined, isDefinedAndNotEmpty, isUndefined } from "helpers/others"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { convertPrice } from "helpers/numbers"; import { SmartList } from "components/SmartList"; import { SelectiveNonNullable } from "types/SelectiveNonNullable"; @@ -31,9 +30,10 @@ import { compareDate } from "helpers/date"; import { HorizontalLine } from "components/HorizontalLine"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { cIf, cJoin } from "helpers/className"; -import { useCurrencies } from "hooks/useLocalData"; import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; +import { useLocalData } from "contexts/LocalDataContext"; +import { useLibraryItemUserStatus } from "hooks/useLibraryItemUserStatus"; /* * ╭─────────────╮ @@ -62,9 +62,8 @@ interface Props extends AppLayoutRequired { const Library = ({ items, ...otherProps }: Props): JSX.Element => { const hoverable = useDeviceSupportsHover(); - const currencies = useCurrencies(); - const { langui } = useAppLayout(); - const { libraryItemUserStatus } = useAppLayout(); + const { langui, currencies } = useLocalData(); + const { libraryItemUserStatus } = useLibraryItemUserStatus(); const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); const [searchName, setSearchName] = useState(DEFAULT_FILTERS_STATE.searchName); diff --git a/src/pages/merch/index.tsx b/src/pages/merch/index.tsx index a98421a..16f3821 100644 --- a/src/pages/merch/index.tsx +++ b/src/pages/merch/index.tsx @@ -4,8 +4,8 @@ import { PanelHeader } from "components/PanelComponents/PanelHeader"; import { SubPanel } from "components/Panels/SubPanel"; import { Icon } from "components/Ico"; import { getOpenGraph } from "helpers/openGraph"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -14,7 +14,7 @@ import { getLangui } from "graphql/fetchLocalData"; interface Props extends AppLayoutRequired {} const Merch = (props: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); return ( { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const isTerminalMode = useIsTerminalMode(); const router = useRouter(); diff --git a/src/pages/news/index.tsx b/src/pages/news/index.tsx index e6884f4..38c2034 100644 --- a/src/pages/news/index.tsx +++ b/src/pages/news/index.tsx @@ -22,11 +22,11 @@ import { TranslatedPreviewCard } from "components/PreviewCard"; import { HorizontalLine } from "components/HorizontalLine"; import { cIf } from "helpers/className"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; import { useIsTerminalMode } from "hooks/useIsTerminalMode"; import { Terminal } from "components/Cli/Terminal"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -49,7 +49,7 @@ interface Props extends AppLayoutRequired { const News = ({ posts, ...otherProps }: Props): JSX.Element => { const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const hoverable = useDeviceSupportsHover(); const [searchName, setSearchName] = useState(DEFAULT_FILTERS_STATE.searchName); const { diff --git a/src/pages/wiki/[slug]/index.tsx b/src/pages/wiki/[slug]/index.tsx index fbedac6..44f1dff 100644 --- a/src/pages/wiki/[slug]/index.tsx +++ b/src/pages/wiki/[slug]/index.tsx @@ -21,11 +21,11 @@ import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/local import { getDescription } from "helpers/description"; import { cIf, cJoin } from "helpers/className"; import { useIs3ColumnsLayout } from "hooks/useContainerQuery"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; import { Terminal } from "components/Cli/Terminal"; import { prettyTerminalBoxedTitle, prettyTerminalUnderlinedTitle } from "helpers/terminal"; import { useIsTerminalMode } from "hooks/useIsTerminalMode"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -37,7 +37,7 @@ interface Props extends AppLayoutRequired { } const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const router = useRouter(); const isTerminalMode = useIsTerminalMode(); const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ diff --git a/src/pages/wiki/chronology.tsx b/src/pages/wiki/chronology.tsx index 5920a79..6a68884 100644 --- a/src/pages/wiki/chronology.tsx +++ b/src/pages/wiki/chronology.tsx @@ -30,8 +30,8 @@ import { TranslatedProps } from "types/TranslatedProps"; import { TranslatedNavOption } from "components/PanelComponents/NavOption"; import { useIntersectionList } from "hooks/useIntersectionList"; import { HorizontalLine } from "components/HorizontalLine"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭────────╮ @@ -44,7 +44,7 @@ interface Props extends AppLayoutRequired { } const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const ids = useMemo( () => filterHasAttributes(chronologyEras, ["attributes"] as const).map( @@ -315,7 +315,7 @@ interface ChronologyEventProps { } export const ChronologyEvent = ({ event, id }: ChronologyEventProps): JSX.Element => { - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ items: event.translations ?? [], languageExtractor: useCallback( diff --git a/src/pages/wiki/index.tsx b/src/pages/wiki/index.tsx index b7dd1d2..a52861b 100644 --- a/src/pages/wiki/index.tsx +++ b/src/pages/wiki/index.tsx @@ -24,11 +24,11 @@ import { getOpenGraph } from "helpers/openGraph"; import { TranslatedPreviewCard } from "components/PreviewCard"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { cIf } from "helpers/className"; -import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; import { sendAnalytics } from "helpers/analytics"; import { Terminal } from "components/Cli/Terminal"; import { useIsTerminalMode } from "hooks/useIsTerminalMode"; +import { useLocalData } from "contexts/LocalDataContext"; /* * ╭─────────────╮ @@ -52,7 +52,7 @@ interface Props extends AppLayoutRequired { const Wiki = ({ pages, ...otherProps }: Props): JSX.Element => { const hoverable = useDeviceSupportsHover(); - const { langui } = useAppLayout(); + const { langui } = useLocalData(); const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); const isTerminalMode = useIsTerminalMode(); diff --git a/src/tailwind.css b/src/tailwind.css index 4061fe9..540b92d 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -25,7 +25,7 @@ a { } mark { - @apply bg-mid px-2; + @apply bg-mid px-2 text-black; } /* SCROLLBARS STYLING */