Fit the Status usage bars to the phone width

This commit is contained in:
Ian Gulliver
2026-10-21 22:14:41 -07:00
parent 385be3f330
commit 1eed510320
+51 -13
View File
@@ -293,8 +293,34 @@ private struct RateLimits: View {
} else { } else {
ViewThatFits(in: .horizontal) { ViewThatFits(in: .horizontal) {
grid grid
ScrollView(.horizontal) { stacked
grid }
}
}
private var stacked: some View {
VStack(alignment: .leading, spacing: 0) {
ForEach(limits.keys.sorted(), id: \.self) { vendor in
let usage = limits[vendor]!
vendorHeader(vendor, usage)
Divider().overlay(Palette.border)
ForEach(Array(usage.windows.enumerated()), id: \.offset) { _, w in
let used = usedFraction(w)
let elapsed = elapsedFraction(w)
VStack(alignment: .leading, spacing: 4) {
HStack(alignment: .firstTextBaseline, spacing: 10) {
Text(w.label)
Text(amountText(w)).foregroundStyle(Palette.muted)
Spacer(minLength: 0)
Text(usedText(w, used)).foregroundStyle(usedColor(used))
}
PaceBar(used: used, elapsed: elapsed)
Text("Elapsed \(elapsed.map { percentText($0 * 100) } ?? "—") · resets \(w.resetsAt.map(resetText) ?? "—")")
.font(Fonts.font(11))
.foregroundStyle(Palette.muted)
}
.padding(.vertical, 6)
Divider().overlay(Palette.border)
} }
} }
} }
@@ -320,28 +346,40 @@ private struct RateLimits: View {
Text(title).font(Fonts.font(11)).foregroundStyle(Palette.muted) Text(title).font(Fonts.font(11)).foregroundStyle(Palette.muted)
} }
@ViewBuilder private func vendorHeader(_ vendor: String, _ usage: VendorUsage) -> some View {
private func vendorRows(_ vendor: String, _ usage: VendorUsage) -> some View {
let rejected = usage.rejected != nil || usage.windows.contains { w in w.limit.map { w.used >= $0 } ?? false } let rejected = usage.rejected != nil || usage.windows.contains { w in w.limit.map { w.used >= $0 } ?? false }
let reason = usage.rejected.flatMap { $0.isEmpty ? nil : $0 } let reason = usage.rejected.flatMap { $0.isEmpty ? nil : $0 }
return HStack(alignment: .firstTextBaseline, spacing: 10) {
Text(vendor).font(Fonts.font(13, weight: 700)).foregroundStyle(Palette.text)
Text(rejected ? "rejected\(reason.map { ": \($0)" } ?? "")" : "allowed").font(Fonts.font(11, weight: 700)).foregroundStyle(rejected ? Palette.danger : Palette.ok)
Text("as of \(since(usage.updatedAt))").font(Fonts.font(11)).foregroundStyle(Palette.muted)
}
.padding(.top, 12)
}
private func usedFraction(_ w: UsageWindow) -> Double? {
w.limit.flatMap { $0 > 0 && (w.used / $0).isFinite ? w.used / $0 : nil }
}
private func usedColor(_ used: Double?) -> Color {
used.map { $0 >= 0.9 ? Palette.danger : $0 >= 0.7 ? Palette.warn : Palette.text } ?? Palette.text
}
@ViewBuilder
private func vendorRows(_ vendor: String, _ usage: VendorUsage) -> some View {
GridRow { GridRow {
HStack(alignment: .firstTextBaseline, spacing: 10) { vendorHeader(vendor, usage)
Text(vendor).font(Fonts.font(13, weight: 700)).foregroundStyle(Palette.text) .gridCellColumns(6)
Text(rejected ? "rejected\(reason.map { ": \($0)" } ?? "")" : "allowed").font(Fonts.font(11, weight: 700)).foregroundStyle(rejected ? Palette.danger : Palette.ok)
Text("as of \(since(usage.updatedAt))").font(Fonts.font(11)).foregroundStyle(Palette.muted)
}
.padding(.top, 12)
.gridCellColumns(6)
} }
Divider().overlay(Palette.border) Divider().overlay(Palette.border)
ForEach(Array(usage.windows.enumerated()), id: \.offset) { _, w in ForEach(Array(usage.windows.enumerated()), id: \.offset) { _, w in
let used = w.limit.flatMap { $0 > 0 && (w.used / $0).isFinite ? w.used / $0 : nil } let used = usedFraction(w)
let elapsed = elapsedFraction(w) let elapsed = elapsedFraction(w)
GridRow { GridRow {
Text(w.label).fixedSize() Text(w.label).fixedSize()
Text(amountText(w)).fixedSize() Text(amountText(w)).fixedSize()
Text(usedText(w, used)) Text(usedText(w, used))
.foregroundStyle(used.map { $0 >= 0.9 ? Palette.danger : $0 >= 0.7 ? Palette.warn : Palette.text } ?? Palette.text) .foregroundStyle(usedColor(used))
.fixedSize() .fixedSize()
Text(elapsed.map { percentText($0 * 100) } ?? "—").fixedSize() Text(elapsed.map { percentText($0 * 100) } ?? "—").fixedSize()
PaceBar(used: used, elapsed: elapsed) PaceBar(used: used, elapsed: elapsed)