mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Hook up favorites, clean up admin dropdown list
This commit is contained in:
parent
170ec3b88b
commit
f38e61b0b2
6 changed files with 102 additions and 29 deletions
|
|
@ -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 = "";
|
||||
|
|
|
|||
|
|
@ -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)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected{
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func removeFavoriteNode(node: NodeInfoEntity, connectedNodeNum: Int64) -> 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)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected{
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func saveLicensedUser(ham: HamParameters, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setHamMode = ham
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<NodeInfoEntity>
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<NodeInfoEntity>
|
||||
@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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue