about summary refs log tree commit diff
path: root/src/locale/helpers.ts
diff options
context:
space:
mode:
authorStanislas Signoud <signez@stanisoft.net>2024-12-31 22:27:14 +0100
committerGitHub <noreply@github.com>2024-12-31 13:27:14 -0800
commit9f075b13405c7711edbd9309ab521738b74a50c5 (patch)
tree33acdca882ef027bc670bb38de3a9d054f6ce721 /src/locale/helpers.ts
parent09297d92cb73fcf3b7eda7d683543661d3f30501 (diff)
downloadvoidsky-9f075b13405c7711edbd9309ab521738b74a50c5.tar.zst
Localize lang selectors according to the app language (#6207)
* Localize lang selectors according to the app language

* Explicitly ignore RangeError when translating locale names
Diffstat (limited to 'src/locale/helpers.ts')
-rw-r--r--src/locale/helpers.ts42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/locale/helpers.ts b/src/locale/helpers.ts
index c469b3c58..94e9d4327 100644
--- a/src/locale/helpers.ts
+++ b/src/locale/helpers.ts
@@ -5,6 +5,7 @@ import lande from 'lande'
 import {hasProp} from '#/lib/type-guards'
 import {
   AppLanguage,
+  type Language,
   LANGUAGES_MAP_CODE2,
   LANGUAGES_MAP_CODE3,
 } from './languages'
@@ -31,9 +32,44 @@ export function code3ToCode2Strict(lang: string): string | undefined {
   return undefined
 }
 
-export function codeToLanguageName(lang: string): string {
-  const lang2 = code3ToCode2(lang)
-  return LANGUAGES_MAP_CODE2[lang2]?.name || lang
+function getLocalizedLanguage(
+  langCode: string,
+  appLang: string,
+): string | undefined {
+  try {
+    const allNames = new Intl.DisplayNames([appLang], {
+      type: 'language',
+      fallback: 'none',
+      languageDisplay: 'standard',
+    })
+    const translatedName = allNames.of(langCode)
+
+    if (translatedName) {
+      // force simple title case (as languages do not always start with an uppercase in Unicode data)
+      return translatedName[0].toLocaleUpperCase() + translatedName.slice(1)
+    }
+  } catch (e) {
+    // ignore RangeError from Intl.DisplayNames APIs
+    if (!(e instanceof RangeError)) {
+      throw e
+    }
+  }
+}
+
+export function languageName(language: Language, appLang: string): string {
+  // if Intl.DisplayNames is unavailable on the target, display the English name
+  if (!(Intl as any).DisplayNames) {
+    return language.name
+  }
+
+  return getLocalizedLanguage(language.code2, appLang) || language.name
+}
+
+export function codeToLanguageName(lang2or3: string, appLang: string): string {
+  const code2 = code3ToCode2(lang2or3)
+  const knownLanguage = LANGUAGES_MAP_CODE2[code2]
+
+  return knownLanguage ? languageName(knownLanguage, appLang) : code2
 }
 
 export function getPostLanguage(