Late dismissal after changing active provider server (#804)

The dismissal action waited until the current connection was
disconnected.

Consider that AppContext makes the explicit .connect() redundant,
reconnection is already happening after saving a profile while
connected.
This commit is contained in:
Davide 2024-11-03 11:12:19 +01:00 committed by GitHub
parent 3f7ad5bf57
commit fff21c3250
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 40 additions and 21 deletions

View File

@ -23,12 +23,14 @@
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
//
import CommonUtils
import PassepartoutKit
import SwiftUI
extension ProviderEntityViewProviding where Self: ProviderCompatibleModule, EntityType.Configuration: ProviderConfigurationIdentifiable & Codable {
func vpnProviderEntityView(
with provider: ModuleMetadata.Provider,
errorHandler: ErrorHandler,
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
) -> some View {
let selectedEntity = try? provider
@ -40,6 +42,7 @@ extension ProviderEntityViewProviding where Self: ProviderCompatibleModule, Enti
return VPNProviderServerCoordinator(
moduleId: id,
providerId: provider.id,
errorHandler: errorHandler,
selectedEntity: selectedEntity,
onSelect: onSelect
)

View File

@ -23,6 +23,7 @@
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
//
import CommonUtils
import PassepartoutKit
import SwiftUI
@ -32,6 +33,7 @@ protocol ProviderEntityViewProviding {
@MainActor
func providerEntityView(
with provider: ModuleMetadata.Provider,
errorHandler: ErrorHandler,
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
) -> EntityContent
}

View File

@ -25,6 +25,7 @@
import AppLibrary
import CommonLibrary
import CommonUtils
import PassepartoutKit
import SwiftUI
@ -51,6 +52,9 @@ public struct AppCoordinator: View, AppCoordinatorConforming {
@State
private var profilePath = NavigationPath()
@StateObject
private var errorHandler: ErrorHandler = .default()
public init(
profileManager: ProfileManager,
tunnel: ExtendedTunnel,
@ -114,6 +118,7 @@ extension AppCoordinator {
tunnel: tunnel,
registry: registry,
isImporting: $isImporting,
errorHandler: errorHandler,
flow: .init(
onEditProfile: {
guard let profile = profileManager.profile(withId: $0.id) else {
@ -167,7 +172,8 @@ extension AppCoordinator {
tunnel: tunnel,
profile: profile,
module: module,
provider: provider
provider: provider,
errorHandler: errorHandler
)
case .settings:

View File

@ -40,14 +40,14 @@ struct ProfileContainerView: View, Routable {
@Binding
var isImporting: Bool
@ObservedObject
var errorHandler: ErrorHandler
var flow: ProfileFlow?
@StateObject
private var interactiveManager = InteractiveManager()
@StateObject
private var errorHandler: ErrorHandler = .default()
var body: some View {
debugChanges()
return innerView
@ -150,7 +150,8 @@ private struct PreviewView: View {
profileManager: .mock,
tunnel: .mock,
registry: Registry(),
isImporting: .constant(false)
isImporting: .constant(false),
errorHandler: .default()
)
}
.withMockEnvironment()

View File

@ -24,6 +24,7 @@
//
import AppLibrary
import CommonUtils
import PassepartoutKit
import SwiftUI
@ -44,9 +45,15 @@ struct ProviderEntitySelector: View {
let provider: ModuleMetadata.Provider
let errorHandler: ErrorHandler
var body: some View {
if let viewProvider = module as? any ProviderEntityViewProviding {
AnyView(viewProvider.providerEntityView(with: provider, onSelect: onSelect))
AnyView(viewProvider.providerEntityView(
with: provider,
errorHandler: errorHandler,
onSelect: onSelect
))
} else {
fatalError("Module got too far without being ProviderEntityViewProviding: \(module)")
}
@ -58,16 +65,15 @@ private extension ProviderEntitySelector {
pp_log(.app, .info, "Select new provider entity: \(entity)")
var builder = profile.builder()
try builder.setProviderEntity(entity, forModuleWithId: module.id)
let newProfile = try builder.tryBuild()
try await profileManager.save(newProfile)
do {
try builder.setProviderEntity(entity, forModuleWithId: module.id)
let newProfile = try builder.tryBuild()
try await profileManager.save(newProfile)
Task {
do {
try await tunnel.connect(with: newProfile, processor: profileProcessor)
} catch {
pp_log(.app, .error, "Unable to connect with new provider entity: \(error)")
}
// will reconnect via AppContext observation
} catch {
pp_log(.app, .error, "Unable to save new provider entity: \(error)")
throw error
}
}
}

View File

@ -23,6 +23,7 @@
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
//
import CommonUtils
import PassepartoutKit
import SwiftUI
@ -35,8 +36,9 @@ extension OpenVPNModule.Builder: ModuleViewProviding {
extension OpenVPNModule: ProviderEntityViewProviding {
func providerEntityView(
with provider: ModuleMetadata.Provider,
errorHandler: ErrorHandler,
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
) -> some View {
vpnProviderEntityView(with: provider, onSelect: onSelect)
vpnProviderEntityView(with: provider, errorHandler: errorHandler, onSelect: onSelect)
}
}

View File

@ -36,13 +36,13 @@ struct VPNProviderServerCoordinator<Configuration>: View where Configuration: Pr
let providerId: ProviderID
@ObservedObject
var errorHandler: ErrorHandler
let selectedEntity: VPNEntity<Configuration>?
let onSelect: (VPNEntity<Configuration>) async throws -> Void
@StateObject
private var errorHandler: ErrorHandler = .default()
var body: some View {
NavigationStack {
VPNProviderServerView(
@ -67,7 +67,6 @@ struct VPNProviderServerCoordinator<Configuration>: View where Configuration: Pr
}
}
}
.withErrorHandler(errorHandler)
}
}
}
@ -77,8 +76,8 @@ private extension VPNProviderServerCoordinator {
Task {
do {
let entity = VPNEntity(server: server, preset: preset)
try await onSelect(entity)
dismiss()
try await onSelect(entity)
} catch {
pp_log(.app, .fault, "Unable to select server \(server.serverId) for provider \(server.provider.id): \(error)")
errorHandler.handle(error, title: Strings.Global.servers)