As Element Call grows in complexity, it has become a pain point that our business logic remains so tightly coupled to the UI code. In particular, this has made testing difficult, and the complex semantics of React hooks are not a great match for arbitrary business logic. Here, I show the beginnings of what it would look like for us to adopt the MVVM pattern. I've created a CallViewModel and TileViewModel that expose their state to the UI as rxjs Observables, as well as a couple of helper functions for consuming view models in React code.
This should contain no user-visible changes, but we need to watch out for regressions particularly around focus switching and promotion of speakers, because this was the logic I chose to refactor first.
This upgrade came with a number of new lints that needed to be fixed across the code base. Primarily: explicit return types on functions, and explicit visibility modifiers on class members.
We're now using LiveKit's magic RoomAudioRenderer component to make sure everyone's audio is rendered regardless of whether they have a tile in the DOM.