diff --git a/src/assets/README.md b/src/assets/README.md index e8c04d52..d3820f45 100644 --- a/src/assets/README.md +++ b/src/assets/README.md @@ -3,7 +3,7 @@ Locales are difficult, here is some guidance. ## Process on adding new languages -1. Use weblate to add translations, see contributing guidelines. +1. Use Weblate to add translations, see contributing guidelines. 2. 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. -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` -4. If the flag in the language dropdown doesn't match the correct one. Add a default country in `@/utils/language.ts` at `countryPriority`. +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` +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`. diff --git a/src/utils/language.ts b/src/utils/language.ts index 5f05113c..2364e6a6 100644 --- a/src/utils/language.ts +++ b/src/utils/language.ts @@ -5,54 +5,46 @@ const languageOrder = ["en", "hi", "fr", "de", "nl", "pt"]; // mapping of language code to country code. // multiple mappings can exist, since languages are spoken in multiple countries. -// This mapping purely exists to prioritize a country over another in languages. +// This mapping purely exists to prioritize a country over another in languages where the base language code does +// 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 // iso639_1 -> iso3166 Alpha-2 const countryPriority: Record = { - en: "us", - nl: "nl", - fr: "fr", - de: "de", - pt: "pt", - ar: "sa", - es: "es", zh: "cn", - ko: "kr", - ta: "lk", }; // list of iso639_1 Alpha-2 codes used as default languages const defaultLanguageCodes: string[] = [ - "en-US", - "cs-CZ", - "de-DE", - "fr-FR", - "pt-BR", - "it-IT", - "nl-NL", - "pl-PL", - "tr-TR", - "vi-VN", - "zh-CN", - "he-IL", - "sv-SE", - "lv-LV", - "th-TH", - "ne-NP", "ar-SA", - "es-ES", - "et-EE", "bg-BG", "bn-BD", + "cs-CZ", + "de-DE", "el-GR", + "en-US", + "es-ES", + "et-EE", "fa-IR", + "fr-FR", + "gl-ES", "gu-IN", + "he-IL", "id-ID", + "it-IT", "ja-JP", "ko-KR", + "lv-LV", + "ne-NP", + "nl-NL", + "pl-PL", + "pt-BR", + "ru-RU", "sl-SI", + "sv-SE", "ta-LK", - "ru-RU", - "gl-ES", + "th-TH", + "tr-TR", + "vi-VN", + "zh-CN", ]; export interface LocaleInfo { @@ -89,7 +81,7 @@ function populateLanguageCode(language: string): string { } /** - * @param locale idk what kinda code this takes, anytihhng in ietf format I guess + * @param locale idk what kinda code this takes, anything in ietf format I guess * @returns pretty format for language, null if it no info can be found for language */ export function getPrettyLanguageNameFromLocale(locale: string): string | null { @@ -105,12 +97,12 @@ export function getPrettyLanguageNameFromLocale(locale: string): string | null { } /** - * Sort locale codes by occurance, rest on alphabetical order + * Sort locale codes by occurrence, rest on alphabetical order * @param langCodes list language codes to sort * @returns sorted version of inputted list */ export function sortLangCodes(langCodes: string[]) { - const languagesOrder = [...languageOrder].reverse(); // Reverse is neccesary, not sure why + const languagesOrder = [...languageOrder].reverse(); // Reverse is necessary, not sure why const results = langCodes.sort((a, b) => { const langOrderA = languagesOrder.findIndex( @@ -134,23 +126,37 @@ export function sortLangCodes(langCodes: string[]) { */ export function getCountryCodeForLocale(locale: string): string | null { let output: LanguageObj | null = null as any as LanguageObj; - const tag = getTag(locale, true); + const tag = getTag(populateLanguageCode(locale), true); if (!tag?.language?.Subtag) return null; - // this function isnt async, so its garuanteed to work like this + // this function isn't async, so its guaranteed to work like this countryLanguages.getLanguage(tag.language.Subtag, (_err, lang) => { if (lang) output = lang; }); + if (!output) return null; const priority = countryPriority[output.iso639_1.toLowerCase()]; if (output.countries.length === 0) { return priority ?? null; } + if (priority) { - const priotizedCountry = output.countries.find( + const prioritizedCountry = output.countries.find( (v) => v.code_2.toLowerCase() === priority, ); - if (priotizedCountry) return priotizedCountry.code_2.toLowerCase(); + if (prioritizedCountry) return prioritizedCountry.code_2.toLowerCase(); + } + + // If the language contains a region, check that against the countries and + // return the region if it matches + const regionSubtag = tag?.region?.Subtag.toLowerCase(); + if (regionSubtag) { + const regionCode = output.countries.find( + (c) => + c.code_2.toLowerCase() === regionSubtag || + c.code_3.toLowerCase() === regionSubtag, + ); + if (regionCode) return regionCode.code_2.toLowerCase(); } return output.countries[0].code_2.toLowerCase(); }