Fix: use persisted read receipts during consolidation

Pass the UserDefaults-backed sentReadReceipts from ChatViewModel to
consolidateMessages() to correctly identify already-read messages
after app restart. This prevents duplicate read receipts and incorrect
unread badges when reopening a chat shortly after reading it.

Addresses PR review feedback.
This commit is contained in:
jack
2025-11-25 10:24:24 -10:00
parent 9d8754099d
commit 6eef030386
2 changed files with 6 additions and 3 deletions
+4 -2
View File
@@ -39,9 +39,10 @@ final class PrivateChatManager: ObservableObject {
/// - Parameters:
/// - peerID: The target peer ID to consolidate messages into
/// - peerNickname: The peer's display name (lowercased for matching)
/// - persistedReadReceipts: The persisted read receipts set from ChatViewModel (UserDefaults-backed)
/// - Returns: True if any unread messages were found during consolidation
@MainActor
func consolidateMessages(for peerID: PeerID, peerNickname: String) -> Bool {
func consolidateMessages(for peerID: PeerID, peerNickname: String, persistedReadReceipts: Set<String>) -> Bool {
guard let meshService = meshService else { return false }
var hasUnreadMessages = false
@@ -74,9 +75,10 @@ final class PrivateChatManager: ObservableObject {
privateChats[peerID]?.append(updatedMessage)
// Check for recent unread messages (< 60s, not sent by us, not already read)
// Use persistedReadReceipts to correctly identify already-read messages after app restart
if message.senderPeerID != meshService.myPeerID {
let messageAge = Date().timeIntervalSince(message.timestamp)
if messageAge < 60 && !sentReadReceipts.contains(message.id) {
if messageAge < 60 && !persistedReadReceipts.contains(message.id) {
hasUnreadMessages = true
}
}
+2 -1
View File
@@ -2560,7 +2560,8 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, CommandContextProv
}
// Consolidate messages from different peer ID representations (stable Noise key, temp Nostr IDs)
_ = privateChatManager.consolidateMessages(for: peerID, peerNickname: peerNickname)
// Pass persisted sentReadReceipts to correctly identify already-read messages after app restart
_ = privateChatManager.consolidateMessages(for: peerID, peerNickname: peerNickname, persistedReadReceipts: sentReadReceipts)
// Trigger handshake if needed (mesh peers only). Skip for Nostr geohash conv keys.
if !peerID.isGeoDM && !peerID.isGeoChat {