accords-library.com/src/hooks/useSmartLanguage.tsx
2022-05-08 12:21:29 +02:00

77 lines
2.3 KiB
TypeScript

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