Commit Graph

127 Commits

Author SHA1 Message Date
Timo K
7eb520a091 Add test: reproduce "ring does not stop" race.
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 16:09:26 +02:00
Timo K
5dfad5ec1e make ring$ a behavior and add code comments to justify/explain the change.
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 14:11:22 +02:00
Will Hunt
2374a3fd33 Prevent showing calling view when disconnected from Livekit. (#3491)
* Refactor disconnection handling

* Use "unknown"

* Update signature

* Add tests

* Expose livekitConnectionState directly

* fix whoopsie
2025-09-16 13:16:11 +00:00
Will Hunt
e201258af3 Add sounds for ringing (#3490)
* add wait for pickup overlay

Signed-off-by: Timo K <toger5@hotmail.de>

* refactor and leave logic

Signed-off-by: Timo K <toger5@hotmail.de>

* recursive play sound logic

Signed-off-by: Timo K <toger5@hotmail.de>

* review

Signed-off-by: Timo K <toger5@hotmail.de>

* text color

Signed-off-by: Timo K <toger5@hotmail.de>

* overlay styling and interval fixes

Signed-off-by: Timo K <toger5@hotmail.de>

* fix permissions and styling

Signed-off-by: Timo K <toger5@hotmail.de>

* fix always getting pickup sound

Signed-off-by: Timo K <toger5@hotmail.de>

* Add sound effects for declined,timeout and ringtone

* better ringtone

* Integrate sounds

* Ensure leave sound does not play

* Remove unused blocked sound

* fix test

* Improve tests

* Loop ring sound inside Audio context for better perf.

* lint

* better ringtone

* Update to delay ringtone logic.

* lint + fix test

* Tidy up ring sync and add comments.

* lint

* Refactor onLeave to take a sound so we don't need to repeat the sound

* fix import

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: Timo K <toger5@hotmail.de>
2025-09-15 15:41:15 +01:00
Robin
1e32b355ce Ignore decline events from the local user 2025-09-05 21:22:32 +02:00
Robin
2541f810fa Ensure that non-ringing notifications lead to a null pickup state 2025-09-05 14:36:27 +02:00
Robin
e9c43856d0 Merge branch 'toger5/waitForNotificationAnswer' into toger5/call-pickup-state-decline-event 2025-09-03 17:59:16 +02:00
Robin
1428df8567 Tentatively rename URL parameter to waitForCallPickup 2025-09-03 16:52:40 +02:00
Robin
880e07c07f Tidy some things up, refactor dialing/ringing behaviors 2025-09-03 16:51:31 +02:00
Robin
07522d6704 Remove unnecessary casts 2025-09-03 13:03:48 +02:00
Timo K
7724cbf9be fix tests
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 19:21:27 +02:00
Timo K
fe65c1f4da fix decline event type
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 19:07:52 +02:00
Timo K
a91c71a8e4 types
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 18:36:23 +02:00
Timo K
e30142a43b Add decline logic and tests
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 18:36:23 +02:00
Timo K
fb8de061f3 rename to callPickupState
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-25 14:31:14 +02:00
Timo K
e475f56af5 waitForNotificationAnswer
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-25 14:11:10 +02:00
fkwp
482e2f8f6f Refine MatrixRTC connection wording (#3463) 2025-08-22 12:34:18 +02:00
Robin
44ddb40eea Iterate in pairing session 2025-08-20 20:47:20 +02:00
Robin
5b8839b577 Pause hand raise updates while in 'reconnecting' state 2025-08-20 19:08:44 +02:00
Robin
33bf63d8d2 Disable a bunch of media/event sources when reconnecting 2025-08-20 18:51:03 +02:00
Robin
a7cc11ac81 Merge branch 'livekit' into reconnecting 2025-08-20 14:13:03 +02:00
Robin
5d0289f3c9 Show 'reconnecting' message when session warns we've hit a timeout
By using the new 'probablyLeft' state provided by MatrixRTCSession.
2025-08-20 13:34:41 +02:00
Robin
3da9013426 Show 'reconnecting' message when disconnected from LiveKit 2025-08-20 13:34:36 +02:00
Robin
1a1e5a9db8 Show 'reconnecting' message when sync loop is disconnected
With this change I'm also taking care to not show the standard "Connection to the server has been lost" banner in the call view, since that is now covered by the 'reconnecting' message.
2025-08-20 13:34:26 +02:00
Robin
f08ae36f9e Pause media tracks and show a message when reconnecting to MatrixRTC 2025-08-15 18:38:52 +02:00
Robin
dc789e63f2 Avoid using the deprecated 'room' field on MatrixRTCSession 2025-08-15 18:32:37 +02:00
Robin
0ed47c2588 Merge branch 'livekit' into robin/switch-camera-tile 2025-08-14 16:39:08 +02:00
Timo
a733461845 Hangup when last person in call (based on url params) (#3372)
* Introduce condigurable auto leave option

* Read url params for auto leave

* add tests

* rename url param to `autoLeave`

* lint

Signed-off-by: Timo K <toger5@hotmail.de>

* fix scope in CallViewModel tests

Signed-off-by: Timo K <toger5@hotmail.de>

* use auto leave in DM case

Signed-off-by: Timo K <toger5@hotmail.de>

* Make last once leave logic based on matrix user id (was participant id before)

Signed-off-by: Timo K <toger5@hotmail.de>

* add test for multi device auto leave

Signed-off-by: Timo K <toger5@hotmail.de>

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-08 17:15:47 +02:00
Timo
6f0ffa84dc Merge branch 'livekit' into robin/behaviors 2025-07-14 19:03:18 +02:00
Timo
8458d198c9 Fix bluetooth iOS issue (device auto switches from Bluetooth to speaker) (#3388)
* fix ios bluetooth

Signed-off-by: Timo K <toger5@hotmail.de>

* fix lints

Signed-off-by: Timo K <toger5@hotmail.de>

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-07-14 12:53:09 +02:00
Robin
c34516e871 Use the initialValue parameter of 'behavior' instead of startWith 2025-07-12 00:34:52 -04:00
Robin
2b76d3dd70 Move 'behavior' to be a method on ObservableScope 2025-07-12 00:34:52 -04:00
Robin
32bf1c30d2 Use Behaviors even more consistently 2025-07-11 23:53:59 -04:00
Timo
434712ba17 fixing some tests 2025-07-11 00:27:46 -04:00
Robin
b3863748dc Replace many usages of useObservableEagerState with useBehavior
This hook is simpler in its implementation (therefore hopefully more correct & performant) and enforces a type-level distinction between raw Observables and Behaviors.
2025-07-11 00:24:46 -04:00
Robin
35ed313577 Replace ObservableScope.state with Observable.behavior 2025-07-10 23:57:33 -04:00
Robin
0c194617a3 Add camera switching to the media view model 2025-07-10 15:29:39 -04:00
Robin
7c5336fc40 Remove the switch camera button 2025-07-10 15:29:38 -04:00
Robin
f509c06cc6 Earpiece switcher and overlay (#3347)
* Add a global control for toggling earpiece mode

This will be used by Element X to show an earpiece toggle button in the header.

* Add an earpiece overlay


* Fix header
The header needs to be passed forward as a string to some components and as a bool (hideHeader) to others.
Also use a enum instead of string options.

* fix top clipping with header


* hide app bar in pip

* revert android overlay app_bar

* Modernize AppBarContext

* Style header icon color as desired and switch earpice/speaker icon

* fix initial selection when using controlled media

* Add "Back to video" button

* fix tests

* remove dead code

* add snapshot test

* fix back to video button

* Request capability to learn the room name

We now need the room name in order to implement the mobile (widget-based) designs with the app bar.

* Test the CallViewModel output switcher directly

---------

Co-authored-by: Timo <toger5@hotmail.de>
2025-06-26 11:08:57 +02:00
Timo
adb5934f0b temp 2025-03-13 17:51:41 -04:00
Timo
c9f2a1c943 Reduce redundant calculations of display name map (#3062)
* Use share() on fromEvent() so that we multiplex subscribers onto the event emitter

* .

* .

* Comment

* Comment

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-03-07 10:18:28 +00:00
Hugh Nimmo-Smith
0f5dc33918 Fix copyright header to say dual license not just AGPL (#3013)
This probably should have been part of https://github.com/element-hq/element-call/pull/2984
2025-02-18 17:59:58 +00:00
Will Hunt
1dde54daa9 Use matrixIdentifier for screenshare (#2981) 2025-02-03 10:17:19 +00:00
Will Hunt
0f2e67dd60 Disambiguate displaynames (#2918)
* Disambigute displaynames

* Add test

* fixup test functions

* prettier

* lint

* Split displayname utils into own file and add tests.

* Split out fixtures

* Add more testcases for displayname calculation.

* lint

* Also listen for displayname changes. (I stand corrected!)

* fix missing media tiles on missing member
2025-01-14 14:46:39 +00:00
Will Hunt
abf2ecd521 Refactor reactions / hand raised to use rxjs and start ordering tiles based on hand raised. (#2885)
* Add support for using CallViewModel for reactions sounds.

* Drop setting

* Convert reaction sounds to call view model / rxjs

* Use call view model for hand raised reactions

* Support raising reactions for matrix rtc members.

* Tie up last bits of useReactions

* linting

* Update calleventaudiorenderer

* Update reaction audio renderer

* more test bits

* All the test bits and pieces

* More refactors

* Refactor reactions into a sender and receiver.

* Fixup reaction toggle button

* Adapt reactions test

* Tests all pass.

* lint

* fix a couple of bugs

* remove unused helper file

* lint

* finnish notation

* Add tests for useReactionsReader

* remove mistaken vitest file

* fix

* filter

* invert

* fixup tests with fake timers

* Port useReactionsReader hook to ReactionsReader class.

* lint

* exclude some files from coverage

* Add screen share sound effect.

* cancel sub on destroy

* tidy tidy
2024-12-19 15:54:28 +00:00
Will Hunt
7d00f85abc Add screen share sound effect. (#2917) 2024-12-19 12:37:10 +00:00
Hugh Nimmo-Smith
79c40f198c Use finnish notation for observables (#2905)
To help make our usage of the observables more readable/intuitive.
2024-12-17 04:01:56 +00:00
Robin
25d0338f35 Skip some redundant updates to the grid and spotlight
While debugging our layout shift issue I learned that a single change to the sort order of the participants can cause 3 or 4 redundant emissions of the same items in the same order. Since each of these would cause React to re-render the grid, skipping these spurious emissions seems like an easy performance win.
2024-12-13 16:40:20 -05:00
Hugh Nimmo-Smith
a723f10d2c Developer setting to show LiveKit participants that do not have MatrixRTC sessions a.k.a. non-member tiles (#2771)
* make tiles based on rtc member

* display missing lk participant + fix tile multiplier

* add show_non_member_participants config option

* per member tiles

* merge fixes

* linter

* linter and tests

* tests

* adapt tests (wip)

* Remove unused keys

* Fix optionality of nonMemberItemCount

* video is optional

* Mock RTC members

* Lint

* Merge fixes

* Fix user id

* Add explicit types for public fields

* isRTCParticipantAvailable => isLiveKitParticipantAvailable

* isLiveKitParticipantAvailable

* Readonly

* More keys removal

* Make local field based on view model class not observable

* Wording

* Fix RTC members in tes

* Tests again

* Lint

* Disable showing non-member tiles by default

* Duplicate screen sharing tiles like we used to

* Lint

* Revert function reordering

* Remove throttleTime from bad merge

* Cleanup

* Tidy config of show non-member settings

* tidy up handling of local rtc member in tests

* tidy up test init

* Fix mocks

* Cleanup

* Apply local override where participant not yet known

* Handle no visible media id

* Assertions for one-on-one view

* Remove isLiveKitParticipantAvailable and show via encryption status

* Handle no local media (yet)

* Remove unused effect for setting

* Tidy settings

* Avoid case of one-to-one layout with missing local or remote

* Iterate

* Remove option to show non-member tiles to simplify code review

* Remove unused code

* Remove more remnants of show-non-member-tiles

* iterate

* back

* Fix unit test

* Refactor

* Expose TestScheduler as global

* Fix incorrect type assertion

* Simplify speaking observer

* Fix

* Whitespace

* Make it clear that we are mocking MatrixRTC memberships

* Test case for only showing tiles for MatrixRTC session members

* Simplify diff

* Simplify diff

These changes are in https://github.com/element-hq/element-call/pull/2809

* .

* Whitespaces

* Use asObservable when exposing subject

* Show "waiting for media..." when no participant

* Additional test case

* Don't show "waiting for media..." in case of local participant

* Make the loading state more subtle
 - instead of a label we show a animated gradient

* Use correct key for matrix rtc foci in code comment. (#2838)

* Update src/tile/SpotlightTile.tsx

Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>

* Update src/state/CallViewModel.ts

Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>

* Make the purpose of BaseMediaViewModel.local explicit

* Use named object instead of unnamed array for spotlightAndPip

* Refactor spotlightAndPip into spotlight and pip

* Use if statement instead of ternary for readability in spotlight and pip logic

* Review feedback

* Fix tests for CallEventAudioRenderer

* Lint

* Developer setting to show non-member tiles

This is based on top of https://github.com/element-hq/element-call/pull/2701

* Lint

* Remove unused code

* Remove changes that should be in https://github.com/element-hq/element-call/pull/2858

* Update src/state/CallViewModel.test.ts

Co-authored-by: Robin <robin@robin.town>

* Merge branch 'livekit' into toger5/show-non-member-tiles

* Remove unused nonMemberItemCount

* Restore default showNonMemberTiles value after test

* Update comments

---------

Co-authored-by: Timo <toger5@hotmail.de>
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
Co-authored-by: Robin <robin@robin.town>
2024-12-13 14:53:08 +00:00
Robin
00056a7cd9 Determine which tiles are on screen in a more stable manner
Instead of tracking for each individual tile whether it's visible, just track the total number of tiles that appear on screen. This ought to make the whole thing a lot less dynamic, which is crucial given that our UI renders asynchronously and RxJS doesn't really support cyclic dependencies in any rigorous way.

In particular this ought to make the following kind of situation impossible:
1. There 3 tiles, ABC. A and B are on screen.
2. Now C becomes important. The requested order is now CAB.
3. To reduce the size of the layout shift, the algorithm selects to swap just B and C in the original order, giving ACB. However, the UI is blocked and doesn't render this order yet.
4. For whatever reason, a spurious update of the importance algorithm occurs. It once again requests CAB.
5. Now because the UI was blocked, the layout still thinks that A and B are on screen (rather than A and C). It thinks that C is some weird island of "off-screen territory" in the middle of the tile order. This confuses it into swapping A and C rather than keeping the layout stable.

The reality is that whenever we think N tiles are visible on screen, we're always referring to the first N tiles in the grid. It's best if the code reflects this assumption.
2024-12-12 18:00:59 -05:00