From a3fa7a892f674570b2ffd27a68ed6459086a3b17 Mon Sep 17 00:00:00 2001 From: Nelson Campos Date: Mon, 7 Jul 2025 23:36:10 -0300 Subject: [PATCH] fix: prevent phantom empty messages during sync - Add content validation to skip empty or whitespace-only messages - Apply validation in both channel and regular message handling - Add validation at retry service level to prevent queuing empty messages - This fixes the phantom space issue between synced messages --- bitchat/Services/MessageRetryService.swift | 5 ++++ bitchat/ViewModels/ChatViewModel.swift | 30 +++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/bitchat/Services/MessageRetryService.swift b/bitchat/Services/MessageRetryService.swift index 53c691eb..6cce8046 100644 --- a/bitchat/Services/MessageRetryService.swift +++ b/bitchat/Services/MessageRetryService.swift @@ -61,6 +61,11 @@ class MessageRetryService { originalMessageID: String? = nil, originalTimestamp: Date? = nil ) { + // Don't queue empty or whitespace-only messages + guard !content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { + return + } + // Don't queue if we're at capacity guard retryQueue.count < maxQueueSize else { return diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 8ae3900b..05975813 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -2727,8 +2727,11 @@ extension ChatViewModel: BitchatDelegate { // Check if this is our own message being echoed back if finalMessage.sender != nickname && finalMessage.sender != "system" { - channelMessages[channel]?.append(finalMessage) - channelMessages[channel]?.sort { $0.timestamp < $1.timestamp } + // Skip empty or whitespace-only messages + if !finalMessage.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + channelMessages[channel]?.append(finalMessage) + channelMessages[channel]?.sort { $0.timestamp < $1.timestamp } + } } else if finalMessage.sender != "system" { // Our own message - check if we already have it (by ID and content) let messageExists = channelMessages[channel]?.contains { existingMsg in @@ -2746,8 +2749,11 @@ extension ChatViewModel: BitchatDelegate { } ?? false if !messageExists { // This is a message we sent from another device or it's missing locally - channelMessages[channel]?.append(finalMessage) - channelMessages[channel]?.sort { $0.timestamp < $1.timestamp } + // Skip empty or whitespace-only messages + if !finalMessage.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + channelMessages[channel]?.append(finalMessage) + channelMessages[channel]?.sort { $0.timestamp < $1.timestamp } + } } } else { // System message - always add @@ -2805,9 +2811,12 @@ extension ChatViewModel: BitchatDelegate { // Check if this is our own message being echoed back if finalMessage.sender != nickname && finalMessage.sender != "system" { - messages.append(finalMessage) - // Sort messages by timestamp to ensure proper ordering - messages.sort { $0.timestamp < $1.timestamp } + // Skip empty or whitespace-only messages + if !finalMessage.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + messages.append(finalMessage) + // Sort messages by timestamp to ensure proper ordering + messages.sort { $0.timestamp < $1.timestamp } + } } else if finalMessage.sender != "system" { // Our own message - check if we already have it (by ID and content) let messageExists = messages.contains { existingMsg in @@ -2825,8 +2834,11 @@ extension ChatViewModel: BitchatDelegate { } if !messageExists { // This is a message we sent from another device or it's missing locally - messages.append(finalMessage) - messages.sort { $0.timestamp < $1.timestamp } + // Skip empty or whitespace-only messages + if !finalMessage.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + messages.append(finalMessage) + messages.sort { $0.timestamp < $1.timestamp } + } } } else { // System message - always add