// // 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 @AppStorage("token") var token: String = "" @AppStorage("network_code") var networkCode: String = "" @AppStorage("hostname") var hostname: String = "" @ObservedObject var vpnManager = VPNManager.shared private var noticeServer: UDPNoticeCenterServer init() { self.noticeServer = UDPNoticeCenterServer() self.noticeServer.start() } var body: some Scene { WindowGroup(id: "mainWindow") { //IndexView(noticeServer: self.noticeServer) RootView() .onAppear { // 获取主屏幕的尺寸 guard let screenFrame = NSScreen.main?.frame else { return } // 获取当前应用的窗口(假设只有一个窗口) NSApplication.shared.windows.forEach { window in // 计算窗口的中心位置 let windowWidth = window.frame.width let windowHeight = window.frame.height let centerX = (screenFrame.width - windowWidth) / 2 let centerY = (screenFrame.height - windowHeight) / 2 // 设置窗口位置 window.setFrameOrigin(NSPoint(x: centerX, y: centerY)) } } //.toolbar(.hidden) .navigationTitle("") } .commands { CommandGroup(replacing: .appInfo) { Button { openWindow(id: "abortPunchnet") } label: { Text("About Punchnet") } } } .windowResizability(.contentSize) .windowToolbarStyle(.unified) Window("", id: "abortPunchnet") { AbortView() .frame(minWidth: 300, maxWidth: 300, minHeight: 500, maxHeight: 500) } MenuBarExtra("punchnet", image: "logo_32") { VStack { Button(action: { self.menuClick() }, label: { Text(vpnManager.title) }) Divider() Button(action: { NSApplication.shared.terminate(nil) }, label: { Text("退出") }) } } .menuBarExtraStyle(.menu) } private func menuClick() { switch self.vpnManager.vpnStatus { case .disconnected: Task { let clientId = SystemConfig.getClientId() try await vpnManager.enableVpn(options: SystemConfig.getOptions(networkCode: self.networkCode, token: self.token, clientId: clientId, hostname: self.hostname, noticePort: self.noticeServer.port)!) } case .connected: Task { try await vpnManager.disableVpn() } } } } // 处理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 } }