mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Onboarding flow coordinator and FTUE changes (#2578)
Fixes #2595, fixes #2594, fixes #2593, fixes #2592, fixes #2591
This commit is contained in:
+1
-1
@@ -86,7 +86,7 @@ class SecureBackupKeyBackupScreenViewModel: SecureBackupKeyBackupScreenViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private static let loadingIndicatorIdentifier = "SecureBackupKeyBackupScreenLoading"
|
||||
private static let loadingIndicatorIdentifier = "\(SecureBackupKeyBackupScreenViewModel.self)-Loading"
|
||||
|
||||
private func showLoadingIndicator() {
|
||||
userIndicatorController?.submitIndicator(.init(id: Self.loadingIndicatorIdentifier, type: .modal, title: L10n.commonLoading, persistent: true))
|
||||
|
||||
+15
-15
@@ -22,12 +22,21 @@ struct SecureBackupKeyBackupScreen: View {
|
||||
@ObservedObject var context: SecureBackupKeyBackupScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
mainContent
|
||||
.padding()
|
||||
.interactiveDismissDisabled()
|
||||
.toolbar { toolbar }
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.alert(item: $context.alertInfo)
|
||||
FullscreenDialog {
|
||||
mainContent
|
||||
} bottomContent: {
|
||||
Button(role: .destructive) {
|
||||
context.send(viewAction: .toggleBackup)
|
||||
} label: {
|
||||
Text(L10n.screenChatBackupKeyBackupActionDisable)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
.background()
|
||||
.environment(\.backgroundStyle, AnyShapeStyle(Color.compound.bgCanvasDefault))
|
||||
.interactiveDismissDisabled()
|
||||
.toolbar { toolbar }
|
||||
.alert(item: $context.alertInfo)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
@@ -71,15 +80,6 @@ struct SecureBackupKeyBackupScreen: View {
|
||||
.foregroundColor(.compound.iconCriticalPrimary)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(role: .destructive) {
|
||||
context.send(viewAction: .toggleBackup)
|
||||
} label: {
|
||||
Text(L10n.screenChatBackupKeyBackupActionDisable)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-30
@@ -22,26 +22,21 @@ struct SecureBackupLogoutConfirmationScreen: View {
|
||||
@ObservedObject var context: SecureBackupLogoutConfirmationScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
ScrollView {
|
||||
VStack(spacing: 16) {
|
||||
header
|
||||
content
|
||||
}
|
||||
.padding()
|
||||
FullscreenDialog {
|
||||
VStack(spacing: 16) {
|
||||
HeroImage(icon: \.keyOffSolid)
|
||||
content
|
||||
}
|
||||
.toolbar { toolbar }
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.safeAreaInset(edge: .bottom) { footer.padding() }
|
||||
.alert(item: $context.alertInfo)
|
||||
.padding()
|
||||
} bottomContent: {
|
||||
footer.padding()
|
||||
}
|
||||
.toolbar { toolbar }
|
||||
.background()
|
||||
.environment(\.backgroundStyle, AnyShapeStyle(Color.compound.bgCanvasDefault))
|
||||
.alert(item: $context.alertInfo)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var header: some View {
|
||||
HeroImage(icon: \.keyOffSolid)
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var content: some View {
|
||||
Text(title)
|
||||
@@ -62,21 +57,23 @@ struct SecureBackupLogoutConfirmationScreen: View {
|
||||
|
||||
@ViewBuilder
|
||||
private var footer: some View {
|
||||
if context.viewState.mode == .saveRecoveryKey {
|
||||
Button {
|
||||
context.send(viewAction: .settings)
|
||||
VStack(spacing: 16.0) {
|
||||
if context.viewState.mode == .saveRecoveryKey {
|
||||
Button {
|
||||
context.send(viewAction: .settings)
|
||||
} label: {
|
||||
Text(L10n.commonSettings)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
|
||||
Button(role: .destructive) {
|
||||
context.send(viewAction: .logout)
|
||||
} label: {
|
||||
Text(L10n.commonSettings)
|
||||
Text(L10n.actionSignout)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
|
||||
Button(role: .destructive) {
|
||||
context.send(viewAction: .logout)
|
||||
} label: {
|
||||
Text(L10n.actionSignout)
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
@@ -88,7 +85,7 @@ struct SecureBackupLogoutConfirmationScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
var title: String {
|
||||
private var title: String {
|
||||
switch context.viewState.mode {
|
||||
case .saveRecoveryKey:
|
||||
return L10n.screenSignoutSaveRecoveryKeyTitle
|
||||
@@ -99,7 +96,7 @@ struct SecureBackupLogoutConfirmationScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
var subtitle: String {
|
||||
private var subtitle: String {
|
||||
switch context.viewState.mode {
|
||||
case .saveRecoveryKey:
|
||||
return L10n.screenSignoutSaveRecoveryKeySubtitle
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ import SwiftUI
|
||||
struct SecureBackupRecoveryKeyScreenCoordinatorParameters {
|
||||
let secureBackupController: SecureBackupControllerProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let isModallyPresented: Bool
|
||||
}
|
||||
|
||||
enum SecureBackupRecoveryKeyScreenCoordinatorAction {
|
||||
@@ -40,7 +41,8 @@ final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
init(parameters: SecureBackupRecoveryKeyScreenCoordinatorParameters) {
|
||||
viewModel = SecureBackupRecoveryKeyScreenViewModel(secureBackupController: parameters.secureBackupController,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
isModallyPresented: parameters.isModallyPresented)
|
||||
}
|
||||
|
||||
func start() {
|
||||
|
||||
+3
@@ -28,6 +28,9 @@ enum SecureBackupRecoveryKeyScreenViewMode {
|
||||
}
|
||||
|
||||
struct SecureBackupRecoveryKeyScreenViewState: BindableState {
|
||||
/// Whether the screen is presented modally or within a navigation stack.
|
||||
var isModallyPresented: Bool
|
||||
|
||||
let mode: SecureBackupRecoveryKeyScreenViewMode
|
||||
|
||||
var recoveryKey: String?
|
||||
|
||||
+6
-2
@@ -28,11 +28,15 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(secureBackupController: SecureBackupControllerProtocol, userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
init(secureBackupController: SecureBackupControllerProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
isModallyPresented: Bool) {
|
||||
self.secureBackupController = secureBackupController
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
super.init(initialViewState: .init(mode: secureBackupController.recoveryState.value.viewMode, bindings: .init()))
|
||||
super.init(initialViewState: .init(isModallyPresented: isModallyPresented,
|
||||
mode: secureBackupController.recoveryState.value.viewMode,
|
||||
bindings: .init()))
|
||||
|
||||
secureBackupController.recoveryState
|
||||
.receive(on: DispatchQueue.main)
|
||||
|
||||
+9
-10
@@ -24,7 +24,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
private let textFieldIdentifier = "textFieldIdentifier"
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
FullscreenDialog {
|
||||
ScrollViewReader { reader in
|
||||
mainContent
|
||||
.padding(16)
|
||||
@@ -33,17 +33,14 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
reader.scrollTo(textFieldIdentifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
.safeAreaInset(edge: .bottom) {
|
||||
} bottomContent: {
|
||||
footer
|
||||
.padding([.horizontal, .bottom], 16)
|
||||
.padding(.top, 8)
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
}
|
||||
.interactiveDismissDisabled()
|
||||
.toolbar { toolbar }
|
||||
.toolbar(.visible, for: .navigationBar)
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.background()
|
||||
.environment(\.backgroundStyle, AnyShapeStyle(Color.compound.bgCanvasDefault))
|
||||
.interactiveDismissDisabled()
|
||||
.alert(item: $context.alertInfo)
|
||||
}
|
||||
|
||||
@@ -101,7 +98,7 @@ struct SecureBackupRecoveryKeyScreen: View {
|
||||
|
||||
@ToolbarContentBuilder
|
||||
private var toolbar: some ToolbarContent {
|
||||
if context.viewState.recoveryKey == nil {
|
||||
if context.viewState.isModallyPresented == true, context.viewState.recoveryKey == nil {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(L10n.actionCancel) {
|
||||
context.send(viewAction: .cancel)
|
||||
@@ -235,6 +232,8 @@ struct SecureBackupRecoveryKeyScreen_Previews: PreviewProvider, TestablePreview
|
||||
let backupController = SecureBackupControllerMock()
|
||||
backupController.underlyingRecoveryState = CurrentValueSubject<SecureBackupRecoveryState, Never>(recoveryState).asCurrentValuePublisher()
|
||||
|
||||
return SecureBackupRecoveryKeyScreenViewModel(secureBackupController: backupController, userIndicatorController: UserIndicatorControllerMock())
|
||||
return SecureBackupRecoveryKeyScreenViewModel(secureBackupController: backupController,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
isModallyPresented: true)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -46,7 +46,8 @@ final class SecureBackupScreenCoordinator: CoordinatorProtocol {
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let recoveryKeyCoordinator = SecureBackupRecoveryKeyScreenCoordinator(parameters: .init(secureBackupController: parameters.secureBackupController,
|
||||
userIndicatorController: parameters.userIndicatorController))
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
isModallyPresented: true))
|
||||
|
||||
recoveryKeyCoordinator.actions.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
Reference in New Issue
Block a user