-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMenuBarContentView.swift
More file actions
118 lines (107 loc) · 3.84 KB
/
Copy pathMenuBarContentView.swift
File metadata and controls
118 lines (107 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import SwiftUI
struct MenuBarContentView: View {
@ObservedObject var viewModel: UsageViewModel
private let openAIGreen = Color(red: 0.06, green: 0.64, blue: 0.50)
private let openAIDark = Color(red: 0.05, green: 0.06, blue: 0.055)
private let openAIMuted = Color(red: 0.70, green: 0.74, blue: 0.70)
var body: some View {
VStack(alignment: .leading, spacing: 12) {
header
Divider()
.overlay(openAIGreen.opacity(0.28))
content
Divider()
.overlay(openAIGreen.opacity(0.20))
footer
}
.padding(12)
.frame(width: 286)
.background(
LinearGradient(
colors: [
openAIDark.opacity(0.96),
Color(red: 0.08, green: 0.11, blue: 0.09).opacity(0.96)
],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
}
private var header: some View {
HStack {
OpenAIMarkView(color: openAIGreen)
Text("CodexUsage").font(.headline)
.foregroundColor(.white)
Spacer()
if viewModel.isLoading {
ProgressView().controlSize(.small).tint(openAIGreen)
}
}
}
@ViewBuilder
private var content: some View {
if let usage = viewModel.usage {
windowRow(title: "Session", window: usage.session)
windowRow(title: "Week", window: usage.week)
HStack {
Spacer()
Text("Updated \(usage.lastUpdated, style: .time)")
.font(.caption2).foregroundColor(openAIMuted)
}
} else if let error = viewModel.lastError {
VStack(alignment: .leading, spacing: 6) {
Label("Error", systemImage: "exclamationmark.triangle")
.font(.caption.bold()).foregroundColor(.red)
Text(error).font(.caption).foregroundColor(openAIMuted)
.fixedSize(horizontal: false, vertical: true)
}
} else {
HStack {
ProgressView().controlSize(.small).tint(openAIGreen)
Text("Loading…").font(.caption).foregroundColor(openAIMuted)
}
}
}
private func windowRow(title: String, window: UsageWindow) -> some View {
VStack(alignment: .leading, spacing: 4) {
HStack {
Text(window.durationLabel.isEmpty ? title : "\(title) (\(window.durationLabel))")
.font(.caption)
.foregroundColor(openAIMuted)
Spacer()
Text("\(window.displayPercent)%")
.font(.caption.monospacedDigit())
.foregroundColor(tint(for: window.utilization))
}
ProgressView(value: window.safeValue)
.tint(tint(for: window.utilization))
Text("Resets \(window.resetsAt, style: .relative)")
.font(.caption2).foregroundColor(openAIMuted.opacity(0.92))
}
}
private func tint(for pct: Double) -> Color {
if pct >= 0.9 { return .red }
if pct >= 0.7 { return .orange }
return openAIGreen
}
private var footer: some View {
HStack {
Button {
Task { await viewModel.refresh() }
} label: {
Image(systemName: "arrow.clockwise")
.foregroundColor(openAIGreen)
}
.help("Refresh")
Spacer()
SettingsLink { Text("Settings…") }
.foregroundColor(openAIMuted)
Button("Quit") {
NSApp.terminate(nil)
}
.foregroundColor(openAIMuted)
}
.buttonStyle(.borderless)
.font(.caption)
}
}