File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11import Foundation
22
3+ enum BillingStatus : Equatable {
4+ case ok
5+ case paymentRequired
6+ case sessionExpired
7+ case forbidden
8+ case rateLimited
9+
10+ var message : String {
11+ switch self {
12+ case . ok: return " "
13+ case . paymentRequired: return " Payment required — update billing at claude.ai "
14+ case . sessionExpired: return " Session expired — please refresh your cookie "
15+ case . forbidden: return " Access denied — cookie may be invalid or account suspended "
16+ case . rateLimited: return " Rate limited — too many requests, try again later "
17+ }
18+ }
19+
20+ var icon : String {
21+ switch self {
22+ case . ok: return " "
23+ case . paymentRequired: return " creditcard.trianglebadge.exclamationmark "
24+ case . sessionExpired: return " key.slash "
25+ case . forbidden: return " lock.slash "
26+ case . rateLimited: return " clock.badge.exclamationmark "
27+ }
28+ }
29+ }
30+
331struct Account : Codable , Identifiable {
432 var id : String
533 var label : String
@@ -21,6 +49,7 @@ struct Account: Codable, Identifiable {
2149 var weeklySonnetResetsAt : Date ?
2250 var hasWeeklySonnet : Bool = false
2351 var errorMessage : String ?
52+ var billingStatus : BillingStatus = . ok
2453 var hasFetchedData : Bool = false
2554 var lastUpdated : Date ?
2655
Original file line number Diff line number Diff line change @@ -172,8 +172,14 @@ class AccountsManager: ObservableObject {
172172 guard let idx = self . accounts. firstIndex ( where: { $0. id == accountId } ) else { return }
173173 if error != nil { self . accounts [ idx] . errorMessage = " Network error " ; self . delegate? . refreshMenuBar ( ) ; return }
174174 guard let http = response as? HTTPURLResponse else { self . accounts [ idx] . errorMessage = " Invalid response " ; return }
175- if http. statusCode == 200 , let data { self . parseUsageData ( data, accountIndex: idx) }
176- else { self . accounts [ idx] . errorMessage = " HTTP \( http. statusCode) " }
175+ if http. statusCode == 200 , let data {
176+ self . accounts [ idx] . billingStatus = . ok
177+ self . parseUsageData ( data, accountIndex: idx)
178+ } else {
179+ self . accounts [ idx] . billingStatus = Self . billingStatus ( for: http. statusCode)
180+ self . accounts [ idx] . errorMessage = self . accounts [ idx] . billingStatus == . ok
181+ ? " HTTP \( http. statusCode) " : nil
182+ }
177183 self . delegate? . refreshMenuBar ( )
178184 }
179185 } . resume ( )
@@ -213,4 +219,14 @@ class AccountsManager: ObservableObject {
213219 for i in accounts. indices { accounts [ i] . updatePercentages ( ) }
214220 }
215221
222+ private static func billingStatus( for statusCode: Int ) -> BillingStatus {
223+ switch statusCode {
224+ case 401 : return . sessionExpired
225+ case 402 : return . paymentRequired
226+ case 403 : return . forbidden
227+ case 429 : return . rateLimited
228+ default : return . ok
229+ }
230+ }
231+
216232}
You can’t perform that action at this time.
0 commit comments