fix networkd

This commit is contained in:
anlicheng 2026-03-25 15:45:13 +08:00
parent c123af8a47
commit 2c440a32c7
5 changed files with 53 additions and 26 deletions

View File

@ -18,6 +18,7 @@ class VPNManager {
private var manager: NETunnelProviderManager? private var manager: NETunnelProviderManager?
private var statusObserver: NSObjectProtocol? private var statusObserver: NSObjectProtocol?
var isConnected: Bool = false
var vpnStatus: VPNStatus = .disconnected var vpnStatus: VPNStatus = .disconnected
var vpnStatusStream: AsyncStream<VPNStatus> var vpnStatusStream: AsyncStream<VPNStatus>
@ -68,12 +69,15 @@ class VPNManager {
case .invalid, .disconnected, .disconnecting: case .invalid, .disconnected, .disconnecting:
self?.vpnStatusCont.yield(.disconnected) self?.vpnStatusCont.yield(.disconnected)
self?.vpnStatus = .disconnected self?.vpnStatus = .disconnected
self?.isConnected = false
case .connecting, .connected, .reasserting: case .connecting, .connected, .reasserting:
self?.vpnStatusCont.yield(.connected) self?.vpnStatusCont.yield(.connected)
self?.vpnStatus = .connected self?.vpnStatus = .connected
self?.isConnected = true
@unknown default: @unknown default:
self?.vpnStatusCont.yield(.disconnected) self?.vpnStatusCont.yield(.disconnected)
self?.vpnStatus = .disconnected self?.vpnStatus = .disconnected
self?.isConnected = false
} }
} }
} }

View File

@ -88,7 +88,7 @@ extension SDLAPIClient {
} }
static func `default`() -> Self { static func `default`() -> Self {
return .init(ip: "", maskLen: 24, hostname: "", identityId: 0, resourceList: [], nodeList: []) return .init(ip: "0.0.0.0", maskLen: 24, hostname: "", identityId: 0, resourceList: [], nodeList: [])
} }
func getNode(id: Int?) -> Node? { func getNode(id: Int?) -> Node? {

View File

@ -107,6 +107,11 @@ class AppContext {
} }
} }
//
func disconnectNetwork() async throws {
try await self.vpnManager.disableVpn()
}
// 退 // 退
func logout() async throws { func logout() async throws {
try await self.vpnManager.disableVpn() try await self.vpnManager.disableVpn()

View File

@ -31,31 +31,7 @@ struct NetworkView: View {
VStack(spacing: 0) { VStack(spacing: 0) {
// 1. (Header) // 1. (Header)
HStack(spacing: 16) { HStack(spacing: 16) {
ZStack { NetworkStatusBar()
Circle()
.fill(connectState == .connected ? Color.green.opacity(0.15) : Color.primary.opacity(0.05))
.frame(width: 36, height: 36)
Image(systemName: connectState == .connected ? "checkmark.shield.fill" : "shield.slash.fill")
.symbolRenderingMode(.hierarchical)
.foregroundStyle(connectState == .connected ? Color.green : Color.secondary)
.font(.system(size: 16))
}
VStack(alignment: .leading, spacing: 2) {
Text(appContext.networkSession?.networkName ?? "未连接网络")
.font(.system(size: 14, weight: .semibold))
if connectState == .connected {
Text("虚拟局域网 IP: \(self.appContext.networkContext.ip)")
.font(.system(size: 11, design: .monospaced))
.foregroundColor(.secondary)
} else {
Text("PunchNet 服务未就绪")
.font(.caption)
.foregroundColor(.secondary)
}
}
Spacer() Spacer()
@ -124,6 +100,47 @@ struct NetworkView: View {
} }
struct NetworkStatusBar: View {
@Environment(AppContext.self) private var appContext
@State private var vpnManger = VPNManager.shared
var body: some View {
HStack(spacing: 12) {
//
HStack(spacing: 20) {
ZStack {
Circle()
.fill(vpnManger.isConnected ? Color.green.opacity(0.15) : Color.primary.opacity(0.05))
.frame(width: 36, height: 36)
Image(systemName: vpnManger.isConnected ? "checkmark.shield.fill" : "shield.slash.fill")
.symbolRenderingMode(.hierarchical)
.foregroundStyle(vpnManger.isConnected ? Color.green : Color.secondary)
.font(.system(size: 16))
}
VStack(alignment: .leading, spacing: 1) {
if let networkSession = appContext.networkSession {
Text(networkSession.networkName)
.font(.system(size: 12, weight: .semibold))
Text("局域网IP: \(appContext.networkContext.ip)")
.font(.system(size: 10, design: .monospaced))
.foregroundColor(.secondary)
}
}
}
// Switch
// 使 Binding /
Toggle("", isOn: $vpnManger.isConnected)
.toggleStyle(.switch)
.controlSize(.small) // macOS 使 small
}
.padding(.vertical, 5)
}
}
struct NetworkConnectedView: View { struct NetworkConnectedView: View {
@Environment(AppContext.self) private var appContext: AppContext @Environment(AppContext.self) private var appContext: AppContext
@Binding var showMode: NetworkShowMode @Binding var showMode: NetworkShowMode

View File

@ -141,6 +141,7 @@ extension SettingsAccountView {
Task { @MainActor in Task { @MainActor in
try await appContext.logout() try await appContext.logout()
} }
self.appContext.appScene = .login(username: nil) self.appContext.appScene = .login(username: nil)
self.dismissWindow(id: "settings") self.dismissWindow(id: "settings")
self.openWindow(id: "main") self.openWindow(id: "main")