mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Update password setup animations
This commit is contained in:
@@ -20,8 +20,6 @@ public enum TwoFactorDataInputMode {
|
||||
case passwordHint(password: String)
|
||||
}
|
||||
|
||||
|
||||
|
||||
public final class TwoFactorDataInputScreen: ViewController {
|
||||
private let context: AccountContext
|
||||
private var presentationData: PresentationData
|
||||
@@ -471,7 +469,7 @@ private func generateTextHiddenImage(color: UIColor, on: Bool) -> UIImage? {
|
||||
private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelegate {
|
||||
private let theme: PresentationTheme
|
||||
let mode: TwoFactorDataInputTextNodeType
|
||||
private let focused: (TwoFactorDataInputTextNode) -> Void
|
||||
private let focusUpdated: (TwoFactorDataInputTextNode, Bool) -> Void
|
||||
private let next: (TwoFactorDataInputTextNode) -> Void
|
||||
private let updated: (TwoFactorDataInputTextNode) -> Void
|
||||
private let toggleTextHidden: (TwoFactorDataInputTextNode) -> Void
|
||||
@@ -481,6 +479,12 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega
|
||||
private let hideButtonNode: HighlightableButtonNode
|
||||
private let clearButtonNode: HighlightableButtonNode
|
||||
|
||||
fileprivate var ignoreTextChanged: Bool = false
|
||||
|
||||
var isFocused: Bool {
|
||||
return self.inputNode.textField.isFirstResponder
|
||||
}
|
||||
|
||||
var text: String {
|
||||
get {
|
||||
return self.inputNode.textField.text ?? ""
|
||||
@@ -490,10 +494,10 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega
|
||||
}
|
||||
}
|
||||
|
||||
init(theme: PresentationTheme, mode: TwoFactorDataInputTextNodeType, placeholder: String, focused: @escaping (TwoFactorDataInputTextNode) -> Void, next: @escaping (TwoFactorDataInputTextNode) -> Void, updated: @escaping (TwoFactorDataInputTextNode) -> Void, toggleTextHidden: @escaping (TwoFactorDataInputTextNode) -> Void) {
|
||||
init(theme: PresentationTheme, mode: TwoFactorDataInputTextNodeType, placeholder: String, focusUpdated: @escaping (TwoFactorDataInputTextNode, Bool) -> Void, next: @escaping (TwoFactorDataInputTextNode) -> Void, updated: @escaping (TwoFactorDataInputTextNode) -> Void, toggleTextHidden: @escaping (TwoFactorDataInputTextNode) -> Void) {
|
||||
self.theme = theme
|
||||
self.mode = mode
|
||||
self.focused = focused
|
||||
self.focusUpdated = focusUpdated
|
||||
self.next = next
|
||||
self.updated = updated
|
||||
self.toggleTextHidden = toggleTextHidden
|
||||
@@ -564,11 +568,21 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega
|
||||
|
||||
func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
let text = self.text
|
||||
let isEmpty = text.isEmpty
|
||||
self.focused(self)
|
||||
|
||||
if self.inputNode.textField.isSecureTextEntry {
|
||||
let previousIgnoreTextChanged = self.ignoreTextChanged
|
||||
self.ignoreTextChanged = true
|
||||
self.inputNode.textField.text = ""
|
||||
self.inputNode.textField.insertText(text + " ")
|
||||
self.inputNode.textField.deleteBackward()
|
||||
self.ignoreTextChanged = previousIgnoreTextChanged
|
||||
}
|
||||
|
||||
self.focusUpdated(self, true)
|
||||
}
|
||||
|
||||
func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
self.focusUpdated(self, false)
|
||||
}
|
||||
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
@@ -581,13 +595,15 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega
|
||||
}
|
||||
|
||||
@objc private func textFieldChanged(_ textField: UITextField) {
|
||||
switch self.mode {
|
||||
case .password:
|
||||
break
|
||||
default:
|
||||
self.clearButtonNode.isHidden = self.text.isEmpty
|
||||
if !self.ignoreTextChanged {
|
||||
switch self.mode {
|
||||
case .password:
|
||||
break
|
||||
default:
|
||||
self.clearButtonNode.isHidden = self.text.isEmpty
|
||||
}
|
||||
self.updated(self)
|
||||
}
|
||||
self.updated(self)
|
||||
}
|
||||
|
||||
@objc private func hidePressed() {
|
||||
@@ -615,7 +631,19 @@ private final class TwoFactorDataInputTextNode: ASDisplayNode, UITextFieldDelega
|
||||
|
||||
func updateTextHidden(_ value: Bool) {
|
||||
self.hideButtonNode.setImage(generateTextHiddenImage(color: self.theme.actionSheet.inputClearButtonColor, on: !value), for: [])
|
||||
let text = self.inputNode.textField.text ?? ""
|
||||
self.inputNode.textField.isSecureTextEntry = value
|
||||
if value {
|
||||
if self.inputNode.textField.isFirstResponder {
|
||||
let previousIgnoreTextChanged = self.ignoreTextChanged
|
||||
self.ignoreTextChanged = true
|
||||
self.inputNode.textField.text = ""
|
||||
self.inputNode.textField.becomeFirstResponder()
|
||||
self.inputNode.textField.insertText(text + " ")
|
||||
self.inputNode.textField.deleteBackward()
|
||||
self.ignoreTextChanged = previousIgnoreTextChanged
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,7 +722,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
|
||||
var inputNodes: [TwoFactorDataInputTextNode] = []
|
||||
var next: ((TwoFactorDataInputTextNode) -> Void)?
|
||||
var focused: ((TwoFactorDataInputTextNode) -> Void)?
|
||||
var focusUpdated: ((TwoFactorDataInputTextNode, Bool) -> Void)?
|
||||
var updated: ((TwoFactorDataInputTextNode) -> Void)?
|
||||
var toggleTextHidden: ((TwoFactorDataInputTextNode) -> Void)?
|
||||
|
||||
@@ -707,8 +735,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
changeEmailActionText = ""
|
||||
resendCodeActionText = ""
|
||||
inputNodes = [
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: false), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderPassword, focused: { node in
|
||||
focused?(node)
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: false), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderPassword, focusUpdated: { node, focused in
|
||||
focusUpdated?(node, focused)
|
||||
}, next: { node in
|
||||
next?(node)
|
||||
}, updated: { node in
|
||||
@@ -716,8 +744,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
}, toggleTextHidden: { node in
|
||||
toggleTextHidden?(node)
|
||||
}),
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: true), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderConfirmPassword, focused: { node in
|
||||
focused?(node)
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .password(confirmation: true), placeholder: presentationData.strings.TwoFactorSetup_Password_PlaceholderConfirmPassword, focusUpdated: { node, focused in
|
||||
focusUpdated?(node, focused)
|
||||
}, next: { node in
|
||||
next?(node)
|
||||
}, updated: { node in
|
||||
@@ -734,8 +762,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
changeEmailActionText = ""
|
||||
resendCodeActionText = ""
|
||||
inputNodes = [
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .email, placeholder: presentationData.strings.TwoFactorSetup_Email_Placeholder, focused: { node in
|
||||
focused?(node)
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .email, placeholder: presentationData.strings.TwoFactorSetup_Email_Placeholder, focusUpdated: { node, focused in
|
||||
focusUpdated?(node, focused)
|
||||
}, next: { node in
|
||||
next?(node)
|
||||
}, updated: { node in
|
||||
@@ -761,8 +789,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
changeEmailActionText = presentationData.strings.TwoFactorSetup_EmailVerification_ChangeAction
|
||||
resendCodeActionText = presentationData.strings.TwoFactorSetup_EmailVerification_ResendAction
|
||||
inputNodes = [
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .code, placeholder: presentationData.strings.TwoFactorSetup_EmailVerification_Placeholder, focused: { node in
|
||||
focused?(node)
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .code, placeholder: presentationData.strings.TwoFactorSetup_EmailVerification_Placeholder, focusUpdated: { node, focused in
|
||||
focusUpdated?(node, focused)
|
||||
}, next: { node in
|
||||
next?(node)
|
||||
}, updated: { node in
|
||||
@@ -781,8 +809,8 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
changeEmailActionText = ""
|
||||
resendCodeActionText = ""
|
||||
inputNodes = [
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .hint, placeholder: presentationData.strings.TwoFactorSetup_Hint_Placeholder, focused: { node in
|
||||
focused?(node)
|
||||
TwoFactorDataInputTextNode(theme: presentationData.theme, mode: .hint, placeholder: presentationData.strings.TwoFactorSetup_Hint_Placeholder, focusUpdated: { node, focused in
|
||||
focusUpdated?(node, focused)
|
||||
}, next: { node in
|
||||
next?(node)
|
||||
}, updated: { node in
|
||||
@@ -917,67 +945,64 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
}
|
||||
}
|
||||
}
|
||||
focused = { [weak self] node in
|
||||
DispatchQueue.main.async {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
var textHidden = true
|
||||
let updateAnimations: () -> Void = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let hasText = strongSelf.inputNodes.contains(where: { !$0.text.isEmpty })
|
||||
/*switch strongSelf.mode {
|
||||
switch strongSelf.mode {
|
||||
case .password:
|
||||
if !hasText {
|
||||
if strongSelf.animationNode.currentItemName == animationPeek.name {
|
||||
strongSelf.animationNode.switchTo(animationHideOutro)
|
||||
strongSelf.animationNode.switchTo(animationIdle)
|
||||
if strongSelf.inputNodes[1].isFocused {
|
||||
let textLength = strongSelf.inputNodes[1].text.count
|
||||
let maxWidth = strongSelf.inputNodes[1].bounds.width
|
||||
|
||||
let textNode = ImmediateTextNode()
|
||||
textNode.attributedText = NSAttributedString(string: strongSelf.inputNodes[1].text, font: Font.regular(17.0), textColor: .black)
|
||||
let textSize = textNode.updateLayout(CGSize(width: 1000.0, height: 100.0))
|
||||
|
||||
let maxTextLength = 20
|
||||
var trackingOffset = textSize.width / maxWidth
|
||||
trackingOffset = max(0.0, min(1.0, trackingOffset))
|
||||
strongSelf.monkeyNode?.setState(.tracking(trackingOffset))
|
||||
} else if strongSelf.inputNodes[0].isFocused {
|
||||
let hasText = !strongSelf.inputNodes[0].text.isEmpty
|
||||
if !hasText {
|
||||
strongSelf.monkeyNode?.setState(.idle)
|
||||
} else if textHidden {
|
||||
strongSelf.monkeyNode?.setState(.eyesClosed)
|
||||
} else {
|
||||
strongSelf.animationNode.switchTo(animationIdle)
|
||||
}
|
||||
} else if textHidden {
|
||||
if strongSelf.animationNode.currentItemName == animationPeek.name {
|
||||
strongSelf.animationNode.switchTo(animationHideNoIntro)
|
||||
} else {
|
||||
strongSelf.animationNode.switchTo(animationHide)
|
||||
strongSelf.monkeyNode?.setState(.peeking)
|
||||
}
|
||||
} else {
|
||||
if strongSelf.animationNode.currentItemName != animationPeek.name {
|
||||
if strongSelf.animationNode.currentItemName == animationHide.name {
|
||||
strongSelf.animationNode.switchTo(animationPeek, noOutro: true)
|
||||
} else if strongSelf.animationNode.currentItemName == animationIdle.name {
|
||||
strongSelf.animationNode.switchTo(animationHideNoOutro)
|
||||
strongSelf.animationNode.switchTo(animationPeek)
|
||||
} else {
|
||||
strongSelf.animationNode.switchTo(animationPeek, noOutro: strongSelf.animationNode.currentItemName == animationHide.name)
|
||||
}
|
||||
}
|
||||
strongSelf.monkeyNode?.setState(.idle)
|
||||
}
|
||||
case .emailAddress:
|
||||
let textLength = strongSelf.inputNodes[0].text.count
|
||||
let maxWidth = strongSelf.inputNodes[0].bounds.width
|
||||
if textLength == 0 || maxWidth.isZero {
|
||||
strongSelf.animationNode.trackTo(frameIndex: 0)
|
||||
} else {
|
||||
if strongSelf.inputNodes[0].isFocused {
|
||||
let textLength = strongSelf.inputNodes[0].text.count
|
||||
let maxWidth = strongSelf.inputNodes[0].bounds.width
|
||||
|
||||
let textNode = ImmediateTextNode()
|
||||
textNode.attributedText = NSAttributedString(string: strongSelf.inputNodes[0].text, font: Font.regular(17.0), textColor: .black)
|
||||
let textSize = textNode.updateLayout(CGSize(width: 1000.0, height: 100.0))
|
||||
|
||||
let maxTextLength = 20
|
||||
let lowerBound = 14
|
||||
let upperBound = 160
|
||||
var trackingOffset = textSize.width / maxWidth
|
||||
trackingOffset = max(0.0, min(1.0, trackingOffset))
|
||||
let frameIndex = lowerBound + Int(trackingOffset * CGFloat(upperBound - lowerBound))
|
||||
strongSelf.animationNode.trackTo(frameIndex: frameIndex)
|
||||
strongSelf.monkeyNode?.setState(.tracking(trackingOffset))
|
||||
} else {
|
||||
strongSelf.monkeyNode?.setState(.idle)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}*/
|
||||
}
|
||||
}
|
||||
focusUpdated = { [weak self] node, _ in
|
||||
DispatchQueue.main.async {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
updateAnimations()
|
||||
}
|
||||
}
|
||||
updated = { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
@@ -1068,7 +1093,13 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
|
||||
let sideInset: CGFloat = 32.0
|
||||
let buttonSideInset: CGFloat = 48.0
|
||||
let iconSpacing: CGFloat = 2.0
|
||||
let iconSpacing: CGFloat
|
||||
switch self.mode {
|
||||
case .passwordHint, .emailConfirmation:
|
||||
iconSpacing = 6.0
|
||||
default:
|
||||
iconSpacing = 2.0
|
||||
}
|
||||
let titleSpacing: CGFloat = 19.0
|
||||
let titleInputSpacing: CGFloat = 26.0
|
||||
let textSpacing: CGFloat = 30.0
|
||||
@@ -1118,6 +1149,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
|
||||
let iconFrame = CGRect(origin: CGPoint(x: floor((contentAreaSize.width - iconSize.width) / 2.0), y: contentVerticalOrigin), size: iconSize)
|
||||
if let animatedStickerNode = self.animatedStickerNode {
|
||||
animatedStickerNode.updateLayout(size: iconFrame.size)
|
||||
transition.updateFrame(node: animatedStickerNode, frame: iconFrame)
|
||||
} else if let monkeyNode = self.monkeyNode {
|
||||
transition.updateFrame(node: monkeyNode, frame: iconFrame)
|
||||
|
||||
Reference in New Issue
Block a user