Fix a bug where the onboarding flow was dismissed by logging out. (#5481)

* Fix a bug where the onboarding flow was dismissed by logging out.

* Add some tests for the available actions while we're here.

---------

Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
This commit is contained in:
Doug
2026-04-27 14:33:09 +01:00
committed by GitHub
parent af08010370
commit 9987a34265
8 changed files with 160 additions and 21 deletions

View File

@@ -13,7 +13,7 @@ import SwiftState
enum OnboardingFlowCoordinatorAction {
case requestPresentation(animated: Bool)
case dismiss
case logout
case logoutConfirmed
}
class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
@@ -260,8 +260,8 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.tryEvent(.nextSkippingIdentityConfirmed)
case .reset:
startEncryptionResetFlow()
case .logout:
actionsSubject.send(.logout)
case .logoutConfirmed:
actionsSubject.send(.logoutConfirmed)
}
}
.store(in: &cancellables)

View File

@@ -275,8 +275,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
navigationTabCoordinator.setFullScreenCoverCoordinator(onboardingStackCoordinator, animated: animated)
case .dismiss:
navigationTabCoordinator.setFullScreenCoverCoordinator(nil)
case .logout:
logout()
case .logoutConfirmed:
actionsSubject.send(.logout)
}
}
.store(in: &cancellables)
@@ -494,7 +494,12 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
}
guard isLastDevice else {
logout()
navigationRootCoordinator.alertInfo = .init(id: .init(),
title: L10n.screenSignoutConfirmationDialogTitle,
message: L10n.screenSignoutConfirmationDialogContent,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
})
return
}
@@ -525,15 +530,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
presentSecureBackupLogoutConfirmationScreen()
}
private func logout() {
navigationRootCoordinator.alertInfo = .init(id: .init(),
title: L10n.screenSignoutConfirmationDialogTitle,
message: L10n.screenSignoutConfirmationDialogContent,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
})
}
private func presentSecureBackupLogoutConfirmationScreen() {
let coordinator = SecureBackupLogoutConfirmationScreenCoordinator(parameters: .init(secureBackupController: userSession.clientProxy.secureBackupController,
homeserverReachabilityPublisher: userSession.clientProxy.homeserverReachabilityPublisher))

View File

@@ -21,7 +21,7 @@ enum IdentityConfirmationScreenCoordinatorAction {
/// Only possible in debug builds.
case skip
case reset
case logout
case logoutConfirmed
}
final class IdentityConfirmationScreenCoordinator: CoordinatorProtocol {
@@ -57,8 +57,8 @@ final class IdentityConfirmationScreenCoordinator: CoordinatorProtocol {
actionsSubject.send(.skip)
case .reset:
actionsSubject.send(.reset)
case .logout:
actionsSubject.send(.logout)
case .logoutConfirmed:
actionsSubject.send(.logoutConfirmed)
}
}
.store(in: &cancellables)

View File

@@ -14,7 +14,7 @@ enum IdentityConfirmationScreenViewModelAction {
/// Only possible in debug builds.
case skip
case reset
case logout
case logoutConfirmed
}
struct IdentityConfirmationScreenViewState: BindableState {
@@ -25,6 +25,16 @@ struct IdentityConfirmationScreenViewState: BindableState {
var availableActions: [AvailableActions]?
let learnMoreURL: URL
var bindings = IdentityConfirmationScreenBindings()
}
struct IdentityConfirmationScreenBindings {
var alertInfo: AlertInfo<IdentityConfirmationScreenAlertType>?
}
enum IdentityConfirmationScreenAlertType {
case logout
}
enum IdentityConfirmationScreenViewAction {

View File

@@ -49,7 +49,7 @@ class IdentityConfirmationScreenViewModel: IdentityConfirmationScreenViewModelTy
case .reset:
actionsSubject.send(.reset)
case .logout:
actionsSubject.send(.logout)
confirmLogout()
}
}
@@ -88,6 +88,19 @@ class IdentityConfirmationScreenViewModel: IdentityConfirmationScreenViewModelTy
state.availableActions = availableActions
}
private func confirmLogout() {
// We need to show the confirmation within this flow as letting the UserSession flow do it results in the
// onboarding flow's modal being dismissed (by SwiftUI, not us). However we don't need any of the additional
// checks made in the UserSession flow as the user's account isn't verified so there's no much they can do unless
// they complete verification.
state.bindings.alertInfo = .init(id: .logout,
title: L10n.screenSignoutConfirmationDialogTitle,
message: L10n.screenSignoutConfirmationDialogContent,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logoutConfirmed)
})
}
private static let loadingIndicatorIdentifier = "\(IdentityConfirmationScreenViewModel.self)-Loading"
private func showLoadingIndicator() {

View File

@@ -10,7 +10,7 @@ import Compound
import SwiftUI
struct IdentityConfirmationScreen: View {
let context: IdentityConfirmationScreenViewModel.Context
@Bindable var context: IdentityConfirmationScreenViewModel.Context
var shouldShowSkipButton: Bool {
#if DEBUG
@@ -31,6 +31,7 @@ struct IdentityConfirmationScreen: View {
.backgroundStyle(.compound.bgCanvasDefault)
.navigationBarBackButtonHidden(true)
.interactiveDismissDisabled()
.alert(item: $context.alertInfo)
}
// MARK: - Private