Encryption Flow Coordinators. (#3471)
* Manage the secure backup screens with flow coordinators.
* Add UI tests for the EncryptionSettingsFlowCoordinator.
* Realise that the settings flow can't reset anymore and remove the sub-flow 🤦♂️
* Add UI tests for the EncryptionResetFlowCoordinator.
This commit is contained in:
@@ -15,23 +15,22 @@ struct SecureBackupRecoveryKeyScreenCoordinatorParameters {
|
||||
}
|
||||
|
||||
enum SecureBackupRecoveryKeyScreenCoordinatorAction {
|
||||
case cancel
|
||||
case recoverySetUp
|
||||
case recoveryChanged
|
||||
case recoveryFixed
|
||||
case resetEncryption
|
||||
case complete
|
||||
}
|
||||
|
||||
final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: SecureBackupRecoveryKeyScreenCoordinatorParameters
|
||||
private var viewModel: SecureBackupRecoveryKeyScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<SecureBackupRecoveryKeyScreenCoordinatorAction, Never> = .init()
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SecureBackupRecoveryKeyScreenCoordinatorAction, Never> = .init()
|
||||
var actions: AnyPublisher<SecureBackupRecoveryKeyScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: SecureBackupRecoveryKeyScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
viewModel = SecureBackupRecoveryKeyScreenViewModel(secureBackupController: parameters.secureBackupController,
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
isModallyPresented: parameters.isModallyPresented)
|
||||
@@ -44,20 +43,19 @@ final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .cancel:
|
||||
self.actionsSubject.send(.cancel)
|
||||
self.actionsSubject.send(.complete)
|
||||
case .done(let mode):
|
||||
switch mode {
|
||||
case .setupRecovery:
|
||||
self.actionsSubject.send(.recoverySetUp)
|
||||
showSuccessIndicator(title: L10n.screenRecoveryKeySetupSuccess)
|
||||
case .changeRecovery:
|
||||
self.actionsSubject.send(.recoveryChanged)
|
||||
showSuccessIndicator(title: L10n.screenRecoveryKeyChangeSuccess)
|
||||
case .fixRecovery:
|
||||
self.actionsSubject.send(.recoveryFixed)
|
||||
showSuccessIndicator(title: L10n.screenRecoveryKeyConfirmSuccess)
|
||||
case .unknown:
|
||||
fatalError()
|
||||
}
|
||||
case .resetEncryption:
|
||||
self.actionsSubject.send(.resetEncryption)
|
||||
self.actionsSubject.send(.complete)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -66,4 +64,14 @@ final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(SecureBackupRecoveryKeyScreen(context: viewModel.context))
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func showSuccessIndicator(title: String) {
|
||||
parameters.userIndicatorController.submitIndicator(.init(id: .init(),
|
||||
type: .modal(progress: .none, interactiveDismissDisabled: false, allowsInteraction: false),
|
||||
title: title,
|
||||
iconName: "checkmark",
|
||||
persistent: false))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import Foundation
|
||||
enum SecureBackupRecoveryKeyScreenViewModelAction {
|
||||
case done(mode: SecureBackupRecoveryKeyScreenViewMode)
|
||||
case cancel
|
||||
case resetEncryption
|
||||
}
|
||||
|
||||
enum SecureBackupRecoveryKeyScreenViewMode {
|
||||
@@ -82,7 +81,6 @@ enum SecureBackupRecoveryKeyScreenViewAction {
|
||||
case copyKey
|
||||
case keySaved
|
||||
case confirmKey
|
||||
case resetEncryption
|
||||
case done
|
||||
case cancel
|
||||
}
|
||||
|
||||
@@ -78,13 +78,11 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
|
||||
state.bindings.alertInfo = .init(id: .init(),
|
||||
title: L10n.screenRecoveryKeySetupConfirmationTitle,
|
||||
message: L10n.screenRecoveryKeySetupConfirmationDescription,
|
||||
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
|
||||
secondaryButton: .init(title: L10n.actionContinue, action: { [weak self] in
|
||||
primaryButton: .init(title: L10n.actionContinue) { [weak self] in
|
||||
guard let self else { return }
|
||||
actionsSubject.send(.done(mode: context.viewState.mode))
|
||||
}))
|
||||
case .resetEncryption:
|
||||
actionsSubject.send(.resetEncryption)
|
||||
},
|
||||
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
.disabled(context.confirmationRecoveryKey.isEmpty)
|
||||
.accessibilityIdentifier(A11yIdentifiers.secureBackupRecoveryKeyScreen.confirm)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +112,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
.disabled(context.viewState.recoveryKey == nil || context.viewState.doneButtonEnabled == false)
|
||||
.accessibilityIdentifier(A11yIdentifiers.secureBackupRecoveryKeyScreen.done)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +142,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
}
|
||||
.font(.compound.bodyLGSemibold)
|
||||
.padding(.vertical, 11)
|
||||
.accessibilityIdentifier(A11yIdentifiers.secureBackupRecoveryKeyScreen.generateRecoveryKey)
|
||||
} else {
|
||||
HStack(spacing: 8) {
|
||||
ProgressView()
|
||||
@@ -163,6 +166,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
}
|
||||
.tint(.compound.iconSecondary)
|
||||
.accessibilityLabel(L10n.actionCopy)
|
||||
.accessibilityIdentifier(A11yIdentifiers.secureBackupRecoveryKeyScreen.copyRecoveryKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,6 +208,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
.onSubmit {
|
||||
context.send(viewAction: .confirmKey)
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.secureBackupRecoveryKeyScreen.recoveryKeyField)
|
||||
|
||||
if let subtitle = context.viewState.recoveryKeySubtitle {
|
||||
Text(subtitle)
|
||||
|
||||
Reference in New Issue
Block a user