mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-05-16 19:44:14 +00:00
Strip optimize from menubar, fix stuck loading spinner
The menubar ran --optimize on every 30-second CLI invocation. As sessions accumulated throughout the day, optimize got heavier until it exceeded the 45-second timeout. When the fetch failed with no cached data, the loading overlay had no escape hatch and stayed forever. - Never pass includeOptimize from the menubar (background loop, forceRefresh, tab/period switches, manual refresh button) - On fetch failure with empty cache, retry without optimize as fallback so the spinner always clears - refreshQuietly also skips optimize
This commit is contained in:
parent
e7560052ed
commit
c706cd2de2
3 changed files with 21 additions and 9 deletions
|
|
@ -71,9 +71,9 @@ final class AppStore {
|
|||
switchTask?.cancel()
|
||||
switchTask = Task {
|
||||
if selectedProvider == .all {
|
||||
await refresh(includeOptimize: true, force: true)
|
||||
await refresh(includeOptimize: false, force: true)
|
||||
} else {
|
||||
async let main: Void = refresh(includeOptimize: true, force: true)
|
||||
async let main: Void = refresh(includeOptimize: false, force: true)
|
||||
async let all: Void = refreshQuietly(period: period)
|
||||
_ = await (main, all)
|
||||
}
|
||||
|
|
@ -88,9 +88,9 @@ final class AppStore {
|
|||
switchTask?.cancel()
|
||||
switchTask = Task {
|
||||
if provider == .all {
|
||||
await refresh(includeOptimize: true, force: true)
|
||||
await refresh(includeOptimize: false, force: true)
|
||||
} else {
|
||||
async let main: Void = refresh(includeOptimize: true, force: true)
|
||||
async let main: Void = refresh(includeOptimize: false, force: true)
|
||||
async let all: Void = refreshQuietly(period: selectedPeriod)
|
||||
_ = await (main, all)
|
||||
}
|
||||
|
|
@ -119,8 +119,20 @@ final class AppStore {
|
|||
lastError = nil
|
||||
} catch {
|
||||
if Task.isCancelled { return }
|
||||
lastError = String(describing: error)
|
||||
NSLog("CodeBurn: fetch failed for \(key.period.rawValue)/\(key.provider.rawValue): \(error)")
|
||||
if includeOptimize, cache[key] == nil {
|
||||
do {
|
||||
let fallback = try await DataClient.fetch(period: key.period, provider: key.provider, includeOptimize: false)
|
||||
guard !Task.isCancelled else { return }
|
||||
cache[key] = CachedPayload(payload: fallback, fetchedAt: Date())
|
||||
lastError = nil
|
||||
return
|
||||
} catch {
|
||||
if Task.isCancelled { return }
|
||||
NSLog("CodeBurn: fallback fetch also failed: \(error)")
|
||||
}
|
||||
}
|
||||
lastError = String(describing: error)
|
||||
}
|
||||
|
||||
let allKey = PayloadCacheKey(period: selectedPeriod, provider: .all)
|
||||
|
|
@ -134,7 +146,7 @@ final class AppStore {
|
|||
/// Always uses the .all provider since the menubar badge shows total spend.
|
||||
func refreshQuietly(period: Period) async {
|
||||
do {
|
||||
let fresh = try await DataClient.fetch(period: period, provider: .all, includeOptimize: true)
|
||||
let fresh = try await DataClient.fetch(period: period, provider: .all, includeOptimize: false)
|
||||
cache[PayloadCacheKey(period: period, provider: .all)] = CachedPayload(payload: fresh, fetchedAt: Date())
|
||||
} catch {
|
||||
NSLog("CodeBurn: quiet refresh failed for \(period.rawValue): \(error)")
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
|
|||
lastRefreshTime = now
|
||||
|
||||
Task {
|
||||
async let main: Void = store.refresh(includeOptimize: true, force: true)
|
||||
async let main: Void = store.refresh(includeOptimize: false, force: true)
|
||||
async let today: Void = store.refreshQuietly(period: .today)
|
||||
_ = await (main, today)
|
||||
refreshStatusButton()
|
||||
|
|
@ -207,7 +207,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
|
|||
if self.store.selectedPeriod != .today || self.store.selectedProvider != .all {
|
||||
await self.store.refreshQuietly(period: .today)
|
||||
}
|
||||
await self.store.refresh(includeOptimize: true, force: true)
|
||||
await self.store.refresh(includeOptimize: false, force: true)
|
||||
self.refreshStatusButton()
|
||||
try? await Task.sleep(nanoseconds: refreshIntervalNanos)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ struct FooterBar: View {
|
|||
.fixedSize()
|
||||
|
||||
Button {
|
||||
Task { await store.refresh(includeOptimize: true, force: true) }
|
||||
Task { await store.refresh(includeOptimize: false, force: true) }
|
||||
} label: {
|
||||
Image(systemName: store.isLoading ? "arrow.triangle.2.circlepath" : "arrow.clockwise")
|
||||
.font(.system(size: 11, weight: .medium))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue