core, ui: return updated support member on send, ignore stale member loads

This commit is contained in:
Narasimha-sc
2026-09-27 21:21:18 +00:00
parent 67422bbbc3
commit 2abbcb2d36
4 changed files with 16 additions and 4 deletions
+5
View File
@@ -592,6 +592,11 @@ private func processSendMessageCmd(toChatType: ChatType, cmd: ChatCommand) async
} else {
r = await chatApiSendCmd(cmd, bgDelay: msgDelay)
if case let .result(.newChatItems(_, aChatItems)) = r {
await MainActor.run {
for aChatItem in aChatItems {
chatModel.upsertSupportChatMember(aChatItem.chatInfo)
}
}
return aChatItems.map { $0.chatItem }
}
sendMessageErrorAlert(r.unexpected)
@@ -265,6 +265,7 @@ suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatMo
newMember
}
}
if (chatModel.chatId.value != groupInfo.id && chatModel.creatingChannelId.value != groupInfo.id) return@coroutineScope
chatModel.groupMembersIndexes.value = emptyMap()
chatModel.groupMembers.value = newMembers
chatModel.membersLoaded.value = true
+5 -3
View File
@@ -32,6 +32,7 @@ Load the list once per open group, then keep it current from what arrives.
- `updateGroupScopeUnreadStats` returns the updated `GroupChatScopeInfo` together with `GroupInfo`.
- `APIChatItemsRead` returns `GroupChat gInfo' chatScopeInfo'`.
- `deleteGroupCIs` puts the updated scope member into each deletion's chat info.
- The group send response re-reads the support scope member after `saveSndChatItems` has updated `support_chat_ts`, instead of returning the member from before the send.
- Existing clients are unaffected: both apps strip the scope in `updateChatInfo`.
**Android/desktop, and iOS**
@@ -40,18 +41,19 @@ Load the list once per open group, then keep it current from what arrives.
- `NewChatItems` events;
- `ChatItemsDeleted` events;
- delete responses (items and reports);
- send responses (Kotlin only);
- send responses;
- the mark-read response;
- the initial load of a support chat.
- The member list loads only if `membersLoaded` is false. The mention picker already uses this flag the same way, and it is reset when leaving the group.
- Kotlin `setGroupMembers` writes its result only if the group is still the open chat (or the channel being created), as iOS `loadGroupMembers` already does. Without this check, a slow load from a previously opened channel could finish after a chat switch and mark another group's members as loaded. The old reload on every return hid that.
- The refresh button is removed. The list is kept current by the updates above.
- iOS also sends `objectWillChange`, because updating a `GMember` in place does not re-render or re-sort the list.
A member's first support message arrives as a `NewChatItems` event with that member, so a new support chat appears in the list without a reload.
## Not covered
## Known limitation
- On iOS, `apiSendMessages` returns bare `ChatItem`s without chat info. The list's last-activity order after the user's own reply updates only when the group is reopened.
A full member load that is in flight when a support-chat update arrives overwrites that update with its snapshot. For example, the first list load can race a member's first support message. The member then reappears on their next message, when their chat is opened, or when the group is reopened.
## Alternatives considered
+5 -1
View File
@@ -4875,7 +4875,11 @@ processChatCommand cxt nm = \case
forM_ (timed_ >>= timedDeleteAt') $ \deleteAt ->
forM_ cis $ \ci ->
startProximateTimedItemThread user (ChatRef CTGroup groupId scope, chatItemId' ci) deleteAt
pure $ CRNewChatItems user (map (AChatItem SCTGroup SMDSnd (GroupChat gInfo chatScopeInfo)) cis)
chatScopeInfo' <- case chatScopeInfo of
Just GCSIMemberSupport {groupMember_ = Just sentScopeMem} ->
Just . GCSIMemberSupport . Just <$> withFastStore (\db -> getGroupMemberById db cxt user (groupMemberId' sentScopeMem))
_ -> pure chatScopeInfo
pure $ CRNewChatItems user (map (AChatItem SCTGroup SMDSnd (GroupChat gInfo chatScopeInfo')) cis)
where
setupSndFileTransfers :: Int -> CM (NonEmpty (Maybe FileInvitation, Maybe (CIFile 'MDSnd)))
setupSndFileTransfers n =