import { LanguageSwitcher } from "components/Inputs/LanguageSwitcher"; import { useAppLayout } from "contexts/AppLayoutContext"; import { AppStaticProps } from "graphql/getAppStaticProps"; import { filterDefined, isDefined } from "helpers/others"; import { useRouter } from "next/router"; import { useEffect, useMemo, useState } from "react"; interface Props { items: T[]; languages: AppStaticProps["languages"]; languageExtractor: (item: NonNullable) => string | undefined; transform?: (item: NonNullable) => NonNullable; } function getPreferredLanguage( preferredLanguages: (string | undefined)[], availableLanguages: Map ): number | undefined { for (const locale of preferredLanguages) { if (isDefined(locale) && availableLanguages.has(locale)) { return availableLanguages.get(locale); } } return undefined; } export function useSmartLanguage( props: Props ): [T | undefined, () => JSX.Element] { const { items, languageExtractor, languages, transform = (item) => item, } = props; const { preferredLanguages } = useAppLayout(); const router = useRouter(); const availableLocales = useMemo(() => { const memo = new Map(); filterDefined(items).map((elem, index) => { const result = languageExtractor(elem); if (isDefined(result)) memo.set(result, index); }); return memo; }, [items, languageExtractor]); const [selectedTranslationIndex, setSelectedTranslationIndex] = useState< number | undefined >(); useEffect(() => { setSelectedTranslationIndex( (current) => current ?? getPreferredLanguage( preferredLanguages ?? [router.locale], availableLocales ) ); }, [preferredLanguages, availableLocales, router.locale]); const selectedTranslation = useMemo(() => { if (isDefined(selectedTranslationIndex)) { const item = items[selectedTranslationIndex]; if (isDefined(item)) { return transform(item); } } return undefined; }, [items, selectedTranslationIndex, transform]); return [ selectedTranslation, () => ( ), ]; }