this repo has no description
1import { useLingui } from '@lingui/react';
2import { useMemo } from 'preact/hooks';
3
4import { CATALOGS, DEFAULT_LANG, DEV_LOCALES, LOCALES } from '../locales';
5import { activateLang } from '../utils/lang';
6import localeCode2Text from '../utils/localeCode2Text';
7import store from '../utils/store';
8
9const regionMaps = {
10 'zh-CN': 'zh-Hans',
11 'zh-TW': 'zh-Hant',
12 'pt-BR': 'pt-BR',
13};
14
15export default function LangSelector() {
16 const { i18n } = useLingui();
17
18 // Sorted on render, so the order won't suddenly change based on current locale
19 const populatedLocales = useMemo(() => {
20 return LOCALES.map((lang) => {
21 // Don't need regions for now, it makes text too noisy
22 // Wait till there's too many languages and there are regional clashes
23 const regionlessCode = regionMaps[lang] || lang.replace(/-[a-z]+$/i, '');
24
25 const native = localeCode2Text({
26 code: regionlessCode,
27 locale: lang,
28 fallback: CATALOGS.find((c) => c.code === lang)?.nativeName,
29 });
30
31 // Not used when rendering because it'll change based on current locale
32 // Only used for sorting on render
33 const _common = localeCode2Text({
34 code: regionlessCode,
35 locale: i18n.locale,
36 fallback: CATALOGS.find((c) => c.code === lang)?.name,
37 });
38
39 return {
40 code: lang,
41 regionlessCode,
42 _common,
43 native,
44 };
45 }).sort((a, b) => {
46 // Sort by common name
47 const order = a._common.localeCompare(b._common, i18n.locale);
48 if (order !== 0) return order;
49 // Sort by code (fallback)
50 if (a.code < b.code) return -1;
51 if (a.code > b.code) return 1;
52 return 0;
53 });
54 }, []);
55
56 return (
57 <label class="lang-selector">
58 🌐{' '}
59 <select
60 class="small"
61 value={i18n.locale || DEFAULT_LANG}
62 onChange={(e) => {
63 store.local.set('lang', e.target.value);
64 activateLang(e.target.value);
65 }}
66 >
67 {populatedLocales.map(({ code, regionlessCode, native }) => {
68 // Common name changes based on current locale
69 const common = localeCode2Text({
70 code: regionlessCode,
71 locale: i18n.locale,
72 fallback: CATALOGS.find((c) => c.code === code)?.name,
73 });
74 const showCommon = !!common && common !== native;
75 return (
76 <option
77 value={code}
78 data-regionless-code={regionlessCode}
79 key={code}
80 >
81 {showCommon ? `${native} - ${common}` : native}
82 </option>
83 );
84 })}
85 {(import.meta.env.DEV || import.meta.env.PHANPY_SHOW_DEV_LOCALES) && (
86 <optgroup label="🚧 Development (<50% translated)">
87 {DEV_LOCALES.map((code) => {
88 if (code === 'pseudo-LOCALE') {
89 return (
90 <>
91 <hr />
92 <option value={code} key={code}>
93 Pseudolocalization (test)
94 </option>
95 </>
96 );
97 }
98 const nativeName = CATALOGS.find(
99 (c) => c.code === code,
100 )?.nativeName;
101 const completion = CATALOGS.find(
102 (c) => c.code === code,
103 )?.completion;
104 return (
105 <option value={code} key={code}>
106 {nativeName || code} ‎[{completion}%]
107 </option>
108 );
109 })}
110 </optgroup>
111 )}
112 </select>
113 </label>
114 );
115}