forked from QuantumNous/new-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlanguages.ts
More file actions
101 lines (91 loc) · 3.26 KB
/
Copy pathlanguages.ts
File metadata and controls
101 lines (91 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
export const INTERFACE_LANGUAGE_OPTIONS = [
{ code: 'zhCN', label: '简体中文' },
{ code: 'en', label: 'English' },
{ code: 'fr', label: 'Français' },
{ code: 'ru', label: 'Русский' },
{ code: 'ja', label: '日本語' },
{ code: 'vi', label: 'Tiếng Việt' },
{ code: 'zhTW', label: '繁體中文' },
] as const
export type InterfaceLanguageCode =
(typeof INTERFACE_LANGUAGE_OPTIONS)[number]['code']
export function normalizeInterfaceLanguage(value?: string | null): string {
if (!value) return 'en'
let normalized = value.trim().replaceAll('_', '-').toLowerCase()
if (
value === 'zh-TW' ||
value === 'zh-HK' ||
value === 'zh-MO' ||
value === 'zhTW'
) {
normalized = 'zhTW'
}
if (value === 'zh-CN' || value === 'zh-Hans' || value === 'zhCN') {
normalized = 'zhCN'
}
return INTERFACE_LANGUAGE_OPTIONS.some((lang) => lang.code === normalized)
? normalized
: 'en'
}
/**
* Map a browser-detected locale onto the interface language codes this project
* uses with i18next (`zhCN` / `zhTW`).
*
* Browsers report standard BCP-47 tags (`zh-CN`, `zh-TW`, `zh-Hant`, `zh`, ...),
* but `supportedLngs`/resources use the non-standard camelCase codes, so without
* this mapping a Chinese browser would never match and fall back to English.
* Non-Chinese codes are returned unchanged so i18next's own `supportedLngs`
* matching still applies (e.g. `fr-FR` -> `fr`, `ja` -> `ja`).
*/
export function convertDetectedLanguage(value: string): string {
const lower = value.trim().replaceAll('_', '-').toLowerCase()
if (!lower.startsWith('zh')) return value
if (
lower === 'zh-tw' ||
lower === 'zh-hk' ||
lower === 'zh-mo' ||
lower.startsWith('zh-hant')
) {
return 'zhTW'
}
return 'zhCN'
}
/**
* Convert an interface language code (the values i18next uses, such as `zhCN` /
* `zhTW`) into a valid BCP-47 locale tag that the `Intl.*` APIs accept.
*
* `new Intl.NumberFormat('zhCN')` throws `RangeError: Invalid language tag`, so
* any locale derived from `i18n.language` / `i18n.resolvedLanguage` MUST be run
* through this before it reaches an `Intl` constructor. Unknown values fall back
* to `undefined`, which makes `Intl` use the runtime default locale.
*/
export function toIntlLocale(value?: string | null): string | undefined {
if (!value) return undefined
switch (value) {
case 'zhCN':
return 'zh-CN'
case 'zhTW':
return 'zh-TW'
default:
break
}
try {
return Intl.getCanonicalLocales(value)[0]
} catch {
return undefined
}
}