import CodexBarCoreimport SwiftUIimport WidgetKit struct CodexBarUsageWidgetView: View { @Environment(\.widgetFamily) private var family let entry: CodexBarWidgetEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) if let providerEntry { self.content(providerEntry: providerEntry) } else { self.emptyState } } .containerBackground(.fill.tertiary, for: .widget) } @ViewBuilder private func content(providerEntry: WidgetSnapshot.ProviderEntry) -> some View { switch self.family { case .systemSmall: SmallUsageView(entry: providerEntry) case .systemMedium: MediumUsageView(entry: providerEntry) default: LargeUsageView(entry: providerEntry) } } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.body) .fontWeight(.semibold) Text("Usage data will appear once the app refreshes.") .font(.caption) .foregroundStyle(.secondary) } .padding(12) }} struct CodexBarHistoryWidgetView: View { @Environment(\.widgetFamily) private var family let entry: CodexBarWidgetEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) if let providerEntry { HistoryView(entry: providerEntry, isLarge: self.family == .systemLarge) } else { self.emptyState } } .containerBackground(.fill.tertiary, for: .widget) } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.body) .fontWeight(.semibold) Text("Usage history will appear after a refresh.") .font(.caption) .foregroundStyle(.secondary) } .padding(12) }} struct CodexBarCompactWidgetView: View { let entry: CodexBarCompactEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) if let providerEntry { CompactMetricView(entry: providerEntry, metric: self.entry.metric) } else { self.emptyState } } .containerBackground(.fill.tertiary, for: .widget) } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.body) .fontWeight(.semibold) Text("Usage data will appear once the app refreshes.") .font(.caption) .foregroundStyle(.secondary) } .padding(12) }} struct CodexBarSwitcherWidgetView: View { @Environment(\.widgetFamily) private var family let entry: CodexBarSwitcherEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) VStack(alignment: .leading, spacing: 10) { ProviderSwitcherRow( providers: self.entry.availableProviders, selected: self.entry.provider, updatedAt: providerEntry?.updatedAt ?? Date(), compact: self.family == .systemSmall, showsTimestamp: self.family != .systemSmall) if let providerEntry { self.content(providerEntry: providerEntry) } else { self.emptyState } } .padding(12) } .containerBackground(.fill.tertiary, for: .widget) } @ViewBuilder private func content(providerEntry: WidgetSnapshot.ProviderEntry) -> some View { switch self.family { case .systemSmall: SwitcherSmallUsageView(entry: providerEntry) case .systemMedium: SwitcherMediumUsageView(entry: providerEntry) default: SwitcherLargeUsageView(entry: providerEntry) } } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.caption) .foregroundStyle(.secondary) Text("Usage data appears after a refresh.") .font(.caption2) .foregroundStyle(.secondary) } }} private struct CompactMetricView: View { let entry: WidgetSnapshot.ProviderEntry let metric: CompactMetric var body: some View { let display = self.display VStack(alignment: .leading, spacing: 8) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) VStack(alignment: .leading, spacing: 2) { Text(display.value) .font(.title2) .fontWeight(.semibold) Text(display.label) .font(.caption2) .foregroundStyle(.secondary) if let detail = display.detail { Text(detail) .font(.caption2) .foregroundStyle(.secondary) } } } .padding(12) } private var display: (value: String, label: String, detail: String?) { switch self.metric { case .credits: let value = self.entry.creditsRemaining.map(WidgetFormat.credits) ?? "—" return (value, "Credits left", nil) case .todayCost: let value = self.entry.tokenUsage?.sessionCostUSD.map(WidgetFormat.usd) ?? "—" let detail = self.entry.tokenUsage?.sessionTokens.map(WidgetFormat.tokenCount) return (value, "Today cost", detail) case .last30DaysCost: let value = self.entry.tokenUsage?.last30DaysCostUSD.map(WidgetFormat.usd) ?? "—" let detail = self.entry.tokenUsage?.last30DaysTokens.map(WidgetFormat.tokenCount) return (value, "30d cost", detail) } }} private struct ProviderSwitcherRow: View { let providers: [UsageProvider] let selected: UsageProvider let updatedAt: Date let compact: Bool let showsTimestamp: Bool var body: some View { HStack(spacing: self.compact ? 4 : 6) { ForEach(self.providers, id: \.self) { provider in ProviderSwitchChip( provider: provider, selected: provider == self.selected, compact: self.compact) } if self.showsTimestamp { Spacer(minLength: 6) Text(WidgetFormat.relativeDate(self.updatedAt)) .font(.caption2) .foregroundStyle(.secondary) } } }} private struct ProviderSwitchChip: View { let provider: UsageProvider let selected: Bool let compact: Bool var body: some View { let label = self.compact ? self.shortLabel : self.longLabel let background = self.selected ? WidgetColors.color(for: self.provider).opacity(0.2) : Color.primary.opacity(0.08) if let choice = ProviderChoice(provider: self.provider) { Button(intent: SwitchWidgetProviderIntent(provider: choice)) { Text(label) .font(self.compact ? .caption2.weight(.semibold) : .caption.weight(.semibold)) .foregroundStyle(self.selected ? Color.primary : Color.secondary) .padding(.horizontal, self.compact ? 6 : 8) .padding(.vertical, self.compact ? 3 : 4) .background(Capsule().fill(background)) } .buttonStyle(.plain) } else { Text(label) .font(self.compact ? .caption2.weight(.semibold) : .caption.weight(.semibold)) .foregroundStyle(self.selected ? Color.primary : Color.secondary) .padding(.horizontal, self.compact ? 6 : 8) .padding(.vertical, self.compact ? 3 : 4) .background(Capsule().fill(background)) } } private var longLabel: String { ProviderDefaults.metadata[self.provider]?.displayName ?? self.provider.rawValue.capitalized } private var shortLabel: String { switch self.provider { case .codex: "Codex" case .claude: "Claude" case .gemini: "Gemini" case .antigravity: "Anti" case .cursor: "Cursor" case .opencode: "OpenCode" case .zai: "z.ai" case .factory: "Droid" case .copilot: "Copilot" case .minimax: "MiniMax" case .vertexai: "Vertex" case .kiro: "Kiro" case .augment: "Augment" case .jetbrains: "JetBrains" case .kimi: "Kimi" case .kimik2: "Kimi K2" case .amp: "Amp" case .synthetic: "Synthetic" case .warp: "Warp" } }} private struct SwitcherSmallUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 8) { UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } } }} private struct SwitcherMediumUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 10) { UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) } } }} private struct SwitcherLargeUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 12) { UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { VStack(alignment: .leading, spacing: 4) { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) ValueLine( title: "30d", value: WidgetFormat.costAndTokens( cost: token.last30DaysCostUSD, tokens: token.last30DaysTokens)) } } UsageHistoryChart(points: self.entry.dailyUsage, color: WidgetColors.color(for: self.entry.provider)) .frame(height: 50) } }} private struct SmallUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 8) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } } .padding(12) }} private struct MediumUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 10) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) } } .padding(12) }} private struct LargeUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 12) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { VStack(alignment: .leading, spacing: 4) { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) ValueLine( title: "30d", value: WidgetFormat.costAndTokens( cost: token.last30DaysCostUSD, tokens: token.last30DaysTokens)) } } UsageHistoryChart(points: self.entry.dailyUsage, color: WidgetColors.color(for: self.entry.provider)) .frame(height: 50) } .padding(12) }} private struct HistoryView: View { let entry: WidgetSnapshot.ProviderEntry let isLarge: Bool var body: some View { VStack(alignment: .leading, spacing: 12) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageHistoryChart(points: self.entry.dailyUsage, color: WidgetColors.color(for: self.entry.provider)) .frame(height: self.isLarge ? 90 : 60) if let token = entry.tokenUsage { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) ValueLine( title: "30d", value: WidgetFormat.costAndTokens(cost: token.last30DaysCostUSD, tokens: token.last30DaysTokens)) } } .padding(12) }} private struct HeaderView: View { let provider: UsageProvider let updatedAt: Date var body: some View { HStack(alignment: .firstTextBaseline) { Text(ProviderDefaults.metadata[self.provider]?.displayName ?? self.provider.rawValue.capitalized) .font(.body) .fontWeight(.semibold) Spacer() Text(WidgetFormat.relativeDate(self.updatedAt)) .font(.caption2) .foregroundStyle(.secondary) }Lines 1–500 of 659. Load more
import CodexBarCore import SwiftUI import WidgetKit struct CodexBarUsageWidgetView: View { @Environment(\.widgetFamily) private var family let entry: CodexBarWidgetEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) if let providerEntry { self.content(providerEntry: providerEntry) } else { self.emptyState } } .containerBackground(.fill.tertiary, for: .widget) } @ViewBuilder private func content(providerEntry: WidgetSnapshot.ProviderEntry) -> some View { switch self.family { case .systemSmall: SmallUsageView(entry: providerEntry) case .systemMedium: MediumUsageView(entry: providerEntry) default: LargeUsageView(entry: providerEntry) } } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.body) .fontWeight(.semibold) Text("Usage data will appear once the app refreshes.") .font(.caption) .foregroundStyle(.secondary) } .padding(12) } } struct CodexBarHistoryWidgetView: View { @Environment(\.widgetFamily) private var family let entry: CodexBarWidgetEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) if let providerEntry { HistoryView(entry: providerEntry, isLarge: self.family == .systemLarge) } else { self.emptyState } } .containerBackground(.fill.tertiary, for: .widget) } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.body) .fontWeight(.semibold) Text("Usage history will appear after a refresh.") .font(.caption) .foregroundStyle(.secondary) } .padding(12) } } struct CodexBarCompactWidgetView: View { let entry: CodexBarCompactEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) if let providerEntry { CompactMetricView(entry: providerEntry, metric: self.entry.metric) } else { self.emptyState } } .containerBackground(.fill.tertiary, for: .widget) } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.body) .fontWeight(.semibold) Text("Usage data will appear once the app refreshes.") .font(.caption) .foregroundStyle(.secondary) } .padding(12) } } struct CodexBarSwitcherWidgetView: View { @Environment(\.widgetFamily) private var family let entry: CodexBarSwitcherEntry var body: some View { let providerEntry = self.entry.snapshot.entries.first { $0.provider == self.entry.provider } ZStack { Color.black.opacity(0.02) VStack(alignment: .leading, spacing: 10) { ProviderSwitcherRow( providers: self.entry.availableProviders, selected: self.entry.provider, updatedAt: providerEntry?.updatedAt ?? Date(), compact: self.family == .systemSmall, showsTimestamp: self.family != .systemSmall) if let providerEntry { self.content(providerEntry: providerEntry) } else { self.emptyState } } .padding(12) } .containerBackground(.fill.tertiary, for: .widget) } @ViewBuilder private func content(providerEntry: WidgetSnapshot.ProviderEntry) -> some View { switch self.family { case .systemSmall: SwitcherSmallUsageView(entry: providerEntry) case .systemMedium: SwitcherMediumUsageView(entry: providerEntry) default: SwitcherLargeUsageView(entry: providerEntry) } } private var emptyState: some View { VStack(alignment: .leading, spacing: 6) { Text("Open CodexBar") .font(.caption) .foregroundStyle(.secondary) Text("Usage data appears after a refresh.") .font(.caption2) .foregroundStyle(.secondary) } } } private struct CompactMetricView: View { let entry: WidgetSnapshot.ProviderEntry let metric: CompactMetric var body: some View { let display = self.display VStack(alignment: .leading, spacing: 8) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) VStack(alignment: .leading, spacing: 2) { Text(display.value) .font(.title2) .fontWeight(.semibold) Text(display.label) .font(.caption2) .foregroundStyle(.secondary) if let detail = display.detail { Text(detail) .font(.caption2) .foregroundStyle(.secondary) } } } .padding(12) } private var display: (value: String, label: String, detail: String?) { switch self.metric { case .credits: let value = self.entry.creditsRemaining.map(WidgetFormat.credits) ?? "—" return (value, "Credits left", nil) case .todayCost: let value = self.entry.tokenUsage?.sessionCostUSD.map(WidgetFormat.usd) ?? "—" let detail = self.entry.tokenUsage?.sessionTokens.map(WidgetFormat.tokenCount) return (value, "Today cost", detail) case .last30DaysCost: let value = self.entry.tokenUsage?.last30DaysCostUSD.map(WidgetFormat.usd) ?? "—" let detail = self.entry.tokenUsage?.last30DaysTokens.map(WidgetFormat.tokenCount) return (value, "30d cost", detail) } } } private struct ProviderSwitcherRow: View { let providers: [UsageProvider] let selected: UsageProvider let updatedAt: Date let compact: Bool let showsTimestamp: Bool var body: some View { HStack(spacing: self.compact ? 4 : 6) { ForEach(self.providers, id: \.self) { provider in ProviderSwitchChip( provider: provider, selected: provider == self.selected, compact: self.compact) } if self.showsTimestamp { Spacer(minLength: 6) Text(WidgetFormat.relativeDate(self.updatedAt)) .font(.caption2) .foregroundStyle(.secondary) } } } } private struct ProviderSwitchChip: View { let provider: UsageProvider let selected: Bool let compact: Bool var body: some View { let label = self.compact ? self.shortLabel : self.longLabel let background = self.selected ? WidgetColors.color(for: self.provider).opacity(0.2) : Color.primary.opacity(0.08) if let choice = ProviderChoice(provider: self.provider) { Button(intent: SwitchWidgetProviderIntent(provider: choice)) { Text(label) .font(self.compact ? .caption2.weight(.semibold) : .caption.weight(.semibold)) .foregroundStyle(self.selected ? Color.primary : Color.secondary) .padding(.horizontal, self.compact ? 6 : 8) .padding(.vertical, self.compact ? 3 : 4) .background(Capsule().fill(background)) } .buttonStyle(.plain) } else { Text(label) .font(self.compact ? .caption2.weight(.semibold) : .caption.weight(.semibold)) .foregroundStyle(self.selected ? Color.primary : Color.secondary) .padding(.horizontal, self.compact ? 6 : 8) .padding(.vertical, self.compact ? 3 : 4) .background(Capsule().fill(background)) } } private var longLabel: String { ProviderDefaults.metadata[self.provider]?.displayName ?? self.provider.rawValue.capitalized } private var shortLabel: String { switch self.provider { case .codex: "Codex" case .claude: "Claude" case .gemini: "Gemini" case .antigravity: "Anti" case .cursor: "Cursor" case .opencode: "OpenCode" case .zai: "z.ai" case .factory: "Droid" case .copilot: "Copilot" case .minimax: "MiniMax" case .vertexai: "Vertex" case .kiro: "Kiro" case .augment: "Augment" case .jetbrains: "JetBrains" case .kimi: "Kimi" case .kimik2: "Kimi K2" case .amp: "Amp" case .synthetic: "Synthetic" case .warp: "Warp" } } } private struct SwitcherSmallUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 8) { UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } } } } private struct SwitcherMediumUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 10) { UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) } } } } private struct SwitcherLargeUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 12) { UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { VStack(alignment: .leading, spacing: 4) { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) ValueLine( title: "30d", value: WidgetFormat.costAndTokens( cost: token.last30DaysCostUSD, tokens: token.last30DaysTokens)) } } UsageHistoryChart(points: self.entry.dailyUsage, color: WidgetColors.color(for: self.entry.provider)) .frame(height: 50) } } } private struct SmallUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 8) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } } .padding(12) } } private struct MediumUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 10) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) } } .padding(12) } } private struct LargeUsageView: View { let entry: WidgetSnapshot.ProviderEntry var body: some View { VStack(alignment: .leading, spacing: 12) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.sessionLabel ?? "Session", percentLeft: self.entry.primary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) UsageBarRow( title: ProviderDefaults.metadata[self.entry.provider]?.weeklyLabel ?? "Weekly", percentLeft: self.entry.secondary?.remainingPercent, color: WidgetColors.color(for: self.entry.provider)) if let codeReview = entry.codeReviewRemainingPercent { UsageBarRow( title: "Code review", percentLeft: codeReview, color: WidgetColors.color(for: self.entry.provider)) } if let credits = entry.creditsRemaining { ValueLine(title: "Credits", value: WidgetFormat.credits(credits)) } if let token = entry.tokenUsage { VStack(alignment: .leading, spacing: 4) { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) ValueLine( title: "30d", value: WidgetFormat.costAndTokens( cost: token.last30DaysCostUSD, tokens: token.last30DaysTokens)) } } UsageHistoryChart(points: self.entry.dailyUsage, color: WidgetColors.color(for: self.entry.provider)) .frame(height: 50) } .padding(12) } } private struct HistoryView: View { let entry: WidgetSnapshot.ProviderEntry let isLarge: Bool var body: some View { VStack(alignment: .leading, spacing: 12) { HeaderView(provider: self.entry.provider, updatedAt: self.entry.updatedAt) UsageHistoryChart(points: self.entry.dailyUsage, color: WidgetColors.color(for: self.entry.provider)) .frame(height: self.isLarge ? 90 : 60) if let token = entry.tokenUsage { ValueLine( title: "Today", value: WidgetFormat.costAndTokens(cost: token.sessionCostUSD, tokens: token.sessionTokens)) ValueLine( title: "30d", value: WidgetFormat.costAndTokens(cost: token.last30DaysCostUSD, tokens: token.last30DaysTokens)) } } .padding(12) } } private struct HeaderView: View { let provider: UsageProvider let updatedAt: Date var body: some View { HStack(alignment: .firstTextBaseline) { Text(ProviderDefaults.metadata[self.provider]?.displayName ?? self.provider.rawValue.capitalized) .font(.body) .fontWeight(.semibold) Spacer() Text(WidgetFormat.relativeDate(self.updatedAt)) .font(.caption2) .foregroundStyle(.secondary) }