core, ui: carry updated support member in internal items, merge only support stats, handle failed member loads

This commit is contained in:
Narasimha-sc
2026-09-27 21:21:18 +00:00
parent 2abbcb2d36
commit 834ea18664
10 changed files with 50 additions and 27 deletions
+6 -1
View File
@@ -1328,7 +1328,12 @@ final class ChatModel: ObservableObject {
func upsertSupportChatMember(_ cInfo: ChatInfo) {
if case let .group(groupInfo, .memberSupport(member?)?) = cInfo {
_ = upsertGroupMember(groupInfo, member)
var m = member
if let current = getGroupMember(member.groupMemberId)?.wrapped {
m = current
m.supportChat = member.supportChat
}
_ = upsertGroupMember(groupInfo, m)
objectWillChange.send()
}
}
+4 -1
View File
@@ -157,7 +157,10 @@ struct SimpleXApp: App {
private func updateChats() async {
do {
let chats = try await apiGetChatsAsync()
await MainActor.run { chatModel.updateChats(chats) }
await MainActor.run {
chatModel.updateChats(chats)
chatModel.membersLoaded = false
}
if let id = chatModel.chatId,
let chat = chatModel.getChat(id),
!NtfManager.shared.navigatingToChat {
@@ -384,7 +384,8 @@ object ChatModel {
suspend fun upsertSupportChatMember(rhId: Long?, cInfo: ChatInfo) {
if (cInfo !is ChatInfo.Group) return
val member = (cInfo.groupChatScope as? GroupChatScopeInfo.MemberSupport)?.groupMember_ ?: return
chatsContext.upsertGroupMember(rhId, cInfo.groupInfo, member)
val current = groupMembersIndexes.value[member.groupMemberId]?.let { groupMembers.value.getOrNull(it) }
chatsContext.upsertGroupMember(rhId, cInfo.groupInfo, current?.copy(supportChat = member.supportChat) ?: member)
}
fun populateGroupMembersIndexes() {
@@ -1210,7 +1210,12 @@ object ChatController {
private suspend fun processSendMessageCmd(rh: Long?, cmd: CC): List<AChatItem>? {
val r = sendCmd(rh, cmd)
return when {
r is API.Result && r.res is CR.NewChatItems -> r.res.chatItems
r is API.Result && r.res is CR.NewChatItems -> {
withContext(Dispatchers.Main) {
r.res.chatItems.forEach { chatModel.upsertSupportChatMember(rh, it.chatInfo) }
}
r.res.chatItems
}
r is API.Error && r.err is ChatError.ChatErrorStore && r.err.storeError is StoreError.LargeMsg && cmd is CC.ApiSendMessages -> {
val mc = cmd.composedMessages.last().msgContent
AlertManager.shared.showAlertMsg(
@@ -2483,11 +2488,11 @@ object ChatController {
return null
}
suspend fun apiListMembers(rh: Long?, groupId: Long): List<GroupMember> {
suspend fun apiListMembers(rh: Long?, groupId: Long): List<GroupMember>? {
val r = sendCmd(rh, CC.ApiListMembers(groupId))
if (r is API.Result && r.res is CR.GroupMembers) return r.res.group.members
Log.e(TAG, "apiListMembers bad response: ${r.responseType} ${r.details}")
return emptyList()
return null
}
suspend fun apiUpdateGroup(rh: Long?, groupId: Long, groupProfile: GroupProfile, isChannel: Boolean): GroupInfo? {
@@ -599,7 +599,6 @@ fun ComposeView(
chatItems.forEach { aChatItem ->
withContext(Dispatchers.Main) {
chatsCtx.addChatItem(chat.remoteHostId, aChatItem.chatInfo, aChatItem.chatItem)
chatModel.upsertSupportChatMember(chat.remoteHostId, aChatItem.chatInfo)
}
}
return chatItems.first().chatItem
@@ -253,7 +253,7 @@ suspend fun apiFindMessages(chatsCtx: ChatModel.ChatsContext, ch: Chat, contentT
suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel) = coroutineScope {
// groupMembers loading can take a long time and if the user already closed the screen, coroutine may be canceled
val groupMembers = chatModel.controller.apiListMembers(rhId, groupInfo.groupId)
val groupMembers = chatModel.controller.apiListMembers(rhId, groupInfo.groupId) ?: return@coroutineScope
val currentMembersById = chatModel.groupMembers.value.associateBy { it.id }
val newMembers = groupMembers.map { newMember ->
val currentMember = currentMembersById[newMember.id]