Improve phone number entry

This commit is contained in:
Ilya Laktyushin
2020-08-25 17:36:15 +03:00
parent d584c0317d
commit b901cdfb0d
7 changed files with 179 additions and 42 deletions

View File

@@ -25,6 +25,7 @@ private func loadCountryCodes() -> [Country] {
let endOfLine = "\n"
var result: [Country] = []
var countriesByPrefix: [String: (Country, Country.CountryCode)] = [:]
var currentLocation = data.startIndex
@@ -46,8 +47,11 @@ private func loadCountryCodes() -> [Country] {
let maybeNameRange = data.range(of: endOfLine, options: [], range: idRange.upperBound ..< data.endIndex)
let countryName = locale.localizedString(forIdentifier: countryId) ?? ""
if let countryCodeInt = Int(countryCode) {
result.append(Country(code: countryId, name: countryName, localizedName: nil, countryCodes: [Country.CountryCode(code: countryCode, prefixes: [], patterns: [])], hidden: false))
if let _ = Int(countryCode) {
let code = Country.CountryCode(code: countryCode, prefixes: [], patterns: [])
let country = Country(id: countryId, name: countryName, localizedName: nil, countryCodes: [code], hidden: false)
result.append(country)
countriesByPrefix["\(code.code)"] = (country, code)
}
if let maybeNameRange = maybeNameRange {
@@ -57,15 +61,35 @@ private func loadCountryCodes() -> [Country] {
}
}
countryCodesByPrefix = countriesByPrefix
return result
}
private var countryCodes: [Country] = loadCountryCodes()
private var countryCodesByPrefix: [String: (Country, Country.CountryCode)] = [:]
public func loadServerCountryCodes(accountManager: AccountManager, network: Network) {
public func loadServerCountryCodes(accountManager: AccountManager, network: Network, completion: @escaping () -> Void) {
let _ = (getCountriesList(accountManager: accountManager, network: network, langCode: nil)
|> deliverOnMainQueue).start(next: { countries in
countryCodes = countries
var countriesByPrefix: [String: (Country, Country.CountryCode)] = [:]
for country in countries {
for code in country.countryCodes {
if !code.prefixes.isEmpty {
for prefix in code.prefixes {
countriesByPrefix["\(code.code)\(prefix)"] = (country, code)
}
} else {
countriesByPrefix[code.code] = (country, code)
}
}
}
countryCodesByPrefix = countriesByPrefix
Queue.mainQueue().async {
completion()
}
})
}
@@ -129,9 +153,13 @@ private final class AuthorizationSequenceCountrySelectionNavigationContentNode:
}
public final class AuthorizationSequenceCountrySelectionController: ViewController {
static func countries() -> [Country] {
return countryCodes
}
public static func lookupCountryNameById(_ id: String, strings: PresentationStrings) -> String? {
for country in countryCodes {
if id == country.code {
for country in self.countries() {
if id == country.id {
let locale = localeWithStrings(strings)
if let countryName = locale.localizedString(forRegionCode: id) {
return countryName
@@ -142,25 +170,73 @@ public final class AuthorizationSequenceCountrySelectionController: ViewControll
}
return nil
}
static func lookupCountryById(_ id: String) -> Country? {
return countryCodes.first { $0.id == id }
}
public static func lookupCountryIdByNumber(_ number: String, preferredCountries: [String: String]) -> (Country, Country.CountryCode)? {
var results: [(Country, Country.CountryCode)]? = nil
if number.count == 1, let preferredCountryId = preferredCountries[number], let country = lookupCountryById(preferredCountryId), let code = country.countryCodes.first {
return (country, code)
}
for i in 0..<number.count {
let prefix = String(number.prefix(number.count - i))
if let country = countryCodesByPrefix[prefix] {
if var currentResults = results {
if let result = currentResults.first, result.1.code.count > country.1.code.count {
break
} else {
currentResults.append(country)
}
} else {
results = [country]
}
}
}
if let results = results {
if !preferredCountries.isEmpty, let (_, code) = results.first {
if let preferredCountry = preferredCountries[code.code] {
for (country, code) in results {
if country.id == preferredCountry {
return (country, code)
}
}
}
}
return results.first
} else {
return nil
}
}
public static func lookupCountryIdByCode(_ code: Int) -> String? {
for country in countryCodes {
for country in self.countries() {
for countryCode in country.countryCodes {
if countryCode.code == "\(code)" {
return country.code
return country.id
}
}
}
return nil
}
public static func lookupPatternByCode(_ code: Int) -> String? {
for country in countryCodes {
for countryCode in country.countryCodes {
if countryCode.code == "\(code)" {
return countryCode.patterns.first
public static func lookupPatternByNumber(_ number: String, preferredCountries: [String: String]) -> String? {
if let (_, code) = lookupCountryIdByNumber(number, preferredCountries: preferredCountries), !code.patterns.isEmpty {
var prefixes: [String: String] = [:]
for pattern in code.patterns {
let cleanPattern = pattern.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "X", with: "")
let cleanPrefix = "\(code.code)\(cleanPattern)"
prefixes[cleanPrefix] = pattern
}
for i in 0..<number.count {
let prefix = String(number.prefix(number.count - i))
if let pattern = prefixes[prefix] {
return pattern
}
}
return code.patterns.first
}
return nil
}