From daa292a9988c7ed6de3edbf0f46051bb0a4cac10 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Tue, 28 Apr 2026 18:09:13 +0200 Subject: [PATCH] Show cached data instantly instead of blocking on CLI refresh Only show the loading overlay when no cached data exists for the current period/provider. When stale data is available, display it immediately while the background fetch runs. Also skip CLI calls entirely when the cache is still fresh (within TTL), reducing redundant subprocess invocations from the 30s LaunchAgent timer. --- mac/Sources/CodeBurnMenubar/AppStore.swift | 12 ++++++++---- .../CodeBurnMenubar/Views/MenuBarContent.swift | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mac/Sources/CodeBurnMenubar/AppStore.swift b/mac/Sources/CodeBurnMenubar/AppStore.swift index f9436066..278f6973 100644 --- a/mac/Sources/CodeBurnMenubar/AppStore.swift +++ b/mac/Sources/CodeBurnMenubar/AppStore.swift @@ -65,13 +65,13 @@ final class AppStore { /// Switch to a period. Always fetches fresh data so the user never sees stale numbers. func switchTo(period: Period) async { selectedPeriod = period - await refresh(includeOptimize: true) + await refresh(includeOptimize: true, force: true) } /// Switch to a provider filter. Always fetches fresh data so the user never sees stale numbers. func switchTo(provider: ProviderFilter) async { selectedProvider = provider - await refresh(includeOptimize: true) + await refresh(includeOptimize: true, force: true) } private var inFlightKeys: Set = [] @@ -79,11 +79,15 @@ final class AppStore { /// Refresh the currently selected (period, provider) combination. Guards against concurrent /// fetches for the same key so a slow initial request can't overwrite a newer one that /// finished first (which would show stale numbers the user has already moved past). - func refresh(includeOptimize: Bool) async { + /// When `force` is false (background timer), skips the CLI call if the cache is still fresh. + func refresh(includeOptimize: Bool, force: Bool = false) async { let key = currentKey + if !force, cache[key]?.isFresh == true { return } guard !inFlightKeys.contains(key) else { return } inFlightKeys.insert(key) - isLoading = true + if cache[key] == nil { + isLoading = true + } defer { inFlightKeys.remove(key) isLoading = false diff --git a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift index 86d1d912..f067aa0e 100644 --- a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift +++ b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift @@ -397,7 +397,7 @@ struct FooterBar: View { .fixedSize() Button { - Task { await store.refresh(includeOptimize: true) } + Task { await store.refresh(includeOptimize: true, force: true) } } label: { Image(systemName: store.isLoading ? "arrow.triangle.2.circlepath" : "arrow.clockwise") .font(.system(size: 11, weight: .medium))