From 98fa02cc16fb37509c892863ed75550ea7120c3a Mon Sep 17 00:00:00 2001 From: jack <212554440+jackjackbits@users.noreply.github.com> Date: Tue, 21 Oct 2025 13:47:24 +0200 Subject: [PATCH] Prevent duplicate action emote echoes (#852) Co-authored-by: jack --- bitchat/ViewModels/ChatViewModel.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index f661943e..f7378938 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -5469,6 +5469,9 @@ final class ChatViewModel: ObservableObject, BitchatDelegate { ) // Append to current visible messages messages.append(systemMessage) + // Track the content key so relayed copies of the same system-style message are ignored + let contentKey = normalizedContentKey(systemMessage.content) + recordContentKey(contentKey, timestamp: systemMessage.timestamp) // Persist into the backing store for the active channel to survive rebinds switch activeChannel { case .mesh: @@ -6285,7 +6288,9 @@ final class ChatViewModel: ObservableObject, BitchatDelegate { let isGeo = finalMessage.senderPeerID?.isGeoChat == true // Apply per-sender and per-content rate limits (drop if exceeded) - if finalMessage.sender != "system" { + // Treat action-style system messages (which carry a senderPeerID) the same as regular user messages + let shouldRateLimit = finalMessage.sender != "system" || finalMessage.senderPeerID != nil + if shouldRateLimit { let senderKey = normalizedSenderKey(for: finalMessage) let contentKey = normalizedContentKey(finalMessage.content) let now = Date()