Previously we were creating a notification state whenever we needed one, which was leading to hundreds of listeners even on a small account. To ease the burden, and reduce the load of having to wake so many listeners, we now record a single listener for each tag ID and room combination.
This commit also introduces a number of utilities to make future notification work a bit of an easier transition, such as the `isX` and `hasX` getters on the new NotificationState abstract class. Similarly, "snapshots" have been added to reduce code duplication between different kinds of states checking for updates.
The ListNotificationState is now heavily tied into the store which offers it to help reuse the cache of room notification states.
Fixes https://github.com/vector-im/riot-web/issues/14370
This is more general maintenance than performance as the RoomList doesn't need to be generating layouts for the sublists, and it certainly doesn't need to be creating a bunch of extra ones.
The sublists are perfectly capable of getting their own layout instance and using it, and we are perfectly able to limit the number of these things we create through the session's lifespan.
In this demonstration, we remove the cutting line (as it collides with the tile in a weird spot) and instead replace the tile with a placeholder when the text is about to collide with the avatar in the tile. We use a `round()` for this because through some amazing coincidence the collision happens at 0.47, which is close enough to 0.5 for people not to notice.
Fixes https://github.com/vector-im/riot-web/issues/14378
Rooms transitioning between multiple states are often at risk of going missing due to the sticky room handling. We now protect that transition by bluntly ensuring the room can't go missing, and by always ensuring we have an updated reference to the room.
react-resizer appears to be okay at tracking state, but it often desyncs from reality. re-resizer is more maintained and more broadly used (160k downloads vs 110k), and appears to generally do a better job of tracking the cursor.
The new library has some oddities though, such as deltas, touch support (hence the polyfill), and calling handles "Enable".
For https://github.com/vector-im/riot-web/issues/14022
We don't need the fake clock anymore, but we do have to wait for async actions to complete before moving forward.
This also exposes a number of functions for the store to be puppetted with.
Fixes https://github.com/vector-im/riot-web/issues/14372
We read/use the options in multiple places, and those places were not in sync. Now when algorithms change and on initial load, both will come to the same conclusions about how to order & sort the rooms.
This fixes a case where a user accepts an invite, which causes a tag change, but the room stays stuck in the invites list. The tag change additionally gets swallowed when the user moves away, causing the room to get lost.
By moving it when we see it, potentially during a sticky room change itself (though extremely rare), we avoid having the room get lost in the wrong lists. A side effect of this is that accepting an invite puts it at the top of the tag it's going to (usually untagged), however this feels like the best option for the user.
A rare case of a tag change happening during a sticky room change is when a leave event comes in for the sticky room, but because it's come through as a tag change it can get swallowed. If it does get swallowed and the user clicks away, the tag change will happen when the room is re-introduced to the list (fake NewRoom event).
Plus a bunch of logging.
This fixes a case where switching rooms would cause the last room you were on to disappear due to an optimization where known NewRoom fires would be translated to tag change fires, which wouldn't re-add the room to the underlying tag algorithm.
By tracking the last sticky room, we can identify when we're about to do this and avoid it.
This commit also adds a check to ensure that we have the latest reference of a room stored as rooms changing from invite -> join change references.
This commit additionally updates the PossibleTagChange handling to be faster and smarter, leading to a more stable generation of the room list. We convert the update cause to a Timeline update in order to indicate it is a change within the same tag rather than having to jump tags. This also means that PossibleTagChange should no longer make it as far as the underlying algorithm.
New logging has also been added to aid debugging.
Fixes https://github.com/vector-im/riot-web/issues/14179
Disclaimer: this is all of the horrible because it's not meant to be here. Invites in general are likely to move out of the room list, which means this is temporary. Additionally, the communities rework will take care of this more correctly. For now, we support the absolute bare minimum to have them shown.
For example, if you only have 3/10 rooms required for the default then resize smaller, we should have a 'show more' button.
This works by changing the rendering to be slightly more efficient and only looping over what is seen (renderVisibleTiles(), using this.numTiles in place of tiles.length) and using a new setVisibleTilesWithin() function on the layout. Previously resizing the 3/10 case would be setting visibleTiles to ~8 instead of ~1 like it should (because the getter returns a default).
`setKnownRooms` is called to regenerate the room list, and if we don't take the sticky room out of the equation we end up with the room being duplicated. So, to make this easy, we simply remove the sticky room and handle it after the fact.
This small check just ensures that we aren't about to blindly accept that the calling code knows what it is doing. There are some unknown cases where NewRoom gets fired for rooms we already know about, so in those cases we just change it to a PossibleTagChange which is what the caller likely intended.
Many of the edge cases are unknown, though this can happen for an invite being accepted (for example). It's easier to handle it here instead of tracking down every single possibility and fixing it higher up.
When a new room is added there's a fairly good chance that the other events being dispatched will happen in the middle of (for example) the room list being re-sorted. This commit wraps the entire handleRoomUpdate() function for the underlying algorithms in a lock so that if we're unlucky enough to get an update while we're sorting (as the ImportanceAlgorithm splices out what it is sorting) we won't scream about invalid index errors.
We have to do a bit of a dance to return the sticky room to the list so we can remove it, if needed, and ensure that we generally swap the rooms out of the list.
This reverts earlier changes made to textForEvent as they are no longer needed.
This also implements an entire tree of textForEvent-like behaviour as the previews need to be different, which is easiest done with its own stack.
Smaller handle width, small shadow on the top of the show more button if there's more rooms to be shown. The resize handle also only shows when you're hovering in the area now.
The original design called for the shadow to show up only if the user is cutting a tile or dragging, however that is complicated implementation-wise. For speed and encouraging a dogfooding pattern we're going ahead with this behaviour instead.
For https://github.com/vector-im/riot-web/issues/14034
One of the largest issues with room switching was that we'd regenerate the entire list when the sticky room changes, which is obviously detrimental on larger accounts (and even some medium accounts). To work through this, we simply handle the NewRoom and RoomRemoved causes (used by the sticky room handling) as splices rather than in-place updates.
Overall this leads to a smoother experience as it means we're doing far less calculations and can even opt out of an update if it isn't required, such as a RoomRemoved cause being fired twice - the second one can result in an update not being required, saving render time.
This commit also includes a fix for handling update causes on the sticky room, as the room list loves to print errors when this happens. We don't need to handle any updates because once the sticky room changes it'll get re-added through NewRoom, causing the underlying algorithm to slot it in where needed, effectively handling all the missed updates.