Implement unmessagable

This commit is contained in:
Garth Vander Houwen 2025-05-15 07:44:12 -07:00
parent 3d8f3ad7a6
commit 690b41e0a0
5 changed files with 41 additions and 23 deletions

View file

@ -2136,6 +2136,12 @@
}
}
}
},
"Add Contact" : {
},
"Add Meshtastic Node %@ as a contact" : {
},
"Add to favorites" : {
"localizations" : {
@ -15095,12 +15101,6 @@
}
}
}
},
"Add Contact" : {
},
"Add Meshtastic Node %@ as a contact" : {
},
"Import Route" : {
"localizations" : {
@ -30920,7 +30920,7 @@
}
}
},
"The URL for the node to import" : {
"The URL for the node to add" : {
},
"There has been no response to a request for device metadata over the admin channel for this node." : {

View file

@ -479,7 +479,6 @@
<attribute name="publicKey" optional="YES" attributeType="Binary"/>
<attribute name="role" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="shortName" attributeType="String"/>
<attribute name="unmessagable" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="userId" attributeType="String"/>
<relationship name="receivedMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="toUser" inverseEntity="MessageEntity"/>
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23605" systemVersion="24D81" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23788" systemVersion="24D81" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="AmbientLightingConfigEntity" representedClassName="AmbientLightingConfigEntity" syncable="YES" codeGenerationType="class">
<attribute name="blue" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="current" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
@ -479,6 +479,7 @@
<attribute name="publicKey" optional="YES" attributeType="Binary"/>
<attribute name="role" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="shortName" attributeType="String"/>
<attribute name="unmessagable" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="userId" attributeType="String"/>
<relationship name="receivedMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="toUser" inverseEntity="MessageEntity"/>
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>

View file

@ -183,6 +183,17 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
newUser.role = Int32(newUserMessage.role.rawValue)
newUser.hwModel = String(describing: newUserMessage.hwModel).uppercased()
newUser.hwModelId = Int32(newUserMessage.hwModel.rawValue)
if newUserMessage.hasIsUnmessagable {
newUser.unmessagable = newUserMessage.isUnmessagable
} else {
// For older firmare make Repeater, Router, Router Late, Sensor, Tracker, TAK, and TAK Tracker unmessagable
let roles: [Int32] = [4, 2, 11, 6, 7, 10]
if roles.contains(newUser.role) {
newUser.unmessagable = true
} else {
newUser.unmessagable = false
}
}
if !newUserMessage.publicKey.isEmpty {
newUser.pkiEncrypted = true
newUser.publicKey = newUserMessage.publicKey
@ -279,6 +290,17 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
fetchedNode[0].user!.role = Int32(nodeInfoMessage.user.role.rawValue)
fetchedNode[0].user!.hwModel = String(describing: nodeInfoMessage.user.hwModel).uppercased()
fetchedNode[0].user!.hwModelId = Int32(nodeInfoMessage.user.hwModel.rawValue)
if nodeInfoMessage.user.hasIsUnmessagable {
fetchedNode[0].user!.unmessagable = nodeInfoMessage.user.isUnmessagable
} else {
// For older firmare make Repeater, Router, Router Late, Sensor, Tracker, TAK, and TAK Tracker unmessagable
let roles: [Int32] = [-1, 4, 2, 11, 6, 7, 10]
if roles.contains(fetchedNode[0].user?.role ?? -1) {
fetchedNode[0].user!.unmessagable = true
} else {
fetchedNode[0].user!.unmessagable = false
}
}
if !nodeInfoMessage.user.publicKey.isEmpty {
fetchedNode[0].user!.pkiEncrypted = true
fetchedNode[0].user!.publicKey = nodeInfoMessage.user.publicKey

View file

@ -46,9 +46,8 @@ struct UserList: View {
NSSortDescriptor(key: "userNode.lastHeard", ascending: false),
NSSortDescriptor(key: "longName", ascending: true)],
predicate: NSPredicate(
format: "userNode.ignored == false && longName != '' AND NOT (userNode.viaMqtt == YES AND userNode.hopsAway > 0)"
), animation: .default
)
format: "userNode.ignored == false && longName != '' AND unmessagable == false"
), animation: .default)
var users: FetchedResults<UserEntity>
@Binding var node: NodeInfoEntity?
@ -298,17 +297,19 @@ struct UserList: View {
let textSearchPredicate = NSCompoundPredicate(type: .or, subpredicates: searchPredicates)
/// Create an array of predicates to hold our AND predicates
var predicates: [NSPredicate] = []
let defaultPredicate = NSPredicate(format: "userNode.ignored == NO AND longName != '' AND unmessagable == NO")
predicates.append(defaultPredicate)
/// Mqtt and lora
if !(viaLora && viaMqtt) {
if viaLora {
let loraPredicate = NSPredicate(format: "userNode.viaMqtt == NO")
predicates.append(loraPredicate)
} else {
let mqttPredicate = NSPredicate(format: "userNode.viaMqtt == YES AND userNode.hopsAway == 0")
let mqttPredicate = NSPredicate(format: "userNode.viaMqtt == YES")
predicates.append(mqttPredicate)
}
} else {
let mqttPredicate = NSPredicate(format: "NOT (userNode.viaMqtt == YES AND userNode.hopsAway > 0)")
let mqttPredicate = NSPredicate(format: "NOT (userNode.viaMqtt == YES)")
predicates.append(mqttPredicate)
}
/// Roles
@ -362,16 +363,11 @@ struct UserList: View {
predicates.append(distancePredicate)
}
}
if predicates.count > 0 || !searchText.isEmpty {
if !searchText.isEmpty {
let filterPredicates = NSCompoundPredicate(type: .and, subpredicates: predicates)
users.nsPredicate = NSCompoundPredicate(type: .and, subpredicates: [textSearchPredicate, filterPredicates])
} else {
users.nsPredicate = NSCompoundPredicate(type: .and, subpredicates: predicates)
}
if !searchText.isEmpty {
let filterPredicates = NSCompoundPredicate(type: .and, subpredicates: predicates)
users.nsPredicate = NSCompoundPredicate(type: .and, subpredicates: [textSearchPredicate, filterPredicates])
} else {
users.nsPredicate = nil
users.nsPredicate = NSCompoundPredicate(type: .and, subpredicates: predicates)
}
}
}