diff --git a/Authenticator/Application/Support/Assets.xcassets/BackgroundColors/backgroundSplash.colorset/Contents.json b/Authenticator/Application/Support/Assets.xcassets/BackgroundColors/backgroundSplash.colorset/Contents.json index 4c8ef69a5..30d144a7b 100644 --- a/Authenticator/Application/Support/Assets.xcassets/BackgroundColors/backgroundSplash.colorset/Contents.json +++ b/Authenticator/Application/Support/Assets.xcassets/BackgroundColors/backgroundSplash.colorset/Contents.json @@ -5,9 +5,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0xF7", - "green" : "0xF2", - "red" : "0xF2" + "blue" : "0xDC", + "green" : "0x5D", + "red" : "0x17" } }, "idiom" : "universal" diff --git a/Authenticator/Application/Support/Assets.xcassets/logoAuthenticator.imageset/Contents.json b/Authenticator/Application/Support/Assets.xcassets/logoAuthenticator.imageset/Contents.json new file mode 100644 index 000000000..b6e3c5224 --- /dev/null +++ b/Authenticator/Application/Support/Assets.xcassets/logoAuthenticator.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "authenticator-logo.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Authenticator/Application/Support/Assets.xcassets/logoAuthenticator.imageset/authenticator-logo.pdf b/Authenticator/Application/Support/Assets.xcassets/logoAuthenticator.imageset/authenticator-logo.pdf new file mode 100644 index 000000000..ec8ba2f15 Binary files /dev/null and b/Authenticator/Application/Support/Assets.xcassets/logoAuthenticator.imageset/authenticator-logo.pdf differ diff --git a/Authenticator/Application/Support/Resources/LaunchScreen.storyboard b/Authenticator/Application/Support/Resources/LaunchScreen.storyboard index a71d69eee..9ddd27131 100644 --- a/Authenticator/Application/Support/Resources/LaunchScreen.storyboard +++ b/Authenticator/Application/Support/Resources/LaunchScreen.storyboard @@ -1,9 +1,9 @@ - + - + @@ -17,13 +17,13 @@ - - + + - + @@ -41,9 +41,9 @@ - + - + diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockProcessor.swift b/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockProcessor.swift index ee8569c51..568d5e3b3 100644 --- a/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockProcessor.swift +++ b/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockProcessor.swift @@ -91,7 +91,7 @@ class VaultUnlockProcessor: StateProcessor< } do { - let key = try await services.biometricsRepository.getUserAuthKey() + _ = try await services.biometricsRepository.getUserAuthKey() await coordinator.handleEvent(.didCompleteAuth) } catch let error as BiometricsServiceError { Logger.processor.error("BiometricsServiceError unlocking vault with biometrics: \(error)") diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockView.swift b/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockView.swift index 5fdb3e483..39fc01c21 100644 --- a/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockView.swift +++ b/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockView.swift @@ -10,6 +10,8 @@ struct VaultUnlockView: View { /// The `Store` for this view. @ObservedObject var store: Store + @Environment(\.colorScheme) private var colorScheme + var body: some View { content .task { @@ -22,11 +24,22 @@ struct VaultUnlockView: View { } private var content: some View { - VStack(spacing: 48) { - Image(decorative: Asset.Images.logo) + ZStack { + if colorScheme == .light { + Asset.Colors.primaryBitwarden.swiftUIColor + } else { + Asset.Colors.backgroundSecondary.swiftUIColor + } + + Image(decorative: Asset.Images.authenticatorLogo) + .resizable() + .frame(width: 232, height: 63) + biometricAuthButton + .offset(y: 63 + 48) + .padding(16) } - .padding(16) + .ignoresSafeArea() } /// A button to trigger a biometric auth unlock. @@ -37,7 +50,14 @@ struct VaultUnlockView: View { } label: { biometricUnlockText(biometryType) } - .buttonStyle(.primary(shouldFillWidth: true)) + .if(colorScheme == .light) { view in + view.buttonStyle(.secondary(shouldFillWidth: true)) + .background(Asset.Colors.backgroundPrimary.swiftUIColor) + .clipShape(RoundedRectangle(cornerRadius: 12)) + } + .if(colorScheme == .dark) { view in + view.buttonStyle(.primary(shouldFillWidth: true)) + } } } @@ -54,21 +74,55 @@ struct VaultUnlockView: View { // MARK: - Previews #if DEBUG -#Preview("Unlock") { - NavigationView { - VaultUnlockView( - store: Store( - processor: StateProcessor( - state: VaultUnlockState( - biometricUnlockStatus: .available( - .faceID, - enabled: true, - hasValidIntegrity: true +struct VaultUnlockView_Previews: PreviewProvider { + static var previews: some View { + NavigationView { + VaultUnlockView( + store: Store( + processor: StateProcessor( + state: VaultUnlockState( + biometricUnlockStatus: .available( + .faceID, + enabled: false, + hasValidIntegrity: false + ) ) ) ) ) - ) + }.previewDisplayName("No Button") + + NavigationView { + VaultUnlockView( + store: Store( + processor: StateProcessor( + state: VaultUnlockState( + biometricUnlockStatus: .available( + .faceID, + enabled: true, + hasValidIntegrity: true + ) + ) + ) + ) + ) + }.previewDisplayName("Face ID Button") + + NavigationView { + VaultUnlockView( + store: Store( + processor: StateProcessor( + state: VaultUnlockState( + biometricUnlockStatus: .available( + .touchID, + enabled: true, + hasValidIntegrity: true + ) + ) + ) + ) + ) + }.previewDisplayName("Touch ID Button") } } #endif diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockViewTests.swift b/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockViewTests.swift new file mode 100644 index 000000000..00ce8c33a --- /dev/null +++ b/AuthenticatorShared/UI/Auth/VaultUnlock/VaultUnlockViewTests.swift @@ -0,0 +1,52 @@ +import SnapshotTesting +import SwiftUI +import ViewInspector +import XCTest + +@testable import AuthenticatorShared + +// MARK: - VaultUnlockViewTests + +class VaultUnlockViewTests: AuthenticatorTestCase { + // MARK: Properties + + var processor: MockProcessor! + var subject: VaultUnlockView! + + // MARK: Setup & Teardown + + override func setUp() { + super.setUp() + + let state = VaultUnlockState() + processor = MockProcessor(state: state) + subject = VaultUnlockView( + store: Store(processor: processor) + ) + } + + override func tearDown() { + super.tearDown() + + processor = nil + subject = nil + } + + // MARK: Tests + + /// Test a snapshot of the ItemListView previews. + func test_snapshot_VaultUnlockView_previews() { + for preview in VaultUnlockView_Previews._allPreviews { + assertSnapshots( + of: preview.content, + as: [ + .defaultPortrait, + .defaultPortraitDark, + .defaultPortraitAX5, + .defaultLandscape, + .defaultLandscapeAX5, + ] + ) + } + } +} diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.1.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.1.png new file mode 100644 index 000000000..f590e9cb0 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.1.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.10.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.10.png new file mode 100644 index 000000000..351da8242 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.10.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.11.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.11.png new file mode 100644 index 000000000..7ea9d7ec4 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.11.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.12.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.12.png new file mode 100644 index 000000000..93c997a10 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.12.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.13.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.13.png new file mode 100644 index 000000000..11fb65291 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.13.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.14.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.14.png new file mode 100644 index 000000000..8d1607913 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.14.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.15.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.15.png new file mode 100644 index 000000000..e93726bc4 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.15.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.2.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.2.png new file mode 100644 index 000000000..9c7737fe5 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.2.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.3.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.3.png new file mode 100644 index 000000000..f590e9cb0 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.3.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.4.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.4.png new file mode 100644 index 000000000..741025806 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.4.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.5.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.5.png new file mode 100644 index 000000000..741025806 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.5.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.6.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.6.png new file mode 100644 index 000000000..fe17aa310 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.6.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.7.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.7.png new file mode 100644 index 000000000..4ce3477a6 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.7.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.8.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.8.png new file mode 100644 index 000000000..6c14cff48 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.8.png differ diff --git a/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.9.png b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.9.png new file mode 100644 index 000000000..a1531a126 Binary files /dev/null and b/AuthenticatorShared/UI/Auth/VaultUnlock/__Snapshots__/VaultUnlockViewTests/test_snapshot_VaultUnlockView_previews.9.png differ diff --git a/AuthenticatorShared/UI/Platform/Application/Extensions/View+Conditionals.swift b/AuthenticatorShared/UI/Platform/Application/Extensions/View+Conditionals.swift index de6da44e3..01ea829e2 100644 --- a/AuthenticatorShared/UI/Platform/Application/Extensions/View+Conditionals.swift +++ b/AuthenticatorShared/UI/Platform/Application/Extensions/View+Conditionals.swift @@ -84,6 +84,20 @@ extension View { } } + /// Conditionally applies the given transform if the given condition evaluates to `true`. + /// - Parameters: + /// - condition: The condition to evaluate. + /// - transform: The transform to apply to the source `View`. + /// - Returns: Either the original `View` or the modified `View` if the condition is `true`. + @ViewBuilder + func `if`(_ condition: @autoclosure () -> Bool, transform: (Self) -> Content) -> some View { + if condition() { + transform(self) + } else { + self + } + } + /// Conditionally adds an action to perform when this view recognizes a long press /// gesture. /// diff --git a/AuthenticatorShared/UI/Platform/Application/Support/Images.xcassets/authenticator-logo.imageset/Contents.json b/AuthenticatorShared/UI/Platform/Application/Support/Images.xcassets/authenticator-logo.imageset/Contents.json new file mode 100644 index 000000000..b6e3c5224 --- /dev/null +++ b/AuthenticatorShared/UI/Platform/Application/Support/Images.xcassets/authenticator-logo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "authenticator-logo.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AuthenticatorShared/UI/Platform/Application/Support/Images.xcassets/authenticator-logo.imageset/authenticator-logo.pdf b/AuthenticatorShared/UI/Platform/Application/Support/Images.xcassets/authenticator-logo.imageset/authenticator-logo.pdf new file mode 100644 index 000000000..ec8ba2f15 Binary files /dev/null and b/AuthenticatorShared/UI/Platform/Application/Support/Images.xcassets/authenticator-logo.imageset/authenticator-logo.pdf differ