Skip to content

Commit f562916

Browse files
committed
fix: isolate provider refresh snapshots
1 parent c29aaa5 commit f562916

2 files changed

Lines changed: 14 additions & 11 deletions

File tree

Sources/CodexBar/MenuCardRefreshMonitor.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,11 @@ final class MenuCardRefreshMonitor {
3333
frozenModels: [UsageProvider: UsageMenuCardView.Model],
3434
provider: UsageProvider? = nil)
3535
{
36-
// Keep the existing frozen card for any provider already refreshing. `frozenManualRefreshMenuCardModels()`
37-
// snapshots every enabled provider, so a second provider's begin re-supplies the first provider's
38-
// now-mid-refresh model; old-wins prevents that from clobbering the pre-refresh card we froze for it.
39-
self.frozenManualRefreshModels.merge(frozenModels) { existing, _ in existing }
4036
if let provider {
37+
self.frozenManualRefreshModels[provider] = frozenModels[provider]
4138
self.manualRefreshProviders.insert(provider)
4239
} else {
40+
self.frozenManualRefreshModels = frozenModels
4341
self.globalManualRefreshInFlight = true
4442
}
4543
}
@@ -48,11 +46,11 @@ final class MenuCardRefreshMonitor {
4846
func endManualRefresh(for provider: UsageProvider? = nil) {
4947
if let provider {
5048
self.manualRefreshProviders.remove(provider)
49+
self.frozenManualRefreshModels[provider] = nil
5150
} else {
5251
self.globalManualRefreshInFlight = false
52+
self.frozenManualRefreshModels.removeAll(keepingCapacity: true)
5353
}
54-
guard self.manualRefreshProviders.isEmpty, !self.globalManualRefreshInFlight else { return }
55-
self.frozenManualRefreshModels.removeAll(keepingCapacity: true)
5654
}
5755

5856
func resetManualRefresh() {

Tests/CodexBarTests/StatusMenuPersistentRefreshTests.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,23 +1121,28 @@ extension StatusMenuPersistentRefreshTests {
11211121
updatedAt: updatedAt)
11221122
}
11231123

1124-
// Claude begins refreshing: freeze its pre-refresh card (21% used -> "79% left").
1124+
// The snapshot helper supplies every enabled provider even for a provider-scoped refresh.
11251125
controller.store.snapshots[.claude] = quotaSnapshot(usedPercent: 21, updatedAt: now)
1126+
controller.store.snapshots[.codex] = quotaSnapshot(usedPercent: 15, updatedAt: now)
11261127
let claudeFrozen = try #require(controller.menuCardModel(for: .claude))
1127-
monitor.beginManualRefresh(frozenModels: [.claude: claudeFrozen], provider: .claude)
1128+
let codexBeforeItsRefresh = try #require(controller.menuCardModel(for: .codex))
1129+
monitor.beginManualRefresh(
1130+
frozenModels: [.claude: claudeFrozen, .codex: codexBeforeItsRefresh],
1131+
provider: .claude)
11281132

1129-
// Claude's snapshot moves mid-refresh; then Codex begins and re-supplies Claude's *current*
1130-
// model, because frozenManualRefreshMenuCardModels captures every enabled provider.
1133+
// Each provider must freeze the card visible when its own refresh starts.
11311134
controller.store.snapshots[.claude] = quotaSnapshot(usedPercent: 65, updatedAt: now.addingTimeInterval(1))
1135+
controller.store.snapshots[.codex] = quotaSnapshot(usedPercent: 42, updatedAt: now.addingTimeInterval(1))
11321136
let claudeMidRefresh = try #require(controller.menuCardModel(for: .claude))
11331137
let codexFrozen = try #require(controller.menuCardModel(for: .codex))
11341138
monitor.beginManualRefresh(
11351139
frozenModels: [.claude: claudeMidRefresh, .codex: codexFrozen],
11361140
provider: .codex)
11371141

1138-
// Claude must still show its pre-refresh card, not the mid-refresh one Codex's begin supplied.
11391142
let shownClaude = monitor.model(for: .claude, fallback: claudeMidRefresh)
1143+
let shownCodex = monitor.model(for: .codex, fallback: codexFrozen)
11401144
#expect(shownClaude.metrics.first?.percentLabel == "79% left")
1145+
#expect(shownCodex.metrics.first?.percentLabel == "58% left")
11411146

11421147
// Ending Codex leaves Claude frozen; ending Claude clears it.
11431148
monitor.endManualRefresh(for: .codex)

0 commit comments

Comments
 (0)