Fix incorrect appState.unreadDirectMessages calculations

This commit is contained in:
Mike Robbins 2025-10-13 02:39:03 -04:00
parent f8c1a600a3
commit 431f1d6f03
4 changed files with 19 additions and 6 deletions

View file

@ -33,7 +33,7 @@ extension AccessoryManager {
}
// Set initial unread message badge states
appState.unreadChannelMessages = fetchedNodeInfo[0].myInfo?.unreadMessages ?? 0
appState.unreadDirectMessages = fetchedNodeInfo[0].user?.unreadMessages ?? 0
appState.unreadDirectMessages = fetchedNodeInfo[0].user?.unreadMessages(in: context, skipLastMessageCheck: true) ?? 0 // skipLastMessageCheck=true because we don't update lastMessage on our own connected node
}
if fetchedNodeInfo.count == 1 && fetchedNodeInfo[0].rangeTestConfig?.enabled == true {
wantRangeTestPackets = true

View file

@ -43,17 +43,21 @@ extension UserEntity {
return (try? context.fetch(fetchRequest)) ?? [MessageEntity]()
}
var unreadMessages: Int {
func unreadMessages(in ctx: NSManagedObjectContext?, skipLastMessageCheck: Bool = false) -> Int {
// Most contacts will have no DMs history, so we can return early.
guard self.lastMessage != nil else { return 0; }
// (For our own node, set skipLastMessageCheck=true, because we don't update lastMessage on our own connected node.)
guard self.lastMessage != nil || skipLastMessageCheck else { return 0; }
let context = PersistenceController.shared.container.viewContext
let context = ctx ?? PersistenceController.shared.container.viewContext // default to viewContext
let fetchRequest = MessageEntity.fetchRequest()
// sort is irrelvant.
fetchRequest.predicate = NSPredicate(format: "((toUser == %@) OR (fromUser == %@)) AND toUser != nil AND fromUser != nil AND isEmoji == false AND admin = false AND portNum != 10 AND read == false", self, self)
return (try? context.count(for: fetchRequest)) ?? 0
}
// Backwards-compatible property (uses viewContext)
var unreadMessages: Int { unreadMessages(in: nil) }
/// SVG Images for Vendors who are signed project backers
var hardwareImage: String? {
guard let hwModel else { return nil }

View file

@ -1040,7 +1040,10 @@ func textMessageAppPacket(
if newMessage.fromUser != nil && newMessage.toUser != nil {
// Set Unread Message Indicators
if packet.to == connectedNode {
appState?.unreadDirectMessages = newMessage.toUser?.unreadMessages ?? 0
let unreadCount = newMessage.toUser?.unreadMessages(in: context, skipLastMessageCheck: true) ?? 0 // skipLastMessageCheck=true because we don't update lastMessage on our own connected node
Task { @MainActor in
appState?.unreadDirectMessages = unreadCount
}
}
if !(newMessage.fromUser?.mute ?? false) && newMessage.isEmoji == false {
// Create an iOS Notification for the received DM message

View file

@ -39,7 +39,13 @@ struct UserMessageList: View {
}
try context.save()
Logger.data.info("📖 [App] All unread direct messages marked as read for user \(user.num, privacy: .public).")
appState.unreadDirectMessages = user.unreadMessages
if let connectedPeripheralNum = accessoryManager.activeDeviceNum,
let connectedNode = getNodeInfo(id: connectedPeripheralNum, context: context),
let connectedUser = connectedNode.user {
appState.unreadDirectMessages = connectedUser.unreadMessages(in: context, skipLastMessageCheck: true) // skipLastMessageCheck=true because we don't update lastMessage on our own connected node
}
context.refresh(user, mergeChanges: true)
} catch {
Logger.data.error("Failed to read direct messages: \(error.localizedDescription, privacy: .public)")