fix network

This commit is contained in:
anlicheng 2026-03-24 00:39:12 +08:00
parent c8c37954ce
commit fbbef96aa9
2 changed files with 108 additions and 126 deletions

View File

@ -6,7 +6,15 @@ import Observation
// MARK: - // MARK: -
enum ConnectState { enum ConnectState {
case waitAuth, connected, disconnected case waitAuth
case connected
case disconnected
}
//
enum NetworkShowMode: String, CaseIterable {
case resource = "访问资源"
case device = "成员设备"
} }
// MARK: - // MARK: -
@ -15,56 +23,26 @@ struct NetworkView: View {
@Environment(\.openWindow) private var openWindow @Environment(\.openWindow) private var openWindow
@State private var networkModel = NetworkModel() @State private var networkModel = NetworkModel()
@State private var showMode: ShowMode = .resource @State private var showMode: NetworkShowMode = .resource
@State private var connectState: ConnectState = .disconnected @State private var connectState: ConnectState = .disconnected
@State private var isConnecting: Bool = false @State private var isConnecting: Bool = false
private var vpnManager = VPNManager.shared private var vpnManager = VPNManager.shared
enum ShowMode: String, CaseIterable {
case resource = "访问资源"
case device = "成员设备"
}
var body: some View { var body: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
// 1. (Header) // 1. (Header)
headerSection
Divider()
// 2. (Content)
Group {
switch connectState {
case .waitAuth:
NetworkWaitAuthView(networkModel: networkModel)
case .connected:
connectedContent
case .disconnected:
disconnectedContent
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow))
}
.frame(minWidth: 700, minHeight: 500) // SplitView
.onAppear {
syncState(vpnManager.vpnStatus)
}
.onChange(of: vpnManager.vpnStatus) { _, newStatus in
withAnimation(.snappy) {
syncState(newStatus)
}
}
}
}
// MARK: -
extension NetworkView {
private var headerSection: some View {
HStack(spacing: 16) { HStack(spacing: 16) {
statusIndicator ZStack {
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) { VStack(alignment: .leading, spacing: 2) {
Text(appContext.networkSession?.networkName ?? "未连接网络") Text(appContext.networkSession?.networkName ?? "未连接网络")
@ -85,7 +63,7 @@ extension NetworkView {
if connectState == .connected { if connectState == .connected {
Picker("", selection: $showMode) { Picker("", selection: $showMode) {
ForEach(ShowMode.allCases, id: \.self) { ForEach(NetworkShowMode.allCases, id: \.self) {
Text($0.rawValue).tag($0) Text($0.rawValue).tag($0)
} }
} }
@ -106,23 +84,15 @@ extension NetworkView {
.padding(.horizontal, 20) .padding(.horizontal, 20)
.padding(.vertical, 14) .padding(.vertical, 14)
.background(VisualEffectView(material: .headerView, blendingMode: .withinWindow)) .background(VisualEffectView(material: .headerView, blendingMode: .withinWindow))
}
private var statusIndicator: some View { Divider()
ZStack {
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") // 2. (Content)
.symbolRenderingMode(.hierarchical) Group {
.foregroundStyle(connectState == .connected ? Color.green : Color.secondary) switch connectState {
.font(.system(size: 16)) case .waitAuth:
} NetworkWaitAuthView(networkModel: networkModel)
} case .connected:
@ViewBuilder
private var connectedContent: some View {
if showMode == .resource { if showMode == .resource {
// //
ScrollView { ScrollView {
@ -144,9 +114,7 @@ extension NetworkView {
NetworkDeviceGroupView(networkModel: networkModel) NetworkDeviceGroupView(networkModel: networkModel)
.transition(.asymmetric(insertion: .move(edge: .trailing), removal: .opacity)) .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .opacity))
} }
} case .disconnected:
private var disconnectedContent: some View {
VStack(spacing: 20) { VStack(spacing: 20) {
Spacer() Spacer()
Image(systemName: "antenna.radiowaves.left.and.right") Image(systemName: "antenna.radiowaves.left.and.right")
@ -172,6 +140,20 @@ extension NetworkView {
Spacer() Spacer()
} }
} }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(VisualEffectView(material: .windowBackground, blendingMode: .behindWindow))
}
.frame(minWidth: 700, minHeight: 500) // SplitView
.onAppear {
syncState(vpnManager.vpnStatus)
}
.onChange(of: vpnManager.vpnStatus) { _, newStatus in
withAnimation(.snappy) {
syncState(newStatus)
}
}
}
private func syncState(_ status: VPNManager.VPNStatus) { private func syncState(_ status: VPNManager.VPNStatus) {
switch status { switch status {

View File

@ -64,7 +64,7 @@ struct punchnetApp: App {
// } // }
// } // }
// } // }
.windowResizability(.contentSize) //.windowResizability(.contentSize)
.windowToolbarStyle(.unified) .windowToolbarStyle(.unified)
.defaultPosition(.center) .defaultPosition(.center)