Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Get country names from the browser instead of manual i18n #11428

Merged
merged 4 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions src/components/views/auth/CountryDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@ import React, { ReactElement } from "react";

import { COUNTRIES, getEmojiFlag, PhoneNumberCountryDefinition } from "../../../phonenumber";
import SdkConfig from "../../../SdkConfig";
import { _t } from "../../../languageHandler";
import { _t, getUserLanguage } from "../../../languageHandler";
import Dropdown from "../elements/Dropdown";
import { NonEmptyArray } from "../../../@types/common";

const COUNTRIES_BY_ISO2: Record<string, PhoneNumberCountryDefinition> = {};
for (const c of COUNTRIES) {
COUNTRIES_BY_ISO2[c.iso2] = c;
interface InternationalisedCountry extends PhoneNumberCountryDefinition {
name: string; // already translated to the user's locale
}

function countryMatchesSearchQuery(query: string, country: PhoneNumberCountryDefinition): boolean {
function countryMatchesSearchQuery(query: string, country: InternationalisedCountry): boolean {
// Remove '+' if present (when searching for a prefix)
if (query[0] === "+") {
query = query.slice(1);
Expand All @@ -41,7 +40,7 @@ function countryMatchesSearchQuery(query: string, country: PhoneNumberCountryDef

interface IProps {
value?: string;
onOptionChange: (country: PhoneNumberCountryDefinition) => void;
onOptionChange: (country: InternationalisedCountry) => void;
isSmall: boolean; // if isSmall, show +44 in the selected value
showPrefix: boolean;
className?: string;
Expand All @@ -53,33 +52,42 @@ interface IState {
}

export default class CountryDropdown extends React.Component<IProps, IState> {
private readonly defaultCountry: PhoneNumberCountryDefinition;
private readonly defaultCountry: InternationalisedCountry;
private readonly countries: InternationalisedCountry[];
private readonly countryMap: Map<string, InternationalisedCountry>;

public constructor(props: IProps) {
super(props);

let defaultCountry: PhoneNumberCountryDefinition | undefined;
const displayNames = new Intl.DisplayNames([getUserLanguage()], { type: "region" });

this.countries = COUNTRIES.map((c) => ({
name: displayNames.of(c.iso2) ?? c.iso2,
...c,
}));
this.countryMap = new Map(this.countries.map((c) => [c.iso2, c]));

let defaultCountry: InternationalisedCountry | undefined;
const defaultCountryCode = SdkConfig.get("default_country_code");
if (defaultCountryCode) {
const country = COUNTRIES.find((c) => c.iso2 === defaultCountryCode.toUpperCase());
const country = this.countries.find((c) => c.iso2 === defaultCountryCode.toUpperCase());
if (country) defaultCountry = country;
}

if (!defaultCountry) {
try {
const locale = new Intl.Locale(navigator.language ?? navigator.languages[0]);
const code = locale.region ?? locale.language ?? locale.baseName;
const displayNames = new Intl.DisplayNames(["en"], { type: "region" });
const displayName = displayNames.of(code)!.toUpperCase();
defaultCountry = COUNTRIES.find(
defaultCountry = this.countries.find(
(c) => c.iso2 === code.toUpperCase() || c.name.toUpperCase() === displayName,
);
} catch (e) {
console.warn("Failed to detect default locale", e);
}
}

this.defaultCountry = defaultCountry ?? COUNTRIES[0];
this.defaultCountry = defaultCountry ?? this.countries[0];
this.state = {
searchQuery: "",
};
Expand All @@ -101,7 +109,7 @@ export default class CountryDropdown extends React.Component<IProps, IState> {
};

private onOptionChange = (iso2: string): void => {
this.props.onOptionChange(COUNTRIES_BY_ISO2[iso2]);
this.props.onOptionChange(this.countryMap.get(iso2)!);
};

private flagImgForIso2(iso2: string): React.ReactNode {
Expand All @@ -112,9 +120,9 @@ export default class CountryDropdown extends React.Component<IProps, IState> {
if (!this.props.isSmall) {
return undefined;
}
let countryPrefix;
let countryPrefix: string | undefined;
if (this.props.showPrefix) {
countryPrefix = "+" + COUNTRIES_BY_ISO2[iso2].prefix;
countryPrefix = "+" + this.countryMap.get(iso2)!.prefix;
}
return (
<span className="mx_CountryDropdown_shortOption">
Expand All @@ -125,26 +133,28 @@ export default class CountryDropdown extends React.Component<IProps, IState> {
};

public render(): React.ReactNode {
let displayedCountries;
let displayedCountries: InternationalisedCountry[];
if (this.state.searchQuery) {
displayedCountries = COUNTRIES.filter(countryMatchesSearchQuery.bind(this, this.state.searchQuery));
if (this.state.searchQuery.length == 2 && COUNTRIES_BY_ISO2[this.state.searchQuery.toUpperCase()]) {
displayedCountries = this.countries.filter((country) =>
countryMatchesSearchQuery(this.state.searchQuery, country),
);
if (this.state.searchQuery.length == 2 && this.countryMap.has(this.state.searchQuery.toUpperCase())) {
// exact ISO2 country name match: make the first result the matches ISO2
const matched = COUNTRIES_BY_ISO2[this.state.searchQuery.toUpperCase()];
const matched = this.countryMap.get(this.state.searchQuery.toUpperCase())!;
displayedCountries = displayedCountries.filter((c) => {
return c.iso2 != matched.iso2;
});
displayedCountries.unshift(matched);
}
} else {
displayedCountries = COUNTRIES;
displayedCountries = this.countries;
}

const options = displayedCountries.map((country) => {
return (
<div className="mx_CountryDropdown_option" key={country.iso2}>
{this.flagImgForIso2(country.iso2)}
{_t(country.name)} (+{country.prefix})
{country.name} (+{country.prefix})
</div>
);
}) as NonEmptyArray<ReactElement & { key: string }>;
Expand Down
249 changes: 0 additions & 249 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,255 +106,6 @@
"Unable to enable Notifications": "Unable to enable Notifications",
"This email address was not found": "This email address was not found",
"Your email address does not appear to be associated with a Matrix ID on this homeserver.": "Your email address does not appear to be associated with a Matrix ID on this homeserver.",
"United Kingdom": "United Kingdom",
"United States": "United States",
"Afghanistan": "Afghanistan",
"Åland Islands": "Åland Islands",
"Albania": "Albania",
"Algeria": "Algeria",
"American Samoa": "American Samoa",
"Andorra": "Andorra",
"Angola": "Angola",
"Anguilla": "Anguilla",
"Antarctica": "Antarctica",
"Antigua & Barbuda": "Antigua & Barbuda",
"Argentina": "Argentina",
"Armenia": "Armenia",
"Aruba": "Aruba",
"Australia": "Australia",
"Austria": "Austria",
"Azerbaijan": "Azerbaijan",
"Bahamas": "Bahamas",
"Bahrain": "Bahrain",
"Bangladesh": "Bangladesh",
"Barbados": "Barbados",
"Belarus": "Belarus",
"Belgium": "Belgium",
"Belize": "Belize",
"Benin": "Benin",
"Bermuda": "Bermuda",
"Bhutan": "Bhutan",
"Bolivia": "Bolivia",
"Bosnia": "Bosnia",
"Botswana": "Botswana",
"Bouvet Island": "Bouvet Island",
"Brazil": "Brazil",
"British Indian Ocean Territory": "British Indian Ocean Territory",
"British Virgin Islands": "British Virgin Islands",
"Brunei": "Brunei",
"Bulgaria": "Bulgaria",
"Burkina Faso": "Burkina Faso",
"Burundi": "Burundi",
"Cambodia": "Cambodia",
"Cameroon": "Cameroon",
"Canada": "Canada",
"Cape Verde": "Cape Verde",
"Caribbean Netherlands": "Caribbean Netherlands",
"Cayman Islands": "Cayman Islands",
"Central African Republic": "Central African Republic",
"Chad": "Chad",
"Chile": "Chile",
"China": "China",
"Christmas Island": "Christmas Island",
"Cocos (Keeling) Islands": "Cocos (Keeling) Islands",
"Colombia": "Colombia",
"Comoros": "Comoros",
"Congo - Brazzaville": "Congo - Brazzaville",
"Congo - Kinshasa": "Congo - Kinshasa",
"Cook Islands": "Cook Islands",
"Costa Rica": "Costa Rica",
"Croatia": "Croatia",
"Cuba": "Cuba",
"Curaçao": "Curaçao",
"Cyprus": "Cyprus",
"Czech Republic": "Czech Republic",
"Côte d’Ivoire": "Côte d’Ivoire",
"Denmark": "Denmark",
"Djibouti": "Djibouti",
"Dominica": "Dominica",
"Dominican Republic": "Dominican Republic",
"Ecuador": "Ecuador",
"Egypt": "Egypt",
"El Salvador": "El Salvador",
"Equatorial Guinea": "Equatorial Guinea",
"Eritrea": "Eritrea",
"Estonia": "Estonia",
"Ethiopia": "Ethiopia",
"Falkland Islands": "Falkland Islands",
"Faroe Islands": "Faroe Islands",
"Fiji": "Fiji",
"Finland": "Finland",
"France": "France",
"French Guiana": "French Guiana",
"French Polynesia": "French Polynesia",
"French Southern Territories": "French Southern Territories",
"Gabon": "Gabon",
"Gambia": "Gambia",
"Georgia": "Georgia",
"Germany": "Germany",
"Ghana": "Ghana",
"Gibraltar": "Gibraltar",
"Greece": "Greece",
"Greenland": "Greenland",
"Grenada": "Grenada",
"Guadeloupe": "Guadeloupe",
"Guam": "Guam",
"Guatemala": "Guatemala",
"Guernsey": "Guernsey",
"Guinea": "Guinea",
"Guinea-Bissau": "Guinea-Bissau",
"Guyana": "Guyana",
"Haiti": "Haiti",
"Heard & McDonald Islands": "Heard & McDonald Islands",
"Honduras": "Honduras",
"Hong Kong": "Hong Kong",
"Hungary": "Hungary",
"Iceland": "Iceland",
"India": "India",
"Indonesia": "Indonesia",
"Iran": "Iran",
"Iraq": "Iraq",
"Ireland": "Ireland",
"Isle of Man": "Isle of Man",
"Israel": "Israel",
"Italy": "Italy",
"Jamaica": "Jamaica",
"Japan": "Japan",
"Jersey": "Jersey",
"Jordan": "Jordan",
"Kazakhstan": "Kazakhstan",
"Kenya": "Kenya",
"Kiribati": "Kiribati",
"Kosovo": "Kosovo",
"Kuwait": "Kuwait",
"Kyrgyzstan": "Kyrgyzstan",
"Laos": "Laos",
"Latvia": "Latvia",
"Lebanon": "Lebanon",
"Lesotho": "Lesotho",
"Liberia": "Liberia",
"Libya": "Libya",
"Liechtenstein": "Liechtenstein",
"Lithuania": "Lithuania",
"Luxembourg": "Luxembourg",
"Macau": "Macau",
"Macedonia": "Macedonia",
"Madagascar": "Madagascar",
"Malawi": "Malawi",
"Malaysia": "Malaysia",
"Maldives": "Maldives",
"Mali": "Mali",
"Malta": "Malta",
"Marshall Islands": "Marshall Islands",
"Martinique": "Martinique",
"Mauritania": "Mauritania",
"Mauritius": "Mauritius",
"Mayotte": "Mayotte",
"Mexico": "Mexico",
"Micronesia": "Micronesia",
"Moldova": "Moldova",
"Monaco": "Monaco",
"Mongolia": "Mongolia",
"Montenegro": "Montenegro",
"Montserrat": "Montserrat",
"Morocco": "Morocco",
"Mozambique": "Mozambique",
"Myanmar": "Myanmar",
"Namibia": "Namibia",
"Nauru": "Nauru",
"Nepal": "Nepal",
"Netherlands": "Netherlands",
"New Caledonia": "New Caledonia",
"New Zealand": "New Zealand",
"Nicaragua": "Nicaragua",
"Niger": "Niger",
"Nigeria": "Nigeria",
"Niue": "Niue",
"Norfolk Island": "Norfolk Island",
"North Korea": "North Korea",
"Northern Mariana Islands": "Northern Mariana Islands",
"Norway": "Norway",
"Oman": "Oman",
"Pakistan": "Pakistan",
"Palau": "Palau",
"Palestine": "Palestine",
"Panama": "Panama",
"Papua New Guinea": "Papua New Guinea",
"Paraguay": "Paraguay",
"Peru": "Peru",
"Philippines": "Philippines",
"Pitcairn Islands": "Pitcairn Islands",
"Poland": "Poland",
"Portugal": "Portugal",
"Puerto Rico": "Puerto Rico",
"Qatar": "Qatar",
"Romania": "Romania",
"Russia": "Russia",
"Rwanda": "Rwanda",
"Réunion": "Réunion",
"Samoa": "Samoa",
"San Marino": "San Marino",
"Saudi Arabia": "Saudi Arabia",
"Senegal": "Senegal",
"Serbia": "Serbia",
"Seychelles": "Seychelles",
"Sierra Leone": "Sierra Leone",
"Singapore": "Singapore",
"Sint Maarten": "Sint Maarten",
"Slovakia": "Slovakia",
"Slovenia": "Slovenia",
"Solomon Islands": "Solomon Islands",
"Somalia": "Somalia",
"South Africa": "South Africa",
"South Georgia & South Sandwich Islands": "South Georgia & South Sandwich Islands",
"South Korea": "South Korea",
"South Sudan": "South Sudan",
"Spain": "Spain",
"Sri Lanka": "Sri Lanka",
"St. Barthélemy": "St. Barthélemy",
"St. Helena": "St. Helena",
"St. Kitts & Nevis": "St. Kitts & Nevis",
"St. Lucia": "St. Lucia",
"St. Martin": "St. Martin",
"St. Pierre & Miquelon": "St. Pierre & Miquelon",
"St. Vincent & Grenadines": "St. Vincent & Grenadines",
"Sudan": "Sudan",
"Suriname": "Suriname",
"Svalbard & Jan Mayen": "Svalbard & Jan Mayen",
"Swaziland": "Swaziland",
"Sweden": "Sweden",
"Switzerland": "Switzerland",
"Syria": "Syria",
"São Tomé & Príncipe": "São Tomé & Príncipe",
"Taiwan": "Taiwan",
"Tajikistan": "Tajikistan",
"Tanzania": "Tanzania",
"Thailand": "Thailand",
"Timor-Leste": "Timor-Leste",
"Togo": "Togo",
"Tokelau": "Tokelau",
"Tonga": "Tonga",
"Trinidad & Tobago": "Trinidad & Tobago",
"Tunisia": "Tunisia",
"Turkey": "Turkey",
"Turkmenistan": "Turkmenistan",
"Turks & Caicos Islands": "Turks & Caicos Islands",
"Tuvalu": "Tuvalu",
"U.S. Virgin Islands": "U.S. Virgin Islands",
"Uganda": "Uganda",
"Ukraine": "Ukraine",
"United Arab Emirates": "United Arab Emirates",
"Uruguay": "Uruguay",
"Uzbekistan": "Uzbekistan",
"Vanuatu": "Vanuatu",
"Vatican City": "Vatican City",
"Venezuela": "Venezuela",
"Vietnam": "Vietnam",
"Wallis & Futuna": "Wallis & Futuna",
"Western Sahara": "Western Sahara",
"Yemen": "Yemen",
"Zambia": "Zambia",
"Zimbabwe": "Zimbabwe",
"Sign In or Create Account": "Sign In or Create Account",
"Sign In": "Sign In",
"Use your account or create a new one to continue.": "Use your account or create a new one to continue.",
Expand Down
Loading