Hugh pointed out that the button labeled "Join call now" on this screen is misleading, because it does not join you to the call but rather send you to the lobby. Meanwhile, the designs call for this screen to use the words "Join as guest" and "Continue", so let's go with that.
Before you're connected to the SFU the local participant object will have the empty string as its ID. This changes to your actual ID once you've connected. Apparently I tried to fix this by forcing the local ID to always be the string 'local' but then I just forgot to use it correctly :)
Previously, dragging it all the way to the left would *not* mute the participant but rather bottom out at 10% volume, and people have found this unintuitive. Let's make it less silly by giving the slider a range of 0% to 100%, and making the mute toggle button have the same effect as dragging the slider to zero. When unmuting, it will reset to the last non-zero "committed" volume, similar to how the volume sliders in desktop environments work.
* Handle case of encryption key for an index to be undefined
As per https://github.com/matrix-org/matrix-js-sdk/pull/4423 the key can be undefined and so we should handle this rather than waiting for SubtleCrypto.importKey() to fail.
* Use release version of matrix-js-sdk
Diff is baa6d13506...v34.7.0
* Use RTCSession. reemitEncryptionKeys()
* Add some test coverage whilst we are here
* Add some test coverage whilst we are here
* Lint
This adds tests for a couple of the less trivial bits of code in CallViewModel. Testing them helped me uncover why focus switches still weren't being smooth! (It was because I was using RxJS's sample operator when I really wanted withLatestFrom.)
Catching two accessibility issues along the way: we were putting the wrong accessible labels on the 'expand' button, and even the off-screen pages of the spotlight tile were being exposed to accessibility technologies rather than hidden.
* Enable lint rules for Promise handling to discourage misuse of them.
Squashed all of Hugh's commits into one.
---------
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
I had experimented with turning this off in order to improve test performance, and apparently that ended up being merged. Now if we're to do component testing, we'll be changing things globally on the document, so isolation is very much necessary.
We were relying on deprecated APIs that are not supported when using Rust crypto. Since this entire file was copied and pasted from matrix-react-sdk originally, I just copied and pasted some of its more recent code in.
* Fix for missing client store (caused by: #2587)
* Fix interactive login with authenticated guest user.
Fix clearing storage before logging in a new account.
This was the result of me playing around with RxJS marble testing to understand how to get things done with its TestScheduler. I discovered that it lacks a clear way to fire arbitrary actions during the test, so I built a small helper function called schedule which does this for us.
We need to be consistent about whether we import matrix-js-sdk from `src` or
`lib`, otherwise we get two copies of matrix-js-sdk, and everything explodes.
* Fix issues detected by Knip
Including cleaning up some unused code and dependencies, using a React hook that we unintentionally stopped using, and also adding some previously undeclared dependencies.
* Replace remaining React ARIA components with Compound components
* fix button position
* disable scrollbars to resolve overlapping button
---------
Co-authored-by: Timo <toger5@hotmail.de>
* Install Knip
* Clarify an import that was confusing Knip
* Fix issues detected by Knip
Including cleaning up some unused code and dependencies, using a React hook that we unintentionally stopped using, and also adding some previously undeclared dependencies.
* Run dead code analysis in lint script and CI
---------
Co-authored-by: Timo <toger5@hotmail.de>
* Fix coverage reporting
Codecov hasn't been working recently because Vitest doesn't report coverage by default.
* Suppress some noisy log lines
Closes https://github.com/element-hq/element-call/issues/686
* Store test files alongside source files
This way we benefit from not having to maintain the same directory structure twice, and our linters etc. will actually lint test files by default.
* Stop using Vitest globals
Vitest provides globals primarily to make the transition from Jest more smooth. But importing its functions explicitly is considered a better pattern, and we have so few tests right now that it's trivial to migrate them all.
* Remove Storybook directory
We no longer use Storybook.
* Configure Codecov
Add a coverage gate for all new changes and disable its comments.
* upgrade vitest
---------
Co-authored-by: Timo <toger5@hotmail.de>
* Stop sharing state observables when the view model is destroyed
By default, observables running with shareReplay will continue running forever even if there are no subscribers. We need to stop them when the view model is destroyed to avoid memory leaks and other unintuitive behavior.
* Hydrate the call view model in a less hacky way
This ensures that only a single view model is created per call, unlike the previous solution which would create extra view models in strict mode which it was unable to dispose of. The other way was invalid because React gives us no way to reliably dispose of a resource created in the render phase. This is essentially a memory leak fix.
* Add simple global controls to put the call in picture-in-picture mode
Our web and mobile apps (will) all support putting calls into a picture-in-picture mode. However, it'd be nice to have a way of doing this that's more explicit than a breakpoint, because PiP views could in theory get fairly large. Specifically, on mobile, we want a way to do this that can tell you whether the call is ongoing, and that works even without the widget API (because we support SPA calls in the Element X apps…)
To this end, I've created a simple global "controls" API on the window. Right now it only has methods for controlling the picture-in-picture state, but in theory we can expand it to also control mute states, which is current possible via the widget API only.
* Fix footer appearing in large PiP views
* Add a method for whether you can enter picture-in-picture mode
* Have the controls emit booleans directly
The buttons were scrolling with the view instead of always being visible in a fixed location on the tile, and the indicators were not adopting the correct width.
The code path for when all tiles can fit on screen was failing to realize that it could sometimes get by with fewer columns. This resulted in wasted space for 4 person calls at some window sizes.
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.