Translation followups (#9980)
This commit is contained in:
@@ -147,7 +147,7 @@ function TranslationLanguageSelect({
|
|||||||
{({props}) => {
|
{({props}) => {
|
||||||
return (
|
return (
|
||||||
<Text {...props} style={[a.text_xs]}>
|
<Text {...props} style={[a.text_xs]}>
|
||||||
<Trans>Edit</Trans>
|
<Trans>Change</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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 = (
|
||||||
@@ -297,6 +302,7 @@ export function DialogInner({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
const lang = item.lang
|
const lang = item.lang
|
||||||
|
const name = languageName(lang, langPrefs.appLanguage)
|
||||||
|
|
||||||
const isLastItem = index === numItems - 1
|
const isLastItem = index === numItems - 1
|
||||||
|
|
||||||
@@ -304,7 +310,7 @@ export function DialogInner({
|
|||||||
<Toggle.Item
|
<Toggle.Item
|
||||||
key={lang.code2}
|
key={lang.code2}
|
||||||
name={lang.code2}
|
name={lang.code2}
|
||||||
label={lang.name}
|
label={name}
|
||||||
style={[
|
style={[
|
||||||
t.atoms.border_contrast_low,
|
t.atoms.border_contrast_low,
|
||||||
!isLastItem && a.border_b,
|
!isLastItem && a.border_b,
|
||||||
@@ -312,9 +318,7 @@ export function DialogInner({
|
|||||||
a.px_0,
|
a.px_0,
|
||||||
a.py_md,
|
a.py_md,
|
||||||
]}>
|
]}>
|
||||||
<Toggle.LabelText style={[a.flex_1]}>
|
<Toggle.LabelText style={[a.flex_1]}>{name}</Toggle.LabelText>
|
||||||
{lang.name}
|
|
||||||
</Toggle.LabelText>
|
|
||||||
<Toggle.Checkbox />
|
<Toggle.Checkbox />
|
||||||
</Toggle.Item>
|
</Toggle.Item>
|
||||||
)
|
)
|
||||||
|
|||||||
+31
-16
@@ -32,21 +32,27 @@ export function code3ToCode2Strict(lang: string): string | undefined {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const displayNamesCache = new Map<string, Intl.DisplayNames>()
|
||||||
|
|
||||||
|
function getDisplayNames(appLang: string): Intl.DisplayNames {
|
||||||
|
let cached = displayNamesCache.get(appLang)
|
||||||
|
if (!cached) {
|
||||||
|
cached = new Intl.DisplayNames([appLang], {
|
||||||
|
type: 'language',
|
||||||
|
fallback: 'none',
|
||||||
|
languageDisplay: 'standard',
|
||||||
|
})
|
||||||
|
displayNamesCache.set(appLang, cached)
|
||||||
|
}
|
||||||
|
return cached
|
||||||
|
}
|
||||||
|
|
||||||
function getLocalizedLanguage(
|
function getLocalizedLanguage(
|
||||||
langCode: string,
|
langCode: string,
|
||||||
appLang: string,
|
appLang: string,
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
try {
|
try {
|
||||||
const allNames = new Intl.DisplayNames([appLang], {
|
return getDisplayNames(appLang).of(langCode) || undefined
|
||||||
type: 'language',
|
|
||||||
fallback: 'none',
|
|
||||||
languageDisplay: 'standard',
|
|
||||||
})
|
|
||||||
const translatedName = allNames.of(langCode)
|
|
||||||
|
|
||||||
if (translatedName) {
|
|
||||||
return translatedName
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore RangeError from Intl.DisplayNames APIs
|
// ignore RangeError from Intl.DisplayNames APIs
|
||||||
if (!(e instanceof RangeError)) {
|
if (!(e instanceof RangeError)) {
|
||||||
@@ -308,17 +314,26 @@ export function regionName(countryCode: string, appLang: string): string {
|
|||||||
return countryCode
|
return countryCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const regionNamesCache = new Map<string, Intl.DisplayNames>()
|
||||||
|
|
||||||
|
function getRegionNames(appLang: string): Intl.DisplayNames {
|
||||||
|
let cached = regionNamesCache.get(appLang)
|
||||||
|
if (!cached) {
|
||||||
|
cached = new Intl.DisplayNames([appLang], {
|
||||||
|
type: 'region',
|
||||||
|
fallback: 'none',
|
||||||
|
})
|
||||||
|
regionNamesCache.set(appLang, cached)
|
||||||
|
}
|
||||||
|
return cached
|
||||||
|
}
|
||||||
|
|
||||||
function getLocalizedRegionName(
|
function getLocalizedRegionName(
|
||||||
countryCode: string,
|
countryCode: string,
|
||||||
appLang: string,
|
appLang: string,
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
try {
|
try {
|
||||||
const allNames = new Intl.DisplayNames([appLang], {
|
return getRegionNames(appLang).of(countryCode)
|
||||||
type: 'region',
|
|
||||||
fallback: 'none',
|
|
||||||
})
|
|
||||||
|
|
||||||
return allNames.of(countryCode)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Error getting localized region name:', err)
|
console.warn('Error getting localized region name:', err)
|
||||||
return undefined
|
return undefined
|
||||||
|
|||||||
+66
-572
File diff suppressed because it is too large
Load Diff
@@ -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}>
|
||||||
|
|||||||
Reference in New Issue
Block a user