vector-im/element-web#23819 is an intermittent failure to correctly initiate a user verification process. The
root cause is as follows:
* In matrix-react-sdk, ensureDMExists tries to create an encrypted DM room, and assumes it is ready for use
(including sending encrypted events) as soon as it receives a RoomStateEvent.NewMember notification
indicating that the other user has been invited or joined.
* However, in sync.ts, we process the membership events in a /sync response (including emitting
RoomStateEvent.NewMember notifications), which is long before we process any m.room.encryption event.
* The upshot is that we can end up trying to send an encrypted event in the new room before processing
the m.room.encryption event, which causes the crypto layer to blow up with an error of "Room was
previously configured to use encryption, but is no longer".
Strictly speaking, ensureDMExists probably ought to be listening for ClientEvent.Room as well as RoomStateEvent.NewMember; but that doesn't help us, because ClientEvent.Room is also emitted
before we process the crypto event.
So, we need to process the crypto event before we start emitting these other events; but a corollary of that
is that we need to do so before we store the new room in the client's store. That makes things tricky, because
currently the crypto layer expects the room to have been stored in the client first.
So... we have to rearrange everything to pass the newly-created Room object into the crypto layer, rather than
just the room id, so that it doesn't need to rely on getting the Room from the client's store.
This refactoring brings a number of improvements to GroupCall, which I've unfortunately had to combine into a single commit due to coupling:
- Moves the expiration timestamp field on call membership state to be per-device
- Makes the participants of a group call visible without having to enter the call yourself
- Enables users to join group calls from multiple devices
- Identifies active speakers by their call feed, rather than just their user ID
- Plays nicely with clients that can be in multiple calls in a room at once
- Fixes a memory leak caused by the call retry loop never stopping
- Changes GroupCall to update its state synchronously, and write back to room state asynchronously
- This was already sort of halfway being done, but now we'd be committing to it
- Generally improves the robustness of the state machine
- It means that group call joins will appear instant, in a sense
For many reasons, this is a breaking change.
Add checks to `addEventToTimeline` as extra insurance that we don't mix events in the wrong timelines (main timeline vs thread timeline).
Split out from https://github.com/matrix-org/matrix-js-sdk/pull/2521
This PR is a v2 of https://github.com/matrix-org/matrix-js-sdk/pull/2848 since it was reverted in https://github.com/matrix-org/matrix-js-sdk/pull/2853
Previously, we just relied on the callers to make sure they're doing the right thing and since it's easy to get it wrong, we mixed and bugs happened.
Call stacks for how events get added to a timeline:
- `TimelineSet.addEventsToTimeline` -> `TimelineSet.addEventToTimeline` -> `Timeline.addEvent`
- `TimelineSet.addEventToTimeline` -> `Timeline.addEvent`
- `TimelineSet.addLiveEvent` -> `TimelineSet.addEventToTimeline` -> `Timeline.addEvent`
Add checks to `addEventToTimeline` as extra insurance that we don't mix events in the wrong timelines (main timeline vs thread timeline).
Split out from https://github.com/matrix-org/matrix-js-sdk/pull/2521
Previously, we just relied on the callers to make sure they're doing the right thing and since it's easy to get it wrong, we mixed and bugs happened.
Call stacks for how events get added to a timeline:
- `TimelineSet.addEventsToTimeline` -> `TimelineSet.addEventToTimeline` -> `Timeline.addEvent`
- `TimelineSet.addEventToTimeline` -> `Timeline.addEvent`
- `TimelineSet.addLiveEvent` -> `TimelineSet.addEventToTimeline` -> `Timeline.addEvent`
Unfortunately there are still other methods that could race with leave and result in broken group call state, such as enter and terminate. For the future, should consider writing a more careful specification of how the whole group call state machine is meant to work.
* Fix bug where undefined vs null in pagination tokens wasn't correctly handled
* Fix bug where thread list results were sorted incorrectly
* Allow removing the relationship of an event to a thread
* Implement feature detection for new threads MSCs and specs
* Prefix dir parameter for threads pagination if necessary
* Make threads conform to the same timeline APIs as any other timeline
* Extract thread timeline loading out of thread class
* fix thread roots not being updated correctly
* fix jumping to events by link
* implement new thread timeline loading
* Fix fetchRoomEvent incorrect return type
Co-authored-by: Germain <germains@element.io>
Co-authored-by: Germain <germain@souquet.com>
* TS strict mode compliance in the call / groupcall code
* Also the test
* Fix initOpponentCrypto
to not panic if it doesn't actually need to init crypto