From fbe2d841136f0365c3e3c370895a1615d91cfab9 Mon Sep 17 00:00:00 2001 From: Davide Date: Sun, 3 Nov 2024 11:27:12 +0100 Subject: [PATCH] Submit on OpenVPN fields (#805) Submit on password or OTP depending on the selected method. --- .../Protocols/InteractiveViewProviding.swift | 2 +- .../Extensions/OpenVPNModule+Extensions.swift | 5 +- .../Modules/OpenVPNView+Credentials.swift | 57 +++++++++++++------ .../Views/UI/InteractiveCoordinator.swift | 2 +- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/Passepartout/Library/Sources/UILibrary/Protocols/InteractiveViewProviding.swift b/Passepartout/Library/Sources/UILibrary/Protocols/InteractiveViewProviding.swift index 31063522..d115cceb 100644 --- a/Passepartout/Library/Sources/UILibrary/Protocols/InteractiveViewProviding.swift +++ b/Passepartout/Library/Sources/UILibrary/Protocols/InteractiveViewProviding.swift @@ -29,5 +29,5 @@ public protocol InteractiveViewProviding { associatedtype InteractiveContent: View @MainActor - func interactiveView(with editor: ProfileEditor) -> InteractiveContent + func interactiveView(with editor: ProfileEditor, onSubmit: @escaping () -> Void) -> InteractiveContent } diff --git a/Passepartout/Library/Sources/UILibrary/Views/Modules/Extensions/OpenVPNModule+Extensions.swift b/Passepartout/Library/Sources/UILibrary/Views/Modules/Extensions/OpenVPNModule+Extensions.swift index dcf7eb5e..356f1d6a 100644 --- a/Passepartout/Library/Sources/UILibrary/Views/Modules/Extensions/OpenVPNModule+Extensions.swift +++ b/Passepartout/Library/Sources/UILibrary/Views/Modules/Extensions/OpenVPNModule+Extensions.swift @@ -27,13 +27,14 @@ import PassepartoutKit import SwiftUI extension OpenVPNModule.Builder: InteractiveViewProviding { - public func interactiveView(with editor: ProfileEditor) -> some View { + public func interactiveView(with editor: ProfileEditor, onSubmit: @escaping () -> Void) -> some View { let draft = editor[self] return OpenVPNCredentialsView( isInteractive: draft.isInteractive, credentials: draft.credentials, - isAuthenticating: true + isAuthenticating: true, + onSubmit: onSubmit ) } } diff --git a/Passepartout/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift b/Passepartout/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift index d59919c3..e1d7e712 100644 --- a/Passepartout/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift +++ b/Passepartout/Library/Sources/UILibrary/Views/Modules/OpenVPNView+Credentials.swift @@ -46,7 +46,9 @@ public struct OpenVPNCredentialsView: View { @Binding private var credentials: OpenVPN.Credentials? - private var isAuthenticating = false + private let isAuthenticating: Bool + + private let onSubmit: (() -> Void)? @State private var builder = OpenVPN.Credentials.Builder() @@ -60,11 +62,13 @@ public struct OpenVPNCredentialsView: View { public init( isInteractive: Binding, credentials: Binding, - isAuthenticating: Bool = false + isAuthenticating: Bool = false, + onSubmit: (() -> Void)? = nil ) { _isInteractive = isInteractive _credentials = credentials self.isAuthenticating = isAuthenticating + self.onSubmit = onSubmit } public var body: some View { @@ -154,22 +158,11 @@ private extension OpenVPNCredentialsView { var inputSection: some View { Group { if !isAuthenticating || builder.otpMethod == .none { - ThemeTextField(Strings.Global.username, text: $builder.username, placeholder: Strings.Placeholders.username) - .textContentType(.username) - .focused($focusedField, equals: .username) - - ThemeSecureField(title: Strings.Global.password, text: $builder.password, placeholder: Strings.Placeholders.secret) - .textContentType(.password) - .focused($focusedField, equals: .password) + usernameField + passwordField } if isEligibleForInteractiveLogin, isAuthenticating, builder.otpMethod != .none { - ThemeSecureField( - title: Strings.Unlocalized.otp, - text: $builder.otp ?? "", - placeholder: Strings.Placeholders.secret - ) - .textContentType(.oneTimeCode) - .focused($focusedField, equals: .otp) + otpField } } .themeSection(footer: inputFooter) @@ -182,6 +175,38 @@ private extension OpenVPNCredentialsView { } return nil } + + var usernameField: some View { + ThemeTextField(Strings.Global.username, text: $builder.username, placeholder: Strings.Placeholders.username) + .textContentType(.username) + .focused($focusedField, equals: .username) + } + + var passwordField: some View { + ThemeSecureField(title: Strings.Global.password, text: $builder.password, placeholder: Strings.Placeholders.secret) + .textContentType(.password) + .focused($focusedField, equals: .password) + .onSubmit { + if builder.otpMethod == .none { + onSubmit?() + } + } + } + + var otpField: some View { + ThemeSecureField( + title: Strings.Unlocalized.otp, + text: $builder.otp ?? "", + placeholder: Strings.Placeholders.secret + ) + .textContentType(.oneTimeCode) + .focused($focusedField, equals: .otp) + .onSubmit { + if builder.otpMethod != .none { + onSubmit?() + } + } + } } #Preview { diff --git a/Passepartout/Library/Sources/UILibrary/Views/UI/InteractiveCoordinator.swift b/Passepartout/Library/Sources/UILibrary/Views/UI/InteractiveCoordinator.swift index f4b0d631..10e2fbee 100644 --- a/Passepartout/Library/Sources/UILibrary/Views/UI/InteractiveCoordinator.swift +++ b/Passepartout/Library/Sources/UILibrary/Views/UI/InteractiveCoordinator.swift @@ -163,7 +163,7 @@ private extension InteractiveCoordinator { } func innerView(with provider: any InteractiveViewProviding) -> some View { - AnyView(provider.interactiveView(with: manager.editor)) + AnyView(provider.interactiveView(with: manager.editor, onSubmit: confirm)) } func confirm() {