Commit Graph

69 Commits

Author SHA1 Message Date
Hugh Nimmo-Smith
fbc2cd3e97 Remove redundant distinctUntilChanged (#2804)
Because this.scope.state() does this for us
2024-11-20 10:31:36 +00:00
Hugh Nimmo-Smith
6e5c468780 Use more explicit names and types for LayoutMedia observables (#2781) 2024-11-14 14:23:50 +01:00
Robin
50d380cf37 Make one-on-one layout less prone to crashing
The basic issue here, I think, was that the 'oneOnOne' observable flag and the 'onOnOneLayout' observable could become out of sync, as RxJS does *not* have atomicity guarantees. We can work around this by combining them into one observable.
2024-11-11 08:25:16 -05:00
Robin
68d71a8329 Improve interactions to hide/show the footer
This fixes a few different usability issues with the footer:

- When tapping one of the footer buttons, the footer would be dismissed rather than activating the button.
- When the footer was hidden, you could still tap the buttons.
- Interacting with controls in the footer would not reset the timer that hides it, leading to a feeling that the footer can disappear out from under you.
2024-11-08 12:52:55 -05:00
Hugh Nimmo-Smith
c45f724279 Show encryption key status from LiveKit (#2700)
* Refactor to make encryption system available in view models

* WIP show encryption errors from LiveKit

* Missing CSS

* Show encryption status based on LK and RTC

* Lint

* Lint

* Fix tests

* Update wording

* Refactor

* Lint
2024-11-06 11:12:46 +00:00
Robin
d3f069e763 Keep tiles in a stable order (#2670)
* Keep tiles in a stable order

This introduces a new layer of abstraction on top of MediaViewModel: TileViewModel, which gives us a place to store data relating to tiles rather than their media, and also generally makes it easier to reason about tiles as they move about the call layout. I have created a class called TileStore to keep track of these tiles.

This allows us to swap out the media shown on a tile as the spotlight speaker changes, and avoid moving tiles around unless they really need to jump between the visible/invisible regions of the layout.

* Don't throttle spotlight updates

Since we now assume that the spotlight and grid will be in sync (i.e. an active speaker in one will behave as an active speaker in the other), we don't want the spotlight to ever lag behind due to throttling. If this causes usability issues we should maybe look into making LiveKit's 'speaking' indicators less erratic first.

* Make layout shifts due to a change in speaker less surprising

Although we try now to avoid layout shifts due to the spotlight speaker changing wherever possible, a spotlight speaker coming from off screen can still trigger one. Let's shift the layout a bit more gracefully in this case.

* Improve the tile ordering tests

* Maximize the spotlight tile in portrait layout

* Tell tiles whether they're actually visible in a more timely manner

* Fix test

* Fix speaking indicators logic

* Improve readability of marbles

* Fix test case

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2024-11-06 09:36:48 +00:00
Robin
98c199d1cf Merge pull request #2690 from robintown/spotlight-speaking
Show speaking indicators in spotlight during screen sharing
2024-11-04 12:36:58 -05:00
Robin
b903e11cfc Fix lint error 2024-11-04 10:56:29 -05:00
Hugh Nimmo-Smith
f2ed07c258 Refactor to make encryption system available in view models (#2702) 2024-11-04 09:11:44 +00:00
Robin
8c0280954c Add a button to switch the camera on mobile 2024-11-01 16:00:34 -04:00
Robin
42be187182 Explain why speaking indicators are hidden 2024-11-01 11:25:55 -04:00
Robin
3a706ea3e0 Show speaking indicators in spotlight during screen sharing 2024-10-28 14:45:06 -04:00
Robin
339a98d1e1 Don't cause the local tile to disappear when joining
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 :)
2024-10-24 17:20:56 -04:00
Robin
156f1e3a10 Merge branch 'livekit' into test-call-vm 2024-09-18 22:37:15 -04:00
Robin
016ba676dd Test CallViewModel
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.)
2024-09-12 15:53:13 -04:00
Robin
ca135d471e React more actively to changes in room membership 2024-09-11 01:27:24 -04:00
Timo
c3edd3e25e Enable lint rules for Promise handling to discourage misuse of them. (#2607)
* 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>
2024-09-10 09:49:35 +02:00
fkwp
9add3e52c4 Update file headers copyright and change licence to AGPL-3.0-only 2024-09-06 10:22:13 +02:00
Robin
5eaabcf74d Clean up our tests in preparation for the testing sprint (#2466)
* 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>
2024-08-27 15:45:39 +02:00
Robin
3a754479dc Add simple global controls to put the call in picture-in-picture mode (#2573)
* 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
2024-08-27 13:47:20 +02:00
Robin
ed99af0be6 Improve readability 2024-08-09 13:38:59 -04:00
Robin
52058716f6 Don't keep someone in the spotlight if they've left the call 2024-08-09 13:08:37 -04:00
Robin
29df87d22c Merge pull request #2548 from robintown/hide-controls
Show controls on tap/hover on small screens
2024-08-09 11:52:01 -04:00
Robin
6443e911dc Make the breakpoint a bit smaller 2024-08-09 11:09:45 -04:00
Robin
aa6b7056ae Show controls on tap/hover on small screens
This changes the mobile landscape view to automatically hide the controls, giving more visibility to the video underneath, and show them on tap/hover.
2024-08-09 11:09:45 -04:00
Robin
c20737ba4c Merge pull request #2546 from robintown/spotlight-duplication
Avoid duplicating the video of someone in the spotlight
2024-08-09 09:11:13 -04:00
Robin
5069b008e2 Avoid duplicating the video of someone in the spotlight
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.
2024-08-08 12:16:32 -04:00
Robin
6d8e45aea8 Consider any sufficiently short window 'flat'
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.
2024-08-08 11:30:57 -04:00
Robin
bf5128cfee Don't show local media on top of itself
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.
2024-08-06 17:12:13 -04:00
Robin
f4cf3d8c62 Adjust the breakpoint 2024-08-06 10:08:56 -04:00
Robin
eb051ab318 Replace the mobile one-on-one layout with an edge-to-edge spotlight 2024-08-01 13:49:49 -04:00
Robin
942e28f3c2 Improve the layouts on small mobile calls
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.
2024-08-01 13:49:49 -04:00
Robin
0bfec65405 Refactor layout selection into smaller chunks 2024-08-01 13:49:49 -04:00
Robin
5a0b81b57f More strongly prefer putting a remote speaker in the spotlight
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.
2024-08-01 12:48:47 -04:00
Robin
a3ce333352 Only show the expand button in spotlight layout (#2510)
It has no effect in any layout other than spotlight, and we've decided to hide it rather than spending effort to make it do something.
2024-07-26 12:57:49 +02:00
Robin
d5faa5ea90 Don't show the speaker in the spotlight in large grids (#2511)
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.
2024-07-26 12:51:34 +02:00
Robin
5becd2e175 Fix a crash when using the duplicate tiles option (#2512) 2024-07-26 12:51:09 +02:00
Robin
d062871f41 Don't consider microphone mute state in importance ordering (#2515)
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.
2024-07-26 11:27:22 +02:00
Robin
4955535374 Use more consistent names for layout types 2024-07-18 11:24:18 -04:00
Robin
0664f978e3 Merge branch 'new-call-layouts' into rest-of-the-layouts 2024-07-18 11:21:56 -04:00
Robin
b4e0df75c0 Merge branch 'new-call-layouts' into one-on-one-layout 2024-07-18 10:28:17 -04:00
Robin
d561a41666 Merge pull request #2416 from robintown/grid-spotlight-speaker
Show speaker in the spotlight in large grids
2024-07-18 10:17:31 -04:00
Robin
e04affe93e Justify the use of a participant count threshold 2024-07-18 10:00:26 -04:00
Robin
7fcd7125c1 Merge branch 'new-call-layouts' into spotlight-layout 2024-07-18 08:48:50 -04:00
Robin
1efa594430 Use Array.some where it's appropriate 2024-07-17 16:06:48 -04:00
Robin
0a8c6c1454 Merge branch 'new-call-layouts' into observable-hooks 2024-07-17 15:55:50 -04:00
Robin
d4a2617f7b Merge pull request #2380 from robintown/pin-always-show
Add toggle to always show yourself
2024-07-17 15:45:29 -04:00
Robin
2bc56dbff2 Use fewer ML-style variable names 2024-07-17 15:40:02 -04:00
Robin
a59875dab5 Explain what each sorting bin means 2024-07-17 15:37:41 -04:00
Robin
2440037639 Implement most of the remaining layout changes
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.
2024-07-12 15:50:17 -04:00