Swiftgram/submodules/SettingsUI/Sources/ChangePhoneNumberController.swift
2022-11-27 21:48:44 +04:00

337 lines
19 KiB
Swift

import Foundation
import UIKit
import Display
import AsyncDisplayKit
import TelegramCore
import SwiftSignalKit
import TelegramPresentationData
import ProgressNavigationButtonNode
import AccountContext
import AlertUI
import PresentationDataUtils
import CountrySelectionUI
import PhoneNumberFormat
import CoreTelephony
import MessageUI
import AuthorizationUI
public func ChangePhoneNumberController(context: AccountContext) -> ViewController {
var dismissImpl: (() -> Void)?
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let requestDisposable = MetaDisposable()
let changePhoneDisposable = MetaDisposable()
let controller = AuthorizationSequencePhoneEntryController(sharedContext: context.sharedContext, account: nil, countriesConfiguration: context.currentCountriesConfiguration.with { $0 }, isTestingEnvironment: false, otherAccountPhoneNumbers: (nil, []), network: context.account.network, presentationData: presentationData, openUrl: { _ in }, back: {
dismissImpl?()
})
controller.loginWithNumber = { [weak controller] phoneNumber, _ in
controller?.inProgress = true
requestDisposable.set((context.engine.accountData.requestChangeAccountPhoneNumberVerification(phoneNumber: phoneNumber)
|> deliverOnMainQueue).start(next: { [weak controller] next in
controller?.inProgress = false
var dismissImpl: (() -> Void)?
let codeController = AuthorizationSequenceCodeEntryController(presentationData: presentationData, back: {
dismissImpl?()
})
codeController.loginWithCode = { [weak codeController] code in
codeController?.inProgress = true
changePhoneDisposable.set((context.engine.accountData.requestChangeAccountPhoneNumber(phoneNumber: phoneNumber, phoneCodeHash: next.hash, phoneCode: code)
|> deliverOnMainQueue).start(error: { [weak codeController] error in
if case .invalidCode = error {
codeController?.animateError(text: presentationData.strings.Login_WrongCodeError)
} else {
var resetCode = false
let text: String
switch error {
case .generic:
text = presentationData.strings.Login_UnknownError
case .invalidCode:
resetCode = true
text = presentationData.strings.Login_InvalidCodeError
case .codeExpired:
resetCode = true
text = presentationData.strings.Login_CodeExpiredError
case .limitExceeded:
resetCode = true
text = presentationData.strings.Login_CodeFloodError
}
if resetCode {
codeController?.resetCode()
}
codeController?.present(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}
}, completed: { [weak codeController] in
codeController?.present(OverlayStatusController(theme: presentationData.theme, type: .success), in: .window(.root))
let _ = dismissServerProvidedSuggestion(account: context.account, suggestion: .validatePhoneNumber).start()
if let navigationController = codeController?.navigationController as? NavigationController {
var viewControllers = navigationController.viewControllers
viewControllers.removeAll(where: { c in
if c is AuthorizationSequencePhoneEntryController {
return true
} else if c is AuthorizationSequenceCodeEntryController {
return true
} else {
return false
}
})
navigationController.setViewControllers(viewControllers, animated: true)
}
}))
}
codeController.openFragment = { url in
context.sharedContext.applicationBindings.openUrl(url)
}
codeController.updateData(number: formatPhoneNumber(context: context, number: phoneNumber), email: nil, codeType: next.type, nextType: nil, timeout: next.timeout, termsOfService: nil)
dismissImpl = { [weak codeController] in
codeController?.dismiss()
}
controller?.push(codeController)
}, error: { [weak controller] error in
controller?.inProgress = false
let text: String
var actions: [TextAlertAction] = []
switch error {
case .limitExceeded:
text = presentationData.strings.Login_CodeFloodError
actions.append(TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {}))
case .invalidPhoneNumber:
text = presentationData.strings.Login_InvalidPhoneError
actions.append(TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {}))
case .phoneNumberOccupied:
text = presentationData.strings.ChangePhone_ErrorOccupied(formatPhoneNumber(context: context, number: phoneNumber)).string
actions.append(TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {}))
case .phoneBanned:
text = presentationData.strings.Login_PhoneBannedError
actions.append(TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {}))
actions.append(TextAlertAction(type: .genericAction, title: presentationData.strings.Login_PhoneNumberHelp, action: { [weak controller] in
let formattedNumber = formatPhoneNumber(context: context, number: phoneNumber)
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
let systemVersion = UIDevice.current.systemVersion
let locale = Locale.current.identifier
let carrier = CTCarrier()
let mnc = carrier.mobileNetworkCode ?? "none"
if MFMailComposeViewController.canSendMail() {
let composeController = MFMailComposeViewController()
composeController.setToRecipients(["login@stel.com"])
composeController.setSubject(presentationData.strings.Login_PhoneBannedEmailSubject(formattedNumber).string)
composeController.setMessageBody(presentationData.strings.Login_PhoneBannedEmailBody(formattedNumber, appVersion, systemVersion, locale, mnc).string, isHTML: false)
composeController.mailComposeDelegate = controller
controller?.view.window?.rootViewController?.present(composeController, animated: true, completion: nil)
} else {
controller?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.Login_EmailNotConfiguredError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}
}))
case .generic:
text = presentationData.strings.Login_UnknownError
actions.append(TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {}))
}
controller?.present(textAlertController(context: context, title: nil, text: text, actions: actions), in: .window(.root))
}))
}
dismissImpl = { [weak controller] in
controller?.dismiss()
}
Queue.mainQueue().justDispatch {
controller.updateData(countryCode: AuthorizationSequenceController.defaultCountryCode(), countryName: nil, number: "")
controller.updateCountryCode()
}
return controller
}
//public final class ChangePhoneNumberController: ViewController, MFMailComposeViewControllerDelegate {
// private var controllerNode: ChangePhoneNumberControllerNode {
// return self.displayNode as! ChangePhoneNumberControllerNode
// }
//
// private let context: AccountContext
//
// private var currentData: (Int32, String?, String)?
// private let requestDisposable = MetaDisposable()
//
// var inProgress: Bool = false {
// didSet {
// if self.inProgress {
// let item = UIBarButtonItem(customDisplayNode: ProgressNavigationButtonNode(color: self.presentationData.theme.rootController.navigationBar.accentTextColor))
// self.navigationItem.rightBarButtonItem = item
// } else {
// self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.nextPressed))
// }
// self.controllerNode.inProgress = self.inProgress
// }
// }
// var loginWithNumber: ((String) -> Void)?
//
// private let hapticFeedback = HapticFeedback()
//
// private var presentationData: PresentationData
//
// public init(context: AccountContext) {
// self.context = context
// self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
//
// super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData))
//
// self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
// self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
//
// self.title = self.presentationData.strings.ChangePhoneNumberNumber_Title
// self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.nextPressed))
// self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
// }
//
// required init(coder aDecoder: NSCoder) {
// fatalError("init(coder:) has not been implemented")
// }
//
// deinit {
// self.requestDisposable.dispose()
// }
//
// func updateData(countryCode: Int32, countryName: String, number: String) {
// if self.currentData == nil || self.currentData! != (countryCode, countryName, number) {
// self.currentData = (countryCode, countryName, number)
// if self.isNodeLoaded {
// self.controllerNode.codeAndNumber = (countryCode, countryName, number)
// }
// }
// }
//
// override public func loadDisplayNode() {
// self.displayNode = ChangePhoneNumberControllerNode(presentationData: self.presentationData)
// self.displayNodeDidLoad()
// self.controllerNode.selectCountryCode = { [weak self] in
// if let strongSelf = self {
// let controller = AuthorizationSequenceCountrySelectionController(strings: strongSelf.presentationData.strings, theme: strongSelf.presentationData.theme)
// controller.completeWithCountryCode = { code, name in
// if let strongSelf = self {
// strongSelf.updateData(countryCode: Int32(code), countryName: name, number: strongSelf.controllerNode.codeAndNumber.2)
// strongSelf.controllerNode.activateInput()
// }
// }
// strongSelf.controllerNode.view.endEditing(true)
// strongSelf.push(controller)
// }
// }
//
// loadServerCountryCodes(accountManager: self.context.sharedContext.accountManager, engine: self.context.engine, completion: { [weak self] in
// if let strongSelf = self {
// strongSelf.controllerNode.updateCountryCode()
// }
// })
//
// self.navigationBar?.updateBackgroundAlpha(0.0, transition: .immediate)
// }
//
// override public func viewWillAppear(_ animated: Bool) {
// super.viewWillAppear(animated)
//
// self.controllerNode.activateInput()
// }
//
// override public func viewDidAppear(_ animated: Bool) {
// super.viewDidAppear(animated)
//
// self.controllerNode.activateInput()
// }
//
// override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
// super.containerLayoutUpdated(layout, transition: transition)
//
// self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: 0.0, transition: transition)
// }
//
// @objc func nextPressed() {
// let (code, _, number) = self.controllerNode.codeAndNumber
// var phoneNumber = number
// if let code = code {
// phoneNumber = "\(code)\(phoneNumber)"
// }
// if !number.isEmpty {
// self.inProgress = true
// self.requestDisposable.set((self.context.engine.accountData.requestChangeAccountPhoneNumberVerification(phoneNumber: self.controllerNode.currentNumber) |> deliverOnMainQueue).start(next: { [weak self] next in
// if let strongSelf = self {
// strongSelf.inProgress = false
// (strongSelf.navigationController as? NavigationController)?.pushViewController(changePhoneNumberCodeController(context: strongSelf.context, phoneNumber: strongSelf.controllerNode.currentNumber, codeData: next))
// }
// }, error: { [weak self] error in
// if let strongSelf = self {
// strongSelf.inProgress = false
//
// let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
//
// let text: String
// var actions: [TextAlertAction] = []
// switch error {
// case .limitExceeded:
// text = presentationData.strings.Login_CodeFloodError
// actions.append(TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {}))
// case .invalidPhoneNumber:
// text = presentationData.strings.Login_InvalidPhoneError
// actions.append(TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {}))
// case .phoneNumberOccupied:
// text = presentationData.strings.ChangePhone_ErrorOccupied(formatPhoneNumber(context: strongSelf.context, number: phoneNumber)).string
// actions.append(TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {}))
// case .phoneBanned:
// text = presentationData.strings.Login_PhoneBannedError
// actions.append(TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_OK, action: {}))
// actions.append(TextAlertAction(type: .genericAction, title: presentationData.strings.Login_PhoneNumberHelp, action: { [weak self] in
// guard let strongSelf = self else {
// return
// }
// let formattedNumber = formatPhoneNumber(context: strongSelf.context, number: number)
// let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
// let systemVersion = UIDevice.current.systemVersion
// let locale = Locale.current.identifier
// let carrier = CTCarrier()
// let mnc = carrier.mobileNetworkCode ?? "none"
//
// strongSelf.presentEmailComposeController(address: "login@stel.com", subject: presentationData.strings.Login_PhoneBannedEmailSubject(formattedNumber).string, body: presentationData.strings.Login_PhoneBannedEmailBody(formattedNumber, appVersion, systemVersion, locale, mnc).string)
// }))
// case .generic:
// text = presentationData.strings.Login_UnknownError
// actions.append(TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {}))
// }
//
// strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: actions), in: .window(.root))
// }
// }))
// } else {
// self.hapticFeedback.error()
// self.controllerNode.animateError()
// }
// }
//
// private func presentEmailComposeController(address: String, subject: String, body: String) {
// if MFMailComposeViewController.canSendMail() {
// let composeController = MFMailComposeViewController()
// composeController.setToRecipients([address])
// composeController.setSubject(subject)
// composeController.setMessageBody(body, isHTML: false)
// composeController.mailComposeDelegate = self
//
// self.view.window?.rootViewController?.present(composeController, animated: true, completion: nil)
// } else {
// self.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: self.presentationData.strings.Login_EmailNotConfiguredError, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
// }
// }
//
// public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
// controller.dismiss(animated: true, completion: nil)
// }
//}