on master help sign in
fix: loading state and Hyper branding in popover

- isLoading now covers both fetches (Hyper + Claude), not just Hyper. Previously when no Hyper API key was set, isLoading was never set to true, so the popover showed ⚡? with no indication anything was loading. - isLoading = false moved to after both applyBalance + applyClaude, so it's not cleared prematurely when the balance result is nil (no key). - Hero section now shows 'Hyper Credits' label above the balance number, and a 'Enter your API key below' prompt when no key is configured.

commit9db15f5e4a8479d9c304014c616f29d78b9f2aab authoriko <mail@iko.soy> dateSat 11 Jul 2026, 18:53 (3 months ago) parent3a0f230
2 files changed+22−4
UsageMenubar/MenuView.swift+18 UsageMenubar/ViewModel.swift+4−4
UsageMenubar/MenuView.swift+18
@@ -66,8 +66,26 @@ struct MenuView: View {
6666 if viewModel.isLoading && viewModel.balance == nil {
6767 PulsingBolt()
6868 .transition(.opacity)
69+ } else if viewModel.balance == nil {
70+ VStack(spacing: 6) {
71+ Text("Hyper Credits")
72+ .font(Self.sectionFont)
73+ .foregroundColor(.secondary)
74+
75+ Text("⚡?")
76+ .font(Self.heroFont)
77+ .foregroundColor(.secondary)
78+
79+ Text("Enter your API key below")
80+ .font(Self.captionFont)
81+ .foregroundColor(.secondary)
82+ }
83+ .transition(.opacity)
6984 } else {
7085 VStack(spacing: 6) {
86+ Text("Hyper Credits")
87+ .font(Self.sectionFont)
88+ .foregroundColor(.secondary)
7189 balanceNumber
7290 caption
7391 sparkline
UsageMenubar/ViewModel.swift+4−4
@@ -276,14 +276,15 @@ final class ViewModel: ObservableObject {
276276 errorMessage = nil
277277 lastUpdated = nil
278278 history.removeAll()
279− isLoading = false
280279 }
281280
282281 refreshTask = Task { @MainActor in
283282 // Check cancellation before setting isLoading — a previous
284283 // refresh() may have cancelled us and already set isLoading = false.
285284 guard !Task.isCancelled else { return }
286− if !key.isEmpty { isLoading = true }
285+ // Loading state covers both fetches: the popover's loading view depends
286+ // on it, and Claude usage is fetched even when there's no Hyper key.
287+ isLoading = true
287288 // Don't clear the errors here — keep showing the last one
288289 // until we have a successful result.
289290
@@ -297,6 +298,7 @@ final class ViewModel: ObservableObject {
297298
298299 applyBalance(balanceResult)
299300 applyClaude(claudeResult)
301+ isLoading = false
300302 }
301303 }
302304
@@ -338,8 +340,6 @@ final class ViewModel: ObservableObject {
338340 // (it's already nil in that case, so nothing to do).
339341 errorMessage = error.localizedDescription
340342 }
341−
342− isLoading = false
343343 }
344344
345345 // MARK: - Claude Usage