This commit is contained in:
anlicheng 2026-04-17 14:19:16 +08:00
parent 58507e2f06
commit ef99a81d76
4 changed files with 536 additions and 282 deletions

View File

@ -29,7 +29,9 @@ class VPNManager {
private var vpnStatusCont: AsyncStream<VPNStatus>.Continuation private var vpnStatusCont: AsyncStream<VPNStatus>.Continuation
enum VPNStatus { enum VPNStatus {
case connecting
case connected case connected
case disconnecting
case disconnected case disconnected
} }
@ -93,11 +95,19 @@ class VPNManager {
self.statusObserver = NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: manager.connection, queue: .main) {[weak self] _ in self.statusObserver = NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: manager.connection, queue: .main) {[weak self] _ in
NSLog("status channge: \(manager.connection.status)") NSLog("status channge: \(manager.connection.status)")
switch manager.connection.status { switch manager.connection.status {
case .invalid, .disconnected, .disconnecting: case .invalid, .disconnected:
self?.vpnStatusCont.yield(.disconnected) self?.vpnStatusCont.yield(.disconnected)
self?.vpnStatus = .disconnected self?.vpnStatus = .disconnected
self?.isConnected = false self?.isConnected = false
case .connecting, .connected, .reasserting: case .disconnecting:
self?.vpnStatusCont.yield(.disconnecting)
self?.vpnStatus = .disconnecting
self?.isConnected = false
case .connecting, .reasserting:
self?.vpnStatusCont.yield(.connecting)
self?.vpnStatus = .connecting
self?.isConnected = true
case .connected:
self?.vpnStatusCont.yield(.connected) self?.vpnStatusCont.yield(.connected)
self?.vpnStatus = .connected self?.vpnStatus = .connected
self?.isConnected = true self?.isConnected = true

View File

@ -146,6 +146,7 @@ class AppContext {
// //
func stopTun() async throws { func stopTun() async throws {
try await self.vpnManager.disableVpn() try await self.vpnManager.disableVpn()
self.networkContext = nil
} }
// 退 // 退

View File

@ -18,11 +18,23 @@ struct MainMenuBar: View {
case .connected: case .connected:
Button(action: { Button(action: {
Task { @MainActor in Task { @MainActor in
try await vpnManager.disableVpn() try await appContext.stopTun()
} }
}, label: { }, label: {
Text("停止") Text("停止")
}) })
case .connecting:
Button(action: {
}, label: {
Text("连接中...")
})
.disabled(true)
case .disconnecting:
Button(action: {
}, label: {
Text("断开中...")
})
.disabled(true)
case .disconnected: case .disconnected:
Button(action: { Button(action: {
Task { @MainActor in Task { @MainActor in
@ -55,8 +67,13 @@ struct MainMenuBar: View {
} }
private func startVPN() async { private func startVPN() async {
if let options = appContext.vpnOptions { do {
try? await vpnManager.enableVpn(options: options) if appContext.networkContext == nil {
try await appContext.connectNetwork()
}
try await appContext.startTun()
} catch {
NSLog("menu start vpn failed: \(error)")
} }
} }

File diff suppressed because it is too large Load Diff