Files
inbuxa-webmail/web/src/lib/languages.ts
T
jcoffey-dev ab759143ab Take Dutch out of Beta with the native speaker's final review
Michael (mbjboon-netizen) sent the final corrections for nl.ts and the Dutch
permission labels and signed the language off, so Nederlands no longer
carries the Beta flag in the picker.

The main catalog changes 52 values, mostly "regels" -> "filterregels" and
"post" -> "e-mail(s)". The permission headings move from compound nouns
("Accountbeheer") to verb phrases ("Accounts beheren"), and the reviewer's
note on that is kept in the file. No keys were added or removed, and every
placeholder is intact.

One entry is kept as it was: "It {damage}, ..." stays "Het {damage}, ...".
{damage} is filled with a verb phrase ("stops in the middle of a line"), so
the added "is" would have doubled the verb.

README, FEATURES, ROADMAP and KNOWN-ISSUES now say Dutch has been reviewed
and the other eight have not.

(cherry picked from commit e30fd73d7dbb1463859efbc4048f680d21d64c56)
2026-09-27 15:57:23 -07:00

67 lines
2.9 KiB
TypeScript

/**
* The interface languages that actually have strings shipped.
*
* Deliberately not `lib/locales.ts`. That list is every tag CLDR can format a
* date in — about 620 of them — and it answers a different question: what
* calendar, clock and numerals to use. This one answers "what language is the
* app written in", and the only honest entries are the ones somebody has
* translated. Offering a language with no strings behind it would set
* `<html lang>` to a language the page is not in, which is worse than not
* offering it: it stops Chrome offering to translate a page the reader cannot
* read.
*
* Wanting German dates with an English interface is a real preference, and so
* is the reverse, which is why `uiLanguage` and `locale` are separate settings
* rather than one.
*
* Adding a language means adding its catalog and then adding it here, in
* that order. RTL languages — Arabic, Hebrew, Persian — need bidi and layout
* work well beyond strings, so they are not simply a matter of another entry.
*/
export interface UiLanguage {
/** BCP 47, and what `<html lang>` is set to. */
tag: string;
/** The language's name in that language, which is how a picker should read. */
name: string;
/**
* Machine-translated and not yet checked by somebody who speaks it.
*
* Stays true until a native speaker has actually read the catalog and said
* so. It is not a measure of how complete the file is -- a catalog can be
* word-for-word finished and still read like a machine wrote it, which is
* the thing this flag is about. Removing it is a deliberate act by a person,
* not something a coverage number earns.
*/
beta?: boolean;
}
export const UI_LANGUAGES: readonly UiLanguage[] = [
{ tag: "en", name: "English" },
{ tag: "de", name: "Deutsch", beta: true },
{ tag: "es", name: "Español", beta: true },
{ tag: "fr", name: "Français", beta: true },
{ tag: "nl", name: "Nederlands" },
{ tag: "pt-BR", name: "Português (Brasil)", beta: true },
{ tag: "ja", name: "日本語", beta: true },
{ tag: "ru", name: "Русский", beta: true },
{ tag: "uk", name: "Українська", beta: true },
{ tag: "zh-Hans", name: "简体中文", beta: true },
];
/** Where to report a bad translation. Beta languages depend on it. */
export const TRANSLATION_ISSUE_URL = "https://git.coffeylabs.org/coffey-labs/ihasmail/issues/new?title=Translation%3A%20";
export const DEFAULT_UI_LANGUAGE = "en";
/**
* The language to actually render in.
*
* A stored preference is only honored if its strings are still shipped: a
* catalog can be withdrawn, and an account carrying `de` from another
* machine must not leave this one claiming to be German while showing English.
*/
export function resolveUiLanguage(stored: string | undefined | null): string {
if (!stored) return DEFAULT_UI_LANGUAGE;
return UI_LANGUAGES.some((l) => l.tag === stored) ? stored : DEFAULT_UI_LANGUAGE;
}