mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Initial implementation for AppLockSetupFlowCoordinator. (#1949)
Rename AppLockSettingsScreen to AppLockSetupSettingsScreen. Implement forced logout and persist PIN entry attempts.
This commit is contained in:
+5
-2
@@ -21,6 +21,8 @@ struct AppLockSetupPINScreenCoordinatorParameters {
|
||||
/// Whether the screen should start in create or unlock mode.
|
||||
/// Specifying confirm here will raise a fatal error.
|
||||
let initialMode: AppLockSetupPINScreenMode
|
||||
/// Whether the screen is mandatory or can be cancelled by the user.
|
||||
let isMandatory: Bool
|
||||
let appLockService: AppLockServiceProtocol
|
||||
}
|
||||
|
||||
@@ -46,6 +48,7 @@ final class AppLockSetupPINScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
self.parameters = parameters
|
||||
viewModel = AppLockSetupPINScreenViewModel(initialMode: parameters.initialMode,
|
||||
isMandatory: parameters.isMandatory,
|
||||
appLockService: parameters.appLockService)
|
||||
}
|
||||
|
||||
@@ -56,9 +59,9 @@ final class AppLockSetupPINScreenCoordinator: CoordinatorProtocol {
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .complete:
|
||||
break
|
||||
actionsSubject.send(.complete)
|
||||
case .cancel:
|
||||
break
|
||||
actionsSubject.send(.cancel)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
+2
@@ -35,6 +35,8 @@ enum AppLockSetupPINScreenMode {
|
||||
struct AppLockSetupPINScreenViewState: BindableState {
|
||||
/// The current mode that the screen is in.
|
||||
var mode: AppLockSetupPINScreenMode
|
||||
/// Whether the screen is mandatory or can be cancelled.
|
||||
let isMandatory: Bool
|
||||
|
||||
var title: String {
|
||||
switch mode {
|
||||
|
||||
+2
-2
@@ -30,9 +30,9 @@ class AppLockSetupPINScreenViewModel: AppLockSetupPINScreenViewModelType, AppLoc
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(initialMode: AppLockSetupPINScreenMode, appLockService: AppLockServiceProtocol) {
|
||||
init(initialMode: AppLockSetupPINScreenMode, isMandatory: Bool, appLockService: AppLockServiceProtocol) {
|
||||
self.appLockService = appLockService
|
||||
super.init(initialViewState: AppLockSetupPINScreenViewState(mode: initialMode, bindings: .init(pinCode: "")))
|
||||
super.init(initialViewState: AppLockSetupPINScreenViewState(mode: initialMode, isMandatory: isMandatory, bindings: .init(pinCode: "")))
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
+29
-3
@@ -21,6 +21,8 @@ import SwiftUI
|
||||
struct AppLockSetupPINScreen: View {
|
||||
@ObservedObject var context: AppLockSetupPINScreenViewModel.Context
|
||||
|
||||
@FocusState private var textFieldFocus
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 48) {
|
||||
@@ -28,6 +30,7 @@ struct AppLockSetupPINScreen: View {
|
||||
|
||||
PINTextField(pinCode: $context.pinCode,
|
||||
isSecure: context.viewState.mode == .unlock)
|
||||
.focused($textFieldFocus)
|
||||
.onChange(of: context.pinCode) { newValue in
|
||||
guard newValue.count == 4 else { return }
|
||||
context.send(viewAction: .submitPINCode)
|
||||
@@ -38,6 +41,12 @@ struct AppLockSetupPINScreen: View {
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||
.toolbar { toolbar }
|
||||
.toolbar(.visible, for: .navigationBar)
|
||||
.navigationBarBackButtonHidden()
|
||||
.interactiveDismissDisabled(context.viewState.isMandatory)
|
||||
.alert(item: $context.alertInfo)
|
||||
.onAppear { textFieldFocus = true }
|
||||
}
|
||||
|
||||
var header: some View {
|
||||
@@ -59,6 +68,17 @@ struct AppLockSetupPINScreen: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
var toolbar: some ToolbarContent {
|
||||
if !context.viewState.isMandatory {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(L10n.actionCancel) {
|
||||
context.send(viewAction: .cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
@@ -66,9 +86,15 @@ struct AppLockSetupPINScreen: View {
|
||||
struct AppLockSetupPINScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let service = AppLockService(keychainController: KeychainControllerMock(),
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
static let createViewModel = AppLockSetupPINScreenViewModel(initialMode: .create, appLockService: service)
|
||||
static let confirmViewModel = AppLockSetupPINScreenViewModel(initialMode: .confirm, appLockService: service)
|
||||
static let unlockViewModel = AppLockSetupPINScreenViewModel(initialMode: .unlock, appLockService: service)
|
||||
static let createViewModel = AppLockSetupPINScreenViewModel(initialMode: .create,
|
||||
isMandatory: false,
|
||||
appLockService: service)
|
||||
static let confirmViewModel = AppLockSetupPINScreenViewModel(initialMode: .confirm,
|
||||
isMandatory: false,
|
||||
appLockService: service)
|
||||
static let unlockViewModel = AppLockSetupPINScreenViewModel(initialMode: .unlock,
|
||||
isMandatory: false,
|
||||
appLockService: service)
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
|
||||
Reference in New Issue
Block a user