diff --git a/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 5b5f3f02..d7067950 100644 --- a/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -51,7 +51,7 @@ "repositoryURL": "https://github.com/passepartoutvpn/tunnelkit", "state": { "branch": null, - "revision": "e075ba6a76ccfa0cc667a58933fb124c95c1f33d", + "revision": "6e0471a55b8277ff0b21e4dd3dfcfcc8da5f0355", "version": null } }, diff --git a/Passepartout/App/Views/VPNToggle.swift b/Passepartout/App/Views/VPNToggle.swift index 373578e1..89f141bc 100644 --- a/Passepartout/App/Views/VPNToggle.swift +++ b/Passepartout/App/Views/VPNToggle.swift @@ -37,18 +37,12 @@ struct VPNToggle: View { private var isEnabled: Binding { .init { - isLocallyEnabled - } set: { - guard toggleVPN() else { - return - } - isLocallyEnabled = $0 + currentVPNState.isEnabled + } set: { _ in + _ = toggleVPN() } } - // local copy grants immediate visual feedback and smooth animation - @State private var isLocallyEnabled = false - @State private var canToggle = true init(rateLimit: Int, onToggle: (() -> Void)? = nil) { @@ -60,11 +54,8 @@ struct VPNToggle: View { var body: some View { Toggle(L10n.Global.Strings.enabled, isOn: isEnabled) - .onAppear { - isLocallyEnabled = currentVPNState.isEnabled - }.onChange(of: currentVPNState.isEnabled) { - isLocallyEnabled = $0 - }.disabled(!canToggle) + .disabled(!canToggle) + .themeAnimation(on: currentVPNState.isEnabled) } private func toggleVPN() -> Bool { diff --git a/PassepartoutCore/Package.swift b/PassepartoutCore/Package.swift index 2f5835b3..ec5430f4 100644 --- a/PassepartoutCore/Package.swift +++ b/PassepartoutCore/Package.swift @@ -24,7 +24,7 @@ let package = Package( // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), // .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", from: "4.1.0"), - .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("e075ba6a76ccfa0cc667a58933fb124c95c1f33d")), + .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("6e0471a55b8277ff0b21e4dd3dfcfcc8da5f0355")), // .package(name: "TunnelKit", path: "../../tunnelkit"), .package(url: "https://github.com/zoul/generic-json-swift", from: "2.0.0"), .package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver", from: "1.9.0") diff --git a/PassepartoutCore/Sources/PassepartoutCore/Managers/VPNManagerStrategy+TunnelKit.swift b/PassepartoutCore/Sources/PassepartoutCore/Managers/VPNManagerStrategy+TunnelKit.swift index f5b575aa..c826bcc6 100644 --- a/PassepartoutCore/Sources/PassepartoutCore/Managers/VPNManagerStrategy+TunnelKit.swift +++ b/PassepartoutCore/Sources/PassepartoutCore/Managers/VPNManagerStrategy+TunnelKit.swift @@ -92,6 +92,7 @@ extension VPNManager { private func registerNotification(withName name: Notification.Name, perform: @escaping (Notification) -> Void) { NotificationCenter.default.publisher(for: name, object: nil) + .receive(on: DispatchQueue.main) .sink(receiveValue: perform) .store(in: &cancellables) } @@ -157,6 +158,12 @@ extension VPNManager { public func removeConfigurations() async { await vpn.uninstall() + + // XXX: force isEnabled to false as it's not properly notified by NetworkExtension + vpnState.send(AtomicState( + isEnabled: false, + vpnStatus: vpnState.value.vpnStatus + )) } // MARK: Notifications @@ -197,6 +204,10 @@ extension VPNManager { } private func onVPNFail(_ notification: Notification) { + vpnState.send(AtomicState( + isEnabled: notification.vpnIsEnabled, + vpnStatus: vpnState.value.vpnStatus + )) currentState?.lastError = notification.vpnError }