Less-noisy language selector with perhaps better sort

This commit is contained in:
Lim Chee Aun 2024-08-18 11:11:03 +08:00
parent 15e4012dd2
commit 1fde4c6730

View file

@ -5,30 +5,53 @@ import { DEFAULT_LANG, LOCALES } from '../locales';
import { activateLang } from '../utils/lang';
import localeCode2Text from '../utils/localeCode2Text';
const regionMaps = {
'zh-CN': 'zh-Hans',
'zh-TW': 'zh-Hant',
};
export default function LangSelector() {
const { i18n } = useLingui();
// Sorted on render, so the order won't suddenly change based on current locale
const populatedLocales = useMemo(() => {
return LOCALES.map((lang) => {
const native = localeCode2Text({ code: lang, locale: lang });
const common = localeCode2Text(lang);
const showCommon = !!common && common !== native;
if (lang === 'pseudo-LOCALE') {
return { code: lang, native: 'Pseudolocalization (test)' };
}
// Don't need regions for now, it makes text too noisy
// Wait till there's too many languages and there are regional clashes
const regionlessCode = regionMaps[lang] || lang.replace(/-[a-z]+$/i, '');
const native = localeCode2Text({ code: regionlessCode, locale: lang });
// Not used when rendering because it'll change based on current locale
// Only used for sorting on render
const _common = localeCode2Text({
code: regionlessCode,
locale: i18n.locale,
});
return {
code: lang,
regionlessCode,
_common,
native,
common,
showCommon,
};
}).sort((a, b) => {
// If pseudo-LOCALE, always put it at the bottom
if (a.code === 'pseudo-LOCALE') return 1;
if (b.code === 'pseudo-LOCALE') return -1;
// Sort by code
// Sort by common name
if (a._common < b._common) return -1;
if (a._common > b._common) return 1;
// Sort by code (fallback)
if (a.code < b.code) return -1;
if (a.code > b.code) return 1;
return 0;
});
}, [i18n.locale]);
}, []);
return (
<label class="lang-selector">
@ -41,19 +64,29 @@ export default function LangSelector() {
activateLang(e.target.value);
}}
>
{populatedLocales.map(({ code, native, common, showCommon }) => {
{populatedLocales.map(({ code, regionlessCode, native }) => {
if (code === 'pseudo-LOCALE') {
return (
<>
<hr />
<option value={code} key={code}>
Pseudolocalization (test)
{native}
</option>
</>
);
}
// Common name changes based on current locale
const common = localeCode2Text({
code: regionlessCode,
locale: i18n.locale,
});
const showCommon = !!common && common !== native;
return (
<option value={code} key={code}>
<option
value={code}
data-regionless-code={regionlessCode}
key={code}
>
{showCommon ? `${native} - ${common}` : native}
</option>
);