Pretty much cut/pasting it in, as there's not really a whole much to help make the code more understandable here.
This also includes a comment block longer than the code it describes in hopes it explains away the problem of understanding what it does.
Should fix https://github.com/vector-im/riot-web/issues/8861
Fixes https://github.com/vector-im/riot-web/issues/8936
Watchers are now managed by the SettingsStore itself through a global/default watch manager. As per the included documentation, the watch manager dispatches updates to callbacks which are redirected by the SettingsStore for consumer safety.
Previously it made some complicated assumptions about the contexts it was called in (it generally assumed it just had to shuffle rooms between tags and didn't really handle new rooms very well).
The algorithm now eagerly tries to drop rooms from tags and carefully inserts them. The actual insertion logic is mostly untouched: the only part changed is how it handles failure to insert into tag. It shouldn't be possible for this algorithm to completely skip a room unless the tag is empty, so we special case that.
There are several TODO comments to be addressed here. Namely, it doesn't handle manually ordered tags (favourites, custom, etc) and doesn't check if tags are even enabled. Changes in this area are waiting for https://github.com/matrix-org/matrix-react-sdk/pull/2686 to land to take advantage of monitoring the settings flag for tags.
New rooms (joined, invited, created, etc) were being ignored because they matched the check as soon as the iterator hit a non-recents section. This fixes the check to ensure there's a positive ID on the room being in the tag (or not, in the case of new rooms) before lying to the rest of the function.
Additionally, a fix for favourites has been included to stop the list expanding to fill the void - turns out it was inserting the room twice into the list, and this was breaking the tile rendering. The room sublist would allocate space for the tile, but React would prevent the tile from showing up because of duplicate keys.
Fixes https://github.com/vector-im/riot-web/issues/8868
Fixes https://github.com/vector-im/riot-web/issues/8857 correctly
When we load the page, all encrypted events arrive well after we've generated our initial grouping which can cause them to jump to the top of their categories wrongly. For direct chats, this meant that people who don't have a lot of unread messages would see ancient rooms bubbling to the top for no reason after the page has loaded.
We still have to track when the last category change was (ie: when we switched from red -> grey) so that when the category doesn't exist in the list we can insert the room at the right place (the start of the last category when we switch beyond the order expected).
This changes the approach from regenerating every time there's a change to incrementally fixing the room lists. Additionally, this forces the pin options on for people and implements the sticky room behaviour.
Known bugs include newly joined rooms, invites, etc not sorting correctly.
`unread` and `unread-muted` store booleans in the cache, and can easily be `false`. Without this patch, both of those cached types would be cleared from the object where a later call to `getRoomState` would try and re-populate them. `getRoomState` is supposed to use the cache where possible to avoid making the more expensive calls required to calculate those booleans.
On my account in a test environment, this brings the `generateRoomLists` execution time down from ~250ms to just ~30ms.
This still does not solve the whole issue, but should solve the more common case of performance woes for people.
Not doing so results in the RoomListStore tracking stale data when the user reads messages on another device. The visual effect of this is rooms being incorrectly pinned in places they shouldn't be, such as the top of the list. This also fixes another visual bug where rooms don't move down once their timelines are read. This second issue is mot prominent when multiple rooms have been pinned to the top, and the middle one is read ahead of the others - it'll stick around until some other condition decides to wipe the room's cached state.
Fixes https://github.com/vector-im/riot-web/issues/7653
This is more reliable with LL enabled as the syncing user is
only known when it was active in the current timeline
or when the members have been loaded
as everything listens to the dispatcher, dispatching an action can be quite slow,
especially when only matched in one listener, and the rest all having to be called
to just say "no, thanks". This is especially the case for the RoomMember.membership
event being put on the dispatcher, as there can be thousands of these events
when the room members are loading.
Since the RoomMember.membership action is only used on one place,
and only for the syncing user, change it to just that and only dispatch
in that case. This saves 100-300ms when setting the OOB members in
a big room (7000k members)
Maybe later on we can back this by room.getMyMembership() and avoid the
listener even...