We've gotten feedback that it's distracting whenever the same video is shown in two places on screen. This fixes the spotlight case by showing only the avatar of anyone who is already visible in the spotlight. It also makes sense to hide the speaking indicators in spotlight layouts, I think, because this information is redundant to the spotlight tile.
This is because our layouts for flat windows are good at adapting to both small width and small height, while our layouts for narrow windows aren't so good at adapting to a small height.
If you were the only one in the call, you could get a broken-looking view in which the local tile is shown in the spotlight, and it's also shown in the PiP. This is redundant.
Due to an oversight of mine, 2440037639 actually removed the ability to see the one-on-one layout on mobile. This restores mobile one-on-one calls to working order and also avoids showing the spotlight tile unless there are more than a few participants.
If no one had spoken yet, we were still showing the local user in the spotlight. We should instead eagerly switch to showing an arbitrary remote participant in this case.
We've concluded that this behavior is actually more distracting than it is helpful, and we want to try out what it's like to just have the importance ordering and visual cues help you find who's speaking.
We're finding that if we reorder participants based on whether their mic is muted, this just creates a lot of distracting layout shifts. People who speak are automatically promoted into the speaker category, so there's little value in additionally caring about mute state.
Includes the mobile UX optimizations and the tweaks we've made to cut down on wasted space, but does not yet include the change to embed the spotlight tile within the grid.
Because we were hiding even the local participant during initial connection, there would be no participants, and therefore nothing to put in the spotlight. The designs don't really tell us what the connecting state should look like, so I've taken the liberty of restoring it to its former glory of showing the local participant immediately.
react-rxjs is the library we've been using to connect our React components to view models and consume observables. However, after spending some time with react-rxjs, I feel that it's a very heavy-handed solution. It requires us to sprinkle <Subscribe /> and <RemoveSubscribe /> components all throughout the code, and makes React go through an extra render cycle whenever we mount a component that binds to a view model. What I really want is a lightweight React hook that just gets the current value out of a plain observable, without any extra setup. Luckily the observable-hooks library with its useObservableEagerState hook seems to do just that—and it's more actively maintained, too!
Here I've implemented an MVP for the new unified grid layout, which scales smoothly up to arbitrarily many participants. It doesn't yet have a special 1:1 layout, so in spotlight mode and 1:1s, we will still fall back to the legacy grid systems.
Things that happened along the way:
- The part of VideoTile that is common to both spotlight and grid tiles, I refactored into MediaView
- VideoTile renamed to GridTile
- Added SpotlightTile for the new, glassy spotlight designs
- NewVideoGrid renamed to Grid, and refactored to be even more generic
- I extracted the media name logic into a custom React hook
- Deleted the BigGrid experiment
I discovered that this hook was calling complete on the returned observable almost immediately when it gets mounted. This caused the call view model to never know when the application was switching focuses. At first I thought this was just because I forgot to move the call to complete to the effect's clean-up function, but even with that changed, React still calls the effect twice in strict mode. So, let's just remove the call entirely.