From 1fec1ee31543165f211663e52759a5898e8927ea Mon Sep 17 00:00:00 2001 From: jack Date: Sun, 6 Jul 2025 22:30:33 +0200 Subject: [PATCH] Fix read receipts using wrong peer ID - Read receipts were being sent to the current ephemeral peer ID instead of the message's senderPeerID - This caused read receipts to be lost when peer IDs changed between sessions - Now using message.senderPeerID consistently for all read receipt sending - Added detailed logging to track which peer ID receives the read receipt --- bitchat/Services/BluetoothMeshService.swift | 2 + bitchat/ViewModels/ChatViewModel.swift | 55 +++++++++++++-------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/bitchat/Services/BluetoothMeshService.swift b/bitchat/Services/BluetoothMeshService.swift index f3a9615f..5c207163 100644 --- a/bitchat/Services/BluetoothMeshService.swift +++ b/bitchat/Services/BluetoothMeshService.swift @@ -708,6 +708,7 @@ class BluetoothMeshService: NSObject { } func sendReadReceipt(_ receipt: ReadReceipt, to recipientID: String) { + print("[DeliveryTracker] Sending read receipt for message \(receipt.originalMessageID) to \(recipientID)") messageQueue.async { [weak self] in guard let self = self else { return } @@ -737,6 +738,7 @@ class BluetoothMeshService: NSObject { ttl: 3 // Limited TTL for receipts ) + print("[DeliveryTracker] Broadcasting read receipt packet to \(recipientID)") // Send immediately without delay self.broadcastPacket(packet) } diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 95293e56..0f53456a 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -914,13 +914,18 @@ class ChatViewModel: ObservableObject { switch status { case .delivered: // Create and send read receipt - let receipt = ReadReceipt( - originalMessageID: message.id, - readerID: meshService.myPeerID, - readerNickname: nickname - ) - meshService.sendReadReceipt(receipt, to: peerID) - print("[Delivery] Sending read receipt for message \(message.id)") + // Use the senderPeerID from the message to ensure it goes to the right peer + if let messageSenderID = message.senderPeerID { + let receipt = ReadReceipt( + originalMessageID: message.id, + readerID: meshService.myPeerID, + readerNickname: nickname + ) + meshService.sendReadReceipt(receipt, to: messageSenderID) + print("[Delivery] Sending read receipt for message \(message.id) to peer \(messageSenderID)") + } else { + print("[Delivery] Cannot send read receipt for message \(message.id) - no senderPeerID") + } case .read: // Already read, no need to send another receipt print("[Delivery] Message \(message.id) already marked as read") @@ -934,12 +939,17 @@ class ChatViewModel: ObservableObject { // No delivery status - this might be an older message // Send read receipt anyway for backwards compatibility print("[Delivery] Message \(message.id) has no delivery status, sending read receipt anyway") - let receipt = ReadReceipt( - originalMessageID: message.id, - readerID: meshService.myPeerID, - readerNickname: nickname - ) - meshService.sendReadReceipt(receipt, to: peerID) + if let messageSenderID = message.senderPeerID { + let receipt = ReadReceipt( + originalMessageID: message.id, + readerID: meshService.myPeerID, + readerNickname: nickname + ) + meshService.sendReadReceipt(receipt, to: messageSenderID) + print("[Delivery] Sending read receipt for old message \(message.id) to peer \(messageSenderID)") + } else { + print("[Delivery] Cannot send read receipt for old message \(message.id) - no senderPeerID") + } } } } @@ -1816,13 +1826,18 @@ extension ChatViewModel: BitchatDelegate { unreadPrivateMessages.remove(peerID) // Send read receipt immediately since we're viewing the chat - let receipt = ReadReceipt( - originalMessageID: message.id, - readerID: meshService.myPeerID, - readerNickname: nickname - ) - meshService.sendReadReceipt(receipt, to: peerID) - print("[Delivery] Sending immediate read receipt for message \(message.id) from \(message.sender)") + // Use the senderPeerID from the message, not the current peerID + if let messageSenderID = message.senderPeerID { + let receipt = ReadReceipt( + originalMessageID: message.id, + readerID: meshService.myPeerID, + readerNickname: nickname + ) + meshService.sendReadReceipt(receipt, to: messageSenderID) + print("[Delivery] Sending immediate read receipt for message \(message.id) from \(message.sender) to peer \(messageSenderID)") + } else { + print("[Delivery] Cannot send read receipt - message has no senderPeerID") + } } } else if message.sender == nickname { // Our own message that was echoed back - ignore it since we already added it locally