vojo/apps/widget-discord/src/i18n/index.ts

34 lines
1.2 KiB
TypeScript

// Tiny i18n harness — Russian primary, English fallback (BCP-47 prefix
// match — any `en` variant). Bootstrap forwards `clientLanguage` from the
// host; main.tsx can also call `createT()` without args before bootstrap
// completes (falls back to navigator.language, then RU).
//
// Identical mechanics to apps/widget-telegram/src/i18n/index.ts; the
// Discord widget keeps its own dictionary file because the copy differs —
// QR-only flow, no SMS, no 2FA password form.
import { RU, type StringKey } from './ru';
import { EN } from './en';
const interpolate = (s: string, vars?: Record<string, string>): string => {
if (!vars) return s;
return s.replace(/\{(\w+)\}/g, (_, k) => vars[k] ?? `{${k}}`);
};
const pickDict = (clientLanguage: string | undefined): Record<StringKey, string> => {
const lang = (
clientLanguage ||
(typeof navigator !== 'undefined' ? navigator.language : '') ||
'ru'
).toLowerCase();
return lang.startsWith('en') ? EN : RU;
};
export type T = (key: StringKey, vars?: Record<string, string>) => string;
export const createT = (clientLanguage?: string): T => {
const dict = pickDict(clientLanguage);
return (key, vars) => interpolate(dict[key], vars);
};
export type { StringKey };