fix network
This commit is contained in:
parent
c8c37954ce
commit
fbbef96aa9
@ -6,7 +6,15 @@ import Observation
|
||||
|
||||
// MARK: - 基础模型协议
|
||||
enum ConnectState {
|
||||
case waitAuth, connected, disconnected
|
||||
case waitAuth
|
||||
case connected
|
||||
case disconnected
|
||||
}
|
||||
|
||||
// 资源展示模式
|
||||
enum NetworkShowMode: String, CaseIterable {
|
||||
case resource = "访问资源"
|
||||
case device = "成员设备"
|
||||
}
|
||||
|
||||
// MARK: - 主网络视图
|
||||
@ -15,56 +23,26 @@ struct NetworkView: View {
|
||||
@Environment(\.openWindow) private var openWindow
|
||||
|
||||
@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 isConnecting: Bool = false
|
||||
|
||||
private var vpnManager = VPNManager.shared
|
||||
|
||||
enum ShowMode: String, CaseIterable {
|
||||
case resource = "访问资源"
|
||||
case device = "成员设备"
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
// 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) {
|
||||
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) {
|
||||
Text(appContext.networkSession?.networkName ?? "未连接网络")
|
||||
@ -85,7 +63,7 @@ extension NetworkView {
|
||||
|
||||
if connectState == .connected {
|
||||
Picker("", selection: $showMode) {
|
||||
ForEach(ShowMode.allCases, id: \.self) {
|
||||
ForEach(NetworkShowMode.allCases, id: \.self) {
|
||||
Text($0.rawValue).tag($0)
|
||||
}
|
||||
}
|
||||
@ -106,23 +84,15 @@ extension NetworkView {
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.vertical, 14)
|
||||
.background(VisualEffectView(material: .headerView, blendingMode: .withinWindow))
|
||||
}
|
||||
|
||||
private var statusIndicator: some View {
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(connectState == .connected ? Color.green.opacity(0.15) : Color.primary.opacity(0.05))
|
||||
.frame(width: 36, height: 36)
|
||||
Divider()
|
||||
|
||||
Image(systemName: connectState == .connected ? "checkmark.shield.fill" : "shield.slash.fill")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.foregroundStyle(connectState == .connected ? Color.green : Color.secondary)
|
||||
.font(.system(size: 16))
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var connectedContent: some View {
|
||||
// 2. 内容区域 (Content)
|
||||
Group {
|
||||
switch connectState {
|
||||
case .waitAuth:
|
||||
NetworkWaitAuthView(networkModel: networkModel)
|
||||
case .connected:
|
||||
if showMode == .resource {
|
||||
// 资源视图:网格布局
|
||||
ScrollView {
|
||||
@ -144,9 +114,7 @@ extension NetworkView {
|
||||
NetworkDeviceGroupView(networkModel: networkModel)
|
||||
.transition(.asymmetric(insertion: .move(edge: .trailing), removal: .opacity))
|
||||
}
|
||||
}
|
||||
|
||||
private var disconnectedContent: some View {
|
||||
case .disconnected:
|
||||
VStack(spacing: 20) {
|
||||
Spacer()
|
||||
Image(systemName: "antenna.radiowaves.left.and.right")
|
||||
@ -172,6 +140,20 @@ extension NetworkView {
|
||||
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) {
|
||||
switch status {
|
||||
|
||||
@ -64,7 +64,7 @@ struct punchnetApp: App {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
.windowResizability(.contentSize)
|
||||
//.windowResizability(.contentSize)
|
||||
.windowToolbarStyle(.unified)
|
||||
.defaultPosition(.center)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user