diff options
| author | Fuwn <[email protected]> | 2024-01-25 03:30:53 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-01-25 03:30:53 -0800 |
| commit | 03345438ea0981882235a90bce97feda2e7df363 (patch) | |
| tree | 1ab66f90a8aaeb00cffa52e715a88bf38dffdc94 /src/stores | |
| parent | fix(wrapped): accidential user id overwrite (diff) | |
| download | due.moe-03345438ea0981882235a90bce97feda2e7df363.tar.xz due.moe-03345438ea0981882235a90bce97feda2e7df363.zip | |
feat(locale): localise profile page
Diffstat (limited to 'src/stores')
| -rw-r--r-- | src/stores/locale.ts | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/src/stores/locale.ts b/src/stores/locale.ts index ba657bf5..2105eb51 100644 --- a/src/stores/locale.ts +++ b/src/stores/locale.ts @@ -2,37 +2,71 @@ import { derived, type Readable } from 'svelte/store'; import { json } from 'svelte-i18n'; import type { Locale } from '$lib/Locale/layout'; -// type FormatXMLElementFn<T, R = string | T | (string | T)[]> = (parts: Array<string | T>) => R; - -// interface Options { -// id?: string; -// locale?: string; -// format?: string; -// default?: string; -// values?: -// | Record< -// string, -// string | number | boolean | Date | FormatXMLElementFn<unknown> | null | undefined -// > -// | undefined; -// } +type FormatXMLElementFn<T, R = string | T | (string | T)[]> = (parts: Array<string | T>) => R; + +type InterpolationValue = + | string + | number + | boolean + | Date + | FormatXMLElementFn<unknown> + | null + | undefined; + +type InterpolationValues = Record<string, InterpolationValue> | undefined; + +interface Options { + id?: string; + locale?: string; + format?: string; + default?: string; + values?: InterpolationValues; +} const createLocale = () => { return derived(json, ($json) => { - return (locale = undefined) => + return (options: Options = {}) => new Proxy( {}, { get(_target, key) { - const localisation = $json(key.toString(), locale); + const localisation = $json(key.toString(), options.locale); if (localisation === key.toString()) return undefined; + const replaceValues = ( + localisation: InterpolationValues, + values: InterpolationValues + ) => { + if (typeof localisation !== 'object' || localisation === null) return localisation; + + const updatedLocalisation: InterpolationValues = {}; + + for (const [key, value] of Object.entries(localisation)) { + if (typeof value === 'string') { + updatedLocalisation[key] = value.replace( + /\{(\w+)\}/g, + (match, name) => (values ? values[name] : match) as string + ); + } else { + updatedLocalisation[key] = replaceValues( + value as InterpolationValues, + values + ) as InterpolationValue; + } + } + + return updatedLocalisation; + }; + + if (options.values) + return replaceValues(localisation as unknown as InterpolationValues, options.values); + return localisation; } } ); - }) as Readable<(locale?: string) => Locale>; + }) as Readable<(options?: Options) => Locale>; }; const locale = createLocale(); |