Fix room list flickering when selecting rooms#64
Fix room list flickering when selecting rooms#64beezly wants to merge 1 commit intoviktorstrate:mainfrom
Conversation
|
Awesome fix, this is great both for performance and for fixing the flickerings. However, I am worried that just ignoring updates might be too optimistic, say that a I was thinking that we can fix this by adding an public func updateRoom(_ room: MatrixRustSDK.Room) {
assert(id == room.id())
self.room = room
}When sketching this, I see that we need to make And then calling that instead of doing nothing, if the room already exists. |
5799b23 to
f71e58c
Compare
When .set or .reset diffs arrive, reuse existing SidebarRoom instances and call updateRoom() to refresh the underlying room reference and re-subscribe. This preserves object identity so SwiftUI doesn't treat the update as a remove+insert, and retains already-loaded roomInfo. LiveRoom now stores its own let room reference so that SidebarRoom.room can be var without needing nonisolated(unsafe). Also cancel the old listener Task on updateRoom to prevent stale writes, and use uniquingKeysWith for defensive handling of duplicate room IDs.
f71e58c to
488b9a1
Compare
|
Thanks for the suggestion! I've reworked the fix to use updateRoom() as you described. The implementation:
To allow room to be var without concurrency issues, LiveRoom now stores its own let room reference captured at init - it doesn't need to follow sidebar updates since it represents the actively-viewed room with its own timeline and state. This avoids needing nonisolated(unsafe) on SidebarRoom.room (which would otherwise be required because LiveRoom has nonisolated computed properties that access it for the Models.Room protocol conformance). A couple of additional defensive changes:
|
Closes #27
Problem
Clicking a room in the sidebar causes all visible room rows to briefly flicker. This only happens the first time a room is selected — once loaded, subsequent clicks to that room are flicker-free.
Root Cause
When a room is clicked, the read marker moves and the SDK emits
.setor.resetroom list updates.updateRoomEntrieshandled these by creating newSidebarRoomobjects:SidebarRoom.initalways starts withroomInfo = niland fires an async task to fetch it. This means every affected row briefly renders withoutroomInfo— losing unread badges and counts — before the fetch completes. That blank frame is the visible flicker.This also explains the behaviour in #27 where favourites appear to temporarily drop to the Rooms section — the new
SidebarRoomstarts withroomInfo = nil, soisFavouriteis momentarily false, causing the room to be filtered into the wrong section until roomInfo is fetched.Fix
Reuse existing
SidebarRoomobjects by room ID rather than replacing them. SinceSidebarRoomis already subscribed to liveroomInfoupdates viasubscribeToRoomInfoUpdates, there's no need to replace the object when the SDK emits a.setfor the same room ID..set: skip replacement if the room ID at that index hasn't changed.reset: build a lookup of existing objects by ID and reuse them, only creating newSidebarRoominstances for genuinely new rooms