Files
wehub-resource-sync 1d1286fadb
Build / Build and test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:18:38 +08:00

100 lines
3.3 KiB
Swift

import AppKit
import SwiftUI
@preconcurrency import UserNotifications
@main
struct MacToolsApp: App {
@NSApplicationDelegateAdaptor(MacToolsAppDelegate.self) private var appDelegate
init() {
AppLanguagePreference.applyStoredPreference()
}
var body: some Scene {
Settings {
EmptyView()
}
}
}
@MainActor
final class MacToolsAppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate {
private let pluginHost = PluginHost(loadDynamicPluginsOnInit: false)
private let appUpdater = AppUpdater()
private let menuBarIconSettings = MenuBarIconSettings()
private let menuBarIconGallery = MenuBarIconGalleryLibrary()
private let launchAtLoginController = LaunchAtLoginController()
private let pluginAutomaticUpdateVersionStore = PluginAutomaticUpdateVersionStore()
private var windowRouter: AppWindowRouter?
private var statusItemController: MenuBarStatusItemController?
func applicationDidFinishLaunching(_ notification: Notification) {
AppAppearancePreference.applyStoredPreference()
launchAtLoginController.refreshStatus()
UNUserNotificationCenter.current().delegate = self
let windowRouter = AppWindowRouter(
pluginHost: pluginHost,
appUpdater: appUpdater,
menuBarIconSettings: menuBarIconSettings,
menuBarIconGallery: menuBarIconGallery,
launchAtLoginController: launchAtLoginController
)
self.windowRouter = windowRouter
statusItemController = MenuBarStatusItemController(
pluginHost: pluginHost,
windowRouter: windowRouter,
iconSettings: menuBarIconSettings
)
bootstrapDynamicPlugins()
}
func application(_ application: NSApplication, open urls: [URL]) {
RightClickURLRouter.shared.handle(urls)
}
func applicationWillTerminate(_ notification: Notification) {
statusItemController?.dismissPanels()
pluginHost.deactivateAllPlugins()
}
nonisolated func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
completionHandler([.banner, .list, .sound])
}
private func bootstrapDynamicPlugins() {
let currentAppVersion = AppMetadata.versionDescription
guard pluginHost.hasInstalledDynamicPlugins else {
pluginHost.loadDynamicPluginsIfNeeded()
pluginAutomaticUpdateVersionStore.markAutomaticUpdateChecked(
currentAppVersion: currentAppVersion
)
return
}
guard pluginAutomaticUpdateVersionStore.needsAutomaticUpdateCheck(
currentAppVersion: currentAppVersion
) else {
pluginHost.loadDynamicPluginsIfNeeded()
return
}
Task { @MainActor in
let updateSucceeded = await pluginHost.automaticUpdateInstalledPluginsBeforeLoading()
guard updateSucceeded else {
return
}
pluginAutomaticUpdateVersionStore.markAutomaticUpdateChecked(
currentAppVersion: currentAppVersion
)
}
}
}