Compare commits

..

2 commits

Author SHA1 Message Date
maxsoch 03c8250def Merge branch 'fix/upgrading-icon' 2026-07-13 19:08:59 +02:00
maxsoch 29501abcd6 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 <noreply@anthropic.com>
2026-07-13 19:08:59 +02:00

View file

@ -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() { func restartTimer() {
refreshTimer?.invalidate() // stop running timer refreshTimer?.invalidate() // stop running timer
refreshTimer = Timer.scheduledTimer(withTimeInterval: refreshInterval, repeats: true) { _ in 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 /// (current versions); the only cost is re-downloading at next install
func runCleanup(purgeCache: Bool) { func runCleanup(purgeCache: Bool) {
statusMenuItem.title = "Cleaning up..." statusMenuItem.title = "Cleaning up..."
setMenuBarIcon("brewbar-updating")
runBrew(purgeCache ? "cleanup --prune=all" : "cleanup") { _, _ in runBrew(purgeCache ? "cleanup --prune=all" : "cleanup") { _, _ in
self.updateStatus(count: self.cachedOutdated.count) self.updateStatus(count: self.cachedOutdated.count)
self.setMenuBarIcon(self.cachedStateIcon())
} }
} }
@ -344,6 +352,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
statusMenuItem.title = "Upgrading..." statusMenuItem.title = "Upgrading..."
setMenuBarIcon("brewbar-updating")
runBrew("update") { _, _ in runBrew("update") { _, _ in
// packages that turn outdated only after this brew update are not // 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 // "all up to date"; keep the cached state and its icon instead
guard success else { guard success else {
self.statusMenuItem.title = "⚠️ Check failed — see Logs" self.statusMenuItem.title = "⚠️ Check failed — see Logs"
self.setMenuBarIcon(self.cachedOutdated.isEmpty ? "brewbar-uptodate" : "brewbar-outdated") self.setMenuBarIcon(self.cachedStateIcon())
return return
} }
@ -496,6 +505,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func runAutoUpgrade(formulae: Bool, casks: Bool) { func runAutoUpgrade(formulae: Bool, casks: Bool) {
statusMenuItem.title = "Auto-upgrading..." statusMenuItem.title = "Auto-upgrading..."
setMenuBarIcon("brewbar-updating")
let caskNames = casks ? cachedOutdated.casks.map(\.name) : [] let caskNames = casks ? cachedOutdated.casks.map(\.name) : []
let upgradeCasksThenRefresh = { let upgradeCasksThenRefresh = {
@ -551,6 +561,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@objc func upgradeSingle(_ sender: NSMenuItem) { @objc func upgradeSingle(_ sender: NSMenuItem) {
guard let name = sender.representedObject as? String else { return } guard let name = sender.representedObject as? String else { return }
statusMenuItem.title = "Upgrading \(name)..."
setMenuBarIcon("brewbar-updating")
let finish = { let finish = {
self.cleanupAfterUpgradeIfEnabled { self.cleanupAfterUpgradeIfEnabled {
self.refreshAll() self.refreshAll()
@ -591,6 +604,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
statusMenuItem.title = "Updating..." statusMenuItem.title = "Updating..."
setMenuBarIcon("brewbar-updating")
// NWPathMonitor can't see a network that is up but broken (captive // NWPathMonitor can't see a network that is up but broken (captive
// portal, dead DNS, git host down); brew update's exit code can. // portal, dead DNS, git host down); brew update's exit code can.
@ -598,6 +612,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
runBrew("update") { _, success in runBrew("update") { _, success in
guard success else { guard success else {
self.statusMenuItem.title = "⚠️ Check failed — see Logs" self.statusMenuItem.title = "⚠️ Check failed — see Logs"
self.setMenuBarIcon(self.cachedStateIcon())
return return
} }
self.fetchOutdated() // ONLY place calling outdated self.fetchOutdated() // ONLY place calling outdated