mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Improve country code extraction
Use new formatting in phone number change section too
This commit is contained in:
parent
b901cdfb0d
commit
8d89ad6a38
@ -152,6 +152,18 @@ private final class AuthorizationSequenceCountrySelectionNavigationContentNode:
|
||||
}
|
||||
}
|
||||
|
||||
private func removePlus(_ text: String?) -> String {
|
||||
var result = ""
|
||||
if let text = text {
|
||||
for c in text {
|
||||
if c != "+" {
|
||||
result += String(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public final class AuthorizationSequenceCountrySelectionController: ViewController {
|
||||
static func countries() -> [Country] {
|
||||
return countryCodes
|
||||
@ -176,6 +188,7 @@ public final class AuthorizationSequenceCountrySelectionController: ViewControll
|
||||
}
|
||||
|
||||
public static func lookupCountryIdByNumber(_ number: String, preferredCountries: [String: String]) -> (Country, Country.CountryCode)? {
|
||||
let number = removePlus(number)
|
||||
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)
|
||||
|
@ -1,6 +1,29 @@
|
||||
import Foundation
|
||||
import AppBundle
|
||||
|
||||
public func emojiFlagForISOCountryCode(_ countryCode: String) -> String {
|
||||
if countryCode.count != 2 {
|
||||
return ""
|
||||
}
|
||||
|
||||
if countryCode == "XG" {
|
||||
return "🛰️"
|
||||
} else if countryCode == "XV" {
|
||||
return "🌍"
|
||||
}
|
||||
|
||||
if ["YL"].contains(countryCode) {
|
||||
return ""
|
||||
}
|
||||
|
||||
let base : UInt32 = 127397
|
||||
var s = ""
|
||||
for v in countryCode.unicodeScalars {
|
||||
s.unicodeScalars.append(UnicodeScalar(base + v.value)!)
|
||||
}
|
||||
return String(s)
|
||||
}
|
||||
|
||||
private func loadCountriesInfo() -> [(Int, String, String)] {
|
||||
guard let filePath = getAppBundle().path(forResource: "PhoneCountries", ofType: "txt") else {
|
||||
return []
|
||||
|
@ -166,6 +166,7 @@ public final class PhoneInputNode: ASDisplayNode, UITextFieldDelegate {
|
||||
public var returnAction: (() -> Void)?
|
||||
|
||||
private let phoneFormatter = InteractivePhoneFormatter()
|
||||
public var customFormatter: ((String) -> String?)?
|
||||
|
||||
public var mask: NSAttributedString? {
|
||||
didSet {
|
||||
@ -180,7 +181,7 @@ public final class PhoneInputNode: ASDisplayNode, UITextFieldDelegate {
|
||||
if let text = self.numberField.textField.text {
|
||||
mutableMask.replaceCharacters(in: NSRange(location: 0, length: min(text.count, mask.string.count)), with: text)
|
||||
}
|
||||
mutableMask.addAttribute(.foregroundColor, value: UIColor.clear, range: NSRange(location: 0, length: min(self.numberField.textField.text?.count ?? 0, mask.string.count)))
|
||||
mutableMask.addAttribute(.foregroundColor, value: UIColor.clear, range: NSRange(location: 0, length: min(self.numberField.textField.text?.count ?? 0, mutableMask.string.count)))
|
||||
mutableMask.addAttribute(.kern, value: 1.6, range: NSRange(location: 0, length: mask.string.count))
|
||||
self.placeholderNode.attributedText = mutableMask
|
||||
} else {
|
||||
@ -265,7 +266,12 @@ public final class PhoneInputNode: ASDisplayNode, UITextFieldDelegate {
|
||||
}
|
||||
|
||||
private func updateNumber(_ inputText: String, tryRestoringInputPosition: Bool = true, forceNotifyCountryCodeUpdated: Bool = false) {
|
||||
let (regionPrefix, text) = self.phoneFormatter.updateText(inputText)
|
||||
var (regionPrefix, text) = self.phoneFormatter.updateText(inputText)
|
||||
|
||||
if let customFormatter = self.customFormatter, let customRegionPrefix = customFormatter(inputText) {
|
||||
regionPrefix = "+\(customRegionPrefix)"
|
||||
text = inputText
|
||||
}
|
||||
|
||||
var realRegionPrefix: String
|
||||
var numberText: String
|
||||
|
@ -87,6 +87,12 @@ final class ChangePhoneNumberController: ViewController {
|
||||
strongSelf.push(controller)
|
||||
}
|
||||
}
|
||||
|
||||
loadServerCountryCodes(accountManager: self.context.sharedContext.accountManager, network: self.context.account.network, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controllerNode.updateCountryCode()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
@ -91,6 +91,8 @@ final class ChangePhoneNumberControllerNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
var preferredCountryIdForCode: [String: String] = [:]
|
||||
|
||||
var selectCountryCode: (() -> Void)?
|
||||
|
||||
var inProgress: Bool = false {
|
||||
@ -155,9 +157,43 @@ final class ChangePhoneNumberControllerNode: ASDisplayNode {
|
||||
|
||||
self.countryButton.addTarget(self, action: #selector(self.countryPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
let processNumberChange: (String) -> Bool = { [weak self] number in
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
if let (country, _) = AuthorizationSequenceCountrySelectionController.lookupCountryIdByNumber(number, preferredCountries: strongSelf.preferredCountryIdForCode) {
|
||||
let flagString = emojiFlagForISOCountryCode(country.id)
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(country.id, strings: strongSelf.presentationData.strings) ?? country.name
|
||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(17.0), with: strongSelf.presentationData.theme.list.itemPrimaryTextColor, for: [])
|
||||
|
||||
let maskFont = Font.with(size: 20.0, design: .regular, traits: [.monospacedNumbers])
|
||||
if let mask = AuthorizationSequenceCountrySelectionController.lookupPatternByNumber(number, preferredCountries: strongSelf.preferredCountryIdForCode).flatMap({ NSAttributedString(string: $0, font: maskFont, textColor: strongSelf.presentationData.theme.list.itemPlaceholderTextColor) }) {
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = nil
|
||||
strongSelf.phoneInputNode.mask = mask
|
||||
} else {
|
||||
strongSelf.phoneInputNode.mask = nil
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strongSelf.presentationData.strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: strongSelf.presentationData.theme.list.itemPlaceholderTextColor)
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
self.phoneInputNode.numberTextUpdated = { [weak self] number in
|
||||
if let strongSelf = self {
|
||||
let _ = processNumberChange(strongSelf.phoneInputNode.number)
|
||||
}
|
||||
}
|
||||
|
||||
self.phoneInputNode.countryCodeUpdated = { [weak self] code, name in
|
||||
if let strongSelf = self {
|
||||
if let code = Int(code), let name = name, let countryName = countryCodeAndIdToName[CountryCodeAndId(code: code, id: name)] {
|
||||
if let name = name {
|
||||
strongSelf.preferredCountryIdForCode[code] = name
|
||||
}
|
||||
|
||||
if processNumberChange(strongSelf.phoneInputNode.number) {
|
||||
} else if let code = Int(code), let name = name, let countryName = countryCodeAndIdToName[CountryCodeAndId(code: code, id: name)] {
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(name, strings: strongSelf.presentationData.strings) ?? countryName
|
||||
strongSelf.countryButton.setTitle(localizedName, with: Font.regular(17.0), with: strongSelf.presentationData.theme.list.itemPrimaryTextColor, for: [])
|
||||
} else if let code = Int(code), let (_, countryName) = countryCodeToIdAndName[code] {
|
||||
@ -168,6 +204,14 @@ final class ChangePhoneNumberControllerNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
self.phoneInputNode.customFormatter = { number in
|
||||
if let (_, code) = AuthorizationSequenceCountrySelectionController.lookupCountryIdByNumber(number, preferredCountries: [:]) {
|
||||
return code.code
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var countryId: String? = nil
|
||||
let networkInfo = CTTelephonyNetworkInfo()
|
||||
if let carrier = networkInfo.subscriberCellularProvider {
|
||||
@ -193,6 +237,10 @@ final class ChangePhoneNumberControllerNode: ASDisplayNode {
|
||||
self.phoneInputNode.number = "+\(countryCodeAndId.0)"
|
||||
}
|
||||
|
||||
func updateCountryCode() {
|
||||
self.phoneInputNode.codeAndNumber = self.codeAndNumber
|
||||
}
|
||||
|
||||
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
var insets = layout.insets(options: [.statusBar, .input])
|
||||
insets.left = layout.safeInsets.left
|
||||
|
@ -13,24 +13,6 @@ import SwiftSignalKit
|
||||
import Postbox
|
||||
import AccountContext
|
||||
|
||||
private func emojiFlagForISOCountryCode(_ countryCode: NSString) -> String {
|
||||
if countryCode.length != 2 {
|
||||
return ""
|
||||
}
|
||||
|
||||
let base: UInt32 = 127462 - 65
|
||||
let first: UInt32 = base + UInt32(countryCode.character(at: 0))
|
||||
let second: UInt32 = base + UInt32(countryCode.character(at: 1))
|
||||
|
||||
var data = Data()
|
||||
data.count = 8
|
||||
data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt32>) -> Void in
|
||||
bytes[0] = first
|
||||
bytes[1] = second
|
||||
}
|
||||
return String(data: data, encoding: String.Encoding.utf32LittleEndian) ?? ""
|
||||
}
|
||||
|
||||
private final class PhoneAndCountryNode: ASDisplayNode {
|
||||
let strings: PresentationStrings
|
||||
let countryButton: ASButtonNode
|
||||
@ -128,25 +110,12 @@ private final class PhoneAndCountryNode: ASDisplayNode {
|
||||
|
||||
self.countryButton.addTarget(self, action: #selector(self.countryPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
func removePlus(_ text: String?) -> String {
|
||||
var result = ""
|
||||
if let text = text {
|
||||
for c in text {
|
||||
if c != "+" {
|
||||
result += String(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let processNumberChange: (String) -> Bool = { [weak self] number in
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
let number = removePlus(number)
|
||||
if let (country, _) = AuthorizationSequenceCountrySelectionController.lookupCountryIdByNumber(number, preferredCountries: strongSelf.preferredCountryIdForCode) {
|
||||
let flagString = emojiFlagForISOCountryCode(country.id as NSString)
|
||||
let flagString = emojiFlagForISOCountryCode(country.id)
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(country.id, strings: strongSelf.strings) ?? country.name
|
||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(20.0), with: theme.list.itemPrimaryTextColor, for: [])
|
||||
|
||||
@ -178,12 +147,12 @@ private final class PhoneAndCountryNode: ASDisplayNode {
|
||||
|
||||
if processNumberChange(strongSelf.phoneInputNode.number) {
|
||||
} else if let code = Int(code), let name = name, let countryName = countryCodeAndIdToName[CountryCodeAndId(code: code, id: name)] {
|
||||
let flagString = emojiFlagForISOCountryCode(name as NSString)
|
||||
let flagString = emojiFlagForISOCountryCode(name)
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(name, strings: strongSelf.strings) ?? countryName
|
||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(20.0), with: theme.list.itemPrimaryTextColor, for: [])
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||
} else if let code = Int(code), let (countryId, countryName) = countryCodeToIdAndName[code] {
|
||||
let flagString = emojiFlagForISOCountryCode(countryId as NSString)
|
||||
let flagString = emojiFlagForISOCountryCode(countryId)
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(countryId, strings: strongSelf.strings) ?? countryName
|
||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(20.0), with: theme.list.itemPrimaryTextColor, for: [])
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||
@ -195,6 +164,14 @@ private final class PhoneAndCountryNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
self.phoneInputNode.customFormatter = { number in
|
||||
if let (_, code) = AuthorizationSequenceCountrySelectionController.lookupCountryIdByNumber(number, preferredCountries: [:]) {
|
||||
return code.code
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
self.phoneInputNode.number = "+1"
|
||||
self.phoneInputNode.returnAction = { [weak self] in
|
||||
self?.checkPhone?()
|
||||
@ -366,10 +343,6 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||
self.tokenEventsDisposable.dispose()
|
||||
}
|
||||
|
||||
func updateCountryCode() {
|
||||
self.phoneAndCountryNode.phoneInputNode.codeAndNumber = self.codeAndNumber
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
@ -379,6 +352,10 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||
#endif
|
||||
}
|
||||
|
||||
func updateCountryCode() {
|
||||
self.phoneAndCountryNode.phoneInputNode.codeAndNumber = self.codeAndNumber
|
||||
}
|
||||
|
||||
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
var insets = layout.insets(options: [])
|
||||
insets.top = navigationBarHeight
|
||||
|
Loading…
x
Reference in New Issue
Block a user