Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 88 additions & 62 deletions apps/decodex-app/Sources/DecodexApp/AccountPanelView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ enum PanelPalette {
static func glassStroke(_ colorScheme: ColorScheme) -> Color {
colorScheme == .dark
? Color.white.opacity(0.1)
: Color.white.opacity(0.5)
: Color(red: 0.34, green: 0.42, blue: 0.52).opacity(0.18)
}

static func glassInnerShadow(_ colorScheme: ColorScheme) -> Color {
Expand Down Expand Up @@ -1526,8 +1526,11 @@ private struct AccountListScrollIndicatorView: View {
}

private enum AccountRunChipLayout {
static let height: CGFloat = 21
static let cornerRadius: CGFloat = 10.5
static let height: CGFloat = 18.5
static let cornerRadius: CGFloat = 9.25
static let horizontalPadding: CGFloat = 6.5
static let iconWidth: CGFloat = 9.5
static let spacing: CGFloat = 4
}

struct AccountRunChipView: View {
Expand All @@ -1537,21 +1540,21 @@ struct AccountRunChipView: View {
@State private var showsPopover = false

var body: some View {
HStack(spacing: 5) {
HStack(spacing: AccountRunChipLayout.spacing) {
Image(systemName: symbol)
.font(PanelFont.summaryIcon)
.font(PanelFont.runChipIcon)
.foregroundStyle(tint.opacity(colorScheme == .dark ? 0.88 : 0.76))
.frame(width: 11)
.frame(width: AccountRunChipLayout.iconWidth)

Text(run.compactTitle)
.font(PanelFont.metricValue)
.font(PanelFont.runChipTitle)
.foregroundStyle(PanelPalette.primaryText(colorScheme).opacity(0.92))
.lineLimit(1)
.truncationMode(.middle)
.fixedSize(horizontal: true, vertical: false)
}
.frame(height: AccountRunChipLayout.height)
.padding(.horizontal, 8)
.padding(.horizontal, AccountRunChipLayout.horizontalPadding)
.background {
RoundedRectangle(cornerRadius: AccountRunChipLayout.cornerRadius, style: .continuous)
.fill(isHovered ? tint.opacity(colorScheme == .dark ? 0.09 : 0.07) : Color.clear)
Expand Down Expand Up @@ -1761,31 +1764,21 @@ struct AccountPoolUsageEstimateView: View {
@Environment(\.colorScheme) private var colorScheme

var body: some View {
VStack(alignment: .leading, spacing: 4) {
HStack(spacing: 0) {
AccountPoolUsageMetricView(
title: "Pool used",
value: formatUsagePercent(estimate.totalUsedOfCapacityPercent),
tint: poolUsageTint
)

usageDivider

AccountPoolUsageMetricView(
title: "Day Δ",
value: dayDeltaText,
tint: dayDeltaTint
)

usageDivider
VStack(alignment: .leading, spacing: 3) {
HStack(spacing: 5) {
ForEach(Array(metrics.enumerated()), id: \.offset) { index, metric in
AccountPoolUsageMetricView(
title: metric.title,
value: metric.value,
tint: metric.tint
)

AccountPoolUsageMetricView(
title: "Daily avg",
value: formatDailyUsageRate(estimate.averageDailyPoolPercent),
tint: PanelPalette.secondaryText(colorScheme)
)
if index < metrics.count - 1 {
Spacer(minLength: 3)
}
}
}
.frame(height: 30)
.frame(height: 16)

if estimate.accountEstimateCount < estimate.accountCount {
Text("\(estimate.accountEstimateCount)/\(estimate.accountCount) accounts measured")
Expand All @@ -1801,10 +1794,20 @@ struct AccountPoolUsageEstimateView: View {
.accessibilityLabel(accessibilityLabel)
}

private var usageDivider: some View {
Rectangle()
.fill(PanelPalette.separator(colorScheme).opacity(colorScheme == .dark ? 0.72 : 0.9))
.frame(width: 0.5, height: 20)
private var metrics: [(title: String, value: String, tint: Color)] {
[
(
"Pool used",
formatUsagePercent(estimate.totalUsedOfCapacityPercent),
poolUsageTint
),
("Day Δ", dayDeltaText, dayDeltaTint),
(
"Daily avg",
formatDailyUsageRate(estimate.averageDailyPoolPercent),
PanelPalette.secondaryText(colorScheme)
),
]
}

private var accessibilityLabel: String {
Expand Down Expand Up @@ -1922,21 +1925,20 @@ struct AccountPoolUsageMetricView: View {
@Environment(\.colorScheme) private var colorScheme

var body: some View {
VStack(alignment: .leading, spacing: 1) {
HStack(alignment: .firstTextBaseline, spacing: 3) {
Text(title)
.font(PanelFont.metricLabel)
.foregroundStyle(PanelPalette.secondaryText(colorScheme))
.font(PanelFont.usageLabel)
.foregroundStyle(PanelPalette.secondaryText(colorScheme).opacity(0.82))
.lineLimit(1)

Text(value)
.font(PanelFont.metricValue)
.font(PanelFont.usageValue)
.foregroundStyle(tint.opacity(colorScheme == .dark ? 0.94 : 0.78))
.monospacedDigit()
.lineLimit(1)
.minimumScaleFactor(0.72)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 5)
.lineLimit(1)
}
}

Expand Down Expand Up @@ -2460,17 +2462,17 @@ struct OperatorStatusStripView: View {
@Environment(\.colorScheme) private var colorScheme

var body: some View {
VStack(alignment: .leading, spacing: 5) {
HStack(spacing: 0) {
VStack(alignment: .leading, spacing: 4) {
HStack(spacing: 5) {
ForEach(Array(metrics.enumerated()), id: \.element.id) { index, metric in
if index > 0 {
flowDivider
}

OperatorFlowMetricView(metric: metric)

if index < metrics.count - 1 {
Spacer(minLength: 3)
}
}
}
.frame(height: 32)
.frame(height: 16)

if let warning = snapshot.warningSummary {
HStack(spacing: 5) {
Expand Down Expand Up @@ -2501,12 +2503,6 @@ struct OperatorStatusStripView: View {
.modernGlassSurface(cornerRadius: 10, depth: .section)
}

private var flowDivider: some View {
Rectangle()
.fill(PanelPalette.separator(colorScheme).opacity(colorScheme == .dark ? 0.72 : 0.9))
.frame(width: 0.5, height: 21)
}

private var metrics: [OperatorFlowMetric] {
[
OperatorFlowMetric(
Expand Down Expand Up @@ -3007,28 +3003,33 @@ struct OperatorFlowMetric: Identifiable {
var unit: String {
value == 1 ? unitSingular : unitPlural
}

var fullText: String {
"\(title) \(value) \(unit)"
}
}

struct OperatorFlowMetricView: View {
let metric: OperatorFlowMetric
@Environment(\.colorScheme) private var colorScheme

var body: some View {
VStack(alignment: .leading, spacing: 1) {
HStack(alignment: .firstTextBaseline, spacing: 3) {
Text(metric.title)
.font(PanelFont.metricLabel)
.foregroundStyle(PanelPalette.secondaryText(colorScheme))
.font(PanelFont.usageLabel)
.foregroundStyle(PanelPalette.secondaryText(colorScheme).opacity(0.82))
.lineLimit(1)

Text("\(metric.value) \(metric.unit)")
.font(PanelFont.metricValue)
Text("\(metric.value)")
.font(PanelFont.usageValue)
.foregroundStyle(valueTint)
.monospacedDigit()
.lineLimit(1)
.minimumScaleFactor(0.72)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 5)
.help(metric.title)
.lineLimit(1)
.help(metric.fullText)
.accessibilityLabel(metric.fullText)
}

private var valueTint: Color {
Expand Down Expand Up @@ -3630,6 +3631,9 @@ struct ModernGlassSurfaceModifier: ViewModifier {

if #available(macOS 26.0, *) {
content
.background {
shape.fill(surfaceFill)
}
.glassEffect(
configuredGlass,
in: shape
Expand All @@ -3649,6 +3653,7 @@ struct ModernGlassSurfaceModifier: ViewModifier {
content
.background {
shape.fill(materialStyle)
shape.fill(surfaceFill)
}
.overlay {
shape
Expand Down Expand Up @@ -3708,6 +3713,27 @@ struct ModernGlassSurfaceModifier: ViewModifier {
}
}

private var surfaceFill: Color {
switch depth {
case .panel:
return colorScheme == .dark
? Color(red: 0.18, green: 0.22, blue: 0.28).opacity(0.08)
: Color(red: 0.95, green: 0.97, blue: 0.99).opacity(0.38)
case .section:
return colorScheme == .dark
? Color(red: 0.22, green: 0.26, blue: 0.32).opacity(0.15)
: Color(red: 0.86, green: 0.9, blue: 0.95).opacity(0.66)
case .row:
return colorScheme == .dark
? Color(red: 0.2, green: 0.24, blue: 0.3).opacity(0.12)
: Color(red: 0.87, green: 0.91, blue: 0.96).opacity(0.56)
case .control:
return colorScheme == .dark
? Color(red: 0.24, green: 0.29, blue: 0.36).opacity(0.18)
: Color(red: 0.8, green: 0.85, blue: 0.91).opacity(0.72)
}
}

private var surfaceStroke: Color {
switch depth {
case .panel:
Expand Down
4 changes: 3 additions & 1 deletion apps/decodex-app/Sources/DecodexApp/PanelTypography.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum PanelFont {
static let emptyBody = text(10.9, weight: .regular)
static let notice = text(10.6, weight: .regular)

static let accountName = text(13.1, weight: .semibold)
static let accountName = text(12.6, weight: .semibold)
static let accountDetail = text(10.9, weight: .medium)

static let summaryIcon = text(10.4, weight: .medium)
Expand All @@ -36,6 +36,8 @@ enum PanelFont {
static let lanePopoverValue = text(11.0, weight: .semibold)
static let lanePopoverMeta = text(10.6, weight: .medium)
static let lanePopoverChip = text(10.5, weight: .semibold)
static let runChipIcon = text(9.5, weight: .semibold)
static let runChipTitle = text(10.6, weight: .semibold)

static let iconButton = text(11.2, weight: .semibold)
}
Expand Down