diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 07a63bb63a..c782ab0ab5 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -659,7 +659,6 @@ B1069F361E604D5436AE9FFD /* StaticLocationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B06663F7858E45882E63471 /* StaticLocationScreen.swift */; }; B1387648C6F71F1B98244803 /* SecureBackupRecoveryKeyScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 596AA8843AC1A234F3387767 /* SecureBackupRecoveryKeyScreenCoordinator.swift */; }; B14BC354E56616B6B7D9A3D7 /* NotificationServiceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27A1AD6389A4659AF0CEAE62 /* NotificationServiceExtension.swift */; }; - B188D0907A4D38AAAF6FEFA8 /* AppLockSetupFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DBB08A95EFA668F2CF27211 /* AppLockSetupFlowCoordinator.swift */; }; B22D857D1E8FCA6DD74A58E3 /* UserSessionScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */; }; B245583C63F8F90357B87FAE /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = A2AE110B053B55E38F8D10C7 /* KZFileWatchers */; }; B27D3190784F85916DA1C394 /* SessionVerificationScreenStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B1EE0908B2BF9212436AD3E /* SessionVerificationScreenStateMachine.swift */; }; @@ -1037,7 +1036,6 @@ 0C671107BDFC6CD1778C0B4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 0D0B159AFFBBD8ECFD0E37FA /* LoginScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = ""; }; 0D8F620C8B314840D8602E3F /* NSE.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.app-extension"; path = NSE.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 0DBB08A95EFA668F2CF27211 /* AppLockSetupFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupFlowCoordinator.swift; sourceTree = ""; }; 0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStore.swift; sourceTree = ""; }; 0EA689E792E679F5E3956F21 /* UITimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITimelineView.swift; sourceTree = ""; }; 0F19DBE940499D3E3DD405D8 /* RoomMemberDetailsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenUITests.swift; sourceTree = ""; }; @@ -2846,7 +2844,6 @@ isa = PBXGroup; children = ( FCE93F0CBF0D96B77111C413 /* AppLockFlowCoordinator.swift */, - 0DBB08A95EFA668F2CF27211 /* AppLockSetupFlowCoordinator.swift */, 9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */, C99FDEEB71173C4C6FA2734C /* UserSessionFlowCoordinator.swift */, E8774CF614849664B5B3C2A1 /* UserSessionFlowCoordinatorStateMachine.swift */, @@ -5145,7 +5142,6 @@ 0AD81E04A8C024C09B7AEAC5 /* AppLockSettingsScreenModels.swift in Sources */, A7BEE8216B4B12BE4C0F2C3F /* AppLockSettingsScreenViewModel.swift in Sources */, 0206016CCEF6EF9365916768 /* AppLockSettingsScreenViewModelProtocol.swift in Sources */, - B188D0907A4D38AAAF6FEFA8 /* AppLockSetupFlowCoordinator.swift in Sources */, 733E2B19AB1FDA3B93293A28 /* AppLockSetupPINScreen.swift in Sources */, 9696ECAFB4F0C079C5C2A526 /* AppLockSetupPINScreenCoordinator.swift in Sources */, E4B07FF075C99D04D9AF792D /* AppLockSetupPINScreenModels.swift in Sources */, diff --git a/ElementX/Sources/Screens/AppLock/AppLockSetupPINScreen/View/PINTextField.swift b/ElementX/Sources/Screens/AppLock/AppLockSetupPINScreen/View/PINTextField.swift index ec6103a09c..e7a23109cf 100644 --- a/ElementX/Sources/Screens/AppLock/AppLockSetupPINScreen/View/PINTextField.swift +++ b/ElementX/Sources/Screens/AppLock/AppLockSetupPINScreen/View/PINTextField.swift @@ -27,9 +27,11 @@ struct PINTextField: View { .textFieldStyle(PINTextFieldStyle(pinCode: pinCode, isSecure: isSecure)) .keyboardType(.numberPad) .onChange(of: pinCode) { newValue in - // add some tests. let sanitized = sanitize(newValue) - if sanitized != newValue { pinCode = sanitized } + if sanitized != newValue { + MXLog.warning("PIN code input sanitized.") + pinCode = sanitized + } } } @@ -59,7 +61,7 @@ private struct PINTextFieldStyle: TextFieldStyle { public func _body(configuration: TextField<_Label>) -> some View { HStack(spacing: 8) { ForEach(0..<4) { index in - PINTextFieldDigit(pinCode: pinCode, index: index, isSecure: isSecure) + PINDigitField(digit: digit(index)) } } .overlay { @@ -69,31 +71,30 @@ private struct PINTextFieldStyle: TextFieldStyle { } .onTapGesture { isFocussed = true } } + + func digit(_ index: Int) -> Character? { + guard pinCode.count > index else { return nil } + let stringIndex = pinCode.index(pinCode.startIndex, offsetBy: index) + return isSecure ? "●" : pinCode[stringIndex] + } } /// A single digit shown within the text field style. -private struct PINTextFieldDigit: View { - let pinCode: String - let index: Int - let isSecure: Bool - - var isEntered: Bool { pinCode.count > index } - - var stringIndex: String.Index { pinCode.index(pinCode.startIndex, offsetBy: index) } - var character: Character { isSecure ? "●" : pinCode[stringIndex] } - var digit: String { isEntered ? String(character) : "" } +private struct PINDigitField: View { + let digit: Character? var body: some View { ZStack { - RoundedRectangle(cornerRadius: 8, style: .continuous) - .fill(Color.compound.bgSubtlePrimary) - .opacity(isEntered ? 1 : 0) - RoundedRectangle(cornerRadius: 8, style: .continuous) - .inset(by: 0.5) - .stroke(Color.compound.iconPrimary, lineWidth: 1) - .opacity(isEntered ? 0 : 1) - Text(digit) - .font(.compound.headingMDBold) + if let digit { + RoundedRectangle(cornerRadius: 8, style: .continuous) + .fill(Color.compound.bgSubtlePrimary) + Text(String(digit)) + .font(.compound.headingMDBold) + } else { + RoundedRectangle(cornerRadius: 8, style: .continuous) + .inset(by: 0.5) + .stroke(Color.compound.iconPrimary, lineWidth: 1) + } } .frame(width: 48, height: 48) }