Kill the grid

This commit is contained in:
Garth Vander Houwen 2024-07-18 07:24:55 -07:00
parent 488177c626
commit 609514db79
3 changed files with 88 additions and 63 deletions

View file

@ -679,7 +679,7 @@
"Airtime" : {
},
"AirTm" : {
"AirTm %@%%" : {
},
"Alert" : {
@ -1428,7 +1428,7 @@
"Barometric Pressure" : {
},
"Batt" : {
"Batt %@%%" : {
},
"Battery Level %" : {
@ -3091,7 +3091,7 @@
"CHG" : {
},
"ChUtil" : {
"ChUtil %@%% " : {
},
"Clear" : {
@ -22292,7 +22292,7 @@
"Via Mqtt" : {
},
"Volt" : {
"Volt %@ " : {
},
"voltage" : {

View file

@ -1061,7 +1061,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
}
} catch {
Logger.data.error("💥 Send message failure \(self.connectedPeripheral.num.toHex(), privacy: .public) to \(toUserNum.toHex(), privacy: .public)")
}
}
return success

View file

@ -12,6 +12,7 @@ struct DeviceMetricsLog: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@State private var isPresentingClearLogConfirm: Bool = false
@State var isExporting = false
@ -21,6 +22,8 @@ struct DeviceMetricsLog: View {
@State private var airtimeChartColor: Color = .yellow
@State private var channelUtilizationChartColor: Color = .green
@ObservedObject var node: NodeInfoEntity
@State private var sortOrder = [KeyPathComparator(\TelemetryEntity.time, order: .reverse)]
@State private var selection: TelemetryEntity.ID?
var body: some View {
VStack {
@ -60,11 +63,9 @@ struct DeviceMetricsLog: View {
RuleMark(y: .value("10% Airtime", 10))
.lineStyle(StrokeStyle(lineWidth: 1, dash: [5, 10]))
.foregroundStyle(.yellow)
RuleMark(y: .value("Network Status Orange", 25))
.lineStyle(StrokeStyle(lineWidth: 1, dash: [5, 10]))
.foregroundStyle(.orange)
RuleMark(y: .value("Network Status Red", 50))
.lineStyle(StrokeStyle(lineWidth: 1, dash: [5, 10]))
.foregroundStyle(.red)
@ -97,10 +98,84 @@ struct DeviceMetricsLog: View {
}
let localeDateFormat = DateFormatter.dateFormat(fromTemplate: "yyMdjmma", options: 0, locale: Locale.current)
let dateFormatString = (localeDateFormat ?? "M/d/YY j:mma").replacingOccurrences(of: ",", with: "")
if UIScreen.main.bounds.size.width > 768 && (UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac) {
// Add a table for mac and ipad
// Table(Array(deviceMetrics),id: \.self) {
Table(deviceMetrics) {
/// New SwiftUI Table
if #available(iOS 17.4, macOS 14.4, *) {
Table(deviceMetrics, selection: $selection, sortOrder: $sortOrder) {
if idiom == .phone {
TableColumn("battery.level") { dm in
HStack {
Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Spacer()
}
.font(.caption)
HStack {
if dm.batteryLevel > 100 {
Text("PWD")
} else {
Text("Batt \(String(dm.batteryLevel))%")
}
Text("Volt \(String(format: "%.2f", dm.voltage)) ")
Text("ChUtil \(String(format: "%.2f", dm.channelUtilization))% ")
Text("AirTm \(String(format: "%.2f", dm.airUtilTx))%")
Spacer()
}
.font(.caption2)
}
.width(ideal: 200, max: .infinity)
} else {
TableColumn("battery.level") { dm in
if dm.batteryLevel > 100 {
Text("Powered")
} else {
Text("\(String(dm.batteryLevel))%")
}
}
TableColumn("voltage") { dm in
Text("\(String(format: "%.2f", dm.voltage))")
}
TableColumn("channel.utilization") { dm in
Text("\(String(format: "%.2f", dm.channelUtilization))%")
}
TableColumn("airtime") { dm in
Text("\(String(format: "%.2f", dm.airUtilTx))%")
}
TableColumn("uptime") { dm in
let now = Date.now
let later = now + TimeInterval(dm.uptimeSeconds)
let components = (now..<later).formatted(.components(style: .narrow))
Text(components)
}
TableColumn("timestamp") { dm in
Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
}
.width(min: 180)
}
}
} else if idiom == .phone {
Table(deviceMetrics, selection: $selection, sortOrder: $sortOrder) {
TableColumn("battery.level") { dm in
HStack {
Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Spacer()
}
.font(.caption)
HStack {
if dm.batteryLevel > 100 {
Text("PWD")
} else {
Text("Batt \(String(dm.batteryLevel))%")
}
Text("Volt \(String(format: "%.2f", dm.voltage)) ")
Text("ChUtil \(String(format: "%.2f", dm.channelUtilization))% ")
Text("AirTm \(String(format: "%.2f", dm.airUtilTx))%")
Spacer()
}
.font(.caption2)
}
.width(ideal: 200, max: .infinity)
}
} else {
Table(deviceMetrics, selection: $selection, sortOrder: $sortOrder) {
TableColumn("battery.level") { dm in
if dm.batteryLevel > 100 {
Text("Powered")
@ -128,56 +203,6 @@ struct DeviceMetricsLog: View {
}
.width(min: 180)
}
} else {
ScrollView {
let columns = [
GridItem(.flexible(minimum: 20, maximum: 60), spacing: 0.1),
GridItem(.flexible(minimum: 20, maximum: 60), spacing: 0.1),
GridItem(.flexible(minimum: 20, maximum: 60), spacing: 0.1),
GridItem(.flexible(minimum: 20, maximum: 60), spacing: 0.1),
GridItem(.flexible(minimum: 100, maximum: .infinity), spacing: 0.1)
]
LazyVGrid(columns: columns, alignment: .leading, spacing: 1) {
GridRow {
Text("Batt")
.font(.caption)
.fontWeight(.bold)
Text("Volt")
.font(.caption)
.fontWeight(.bold)
Text("ChUtil")
.font(.caption)
.fontWeight(.bold)
Text("AirTm")
.font(.caption)
.fontWeight(.bold)
Text("timestamp")
.font(.caption)
.fontWeight(.bold)
}
ForEach(deviceMetrics) { dm in
GridRow {
if dm.batteryLevel > 100 {
Text("PWD")
.font(.caption)
} else {
Text("\(String(dm.batteryLevel))%")
.font(.caption)
}
Text(String(dm.voltage))
.font(.caption)
Text("\(String(format: "%.2f", dm.channelUtilization))%")
.font(.caption)
Text("\(String(format: "%.2f", dm.airUtilTx))%")
.font(.caption)
Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
.font(.caption)
}
}
}
.padding(.leading, 15)
.padding(.trailing, 5)
}
}
HStack {
Button(role: .destructive) {
@ -187,7 +212,7 @@ struct DeviceMetricsLog: View {
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
.controlSize(.large)
.controlSize(idiom == .phone ? .regular : .large)
.padding(.bottom)
.padding(.leading)
.confirmationDialog(
@ -212,7 +237,7 @@ struct DeviceMetricsLog: View {
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
.controlSize(.large)
.controlSize(idiom == .phone ? .regular : .large)
.padding(.bottom)
.padding(.trailing)
}