mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-02 08:07:11 +00:00
feat: add thai and estonian
This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"calendar": {
|
||||||
|
"detail": {
|
||||||
|
"delete_confirm": "Kustutada see sündmus?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contacts": {
|
||||||
|
"bulk": {
|
||||||
|
"delete_confirm_title": "Kustuta kontaktid"
|
||||||
|
},
|
||||||
|
"delete_confirm_title": "Kustuta kontakt"
|
||||||
|
},
|
||||||
|
"email_viewer": {
|
||||||
|
"not_spam_short": "Pole rämpspost",
|
||||||
|
"spam_short": "Rämpspost"
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"batch_delete_confirm_message": "Kas oled kindel, et soovid kustutada {count, plural, one {1 üksuse} other {# üksust}}? Seda ei saa tagasi võtta.",
|
||||||
|
"batch_delete_success": "{count, plural, one {1 üksus kustutatud} other {# üksust kustutatud}}",
|
||||||
|
"delete_confirm_message": "Kas oled kindel, et soovid kustutada \"{name}\"? Seda ei saa tagasi võtta.",
|
||||||
|
"delete_confirm_title": "Kustuta ressurss",
|
||||||
|
"delete_success": "Edukalt kustutatud"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"composer": {
|
||||||
|
"autosave": {
|
||||||
|
"1m": "Iga minuti järel",
|
||||||
|
"2m": "Iga 2 minuti järel",
|
||||||
|
"30s": "Iga 30 sekundi järel",
|
||||||
|
"5m": "Iga 5 minuti järel",
|
||||||
|
"description": "Kui sageli mustandeid automaatselt salvestatakse",
|
||||||
|
"label": "Automaatsalvestuse intervall"
|
||||||
|
},
|
||||||
|
"description": "Seadista kirja koostamise sätteid",
|
||||||
|
"title": "Koostamine"
|
||||||
|
},
|
||||||
|
"email_behavior": {
|
||||||
|
"disable_threading": {
|
||||||
|
"description": "Kuva e-kirjad üksikute kirjadena vestluste kaupa rühmitamise asemel",
|
||||||
|
"label": "Keela vestluste rühmitamine"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filters": {
|
||||||
|
"sieve_editor": {
|
||||||
|
"confirm_save": "Kinnita salvestamine",
|
||||||
|
"save_warning": "Salvestamine kirjutab kõik visuaalsed reeglid üle. Seda ei saa tagasi võtta. Kinnitamiseks klõpsa uuesti nuppu Salvesta."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"identities": {
|
||||||
|
"title": "Saatja identiteedid"
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"calendar": {
|
||||||
|
"invitation_parsing": "Tuvasta e-kirjade kutsed",
|
||||||
|
"invitation_parsing_desc": "Tuvasta kalendrikutsed e-kirjade manustest ja kuva kalenditoimingud"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tab_groups": {
|
||||||
|
"advanced": "Täpsemalt",
|
||||||
|
"appearance": "Välimus",
|
||||||
|
"general": "Üldine",
|
||||||
|
"privacy": "Privaatsus ja turvalisus"
|
||||||
|
},
|
||||||
|
"tabs": {
|
||||||
|
"content_senders": "Sisu ja saatjad",
|
||||||
|
"downloads": "Allalaadimised",
|
||||||
|
"identities": "Identiteedid",
|
||||||
|
"keywords": "Sildid",
|
||||||
|
"language": "Keel, piirkond ja kellaaeg",
|
||||||
|
"layout": "Paigutus",
|
||||||
|
"sidebar_apps": "Külgriba rakendused",
|
||||||
|
"templates": "Mallid",
|
||||||
|
"themes": "Teemad"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -23,6 +23,11 @@ describe('resolveLocaleTag', () => {
|
|||||||
expect(resolveLocaleTag({ languageCode: 'nb', languageTag: 'nb-NO' })).toBe('nb');
|
expect(resolveLocaleTag({ languageCode: 'nb', languageTag: 'nb-NO' })).toBe('nb');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('takes Thai and Estonian, which the webmail has too', () => {
|
||||||
|
expect(resolveLocaleTag({ languageCode: 'th', languageTag: 'th-TH' })).toBe('th');
|
||||||
|
expect(resolveLocaleTag({ languageCode: 'et', languageTag: 'et-EE' })).toBe('et');
|
||||||
|
});
|
||||||
|
|
||||||
it('returns null for unsupported languages', () => {
|
it('returns null for unsupported languages', () => {
|
||||||
expect(resolveLocaleTag({ languageCode: 'xx', languageTag: 'xx-XX' })).toBeNull();
|
expect(resolveLocaleTag({ languageCode: 'xx', languageTag: 'xx-XX' })).toBeNull();
|
||||||
expect(resolveLocaleTag({})).toBeNull();
|
expect(resolveLocaleTag({})).toBeNull();
|
||||||
@@ -40,6 +45,11 @@ describe('getLocaleDirection', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('translate', () => {
|
describe('translate', () => {
|
||||||
|
it('reads Thai and Estonian from their own catalogs', () => {
|
||||||
|
expect(translate('th', 'settings.title')).not.toBe(translate('en', 'settings.title'));
|
||||||
|
expect(translate('et', 'settings.title')).not.toBe(translate('en', 'settings.title'));
|
||||||
|
});
|
||||||
|
|
||||||
it('falls back locale → en → fallback → key', () => {
|
it('falls back locale → en → fallback → key', () => {
|
||||||
expect(translate('de', 'settings.title')).not.toBe('settings.title');
|
expect(translate('de', 'settings.title')).not.toBe('settings.title');
|
||||||
expect(translate('de', 'nope.missing', 'Fallback')).toBe('Fallback');
|
expect(translate('de', 'nope.missing', 'Fallback')).toBe('Fallback');
|
||||||
|
|||||||
+7
-1
@@ -30,6 +30,7 @@ export const SUPPORTED_LOCALES = [
|
|||||||
{ code: 'da', label: 'Dansk' },
|
{ code: 'da', label: 'Dansk' },
|
||||||
{ code: 'de', label: 'Deutsch' },
|
{ code: 'de', label: 'Deutsch' },
|
||||||
{ code: 'en', label: 'English' },
|
{ code: 'en', label: 'English' },
|
||||||
|
{ code: 'et', label: 'Eesti' },
|
||||||
{ code: 'fa', label: 'فارسی' },
|
{ code: 'fa', label: 'فارسی' },
|
||||||
{ code: 'es', label: 'Español' },
|
{ code: 'es', label: 'Español' },
|
||||||
{ code: 'fr', label: 'Français' },
|
{ code: 'fr', label: 'Français' },
|
||||||
@@ -42,6 +43,7 @@ export const SUPPORTED_LOCALES = [
|
|||||||
{ code: 'pl', label: 'Polski' },
|
{ code: 'pl', label: 'Polski' },
|
||||||
{ code: 'pt', label: 'Português' },
|
{ code: 'pt', label: 'Português' },
|
||||||
{ code: 'ro', label: 'Română' },
|
{ code: 'ro', label: 'Română' },
|
||||||
|
{ code: 'th', label: 'ไทย' },
|
||||||
{ code: 'tr', label: 'Türkçe' },
|
{ code: 'tr', label: 'Türkçe' },
|
||||||
{ code: 'ru', label: 'Русский' },
|
{ code: 'ru', label: 'Русский' },
|
||||||
{ code: 'uk', label: 'Українська' },
|
{ code: 'uk', label: 'Українська' },
|
||||||
@@ -74,7 +76,7 @@ function deepMerge(base: Dictionary, overlay: Dictionary): Dictionary {
|
|||||||
|
|
||||||
// A catalog is a few hundred KB of JSON. Metro only evaluates a module when it
|
// A catalog is a few hundred KB of JSON. Metro only evaluates a module when it
|
||||||
// is first required, so keeping each require inside its loader means startup
|
// is first required, so keeping each require inside its loader means startup
|
||||||
// builds English plus the active language instead of all 27, and switching
|
// builds English plus the active language instead of all 29, and switching
|
||||||
// language loads the new catalog synchronously on the next t() call. The
|
// language loads the new catalog synchronously on the next t() call. The
|
||||||
// require paths must stay string literals for Metro to bundle them.
|
// require paths must stay string literals for Metro to bundle them.
|
||||||
const CATALOG_LOADERS: Record<LocaleCode, () => Dictionary> = {
|
const CATALOG_LOADERS: Record<LocaleCode, () => Dictionary> = {
|
||||||
@@ -84,6 +86,7 @@ const CATALOG_LOADERS: Record<LocaleCode, () => Dictionary> = {
|
|||||||
da: () => require('../../locales/da/common.json'),
|
da: () => require('../../locales/da/common.json'),
|
||||||
de: () => require('../../locales/de/common.json'),
|
de: () => require('../../locales/de/common.json'),
|
||||||
en: () => en as Dictionary,
|
en: () => en as Dictionary,
|
||||||
|
et: () => require('../../locales/et/common.json'),
|
||||||
es: () => require('../../locales/es/common.json'),
|
es: () => require('../../locales/es/common.json'),
|
||||||
fa: () => require('../../locales/fa/common.json'),
|
fa: () => require('../../locales/fa/common.json'),
|
||||||
fr: () => require('../../locales/fr/common.json'),
|
fr: () => require('../../locales/fr/common.json'),
|
||||||
@@ -100,6 +103,7 @@ const CATALOG_LOADERS: Record<LocaleCode, () => Dictionary> = {
|
|||||||
pt: () => require('../../locales/pt/common.json'),
|
pt: () => require('../../locales/pt/common.json'),
|
||||||
ro: () => require('../../locales/ro/common.json'),
|
ro: () => require('../../locales/ro/common.json'),
|
||||||
ru: () => require('../../locales/ru/common.json'),
|
ru: () => require('../../locales/ru/common.json'),
|
||||||
|
th: () => require('../../locales/th/common.json'),
|
||||||
sk: () => require('../../locales/sk/common.json'),
|
sk: () => require('../../locales/sk/common.json'),
|
||||||
tr: () => require('../../locales/tr/common.json'),
|
tr: () => require('../../locales/tr/common.json'),
|
||||||
uk: () => require('../../locales/uk/common.json'),
|
uk: () => require('../../locales/uk/common.json'),
|
||||||
@@ -115,6 +119,7 @@ const OVERLAY_LOADERS: Record<LocaleCode, () => Dictionary> = {
|
|||||||
da: () => require('../../locales/rn/da.json'),
|
da: () => require('../../locales/rn/da.json'),
|
||||||
de: () => require('../../locales/rn/de.json'),
|
de: () => require('../../locales/rn/de.json'),
|
||||||
en: () => rnEn as Dictionary,
|
en: () => rnEn as Dictionary,
|
||||||
|
et: () => require('../../locales/rn/et.json'),
|
||||||
es: () => require('../../locales/rn/es.json'),
|
es: () => require('../../locales/rn/es.json'),
|
||||||
fa: () => require('../../locales/rn/fa.json'),
|
fa: () => require('../../locales/rn/fa.json'),
|
||||||
fr: () => require('../../locales/rn/fr.json'),
|
fr: () => require('../../locales/rn/fr.json'),
|
||||||
@@ -131,6 +136,7 @@ const OVERLAY_LOADERS: Record<LocaleCode, () => Dictionary> = {
|
|||||||
pt: () => require('../../locales/rn/pt.json'),
|
pt: () => require('../../locales/rn/pt.json'),
|
||||||
ro: () => require('../../locales/rn/ro.json'),
|
ro: () => require('../../locales/rn/ro.json'),
|
||||||
ru: () => require('../../locales/rn/ru.json'),
|
ru: () => require('../../locales/rn/ru.json'),
|
||||||
|
th: () => require('../../locales/rn/th.json'),
|
||||||
sk: () => require('../../locales/rn/sk.json'),
|
sk: () => require('../../locales/rn/sk.json'),
|
||||||
tr: () => require('../../locales/rn/tr.json'),
|
tr: () => require('../../locales/rn/tr.json'),
|
||||||
uk: () => require('../../locales/rn/uk.json'),
|
uk: () => require('../../locales/rn/uk.json'),
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const DATE_FNS_LOCALE_LOADERS: Record<LocaleCode, () => Locale> = {
|
|||||||
da: () => require('date-fns/locale/da').da,
|
da: () => require('date-fns/locale/da').da,
|
||||||
de: () => require('date-fns/locale/de').de,
|
de: () => require('date-fns/locale/de').de,
|
||||||
es: () => require('date-fns/locale/es').es,
|
es: () => require('date-fns/locale/es').es,
|
||||||
|
et: () => require('date-fns/locale/et').et,
|
||||||
fa: () => require('date-fns/locale/fa-IR').faIR,
|
fa: () => require('date-fns/locale/fa-IR').faIR,
|
||||||
fr: () => require('date-fns/locale/fr').fr,
|
fr: () => require('date-fns/locale/fr').fr,
|
||||||
he: () => require('date-fns/locale/he').he,
|
he: () => require('date-fns/locale/he').he,
|
||||||
@@ -35,6 +36,7 @@ const DATE_FNS_LOCALE_LOADERS: Record<LocaleCode, () => Locale> = {
|
|||||||
ro: () => require('date-fns/locale/ro').ro,
|
ro: () => require('date-fns/locale/ro').ro,
|
||||||
ru: () => require('date-fns/locale/ru').ru,
|
ru: () => require('date-fns/locale/ru').ru,
|
||||||
sk: () => require('date-fns/locale/sk').sk,
|
sk: () => require('date-fns/locale/sk').sk,
|
||||||
|
th: () => require('date-fns/locale/th').th,
|
||||||
tr: () => require('date-fns/locale/tr').tr,
|
tr: () => require('date-fns/locale/tr').tr,
|
||||||
uk: () => require('date-fns/locale/uk').uk,
|
uk: () => require('date-fns/locale/uk').uk,
|
||||||
zh: () => require('date-fns/locale/zh-CN').zhCN,
|
zh: () => require('date-fns/locale/zh-CN').zhCN,
|
||||||
|
|||||||
Reference in New Issue
Block a user