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:
parent
3f7ad5bf57
commit
fff21c3250
|
@ -23,12 +23,14 @@
|
||||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
extension ProviderEntityViewProviding where Self: ProviderCompatibleModule, EntityType.Configuration: ProviderConfigurationIdentifiable & Codable {
|
extension ProviderEntityViewProviding where Self: ProviderCompatibleModule, EntityType.Configuration: ProviderConfigurationIdentifiable & Codable {
|
||||||
func vpnProviderEntityView(
|
func vpnProviderEntityView(
|
||||||
with provider: ModuleMetadata.Provider,
|
with provider: ModuleMetadata.Provider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
|
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
|
||||||
) -> some View {
|
) -> some View {
|
||||||
let selectedEntity = try? provider
|
let selectedEntity = try? provider
|
||||||
|
@ -40,6 +42,7 @@ extension ProviderEntityViewProviding where Self: ProviderCompatibleModule, Enti
|
||||||
return VPNProviderServerCoordinator(
|
return VPNProviderServerCoordinator(
|
||||||
moduleId: id,
|
moduleId: id,
|
||||||
providerId: provider.id,
|
providerId: provider.id,
|
||||||
|
errorHandler: errorHandler,
|
||||||
selectedEntity: selectedEntity,
|
selectedEntity: selectedEntity,
|
||||||
onSelect: onSelect
|
onSelect: onSelect
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ protocol ProviderEntityViewProviding {
|
||||||
@MainActor
|
@MainActor
|
||||||
func providerEntityView(
|
func providerEntityView(
|
||||||
with provider: ModuleMetadata.Provider,
|
with provider: ModuleMetadata.Provider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
|
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
|
||||||
) -> EntityContent
|
) -> EntityContent
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
import AppLibrary
|
import AppLibrary
|
||||||
import CommonLibrary
|
import CommonLibrary
|
||||||
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@ -51,6 +52,9 @@ public struct AppCoordinator: View, AppCoordinatorConforming {
|
||||||
@State
|
@State
|
||||||
private var profilePath = NavigationPath()
|
private var profilePath = NavigationPath()
|
||||||
|
|
||||||
|
@StateObject
|
||||||
|
private var errorHandler: ErrorHandler = .default()
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
profileManager: ProfileManager,
|
profileManager: ProfileManager,
|
||||||
tunnel: ExtendedTunnel,
|
tunnel: ExtendedTunnel,
|
||||||
|
@ -114,6 +118,7 @@ extension AppCoordinator {
|
||||||
tunnel: tunnel,
|
tunnel: tunnel,
|
||||||
registry: registry,
|
registry: registry,
|
||||||
isImporting: $isImporting,
|
isImporting: $isImporting,
|
||||||
|
errorHandler: errorHandler,
|
||||||
flow: .init(
|
flow: .init(
|
||||||
onEditProfile: {
|
onEditProfile: {
|
||||||
guard let profile = profileManager.profile(withId: $0.id) else {
|
guard let profile = profileManager.profile(withId: $0.id) else {
|
||||||
|
@ -167,7 +172,8 @@ extension AppCoordinator {
|
||||||
tunnel: tunnel,
|
tunnel: tunnel,
|
||||||
profile: profile,
|
profile: profile,
|
||||||
module: module,
|
module: module,
|
||||||
provider: provider
|
provider: provider,
|
||||||
|
errorHandler: errorHandler
|
||||||
)
|
)
|
||||||
|
|
||||||
case .settings:
|
case .settings:
|
||||||
|
|
|
@ -40,14 +40,14 @@ struct ProfileContainerView: View, Routable {
|
||||||
@Binding
|
@Binding
|
||||||
var isImporting: Bool
|
var isImporting: Bool
|
||||||
|
|
||||||
|
@ObservedObject
|
||||||
|
var errorHandler: ErrorHandler
|
||||||
|
|
||||||
var flow: ProfileFlow?
|
var flow: ProfileFlow?
|
||||||
|
|
||||||
@StateObject
|
@StateObject
|
||||||
private var interactiveManager = InteractiveManager()
|
private var interactiveManager = InteractiveManager()
|
||||||
|
|
||||||
@StateObject
|
|
||||||
private var errorHandler: ErrorHandler = .default()
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
debugChanges()
|
debugChanges()
|
||||||
return innerView
|
return innerView
|
||||||
|
@ -150,7 +150,8 @@ private struct PreviewView: View {
|
||||||
profileManager: .mock,
|
profileManager: .mock,
|
||||||
tunnel: .mock,
|
tunnel: .mock,
|
||||||
registry: Registry(),
|
registry: Registry(),
|
||||||
isImporting: .constant(false)
|
isImporting: .constant(false),
|
||||||
|
errorHandler: .default()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.withMockEnvironment()
|
.withMockEnvironment()
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import AppLibrary
|
import AppLibrary
|
||||||
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@ -44,9 +45,15 @@ struct ProviderEntitySelector: View {
|
||||||
|
|
||||||
let provider: ModuleMetadata.Provider
|
let provider: ModuleMetadata.Provider
|
||||||
|
|
||||||
|
let errorHandler: ErrorHandler
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if let viewProvider = module as? any ProviderEntityViewProviding {
|
if let viewProvider = module as? any ProviderEntityViewProviding {
|
||||||
AnyView(viewProvider.providerEntityView(with: provider, onSelect: onSelect))
|
AnyView(viewProvider.providerEntityView(
|
||||||
|
with: provider,
|
||||||
|
errorHandler: errorHandler,
|
||||||
|
onSelect: onSelect
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
fatalError("Module got too far without being ProviderEntityViewProviding: \(module)")
|
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)")
|
pp_log(.app, .info, "Select new provider entity: \(entity)")
|
||||||
|
|
||||||
var builder = profile.builder()
|
var builder = profile.builder()
|
||||||
try builder.setProviderEntity(entity, forModuleWithId: module.id)
|
do {
|
||||||
let newProfile = try builder.tryBuild()
|
try builder.setProviderEntity(entity, forModuleWithId: module.id)
|
||||||
try await profileManager.save(newProfile)
|
let newProfile = try builder.tryBuild()
|
||||||
|
try await profileManager.save(newProfile)
|
||||||
|
|
||||||
Task {
|
// will reconnect via AppContext observation
|
||||||
do {
|
} catch {
|
||||||
try await tunnel.connect(with: newProfile, processor: profileProcessor)
|
pp_log(.app, .error, "Unable to save new provider entity: \(error)")
|
||||||
} catch {
|
throw error
|
||||||
pp_log(.app, .error, "Unable to connect with new provider entity: \(error)")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@ -35,8 +36,9 @@ extension OpenVPNModule.Builder: ModuleViewProviding {
|
||||||
extension OpenVPNModule: ProviderEntityViewProviding {
|
extension OpenVPNModule: ProviderEntityViewProviding {
|
||||||
func providerEntityView(
|
func providerEntityView(
|
||||||
with provider: ModuleMetadata.Provider,
|
with provider: ModuleMetadata.Provider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
|
onSelect: @escaping (any ProviderEntity & Encodable) async throws -> Void
|
||||||
) -> some View {
|
) -> some View {
|
||||||
vpnProviderEntityView(with: provider, onSelect: onSelect)
|
vpnProviderEntityView(with: provider, errorHandler: errorHandler, onSelect: onSelect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,13 +36,13 @@ struct VPNProviderServerCoordinator<Configuration>: View where Configuration: Pr
|
||||||
|
|
||||||
let providerId: ProviderID
|
let providerId: ProviderID
|
||||||
|
|
||||||
|
@ObservedObject
|
||||||
|
var errorHandler: ErrorHandler
|
||||||
|
|
||||||
let selectedEntity: VPNEntity<Configuration>?
|
let selectedEntity: VPNEntity<Configuration>?
|
||||||
|
|
||||||
let onSelect: (VPNEntity<Configuration>) async throws -> Void
|
let onSelect: (VPNEntity<Configuration>) async throws -> Void
|
||||||
|
|
||||||
@StateObject
|
|
||||||
private var errorHandler: ErrorHandler = .default()
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
VPNProviderServerView(
|
VPNProviderServerView(
|
||||||
|
@ -67,7 +67,6 @@ struct VPNProviderServerCoordinator<Configuration>: View where Configuration: Pr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.withErrorHandler(errorHandler)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,8 +76,8 @@ private extension VPNProviderServerCoordinator {
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let entity = VPNEntity(server: server, preset: preset)
|
let entity = VPNEntity(server: server, preset: preset)
|
||||||
try await onSelect(entity)
|
|
||||||
dismiss()
|
dismiss()
|
||||||
|
try await onSelect(entity)
|
||||||
} catch {
|
} catch {
|
||||||
pp_log(.app, .fault, "Unable to select server \(server.serverId) for provider \(server.provider.id): \(error)")
|
pp_log(.app, .fault, "Unable to select server \(server.serverId) for provider \(server.provider.id): \(error)")
|
||||||
errorHandler.handle(error, title: Strings.Global.servers)
|
errorHandler.handle(error, title: Strings.Global.servers)
|
||||||
|
|
Loading…
Reference in New Issue