mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-05 23:07:57 +00:00
core, tests, ui: keep member order with role index, skip down-migration schema comparison, reload support list on return with older remote hosts
This commit is contained in:
+7
-5
@@ -383,14 +383,14 @@ object ChatModel {
|
||||
fun getGroupChat(groupId: Long): Chat? = chats.value.firstOrNull { it.chatInfo is ChatInfo.Group && it.chatInfo.apiId == groupId }
|
||||
|
||||
suspend fun upsertSupportChatMember(rhId: Long?, cInfo: ChatInfo) {
|
||||
if (cInfo !is ChatInfo.Group) return
|
||||
if (cInfo !is ChatInfo.Group || remoteHostId() != rhId) return
|
||||
val member = (cInfo.groupChatScope as? GroupChatScopeInfo.MemberSupport)?.groupMember_ ?: return
|
||||
val current = groupMembersIndexes.value[member.groupMemberId]?.let { groupMembers.value.getOrNull(it) }
|
||||
val current = getGroupMember(member.groupMemberId)
|
||||
chatsContext.upsertGroupMember(rhId, cInfo.groupInfo, current?.copy(supportChat = member.supportChat, memberProfile = member.memberProfile) ?: member)
|
||||
}
|
||||
|
||||
fun withLoadedSupportChat(member: GroupMember): GroupMember {
|
||||
val supportChat = groupMembersIndexes.value[member.groupMemberId]?.let { groupMembers.value.getOrNull(it) }?.supportChat
|
||||
val supportChat = getGroupMember(member.groupMemberId)?.supportChat
|
||||
return if (supportChat != null) member.copy(supportChat = supportChat) else member
|
||||
}
|
||||
|
||||
@@ -986,8 +986,10 @@ object ChatModel {
|
||||
// stale data, should be cleared at that point, otherwise, duplicated items will be here which will produce crashes in LazyColumn
|
||||
groupMembers.value = emptyList()
|
||||
groupMembersIndexes.value = emptyMap()
|
||||
membersLoaded.value = false
|
||||
supportMembersLoaded.value = false
|
||||
if (chatId.value == groupInfo.id) {
|
||||
membersLoaded.value = false
|
||||
supportMembersLoaded.value = false
|
||||
}
|
||||
}
|
||||
val memberIndex = groupMembersIndexes.value[member.groupMemberId]
|
||||
val updated = chatItems.value.map {
|
||||
|
||||
+3
-5
@@ -1211,9 +1211,7 @@ object ChatController {
|
||||
val r = sendCmd(rh, cmd)
|
||||
return when {
|
||||
r is API.Result && r.res is CR.NewChatItems -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
r.res.chatItems.forEach { chatModel.upsertSupportChatMember(rh, it.chatInfo) }
|
||||
}
|
||||
r.res.chatItems.lastOrNull()?.let { withContext(Dispatchers.Main) { 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 -> {
|
||||
@@ -2488,11 +2486,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 null
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
suspend fun apiListSupportMembers(rh: Long?, groupId: Long): List<GroupMember>? {
|
||||
|
||||
-1
@@ -3445,7 +3445,6 @@ private fun archiveReports(chatRh: Long?, chatInfo: ChatInfo, itemIds: List<Long
|
||||
}
|
||||
deleted.lastOrNull()?.deletedChatItem?.chatInfo?.let { updatedChatInfo ->
|
||||
chatModel.chatsContext.updateChatInfo(chatRh, updatedChatInfo)
|
||||
chatModel.upsertSupportChatMember(chatRh, updatedChatInfo)
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ private fun acceptMember(rhId: Long?, groupInfo: GroupInfo, member: GroupMember,
|
||||
val r = chatModel.controller.apiAcceptMember(rhId, groupInfo.groupId, member.groupMemberId, role)
|
||||
if (r != null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
chatModel.chatsContext.upsertGroupMember(rhId, r.first, r.second)
|
||||
chatModel.chatsContext.upsertGroupMember(rhId, r.first, chatModel.withLoadedSupportChat(r.second))
|
||||
chatModel.chatsContext.updateGroup(rhId, r.first)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-11
@@ -41,20 +41,19 @@ fun ModalData.MemberSupportView(
|
||||
KeyChangeEffect(chatModel.chatId.value) {
|
||||
ModalManager.end.closeModals()
|
||||
}
|
||||
val membersLoading = remember { stateGetOrPut("membersLoading") { false } }
|
||||
LaunchedEffect(Unit) {
|
||||
if (rhId != null) setSupportMembers(rhId, groupInfo, chatModel)
|
||||
}
|
||||
LaunchedEffect(chatModel.membersLoaded.value, chatModel.supportMembersLoaded.value) {
|
||||
if (!chatModel.membersLoaded.value && !chatModel.supportMembersLoaded.value && chatModel.chatId.value == groupInfo.id && !membersLoading.value) {
|
||||
membersLoading.value = true
|
||||
withBGApi {
|
||||
try {
|
||||
setSupportMembers(rhId, groupInfo, chatModel)
|
||||
} finally {
|
||||
membersLoading.value = false
|
||||
}
|
||||
}
|
||||
if (rhId != null || chatModel.chatId.value != groupInfo.id) return@LaunchedEffect
|
||||
val otherGroupMembers = chatModel.groupMembers.value.firstOrNull()?.let { it.groupId != groupInfo.groupId } == true
|
||||
if ((!chatModel.membersLoaded.value && !chatModel.supportMembersLoaded.value) || otherGroupMembers) {
|
||||
setSupportMembers(rhId, groupInfo, chatModel)
|
||||
}
|
||||
}
|
||||
ModalView(close = close) {
|
||||
ModalView(
|
||||
close = close
|
||||
) {
|
||||
MemberSupportViewLayout(
|
||||
chat,
|
||||
groupInfo,
|
||||
|
||||
+10
-7
@@ -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) ?: return@coroutineScope
|
||||
val groupMembers = chatModel.controller.apiListMembers(rhId, groupInfo.groupId)
|
||||
val currentMembersById = chatModel.groupMembers.value.associateBy { it.id }
|
||||
val newMembers = groupMembers.map { newMember ->
|
||||
val currentMember = currentMembersById[newMember.id]
|
||||
@@ -265,8 +265,7 @@ suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatMo
|
||||
newMember
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (chatModel.chatId.value != groupInfo.id && chatModel.creatingChannelId.value != groupInfo.id) return@withContext
|
||||
withContext(NonCancellable + Dispatchers.Main) {
|
||||
chatModel.groupMembersIndexes.value = emptyMap()
|
||||
chatModel.groupMembers.value = newMembers
|
||||
chatModel.membersLoaded.value = true
|
||||
@@ -274,11 +273,15 @@ suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatMo
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setSupportMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel) = coroutineScope {
|
||||
suspend fun setSupportMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel) {
|
||||
val supportMembers = chatModel.controller.apiListSupportMembers(rhId, groupInfo.groupId)
|
||||
?: return@coroutineScope setGroupMembers(rhId, groupInfo, chatModel)
|
||||
withContext(Dispatchers.Main) {
|
||||
if (chatModel.chatId.value != groupInfo.id) return@withContext
|
||||
if (supportMembers == null) {
|
||||
setGroupMembers(rhId, groupInfo, chatModel)
|
||||
return
|
||||
}
|
||||
withContext(NonCancellable + Dispatchers.Main) {
|
||||
if (chatModel.chatId.value != groupInfo.id || chatModel.remoteHostId() != rhId) return@withContext
|
||||
if (chatModel.groupMembers.value.any { it.groupId != groupInfo.groupId }) chatModel.membersLoaded.value = false
|
||||
val membersById = LinkedHashMap<Long, GroupMember>()
|
||||
chatModel.groupMembers.value.forEach { if (it.groupId == groupInfo.groupId) membersById[it.groupMemberId] = it }
|
||||
supportMembers.forEach { member ->
|
||||
|
||||
Reference in New Issue
Block a user