Better i18n API
This commit is contained in:
@ -69,115 +69,118 @@ export type GenericI18n<MessageKey extends string> = {
|
|||||||
|
|
||||||
export type I18n = GenericI18n<MessageKeyBase>;
|
export type I18n = GenericI18n<MessageKeyBase>;
|
||||||
|
|
||||||
export function useGenericI18n<ExtraMessageKey extends string = never>(params: {
|
export function createUseI18n<ExtraMessageKey extends string = never>(extraMessages: {
|
||||||
kcContext: KcContextLike;
|
[languageTag: string]: { [key in ExtraMessageKey]: string };
|
||||||
extraMessages: { [languageTag: string]: { [key in ExtraMessageKey]: string } };
|
}) {
|
||||||
}): GenericI18n<MessageKeyBase | ExtraMessageKey> | null {
|
function useI18n(params: { kcContext: KcContextLike }): GenericI18n<MessageKeyBase | ExtraMessageKey> | null {
|
||||||
const { kcContext, extraMessages } = params;
|
const { kcContext } = params;
|
||||||
|
|
||||||
const [i18n, setI18n] = useState<GenericI18n<ExtraMessageKey | MessageKeyBase> | undefined>(undefined);
|
const [i18n, setI18n] = useState<GenericI18n<ExtraMessageKey | MessageKeyBase> | undefined>(undefined);
|
||||||
|
|
||||||
const refHasStartedFetching = useRef(false);
|
const refHasStartedFetching = useRef(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (refHasStartedFetching.current) {
|
if (refHasStartedFetching.current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
refHasStartedFetching.current = true;
|
refHasStartedFetching.current = true;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const { currentLanguageTag = fallbackLanguageTag } = kcContext.locale ?? {};
|
const { currentLanguageTag = fallbackLanguageTag } = kcContext.locale ?? {};
|
||||||
|
|
||||||
const [fallbackMessages, messages] = await Promise.all([
|
const [fallbackMessages, messages] = await Promise.all([
|
||||||
import("./generated_messages/18.0.1/login/en"),
|
import("./generated_messages/18.0.1/login/en"),
|
||||||
(() => {
|
(() => {
|
||||||
switch (currentLanguageTag) {
|
switch (currentLanguageTag) {
|
||||||
case "ca":
|
case "ca":
|
||||||
return import("./generated_messages/18.0.1/login/ca");
|
return import("./generated_messages/18.0.1/login/ca");
|
||||||
case "cs":
|
case "cs":
|
||||||
return import("./generated_messages/18.0.1/login/cs");
|
return import("./generated_messages/18.0.1/login/cs");
|
||||||
case "da":
|
case "da":
|
||||||
return import("./generated_messages/18.0.1/login/da");
|
return import("./generated_messages/18.0.1/login/da");
|
||||||
case "de":
|
case "de":
|
||||||
return import("./generated_messages/18.0.1/login/de");
|
return import("./generated_messages/18.0.1/login/de");
|
||||||
case "en":
|
case "en":
|
||||||
return import("./generated_messages/18.0.1/login/en");
|
return import("./generated_messages/18.0.1/login/en");
|
||||||
case "es":
|
case "es":
|
||||||
return import("./generated_messages/18.0.1/login/es");
|
return import("./generated_messages/18.0.1/login/es");
|
||||||
case "fi":
|
case "fi":
|
||||||
return import("./generated_messages/18.0.1/login/fi");
|
return import("./generated_messages/18.0.1/login/fi");
|
||||||
case "fr":
|
case "fr":
|
||||||
return import("./generated_messages/18.0.1/login/fr");
|
return import("./generated_messages/18.0.1/login/fr");
|
||||||
case "hu":
|
case "hu":
|
||||||
return import("./generated_messages/18.0.1/login/hu");
|
return import("./generated_messages/18.0.1/login/hu");
|
||||||
case "it":
|
case "it":
|
||||||
return import("./generated_messages/18.0.1/login/it");
|
return import("./generated_messages/18.0.1/login/it");
|
||||||
case "ja":
|
case "ja":
|
||||||
return import("./generated_messages/18.0.1/login/ja");
|
return import("./generated_messages/18.0.1/login/ja");
|
||||||
case "lt":
|
case "lt":
|
||||||
return import("./generated_messages/18.0.1/login/lt");
|
return import("./generated_messages/18.0.1/login/lt");
|
||||||
case "lv":
|
case "lv":
|
||||||
return import("./generated_messages/18.0.1/login/lv");
|
return import("./generated_messages/18.0.1/login/lv");
|
||||||
case "nl":
|
case "nl":
|
||||||
return import("./generated_messages/18.0.1/login/nl");
|
return import("./generated_messages/18.0.1/login/nl");
|
||||||
case "no":
|
case "no":
|
||||||
return import("./generated_messages/18.0.1/login/no");
|
return import("./generated_messages/18.0.1/login/no");
|
||||||
case "pl":
|
case "pl":
|
||||||
return import("./generated_messages/18.0.1/login/pl");
|
return import("./generated_messages/18.0.1/login/pl");
|
||||||
case "pt-BR":
|
case "pt-BR":
|
||||||
return import("./generated_messages/18.0.1/login/pt-BR");
|
return import("./generated_messages/18.0.1/login/pt-BR");
|
||||||
case "ru":
|
case "ru":
|
||||||
return import("./generated_messages/18.0.1/login/ru");
|
return import("./generated_messages/18.0.1/login/ru");
|
||||||
case "sk":
|
case "sk":
|
||||||
return import("./generated_messages/18.0.1/login/sk");
|
return import("./generated_messages/18.0.1/login/sk");
|
||||||
case "sv":
|
case "sv":
|
||||||
return import("./generated_messages/18.0.1/login/sv");
|
return import("./generated_messages/18.0.1/login/sv");
|
||||||
case "tr":
|
case "tr":
|
||||||
return import("./generated_messages/18.0.1/login/tr");
|
return import("./generated_messages/18.0.1/login/tr");
|
||||||
case "zh-CN":
|
case "zh-CN":
|
||||||
return import("./generated_messages/18.0.1/login/zh-CN");
|
return import("./generated_messages/18.0.1/login/zh-CN");
|
||||||
default:
|
default:
|
||||||
return { "default": {} };
|
return { "default": {} };
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
]).then(modules => modules.map(module => module.default));
|
]).then(modules => modules.map(module => module.default));
|
||||||
|
|
||||||
setI18n({
|
setI18n({
|
||||||
...createI18nTranslationFunctions({
|
...createI18nTranslationFunctions({
|
||||||
"fallbackMessages": {
|
"fallbackMessages": {
|
||||||
...fallbackMessages,
|
...fallbackMessages,
|
||||||
...(keycloakifyExtraMessages[fallbackLanguageTag] ?? {}),
|
...(keycloakifyExtraMessages[fallbackLanguageTag] ?? {}),
|
||||||
...(extraMessages[fallbackLanguageTag] ?? {})
|
...(extraMessages[fallbackLanguageTag] ?? {})
|
||||||
} as any,
|
} as any,
|
||||||
"messages": {
|
"messages": {
|
||||||
...messages,
|
...messages,
|
||||||
...((keycloakifyExtraMessages as any)[currentLanguageTag] ?? {}),
|
...((keycloakifyExtraMessages as any)[currentLanguageTag] ?? {}),
|
||||||
...(extraMessages[currentLanguageTag] ?? {})
|
...(extraMessages[currentLanguageTag] ?? {})
|
||||||
} as any
|
} as any
|
||||||
}),
|
}),
|
||||||
currentLanguageTag,
|
currentLanguageTag,
|
||||||
"changeLocale": newLanguageTag => {
|
"changeLocale": newLanguageTag => {
|
||||||
const { locale } = kcContext;
|
const { locale } = kcContext;
|
||||||
|
|
||||||
assert(locale !== undefined, "Internationalization not enabled");
|
assert(locale !== undefined, "Internationalization not enabled");
|
||||||
|
|
||||||
const targetSupportedLocale = locale.supported.find(({ languageTag }) => languageTag === newLanguageTag);
|
const targetSupportedLocale = locale.supported.find(({ languageTag }) => languageTag === newLanguageTag);
|
||||||
|
|
||||||
assert(targetSupportedLocale !== undefined, `${newLanguageTag} need to be enabled in Keycloak admin`);
|
assert(targetSupportedLocale !== undefined, `${newLanguageTag} need to be enabled in Keycloak admin`);
|
||||||
|
|
||||||
window.location.href = targetSupportedLocale.url;
|
window.location.href = targetSupportedLocale.url;
|
||||||
|
|
||||||
assert(false, "never");
|
assert(false, "never");
|
||||||
},
|
},
|
||||||
"labelBySupportedLanguageTag": Object.fromEntries(
|
"labelBySupportedLanguageTag": Object.fromEntries(
|
||||||
(kcContext.locale?.supported ?? []).map(({ languageTag, label }) => [languageTag, label])
|
(kcContext.locale?.supported ?? []).map(({ languageTag, label }) => [languageTag, label])
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return i18n ?? null;
|
return i18n ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { useI18n };
|
||||||
}
|
}
|
||||||
|
|
||||||
function createI18nTranslationFunctions<MessageKey extends string>(params: {
|
function createI18nTranslationFunctions<MessageKey extends string>(params: {
|
||||||
|
@ -5,6 +5,6 @@ export default Fallback;
|
|||||||
export { createKeycloakAdapter } from "keycloakify/lib/keycloakJsAdapter";
|
export { createKeycloakAdapter } from "keycloakify/lib/keycloakJsAdapter";
|
||||||
export { useDownloadTerms } from "keycloakify/lib/useDownloadTerms";
|
export { useDownloadTerms } from "keycloakify/lib/useDownloadTerms";
|
||||||
export { getKcContext } from "keycloakify/kcContext/getKcContext";
|
export { getKcContext } from "keycloakify/kcContext/getKcContext";
|
||||||
export { useGenericI18n } from "keycloakify/i18n";
|
export { createUseI18n } from "keycloakify/i18n";
|
||||||
|
|
||||||
export type { PageProps } from "keycloakify/pages/PageProps";
|
export type { PageProps } from "keycloakify/pages/PageProps";
|
||||||
|
Reference in New Issue
Block a user