Handle invalid PIN input in the settings flow. (#1972)

This commit is contained in:
Doug
2023-10-27 14:08:06 +01:00
committed by GitHub
parent acfc564490
commit 84a16091b2
19 changed files with 209 additions and 39 deletions
@@ -23,9 +23,21 @@ struct AppLockSetupPINScreen: View {
@FocusState private var textFieldFocus
var stackSpacing: CGFloat {
context.viewState.mode == .unlock ? 36 : 40
}
var subtitleColor: Color {
context.viewState.isSubtitleWarning ? .compound.textCriticalPrimary : .compound.textSecondary
}
var interactiveDismissDisabled: Bool {
context.viewState.isMandatory || context.viewState.isLoggingOut
}
var body: some View {
ScrollView {
VStack(spacing: 48) {
VStack(spacing: stackSpacing) {
header
PINTextField(pinCode: $context.pinCode,
@@ -44,7 +56,8 @@ struct AppLockSetupPINScreen: View {
.toolbar { toolbar }
.toolbar(.visible, for: .navigationBar)
.navigationBarBackButtonHidden()
.interactiveDismissDisabled(context.viewState.isMandatory)
.interactiveDismissDisabled(interactiveDismissDisabled)
.disabled(context.viewState.isLoggingOut)
.alert(item: $context.alertInfo)
.onAppear { textFieldFocus = true }
}
@@ -60,12 +73,10 @@ struct AppLockSetupPINScreen: View {
.multilineTextAlignment(.center)
.foregroundColor(.compound.textPrimary)
if let subtitle = context.viewState.subtitle {
Text(subtitle)
.font(.compound.bodyMD)
.multilineTextAlignment(.center)
.foregroundColor(.compound.textSecondary)
}
Text(context.viewState.subtitle)
.font(.compound.bodyMD)
.multilineTextAlignment(.center)
.foregroundColor(subtitleColor)
}
}
@@ -84,8 +95,9 @@ struct AppLockSetupPINScreen: View {
// MARK: - Previews
struct AppLockSetupPINScreen_Previews: PreviewProvider, TestablePreview {
static let service = AppLockService(keychainController: KeychainControllerMock(),
appSettings: ServiceLocator.shared.settings)
static let service = AppLockServiceMock.mock()
static let failedService = AppLockServiceMock.mock(numberOfPINAttempts: 1)
static let createViewModel = AppLockSetupPINScreenViewModel(initialMode: .create,
isMandatory: false,
appLockService: service)
@@ -95,6 +107,9 @@ struct AppLockSetupPINScreen_Previews: PreviewProvider, TestablePreview {
static let unlockViewModel = AppLockSetupPINScreenViewModel(initialMode: .unlock,
isMandatory: false,
appLockService: service)
static let unlockFailedViewModel = AppLockSetupPINScreenViewModel(initialMode: .unlock,
isMandatory: false,
appLockService: failedService)
static var previews: some View {
NavigationStack {
@@ -111,5 +126,10 @@ struct AppLockSetupPINScreen_Previews: PreviewProvider, TestablePreview {
AppLockSetupPINScreen(context: unlockViewModel.context)
}
.previewDisplayName("Unlock")
NavigationStack {
AppLockSetupPINScreen(context: unlockFailedViewModel.context)
}
.previewDisplayName("Unlock Failed")
}
}