Authorization improvements

This commit is contained in:
Ilya Laktyushin
2022-08-24 15:11:06 +02:00
parent 6550313056
commit a28f744eb4
31 changed files with 720 additions and 436 deletions

View File

@@ -2,23 +2,30 @@ import Foundation
import UIKit
import AsyncDisplayKit
import Display
import SwiftSignalKit
import PhoneNumberFormat
public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
public struct Theme: Equatable {
public var inactiveBorder: UInt32
public var activeBorder: UInt32
public var succeedBorder: UInt32
public var failedBorder: UInt32
public var foreground: UInt32
public var isDark: Bool
public init(
inactiveBorder: UInt32,
activeBorder: UInt32,
succeedBorder: UInt32,
failedBorder: UInt32,
foreground: UInt32,
isDark: Bool
) {
self.inactiveBorder = inactiveBorder
self.activeBorder = activeBorder
self.succeedBorder = succeedBorder
self.failedBorder = failedBorder
self.foreground = foreground
self.isDark = isDark
}
@@ -71,7 +78,7 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
}
}
func update(textColor: UInt32, text: String, size: CGSize, fontSize: CGFloat, animated: Bool) {
func update(textColor: UInt32, text: String, size: CGSize, fontSize: CGFloat, animated: Bool, delay: Double? = nil) {
let previousText = self.text
self.text = text
@@ -83,10 +90,10 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
} else {
if let copyView = self.textNode.view.snapshotContentTree() {
self.view.insertSubview(copyView, at: 0)
copyView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak copyView] _ in
copyView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, delay: delay ?? 0.0, removeOnCompletion: false, completion: { [weak copyView] _ in
copyView?.removeFromSuperview()
})
copyView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: size.height / 2.0), duration: 0.2, removeOnCompletion: false, additive: true)
copyView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: size.height / 2.0), duration: 0.2, delay: delay ?? 0.0, removeOnCompletion: false, additive: true)
}
}
}
@@ -160,6 +167,28 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
}
}
private var isSucceed = false
private var isFailed = false
private var isResetting = false
public func animateError() {
self.isFailed = true
self.updateItemViews(animated: true)
Queue.mainQueue().after(0.85, {
self.textValue = ""
self.isResetting = true
self.updateItemViews(animated: true)
self.isResetting = false
self.textField.text = ""
self.isFailed = false
self.updateItemViews(animated: true)
})
}
public func animateSuccess() {
self.isSucceed = true
self.updateItemViews(animated: true)
}
@objc func textFieldChanged(_ textField: UITextField) {
self.textValue = textField.text ?? ""
self.updateItemViews(animated: true)
@@ -170,6 +199,11 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
guard let count = self.count else {
return false
}
guard !self.isFailed else {
return false
}
var text = textField.text ?? ""
guard let stringRange = Range(range, in: text) else {
return false
@@ -220,6 +254,7 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
return
}
var delay: Double = 0.0
for i in 0 ..< self.itemViews.count {
let itemView = self.itemViews[i]
let itemSize = itemView.bounds.size
@@ -233,14 +268,26 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
fontSize = floor(21.0 * height / 28.0)
}
itemView.update(borderColor: self.focusIndex == i ? theme.activeBorder : theme.inactiveBorder, isHighlighted: self.focusIndex == i)
let borderColor: UInt32
if self.isSucceed {
borderColor = theme.succeedBorder
} else if self.isFailed {
borderColor = theme.failedBorder
} else {
borderColor = self.focusIndex == i ? theme.activeBorder : theme.inactiveBorder
}
itemView.update(borderColor: borderColor, isHighlighted: self.focusIndex == i)
let itemText: String
if i < self.textValue.count {
itemText = String(self.textValue[self.textValue.index(self.textValue.startIndex, offsetBy: i)])
} else {
itemText = ""
}
itemView.update(textColor: theme.foreground, text: itemText, size: itemSize, fontSize: fontSize, animated: animated)
itemView.update(textColor: theme.foreground, text: itemText, size: itemSize, fontSize: fontSize, animated: animated, delay: delay)
if self.isResetting {
delay += 0.05
}
}
}
@@ -291,7 +338,17 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
self.itemViews.append(itemView)
self.addSubnode(itemView)
}
itemView.update(borderColor: self.focusIndex == i ? theme.activeBorder : theme.inactiveBorder, isHighlighted: self.focusIndex == i)
let borderColor: UInt32
if self.isSucceed {
borderColor = theme.succeedBorder
} else if self.isFailed {
borderColor = theme.failedBorder
} else {
borderColor = self.focusIndex == i ? theme.activeBorder : theme.inactiveBorder
}
itemView.update(borderColor: borderColor, isHighlighted: self.focusIndex == i)
let itemText: String
if i < self.textValue.count {
itemText = String(self.textValue[self.textValue.index(self.textValue.startIndex, offsetBy: i)])