Something went wrong. Try again.
become more token aware with this one free trick! providers hate her
Something went wrong. Try again.
4.7 kB · 145 lines
Swift
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146import AppKitimport SwiftUIimport Combine
@MainActorpublic class StatusBarController: NSObject, NSPopoverDelegate { private var statusItem: NSStatusItem private var popover: NSPopover private var store: UsageStore private var cancellables = Set<AnyCancellable>() private var contextMenu: NSMenu! private var hostingController: NSHostingController<PopoverContentView>? private var lastCloseTime: Date?
public init(store: UsageStore) { self.store = store self.statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) self.popover = NSPopover() super.init()
setupPopover() setupContextMenu() setupStatusItem() bindStore() }
private func setupPopover() { popover.behavior = .transient popover.animates = true popover.appearance = NSAppearance(named: .darkAqua) popover.delegate = self }
public func popoverDidClose(_ notification: Notification) { lastCloseTime = Date() popover.contentViewController = nil hostingController = nil }
private func setupContextMenu() { contextMenu = NSMenu()
let refreshItem = NSMenuItem(title: "Refresh Now", action: #selector(menuRefresh), keyEquivalent: "r") refreshItem.target = self contextMenu.addItem(refreshItem)
let openConfigItem = NSMenuItem(title: "Open config.json", action: #selector(menuOpenConfig), keyEquivalent: "c") openConfigItem.target = self contextMenu.addItem(openConfigItem)
let openAuthItem = NSMenuItem(title: "Open auth.json", action: #selector(menuOpenAuth), keyEquivalent: "o") openAuthItem.target = self contextMenu.addItem(openAuthItem)
contextMenu.addItem(NSMenuItem.separator())
let quitItem = NSMenuItem(title: "Quit UsageTray", action: #selector(menuQuit), keyEquivalent: "q") quitItem.target = self contextMenu.addItem(quitItem) }
private func setupStatusItem() { guard let button = statusItem.button else { return }
let config = NSImage.SymbolConfiguration(pointSize: 13, weight: .medium) if let image = NSImage(systemSymbolName: "gauge.open.with.lines.needle.33percent", accessibilityDescription: "Usage")?.withSymbolConfiguration(config) { image.isTemplate = true button.image = image }
if let font = NSFont(name: "Comic Mono", size: 12) { button.font = font }
button.imagePosition = .imageLeading button.action = #selector(handleClick(_:)) button.target = self button.sendAction(on: [.leftMouseUp, .rightMouseUp]) }
private func bindStore() { store.$harmonized .receive(on: DispatchQueue.main) .sink { [weak self] _ in guard let self = self else { return } self.statusItem.button?.title = self.store.statusItemTitle } .store(in: &cancellables) }
@objc private func handleClick(_ sender: AnyObject?) { guard let button = statusItem.button else { return } let event = NSApp.currentEvent if event?.type == .rightMouseUp { contextMenu.popUp(positioning: nil, at: NSPoint(x: 0, y: button.bounds.height + 4), in: button) } else { togglePopover(sender) } }
@objc public func togglePopover(_ sender: AnyObject?) { guard let button = statusItem.button else { return }
if popover.isShown { popover.performClose(sender) return }
if let lastClose = lastCloseTime, Date().timeIntervalSince(lastClose) < 0.25 { return }
Task { await store.refresh(force: false) } let hc = NSHostingController(rootView: PopoverContentView(store: store)) self.hostingController = hc popover.contentViewController = hc
let v = hc.view v.layoutSubtreeIfNeeded() let fit = v.fittingSize popover.contentSize = NSSize(width: 360, height: max(320, fit.height)) popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY) hc.view.window?.makeKey() }
@objc private func menuRefresh() { Task { await store.refresh(force: true) } }
@objc private func menuOpenConfig() { NSWorkspace.shared.open(AppConfig.configURL) }
@objc private func menuOpenAuth() { NSWorkspace.shared.open(AuthStorage.authURL) }
@objc private func menuQuit() { NSApplication.shared.terminate(nil) }}