diff --git a/punchnet/Views/AppContext.swift b/punchnet/Views/AppContext.swift index 8290308..5cced56 100644 --- a/punchnet/Views/AppContext.swift +++ b/punchnet/Views/AppContext.swift @@ -31,6 +31,11 @@ class AppContext { // 登陆凭证 var loginCredit: Credit? + // 判断用户是否登陆 + var isLogined: Bool { + return loginCredit != nil + } + enum Credit { case token(token: String, session: SDLAPIClient.NetworkSession) case accountAndPasword(account: String, password: String, session: SDLAPIClient.NetworkSession) @@ -116,6 +121,8 @@ class AppContext { // 退出登陆 func logout() async throws { try await VPNManager.shared.disableVpn() + self.networkContext = .default() + self.loginCredit = nil } } diff --git a/punchnet/Views/MenuBar/MainMenuBar.swift b/punchnet/Views/MenuBar/MainMenuBar.swift new file mode 100644 index 0000000..5af6fdd --- /dev/null +++ b/punchnet/Views/MenuBar/MainMenuBar.swift @@ -0,0 +1,68 @@ +// +// MainMenuBar.swift +// punchnet +// +// Created by 安礼成 on 2026/3/24. +// + +import SwiftUI + +struct MainMenuBar: View { + @State private var vpnManager = VPNManager.shared + @Environment(AppContext.self) private var appContext: AppContext + @Environment(\.openWindow) private var openWindow + @Environment(\.dismissWindow) private var dismissWindow + + var body: some View { + VStack { + switch self.vpnManager.vpnStatus { + case .connected: + Button(action: { + Task { @MainActor in + try await vpnManager.disableVpn() + } + }, label: { + Text("停止") + }) + case .disconnected: + Button(action: { + Task { @MainActor in + await self.startVPN() + } + }, label: { + Text("启动") + }) + } + + Divider() + +// Button("打开控制面板") { +// openWindow(id: appContext.isLoggedIn ? "logined" : "login") +// } + + SettingsLink { + Text("设置") + } + .buttonStyle(.plain) + + Divider() + + Button(action: { + NSApplication.shared.terminate(nil) + }, label: { + Text("退出应用") + }) + } + } + + private func startVPN() async { + if let options = appContext.vpnOptions { + try? await vpnManager.enableVpn(options: options) + dismissWindow(id: "login") + openWindow(id: "logined") + } else { + openWindow(id: "login") + } + } + +} diff --git a/punchnet/Views/Network/NetworkView.swift b/punchnet/Views/Network/NetworkView.swift index 22fb0a4..16acbfa 100644 --- a/punchnet/Views/Network/NetworkView.swift +++ b/punchnet/Views/Network/NetworkView.swift @@ -69,9 +69,7 @@ struct NetworkView: View { .frame(width: 160) } - Button { - openWindow(id: "settings") - } label: { + SettingsLink { Image(systemName: "slider.horizontal.3") .font(.system(size: 14)) .foregroundColor(.secondary) diff --git a/punchnet/Views/Settings/SettingsAccountView.swift b/punchnet/Views/Settings/SettingsAccountView.swift index 8c7313b..3e41f28 100644 --- a/punchnet/Views/Settings/SettingsAccountView.swift +++ b/punchnet/Views/Settings/SettingsAccountView.swift @@ -28,7 +28,7 @@ struct SettingsAccountView: View { } else { // 蓝色主按钮 Button { - self.openMainWindow(id: "main") + self.openMainWindow(id: "login") } label: { Text("登录") .fontWeight(.medium) @@ -116,20 +116,29 @@ extension SettingsAccountView { struct AccountCreditView: View { @Environment(AppContext.self) var appContext: AppContext + @Environment(\.openWindow) var openWindow + @Environment(\.dismissWindow) var dismissWindow + let username: String var body: some View { AccountRow(icon: "person.fill", title: "当前登录账号", subtitle: username, actions: AnyView( HStack(spacing: 12) { - Button("修改密码") { - - } - .buttonStyle(.link) +// Button("修改密码") { +// +// } +// .buttonStyle(.link) Button("退出登录") { Task { @MainActor in try await appContext.logout() } + + self.dismissWindow(id: "logined") + self.dismissWindow(id: "settings") + + self.openWindow(id: "login") + } .buttonStyle(.bordered) .foregroundColor(.red) @@ -140,6 +149,9 @@ extension SettingsAccountView { struct TokenCreditView: View { @Environment(AppContext.self) var appContext: AppContext + @Environment(\.openWindow) var openWindow + @Environment(\.dismissWindow) var dismissWindow + let token: String var body: some View { @@ -148,10 +160,16 @@ extension SettingsAccountView { Task { @MainActor in try await appContext.logout() } + + self.dismissWindow(id: "logined") + self.dismissWindow(id: "settings") + + self.openWindow(id: "login") } .buttonStyle(.bordered) .foregroundColor(.red) )) } } + } diff --git a/punchnet/punchnetApp.swift b/punchnet/punchnetApp.swift index e618aac..ddc6dc5 100644 --- a/punchnet/punchnetApp.swift +++ b/punchnet/punchnetApp.swift @@ -69,7 +69,7 @@ struct punchnetApp: App { .windowResizability(.contentSize) .defaultPosition(.center) - Window("设置", id: "settings") { + Settings { SettingsView() .environment(self.appContext) .frame(width: 750, height: 500) @@ -78,48 +78,12 @@ struct punchnetApp: App { .defaultPosition(.center) MenuBarExtra("punchnet", image: "logo_32") { - VStack { - - switch self.vpnManager.vpnStatus { - case .connected: - Button(action: { - Task { @MainActor in - try await vpnManager.disableVpn() - } - }, label: { - Text("停止") - }) - case .disconnected: - Button(action: { - Task { @MainActor in - await self.startVPN() - } - }, label: { - Text("启动") - }) - } - - Divider() - - Button(action: { - NSApplication.shared.terminate(nil) - }, label: { - Text("退出应用") - }) - - } + MainMenuBar() + .environment(appContext) } .menuBarExtraStyle(.menu) } - private func startVPN() async { - if let options = appContext.vpnOptions { - try? await vpnManager.enableVpn(options: options) - } else { - openWindow(id: "login") - } - } - } // 处理APP的生命周期