From fb2f182f7032fb2649dc3b2686a2668831586b0e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 29 Jun 2024 15:36:09 -0700 Subject: [PATCH 1/9] Device roles state --- Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift | 1 + Meshtastic/Views/Nodes/NodeList.swift | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index 2c49a7df..a5917f63 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -20,6 +20,7 @@ struct NodeListFilter: View { @Binding var maximumDistance: Double @Binding var hopsAway: Int @Binding var deviceRole: Int + @Binding var deviceRoles: Set var body: some View { diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index f31755ff..b71d53b1 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -27,6 +27,7 @@ struct NodeList: View { @State private var maxDistance: Double = 800000 @State private var hopsAway: Int = -1 @State private var deviceRole: Int = -1 + @State private var deviceRoles: Set = [] @State var isEditingFilters = false @@ -188,7 +189,7 @@ struct NodeList: View { } } .sheet(isPresented: $isEditingFilters) { - NodeListFilter(viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, deviceRole: $deviceRole) + NodeListFilter(viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, deviceRole: $deviceRole, deviceRoles: $deviceRoles) } .safeAreaInset(edge: .bottom, alignment: .trailing) { HStack { From b19109b7c7f34f995e830ecb7e058e1f6a20716b Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 29 Jun 2024 16:05:54 -0700 Subject: [PATCH 2/9] role filter mockup --- Localizable.xcstrings | 5 +++- Meshtastic/Views/Messages/UserList.swift | 4 ++- .../Views/Nodes/Helpers/NodeListFilter.swift | 27 +++++++++++++++++++ Meshtastic/Views/Nodes/NodeList.swift | 11 ++++---- .../Views/Settings/Logs/AppLogFilter.swift | 2 +- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index aa22cc67..2423c914 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -17386,6 +17386,9 @@ }, "Role: %@" : { + }, + "Roles" : { + }, "Root Topic" : { @@ -22405,4 +22408,4 @@ } }, "version" : "1.0" -} +} \ No newline at end of file diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index a7bab2a2..0f068c29 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -26,6 +26,8 @@ struct UserList: View { @State private var maxDistance: Double = 800000 @State private var hopsAway: Int = -1 @State private var deviceRole: Int = -1 + @State private var roleFilter = false + @State private var deviceRoles: Set = [] @State var isEditingFilters = false @FetchRequest( @@ -170,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, deviceRole: $deviceRole) + NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, deviceRole: $deviceRole, roleFilter: $roleFilter, deviceRoles: $deviceRoles) } .onChange(of: searchText) { _ in searchUserList() diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index a5917f63..ba4b64e7 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -10,6 +10,7 @@ import SwiftUI struct NodeListFilter: View { @Environment(\.dismiss) private var dismiss + @State var editMode = EditMode.active /// Filters var filterTitle = "Node Filters" @Binding var viaLora: Bool @@ -20,6 +21,7 @@ struct NodeListFilter: View { @Binding var maximumDistance: Double @Binding var hopsAway: Int @Binding var deviceRole: Int + @Binding var roleFilter: Bool @Binding var deviceRoles: Set var body: some View { @@ -127,6 +129,31 @@ struct NodeListFilter: View { } .pickerStyle(DefaultPickerStyle()) } + Toggle(isOn: $roleFilter) { + + Label { + Text("Roles") + } icon: { + Image(systemName: "apps.iphone") + } + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + + .listRowSeparator(roleFilter ? .hidden : .visible) + if roleFilter { + VStack { + List(DeviceRoles.allCases, selection: $deviceRoles) { dr in + Label { + Text(" \(dr.name)") + } icon: { + Image(systemName: dr.systemName) + } + } + .listStyle(.plain) + .environment(\.editMode, $editMode) /// bind it here! + .frame(minHeight: 210, maxHeight: .infinity) + } + } } } #if targetEnvironment(macCatalyst) diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index b71d53b1..18ac320a 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -26,7 +26,8 @@ struct NodeList: View { @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @State private var hopsAway: Int = -1 - @State private var deviceRole: Int = -1 + @State private var nodeRole: Int = -1 + @State private var roleFilter = false @State private var deviceRoles: Set = [] @State var isEditingFilters = false @@ -189,7 +190,7 @@ struct NodeList: View { } } .sheet(isPresented: $isEditingFilters) { - NodeListFilter(viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, deviceRole: $deviceRole, deviceRoles: $deviceRoles) + NodeListFilter(viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, deviceRole: $nodeRole, roleFilter: $roleFilter, deviceRoles: $deviceRoles) } .safeAreaInset(edge: .bottom, alignment: .trailing) { HStack { @@ -298,7 +299,7 @@ struct NodeList: View { } searchNodeList() } - .onChange(of: deviceRole) { _ in + .onChange(of: nodeRole) { _ in searchNodeList() } .onChange(of: hopsAway) { _ in @@ -363,8 +364,8 @@ struct NodeList: View { } } /// Role - if deviceRole > -1 { - let rolePredicate = NSPredicate(format: "user.role == %i", Int32(deviceRole)) + if nodeRole > -1 { + let rolePredicate = NSPredicate(format: "user.role == %i", Int32(nodeRole)) predicates.append(rolePredicate) } /// Hops Away diff --git a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift index 46d6f838..9943c2de 100644 --- a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift +++ b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift @@ -101,7 +101,7 @@ struct AppLogFilter: View { var filterTitle = "App Log Filters" @Binding var categories: Set @Binding var levels: Set - @State var editMode = EditMode.active /// the edit mode + @State var editMode = EditMode.active var body: some View { From 236955900ea0982ec7e264f288d3ec95ec5f4c46 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 29 Jun 2024 16:19:56 -0700 Subject: [PATCH 3/9] Role filters --- Localizable.xcstrings | 3 --- Meshtastic/Views/Messages/UserList.swift | 18 ++++++++++------- .../Views/Nodes/Helpers/NodeListFilter.swift | 20 ++----------------- Meshtastic/Views/Nodes/NodeList.swift | 16 +++++++++------ 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 2423c914..d382e186 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -668,9 +668,6 @@ }, "All device and app data will be deleted. You will also need to forget your devices under Settings > Bluetooth." : { - }, - "All Roles" : { - }, "Allow Position Requests" : { diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index 0f068c29..393458df 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -25,7 +25,6 @@ struct UserList: View { @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @State private var hopsAway: Int = -1 - @State private var deviceRole: Int = -1 @State private var roleFilter = false @State private var deviceRoles: Set = [] @State var isEditingFilters = false @@ -172,7 +171,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, deviceRole: $deviceRole, roleFilter: $roleFilter, deviceRoles: $deviceRoles) + NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles) } .onChange(of: searchText) { _ in searchUserList() @@ -189,7 +188,7 @@ struct UserList: View { } searchUserList() } - .onChange(of: deviceRole) { _ in + .onChange(of: [deviceRoles]) { _ in searchUserList() } .onChange(of: hopsAway) { _ in @@ -261,10 +260,15 @@ struct UserList: View { predicates.append(mqttPredicate) } } - /// Role - if deviceRole > -1 { - let rolePredicate = NSPredicate(format: "role == %i", Int32(deviceRole)) - predicates.append(rolePredicate) + /// Roles + if roleFilter && deviceRoles.count > 0 { + var rolesArray: [NSPredicate] = [] + for dr in deviceRoles { + let deviceRolePredicate = NSPredicate(format: "user.role == %i", Int32(dr)) + rolesArray.append(deviceRolePredicate) + } + let compoundPredicate = NSCompoundPredicate(type: .or, subpredicates: rolesArray) + predicates.append(compoundPredicate) } /// Hops Away if hopsAway > 0 { diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index ba4b64e7..eb126638 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -20,7 +20,6 @@ struct NodeListFilter: View { @Binding var distanceFilter: Bool @Binding var maximumDistance: Double @Binding var hopsAway: Int - @Binding var deviceRole: Int @Binding var roleFilter: Bool @Binding var deviceRoles: Set @@ -114,21 +113,6 @@ struct NodeListFilter: View { } .pickerStyle(DefaultPickerStyle()) } - HStack { - Label("Device Role", systemImage: "apps.iphone") - Picker("", selection: $deviceRole) { - Text("All Roles") - .tag(-1) - ForEach(DeviceRoles.allCases) { dr in - Label { - Text(" \(dr.name)") - } icon: { - Image(systemName: dr.systemName) - } - } - } - .pickerStyle(DefaultPickerStyle()) - } Toggle(isOn: $roleFilter) { Label { @@ -151,7 +135,7 @@ struct NodeListFilter: View { } .listStyle(.plain) .environment(\.editMode, $editMode) /// bind it here! - .frame(minHeight: 210, maxHeight: .infinity) + .frame(minHeight: 490, maxHeight: .infinity) } } } @@ -169,7 +153,7 @@ struct NodeListFilter: View { .padding(.bottom) #endif } - .presentationDetents([.fraction(0.6), .fraction(0.75)]) + .presentationDetents([.fraction(1.0)]) .presentationDragIndicator(.visible) } } diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 18ac320a..0f8c8683 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -26,7 +26,6 @@ struct NodeList: View { @State private var distanceFilter = false @State private var maxDistance: Double = 800000 @State private var hopsAway: Int = -1 - @State private var nodeRole: Int = -1 @State private var roleFilter = false @State private var deviceRoles: Set = [] @@ -190,7 +189,7 @@ struct NodeList: View { } } .sheet(isPresented: $isEditingFilters) { - NodeListFilter(viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, deviceRole: $nodeRole, roleFilter: $roleFilter, deviceRoles: $deviceRoles) + NodeListFilter(viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isFavorite: $isFavorite, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles) } .safeAreaInset(edge: .bottom, alignment: .trailing) { HStack { @@ -299,7 +298,7 @@ struct NodeList: View { } searchNodeList() } - .onChange(of: nodeRole) { _ in + .onChange(of: [deviceRoles]) { _ in searchNodeList() } .onChange(of: hopsAway) { _ in @@ -364,9 +363,14 @@ struct NodeList: View { } } /// Role - if nodeRole > -1 { - let rolePredicate = NSPredicate(format: "user.role == %i", Int32(nodeRole)) - predicates.append(rolePredicate) + if roleFilter && deviceRoles.count > 0 { + var rolesArray: [NSPredicate] = [] + for dr in deviceRoles { + let deviceRolePredicate = NSPredicate(format: "user.role == %i", Int32(dr)) + rolesArray.append(deviceRolePredicate) + } + let compoundPredicate = NSCompoundPredicate(type: .or, subpredicates: rolesArray) + predicates.append(compoundPredicate) } /// Hops Away if hopsAway > 0 { From 457c87c128fdb2634b1ae0a08f17a4d112ad7c04 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 29 Jun 2024 16:31:30 -0700 Subject: [PATCH 4/9] size the node filter --- Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index eb126638..5559037b 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -153,7 +153,7 @@ struct NodeListFilter: View { .padding(.bottom) #endif } - .presentationDetents([.fraction(1.0)]) + .presentationDetents([.fraction(roleFilter ? 1.0 : 0.55)]) .presentationDragIndicator(.visible) } } From 8059f4332a239205484c4ce03226572c669e49c1 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 29 Jun 2024 19:13:48 -0700 Subject: [PATCH 5/9] Role Silders for user and node list filters --- Localizable.xcstrings | 21 ++++++++++-- Meshtastic/Views/Messages/UserList.swift | 14 +++++--- .../Views/Nodes/Helpers/NodeListFilter.swift | 34 ++++++++++++------- Meshtastic/Views/Nodes/NodeList.swift | 13 ++++--- 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index d382e186..2fd86fed 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -139,9 +139,15 @@ }, "%d%%" : { + }, + "%lf" : { + }, "%lld" : { + }, + "%lld or less hops away" : { + }, "%lld Readings Total" : { @@ -166,6 +172,15 @@ }, "1 byte" : { + }, + "1 hop away" : { + + }, + "7" : { + + }, + "8" : { + }, "25" : { @@ -665,6 +680,9 @@ }, "Alert when receiving a message" : { + }, + "All" : { + }, "All device and app data will be deleted. You will also need to forget your devices under Settings > Bluetooth." : { @@ -870,9 +888,6 @@ }, "An open source, off-grid, decentralized, mesh network that runs on affordable, low-power radios." : { - }, - "Any" : { - }, "Any missed messages will be delivered again." : { diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index 393458df..21be016a 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -24,7 +24,7 @@ struct UserList: View { @State private var isFavorite = false @State private var distanceFilter = false @State private var maxDistance: Double = 800000 - @State private var hopsAway: Int = -1 + @State private var hopsAway: Double = -1.0 @State private var roleFilter = false @State private var deviceRoles: Set = [] @State var isEditingFilters = false @@ -271,11 +271,15 @@ struct UserList: View { predicates.append(compoundPredicate) } /// Hops Away - if hopsAway > 0 { - let hopsAwayPredicate = NSPredicate(format: "userNode.hopsAway == %i", Int32(hopsAway)) - predicates.append(hopsAwayPredicate) + if hopsAway > -1.0 { + if hopsAway == 0.0 { + let hopsAwayPredicate = NSPredicate(format: "userNode.hopsAway == %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } else { + let hopsAwayPredicate = NSPredicate(format: "userNode.hopsAway > 0 AND userNode.hopsAway <= %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } } - /// Online if isOnline { let isOnlinePredicate = NSPredicate(format: "userNode.lastHeard >= %@", Calendar.current.date(byAdding: .minute, value: -15, to: Date())! as NSDate) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index 5559037b..15f8f712 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -19,7 +19,7 @@ struct NodeListFilter: View { @Binding var isFavorite: Bool @Binding var distanceFilter: Bool @Binding var maximumDistance: Double - @Binding var hopsAway: Int + @Binding var hopsAway: Double @Binding var roleFilter: Bool @Binding var deviceRoles: Set @@ -99,19 +99,27 @@ struct NodeListFilter: View { .pickerStyle(DefaultPickerStyle()) } } - HStack { + VStack(alignment: .leading) { Label("Hops Away", systemImage: "hare") - Picker("", selection: $hopsAway) { - Text("Any") - .tag(-1) - Text("Direct") - .tag(0) - ForEach(1..<8) { - Text("\($0)") - .tag($0) - } + Slider( + value: $hopsAway, + in: -1...7, + step: 1 + ) { + Text("Speed") + } minimumValueLabel: { + Text("All") + } maximumValueLabel: { + Text("7") + } + if hopsAway >= 0 { + if hopsAway == 0 { + Text("Direct") + } else if hopsAway == 1 { + Text("1 hop away") + } else { + Text("\(Int(hopsAway)) or less hops away") } } - .pickerStyle(DefaultPickerStyle()) } Toggle(isOn: $roleFilter) { @@ -153,7 +161,7 @@ struct NodeListFilter: View { .padding(.bottom) #endif } - .presentationDetents([.fraction(roleFilter ? 1.0 : 0.55)]) + .presentationDetents([.fraction(roleFilter ? 1.0 : 0.65)]) .presentationDragIndicator(.visible) } } diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 0f8c8683..81c034cc 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -25,7 +25,7 @@ struct NodeList: View { @State private var isFavorite = false @State private var distanceFilter = false @State private var maxDistance: Double = 800000 - @State private var hopsAway: Int = -1 + @State private var hopsAway: Double = -1.0 @State private var roleFilter = false @State private var deviceRoles: Set = [] @@ -373,9 +373,14 @@ struct NodeList: View { predicates.append(compoundPredicate) } /// Hops Away - if hopsAway > 0 { - let hopsAwayPredicate = NSPredicate(format: "hopsAway == %i", Int32(hopsAway)) - predicates.append(hopsAwayPredicate) + if hopsAway > -1.0 { + if hopsAway == 0.0 { + let hopsAwayPredicate = NSPredicate(format: "hopsAway == %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } else { + let hopsAwayPredicate = NSPredicate(format: "hopsAway > 0 AND hopsAway <= %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } } /// Online From 33d1c6bbac2b4263d5944b66fae5575aa77f2117 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 29 Jun 2024 19:25:14 -0700 Subject: [PATCH 6/9] Fix role query on user list --- Meshtastic/Views/Messages/UserList.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index 21be016a..19d3dc11 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -264,7 +264,7 @@ struct UserList: View { if roleFilter && deviceRoles.count > 0 { var rolesArray: [NSPredicate] = [] for dr in deviceRoles { - let deviceRolePredicate = NSPredicate(format: "user.role == %i", Int32(dr)) + let deviceRolePredicate = NSPredicate(format: "role == %i", Int32(dr)) rolesArray.append(deviceRolePredicate) } let compoundPredicate = NSCompoundPredicate(type: .or, subpredicates: rolesArray) From 0ffd3a06d024bd9467b916c41f8adb5522dc8894 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 29 Jun 2024 20:21:53 -0700 Subject: [PATCH 7/9] Start to make the node list search async --- Meshtastic/Helpers/BLEManager.swift | 1 + .../Views/Nodes/Helpers/NodeListFilter.swift | 3 -- Meshtastic/Views/Nodes/NodeList.swift | 42 ++++++++++++++----- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 8fddb80a..f3718afc 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -645,6 +645,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate do { disconnectPeripheral(reconnect: false) try container.restorePersistentStore(from: databasePath) + context?.refreshAllObjects() let request = MyInfoEntity.fetchRequest() try context?.fetch(request) UserDefaults.preferredPeripheralNum = Int(myInfo?.myNodeNum ?? 0) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index 15f8f712..247cb954 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -11,7 +11,6 @@ import SwiftUI struct NodeListFilter: View { @Environment(\.dismiss) private var dismiss @State var editMode = EditMode.active - /// Filters var filterTitle = "Node Filters" @Binding var viaLora: Bool @Binding var viaMqtt: Bool @@ -130,8 +129,6 @@ struct NodeListFilter: View { } } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) - - .listRowSeparator(roleFilter ? .hidden : .visible) if roleFilter { VStack { List(DeviceRoles.allCases, selection: $deviceRoles) { dr in diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 81c034cc..d9574f43 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -284,37 +284,55 @@ struct NodeList: View { } .navigationSplitViewStyle(.balanced) .onChange(of: searchText) { _ in - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: viaLora) { _ in if !viaLora && !viaMqtt { viaMqtt = true } - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: viaMqtt) { _ in if !viaLora && !viaMqtt { viaLora = true } - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: [deviceRoles]) { _ in - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: hopsAway) { _ in - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: isOnline) { _ in - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: isFavorite) { _ in - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: maxDistance) { _ in - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: distanceFilter) { _ in - searchNodeList() + Task { + await searchNodeList() + } } .onChange(of: (appState.navigationPath)) { newPath in @@ -339,11 +357,13 @@ struct NodeList: View { if self.bleManager.context == nil { self.bleManager.context = context } - searchNodeList() + Task { + await searchNodeList() + } } } - private func searchNodeList() { + private func searchNodeList() async -> Void { /// Case Insensitive Search Text Predicates let searchPredicates = ["user.userId", "user.numString", "user.hwModel", "user.longName", "user.shortName"].map { property in return NSPredicate(format: "%K CONTAINS[c] %@", property, searchText) From 54af67284b0690506ebc8654afb88b409cd0caa0 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 2 Jul 2024 08:01:13 -0700 Subject: [PATCH 8/9] Update Meshtastic/Views/Messages/UserList.swift Co-authored-by: Blake McAnally --- Meshtastic/Views/Messages/UserList.swift | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index 19d3dc11..f6e30e81 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -271,14 +271,13 @@ struct UserList: View { predicates.append(compoundPredicate) } /// Hops Away - if hopsAway > -1.0 { - if hopsAway == 0.0 { - let hopsAwayPredicate = NSPredicate(format: "userNode.hopsAway == %i", Int32(hopsAway)) - predicates.append(hopsAwayPredicate) - } else { - let hopsAwayPredicate = NSPredicate(format: "userNode.hopsAway > 0 AND userNode.hopsAway <= %i", Int32(hopsAway)) - predicates.append(hopsAwayPredicate) - } + if hopsAway == 0.0 { + let hopsAwayPredicate = NSPredicate(format: "userNode.hopsAway == %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } else if hopsAway > -1.0 { + let hopsAwayPredicate = NSPredicate(format: "userNode.hopsAway > 0 AND userNode.hopsAway <= %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } } /// Online if isOnline { From 251456f52a7a7fd0431b77e1268e24f6e99b9ad9 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 2 Jul 2024 08:01:28 -0700 Subject: [PATCH 9/9] Update Meshtastic/Views/Nodes/NodeList.swift Co-authored-by: Blake McAnally --- Meshtastic/Views/Nodes/NodeList.swift | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index d9574f43..9b69af2a 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -393,14 +393,13 @@ struct NodeList: View { predicates.append(compoundPredicate) } /// Hops Away - if hopsAway > -1.0 { - if hopsAway == 0.0 { - let hopsAwayPredicate = NSPredicate(format: "hopsAway == %i", Int32(hopsAway)) - predicates.append(hopsAwayPredicate) - } else { - let hopsAwayPredicate = NSPredicate(format: "hopsAway > 0 AND hopsAway <= %i", Int32(hopsAway)) - predicates.append(hopsAwayPredicate) - } + if hopsAway == 0.0 { + let hopsAwayPredicate = NSPredicate(format: "hopsAway == %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } else if hopsAway > -1.0 { + let hopsAwayPredicate = NSPredicate(format: "hopsAway > 0 AND hopsAway <= %i", Int32(hopsAway)) + predicates.append(hopsAwayPredicate) + } } /// Online