diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 77378b59..d287f783 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -105,6 +105,7 @@ DDB75A1A2A05EB67006ED576 /* alpha.png in Resources */ = {isa = PBXBuildFile; fileRef = DDB75A192A05EB67006ED576 /* alpha.png */; }; DDB75A1E2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */; }; DDB75A212A12B954006ED576 /* LoRaSignalStrength.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A202A12B954006ED576 /* LoRaSignalStrength.swift */; }; + DDB75A232A13CDA9006ED576 /* BatteryLevelCompact.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A222A13CDA9006ED576 /* BatteryLevelCompact.swift */; }; DDC2E15826CE248E0042C5E4 /* MeshtasticApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */; }; DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */; }; DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */; }; @@ -296,6 +297,7 @@ DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoRaSignalStrengthIndicator.swift; sourceTree = ""; }; DDB75A1F2A10766D006ED576 /* MeshtasticDataModelV13.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV13.xcdatamodel; sourceTree = ""; }; DDB75A202A12B954006ED576 /* LoRaSignalStrength.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoRaSignalStrength.swift; sourceTree = ""; }; + DDB75A222A13CDA9006ED576 /* BatteryLevelCompact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryLevelCompact.swift; sourceTree = ""; }; DDBA45EC299ED78100DEEDDC /* MeshtasticDataModelV8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV8.xcdatamodel; sourceTree = ""; }; DDC2E15426CE248E0042C5E4 /* Meshtastic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Meshtastic.app; sourceTree = BUILT_PRODUCTS_DIR; }; DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticApp.swift; sourceTree = ""; }; @@ -697,6 +699,7 @@ DD457187293C7E63000C49FB /* BLESignalStrengthIndicator.swift */, DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */, DDB75A202A12B954006ED576 /* LoRaSignalStrength.swift */, + DDB75A222A13CDA9006ED576 /* BatteryLevelCompact.swift */, ); path = Helpers; sourceTree = ""; @@ -1011,6 +1014,7 @@ DD2160AF28C5552500C17253 /* MQTTConfig.swift in Sources */, DDDB444229F8A88700EE2349 /* Double.swift in Sources */, DD5E520F298EE33B00D21B61 /* cannedmessages.pb.swift in Sources */, + DDB75A232A13CDA9006ED576 /* BatteryLevelCompact.swift in Sources */, DDB75A162A0594AD006ED576 /* TileOverlay.swift in Sources */, DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */, DD3CC6BE28E4CD9800FA9159 /* BatteryGauge.swift in Sources */, diff --git a/Meshtastic/Views/Helpers/BatteryLevelCompact.swift b/Meshtastic/Views/Helpers/BatteryLevelCompact.swift new file mode 100644 index 00000000..8cbd4764 --- /dev/null +++ b/Meshtastic/Views/Helpers/BatteryLevelCompact.swift @@ -0,0 +1,88 @@ +// +// BatteryIcon.swift +// Meshtastic +// +// Copyright Garth Vander Houwen 3/24/23. +// +import SwiftUI + +struct BatteryLevelCompact: View { + var batteryLevel: Int32? + var font: Font + var iconFont: Font + var color: Color + + var body: some View { + + HStack (alignment: .center, spacing: 0) { + if batteryLevel == 100 { + + Image(systemName: "battery.100.bolt") + .font(iconFont) + .foregroundColor(color) + .symbolRenderingMode(.hierarchical) + } else if batteryLevel! < 100 && batteryLevel! > 74 { + + Image(systemName: "battery.75") + .font(iconFont) + .foregroundColor(color) + .symbolRenderingMode(.hierarchical) + } else if batteryLevel! < 75 && batteryLevel! > 49 { + + Image(systemName: "battery.50") + .font(iconFont) + .foregroundColor(color) + .symbolRenderingMode(.hierarchical) + } else if batteryLevel! < 50 && batteryLevel! > 14 { + + Image(systemName: "battery.25") + .font(iconFont) + .foregroundColor(color) + .symbolRenderingMode(.hierarchical) + } else if batteryLevel! < 15 && batteryLevel! > 0 { + + Image(systemName: "battery.0") + .font(iconFont) + .foregroundColor(color) + .symbolRenderingMode(.hierarchical) + + } else if batteryLevel! == 0 { + + Image(systemName: "battery.0") + .font(iconFont) + .foregroundColor(.red) + .symbolRenderingMode(.hierarchical) + } else if batteryLevel! > 100 { + + Image(systemName: "powerplug") + .font(iconFont) + .foregroundColor(color) + .symbolRenderingMode(.hierarchical) + } + + if batteryLevel ?? 0 > 100 { + Text("PWD") + .font(font) + } else if batteryLevel == 100 { + Text("CHG") + .font(font) + } else { + Text("\(batteryLevel ?? 0)%") + .font(font) + } + } + } +} + +struct BatteryLevelCompact_Previews: PreviewProvider { + static var previews: some View { + VStack { + BatteryLevelCompact(batteryLevel: 111, font: .footnote, iconFont: .callout, color: Color.accentColor) + BatteryLevelCompact(batteryLevel: 100, font: .footnote, iconFont: .callout, color: Color.accentColor) + BatteryLevelCompact(batteryLevel: 99, font: .footnote, iconFont: .callout, color: Color.accentColor) + BatteryLevelCompact(batteryLevel: 74, font: .footnote, iconFont: .callout, color: Color.accentColor) + BatteryLevelCompact(batteryLevel: 49, font: .footnote, iconFont: .callout, color: Color.accentColor) + BatteryLevelCompact(batteryLevel: 14, font: .footnote, iconFont: .callout, color: Color.accentColor) + } + } +} diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index d4a8aa87..2802c788 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -37,8 +37,15 @@ struct NodeList: View { let connected: Bool = (bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral?.num ?? -1 == node.num) VStack(alignment: .leading) { HStack { - CircleText(text: node.user?.shortName ?? "???", color: Color(UIColor(hex: UInt32(node.num))), circleSize: 65, fontSize: (node.user?.shortName ?? "???").isEmoji() ? 44 : 22, brightness: 0.0, textColor: UIColor(hex: UInt32(node.num)).isLight() ? .black : .white) - .padding(.trailing, 5) + VStack(alignment: .leading) { + CircleText(text: node.user?.shortName ?? "???", color: Color(UIColor(hex: UInt32(node.num))), circleSize: 65, fontSize: (node.user?.shortName ?? "???").isEmoji() ? 44 : 22, brightness: 0.0, textColor: UIColor(hex: UInt32(node.num)).isLight() ? .black : .white) + .padding(.trailing, 5) + let deviceMetrics = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")) + if deviceMetrics?.count ?? 0 >= 1 { + let mostRecent = deviceMetrics?.lastObject as? TelemetryEntity + BatteryLevelCompact(batteryLevel: mostRecent?.batteryLevel, font: .caption2, iconFont: .callout, color: .accentColor) + } + } VStack(alignment: .leading) { Text(node.user?.longName ?? "unknown".localized) .fontWeight(.medium)