diff --git a/Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift b/Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift index 16a8332c..e88a2bee 100644 --- a/Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift @@ -11,11 +11,11 @@ import CoreData extension NodeInfoEntity { var latestPosition: PositionEntity? { - return self.positions?.lastObject as? PositionEntity + return self.positions?.lastObject as? PositionEntity } var latestEnvironmentMetrics: TelemetryEntity? { - return self.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")).lastObject as? TelemetryEntity + return self.telemetries?.filtered(using: NSPredicate(format: "metricsType == 1")).lastObject as? TelemetryEntity } var hasPositions: Bool { diff --git a/Meshtastic/Extensions/Float.swift b/Meshtastic/Extensions/Float.swift index f85e4222..60a45b12 100644 --- a/Meshtastic/Extensions/Float.swift +++ b/Meshtastic/Extensions/Float.swift @@ -15,6 +15,13 @@ extension Float { mf.numberFormatter.maximumFractionDigits = 0 return mf.string(from: temperature) } + func shortFormattedTemperature() -> String { + let temperature = Measurement(value: Double(self), unit: .celsius) + let mf = MeasurementFormatter() + mf.unitStyle = .short + mf.numberFormatter.maximumFractionDigits = 0 + return mf.string(from: temperature) + } func localeTemperature() -> Double { let temperature = Measurement(value: Double(self), unit: .celsius) let locale = NSLocale.current as NSLocale diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index b0c9beb0..8a7b6333 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -22,6 +22,7 @@ struct UserList: View { @State private var viaMqtt = true @State private var isOnline = false @State private var isFavorite = false + @State private var isEnvironment = false @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @State private var hopsAway: Double = -1.0 @@ -171,7 +172,7 @@ struct UserList: View { .listStyle(.plain) .navigationTitle(String.localizedStringWithFormat("contacts %@".localized, String(users.count == 0 ? 0 : users.count - 1))) .sheet(isPresented: $isEditingFilters) { - NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles) + NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles) } .onChange(of: searchText) { _ in searchUserList() diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift index 7c92ab5c..06c255b4 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift @@ -167,10 +167,10 @@ struct NodeDetail: View { IndoorAirQuality(iaq: Int(node.latestEnvironmentMetrics?.iaq ?? 0), displayMode: .gradient) .padding(.vertical) LazyVGrid(columns: gridItemLayout) { - WeatherConditionsCompactWidget(temperature: String(node.latestEnvironmentMetrics?.temperature.formattedTemperature() ?? "99°"), symbolName: "cloud.sun", description: "TEMP") + WeatherConditionsCompactWidget(temperature: String(node.latestEnvironmentMetrics?.temperature.shortFormattedTemperature() ?? "99°"), symbolName: "cloud.sun", description: "TEMP") HumidityCompactWidget(humidity: Int(node.latestEnvironmentMetrics?.relativeHumidity ?? 0), dewPoint: "99°") PressureCompactWidget(pressure: String(node.latestEnvironmentMetrics?.barometricPressure ?? 0.0), unit: "mbar") - //WindCompactWidget(speed: String(node.latestEnvironmentMetrics?.windSpeed ?? 0.0), gust: String(node.latestEnvironmentMetrics?.windGust ?? 0.0), direction: "") + // WindCompactWidget(speed: String(node.latestEnvironmentMetrics?.windSpeed ?? 0.0), gust: String(node.latestEnvironmentMetrics?.windGust ?? 0.0), direction: "") } } } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index 247cb954..e8de1c93 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -16,6 +16,7 @@ struct NodeListFilter: View { @Binding var viaMqtt: Bool @Binding var isOnline: Bool @Binding var isFavorite: Bool + @Binding var isEnvironment: Bool @Binding var distanceFilter: Bool @Binding var maximumDistance: Double @Binding var hopsAway: Double @@ -75,6 +76,19 @@ struct NodeListFilter: View { .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) + Toggle(isOn: $isEnvironment) { + + Label { + Text("Environment") + } icon: { + + Image(systemName: "cloud.sun") + .symbolRenderingMode(.multicolor) + } + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .listRowSeparator(.visible) + Toggle(isOn: $distanceFilter) { Label { diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 096261ad..e06bbcc0 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -18,11 +18,20 @@ struct NodeList: View { @State private var viaMqtt = true @State private var isOnline = false @State private var isFavorite = false + @State private var isEnvironment = false @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @State private var hopsAway: Double = -1.0 @State private var roleFilter = false @State private var deviceRoles: Set = [] + + var boolFilters: [Bool] {[ + isOnline, + isFavorite, + isEnvironment, + distanceFilter, + roleFilter + ]} @State var isEditingFilters = false @@ -92,6 +101,7 @@ struct NodeList: View { viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, + isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, @@ -203,6 +213,11 @@ struct NodeList: View { await searchNodeList() } } + .onChange(of: boolFilters) { _ in + Task { + await searchNodeList() + } + } .onChange(of: [deviceRoles]) { _ in Task { await searchNodeList() @@ -213,26 +228,11 @@ struct NodeList: View { await searchNodeList() } } - .onChange(of: isOnline) { _ in - Task { - await searchNodeList() - } - } - .onChange(of: isFavorite) { _ in - Task { - await searchNodeList() - } - } .onChange(of: maxDistance) { _ in Task { await searchNodeList() } } - .onChange(of: distanceFilter) { _ in - Task { - await searchNodeList() - } - } .onChange(of: (appState.navigationPath)) { newPath in guard let deepLink = newPath else { @@ -310,6 +310,11 @@ struct NodeList: View { let isFavoritePredicate = NSPredicate(format: "favorite == YES") predicates.append(isFavoritePredicate) } + /// Environment + if isEnvironment { + let environmentPredicate = NSPredicate(format: "SUBQUERY(telemetries, $tel, $tel.metricsType == 1).@count > 0") + predicates.append(environmentPredicate) + } /// Distance if distanceFilter { let pointOfInterest = LocationHelper.currentLocation