mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-10-25 07:41:41 +00:00
Merge 6167c9f6eabedf15a39302345935348ef7d1045a into 9b84b361225facd8e623f25d76f889d3dc54a879
This commit is contained in:
commit
cace62cb94
@ -87,7 +87,7 @@ final class PrivateChatManager: ObservableObject {
|
||||
/// This ensures messages from stable Noise keys and temporary Nostr peer IDs are merged.
|
||||
/// - Parameters:
|
||||
/// - peerID: The target peer ID to consolidate messages into
|
||||
/// - peerNickname: The peer's display name (lowercased for matching)
|
||||
/// - peerNickname: The peer's display name (NFC + lowercased for matching)
|
||||
/// - persistedReadReceipts: The persisted read receipts set from ChatViewModel (UserDefaults-backed)
|
||||
/// - Returns: True if any unread messages were found during consolidation
|
||||
@MainActor
|
||||
@ -140,13 +140,17 @@ final class PrivateChatManager: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Consolidate from temporary Nostr peer IDs (nostr_* prefixed)
|
||||
let normalizedNickname = peerNickname.lowercased()
|
||||
// 2. Consolidate from temporary Nostr peer IDs (nostr_* prefixed).
|
||||
// Match on NFC so a wire sender typed with combining accents still
|
||||
// merges into the stored peer nickname (precomposed after #1502).
|
||||
let normalizedNickname = peerNickname.normalizedNickname.lowercased()
|
||||
var tempPeerIDsToConsolidate: [PeerID] = []
|
||||
|
||||
for (storedPeerID, messages) in privateChats {
|
||||
if storedPeerID.isGeoDM && storedPeerID != peerID {
|
||||
let nicknamesMatch = messages.allSatisfy { $0.sender.lowercased() == normalizedNickname }
|
||||
let nicknamesMatch = messages.allSatisfy {
|
||||
$0.sender.normalizedNickname.lowercased() == normalizedNickname
|
||||
}
|
||||
if nicknamesMatch && !messages.isEmpty {
|
||||
tempPeerIDsToConsolidate.append(storedPeerID)
|
||||
}
|
||||
|
||||
@ -258,6 +258,44 @@ struct PrivateChatManagerTests {
|
||||
#expect(!manager.unreadMessages.contains(tempPeerID))
|
||||
}
|
||||
|
||||
@Test @MainActor
|
||||
func consolidateMessages_movesTemporaryGeoDMHistoryByCanonicalNickname() async {
|
||||
// Wire sender can arrive NFD while the peer nickname is stored NFC
|
||||
// (#1502). Consolidation must still merge the temp geo DM thread.
|
||||
let transport = MockTransport()
|
||||
let (manager, store) = Self.makeManager(transport: transport)
|
||||
let peerID = PeerID(str: "0011223344556677")
|
||||
let tempPeerID = PeerID(nostr_: "0000000000000000000000000000000000000000000000000000000000000042")
|
||||
let decomposed = "cafe\u{0301}"
|
||||
let precomposed = "caf\u{00E9}"
|
||||
|
||||
store.append(
|
||||
BitchatMessage(
|
||||
id: "geo-nfc-msg",
|
||||
sender: decomposed,
|
||||
content: "Geo hello",
|
||||
timestamp: Date(),
|
||||
isRelay: false,
|
||||
isPrivate: true,
|
||||
recipientNickname: "Me",
|
||||
senderPeerID: tempPeerID
|
||||
),
|
||||
to: .directPeer(tempPeerID)
|
||||
)
|
||||
store.markUnread(.directPeer(tempPeerID))
|
||||
|
||||
let hadUnread = manager.consolidateMessages(
|
||||
for: peerID,
|
||||
peerNickname: precomposed,
|
||||
persistedReadReceipts: []
|
||||
)
|
||||
|
||||
#expect(hadUnread)
|
||||
#expect(manager.privateChats[tempPeerID] == nil)
|
||||
#expect(manager.privateChats[peerID]?.count == 1)
|
||||
#expect(manager.unreadMessages.contains(peerID))
|
||||
}
|
||||
|
||||
@Test @MainActor
|
||||
func syncReadReceiptsForSentMessages_onlyCopiesDeliveredAndRead() async {
|
||||
let transport = MockTransport()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user