// // punchnetApp.swift // punchnet // // Created by 安礼成 on 2025/5/12. // import SwiftUI import AppKit import SwiftData import Combine @main struct punchnetApp: App { /* var sharedModelContainer: ModelContainer = { let schema = Schema([ Item.self, ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() */ @Environment(\.openWindow) private var openWindow @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate private var noticeServer: UDPNoticeCenterServer @State private var appContext: AppContext @State private var userContext = UserContext() init() { self.noticeServer = UDPNoticeCenterServer() self.noticeServer.start() self.appContext = AppContext(noticePort: self.noticeServer.port) // TODO test self.userContext.networkSession = .init(accessToken: "", username: "", userType: "", audit: 0, networkId: 1, networkName: "测试网络1", networkDomain: "punchnet.com", exitNodes: [ .init(nnid: 1, nodeName: "出口1"), .init(nnid: 2, nodeName: "出口2"), .init(nnid: 3, nodeName: "出口2"), ]) } var body: some Scene { WindowGroup(id: "main") { RootView() .navigationTitle("") .environment(self.appContext) .environment(self.userContext) } .commands { CommandGroup(replacing: .appInfo) { Button { openWindow(id: "abortPunchnet") } label: { Text("About Punchnet") } } } .windowResizability(.contentSize) .windowToolbarStyle(.unified) .defaultPosition(.center) Window("设置", id: "settings") { SettingsView() .environment(self.userContext) .environment(self.appContext) } .defaultSize(width: 800, height: 500) .defaultPosition(.center) Window("重置密码", id: "resetPassword") { ResetPasswordRootView() .environment(self.userContext) .environment(self.appContext) } .defaultSize(width: 800, height: 500) .defaultPosition(.center) Window("注册", id: "register") { ResetPasswordRootView() .environment(self.userContext) .environment(self.appContext) } .defaultSize(width: 800, height: 500) .defaultPosition(.center) MenuBarExtra("punchnet", image: "logo_32") { VStack { Button(action: { self.menuClick() }, label: { Text("启动") }) Divider() Button(action: { NSApplication.shared.terminate(nil) }, label: { Text("退出") }) } } .menuBarExtraStyle(.menu) } private func menuClick() { } } // 处理APP的生命周期 class AppDelegate: NSObject, NSApplicationDelegate { func applicationWillFinishLaunching(_ notification: Notification) { } func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply { Task { try await VPNManager.shared.disableVpn() DispatchQueue.main.async { sender.reply(toApplicationShouldTerminate: true) } } return .terminateLater } }