From a9a19ef6dac541738d0ca15275ac22bdb56584d6 Mon Sep 17 00:00:00 2001 From: Mike Surowiec Date: Thu, 29 Jul 2021 09:36:11 -0400 Subject: [PATCH] Move languages out of MainContext (#20503) * move languages off of MainContext * load languages from request to workaround sharing the languages file --- components/HeaderNotifications.tsx | 3 ++- components/LanguagePicker.tsx | 4 +-- components/Search.tsx | 4 ++- components/context/LanguagesContext.tsx | 33 +++++++++++++++++++++++++ components/context/MainContext.tsx | 23 ----------------- pages/_app.tsx | 8 ++++-- 6 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 components/context/LanguagesContext.tsx diff --git a/components/HeaderNotifications.tsx b/components/HeaderNotifications.tsx index db6acda1fe..efce794d0c 100644 --- a/components/HeaderNotifications.tsx +++ b/components/HeaderNotifications.tsx @@ -5,6 +5,7 @@ import { useMainContext } from 'components/context/MainContext' import { useTranslation } from 'components/hooks/useTranslation' import { ExcludesNull } from 'components/lib/ExcludesNull' import { useVersion } from './hooks/useVersion' +import { useLanguages } from './context/LanguagesContext' enum NotificationType { RELEASE = 'RELEASE', @@ -23,11 +24,11 @@ export const HeaderNotifications = () => { relativePath, allVersions, data, - languages, currentLanguage, userLanguage, currentPathWithoutLanguage, } = useMainContext() + const { languages } = useLanguages() const { t } = useTranslation('header') const translationNotices: Array = [] diff --git a/components/LanguagePicker.tsx b/components/LanguagePicker.tsx index 7e05e04e82..0bc308783c 100644 --- a/components/LanguagePicker.tsx +++ b/components/LanguagePicker.tsx @@ -4,14 +4,14 @@ import { Dropdown, Details, useDetails } from '@primer/components' import { ChevronDownIcon } from '@primer/octicons-react' import { Link } from 'components/Link' -import { useMainContext } from './context/MainContext' +import { useLanguages } from './context/LanguagesContext' type Props = { variant?: 'inline' } export const LanguagePicker = ({ variant }: Props) => { const router = useRouter() - const { languages } = useMainContext() + const { languages } = useLanguages() const { getDetailsProps } = useDetails({}) const locale = router.locale || 'en' const langs = Object.values(languages) diff --git a/components/Search.tsx b/components/Search.tsx index 83667a1ee3..b69455aaed 100644 --- a/components/Search.tsx +++ b/components/Search.tsx @@ -6,6 +6,7 @@ import { sendEvent, EventType } from 'components/lib/events' import { useMainContext } from './context/MainContext' import { useVersion } from 'components/hooks/useVersion' import cx from 'classnames' +import { useLanguages } from './context/LanguagesContext' type SearchResult = { url: string @@ -30,9 +31,10 @@ export function Search({ isStandalone = false, updateSearchParams = true, childr const inputRef = useRef(null) const { t } = useTranslation('search') const { currentVersion } = useVersion() + const { languages } = useLanguages() // Figure out language and version for index - const { languages, searchVersions, nonEnterpriseDefaultVersion } = useMainContext() + const { searchVersions, nonEnterpriseDefaultVersion } = useMainContext() // fall back to the non-enterprise default version (FPT currently) on the homepage, 404 page, etc. const version = searchVersions[currentVersion] || searchVersions[nonEnterpriseDefaultVersion] const language = (Object.keys(languages).includes(router.locale || '') && router.locale) || 'en' diff --git a/components/context/LanguagesContext.tsx b/components/context/LanguagesContext.tsx new file mode 100644 index 0000000000..630e806da3 --- /dev/null +++ b/components/context/LanguagesContext.tsx @@ -0,0 +1,33 @@ +import { createContext, useContext } from 'react' +import languages from 'lib/languages.js' + +type LanguageItem = { + name: string + nativeName?: string + code: string + hreflang: string + wip?: boolean +} + +export type LanguagesContextT = { + languages: Record +} + +export const LanguagesContext = createContext(null) + +type Props = { + children?: React.ReactNode +} +export const LanguagesProvider = ({ children }: Props) => { + return {children} +} + +export const useLanguages = (): LanguagesContextT => { + const context = useContext(LanguagesContext) + + if (!context) { + throw new Error('"useLanguagesContext" may only be used inside "LanguagesContext.Provider"') + } + + return context +} diff --git a/components/context/MainContext.tsx b/components/context/MainContext.tsx index 8dbedbfc42..18cce7fce1 100644 --- a/components/context/MainContext.tsx +++ b/components/context/MainContext.tsx @@ -13,14 +13,6 @@ type ProductT = { versions?: Array } -type LanguageItem = { - name: string - nativeName: string - code: string - hreflang: string - wip?: boolean -} - type VersionItem = { version: string versionTitle: string @@ -83,7 +75,6 @@ export type MainContextT = { currentPathWithoutLanguage: string currentLanguage: string userLanguage: string - languages: Record allVersions: Record currentProductTree?: ProductTreeNode | null featureFlags: FeatureFlags @@ -162,20 +153,6 @@ export const getMainContextFromRequest = (req: any): MainContextT => { enterpriseServerVersions: req.context.enterpriseServerVersions, currentLanguage: req.context.currentLanguage, userLanguage: req.context.userLanguage || '', - languages: Object.fromEntries( - Object.entries(req.context.languages).map(([key, entry]: any) => { - return [ - key, - { - name: entry.name, - nativeName: entry.nativeName || '', - code: entry.code, - hreflang: entry.hreflang, - wip: entry.wip || false, - }, - ] - }) - ), allVersions: req.context.allVersions, currentProductTree: req.context.currentProductTree ? getCurrentProductTree(req.context.currentProductTree) diff --git a/pages/_app.tsx b/pages/_app.tsx index 7ec1fdf22d..164a912cbf 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -9,6 +9,8 @@ import '../stylesheets/index.scss' import events from 'components/lib/events' import experiment from 'components/lib/experiment' +import { LanguagesProvider } from 'components/context/LanguagesContext' + type MyAppProps = AppProps & { csrfToken: string; themeProps: typeof defaultThemeProps } const MyApp = ({ Component, pageProps, csrfToken, themeProps }: MyAppProps) => { @@ -39,8 +41,10 @@ const MyApp = ({ Component, pageProps, csrfToken, themeProps }: MyAppProps) => { - - + + + + )