Includes provider integrations, settings, NSStatusItem UI, tests, Makefile, and README with screenshot. Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
1.9 KiB
Swift
58 lines
1.9 KiB
Swift
import SwiftUI
|
|
|
|
struct PopoverView: View {
|
|
@ObservedObject var refreshService: UsageRefreshService
|
|
@ObservedObject var settings: AppSettings
|
|
@Environment(\.openSettings) private var openSettings
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 12) {
|
|
HStack {
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
Text("AI Menubar Usage")
|
|
.font(.headline)
|
|
if let lastRefresh = refreshService.lastRefreshAt {
|
|
Text("Last refresh \(lastRefresh.formatted(date: .omitted, time: .shortened))")
|
|
.font(.caption2)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
Spacer()
|
|
Button {
|
|
Task { await refreshService.refresh() }
|
|
} label: {
|
|
Image(systemName: "arrow.clockwise")
|
|
}
|
|
.buttonStyle(.borderless)
|
|
.disabled(refreshService.isRefreshing)
|
|
.help("Refresh now")
|
|
}
|
|
|
|
ForEach(settings.enabledProviders) { providerID in
|
|
ProviderCardView(
|
|
providerID: providerID,
|
|
state: refreshService.providerStates[providerID],
|
|
settings: settings
|
|
)
|
|
}
|
|
|
|
Divider()
|
|
|
|
HStack {
|
|
Button("Settings…") {
|
|
openSettings()
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
}
|
|
Spacer()
|
|
Button("Quit") {
|
|
NSApplication.shared.terminate(nil)
|
|
}
|
|
}
|
|
.buttonStyle(.link)
|
|
.font(.caption)
|
|
}
|
|
.padding(14)
|
|
.frame(width: 320)
|
|
.preferredColorScheme(settings.appearanceMode.colorScheme)
|
|
}
|
|
}
|