import AppKit import ServiceManagement import SwiftUI final class AppDelegate: NSObject, NSApplicationDelegate { static weak var shared: AppDelegate? private var statusItem: NSStatusItem! private var popover: NSPopover! private var floatingWidget: FloatingWidgetWindow? private let bugStore = BugStore.shared func applicationDidFinishLaunching(_ notification: Notification) { Self.shared = self NSApp.setActivationPolicy(.accessory) NSAppleEventManager.shared().setEventHandler( self, andSelector: #selector(handleURLEvent(_:withReplyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL) ) setupStatusItem() setupPopover() if let config = AppStateService.shared.config { if config.showFloatingWidget { showFloatingWidget() } if config.launchAtLogin { try? SMAppService.mainApp.register() } } Task { await PollerService.shared.startIfConfigured() } } private func setupStatusItem() { statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) if let button = statusItem.button { button.image = NSImage(systemSymbolName: "ant.fill", accessibilityDescription: "Bugger") button.action = #selector(togglePopover) button.target = self } updateBadge(count: bugStore.unseenActiveCount) } private func setupPopover() { popover = NSPopover() popover.contentSize = NSSize(width: 360, height: 500) popover.behavior = .transient popover.contentViewController = NSHostingController(rootView: BugListPopover()) } func updateBadge(count: Int) { if count > 0 { statusItem.button?.title = " \(count)" } else { statusItem.button?.title = "" } } @objc func togglePopover() { guard let button = statusItem.button else { return } if popover.isShown { closePopover() } else { popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY) popover.contentViewController?.view.window?.makeKey() } } func closePopover() { popover.performClose(nil) } func showFloatingWidget() { guard floatingWidget == nil else { return } floatingWidget = FloatingWidgetWindow() floatingWidget?.orderFrontRegardless() } func hideFloatingWidget() { floatingWidget?.close() floatingWidget = nil } @objc private func handleURLEvent(_ event: NSAppleEventDescriptor, withReplyEvent: NSAppleEventDescriptor) { guard let urlString = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue, let url = URL(string: urlString) else { return } OAuthCallbackHandler.handle(url) } }