mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-05-17 03:56:45 +00:00
Fix menubar refresh stuck after first load (#179)
forceRefresh() was missing force:true, so the cache TTL guard silently skipped every LaunchAgent and wake-triggered refresh. Also adds right-click context menu and version label in footer.
This commit is contained in:
parent
78aa6fc534
commit
f35400f199
3 changed files with 71 additions and 3 deletions
|
|
@ -26,9 +26,14 @@
|
|||
- **Instant cached data display.** Shows cached data immediately instead of blocking on CLI refresh.
|
||||
|
||||
### Fixed (macOS menubar)
|
||||
- **Menubar stops updating after first load.** Background refresh was silently skipped by the cache TTL guard. Data loaded once, then froze. Fixes #179.
|
||||
- **Menubar not dimming on inactive screens.**
|
||||
- **Performance improvements.** Reduced unnecessary redraws and CLI invocations.
|
||||
|
||||
### Added (macOS menubar)
|
||||
- **Right-click context menu.** Right-click the status bar icon for "Check for Updates" and "Quit CodeBurn".
|
||||
- **Version label in footer.**
|
||||
|
||||
### Changed
|
||||
- README restructured with honeycomb provider hero image, 2x2 screenshot grid, and complete inline reference.
|
||||
- `bunx codeburn` added as alternative install option.
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
|
|||
lastRefreshTime = now
|
||||
|
||||
Task {
|
||||
await store.refresh(includeOptimize: true)
|
||||
await store.refresh(includeOptimize: true, force: true)
|
||||
refreshStatusButton()
|
||||
}
|
||||
}
|
||||
|
|
@ -311,7 +311,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
|
|||
}
|
||||
|
||||
@objc private func handleButtonClick(_ sender: AnyObject?) {
|
||||
guard let button = statusItem.button else { return }
|
||||
guard let button = statusItem.button,
|
||||
let event = NSApp.currentEvent else { return }
|
||||
|
||||
if event.type == .rightMouseUp {
|
||||
showContextMenu(from: button)
|
||||
return
|
||||
}
|
||||
|
||||
if popover.isShown {
|
||||
popover.performClose(sender)
|
||||
} else {
|
||||
|
|
@ -321,6 +328,58 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
private func showContextMenu(from button: NSStatusBarButton) {
|
||||
let menu = NSMenu()
|
||||
let updateItem = NSMenuItem(title: "Check for Updates", action: #selector(checkForUpdates), keyEquivalent: "")
|
||||
updateItem.target = self
|
||||
menu.addItem(updateItem)
|
||||
menu.addItem(.separator())
|
||||
let quitItem = NSMenuItem(title: "Quit CodeBurn", action: #selector(quitApp), keyEquivalent: "q")
|
||||
quitItem.target = self
|
||||
menu.addItem(quitItem)
|
||||
statusItem.menu = menu
|
||||
button.performClick(nil)
|
||||
statusItem.menu = nil
|
||||
}
|
||||
|
||||
private func codeburnAlertIcon() -> NSImage? {
|
||||
let config = NSImage.SymbolConfiguration(pointSize: 32, weight: .medium)
|
||||
guard let symbol = NSImage(systemSymbolName: "flame.fill", accessibilityDescription: "CodeBurn")?
|
||||
.withSymbolConfiguration(config) else { return nil }
|
||||
let size = NSSize(width: 64, height: 64)
|
||||
let img = NSImage(size: size, flipped: false) { rect in
|
||||
let symbolSize = symbol.size
|
||||
let x = (rect.width - symbolSize.width) / 2
|
||||
let y = (rect.height - symbolSize.height) / 2
|
||||
symbol.draw(in: NSRect(x: x, y: y, width: symbolSize.width, height: symbolSize.height))
|
||||
return true
|
||||
}
|
||||
img.isTemplate = false
|
||||
return img
|
||||
}
|
||||
|
||||
@objc private func checkForUpdates() {
|
||||
Task {
|
||||
await updateChecker.check()
|
||||
let alert = NSAlert()
|
||||
alert.icon = codeburnAlertIcon()
|
||||
if updateChecker.updateAvailable, let latest = updateChecker.latestVersion {
|
||||
alert.messageText = "Update Available"
|
||||
alert.informativeText = "v\(latest) is available (you have v\(updateChecker.currentVersion)). Run:\n\ncodeburn menubar --force"
|
||||
} else {
|
||||
alert.messageText = "Up to Date"
|
||||
alert.informativeText = "You're on the latest version (v\(updateChecker.currentVersion))."
|
||||
}
|
||||
alert.alertStyle = .informational
|
||||
alert.addButton(withTitle: "OK")
|
||||
alert.runModal()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func quitApp() {
|
||||
NSApp.terminate(nil)
|
||||
}
|
||||
|
||||
// MARK: - NSPopoverDelegate
|
||||
|
||||
func popoverShouldDetach(_ popover: NSPopover) -> Bool {
|
||||
|
|
|
|||
|
|
@ -422,8 +422,12 @@ struct FooterBar: View {
|
|||
|
||||
Spacer()
|
||||
|
||||
Text("v\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "?")")
|
||||
.font(.system(size: 10, weight: .regular, design: .monospaced))
|
||||
.foregroundStyle(.tertiary)
|
||||
|
||||
Button { openReport() } label: {
|
||||
Label("Open Full Report", systemImage: "terminal")
|
||||
Label("Full Report", systemImage: "terminal")
|
||||
.font(.system(size: 11, weight: .semibold))
|
||||
.labelStyle(.titleAndIcon)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue