From 85a030373178427c4a63b492bb3080c9e1b9d721 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 13 Dec 2024 20:53:07 -0800 Subject: [PATCH 1/3] Bump version --- Meshtastic.xcodeproj/project.pbxproj | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 35592c2d..f4adb4b5 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1524,7 +1524,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.5; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.MeshtasticTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1547,7 +1547,7 @@ DEVELOPMENT_TEAM = GCH7VS5Y9R; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.5; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.MeshtasticTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1704,7 +1704,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.11; + MARKETING_VERSION = 2.5.12; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1738,7 +1738,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.11; + MARKETING_VERSION = 2.5.12; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1764,13 +1764,13 @@ INFOPLIST_FILE = Widgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Widgets; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 16.6; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.11; + MARKETING_VERSION = 2.5.12; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1797,13 +1797,13 @@ INFOPLIST_FILE = Widgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Widgets; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 16.6; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.11; + MARKETING_VERSION = 2.5.12; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From e118412808ecaee1cfc44aebaf355f0183ef6ce1 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 13 Dec 2024 21:11:12 -0800 Subject: [PATCH 2/3] Add ignore node button --- Localizable.xcstrings | 6 + Meshtastic.xcodeproj/project.pbxproj | 8 +- Meshtastic/Helpers/BLEManager.swift | 58 +++ Meshtastic/Helpers/MeshPackets.swift | 2 + .../Meshtastic.xcdatamodeld/.xccurrentversion | 2 +- .../contents | 485 ++++++++++++++++++ .../Helpers/Actions/IgnoreNodeButton.swift | 45 ++ Meshtastic/Views/Nodes/NodeList.swift | 5 + 8 files changed, 609 insertions(+), 2 deletions(-) create mode 100644 Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 47.xcdatamodel/contents create mode 100644 Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift diff --git a/Localizable.xcstrings b/Localizable.xcstrings index ad45481e..caa1ef6e 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -8954,6 +8954,9 @@ }, "Ignore MQTT" : { + }, + "Ignore Node" : { + }, "Import Route" : { @@ -18055,6 +18058,9 @@ } } } + }, + "Remove from ignored" : { + }, "Replace Channels" : { diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index f4adb4b5..71e33de4 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -215,6 +215,7 @@ DDDE5A1129AFE69700490C6C /* MeshActivityAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDE5A0F29AFE69700490C6C /* MeshActivityAttributes.swift */; }; DDDE5A1329AFEAB900490C6C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDDE5A1229AFEAB900490C6C /* Assets.xcassets */; }; DDDE5A1429AFEAB900490C6C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDDE5A1229AFEAB900490C6C /* Assets.xcassets */; }; + DDDFE73F2D0D48FF0044463C /* IgnoreNodeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDFE73E2D0D48FF0044463C /* IgnoreNodeButton.swift */; }; DDE0F7C5295F77B700B8AAB3 /* AppSettingsEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE0F7C4295F77B700B8AAB3 /* AppSettingsEnums.swift */; }; DDE5B4042B2279A700FCDD05 /* TraceRouteLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE5B4032B2279A700FCDD05 /* TraceRouteLog.swift */; }; DDE9659C2B1C3B6A00531070 /* RouteRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE9659B2B1C3B6A00531070 /* RouteRecorder.swift */; }; @@ -506,6 +507,8 @@ DDDE5A0F29AFE69700490C6C /* MeshActivityAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshActivityAttributes.swift; sourceTree = ""; }; DDDE5A1229AFEAB900490C6C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; DDDEE5E229DBE43E00A8E078 /* MeshtasticDataModelV11.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV11.xcdatamodel; sourceTree = ""; }; + DDDFE73E2D0D48FF0044463C /* IgnoreNodeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IgnoreNodeButton.swift; sourceTree = ""; }; + DDDFE7402D0D4A070044463C /* MeshtasticDataModelV 47.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 47.xcdatamodel"; sourceTree = ""; }; DDE0F7C4295F77B700B8AAB3 /* AppSettingsEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettingsEnums.swift; sourceTree = ""; }; DDE5B4032B2279A700FCDD05 /* TraceRouteLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraceRouteLog.swift; sourceTree = ""; }; DDE5B4052B227E3200FCDD05 /* TraceRouteEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraceRouteEntityExtension.swift; sourceTree = ""; }; @@ -555,6 +558,7 @@ 251926882C3BAF2E00249DF5 /* Actions */ = { isa = PBXGroup; children = ( + DDDFE73E2D0D48FF0044463C /* IgnoreNodeButton.swift */, 251926842C3BA97800249DF5 /* FavoriteNodeButton.swift */, 251926892C3BB1B200249DF5 /* ExchangePositionsButton.swift */, 251926862C3BAE2200249DF5 /* NodeAlertsButton.swift */, @@ -1311,6 +1315,7 @@ 6D825E622C34786C008DBEE4 /* CommonRegex.swift in Sources */, DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */, DDDB444C29F8AAA600EE2349 /* Color.swift in Sources */, + DDDFE73F2D0D48FF0044463C /* IgnoreNodeButton.swift in Sources */, DDB8F4122A9EE5DD00230ECE /* UserList.swift in Sources */, DDB75A0F2A05920E006ED576 /* FileManager.swift in Sources */, DD3D17E02C3FB67200561584 /* LocalWeatherConditions.swift in Sources */, @@ -1915,6 +1920,7 @@ DD3CC6BA28E366DF00FA9159 /* Meshtastic.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + DDDFE7402D0D4A070044463C /* MeshtasticDataModelV 47.xcdatamodel */, DD0BE30C2CB785D8000BA445 /* MeshtasticDataModelV 46.xcdatamodel */, DD6D5A342CA13BA600ED3032 /* MeshtasticDataModelV 45.xcdatamodel */, DD7CF8DA2C93663C008BD10E /* MeshtasticDataModelV 44.xcdatamodel */, @@ -1962,7 +1968,7 @@ DD5D0A9A2931AD6B00F7EA61 /* MeshtasticDataModelV2.xcdatamodel */, DD3CC6BB28E366DF00FA9159 /* MeshtasticDataModel.xcdatamodel */, ); - currentVersion = DD0BE30C2CB785D8000BA445 /* MeshtasticDataModelV 46.xcdatamodel */; + currentVersion = DDDFE7402D0D4A070044463C /* MeshtasticDataModelV 47.xcdatamodel */; name = Meshtastic.xcdatamodeld; path = Meshtastic/Meshtastic.xcdatamodeld; sourceTree = ""; diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 90d9f978..0234ce78 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -1895,6 +1895,64 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return false } + public func setIgnoredNode(node: NodeInfoEntity, connectedNodeNum: Int64) -> Bool { + var adminPacket = AdminMessage() + adminPacket.setIgnoredNode = UInt32(node.num) + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedNodeNum) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Bool { + var adminPacket = AdminMessage() + adminPacket.removeIgnoredNode = UInt32(node.num) + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedNodeNum) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Int64 { var adminPacket = AdminMessage() adminPacket.setHamMode = ham diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index b2f59586..273ef683 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -270,6 +270,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje newNode.num = Int64(nodeInfo.num) newNode.channel = Int32(nodeInfo.channel) newNode.favorite = nodeInfo.isFavorite + newNode.ignored = nodeInfo.isIgnored newNode.hopsAway = Int32(nodeInfo.hopsAway) if nodeInfo.hasDeviceMetrics { @@ -358,6 +359,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje fetchedNode[0].snr = nodeInfo.snr fetchedNode[0].channel = Int32(nodeInfo.channel) fetchedNode[0].favorite = nodeInfo.isFavorite + fetchedNode[0].ignored = nodeInfo.isIgnored fetchedNode[0].hopsAway = Int32(nodeInfo.hopsAway) if nodeInfo.hasUser { diff --git a/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion b/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion index 6d376a5f..3581f63f 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion +++ b/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - MeshtasticDataModelV 46.xcdatamodel + MeshtasticDataModelV 47.xcdatamodel diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 47.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 47.xcdatamodel/contents new file mode 100644 index 00000000..095149bd --- /dev/null +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 47.xcdatamodel/contents @@ -0,0 +1,485 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift new file mode 100644 index 00000000..ad6eb156 --- /dev/null +++ b/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift @@ -0,0 +1,45 @@ +import CoreData +import OSLog +import SwiftUI + +struct IgnoreNodeButton: View { + var bleManager: BLEManager + var context: NSManagedObjectContext + + @ObservedObject + var node: NodeInfoEntity + + var body: some View { + Button { + guard let connectedNodeNum = bleManager.connectedPeripheral?.num else { return } + let success = if node.ignored { + bleManager.removeIgnoredNode( + node: node, + connectedNodeNum: Int64(connectedNodeNum) + ) + } else { + bleManager.setIgnoredNode( + node: node, + connectedNodeNum: Int64(connectedNodeNum) + ) + } + if success { + node.ignored = !node.ignored + do { + try context.save() + } catch { + context.rollback() + Logger.data.error("Save Ignored Node Error") + } + Logger.data.debug("Ignored a node") + } + } label: { + Label { + Text(node.favorite ? "Remove from ignored" : "Ignore Node") + } icon: { + Image(systemName: node.favorite ? "minus.circle.fill" : "minus.circle") + .symbolRenderingMode(.multicolor) + } + } + } +} diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 756f1179..7af36d4b 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -132,6 +132,11 @@ struct NodeList: View { } label: { Label("Exchange Positions", systemImage: "arrow.triangle.2.circlepath") } + IgnoreNodeButton( + bleManager: bleManager, + context: context, + node: node + ) Button(role: .destructive) { deleteNodeId = node.num isPresentingDeleteNodeAlert = true From 49c7bd7bef3e219336bc19594f6f6037cfe900bc Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 16 Dec 2024 14:43:59 -0800 Subject: [PATCH 3/3] Add ignore node functionality to the node and user list --- Localizable.xcstrings | 3 +++ .../Extensions/CoreData/UserEntityExtension.swift | 8 ++++---- Meshtastic/Views/Messages/UserList.swift | 5 +++-- .../Nodes/Helpers/Actions/IgnoreNodeButton.swift | 4 ++-- Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift | 13 +++++++++++++ Meshtastic/Views/Nodes/MeshMap.swift | 2 ++ Meshtastic/Views/Nodes/NodeList.swift | 12 ++++++++++++ 7 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index caa1ef6e..6a2bfdca 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -8957,6 +8957,9 @@ }, "Ignore Node" : { + }, + "Ignored" : { + }, "Import Route" : { diff --git a/Meshtastic/Extensions/CoreData/UserEntityExtension.swift b/Meshtastic/Extensions/CoreData/UserEntityExtension.swift index b0700423..52399f38 100644 --- a/Meshtastic/Extensions/CoreData/UserEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/UserEntityExtension.swift @@ -77,13 +77,13 @@ extension UserEntity { return "TLORAV2118" /// Seeed Studio case "SENSECAPINDICATOR": - return "SENSECAPINDICATOR" + return "UNSET" case "TRACKERT1000E": - return "TRACKERT1000E" + return "UNSET" case "SEEEDXIAOS3": - return "SEEEDXIAOS3" + return "UNSET" case "WIOWM1110": - return "WIOWM1110" + return "UNSET" /// RAK Wireless case "RAK4631": return "UNSET" diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index 14c826ed..0496a51e 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -20,6 +20,7 @@ struct UserList: View { @State private var isOnline = false @State private var isPkiEncrypted = false @State private var isFavorite = false + @State private var isIgnored = false @State private var isEnvironment = false @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @@ -44,7 +45,7 @@ struct UserList: View { NSSortDescriptor(key: "pkiEncrypted", ascending: false), NSSortDescriptor(key: "userNode.lastHeard", ascending: false), NSSortDescriptor(key: "longName", ascending: true)], - predicate: NSPredicate(format: "longName != ''"), + predicate: NSPredicate(format: "userNode.ignored == false && longName != ''"), animation: .default ) var users: FetchedResults @@ -194,7 +195,7 @@ struct UserList: View { .listStyle(.plain) .navigationTitle(String.localizedStringWithFormat("contacts %@".localized, String(users.count == 0 ? 0 : users.count))) .sheet(isPresented: $editingFilters) { - NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles) + NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, isIgnored: $isIgnored, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles) } .sheet(isPresented: $showingHelp) { DirectMessagesHelp() diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift index ad6eb156..0ec05164 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/IgnoreNodeButton.swift @@ -35,9 +35,9 @@ struct IgnoreNodeButton: View { } } label: { Label { - Text(node.favorite ? "Remove from ignored" : "Ignore Node") + Text(node.ignored ? "Remove from ignored" : "Ignore Node") } icon: { - Image(systemName: node.favorite ? "minus.circle.fill" : "minus.circle") + Image(systemName: node.ignored ? "minus.circle.fill" : "minus.circle") .symbolRenderingMode(.multicolor) } } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index 210e58d1..454b3607 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -17,6 +17,7 @@ struct NodeListFilter: View { @Binding var isOnline: Bool @Binding var isPkiEncrypted: Bool @Binding var isFavorite: Bool + @Binding var isIgnored: Bool @Binding var isEnvironment: Bool @Binding var distanceFilter: Bool @Binding var maximumDistance: Double @@ -90,6 +91,18 @@ struct NodeListFilter: View { } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) + Toggle(isOn: $isIgnored) { + + Label { + Text("Ignored") + } icon: { + + Image(systemName: "minus.circle.fill") + .symbolRenderingMode(.multicolor) + } + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .listRowSeparator(.visible) if filterTitle == "Node Filters" { Toggle(isOn: $isEnvironment) { diff --git a/Meshtastic/Views/Nodes/MeshMap.swift b/Meshtastic/Views/Nodes/MeshMap.swift index 447f6fdd..65928ba3 100644 --- a/Meshtastic/Views/Nodes/MeshMap.swift +++ b/Meshtastic/Views/Nodes/MeshMap.swift @@ -46,6 +46,7 @@ struct MeshMap: View { @State private var isOnline = false @State private var isPkiEncrypted = false @State private var isFavorite = false + @State private var isIgnored = false @State private var isEnvironment = false @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @@ -161,6 +162,7 @@ struct MeshMap: View { isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, + isIgnored: $isIgnored, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 7af36d4b..6f031018 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -26,6 +26,7 @@ struct NodeList: View { @State private var isOnline = false @State private var isPkiEncrypted = false @State private var isFavorite = false + @State private var isIgnored = false @State private var isEnvironment = false @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @@ -40,6 +41,7 @@ struct NodeList: View { var boolFilters: [Bool] {[ isFavorite, + isIgnored, isOnline, isPkiEncrypted, isEnvironment, @@ -53,6 +55,7 @@ struct NodeList: View { @FetchRequest( sortDescriptors: [ + NSSortDescriptor(key: "ignored", ascending: true), NSSortDescriptor(key: "favorite", ascending: false), NSSortDescriptor(key: "lastHeard", ascending: false), NSSortDescriptor(key: "user.longName", ascending: true) @@ -169,6 +172,7 @@ struct NodeList: View { isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, + isIgnored: $isIgnored, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, @@ -397,6 +401,14 @@ struct NodeList: View { let isFavoritePredicate = NSPredicate(format: "favorite == YES") predicates.append(isFavoritePredicate) } + /// Ignored + if isIgnored { + let isIgnoredPredicate = NSPredicate(format: "ignored == YES") + predicates.append(isIgnoredPredicate) + } else if !isIgnored { + let isIgnoredPredicate = NSPredicate(format: "ignored == NO") + predicates.append(isIgnoredPredicate) + } /// Environment if isEnvironment { let environmentPredicate = NSPredicate(format: "SUBQUERY(telemetries, $tel, $tel.metricsType == 1).@count > 0")