index.ts
3.2 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import cn from "./cn";
import en from "./en";
import pt from "./pt";
import tw from "./tw";
import da from "./da";
import id from "./id";
import fr from "./fr";
import es from "./es";
import it from "./it";
import tr from "./tr";
import jp from "./jp";
import de from "./de";
import vi from "./vi";
import ru from "./ru";
import no from "./no";
import cs from "./cs";
import ko from "./ko";
import ar from "./ar";
import bn from "./bn";
import sk from "./sk";
import { merge } from "../utils/merge";
import { safeLocalStorage } from "@/app/utils";
import type { LocaleType } from "./cn";
export type { LocaleType, PartialLocaleType } from "./cn";
const localStorage = safeLocalStorage();
const ALL_LANGS = {
cn,
en,
tw,
pt,
da,
jp,
ko,
id,
fr,
es,
it,
tr,
de,
vi,
ru,
cs,
no,
ar,
bn,
sk,
};
export type Lang = keyof typeof ALL_LANGS;
export const AllLangs = Object.keys(ALL_LANGS) as Lang[];
export const ALL_LANG_OPTIONS: Record<Lang, string> = {
cn: "简体中文",
en: "English",
pt: "Português",
tw: "繁體中文",
da: "Dansk",
jp: "日本語",
ko: "한국어",
id: "Indonesia",
fr: "Français",
es: "Español",
it: "Italiano",
tr: "Türkçe",
de: "Deutsch",
vi: "Tiếng Việt",
ru: "Русский",
cs: "Čeština",
no: "Nynorsk",
ar: "العربية",
bn: "বাংলা",
sk: "Slovensky",
};
const LANG_KEY = "lang";
const DEFAULT_LANG = "en";
const fallbackLang = en;
const targetLang = ALL_LANGS[getLang()] as LocaleType;
// if target lang missing some fields, it will use fallback lang string
merge(fallbackLang, targetLang);
export default fallbackLang as LocaleType;
function getItem(key: string) {
return localStorage.getItem(key);
}
function setItem(key: string, value: string) {
localStorage.setItem(key, value);
}
function getLanguage() {
try {
const locale = new Intl.Locale(navigator.language).maximize();
const region = locale?.region?.toLowerCase();
// 1. check region code in ALL_LANGS
if (AllLangs.includes(region as Lang)) {
return region as Lang;
}
// 2. check language code in ALL_LANGS
if (AllLangs.includes(locale.language as Lang)) {
return locale.language as Lang;
}
return DEFAULT_LANG;
} catch {
return DEFAULT_LANG;
}
}
export function getLang(): Lang {
const savedLang = getItem(LANG_KEY);
if (AllLangs.includes((savedLang ?? "") as Lang)) {
return savedLang as Lang;
}
return getLanguage();
}
export function changeLang(lang: Lang) {
setItem(LANG_KEY, lang);
location.reload();
}
export function getISOLang() {
const isoLangString: Record<string, string> = {
cn: "zh-Hans",
tw: "zh-Hant",
};
const lang = getLang();
return isoLangString[lang] ?? lang;
}
const DEFAULT_STT_LANG = "zh-CN";
export const STT_LANG_MAP: Record<Lang, string> = {
cn: "zh-CN",
en: "en-US",
pt: "pt-BR",
tw: "zh-TW",
da: "da-DK",
jp: "ja-JP",
ko: "ko-KR",
id: "id-ID",
fr: "fr-FR",
es: "es-ES",
it: "it-IT",
tr: "tr-TR",
de: "de-DE",
vi: "vi-VN",
ru: "ru-RU",
cs: "cs-CZ",
no: "no-NO",
ar: "ar-SA",
bn: "bn-BD",
sk: "sk-SK",
};
export function getSTTLang(): string {
try {
return STT_LANG_MAP[getLang()];
} catch {
return DEFAULT_STT_LANG;
}
}