···33Locales are difficult, here is some guidance.
4455## Process on adding new languages
66-1. Use weblate to add translations, see contributing guidelines.
66+1. Use Weblate to add translations, see contributing guidelines.
772. Add your language to `@/assets/languages.ts`. Must be in ISO format (ISO-639 for language and ISO-3166 for country/region). For joke languages, use any format.
88-3. If your language doesn't have a region specified (Such as in `pt-BR`, `BR` being the region). Add a default region in `@/utils/language.ts` at `defaultLanguageCodes`
99-4. If the flag in the language dropdown doesn't match the correct one. Add a default country in `@/utils/language.ts` at `countryPriority`.
88+3. If the language code doesn't have a region specified (Such as in `pt-BR`, `BR` being the region), add a default region in `@/utils/language.ts` at `defaultLanguageCodes`
99+4. If the language code doesn't contain a region (Such as in `zh-Hant`), add a default country in `@/utils/language.ts` at `countryPriority`.
+43-37
src/utils/language.ts
···5566// mapping of language code to country code.
77// multiple mappings can exist, since languages are spoken in multiple countries.
88-// This mapping purely exists to prioritize a country over another in languages.
88+// This mapping purely exists to prioritize a country over another in languages where the base language code does
99+// not contain a region (i.e. if the language code is zh-Hant where Hant is a script) or if the region in the language code is incorrect
910// iso639_1 -> iso3166 Alpha-2
1011const countryPriority: Record<string, string> = {
1111- en: "us",
1212- nl: "nl",
1313- fr: "fr",
1414- de: "de",
1515- pt: "pt",
1616- ar: "sa",
1717- es: "es",
1812 zh: "cn",
1919- ko: "kr",
2020- ta: "lk",
2113};
22142315// list of iso639_1 Alpha-2 codes used as default languages
2416const defaultLanguageCodes: string[] = [
2525- "en-US",
2626- "cs-CZ",
2727- "de-DE",
2828- "fr-FR",
2929- "pt-BR",
3030- "it-IT",
3131- "nl-NL",
3232- "pl-PL",
3333- "tr-TR",
3434- "vi-VN",
3535- "zh-CN",
3636- "he-IL",
3737- "sv-SE",
3838- "lv-LV",
3939- "th-TH",
4040- "ne-NP",
4117 "ar-SA",
4242- "es-ES",
4343- "et-EE",
4418 "bg-BG",
4519 "bn-BD",
2020+ "cs-CZ",
2121+ "de-DE",
4622 "el-GR",
2323+ "en-US",
2424+ "es-ES",
2525+ "et-EE",
4726 "fa-IR",
2727+ "fr-FR",
2828+ "gl-ES",
4829 "gu-IN",
3030+ "he-IL",
4931 "id-ID",
3232+ "it-IT",
5033 "ja-JP",
5134 "ko-KR",
3535+ "lv-LV",
3636+ "ne-NP",
3737+ "nl-NL",
3838+ "pl-PL",
3939+ "pt-BR",
4040+ "ru-RU",
5241 "sl-SI",
4242+ "sv-SE",
5343 "ta-LK",
5454- "ru-RU",
5555- "gl-ES",
4444+ "th-TH",
4545+ "tr-TR",
4646+ "vi-VN",
4747+ "zh-CN",
5648];
57495850export interface LocaleInfo {
···8981}
90829183/**
9292- * @param locale idk what kinda code this takes, anytihhng in ietf format I guess
8484+ * @param locale idk what kinda code this takes, anything in ietf format I guess
9385 * @returns pretty format for language, null if it no info can be found for language
9486 */
9587export function getPrettyLanguageNameFromLocale(locale: string): string | null {
···10597}
1069810799/**
108108- * Sort locale codes by occurance, rest on alphabetical order
100100+ * Sort locale codes by occurrence, rest on alphabetical order
109101 * @param langCodes list language codes to sort
110102 * @returns sorted version of inputted list
111103 */
112104export function sortLangCodes(langCodes: string[]) {
113113- const languagesOrder = [...languageOrder].reverse(); // Reverse is neccesary, not sure why
105105+ const languagesOrder = [...languageOrder].reverse(); // Reverse is necessary, not sure why
114106115107 const results = langCodes.sort((a, b) => {
116108 const langOrderA = languagesOrder.findIndex(
···134126 */
135127export function getCountryCodeForLocale(locale: string): string | null {
136128 let output: LanguageObj | null = null as any as LanguageObj;
137137- const tag = getTag(locale, true);
129129+ const tag = getTag(populateLanguageCode(locale), true);
138130139131 if (!tag?.language?.Subtag) return null;
140140- // this function isnt async, so its garuanteed to work like this
132132+ // this function isn't async, so its guaranteed to work like this
141133 countryLanguages.getLanguage(tag.language.Subtag, (_err, lang) => {
142134 if (lang) output = lang;
143135 });
136136+144137 if (!output) return null;
145138 const priority = countryPriority[output.iso639_1.toLowerCase()];
146139 if (output.countries.length === 0) {
147140 return priority ?? null;
148141 }
142142+149143 if (priority) {
150150- const priotizedCountry = output.countries.find(
144144+ const prioritizedCountry = output.countries.find(
151145 (v) => v.code_2.toLowerCase() === priority,
152146 );
153153- if (priotizedCountry) return priotizedCountry.code_2.toLowerCase();
147147+ if (prioritizedCountry) return prioritizedCountry.code_2.toLowerCase();
148148+ }
149149+150150+ // If the language contains a region, check that against the countries and
151151+ // return the region if it matches
152152+ const regionSubtag = tag?.region?.Subtag.toLowerCase();
153153+ if (regionSubtag) {
154154+ const regionCode = output.countries.find(
155155+ (c) =>
156156+ c.code_2.toLowerCase() === regionSubtag ||
157157+ c.code_3.toLowerCase() === regionSubtag,
158158+ );
159159+ if (regionCode) return regionCode.code_2.toLowerCase();
154160 }
155161 return output.countries[0].code_2.toLowerCase();
156162}