From f38e61b0b2393aafcfd963a1f68b7b430fbe957c Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 29 Mar 2024 14:37:09 -0700 Subject: [PATCH] Hook up favorites, clean up admin dropdown list --- Meshtastic.xcodeproj/project.pbxproj | 8 +-- Meshtastic/Helpers/BLEManager.swift | 49 +++++++++++++++++++ .../Map/MapContent/MeshMapContent.swift | 4 +- .../Views/Nodes/Helpers/NodeListItem.swift | 2 +- Meshtastic/Views/Nodes/NodeList.swift | 44 ++++++++++++----- Meshtastic/Views/Settings/Settings.swift | 24 +++++---- 6 files changed, 102 insertions(+), 29 deletions(-) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 9339e55d..094f1625 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1610,7 +1610,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.3.2; + MARKETING_VERSION = 2.3.3; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1644,7 +1644,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.3.2; + MARKETING_VERSION = 2.3.3; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1766,7 +1766,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.2; + MARKETING_VERSION = 2.3.3; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1799,7 +1799,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.2; + MARKETING_VERSION = 2.3.3; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 9327ebc8..abf65753 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -761,6 +761,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } if fetchedNodeInfo.count == 1 { if !(fetchedNodeInfo[0].user?.vip ?? false) { + fetchedNodeInfo[0].favorite = true fetchedNodeInfo[0].user?.vip = true do { try context!.save() @@ -1448,6 +1449,54 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return false } + public func setFavoriteNode(node: NodeInfoEntity, connectedNodeNum: Int64) -> Bool { + var adminPacket = AdminMessage() + adminPacket.setFavoriteNode = UInt32(node.num) + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedNodeNum) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Bool { + var adminPacket = AdminMessage() + adminPacket.removeFavoriteNode = 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/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift index 2655fbd4..6a03aba8 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift @@ -93,7 +93,7 @@ struct MeshMapContent: MapContent { } /// Node History and Route Lines for favorites - if position.nodePosition?.user?.vip ?? false { + if position.nodePosition?.favorite ?? false { if showRouteLines { let nodePositions = Array(position.nodePosition!.positions!) as! [PositionEntity] let routeCoords = nodePositions.compactMap({(pos) -> CLLocationCoordinate2D in @@ -112,7 +112,7 @@ struct MeshMapContent: MapContent { } if showNodeHistory { ForEach(Array(position.nodePosition!.positions!) as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in - if mappin.latest == false && mappin.nodePosition?.user?.vip ?? false { + if mappin.latest == false && mappin.nodePosition?.favorite ?? false { let pf = PositionFlags(rawValue: Int(mappin.nodePosition?.metadata?.positionFlags ?? 771)) let headingDegrees = Angle.degrees(Double(mappin.heading)) Annotation("", coordinate: mappin.coordinate) { diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift index f7ea4ffc..21bf839d 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift @@ -31,7 +31,7 @@ struct NodeListItem: View { Text(node.user?.longName ?? "unknown".localized) .fontWeight(.medium) .font(.headline) - if node.user?.vip ?? false { + if node.favorite { Spacer() Image(systemName: "star.fill") .foregroundColor(.yellow) diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 8a63d2a9..1cb3508e 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -33,7 +33,7 @@ struct NodeList: View { @EnvironmentObject var bleManager: BLEManager @FetchRequest( - sortDescriptors: [NSSortDescriptor(key: "user.vip", ascending: false), NSSortDescriptor(key: "lastHeard", ascending: false)], + sortDescriptors: [NSSortDescriptor(key: "favorite", ascending: false), NSSortDescriptor(key: "lastHeard", ascending: false)], animation: .default) var nodes: FetchedResults @@ -49,19 +49,39 @@ struct NodeList: View { connected: bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral?.num ?? -1 == node.num, connectedNode: (bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral?.num ?? -1 : -1)) .contextMenu { - if node.user != nil { - Button { - node.user!.vip = !node.user!.vip - context.refresh(node, mergeChanges: true) - do { - try context.save() - } catch { - context.rollback() - print("💥 Save User VIP Error") + + Button { + node.user!.vip = !node.user!.vip + if !node.favorite { + let success = bleManager.setFavoriteNode(node: node, connectedNodeNum: Int64(connectedNodeNum)) + if success { + node.favorite = !node.favorite + do { + try context.save() + } catch { + context.rollback() + print("💥 Save Node Favorite Error") + } + print("Favorited a node") + } + } else { + let success = bleManager.removeFavoriteNode(node: node, connectedNodeNum: Int64(connectedNodeNum)) + if success { + node.favorite = !node.favorite + do { + try context.save() + } catch { + context.rollback() + print("💥 Save Node Favorite Error") + } + print("Favorited a node") } - } label: { - Label(node.user?.vip ?? false ? "Un-Favorite" : "Favorite", systemImage: node.user?.vip ?? false ? "star.slash.fill" : "star.fill") } + + } label: { + Label(node.favorite ? "Un-Favorite" : "Favorite", systemImage: node.favorite ? "star.slash.fill" : "star.fill") + } + if node.user != nil { Button { node.user!.mute = !node.user!.mute context.refresh(node, mergeChanges: true) diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index b990b0f4..3db5cb86 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -13,7 +13,8 @@ import TipKit struct Settings: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager - @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "user.longName", ascending: true)], animation: .default) + @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "favorite", ascending: false), + NSSortDescriptor(key: "user.longName", ascending: true)], animation: .default) private var nodes: FetchedResults @State private var selectedNode: Int = 0 @State private var preferredNodeNum: Int = 0 @@ -106,16 +107,19 @@ struct Settings: View { if selectedNode == 0 { Text("Connect to a Node").tag(0) } + ForEach(nodes) { node in - if node.num == bleManager.connectedPeripheral?.num ?? 0 { - Text("BLE Config: \(node.user?.longName ?? "unknown".localized)") - .tag(Int(node.num)) - } else if node.metadata != nil { - Text("Remote Config: \(node.user?.longName ?? "unknown".localized)") - .tag(Int(node.num)) - } else if hasAdmin { - Text("Request Admin: \(node.user?.longName ?? "unknown".localized)") - .tag(Int(node.num)) + if !node.viaMqtt { + if node.num == bleManager.connectedPeripheral?.num ?? 0 { + Text("BLE Config: \(node.user?.longName ?? "unknown".localized)") + .tag(Int(node.num)) + } else if node.metadata != nil { + Text("Remote Config: \(node.user?.longName ?? "unknown".localized)") + .tag(Int(node.num)) + } else if hasAdmin { + Text("Request Admin: \(node.user?.longName ?? "unknown".localized)") + .tag(Int(node.num)) + } } } }