Dispatch updates to the UI later only after processing all of them instead of after each one

This commit is contained in:
Stefan Ceriu
2023-08-23 19:59:21 +03:00
committed by Stefan Ceriu
parent 5addf9d64a
commit 2f05400113
@@ -133,35 +133,41 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
MXLog.verbose("\(name): Received \(diffs.count) diffs, current room list \(rooms.compactMap { $0.id ?? "Empty" })") MXLog.verbose("\(name): Received \(diffs.count) diffs, current room list \(rooms.compactMap { $0.id ?? "Empty" })")
var updatedItems = rooms
for diff in diffs { for diff in diffs {
// Special case resets in order to prevent large updates from blocking the UI
// Render the first resetDiffChunkingThreshhold as a reset and then append the rest to give the UI time to update
let resetDiffChunkingThreshhold = 50 let resetDiffChunkingThreshhold = 50
if case .reset(let values) = diff, values.count > resetDiffChunkingThreshhold { if case .reset(let values) = diff, values.count > resetDiffChunkingThreshhold {
processDiff(RoomListEntriesUpdate.reset(values: Array(values[..<resetDiffChunkingThreshhold]))) // Special case resets in order to prevent large updates from blocking the UI
processDiff(RoomListEntriesUpdate.append(values: Array(values.dropFirst(resetDiffChunkingThreshhold)))) // Render the first resetDiffChunkingThreshhold as a reset and then append the rest to give the UI time to update
updatedItems = processDiff(.reset(values: Array(values[..<resetDiffChunkingThreshhold])), on: updatedItems)
// Once a reset is chunked dispatch the first part to the UI for rendering
rooms = updatedItems
updatedItems = processDiff(.append(values: Array(values.dropFirst(resetDiffChunkingThreshhold))), on: updatedItems)
} else { } else {
processDiff(diff) updatedItems = processDiff(diff, on: updatedItems)
} }
} }
rooms = updatedItems
detectDuplicatesInRoomList(rooms) detectDuplicatesInRoomList(rooms)
MXLog.verbose("\(name): Finished applying \(diffs.count) diffs, new room list \(rooms.compactMap { $0.id ?? "Empty" })") MXLog.verbose("\(name): Finished applying \(diffs.count) diffs, new room list \(rooms.compactMap { $0.id ?? "Empty" })")
} }
private func processDiff(_ diff: RoomListEntriesUpdate) { private func processDiff(_ diff: RoomListEntriesUpdate, on currentItems: [RoomSummary]) -> [RoomSummary] {
guard let collectionDiff = buildDiff(from: diff, on: rooms) else { guard let collectionDiff = buildDiff(from: diff, on: currentItems) else {
MXLog.error("\(name): Failed building CollectionDifference from \(diff)") MXLog.error("\(name): Failed building CollectionDifference from \(diff)")
return return currentItems
} }
guard let updatedItems = rooms.applying(collectionDiff) else { guard let updatedItems = currentItems.applying(collectionDiff) else {
MXLog.error("\(name): Failed applying diff: \(collectionDiff)") MXLog.error("\(name): Failed applying diff: \(collectionDiff)")
return return currentItems
} }
rooms = updatedItems return updatedItems
} }
private func fetchRoomInfo(roomListItem: RoomListItemProtocol) -> RoomInfo? { private func fetchRoomInfo(roomListItem: RoomListItemProtocol) -> RoomInfo? {