mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Update API
This commit is contained in:
@@ -220,7 +220,7 @@ public final class AuthorizationSequenceCodeEntryController: ViewController {
|
||||
minimalCodeLength = Int(length)
|
||||
case let .firebase(_, length):
|
||||
minimalCodeLength = Int(length)
|
||||
case .flashCall, .emailSetupRequired:
|
||||
case .flashCall, .emailSetupRequired, .word, .phrase:
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
private var signInWithAppleButton: UIControl?
|
||||
private let proceedNode: SolidRoundedButtonNode
|
||||
|
||||
private let textField: TextFieldNode
|
||||
private let textSeparatorNode: ASDisplayNode
|
||||
|
||||
private let codeInputView: CodeInputView
|
||||
private let errorTextNode: ImmediateTextNode
|
||||
|
||||
@@ -64,7 +67,12 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
var email: String?
|
||||
|
||||
var currentCode: String {
|
||||
return self.codeInputView.text
|
||||
switch self.codeType {
|
||||
case .word, .phrase:
|
||||
return self.textField.textField.text ?? ""
|
||||
default:
|
||||
return self.codeInputView.text
|
||||
}
|
||||
}
|
||||
|
||||
var loginWithCode: ((String) -> Void)?
|
||||
@@ -81,6 +89,19 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
var inProgress: Bool = false {
|
||||
didSet {
|
||||
self.codeInputView.alpha = self.inProgress ? 0.6 : 1.0
|
||||
|
||||
switch self.codeType {
|
||||
case .word, .phrase:
|
||||
if self.inProgress != oldValue {
|
||||
if self.inProgress {
|
||||
self.proceedNode.transitionToProgress()
|
||||
} else {
|
||||
self.proceedNode.transitionFromProgress()
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +172,28 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
self.codeInputView.textField.keyboardType = .numberPad
|
||||
}
|
||||
|
||||
self.textSeparatorNode = ASDisplayNode()
|
||||
self.textSeparatorNode.isLayerBacked = true
|
||||
self.textSeparatorNode.backgroundColor = self.theme.list.itemPlainSeparatorColor
|
||||
|
||||
self.textField = TextFieldNode()
|
||||
self.textField.textField.font = Font.regular(20.0)
|
||||
self.textField.textField.textColor = self.theme.list.itemPrimaryTextColor
|
||||
self.textField.textField.textAlignment = .natural
|
||||
self.textField.textField.autocorrectionType = .yes
|
||||
self.textField.textField.autocorrectionType = .no
|
||||
self.textField.textField.spellCheckingType = .yes
|
||||
self.textField.textField.spellCheckingType = .no
|
||||
self.textField.textField.autocapitalizationType = .none
|
||||
self.textField.textField.keyboardType = .default
|
||||
if #available(iOSApplicationExtension 10.0, iOS 10.0, *) {
|
||||
self.textField.textField.textContentType = UITextContentType(rawValue: "")
|
||||
}
|
||||
self.textField.textField.returnKeyType = .default
|
||||
self.textField.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||
self.textField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
||||
self.textField.textField.tintColor = self.theme.list.itemAccentColor
|
||||
|
||||
self.errorTextNode = ImmediateTextNode()
|
||||
self.errorTextNode.alpha = 0.0
|
||||
self.errorTextNode.displaysAsynchronously = false
|
||||
@@ -175,11 +218,12 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
self.signInWithAppleButton?.isHidden = true
|
||||
(self.signInWithAppleButton as? ASAuthorizationAppleIDButton)?.cornerRadius = 11
|
||||
}
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_OpenFragment, theme: SolidRoundedButtonTheme(backgroundColor: UIColor(rgb: 0x37475a), foregroundColor: .white), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||
self.proceedNode.progressType = .embedded
|
||||
self.proceedNode.isHidden = true
|
||||
self.proceedNode.iconSpacing = 4.0
|
||||
self.proceedNode.animationSize = CGSize(width: 36.0, height: 36.0)
|
||||
self.proceedNode.isEnabled = false
|
||||
|
||||
super.init()
|
||||
|
||||
@@ -189,7 +233,11 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
|
||||
self.backgroundColor = self.theme.list.plainBackgroundColor
|
||||
|
||||
self.textField.textField.delegate = self
|
||||
|
||||
self.addSubnode(self.codeInputView)
|
||||
self.addSubnode(self.textSeparatorNode)
|
||||
self.addSubnode(self.textField)
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.titleActivateAreaNode)
|
||||
self.addSubnode(self.titleIconNode)
|
||||
@@ -208,9 +256,11 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.textChanged(text: strongSelf.codeInputView.text)
|
||||
strongSelf.codeChanged(text: strongSelf.codeInputView.text)
|
||||
}
|
||||
|
||||
self.textField.textField.addTarget(self, action: #selector(self.textDidChange), for: .editingChanged)
|
||||
|
||||
self.codeInputView.longPressed = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@@ -261,7 +311,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
|
||||
func updateCode(_ code: String) {
|
||||
self.codeInputView.text = code
|
||||
self.textChanged(text: code)
|
||||
self.codeChanged(text: code)
|
||||
|
||||
if let codeLength = self.requiredCodeLength, code.count == Int(codeLength) {
|
||||
self.loginWithCode?(code)
|
||||
@@ -401,6 +451,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
|
||||
var animationName = "IntroMessage"
|
||||
var animationPlaybackMode: AnimatedStickerPlaybackMode = .once
|
||||
var textFieldPlaceholder = ""
|
||||
if let codeType = self.codeType {
|
||||
switch codeType {
|
||||
case .missedCall:
|
||||
@@ -412,9 +463,20 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterCodeSMSTitle, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
case .fragment:
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterCodeFragmentTitle, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
|
||||
self.proceedNode.title = self.strings.Login_OpenFragment
|
||||
self.proceedNode.updateTheme(SolidRoundedButtonTheme(backgroundColor: UIColor(rgb: 0x37475a), foregroundColor: .white))
|
||||
self.proceedNode.isEnabled = true
|
||||
|
||||
animationName = "IntroFragment"
|
||||
animationPlaybackMode = .count(3)
|
||||
self.proceedNode.animation = "anim_fragment"
|
||||
case .word:
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterWordTitle, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
textFieldPlaceholder = self.strings.Login_EnterWordPlaceholder
|
||||
case .phrase:
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterPhraseTitle, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
textFieldPlaceholder = self.strings.Login_EnterPhrasePlaceholder
|
||||
default:
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterCodeTelegramTitle, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
}
|
||||
@@ -422,14 +484,17 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterCodeTelegramTitle, font: Font.semibold(40.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
}
|
||||
|
||||
self.textField.textField.placeholder = textFieldPlaceholder
|
||||
|
||||
self.titleActivateAreaNode.accessibilityLabel = self.titleNode.attributedText?.string ?? ""
|
||||
|
||||
if let inputHeight = layout.inputHeight {
|
||||
if let codeType = self.codeType, case .email = codeType {
|
||||
switch self.codeType {
|
||||
case .email, .fragment:
|
||||
insets.bottom = max(inputHeight, insets.bottom)
|
||||
} else if let codeType = self.codeType, case .fragment = codeType {
|
||||
insets.bottom = max(inputHeight, insets.bottom)
|
||||
} else {
|
||||
case .word, .phrase:
|
||||
insets.bottom = max(inputHeight, layout.standardKeyboardHeight)
|
||||
default:
|
||||
insets.bottom = max(inputHeight, layout.standardInputHeight)
|
||||
}
|
||||
}
|
||||
@@ -475,6 +540,8 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
codeLength = Int(length)
|
||||
case .emailSetupRequired:
|
||||
codeLength = 6
|
||||
case .word, .phrase:
|
||||
codeLength = 0
|
||||
case .none:
|
||||
codeLength = 6
|
||||
}
|
||||
@@ -498,8 +565,11 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
if layout.size.width > 320.0 {
|
||||
items.append(AuthorizationLayoutItem(node: self.animationNode, size: animationSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 10.0, maxValue: 10.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||
self.animationNode.updateLayout(size: animationSize)
|
||||
self.animationNode.isHidden = false
|
||||
self.animationNode.visibility = true
|
||||
} else {
|
||||
insets.top = navigationBarHeight
|
||||
self.animationNode.isHidden = true
|
||||
}
|
||||
|
||||
var additionalBottomInset: CGFloat = 20.0
|
||||
@@ -550,7 +620,19 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
}
|
||||
}
|
||||
|
||||
items.append(AuthorizationLayoutItem(node: self.codeInputView, size: codeFieldSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 30.0, maxValue: 30.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: canReset || pendingDate != nil ? 0.0 : 104.0, maxValue: canReset ? 0.0 : 104.0)))
|
||||
switch codeType {
|
||||
case .word, .phrase:
|
||||
self.codeInputView.isHidden = true
|
||||
self.textField.isHidden = false
|
||||
self.textSeparatorNode.isHidden = false
|
||||
items.append(AuthorizationLayoutItem(node: self.textField, size: CGSize(width: maximumWidth - 88.0, height: 44.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 18.0, maxValue: 30.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||
items.append(AuthorizationLayoutItem(node: self.textSeparatorNode, size: CGSize(width: maximumWidth - 48.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||
default:
|
||||
self.codeInputView.isHidden = false
|
||||
self.textField.isHidden = true
|
||||
self.textSeparatorNode.isHidden = true
|
||||
items.append(AuthorizationLayoutItem(node: self.codeInputView, size: codeFieldSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 30.0, maxValue: 30.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: canReset || pendingDate != nil ? 0.0 : 104.0, maxValue: canReset ? 0.0 : 104.0)))
|
||||
}
|
||||
|
||||
if canReset {
|
||||
self.resetNode.setAttributedTitle(NSAttributedString(string: self.strings.Login_Email_CantAccess, font: Font.regular(17.0), textColor: self.theme.list.itemAccentColor, paragraphAlignment: .center), for: [])
|
||||
@@ -614,7 +696,29 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
} else {
|
||||
self.signInWithAppleButton?.isHidden = true
|
||||
self.dividerNode.isHidden = true
|
||||
self.proceedNode.isHidden = true
|
||||
|
||||
switch codeType {
|
||||
case .word, .phrase:
|
||||
additionalBottomInset = 120.0
|
||||
|
||||
self.nextOptionButtonNode.isHidden = false
|
||||
items.append(AuthorizationLayoutItem(node: self.nextOptionButtonNode, size: nextOptionSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 50.0, maxValue: 120.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||
if layout.size.width > 320.0 {
|
||||
self.proceedNode.isHidden = false
|
||||
} else {
|
||||
self.proceedNode.isHidden = true
|
||||
}
|
||||
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - proceedSize.width) / 2.0), y: layout.size.height - insets.bottom - proceedSize.height - inset), size: proceedSize)
|
||||
transition.updateFrame(node: self.proceedNode, frame: buttonFrame)
|
||||
case .email:
|
||||
self.nextOptionButtonNode.isHidden = true
|
||||
self.proceedNode.isHidden = true
|
||||
default:
|
||||
self.nextOptionButtonNode.isHidden = false
|
||||
self.proceedNode.isHidden = true
|
||||
items.append(AuthorizationLayoutItem(node: self.nextOptionButtonNode, size: nextOptionSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 50.0, maxValue: 120.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||
}
|
||||
|
||||
if case .email = codeType {
|
||||
self.nextOptionButtonNode.isHidden = true
|
||||
@@ -644,31 +748,58 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
}
|
||||
|
||||
func activateInput() {
|
||||
let _ = self.codeInputView.becomeFirstResponder()
|
||||
switch self.codeType {
|
||||
case .word, .phrase:
|
||||
self.textField.textField.becomeFirstResponder()
|
||||
default:
|
||||
let _ = self.codeInputView.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
|
||||
func animateError() {
|
||||
self.codeInputView.layer.addShakeAnimation()
|
||||
switch self.codeType {
|
||||
case .word, .phrase:
|
||||
self.textField.layer.addShakeAnimation()
|
||||
default:
|
||||
self.codeInputView.layer.addShakeAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
func animateError(text: String) {
|
||||
self.codeInputView.animateError()
|
||||
self.codeInputView.layer.addShakeAnimation(amplitude: -30.0, duration: 0.5, count: 6, decay: true)
|
||||
let errorOriginY: CGFloat
|
||||
let errorOriginOffset: CGFloat
|
||||
switch self.codeType {
|
||||
case .word, .phrase:
|
||||
self.textField.layer.addShakeAnimation()
|
||||
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.15, curve: .easeInOut)
|
||||
transition.updateBackgroundColor(node: self.textSeparatorNode, color: self.theme.list.itemDestructiveColor)
|
||||
errorOriginY = self.textField.frame.maxY
|
||||
errorOriginOffset = 5.0
|
||||
default:
|
||||
self.codeInputView.animateError()
|
||||
self.codeInputView.layer.addShakeAnimation(amplitude: -30.0, duration: 0.5, count: 6, decay: true)
|
||||
errorOriginY = self.codeInputView.frame.maxY
|
||||
errorOriginOffset = 11.0
|
||||
}
|
||||
|
||||
self.errorTextNode.attributedText = NSAttributedString(string: text, font: Font.regular(17.0), textColor: self.theme.list.itemDestructiveColor, paragraphAlignment: .center)
|
||||
self.errorTextNode.attributedText = NSAttributedString(string: text, font: Font.regular(13.0), textColor: self.theme.list.itemDestructiveColor, paragraphAlignment: .center)
|
||||
|
||||
if let (layout, _) = self.layoutArguments {
|
||||
let errorTextSize = self.errorTextNode.updateLayout(CGSize(width: layout.size.width - 48.0, height: .greatestFiniteMagnitude))
|
||||
let yOffset: CGFloat = layout.size.width > 320.0 ? 28.0 : 15.0
|
||||
self.errorTextNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - errorTextSize.width) / 2.0), y: self.codeInputView.frame.maxY + yOffset), size: errorTextSize)
|
||||
let yOffset: CGFloat = layout.size.width > 320.0 ? errorOriginOffset + 13.0 : errorOriginOffset
|
||||
self.errorTextNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - errorTextSize.width) / 2.0), y: errorOriginY + yOffset), size: errorTextSize)
|
||||
}
|
||||
self.errorTextNode.alpha = 1.0
|
||||
self.errorTextNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15)
|
||||
self.errorTextNode.layer.addShakeAnimation(amplitude: -8.0, duration: 0.5, count: 6, decay: true)
|
||||
|
||||
Queue.mainQueue().after(0.85) {
|
||||
Queue.mainQueue().after(1.6) {
|
||||
self.errorTextNode.alpha = 0.0
|
||||
self.errorTextNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15)
|
||||
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.15, curve: .easeInOut)
|
||||
transition.updateBackgroundColor(node: self.textSeparatorNode, color: self.theme.list.itemPlainSeparatorColor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,12 +809,14 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
let values: [NSNumber] = [1.0, 1.1, 1.0]
|
||||
self.codeInputView.layer.animateKeyframes(values: values, duration: 0.4, keyPath: "transform.scale")
|
||||
}
|
||||
|
||||
@objc func codeFieldTextChanged(_ textField: UITextField) {
|
||||
self.textChanged(text: textField.text ?? "")
|
||||
|
||||
@objc private func textDidChange() {
|
||||
let text = self.textField.textField.text ?? ""
|
||||
self.proceedNode.isEnabled = !text.isEmpty
|
||||
self.updateNextEnabled?(!text.isEmpty)
|
||||
}
|
||||
|
||||
private func textChanged(text: String) {
|
||||
|
||||
private func codeChanged(text: String) {
|
||||
self.updateNextEnabled?(!text.isEmpty)
|
||||
if let codeType = self.codeType {
|
||||
var codeLength: Int32?
|
||||
@@ -715,20 +848,36 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
if self.inProgress {
|
||||
return false
|
||||
}
|
||||
var result = ""
|
||||
for c in string {
|
||||
if c.unicodeScalars.count == 1 {
|
||||
let scalar = c.unicodeScalars.first!
|
||||
if scalar >= "0" && scalar <= "9" {
|
||||
result.append(c)
|
||||
|
||||
var updated = textField.text ?? ""
|
||||
updated.replaceSubrange(updated.index(updated.startIndex, offsetBy: range.lowerBound) ..< updated.index(updated.startIndex, offsetBy: range.upperBound), with: string)
|
||||
|
||||
if let codeType = self.codeType {
|
||||
switch codeType {
|
||||
case let .word(startsWith):
|
||||
if let startsWith, startsWith.count == 1, !updated.isEmpty && !updated.hasPrefix(startsWith) {
|
||||
if self.errorTextNode.alpha.isZero {
|
||||
//TODO:localize
|
||||
self.animateError(text: "Incorrect, please try again")
|
||||
}
|
||||
return false
|
||||
}
|
||||
case let .phrase(startsWith):
|
||||
if let startsWith, !updated.isEmpty {
|
||||
let firstWord = updated.components(separatedBy: " ").first ?? ""
|
||||
if !firstWord.isEmpty && !startsWith.hasPrefix(firstWord) {
|
||||
if self.errorTextNode.alpha.isZero {
|
||||
//TODO:localize
|
||||
self.animateError(text: "Incorrect, please try again")
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
if result != string {
|
||||
textField.text = result
|
||||
self.codeFieldTextChanged(textField)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -737,8 +886,15 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
}
|
||||
|
||||
@objc func proceedPressed() {
|
||||
if case let .fragment(url, _) = self.codeType {
|
||||
switch self.codeType {
|
||||
case let .fragment(url, _):
|
||||
self.openFragment?(url)
|
||||
case .word, .phrase:
|
||||
if let text = self.textField.textField.text, !text.isEmpty {
|
||||
self.loginWithCode?(text)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,10 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
}
|
||||
private var didSetReady = false
|
||||
|
||||
fileprivate var engine: TelegramEngineUnauthorized {
|
||||
return TelegramEngineUnauthorized(account: self.account)
|
||||
}
|
||||
|
||||
public init(sharedContext: SharedAccountContext, account: UnauthorizedAccount, otherAccountPhoneNumbers: ((String, AccountRecordId, Bool)?, [(String, AccountRecordId, Bool)]), presentationData: PresentationData, openUrl: @escaping (String) -> Void, apiId: Int32, apiHash: String, authorizationCompleted: @escaping () -> Void) {
|
||||
self.sharedContext = sharedContext
|
||||
self.account = account
|
||||
@@ -74,7 +78,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
|
||||
super.init(mode: .single, theme: NavigationControllerTheme(statusBar: navigationStatusBar, navigationBar: AuthorizationSequenceController.navigationBarTheme(presentationData.theme), emptyAreaColor: .black), isFlat: true)
|
||||
|
||||
self.stateDisposable = (TelegramEngineUnauthorized(account: self.account).auth.state()
|
||||
self.stateDisposable = (self.engine.auth.state()
|
||||
|> map { state -> InnerState in
|
||||
if case .authorized = state {
|
||||
return .authorized
|
||||
@@ -127,7 +131,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: isTestingEnvironment, masterDatacenterId: masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: isTestingEnvironment, masterDatacenterId: masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,7 +161,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
transaction.removeAuth()
|
||||
}).startStandalone()
|
||||
} else {
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
})
|
||||
if let splashController = splashController {
|
||||
@@ -299,9 +303,6 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
if c.data?.2 == type {
|
||||
currentController = c
|
||||
}
|
||||
// else if case let .email(_, _, _, newPendingDate, _, _) = type, let previousType = c.data?.2, case let .email(_, _, _, previousPendingDate, _, _) = previousType, newPendingDate != nil && previousPendingDate == nil {
|
||||
// currentController = c
|
||||
// }
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -315,7 +316,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
controller.retryResetEmail = { [weak self] in
|
||||
if let self {
|
||||
@@ -381,7 +382,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
case .codeExpired:
|
||||
text = self.presentationData.strings.Login_CodeExpired
|
||||
let account = self.account
|
||||
let _ = TelegramEngineUnauthorized(account: self.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = self.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
|
||||
controller.presentInGlobalOverlay(standardTextAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]))
|
||||
@@ -430,7 +431,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
case .codeExpired:
|
||||
text = strongSelf.presentationData.strings.Login_CodeExpired
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
case .timeout:
|
||||
text = strongSelf.presentationData.strings.Login_NetworkError
|
||||
case .invalidEmailToken:
|
||||
@@ -490,7 +491,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
return
|
||||
}
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
})]), on: .root, blockInteraction: false, completion: {})
|
||||
})
|
||||
], actionLayout: .vertical, dismissOnOutsideTap: true)
|
||||
@@ -522,7 +523,14 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
controller.inProgress = false
|
||||
|
||||
if case .invalidCode = error {
|
||||
controller.animateError(text: strongSelf.presentationData.strings.Login_WrongCodeError)
|
||||
let text: String
|
||||
switch type {
|
||||
case .word, .phrase:
|
||||
text = strongSelf.presentationData.strings.Login_WrongPhraseError
|
||||
default:
|
||||
text = strongSelf.presentationData.strings.Login_WrongCodeError
|
||||
}
|
||||
controller.animateError(text: text)
|
||||
} else {
|
||||
var resetCode = false
|
||||
let text: String
|
||||
@@ -538,7 +546,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
case .codeExpired:
|
||||
text = strongSelf.presentationData.strings.Login_CodeExpired
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
case .invalidEmailToken:
|
||||
text = strongSelf.presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .invalidEmailAddress:
|
||||
@@ -562,7 +570,11 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
if let strongSelf = self {
|
||||
if nextType == nil {
|
||||
if let controller {
|
||||
AuthorizationSequenceController.presentDidNotGetCodeUI(controller: controller, presentationData: strongSelf.presentationData, number: number)
|
||||
let carrier = CTCarrier()
|
||||
let mnc = carrier.mobileNetworkCode ?? "none"
|
||||
let _ = strongSelf.engine.auth.reportMissingCode(phoneNumber: number, phoneCodeHash: phoneCodeHash, mnc: mnc).start()
|
||||
|
||||
AuthorizationSequenceController.presentDidNotGetCodeUI(controller: controller, presentationData: strongSelf.presentationData, phoneNumber: number, mnc: mnc)
|
||||
}
|
||||
} else {
|
||||
controller?.inProgress = true
|
||||
@@ -607,7 +619,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
controller.reset = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
}
|
||||
controller.signInWithApple = { [weak self] in
|
||||
@@ -659,7 +671,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
}
|
||||
controller.proceedWithEmail = { [weak self, weak controller] email in
|
||||
@@ -783,7 +795,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
case .codeExpired:
|
||||
text = strongSelf.presentationData.strings.Login_CodeExpired
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
case .invalidEmailToken:
|
||||
text = strongSelf.presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .invalidEmailAddress:
|
||||
@@ -832,7 +844,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
controller.loginWithPassword = { [weak self, weak controller] password in
|
||||
if let strongSelf = self {
|
||||
@@ -864,19 +876,19 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
controller.forgot = { [weak self, weak controller] in
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
strongController.inProgress = true
|
||||
strongSelf.actionDisposable.set((TelegramEngineUnauthorized(account: strongSelf.account).auth.requestTwoStepVerificationPasswordRecoveryCode()
|
||||
strongSelf.actionDisposable.set((strongSelf.engine.auth.requestTwoStepVerificationPasswordRecoveryCode()
|
||||
|> deliverOnMainQueue).startStrict(next: { pattern in
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
strongController.inProgress = false
|
||||
|
||||
let _ = (TelegramEngineUnauthorized(account: strongSelf.account).auth.state()
|
||||
let _ = (strongSelf.engine.auth.state()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).startStandalone(next: { state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if case let .unauthorized(state) = state, case let .passwordEntry(hint, number, code, _, syncContacts) = state.contents {
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern, syncContacts: syncContacts))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern, syncContacts: syncContacts))).startStandalone()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -937,7 +949,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
if let currentController = currentController {
|
||||
controller = currentController
|
||||
} else {
|
||||
controller = TwoFactorDataInputScreen(sharedContext: self.sharedContext, engine: .unauthorized(TelegramEngineUnauthorized(account: self.account)), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .notAuthorized(syncContacts: syncContacts), doneText: self.presentationData.strings.TwoFactorSetup_Done_Action), stateUpdated: { _ in
|
||||
controller = TwoFactorDataInputScreen(sharedContext: self.sharedContext, engine: .unauthorized(self.engine), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .notAuthorized(syncContacts: syncContacts), doneText: self.presentationData.strings.TwoFactorSetup_Done_Action), stateUpdated: { _ in
|
||||
}, presentation: .default)
|
||||
}
|
||||
controller.passwordRecoveryFailed = { [weak self] in
|
||||
@@ -945,14 +957,14 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (TelegramEngineUnauthorized(account: strongSelf.account).auth.state()
|
||||
let _ = (strongSelf.engine.auth.state()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).startStandalone(next: { state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if case let .unauthorized(state) = state, case let .passwordRecovery(hint, number, code, _, syncContacts) = state.contents {
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true, syncContacts: syncContacts))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true, syncContacts: syncContacts))).startStandalone()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -977,7 +989,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
})
|
||||
controller.reset = { [weak self, weak controller] in
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
@@ -1011,7 +1023,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
controller.logout = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let account = strongSelf.account
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).startStandalone()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1037,7 +1049,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
}
|
||||
let countryCode = AuthorizationSequenceController.defaultCountryCode()
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
let _ = strongSelf.engine.auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).startStandalone()
|
||||
}, displayCancel: displayCancel)
|
||||
controller.openUrl = { [weak self] url in
|
||||
guard let self else {
|
||||
@@ -1056,7 +1068,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
|
||||
let avatarVideo: Signal<UploadedPeerPhotoData?, NoError>?
|
||||
if let avatarAsset = avatarAsset as? AVAsset {
|
||||
let account = strongSelf.account
|
||||
let engine = strongSelf.engine
|
||||
avatarVideo = Signal<TelegramMediaResource?, NoError> { subscriber in
|
||||
let entityRenderer: LegacyPaintEntityRenderer? = avatarAdjustments.flatMap { adjustments in
|
||||
if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
|
||||
@@ -1075,7 +1087,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
if stat(result.fileURL.path, &value) == 0 {
|
||||
if let data = try? Data(contentsOf: result.fileURL) {
|
||||
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||
account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
engine.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
subscriber.putNext(resource)
|
||||
|
||||
EngineTempBox.shared.dispose(tempFile)
|
||||
@@ -1096,7 +1108,7 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
}
|
||||
|> mapToSignal { resource -> Signal<UploadedPeerPhotoData?, NoError> in
|
||||
if let resource = resource {
|
||||
return TelegramEngineUnauthorized(account: account).auth.uploadedPeerVideo(resource: resource) |> map(Optional.init)
|
||||
return engine.auth.uploadedPeerVideo(resource: resource) |> map(Optional.init)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
@@ -1320,9 +1332,14 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
return countryCode
|
||||
}
|
||||
|
||||
public static func presentDidNotGetCodeUI(controller: ViewController, presentationData: PresentationData, number: String) {
|
||||
public static func presentDidNotGetCodeUI(
|
||||
controller: ViewController,
|
||||
presentationData: PresentationData,
|
||||
phoneNumber: String,
|
||||
mnc: String
|
||||
) {
|
||||
if MFMailComposeViewController.canSendMail() {
|
||||
let formattedNumber = formatPhoneNumber(number)
|
||||
let formattedNumber = formatPhoneNumber(phoneNumber)
|
||||
|
||||
var emailBody = ""
|
||||
emailBody.append(presentationData.strings.Login_EmailCodeBody(formattedNumber).string)
|
||||
@@ -1331,8 +1348,6 @@ public final class AuthorizationSequenceController: NavigationController, ASAuth
|
||||
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"
|
||||
emailBody.append("Telegram: \(appVersion)\n")
|
||||
emailBody.append("OS: \(systemVersion)\n")
|
||||
emailBody.append("Locale: \(locale)\n")
|
||||
|
||||
Reference in New Issue
Block a user