89 lines
2.7 KiB
Swift
89 lines
2.7 KiB
Swift
import SwiftUI
|
|
|
|
struct PageHeader<Trailing: View>: View {
|
|
let title: String
|
|
let subtitle: String?
|
|
@ViewBuilder let trailing: () -> Trailing
|
|
|
|
init(title: String, subtitle: String? = nil, @ViewBuilder trailing: @escaping () -> Trailing = { EmptyView() }) {
|
|
self.title = title
|
|
self.subtitle = subtitle
|
|
self.trailing = trailing
|
|
}
|
|
|
|
var body: some View {
|
|
HStack(alignment: .firstTextBaseline) {
|
|
VStack(alignment: .leading, spacing: 3) {
|
|
Text(title).font(.system(size: 28, weight: .semibold))
|
|
if let subtitle { Text(subtitle).font(.callout).foregroundStyle(.secondary) }
|
|
}
|
|
Spacer()
|
|
trailing()
|
|
}
|
|
.padding(.horizontal, 20)
|
|
.padding(.top, 18)
|
|
.padding(.bottom, 14)
|
|
}
|
|
}
|
|
|
|
struct ResourceSummaryBar: View {
|
|
let snapshot: SystemSnapshot
|
|
|
|
var body: some View {
|
|
HStack(spacing: 22) {
|
|
Label("\(Formatters.percent(snapshot.cpuPercent)) CPU", systemImage: "cpu")
|
|
Label("\(Formatters.percent(snapshot.memoryPercent)) Memory", systemImage: "memorychip")
|
|
Label("\(Formatters.percent(snapshot.diskPercent)) Disk", systemImage: "internaldrive")
|
|
Label("\(Formatters.rate(snapshot.networkReceiveRate + snapshot.networkSendRate)) Network", systemImage: "network")
|
|
Spacer()
|
|
}
|
|
.font(.callout.weight(.medium))
|
|
.padding(.horizontal, 20)
|
|
.padding(.vertical, 9)
|
|
.background(Color.accentColor.opacity(0.06))
|
|
.overlay(alignment: .bottom) { Divider() }
|
|
}
|
|
}
|
|
|
|
struct UpdateStatus: View {
|
|
@Environment(SystemMonitor.self) private var monitor
|
|
|
|
var body: some View {
|
|
HStack(spacing: 6) {
|
|
Circle().fill(monitor.isPaused ? .orange : .green).frame(width: 7, height: 7)
|
|
if monitor.isPaused {
|
|
Text("Updates paused")
|
|
} else if let date = monitor.lastUpdated {
|
|
Text("Updated \(date, style: .relative)")
|
|
} else {
|
|
Text("Collecting system data…")
|
|
}
|
|
}
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
|
|
struct EmptyState: View {
|
|
let icon: String
|
|
let title: String
|
|
let message: String
|
|
|
|
var body: some View {
|
|
ContentUnavailableView(title, systemImage: icon, description: Text(message))
|
|
}
|
|
}
|
|
|
|
struct UpdateSpeedPicker: View {
|
|
@Binding var selection: UpdateSpeed
|
|
|
|
var body: some View {
|
|
Picker("Update speed", selection: $selection) {
|
|
Text("High").tag(UpdateSpeed.high)
|
|
Text("Normal").tag(UpdateSpeed.normal)
|
|
Text("Low").tag(UpdateSpeed.low)
|
|
Text("Paused").tag(UpdateSpeed.paused)
|
|
}
|
|
}
|
|
}
|