From 29501abcd6557a73a42ca15752ed2d7bc8edbae7 Mon Sep 17 00:00:00 2001 From: maxsoch Date: Mon, 13 Jul 2026 19:08:59 +0200 Subject: [PATCH] show the updating icon during upgrades and cleanup, not just checks Only fetchOutdated ever touched the menu bar icon, so during an upgrade it kept showing "updates available". Every long-running operation now sets the updating icon when it starts; paths that end without a refetch (cleanup, failed refresh) restore the icon of the last known state via a new cachedStateIcon() helper. Single-package upgrades also gained a status line, they showed nothing before. Co-Authored-By: Claude Fable 5 --- BrewBar/BrewBarApp.swift | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/BrewBar/BrewBarApp.swift b/BrewBar/BrewBarApp.swift index a8487d1..2b16c82 100644 --- a/BrewBar/BrewBarApp.swift +++ b/BrewBar/BrewBarApp.swift @@ -148,6 +148,12 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } + /// icon matching the last fetched state, for operations that end + /// without triggering a refetch + func cachedStateIcon() -> String { + cachedOutdated.isEmpty ? "brewbar-uptodate" : "brewbar-outdated" + } + func restartTimer() { refreshTimer?.invalidate() // stop running timer refreshTimer = Timer.scheduledTimer(withTimeInterval: refreshInterval, repeats: true) { _ in @@ -310,8 +316,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { /// (current versions); the only cost is re-downloading at next install func runCleanup(purgeCache: Bool) { statusMenuItem.title = "Cleaning up..." + setMenuBarIcon("brewbar-updating") runBrew(purgeCache ? "cleanup --prune=all" : "cleanup") { _, _ in self.updateStatus(count: self.cachedOutdated.count) + self.setMenuBarIcon(self.cachedStateIcon()) } } @@ -344,6 +352,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { } statusMenuItem.title = "Upgrading..." + setMenuBarIcon("brewbar-updating") runBrew("update") { _, _ in // packages that turn outdated only after this brew update are not @@ -443,7 +452,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { // "all up to date"; keep the cached state and its icon instead guard success else { self.statusMenuItem.title = "⚠️ Check failed — see Logs" - self.setMenuBarIcon(self.cachedOutdated.isEmpty ? "brewbar-uptodate" : "brewbar-outdated") + self.setMenuBarIcon(self.cachedStateIcon()) return } @@ -496,6 +505,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { func runAutoUpgrade(formulae: Bool, casks: Bool) { statusMenuItem.title = "Auto-upgrading..." + setMenuBarIcon("brewbar-updating") let caskNames = casks ? cachedOutdated.casks.map(\.name) : [] let upgradeCasksThenRefresh = { @@ -551,6 +561,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { @objc func upgradeSingle(_ sender: NSMenuItem) { guard let name = sender.representedObject as? String else { return } + statusMenuItem.title = "Upgrading \(name)..." + setMenuBarIcon("brewbar-updating") + let finish = { self.cleanupAfterUpgradeIfEnabled { self.refreshAll() @@ -591,6 +604,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { } statusMenuItem.title = "Updating..." + setMenuBarIcon("brewbar-updating") // NWPathMonitor can't see a network that is up but broken (captive // portal, dead DNS, git host down); brew update's exit code can. @@ -598,6 +612,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { runBrew("update") { _, success in guard success else { self.statusMenuItem.title = "⚠️ Check failed — see Logs" + self.setMenuBarIcon(self.cachedStateIcon()) return } self.fetchOutdated() // ✅ ONLY place calling outdated