Address VPN toggle losing sync with internal state
- Update TunnelKit - Receive TunnelKit notifications on main queue - Bind VPN toggle to VPNManager directly (implicit animations) - Update state on VPN didFail - Set isEnabled = false after uninstalling VPN (not notified)
This commit is contained in:
parent
a7258b3a94
commit
49a1f1b55c
|
@ -51,7 +51,7 @@
|
|||
"repositoryURL": "https://github.com/passepartoutvpn/tunnelkit",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "e075ba6a76ccfa0cc667a58933fb124c95c1f33d",
|
||||
"revision": "6e0471a55b8277ff0b21e4dd3dfcfcc8da5f0355",
|
||||
"version": null
|
||||
}
|
||||
},
|
||||
|
|
|
@ -37,18 +37,12 @@ struct VPNToggle: View {
|
|||
|
||||
private var isEnabled: Binding<Bool> {
|
||||
.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 {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue