* Add Polish (pl) localization * translations * fix: add missing Polish translations * copy en keys to pl * fix: complete Polish settings translations * fix: localize PWA install prompt * fix pwa install prompt lifecycle and complete Polish locale keys * polish polish locale wording for natural phrasing --------- Co-authored-by: levy52 <levy52@vp.pl> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
export type Locale = 'en' | 'zh-CN' | 'uk' | 'es' | 'pt-BR' | 'ko' | 'pl';
|
|
|
|
export const LOCALES = ['en', 'zh-CN', 'uk', 'es', 'pt-BR', 'ko', 'pl'] as const satisfies readonly Locale[];
|
|
|
|
export const DEFAULT_LOCALE: Locale = 'en';
|
|
|
|
export const LOCALE_LABEL_KEYS: Record<Locale, 'common.language.english' | 'common.language.simplifiedChinese' | 'common.language.ukrainian' | 'common.language.spanish' | 'common.language.brazilianPortuguese' | 'common.language.korean' | 'common.language.polish'> = {
|
|
en: 'common.language.english',
|
|
'zh-CN': 'common.language.simplifiedChinese',
|
|
uk: 'common.language.ukrainian',
|
|
es: 'common.language.spanish',
|
|
'pt-BR': 'common.language.brazilianPortuguese',
|
|
ko: 'common.language.korean',
|
|
pl: 'common.language.polish',
|
|
};
|
|
|
|
export const LOCALE_STORAGE_KEY = 'openchamber.i18n.v1';
|
|
|
|
type StoredLocale = {
|
|
locale?: unknown;
|
|
};
|
|
|
|
export function normalizeLocale(value: string | undefined | null): Locale {
|
|
if (!value) {
|
|
return DEFAULT_LOCALE;
|
|
}
|
|
|
|
const normalized = value.toLowerCase().replace(/_/g, '-');
|
|
if (normalized === 'zh-cn' || normalized === 'zh-hans' || normalized.startsWith('zh-hans-')) {
|
|
return 'zh-CN';
|
|
}
|
|
if (normalized.startsWith('zh')) {
|
|
return 'zh-CN';
|
|
}
|
|
if (normalized.startsWith('en')) {
|
|
return 'en';
|
|
}
|
|
if (normalized === 'uk' || normalized.startsWith('uk-') || normalized === 'ua' || normalized.startsWith('ua-')) {
|
|
return 'uk';
|
|
}
|
|
if (normalized === 'es' || normalized.startsWith('es-')) {
|
|
return 'es';
|
|
}
|
|
if (normalized === 'pt' || normalized === 'pt-br' || normalized.startsWith('pt-br-')) {
|
|
return 'pt-BR';
|
|
}
|
|
if (normalized === 'ko' || normalized.startsWith('ko-')) {
|
|
return 'ko';
|
|
}
|
|
if (normalized === 'pl' || normalized.startsWith('pl-')) {
|
|
return 'pl';
|
|
}
|
|
return DEFAULT_LOCALE;
|
|
}
|
|
|
|
export function readStoredLocale(): Locale | undefined {
|
|
if (typeof window === 'undefined') {
|
|
return undefined;
|
|
}
|
|
|
|
try {
|
|
const raw = window.localStorage.getItem(LOCALE_STORAGE_KEY);
|
|
if (!raw) {
|
|
return undefined;
|
|
}
|
|
const parsed = JSON.parse(raw) as StoredLocale;
|
|
return typeof parsed.locale === 'string' ? normalizeLocale(parsed.locale) : undefined;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
export function writeStoredLocale(locale: Locale): void {
|
|
if (typeof window === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
window.localStorage.setItem(LOCALE_STORAGE_KEY, JSON.stringify({ locale }));
|
|
} catch {
|
|
return;
|
|
}
|
|
}
|
|
|
|
export function detectInitialLocale(): Locale {
|
|
const stored = readStoredLocale();
|
|
if (stored) {
|
|
return stored;
|
|
}
|
|
|
|
return DEFAULT_LOCALE;
|
|
}
|