fix Network

This commit is contained in:
anlicheng 2026-03-24 14:41:12 +08:00
parent d48c527326
commit 77d7e95eae
4 changed files with 45 additions and 62 deletions

View File

@ -13,12 +13,14 @@ class AppContext {
var noticePort: Int var noticePort: Int
// "/connect" // "/connect"
var networkContext: SDLAPIClient.NetworkContext? var networkContext: SDLAPIClient.NetworkContext = .default()
var loginCredit: Credit?
// app // app
var appScene: AppScene = .login(username: nil) var appScene: AppScene = .login(username: nil)
//
var loginCredit: Credit?
enum Credit { enum Credit {
case token(token: String, session: SDLAPIClient.NetworkSession) case token(token: String, session: SDLAPIClient.NetworkSession)
case accountAndPasword(account: String, password: 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? { func loadCacheToken() -> String? {
if let data = try? KeychainStore.shared.load(account: "token") { if let data = try? KeychainStore.shared.load(account: "token") {

View File

@ -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)
}
}

View File

@ -25,9 +25,6 @@ struct NetworkView: View {
@State private var showMode: NetworkShowMode = .resource @State private var showMode: NetworkShowMode = .resource
@State private var connectState: ConnectState = .disconnected @State private var connectState: ConnectState = .disconnected
// View
@State private var networkModel: NetworkModel = NetworkModel()
private var vpnManager = VPNManager.shared private var vpnManager = VPNManager.shared
var body: some View { var body: some View {
@ -50,7 +47,7 @@ struct NetworkView: View {
.font(.system(size: 14, weight: .semibold)) .font(.system(size: 14, weight: .semibold))
if connectState == .connected { if connectState == .connected {
Text("虚拟局域网 IP: \(networkModel.networkContext.ip)") Text("虚拟局域网 IP: \(self.appContext.networkContext.ip)")
.font(.system(size: 11, design: .monospaced)) .font(.system(size: 11, design: .monospaced))
.foregroundColor(.secondary) .foregroundColor(.secondary)
} else { } else {
@ -103,7 +100,6 @@ struct NetworkView: View {
.background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow)) .background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow))
} }
.frame(minWidth: 700, minHeight: 500) // SplitView .frame(minWidth: 700, minHeight: 500) // SplitView
.environment(self.networkModel)
.onAppear { .onAppear {
syncState(vpnManager.vpnStatus) syncState(vpnManager.vpnStatus)
} }
@ -129,7 +125,7 @@ struct NetworkView: View {
} }
struct NetworkConnectedView: View { struct NetworkConnectedView: View {
@Environment(NetworkModel.self) private var networkModel: NetworkModel @Environment(AppContext.self) private var appContext: AppContext
@Binding var showMode: NetworkShowMode @Binding var showMode: NetworkShowMode
var body: some View { var body: some View {
@ -141,7 +137,7 @@ struct NetworkConnectedView: View {
GridItem(.flexible(), spacing: 8), GridItem(.flexible(), spacing: 8),
GridItem(.flexible(), spacing: 8) GridItem(.flexible(), spacing: 8)
], spacing: 10) { ], spacing: 10) {
ForEach(networkModel.networkContext.resourceList, id: \.uuid) { res in ForEach(appContext.networkContext.resourceList, id: \.uuid) { res in
ResourceItemCard(resource: res) ResourceItemCard(resource: res)
} }
} }
@ -160,7 +156,6 @@ struct NetworkConnectedView: View {
struct NetworkDisconnectedView: View { struct NetworkDisconnectedView: View {
@Environment(AppContext.self) private var appContext: AppContext @Environment(AppContext.self) private var appContext: AppContext
@Environment(NetworkModel.self) private var networkModel: NetworkModel
@State private var isConnecting: Bool = false @State private var isConnecting: Bool = false
var body: some View { var body: some View {
@ -201,26 +196,9 @@ struct NetworkDisconnectedView: View {
} }
do { do {
guard let session = appContext.networkSession else { try await self.appContext.connectNetwork()
return } catch let err {
} print("Connection error: \(err)")
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)")
} }
} }
@ -228,19 +206,19 @@ struct NetworkDisconnectedView: View {
// MARK: - (NavigationSplitView) // MARK: - (NavigationSplitView)
struct NetworkDeviceGroupView: View { struct NetworkDeviceGroupView: View {
@Environment(NetworkModel.self) private var networkModel: NetworkModel @Environment(AppContext.self) private var appContext: AppContext
@State private var selectedId: Int? @State private var selectedId: Int?
var body: some View { var body: some View {
NavigationSplitView { NavigationSplitView {
List(networkModel.networkContext.nodeList, id: \.id, selection: $selectedId) { node in List(appContext.networkContext.nodeList, id: \.id, selection: $selectedId) { node in
NetworkNodeHeadView(node: node) NetworkNodeHeadView(node: node)
.tag(node.id) .tag(node.id)
} }
.listStyle(.sidebar) .listStyle(.sidebar)
.navigationSplitViewColumnWidth(min: 200, ideal: 220) .navigationSplitViewColumnWidth(min: 200, ideal: 220)
} detail: { } 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) NetworkNodeDetailView(node: selectedNode)
} else { } else {
ContentUnavailableView("选择成员设备", systemImage: "macbook.and.iphone", description: Text("查看详细网络信息和服务")) ContentUnavailableView("选择成员设备", systemImage: "macbook.and.iphone", description: Text("查看详细网络信息和服务"))
@ -248,7 +226,7 @@ struct NetworkDeviceGroupView: View {
} }
.onAppear { .onAppear {
if selectedId == nil { if selectedId == nil {
selectedId = networkModel.networkContext.nodeList.first?.id selectedId = appContext.networkContext.nodeList.first?.id
} }
} }
} }

View File

@ -24,21 +24,21 @@ struct SettingsDeviceView: View {
.cornerRadius(12) .cornerRadius(12)
// TODO // TODO
// VStack(alignment: .leading, spacing: 4) { VStack(alignment: .leading, spacing: 4) {
// Text(self.appContext.networkContext?.hostname ?? "") Text(self.appContext.networkContext.hostname)
// .font(.title3.bold()) .font(.title3.bold())
//
// Text(SystemConfig.systemInfo) Text(SystemConfig.systemInfo)
// .font(.subheadline) .font(.subheadline)
// .foregroundColor(.secondary) .foregroundColor(.secondary)
// } }
} }
.padding(.horizontal, 4) .padding(.horizontal, 4)
// MARK: - // MARK: -
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
// //
DevicePropertyRow(title: "设备名称", value: self.appContext.networkContext?.hostname ?? "未定义") { DevicePropertyRow(title: "设备名称", value: self.appContext.networkContext.hostname) {
Button { Button {
// //
} label: { } label: {
@ -55,7 +55,7 @@ struct SettingsDeviceView: View {
Divider().padding(.leading, 16) Divider().padding(.leading, 16)
// IPv4 // 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") Image(systemName: "info.circle")
.foregroundColor(.secondary) .foregroundColor(.secondary)
} }