Use PIN progress animation for verification
This commit is contained in:
parent
a8c32a92e6
commit
5500a531b9
@ -429,7 +429,7 @@ public class PinSetupViewController: OWSViewController {
|
||||
|
||||
pinTextField.resignFirstResponder()
|
||||
|
||||
let progressView = ProgressView(
|
||||
let progressView = PinProgressView(
|
||||
loadingText: NSLocalizedString("PIN_CREATION_PIN_PROGRESS",
|
||||
comment: "Indicates the work we are doing while creating the user's pin")
|
||||
)
|
||||
@ -520,7 +520,7 @@ extension PinSetupViewController: UITextFieldDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
private class ProgressView: UIView {
|
||||
class PinProgressView: UIView {
|
||||
private let label = UILabel()
|
||||
private let progressAnimation = AnimationView(name: "pinCreationInProgress")
|
||||
private let errorAnimation = AnimationView(name: "pinCreationFail")
|
||||
|
||||
@ -13,6 +13,8 @@ public class Onboarding2FAViewController: OnboardingBaseViewController {
|
||||
|
||||
private let pinTextField = UITextField()
|
||||
private let pinTypeToggle = UIButton()
|
||||
private lazy var nextButton = self.primaryButton(title: CommonStrings.nextButton,
|
||||
selector: #selector(nextPressed))
|
||||
|
||||
private lazy var pinStrokeNormal = pinTextField.addBottomStroke()
|
||||
private lazy var pinStrokeError = pinTextField.addBottomStroke(color: .ows_accentRed, strokeWidth: 2)
|
||||
@ -121,8 +123,6 @@ public class Onboarding2FAViewController: OnboardingBaseViewController {
|
||||
pinTypeToggle.addTarget(self, action: #selector(togglePinType), for: .touchUpInside)
|
||||
pinTypeToggle.accessibilityIdentifier = "pinCreation.pinTypeToggle"
|
||||
|
||||
let nextButton = self.primaryButton(title: CommonStrings.nextButton,
|
||||
selector: #selector(nextPressed))
|
||||
nextButton.accessibilityIdentifier = "onboarding.2fa." + "nextButton"
|
||||
let primaryButtonView = OnboardingBaseViewController.horizontallyWrap(primaryButton: nextButton)
|
||||
|
||||
@ -241,6 +241,30 @@ public class Onboarding2FAViewController: OnboardingBaseViewController {
|
||||
return
|
||||
}
|
||||
|
||||
let progressView = PinProgressView(
|
||||
loadingText: NSLocalizedString("REGISTER_2FA_PIN_PROGRESS",
|
||||
comment: "Indicates the work we are doing while verifying the user's pin")
|
||||
)
|
||||
view.addSubview(progressView)
|
||||
progressView.autoPinWidthToSuperview()
|
||||
progressView.autoVCenterInSuperview()
|
||||
|
||||
progressView.startLoading {
|
||||
self.view.isUserInteractionEnabled = false
|
||||
self.nextButton.alpha = 0.5
|
||||
self.pinTypeToggle.alpha = 0.5
|
||||
}
|
||||
|
||||
func animateProgressFail() {
|
||||
progressView.loadingComplete(success: false, animateAlongside: {
|
||||
self.nextButton.alpha = 1
|
||||
self.pinTypeToggle.alpha = 1
|
||||
}) {
|
||||
self.view.isUserInteractionEnabled = true
|
||||
progressView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
// v1 pins also have a max length, but we'll rely on the server to verify that
|
||||
// since we do not know if this is a v1 or a v2 pin at registration time.
|
||||
|
||||
@ -259,17 +283,30 @@ public class Onboarding2FAViewController: OnboardingBaseViewController {
|
||||
}
|
||||
|
||||
self.attemptState = .invalid(remainingAttempts: nil)
|
||||
animateProgressFail()
|
||||
case .invalidV2RegistrationLockPin(let remainingAttempts):
|
||||
self.attemptState = .invalid(remainingAttempts: remainingAttempts)
|
||||
animateProgressFail()
|
||||
case .exhaustedV2RegistrationLockAttempts:
|
||||
self.attemptState = .exhausted
|
||||
self.showAttemptsExhausted()
|
||||
|
||||
progressView.loadingComplete(success: false, animated: false) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.showAttemptsExhausted()
|
||||
}
|
||||
case .success:
|
||||
self.attemptState = .valid
|
||||
// If we have success while pending restoration, show the next onboarding milestone.
|
||||
if self.hasPendingRestoration { self.showNextMilestone(wasSuccessful: true) }
|
||||
|
||||
// The completion handler always dismisses this view, so we don't want to animate anything.
|
||||
progressView.loadingComplete(success: true, animated: false) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
// If we have success while pending restoration, show the next onboarding milestone.
|
||||
if self.hasPendingRestoration { self.showNextMilestone(wasSuccessful: true) }
|
||||
}
|
||||
|
||||
case .invalidVerificationCode:
|
||||
owsFailDebug("Invalid verification code in 2FA view.")
|
||||
animateProgressFail()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -743,42 +743,36 @@ public class OnboardingController: NSObject {
|
||||
return completion(.invalid2FAPin)
|
||||
}
|
||||
|
||||
ModalActivityIndicatorViewController.present(fromViewController: fromViewController, canCancel: false) { modal in
|
||||
KeyBackupService.restoreKeys(with: twoFAPin, and: self.kbsAuth).done {
|
||||
// If we restored successfully clear out KBS auth, the server will give it
|
||||
// to us again if we still need to do KBS operations.
|
||||
self.kbsAuth = nil
|
||||
KeyBackupService.restoreKeys(with: twoFAPin, and: self.kbsAuth).done {
|
||||
// If we restored successfully clear out KBS auth, the server will give it
|
||||
// to us again if we still need to do KBS operations.
|
||||
self.kbsAuth = nil
|
||||
|
||||
modal.dismiss {
|
||||
if self.tsAccountManager.isRegistered {
|
||||
completion(.success)
|
||||
} else {
|
||||
// We've restored our keys, we can now re-run this method to post our registration token
|
||||
self.submitVerification(fromViewController: fromViewController, completion: completion)
|
||||
}
|
||||
}
|
||||
}.catch { error in
|
||||
modal.dismiss {
|
||||
guard let error = error as? KeyBackupService.KBSError else {
|
||||
owsFailDebug("unexpected response from KBS")
|
||||
return completion(.invalid2FAPin)
|
||||
}
|
||||
if self.tsAccountManager.isRegistered {
|
||||
completion(.success)
|
||||
} else {
|
||||
// We've restored our keys, we can now re-run this method to post our registration token
|
||||
self.submitVerification(fromViewController: fromViewController, completion: completion)
|
||||
}
|
||||
}.catch { error in
|
||||
guard let error = error as? KeyBackupService.KBSError else {
|
||||
owsFailDebug("unexpected response from KBS")
|
||||
return completion(.invalid2FAPin)
|
||||
}
|
||||
|
||||
switch error {
|
||||
case .assertion:
|
||||
owsFailDebug("unexpected response from KBS")
|
||||
completion(.invalid2FAPin)
|
||||
case .invalidPin(let remainingAttempts):
|
||||
completion(.invalidV2RegistrationLockPin(remainingAttempts: remainingAttempts))
|
||||
case .backupMissing:
|
||||
// We don't have a backup for this person, it probably
|
||||
// was deleted due to too many failed attempts. They'll
|
||||
// have to retry after the registration lock window expires.
|
||||
completion(.exhaustedV2RegistrationLockAttempts)
|
||||
}
|
||||
}
|
||||
}.retainUntilComplete()
|
||||
}
|
||||
switch error {
|
||||
case .assertion:
|
||||
owsFailDebug("unexpected response from KBS")
|
||||
completion(.invalid2FAPin)
|
||||
case .invalidPin(let remainingAttempts):
|
||||
completion(.invalidV2RegistrationLockPin(remainingAttempts: remainingAttempts))
|
||||
case .backupMissing:
|
||||
// We don't have a backup for this person, it probably
|
||||
// was deleted due to too many failed attempts. They'll
|
||||
// have to retry after the registration lock window expires.
|
||||
completion(.exhaustedV2RegistrationLockAttempts)
|
||||
}
|
||||
}.retainUntilComplete()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -2391,7 +2391,7 @@
|
||||
"PIN_CREATION_PIN_CONFIRMATION_HINT" = "Re-enter PIN";
|
||||
|
||||
/* Indicates the work we are doing while creating the user's pin */
|
||||
"PIN_CREATION_PIN_PROGRESS" = "Creating PIN...";
|
||||
"PIN_CREATION_PIN_PROGRESS" = "Creating PIN…";
|
||||
|
||||
/* The re-creation explanation in the 'pin creation' view. */
|
||||
"PIN_CREATION_RECREATION_EXPLANATION" = "You can choose a new PIN because this device is registered. If you forget your PIN, you may need to wait 7 days to register again.";
|
||||
@ -2711,6 +2711,9 @@
|
||||
/* Alert title explaining what happens if you forget your 'two-factor auth pin'. */
|
||||
"REGISTER_2FA_INVALID_PIN_ALERT_TITLE" = "Incorrect PIN";
|
||||
|
||||
/* Indicates the work we are doing while verifying the user's pin */
|
||||
"REGISTER_2FA_PIN_PROGRESS" = "Verifying PIN…";
|
||||
|
||||
/* Label for 'submit' button in the 2FA registration view. */
|
||||
"REGISTER_2FA_SUBMIT_BUTTON" = "Submit";
|
||||
|
||||
@ -2898,7 +2901,7 @@
|
||||
"SECONDARY_ONBOARDING_GET_STARTED_BY_OPENING_PRIMARY" = "Launch Signal on your phone to link this iPad to your account";
|
||||
|
||||
/* Link explaining what to do when trying to link a device before having a primary device. */
|
||||
"SECONDARY_ONBOARDING_GET_STARTED_DO_NOT_HAVE_PRIMARY" = "I don't have Signal on my phone...";
|
||||
"SECONDARY_ONBOARDING_GET_STARTED_DO_NOT_HAVE_PRIMARY" = "I don't have Signal on my phone…";
|
||||
|
||||
/* alert body */
|
||||
"SECONDARY_ONBOARDING_INSTALL_PRIMARY_FIRST_BODY" = "Go to the App Store on your phone, install Signal, complete the registration process, and then you can link your iPad to the same account.";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user