use Intl.DisplayNames for language name localisation

This commit is contained in:
Samuel Newman
2026-03-02 13:54:30 +02:00
parent 9622d6b372
commit 80dc15e776
3 changed files with 97 additions and 604 deletions
@@ -5,6 +5,7 @@ import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro' import {Trans} from '@lingui/react/macro'
import {languageName} from '#/locale/helpers'
import {type Language, LANGUAGES, LANGUAGES_MAP_CODE2} from '#/locale/languages' import {type Language, LANGUAGES, LANGUAGES_MAP_CODE2} from '#/locale/languages'
import {useLanguagePrefs} from '#/state/preferences/languages' import {useLanguagePrefs} from '#/state/preferences/languages'
import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
@@ -139,8 +140,11 @@ export function DialogInner({
const recentLanguages = mapCode2List(recentLanguagesCode2) const recentLanguages = mapCode2List(recentLanguagesCode2)
// NOTE(@elijaharita): helper functions // NOTE(@elijaharita): helper functions
const searchLower = search.toLowerCase()
const matchesSearch = (lang: Language) => const matchesSearch = (lang: Language) =>
lang.name.toLowerCase().includes(search.toLowerCase()) languageName(lang, langPrefs.appLanguage)
.toLowerCase()
.includes(searchLower) || lang.name.toLowerCase().includes(searchLower)
const isChecked = (lang: Language) => const isChecked = (lang: Language) =>
checkedLanguagesCode2.includes(lang.code2) checkedLanguagesCode2.includes(lang.code2)
const isInRecents = (lang: Language) => const isInRecents = (lang: Language) =>
@@ -182,6 +186,7 @@ export function DialogInner({
search, search,
langPrefs.postLanguageHistory, langPrefs.postLanguageHistory,
checkedLanguagesCode2, checkedLanguagesCode2,
langPrefs.appLanguage,
]) ])
const listHeader = ( const listHeader = (
@@ -304,7 +309,7 @@ export function DialogInner({
<Toggle.Item <Toggle.Item
key={lang.code2} key={lang.code2}
name={lang.code2} name={lang.code2}
label={lang.name} label={languageName(lang, langPrefs.appLanguage)}
style={[ style={[
t.atoms.border_contrast_low, t.atoms.border_contrast_low,
!isLastItem && a.border_b, !isLastItem && a.border_b,
@@ -313,7 +318,7 @@ export function DialogInner({
a.py_md, a.py_md,
]}> ]}>
<Toggle.LabelText style={[a.flex_1]}> <Toggle.LabelText style={[a.flex_1]}>
{lang.name} {languageName(lang, langPrefs.appLanguage)}
</Toggle.LabelText> </Toggle.LabelText>
<Toggle.Checkbox /> <Toggle.Checkbox />
</Toggle.Item> </Toggle.Item>
+66 -572
View File
File diff suppressed because it is too large Load Diff
+23 -29
View File
@@ -8,7 +8,7 @@ import {
type CommonNavigatorParams, type CommonNavigatorParams,
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {sanitizeAppLanguageSetting} from '#/locale/helpers' import {languageName, sanitizeAppLanguageSetting} from '#/locale/helpers'
import {APP_LANGUAGES, LANGUAGES} from '#/locale/languages' import {APP_LANGUAGES, LANGUAGES} from '#/locale/languages'
import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences' import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences'
import {atoms as a, web} from '#/alf' import {atoms as a, web} from '#/alf'
@@ -144,13 +144,12 @@ export function LanguageSettingsScreen({}: Props) {
<Select.ItemText>{label}</Select.ItemText> <Select.ItemText>{label}</Select.ItemText>
</Select.Item> </Select.Item>
)} )}
items={DEDUPED_LANGUAGES.sort( items={DEDUPED_LANGUAGES.map(l => ({
(a, b) => label: languageName(l, langPrefs.appLanguage),
a.name.localeCompare(b.name, langPrefs.appLanguage), // Localized sort
).map(l => ({
label: l.name, // Pre-generated name using Intl.DisplayNames
value: l.code2, value: l.code2,
}))} })).sort((a, b) =>
a.label.localeCompare(b.label, langPrefs.appLanguage),
)}
/> />
</Select.Root> </Select.Root>
</View> </View>
@@ -180,29 +179,24 @@ export function LanguageSettingsScreen({}: Props) {
values={langPrefs.contentLanguages} values={langPrefs.contentLanguages}
onChange={setLangPrefs.setContentLanguages}> onChange={setLangPrefs.setContentLanguages}>
<Toggle.PanelGroup> <Toggle.PanelGroup>
{possibleLanguages {possibleLanguages.map((language, index) => {
.sort( const name = languageName(language, langPrefs.appLanguage)
(a, b) => return (
a.name.localeCompare(b.name, langPrefs.appLanguage), // Localized sort <Toggle.Item
key={language.code2}
name={language.code2}
label={name}>
{({selected}) => (
<Toggle.Panel
active={selected}
adjacent={index === 0 ? 'trailing' : 'both'}>
<Toggle.Checkbox />
<Toggle.PanelText>{name}</Toggle.PanelText>
</Toggle.Panel>
)}
</Toggle.Item>
) )
.map((language, index) => { })}
const name = language.name // Pre-generated name using Intl.DisplayNames
return (
<Toggle.Item
key={language.code2}
name={language.code2}
label={name}>
{({selected}) => (
<Toggle.Panel
active={selected}
adjacent={index === 0 ? 'trailing' : 'both'}>
<Toggle.Checkbox />
<Toggle.PanelText>{name}</Toggle.PanelText>
</Toggle.Panel>
)}
</Toggle.Item>
)
})}
<Button <Button
label={_(msg`Add more languages…`)} label={_(msg`Add more languages…`)}
onPress={contentLanguagePrefsControl.open}> onPress={contentLanguagePrefsControl.open}>