v2.0.2 — Show spent, limit, and balance in extra usage section

This commit is contained in:
superdooper86
2026-05-07 13:46:36 +02:00
parent 255f3f6cd5
commit 3199b228a8
2 changed files with 40 additions and 16 deletions
+29 -11
View File
@@ -493,6 +493,12 @@ struct ExtraUsageRow: View {
var pct: Double { min(100, max(0, extra.utilization ?? 0)) }
var color: Color { pct > 80 ? .red : pct > 50 ? .orange : .green }
var cur: String { extra.currency ?? "" }
func fmt(_ cents: Double?) -> String {
guard let cents else { return "" }
return String(format: "%.2f", cents / 100)
}
var body: some View {
VStack(alignment: .leading, spacing: 8) {
@@ -503,18 +509,13 @@ struct ExtraUsageRow: View {
Text("Extra Usage Credits")
.font(.system(size: 12, weight: .semibold))
.foregroundColor(.secondary)
Spacer()
Group {
let spent = String(format: "%.2f", (extra.usedCredits ?? 0) / 100)
let currency = extra.currency ?? ""
if let limit = extra.monthlyLimit {
Text("\(currency) \(spent) / \(String(format: "%.2f", limit / 100))")
} else {
Text("\(currency) \(spent) / Unlimited")
}
}
VStack(spacing: 4) {
ExtraUsageLine(label: "Spent", value: "\(cur) \(fmt(extra.usedCredits))", color: color)
ExtraUsageLine(label: "Limit", value: extra.monthlyLimit != nil ? "\(cur) \(fmt(extra.monthlyLimit))" : "Unlimited", color: .secondary)
if extra.currentBalance != nil {
ExtraUsageLine(label: "Balance", value: "\(cur) \(fmt(extra.currentBalance))", color: .primary)
}
.font(.system(size: 11.5, weight: .medium).monospacedDigit())
.foregroundColor(color)
}
if extra.monthlyLimit != nil {
ProgressBar(value: pct / 100, color: color)
@@ -528,6 +529,23 @@ struct ExtraUsageRow: View {
}
}
struct ExtraUsageLine: View {
let label: String
let value: String
let color: Color
var body: some View {
HStack {
Text(label)
.font(.system(size: 11))
.foregroundColor(.secondary)
Spacer()
Text(value)
.font(.system(size: 11.5, weight: .medium).monospacedDigit())
.foregroundColor(color)
}
}
}
// MARK: - Settings View
struct SettingsView: View {
+11 -5
View File
@@ -85,22 +85,28 @@ struct ExtraUsage: Codable {
let isEnabled: Bool
let monthlyLimit: Double?
let usedCredits: Double?
let currentBalance: Double?
let utilization: Double?
let currency: String?
let resetsAt: String?
enum CodingKeys: String, CodingKey {
case isEnabled = "is_enabled"
case monthlyLimit = "monthly_limit"
case usedCredits = "used_credits"
case currentBalance = "current_balance"
case utilization
case currency
case resetsAt = "resets_at"
}
init(from decoder: Decoder) throws {
let c = try decoder.container(keyedBy: CodingKeys.self)
isEnabled = (try? c.decodeIfPresent(Bool.self, forKey: .isEnabled)) ?? false
monthlyLimit = try? c.decodeIfPresent(Double.self, forKey: .monthlyLimit)
usedCredits = try? c.decodeIfPresent(Double.self, forKey: .usedCredits)
utilization = try? c.decodeIfPresent(Double.self, forKey: .utilization)
currency = try? c.decodeIfPresent(String.self, forKey: .currency)
isEnabled = (try? c.decodeIfPresent(Bool.self, forKey: .isEnabled)) ?? false
monthlyLimit = try? c.decodeIfPresent(Double.self, forKey: .monthlyLimit)
usedCredits = try? c.decodeIfPresent(Double.self, forKey: .usedCredits)
currentBalance = try? c.decodeIfPresent(Double.self, forKey: .currentBalance)
utilization = try? c.decodeIfPresent(Double.self, forKey: .utilization)
currency = try? c.decodeIfPresent(String.self, forKey: .currency)
resetsAt = try? c.decodeIfPresent(String.self, forKey: .resetsAt)
}
}