From 0fd544348fee04f2cacd41f55d19a992e4781a25 Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 4 Dec 2024 20:50:51 +0100 Subject: [PATCH] Disclose details about selected provider server configuration (#980) Like in v2. --- Library/Package.resolved | 2 +- Library/Package.swift | 2 +- .../Modules/OpenVPNView+Configuration.swift | 5 +- .../AppUIMain/Views/Modules/OpenVPNView.swift | 75 ++++++++++++------- .../Providers/ProviderContentModifier.swift | 4 +- .../UILibrary/L10n/SwiftGen+Strings.swift | 2 + .../Resources/en.lproj/Localizable.strings | 1 + 7 files changed, 60 insertions(+), 31 deletions(-) diff --git a/Library/Package.resolved b/Library/Package.resolved index 82bd861f..22cd3209 100644 --- a/Library/Package.resolved +++ b/Library/Package.resolved @@ -41,7 +41,7 @@ "kind" : "remoteSourceControl", "location" : "git@github.com:passepartoutvpn/passepartoutkit-source", "state" : { - "revision" : "4d9cb52344de9c4a075389966a706574af936c08" + "revision" : "d033e4431a24c7a7559464ef27036af9994647f2" } }, { diff --git a/Library/Package.swift b/Library/Package.swift index d9197aaa..e76e7cdb 100644 --- a/Library/Package.swift +++ b/Library/Package.swift @@ -52,7 +52,7 @@ let package = Package( ], dependencies: [ // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.12.0"), - .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "4d9cb52344de9c4a075389966a706574af936c08"), + .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "d033e4431a24c7a7559464ef27036af9994647f2"), // .package(path: "../../passepartoutkit-source"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.9.1"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"), diff --git a/Library/Sources/AppUIMain/Views/Modules/OpenVPNView+Configuration.swift b/Library/Sources/AppUIMain/Views/Modules/OpenVPNView+Configuration.swift index cea65555..6cd7dc90 100644 --- a/Library/Sources/AppUIMain/Views/Modules/OpenVPNView+Configuration.swift +++ b/Library/Sources/AppUIMain/Views/Modules/OpenVPNView+Configuration.swift @@ -32,7 +32,7 @@ extension OpenVPNView { let configuration: OpenVPN.Configuration.Builder - let credentialsRoute: any Hashable + let credentialsRoute: (any Hashable)? var body: some View { moduleSection(for: accountRows, header: Strings.Global.Nouns.account) @@ -63,6 +63,9 @@ extension OpenVPNView { private extension OpenVPNView.ConfigurationView { var accountRows: [ModuleRow]? { + guard let credentialsRoute else { + return nil + } guard configuration.authUserPass == true else { return nil } diff --git a/Library/Sources/AppUIMain/Views/Modules/OpenVPNView.swift b/Library/Sources/AppUIMain/Views/Modules/OpenVPNView.swift index 40d76a62..9e7e74c3 100644 --- a/Library/Sources/AppUIMain/Views/Modules/OpenVPNView.swift +++ b/Library/Sources/AppUIMain/Views/Modules/OpenVPNView.swift @@ -106,40 +106,50 @@ private extension OpenVPNView { credentialsRoute: Subroute.credentials ) } else { - importButton + emptyConfigurationView .modifier(providerModifier) } } @ViewBuilder - var importButton: some View { - if draft.wrappedValue.providerId == nil { - Button(Strings.Modules.General.Rows.importFromFile.withTrailingDots) { - isImporting = true - } - .alert( - module.moduleType.localizedDescription, - isPresented: $requiresPassphrase, - presenting: importURL, - actions: { url in - SecureField( - Strings.Placeholders.secret, - text: $importPassphrase ?? "" - ) - Button(Strings.Alerts.Import.Passphrase.ok) { - importConfiguration(from: .success(url)) - } - Button(Strings.Global.Actions.cancel, role: .cancel) { - isImporting = false - } - }, - message: { - Text(Strings.Alerts.Import.Passphrase.message($0.lastPathComponent)) - } - ) + var emptyConfigurationView: some View { + if draft.wrappedValue.providerSelection == nil { + importButton + } else if let configuration = try? draft.wrappedValue.providerSelection?.configuration() { + providerConfigurationLink(with: configuration) } } + func providerConfigurationLink(with configuration: OpenVPN.Configuration) -> some View { + NavigationLink(Strings.Global.Nouns.configuration, value: Subroute.providerConfiguration(configuration)) + } + + var importButton: some View { + Button(Strings.Modules.General.Rows.importFromFile.withTrailingDots) { + isImporting = true + } + .alert( + module.moduleType.localizedDescription, + isPresented: $requiresPassphrase, + presenting: importURL, + actions: { url in + SecureField( + Strings.Placeholders.secret, + text: $importPassphrase ?? "" + ) + Button(Strings.Alerts.Import.Passphrase.ok) { + importConfiguration(from: .success(url)) + } + Button(Strings.Global.Actions.cancel, role: .cancel) { + isImporting = false + } + }, + message: { + Text(Strings.Alerts.Import.Passphrase.message($0.lastPathComponent)) + } + ) + } + var providerModifier: some ViewModifier { VPNProviderContentModifier( providerId: providerId, @@ -207,6 +217,8 @@ private extension OpenVPNView { enum Subroute: Hashable { case providerServer + case providerConfiguration(OpenVPN.Configuration) + case credentials } @@ -224,6 +236,17 @@ private extension OpenVPNView { ) } + case .providerConfiguration(let configuration): + Form { + ConfigurationView( + isServerPushed: false, + configuration: configuration.builder(), + credentialsRoute: nil + ) + } + .themeForm() + .navigationTitle(Strings.Global.Nouns.configuration) + case .credentials: Form { OpenVPNCredentialsView( diff --git a/Library/Sources/AppUIMain/Views/Providers/ProviderContentModifier.swift b/Library/Sources/AppUIMain/Views/Providers/ProviderContentModifier.swift index 5128826a..321b3aed 100644 --- a/Library/Sources/AppUIMain/Views/Providers/ProviderContentModifier.swift +++ b/Library/Sources/AppUIMain/Views/Providers/ProviderContentModifier.swift @@ -117,7 +117,9 @@ private extension ProviderContentModifier { paywallReason: $paywallReason ) } +} +private extension ProviderContentModifier { var supportedProviders: [Provider] { providerManager .providers @@ -139,9 +141,7 @@ private extension ProviderContentModifier { } return Strings.Views.Providers.lastUpdated(lastUpdate.localizedDescription(style: .timestamp)) } -} -private extension ProviderContentModifier { func loadCurrentProvider() { Task { await refreshIndex() diff --git a/Library/Sources/UILibrary/L10n/SwiftGen+Strings.swift b/Library/Sources/UILibrary/L10n/SwiftGen+Strings.swift index b3f0000f..c44cce5e 100644 --- a/Library/Sources/UILibrary/L10n/SwiftGen+Strings.swift +++ b/Library/Sources/UILibrary/L10n/SwiftGen+Strings.swift @@ -238,6 +238,8 @@ public enum Strings { public static let certificate = Strings.tr("Localizable", "global.nouns.certificate", fallback: "Certificate") /// Compression public static let compression = Strings.tr("Localizable", "global.nouns.compression", fallback: "Compression") + /// Configuration + public static let configuration = Strings.tr("Localizable", "global.nouns.configuration", fallback: "Configuration") /// Connection public static let connection = Strings.tr("Localizable", "global.nouns.connection", fallback: "Connection") /// Country diff --git a/Library/Sources/UILibrary/Resources/en.lproj/Localizable.strings b/Library/Sources/UILibrary/Resources/en.lproj/Localizable.strings index c1e951a2..f9df6065 100644 --- a/Library/Sources/UILibrary/Resources/en.lproj/Localizable.strings +++ b/Library/Sources/UILibrary/Resources/en.lproj/Localizable.strings @@ -259,6 +259,7 @@ "global.nouns.category" = "Category"; "global.nouns.certificate" = "Certificate"; "global.nouns.compression" = "Compression"; +"global.nouns.configuration" = "Configuration"; "global.nouns.connection" = "Connection"; "global.nouns.country" = "Country"; "global.nouns.default" = "Default";