diff --git a/punchnet/Views/AppContext.swift b/punchnet/Views/AppContext.swift index 95d8291..fd0ba93 100644 --- a/punchnet/Views/AppContext.swift +++ b/punchnet/Views/AppContext.swift @@ -13,12 +13,14 @@ class AppContext { var noticePort: Int // 调用 "/connect" 之后的网络信息 - var networkContext: SDLAPIClient.NetworkContext? + var networkContext: SDLAPIClient.NetworkContext = .default() - var loginCredit: Credit? // 当前app所处的场景 var appScene: AppScene = .login(username: nil) + // 登陆凭证 + var loginCredit: Credit? + enum Credit { case token(token: String, session: SDLAPIClient.NetworkSession) case accountAndPasword(account: String, password: String, session: SDLAPIClient.NetworkSession) @@ -68,7 +70,27 @@ class AppContext { } } - + // 连接到对应的网络 + func connectNetwork() async throws { + guard let session = self.networkSession else { + return + } + + let context = try await SDLAPIClient.connectNetwork(accesToken: session.accessToken) + if let options = SystemConfig.getOptions( + networkId: UInt32(session.networkId), + networkDomain: session.networkDomain, + ip: context.ip, + maskLen: context.maskLen, + accessToken: session.accessToken, + identityId: context.identityId, + hostname: context.hostname, + noticePort: noticePort + ) { + try await VPNManager.shared.enableVpn(options: options) + self.networkContext = context + } + } func loadCacheToken() -> String? { if let data = try? KeychainStore.shared.load(account: "token") { diff --git a/punchnet/Views/Network/NetworkModel.swift b/punchnet/Views/Network/NetworkModel.swift deleted file mode 100644 index 1164b4d..0000000 --- a/punchnet/Views/Network/NetworkModel.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// NetworkModel.swift -// punchnet -// -// Created by 安礼成 on 2026/3/24. -// -import Foundation -import Observation - -@Observable -class NetworkModel { - var networkContext: SDLAPIClient.NetworkContext = .default() - - func connectNetwork(accessToken: String) async throws { - self.networkContext = try await SDLAPIClient.connectNetwork(accesToken: accessToken) - } -} diff --git a/punchnet/Views/Network/NetworkView.swift b/punchnet/Views/Network/NetworkView.swift index 3233195..56f3041 100644 --- a/punchnet/Views/Network/NetworkView.swift +++ b/punchnet/Views/Network/NetworkView.swift @@ -25,9 +25,6 @@ struct NetworkView: View { @State private var showMode: NetworkShowMode = .resource @State private var connectState: ConnectState = .disconnected - // 多个View之间共享变量的最佳方式 - @State private var networkModel: NetworkModel = NetworkModel() - private var vpnManager = VPNManager.shared var body: some View { @@ -50,7 +47,7 @@ struct NetworkView: View { .font(.system(size: 14, weight: .semibold)) if connectState == .connected { - Text("虚拟局域网 IP: \(networkModel.networkContext.ip)") + Text("虚拟局域网 IP: \(self.appContext.networkContext.ip)") .font(.system(size: 11, design: .monospaced)) .foregroundColor(.secondary) } else { @@ -103,7 +100,6 @@ struct NetworkView: View { .background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow)) } .frame(minWidth: 700, minHeight: 500) // 适当调大宽度以适应 SplitView - .environment(self.networkModel) .onAppear { syncState(vpnManager.vpnStatus) } @@ -129,7 +125,7 @@ struct NetworkView: View { } struct NetworkConnectedView: View { - @Environment(NetworkModel.self) private var networkModel: NetworkModel + @Environment(AppContext.self) private var appContext: AppContext @Binding var showMode: NetworkShowMode var body: some View { @@ -141,7 +137,7 @@ struct NetworkConnectedView: View { GridItem(.flexible(), spacing: 8), GridItem(.flexible(), spacing: 8) ], spacing: 10) { - ForEach(networkModel.networkContext.resourceList, id: \.uuid) { res in + ForEach(appContext.networkContext.resourceList, id: \.uuid) { res in ResourceItemCard(resource: res) } } @@ -160,7 +156,6 @@ struct NetworkConnectedView: View { struct NetworkDisconnectedView: View { @Environment(AppContext.self) private var appContext: AppContext - @Environment(NetworkModel.self) private var networkModel: NetworkModel @State private var isConnecting: Bool = false var body: some View { @@ -201,26 +196,9 @@ struct NetworkDisconnectedView: View { } do { - guard let session = appContext.networkSession else { - return - } - - let context = try await SDLAPIClient.connectNetwork(accesToken: session.accessToken) - if let options = SystemConfig.getOptions( - networkId: UInt32(session.networkId), - networkDomain: session.networkDomain, - ip: context.ip, - maskLen: context.maskLen, - accessToken: session.accessToken, - identityId: context.identityId, - hostname: context.hostname, - noticePort: appContext.noticePort - ) { - try await VPNManager.shared.enableVpn(options: options) - self.networkModel.networkContext = context - } - } catch { - print("Connection error: \(error)") + try await self.appContext.connectNetwork() + } catch let err { + print("Connection error: \(err)") } } @@ -228,19 +206,19 @@ struct NetworkDisconnectedView: View { // MARK: - 设备组视图 (NavigationSplitView) struct NetworkDeviceGroupView: View { - @Environment(NetworkModel.self) private var networkModel: NetworkModel + @Environment(AppContext.self) private var appContext: AppContext @State private var selectedId: Int? var body: some View { NavigationSplitView { - List(networkModel.networkContext.nodeList, id: \.id, selection: $selectedId) { node in + List(appContext.networkContext.nodeList, id: \.id, selection: $selectedId) { node in NetworkNodeHeadView(node: node) .tag(node.id) } .listStyle(.sidebar) .navigationSplitViewColumnWidth(min: 200, ideal: 220) } detail: { - if let selectedNode = networkModel.networkContext.nodeList.first(where: { $0.id == selectedId }) { + if let selectedNode = appContext.networkContext.nodeList.first(where: { $0.id == selectedId }) { NetworkNodeDetailView(node: selectedNode) } else { ContentUnavailableView("选择成员设备", systemImage: "macbook.and.iphone", description: Text("查看详细网络信息和服务")) @@ -248,7 +226,7 @@ struct NetworkDeviceGroupView: View { } .onAppear { if selectedId == nil { - selectedId = networkModel.networkContext.nodeList.first?.id + selectedId = appContext.networkContext.nodeList.first?.id } } } diff --git a/punchnet/Views/Settings/SettingsDeviceView.swift b/punchnet/Views/Settings/SettingsDeviceView.swift index 27bfa89..c8a52fc 100644 --- a/punchnet/Views/Settings/SettingsDeviceView.swift +++ b/punchnet/Views/Settings/SettingsDeviceView.swift @@ -24,21 +24,21 @@ struct SettingsDeviceView: View { .cornerRadius(12) // TODO -// VStack(alignment: .leading, spacing: 4) { -// Text(self.appContext.networkContext?.hostname ?? "未定义") -// .font(.title3.bold()) -// -// Text(SystemConfig.systemInfo) -// .font(.subheadline) -// .foregroundColor(.secondary) -// } + VStack(alignment: .leading, spacing: 4) { + Text(self.appContext.networkContext.hostname) + .font(.title3.bold()) + + Text(SystemConfig.systemInfo) + .font(.subheadline) + .foregroundColor(.secondary) + } } .padding(.horizontal, 4) // MARK: - 详细参数卡片 VStack(alignment: .leading, spacing: 0) { // 设备名称行 - DevicePropertyRow(title: "设备名称", value: self.appContext.networkContext?.hostname ?? "未定义") { + DevicePropertyRow(title: "设备名称", value: self.appContext.networkContext.hostname) { Button { // 修改逻辑 } label: { @@ -55,7 +55,7 @@ struct SettingsDeviceView: View { Divider().padding(.leading, 16) // IPv4 行 - DevicePropertyRow(title: "虚拟 IPv4", value: self.appContext.networkContext?.ip ?? "0.0.0.0") { + DevicePropertyRow(title: "虚拟 IPv4", value: self.appContext.networkContext.ip) { Image(systemName: "info.circle") .foregroundColor(.secondary) }