i18n: optimize performance
* createCurrentLanguage: caching result with memo * createStringResource: use useAppLocale
This commit is contained in:
parent
6df5c2e216
commit
b1812392cb
1 changed files with 44 additions and 2 deletions
|
@ -25,12 +25,22 @@ const DEFAULT_LANG = "en";
|
|||
|
||||
/**
|
||||
* Decide the using language for the user.
|
||||
*
|
||||
* **Performance**: This function is costy, make sure you cache the result.
|
||||
* In the app, you should use {@link useAppLocale} instead.
|
||||
*
|
||||
* @returns the selected language tag
|
||||
*/
|
||||
export function autoMatchLangTag() {
|
||||
return match(Array.from(navigator.languages), SUPPORTED_LANGS, DEFAULT_LANG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide the using region for the user.
|
||||
*
|
||||
* **Performance**: This function is costy, make sure you cache the result.
|
||||
* In the app, you should use {@link useAppLocale} instead.
|
||||
*/
|
||||
export function autoMatchRegion() {
|
||||
const specifiers = navigator.languages.map((x) => x.split("-"));
|
||||
|
||||
|
@ -99,7 +109,7 @@ export function useDateFnLocale(): Accessor<Locale> {
|
|||
|
||||
export function createCurrentLanguage() {
|
||||
const settings = useStore($settings);
|
||||
return () => settings().language || autoMatchLangTag();
|
||||
return createMemo(() => settings().language || autoMatchLangTag());
|
||||
}
|
||||
|
||||
type ImportFn<T> = (name: string) => Promise<{ default: T }>;
|
||||
|
@ -114,10 +124,30 @@ type MergedImportedModule<T> = T extends []
|
|||
? ImportedModule<I> & MergedImportedModule<J>
|
||||
: never;
|
||||
|
||||
/**
|
||||
* Create a resource that combines all I18N strings into one object.
|
||||
*
|
||||
* The result is combined in the order of the argument functions.
|
||||
* The formers will be overrided by the latter.
|
||||
*
|
||||
* @param importFns a series of functions imports the string modules
|
||||
* based on the specified language code.
|
||||
*
|
||||
* **Context**: This function must be used under {@link AppLocaleProvider}.
|
||||
*
|
||||
* @example ````ts
|
||||
* const [strings] = createStringResource(
|
||||
* async (code) => await import(`./i18n/${code}.json`), // Vite can handle the bundling
|
||||
* async () => import("./i18n/generic.json"), // You can also ignore the code.
|
||||
* );
|
||||
* ````
|
||||
*
|
||||
* @see {@link createTranslator} if you need a Translator from "@solid-primitives/i18n"
|
||||
*/
|
||||
export function createStringResource<
|
||||
T extends ImportFn<Record<string, string | Template<any> | undefined>>[],
|
||||
>(...importFns: T) {
|
||||
const language = createCurrentLanguage();
|
||||
const { language } = useAppLocale();
|
||||
const cache: Record<string, MergedImportedModule<T>> = {};
|
||||
|
||||
return createResource(
|
||||
|
@ -140,6 +170,18 @@ export function createStringResource<
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Translator from "@solid-primitives/i18n" based on
|
||||
* the {@link createStringResource}.
|
||||
*
|
||||
* @param importFns same to {@link createStringResource}
|
||||
*
|
||||
* @returns the first element is the translator, the second is the result from
|
||||
* {@link createStringResource}.
|
||||
*
|
||||
* @see {@link translator} for the translator usage
|
||||
* @see {@link createStringResource} for the raw strings
|
||||
*/
|
||||
export function createTranslator<
|
||||
T extends ImportFn<Record<string, string | Template<any> | undefined>>[],
|
||||
>(...importFns: T) {
|
||||
|
|
Loading…
Add table
Reference in a new issue