From 2b20c9efb2a8e1a4889c23922d9d02bb30698e1c Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Thu, 18 Jun 2026 13:32:31 +0000 Subject: [PATCH] android, desktop, ios: keep pending invitee preview in sync on support message edit/delete upsertChatItem/removeChatItem gated their main-list preview update on groupChatScope()==null, so once a pending invitee's support message was the preview, editing it left stale text and deleting/moderating it left a phantom. Add the same memberPending exception addChatItem has (both already match the preview item by id). On iOS, restrict the 'update preview for an item not in the open scope' clause to main scope so a support item's status updates don't churn the preview. --- apps/ios/Shared/Model/ChatModel.swift | 10 +++++++--- .../kotlin/chat/simplex/common/model/ChatModel.kt | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index ab7d2b6d9d..423f16adaa 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -722,10 +722,12 @@ final class ChatModel: ObservableObject { func upsertChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) -> Bool { // update chat list var itemAdded: Bool = false - if cInfo.groupChatScope() == nil { + // memberPending: a pending invitee's support item may be the main-list preview, so keep it in + // sync on edit/status change too (matching addChatItem) + if cInfo.groupChatScope() == nil || cInfo.groupInfo?.membership.memberPending ?? false { if let chat = getChat(cInfo.id) { if let pItem = chat.chatItems.last { - if pItem.id == cItem.id || (chatId == cInfo.id && im.reversedChatItems.first(where: { $0.id == cItem.id }) == nil) { + if pItem.id == cItem.id || (cInfo.groupChatScope() == nil && chatId == cInfo.id && im.reversedChatItems.first(where: { $0.id == cItem.id }) == nil) { chat.chatItems = [cItem] } } else { @@ -793,7 +795,9 @@ final class ChatModel: ObservableObject { func removeChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) { // update chat list - if cInfo.groupChatScope() == nil { + // memberPending: a pending invitee's support item may be the main-list preview, so clear it + // when deleted/moderated too (matching addChatItem) + if cInfo.groupChatScope() == nil || cInfo.groupInfo?.membership.memberPending ?? false { if cItem.isRcvNew { unreadCollector.changeUnreadCounter(cInfo.id, by: -1, unreadMentions: cItem.meta.userMention ? -1 : 0) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 88c7b6d8e4..644a62e949 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -622,7 +622,9 @@ object ChatModel { suspend fun upsertChatItem(rhId: Long?, cInfo: ChatInfo, cItem: ChatItem): Boolean { var itemAdded = false // update chat list - if (cInfo.groupChatScope() == null) { + // memberPending: a pending invitee's support item may be the main-list preview, so keep it in + // sync on edit/status change too (matching addChatItem) + if (cInfo.groupChatScope() == null || cInfo.groupInfo_?.membership?.memberPending == true) { val i = getChatIndex(rhId, cInfo.id) val chat: Chat if (i >= 0) { @@ -680,7 +682,9 @@ object ChatModel { fun removeChatItem(rhId: Long?, cInfo: ChatInfo, cItem: ChatItem) { // update chat list - if (cInfo.groupChatScope() == null) { + // memberPending: a pending invitee's support item may be the main-list preview, so clear it + // when deleted/moderated too (matching addChatItem) + if (cInfo.groupChatScope() == null || cInfo.groupInfo_?.membership?.memberPending == true) { if (cItem.isRcvNew) { decreaseCounterInPrimaryContext(rhId, cInfo.id) }