diff --git a/Cable.xcodeproj/project.pbxproj b/Cable.xcodeproj/project.pbxproj index 70baabb..b8f94db 100644 --- a/Cable.xcodeproj/project.pbxproj +++ b/Cable.xcodeproj/project.pbxproj @@ -405,7 +405,7 @@ CODE_SIGN_ENTITLEMENTS = Cable/Cable.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 32; DEVELOPMENT_TEAM = RE4FXQ754N; ENABLE_APP_SANDBOX = YES; ENABLE_PREVIEWS = YES; @@ -440,7 +440,7 @@ CODE_SIGN_ENTITLEMENTS = Cable/Cable.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 32; DEVELOPMENT_TEAM = RE4FXQ754N; ENABLE_APP_SANDBOX = YES; ENABLE_PREVIEWS = YES; diff --git a/Cable/Overview/SystemOverviewView.swift b/Cable/Overview/SystemOverviewView.swift index 48ed1a0..cf5ce5a 100644 --- a/Cable/Overview/SystemOverviewView.swift +++ b/Cable/Overview/SystemOverviewView.swift @@ -67,19 +67,19 @@ struct SystemOverviewView: View { label: loadsCountLabel, value: "\(loads.count)", tint: .blue - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "battery.100", label: batteryCountLabel, value: "\(batteries.count)", tint: .green - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "bolt.fill", label: chargerCountLabel, value: "\(chargers.count)", tint: .orange - ) + ).frame(maxWidth: .infinity, alignment: .leading) } VStack(alignment: .leading, spacing: 12) { @@ -88,19 +88,19 @@ struct SystemOverviewView: View { label: loadsCountLabel, value: "\(loads.count)", tint: .blue - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "battery.100", label: batteryCountLabel, value: "\(batteries.count)", tint: .green - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "bolt.fill", label: chargerCountLabel, value: "\(chargers.count)", tint: .orange - ) + ).frame(maxWidth: .infinity, alignment: .leading) } } @@ -179,19 +179,19 @@ struct SystemOverviewView: View { label: loadsCountLabel, value: "\(loads.count)", tint: .blue - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "bolt.fill", label: loadsCurrentLabel, value: formattedCurrent(totalCurrent), tint: .orange - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "gauge.medium", label: loadsPowerLabel, value: formattedPower(totalPower), tint: .green - ) + ).frame(maxWidth: .infinity, alignment: .leading) } VStack(alignment: .leading, spacing: 12) { @@ -200,19 +200,19 @@ struct SystemOverviewView: View { label: loadsCountLabel, value: "\(loads.count)", tint: .blue - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "bolt.fill", label: loadsCurrentLabel, value: formattedCurrent(totalCurrent), tint: .orange - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "gauge.medium", label: loadsPowerLabel, value: formattedPower(totalPower), tint: .green - ) + ).frame(maxWidth: .infinity, alignment: .leading) } } @@ -306,19 +306,19 @@ struct SystemOverviewView: View { label: batteryCountLabel, value: "\(batteries.count)", tint: .blue - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "gauge.medium", label: batteryCapacityLabel, value: formattedValue(totalCapacity, unit: "Ah"), tint: .orange - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "bolt.circle", label: batteryEnergyLabel, value: formattedValue(totalEnergy, unit: "Wh"), tint: .green - ) + ).frame(maxWidth: .infinity, alignment: .leading) } VStack(alignment: .leading, spacing: 12) { @@ -327,19 +327,19 @@ struct SystemOverviewView: View { label: batteryCountLabel, value: "\(batteries.count)", tint: .blue - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "gauge.medium", label: batteryCapacityLabel, value: formattedValue(totalCapacity, unit: "Ah"), tint: .orange - ) + ).frame(maxWidth: .infinity, alignment: .leading) summaryMetric( icon: "bolt.circle", label: batteryEnergyLabel, value: formattedValue(totalEnergy, unit: "Wh"), tint: .green - ) + ).frame(maxWidth: .infinity, alignment: .leading) } } } @@ -382,52 +382,19 @@ struct SystemOverviewView: View { } else { ViewThatFits(in: .horizontal) { HStack(spacing: 16) { - summaryMetric( - icon: "bolt.fill", - label: chargerCountLabel, - value: "\(chargers.count)", - tint: .orange - ) - summaryMetric( - icon: "powerplug", - label: chargerOutputLabel, - value: formattedChargerOutput(representativeChargerOutput), - tint: .indigo - ) - summaryMetric( - icon: "gauge.medium", - label: chargerCurrentLabel, - value: formattedCurrent(totalChargerCurrent), - tint: .blue - ) - summaryMetric( - icon: "bolt.circle", - label: chargerPowerLabel, - value: formattedPower(totalChargerPower), - tint: .pink - ) + chargerMetricsContent + } + + LazyVGrid( + columns: Array(repeating: GridItem(.flexible(), spacing: 16), count: 2), + alignment: .leading, + spacing: 16 + ) { + chargerMetricsContent } VStack(alignment: .leading, spacing: 12) { - summaryMetric( - icon: "bolt.fill", - label: chargerCountLabel, - value: "\(chargers.count)", - tint: .orange - ) - summaryMetric( - icon: "powerplug", - label: chargerOutputLabel, - value: formattedChargerOutput(representativeChargerOutput), - tint: .indigo - ) - summaryMetric( - icon: "gauge.medium", - label: chargerCurrentLabel, - value: formattedCurrent(totalChargerCurrent), - tint: .blue - ) - + chargerMetricsContent } } } @@ -443,6 +410,28 @@ struct SystemOverviewView: View { .buttonStyle(.plain) } + @ViewBuilder + private var chargerMetricsContent: some View { + summaryMetric( + icon: "bolt.fill", + label: chargerCountLabel, + value: "\(chargers.count)", + tint: .blue + ).frame(maxWidth: .infinity, alignment: .leading) + summaryMetric( + icon: "gauge.medium", + label: chargerCurrentLabel, + value: formattedCurrent(totalChargerCurrent), + tint: .orange + ).frame(maxWidth: .infinity, alignment: .leading) + summaryMetric( + icon: "bolt.circle", + label: chargerPowerLabel, + value: formattedPower(totalChargerPower), + tint: .green + ).frame(maxWidth: .infinity, alignment: .leading) + } + private var loadStatus: LoadConfigurationStatus? { guard !loads.isEmpty else { return nil } let incomplete = loads.filter { load in