mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-28 11:19:21 +00:00
ios: gate support list reload on the group members were loaded for
This commit is contained in:
@@ -424,6 +424,7 @@ final class ChatModel: ObservableObject {
|
||||
@Published var groupMembers: [GMember] = []
|
||||
@Published var groupMembersIndexes: Dictionary<Int64, Int> = [:] // groupMemberId to index in groupMembers list
|
||||
@Published var membersLoaded = false
|
||||
var membersLoadedGroupId: Int64?
|
||||
// Runtime-only relay hostnames for pre-join channel display, not persisted — lost on app restart.
|
||||
// APIConnectPreparedGroup re-fetches fresh relays at connect time, so stale data doesn't affect join.
|
||||
@Published var channelRelayHostnames: [Int64: [String]] = [:]
|
||||
@@ -581,6 +582,7 @@ final class ChatModel: ObservableObject {
|
||||
self.groupMembers = groupMembers.map { GMember.init($0) }
|
||||
self.populateGroupMembersIndexes()
|
||||
self.membersLoaded = true
|
||||
self.membersLoadedGroupId = groupInfo.groupId
|
||||
}
|
||||
updateView()
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ struct MemberSupportView: View {
|
||||
var body: some View {
|
||||
viewBody()
|
||||
.onAppear {
|
||||
if !chatModel.membersLoaded || chatModel.groupMembers.first?.wrapped.groupId != groupInfo.groupId {
|
||||
if !chatModel.membersLoaded || chatModel.membersLoadedGroupId != groupInfo.groupId {
|
||||
Task {
|
||||
await chatModel.loadGroupMembers(groupInfo)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ Load the list once per open group, then keep it current from what arrives.
|
||||
- `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. If that read returns a store error, it falls back to the pre-send member rather than failing a send that has already happened.
|
||||
- Internal items go through `createChatItems`, for example "new member pending review" (unread and attention +1). It now builds its items from the `ChatInfo` returned by `updateChatTsStats`, as `saveRcvChatItem'` already does, instead of the pre-update `toChatInfo cd`. Otherwise a new pending member would appear without a badge.
|
||||
- Internal items go through `createChatItems`, for example "new member pending review" (unread and attention +1). It now builds its items from the `ChatInfo` returned by `updateChatTsStats`, as `saveRcvChatItem'` already does, instead of the pre-update `toChatInfo cd`. Otherwise a new pending member would appear without a badge. This applies to every chat type: direct and main group chats now carry the updated `chatTs`, as received items already did.
|
||||
- A moderation that arrives before its message creates the item and marks it deleted. The `ChatItemsDeleted` event now carries the group info and scope returned by creating the item, not those from before it.
|
||||
- Opening a member's support chat for the first time sets `support_chat_ts` and now returns the re-read member, so the new chat appears in the list.
|
||||
- Existing clients are unaffected: both apps strip the scope in `updateChatInfo`.
|
||||
@@ -50,7 +50,7 @@ Load the list once per open group, then keep it current from what arrives.
|
||||
- `JoinedGroupMember` and `JoinedGroupMemberConnecting` are emitted right after the "new member pending review" item, and they carry the member with zero support stats. Their handlers keep the support stats already in the list, so they do not erase the badge the item event just set. On Kotlin that item event can also be applied after them; the merge covers either order.
|
||||
- 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.
|
||||
- `apiListMembers` returns `null`/`nil` on error on both platforms, and the member load then keeps the current state, so a failed load does not mark members as loaded. iOS still runs the load's completion, so group info still opens.
|
||||
- iOS clears the loaded members and resets `membersLoaded` when the open chat changes without going through the chat list (notification tap, "forwarded from", member info), as Kotlin already does. Because group info can also be opened from a message avatar without reloading members, the iOS list additionally reloads when the loaded members belong to another group.
|
||||
- iOS clears the loaded members and resets `membersLoaded` when the open chat changes without going through the chat list (notification tap, "forwarded from", member info), as Kotlin already does. Because group info can also be opened from a message avatar without reloading members, the iOS list additionally reloads unless members were loaded for this group (`membersLoadedGroupId`).
|
||||
- iOS resets `membersLoaded` when chats are refreshed on resume, because the notification extension may have changed support chats while the app was suspended.
|
||||
- Kotlin `upsertGroupMember` also resets `membersLoaded` when it clears another group's stale members.
|
||||
- Kotlin `setGroupMembers` now writes on the main thread, where all upserts run, so an upsert can no longer land between clearing the index and rebuilding it and add a duplicate. It 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.
|
||||
@@ -65,7 +65,7 @@ A member's first support message arrives as a `NewChatItems` event with that mem
|
||||
- Support stats snapshots from different events and responses are applied in arrival order, so a rare reordering can briefly show an older count until the next update for that member.
|
||||
- On iOS, if the list is on screen while the app resumes, changes the notification extension made while suspended appear only after the list is left and reopened.
|
||||
- On iOS, handlers that update an existing member in place without publishing a change, such as "Mark read" from the context menu or accept, update the row but not the list order or filter until the next `ChatModel` change. The existing TODO in `deleteMemberSupportChat` describes the same mechanism. Previously, returning to the list also re-sorted it.
|
||||
- The connection-state labels in rows (failed, disabled, inactive) come from `activeConn`. Neither app handles `ConnectionDisabled` or `ConnectionInactive`, so these labels now refresh only when the group is reopened.
|
||||
- The connection-state labels in rows (failed, disabled, inactive) come from `activeConn`. Neither app handles `ConnectionDisabled` or `ConnectionInactive`, so these labels now refresh only on the next full member event for that member (role, profile, connected) or when the group is reopened.
|
||||
|
||||
## Not addressed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user