This reduces the update cost of rooms changing, and fixes a bug where when a sublist became filtered it would change the notification count of the sublist.
This does change the expected usage of the state store to ensuring that only one place updates the rooms on the list states, which is currently the room list store. Ideally the state store could listen to the room list store to update itself, however due to a complicated require() loop it is not possible.
Fixes https://github.com/vector-im/riot-web/issues/14694
Instead of spending 10-1000ms in a function iterating over a whole lot of room events, we can use our cached state from the Notification State Store.
This commit sets up a structure that could be applied to communities in the TagPanel too, as that could probably use a similar optimization.
This reduces the updateStatusIndicator() time to just 4ms on average.
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