2023-08-22 18:08:34 +00:00
|
|
|
import { lookup } from "bcp-47-match";
|
2023-08-19 00:46:17 +00:00
|
|
|
import { useSession } from "next-auth/react";
|
2021-10-12 13:11:33 +00:00
|
|
|
import { useTranslation } from "next-i18next";
|
2021-10-14 19:10:44 +00:00
|
|
|
import { useEffect } from "react";
|
2021-10-12 13:11:33 +00:00
|
|
|
|
2023-08-22 12:34:55 +00:00
|
|
|
import { CALCOM_VERSION } from "@calcom/lib/constants";
|
2022-07-22 17:27:06 +00:00
|
|
|
import { trpc } from "@calcom/trpc/react";
|
2021-10-12 13:11:33 +00:00
|
|
|
|
2023-08-22 12:34:55 +00:00
|
|
|
function useViewerI18n(locale: string) {
|
2023-08-19 00:46:17 +00:00
|
|
|
return trpc.viewer.public.i18n.useQuery(
|
2023-08-22 12:34:55 +00:00
|
|
|
{ locale, CalComVersion: CALCOM_VERSION },
|
2023-08-19 00:46:17 +00:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* i18n should never be clubbed with other queries, so that it's caching can be managed independently.
|
|
|
|
**/
|
|
|
|
trpc: {
|
|
|
|
context: { skipBatch: true },
|
|
|
|
},
|
|
|
|
}
|
|
|
|
);
|
2021-10-14 19:10:44 +00:00
|
|
|
}
|
|
|
|
|
2023-08-22 12:34:55 +00:00
|
|
|
function useClientLocale(locales: string[]) {
|
|
|
|
const session = useSession();
|
|
|
|
// If the user is logged in, use their locale
|
|
|
|
if (session.data?.user.locale) return session.data.user.locale;
|
|
|
|
// If the user is not logged in, use the browser locale
|
|
|
|
if (typeof window !== "undefined") {
|
|
|
|
// This is the only way I found to ensure the prefetched locale is used on first render
|
|
|
|
// FIXME: Find a better way to pick the best matching locale from the browser
|
2023-08-22 18:08:34 +00:00
|
|
|
return lookup(locales, window.navigator.language) || window.navigator.language;
|
2023-08-22 12:34:55 +00:00
|
|
|
}
|
|
|
|
// If the browser is not available, use English
|
|
|
|
return "en";
|
|
|
|
}
|
|
|
|
|
|
|
|
export function useClientViewerI18n(locales: string[]) {
|
|
|
|
const clientLocale = useClientLocale(locales);
|
|
|
|
return useViewerI18n(clientLocale);
|
|
|
|
}
|
|
|
|
|
2021-10-14 10:57:49 +00:00
|
|
|
/**
|
|
|
|
* Auto-switches locale client-side to the logged in user's preference
|
|
|
|
*/
|
2023-08-22 12:34:55 +00:00
|
|
|
const I18nLanguageHandler = (props: { locales: string[] }) => {
|
|
|
|
const { locales } = props;
|
2021-10-12 13:11:33 +00:00
|
|
|
const { i18n } = useTranslation("common");
|
2023-08-22 12:34:55 +00:00
|
|
|
const locale = useClientViewerI18n(locales).data?.locale || i18n.language;
|
2021-10-14 10:57:49 +00:00
|
|
|
|
2021-10-14 19:10:44 +00:00
|
|
|
useEffect(() => {
|
2023-04-21 00:45:22 +00:00
|
|
|
// bail early when i18n = {}
|
2023-07-19 09:19:53 +00:00
|
|
|
if (Object.keys(i18n).length === 0) return;
|
2023-04-21 00:45:22 +00:00
|
|
|
// if locale is ready and the i18n.language does != locale - changeLanguage
|
|
|
|
if (locale && i18n.language !== locale) {
|
|
|
|
i18n.changeLanguage(locale);
|
2021-10-14 19:10:44 +00:00
|
|
|
}
|
2023-04-21 00:45:22 +00:00
|
|
|
// set dir="rtl|ltr"
|
|
|
|
document.dir = i18n.dir();
|
2023-01-03 10:09:05 +00:00
|
|
|
document.documentElement.setAttribute("lang", locale);
|
2021-10-14 19:10:44 +00:00
|
|
|
}, [locale, i18n]);
|
2023-07-19 12:30:25 +00:00
|
|
|
return null;
|
2021-10-12 13:11:33 +00:00
|
|
|
};
|
|
|
|
|
2023-07-19 12:30:25 +00:00
|
|
|
export default I18nLanguageHandler;
|