Commit Graph

55 Commits

Author SHA1 Message Date
Valere
c3c0516f0d Lint: fix all the lint errors 2025-10-07 16:00:59 +02:00
Timo K
68aae4a8e3 fix another rename + another js-sdk bump
Signed-off-by: Timo K <toger5@hotmail.de>
2025-10-02 11:23:11 +02:00
Robin
4980d8a622 Merge branch 'livekit' into voip-team/rebased-multiSFU 2025-09-25 18:40:59 -04:00
Will Hunt
d24da1859e Add media hints for notification events. (#3493)
* Add media hints for notification events.

* Prevent showing calling view when disconnected from Livekit. (#3491)

* Refactor disconnection handling

* Use "unknown"

* Update signature

* Add tests

* Expose livekitConnectionState directly

* fix whoopsie

* Update dependency livekit-client to v2.15.7 (#3496)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Fix the interactivity of buttons while reconnecting or in earpiece mode (#3486)

* Fix the interactivity of buttons while reconnecting or in earpiece mode

When we're in one of these modes, we need to ensure that everything above the overlay (the header and footer buttons) is interactive, while everything obscured by the overlay (the media tiles) is non-interactive and removed from the accessibility tree. It's not a very easy task to trap focus *outside* an element, so the best solution I could come up with is to set tabindex="-1" manually on all interactive elements belonging to the media tiles.

* Write a Playwright test for reconnecting

* fix lints

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

* fix test

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

* enable http2 for matrx-rtc host to allow the jwt service to talk to the SFU

* remove rate limit for delayed events

* more time to connect to livekit SFU

* Due to a Firefox issue we set the start anchor for the tab test to the Mute microphone button

* adapt to most recent Element Web version

* Use the "End call" button as proofe for a started call

* Currrenty disabled due to recent Element Web
- not indicating the number of participants
- bypassing Lobby

* linting

* disable 'can only interact with header and footer while reconnecting' for firefox

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
Co-authored-by: Timo K <toger5@hotmail.de>
Co-authored-by: fkwp <github-fkwp@w4ve.de>

* Log when a track is unpublished or runs into an error (#3495)

* default mute states (unmuted!) in widget mode (embedded + intent) (#3494)

* default mute states (unmuted!) in widget mode (embedded + intent)

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

* review

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

* introduce a cache for the url params.

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

* Add an option to skip the cache.

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

---------

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

* Apply new hint code

* missed a bit

* fix intent

* Automatically update intent on mute change

* update packages

* lint

* Fix tests

* fix merge fails

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robin <robin@robin.town>
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
Co-authored-by: Timo K <toger5@hotmail.de>
Co-authored-by: fkwp <github-fkwp@w4ve.de>
2025-09-25 13:02:43 +01:00
Timo K
6b44f3b008 a tiny bit of tests lint fixes.
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-23 12:25:31 +02:00
Timo K
d9fe31039f start fixing CallViewModel tests.
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 18:01:45 +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
e30142a43b Add decline logic and tests
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 18:36:23 +02:00
Robin
7ba4df7781 Test sync loop status and membership status in reconnection test as well 2025-08-22 18:15:21 +02:00
Robin
44ddb40eea Iterate in pairing session 2025-08-20 20:47:20 +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
db59679ad4 Allow the local participant's RTC membership to be absent in tests 2025-08-15 20:18:21 +02:00
Robin
f08ae36f9e Pause media tracks and show a message when reconnecting to MatrixRTC 2025-08-15 18:38:52 +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
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
Robin
586a923be3 Fix remaining tests 2025-07-11 23:53:31 -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
5e2e94d794 Refactor media devices to live outside React as Observables (#3334)
* Refactor media devices to live outside React as Observables

This moves the media devices state out of React to further our transition to a MVVM architecture in which we can more easily model and store complex application state. I have created an AppViewModel to act as the overarching state holder for any future non-React state we end up creating, and the MediaDevices reside within this. We should move more application logic (including the CallViewModel itself) there in the future.

* Address review feedback

* Fixes from ios debugging session: (#3342)

- dont use preferred vs selected concept in controlled media. Its not needed since we dont use the id for actual browser media devices (the id's are not even actual browser media devices)
  - add more logging
  - add more conditions to not accidently set a deviceId that is not a browser deviceId but one provided via controlled.

---------

Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2025-06-20 18:37:25 +02:00
Robin
b0587fcfb3 Avoid reactivity bugs in how we track external state (#3316)
* Avoid reactivity bugs in how we track external state

Many of our hooks which attempt to bridge external state from an EventEmitter or EventTarget into React had subtle bugs which could cause them to fail to react to certain updates. The conditions necessary for triggering these bugs are explained by the tests that I've included.

In the majority of cases, I don't think we were triggering these bugs in practice. They could've become problems if we refactored our components in certain ways. The one concrete case I'm aware of in which we actually triggered such a bug was the race condition with the useRoomEncryptionSystem shared secret logic (addressed by a1110af6d5).

But, particularly with all the weird reactivity issues we're debugging this week, I think we need to eliminate the possibility that any of the bugs in these hooks are the cause of our current headaches.

* Reuse useTypedEventEmitterState in useLocalStorage

* Fix type error
2025-06-05 13:54:57 +02:00
Timo
b5fe55aef2 Add custom audio renderer for iPhone earpiece and only render joined participants (#3249)
* Add custom audio renderer to only render joined participants & add ios earpice workaround

fix left right to match chromium + safari
(firefox is swapped)

earpice as setting

Simpler code and documentation
The doc explains, what this class actually does and why it is so complicated.

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

use only one audioContext, remove (non working) standby fallback

* Add tests

* use optional audio context and effect to initiate it + review
2025-05-15 20:46:39 +02:00
Timo
e6710f72e3 Fix to-device encryption info label (#3208)
* Fix to-device encryption info label
The label was shown also without checking that we use PerParticipantE2EE. Which is a prerequisite for toDevice transport. As a result the label was shown when not desired.

* rename: useLiveKit -> useLivekit

* make the settings naming consistent
2025-05-13 22:05:55 +02:00
Robin
33700d1529 Merge branch 'livekit' into toger5/src-to-lib-import 2025-03-27 14:35:08 -04:00
Robin
9a5dd10e27 Show errors that occur in GroupCallView using the error boundary
We were previously using the useGroupCallErrorBoundary hook to surface errors that happened during joining, but because that part is outside the GroupCallErrorBoundary it just ended up sending them to the app-level error boundary where they got displayed with a more generic message.
2025-03-21 14:59:27 -04:00
Hugh Nimmo-Smith
6043b3949b Analytics configuration is the responsibility of the host application when running in widget mode (#3089)
* Support for analytics configuration via URL parameters in widget mode

Adds:

- posthogApiHost
- posthogApiKey
- rageshakeSubmitUrl
- sentryDsn
- sentryEnvironment

Deprecate analyticsId and use posthogUserId instead

* Partial test coverage

* Simplify tests

* More tests

* Lint

* Split embedded only parameters into own section for clarity

* Update docs/url-params.md

* Update docs/url-params.md

* Update vite.config.js
2025-03-21 11:15:20 +01:00
Timo
adb5934f0b temp 2025-03-13 17:51:41 -04:00
Robin
a75952cf77 Send a 'close' action when the widget is ready to close
By keeping 'hangup' and 'close' as separate actions, we can allow Element Call widgets to stay on an error screen after the user has been disconnected without the widget completely disappearing from the host's UI. We don't have to request any additional capabilities to use a custom widget action like this one.
2025-02-20 11:17:17 +07: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
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
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
Will Hunt
77facd01e4 Add support for playing a sound when the user exits a call. (#2860)
* Refactor to use AudioContext

* Remove unused audio format.

* Reduce update frequency for volume

* Port to useAudioContext

* Port reactionaudiorenderer to useAudioContext

* Integrate raise hand sound into call event renderer.

* Simplify reaction sounds

* only play one sound per reaction type

* Start to build out tests

* fixup tests / comments

* Fix reaction sound

* remove console line

* Remove another debug line.

* fix lint

* Use testing library click

* lint

* Add support for playing a sound when the user exits a call.

* Port GroupCallView to useAudioContext

* Remove debug bits.

* asyncify

* lint

* lint

* lint

* tidy

* Add test for group call view

* Test widget mode too.

* fix ?.

* Format

* Lint

* Lint

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2024-12-12 07:33:47 +00:00
Hugh Nimmo-Smith
0087e37f30 Enable @typescript-eslint/consistent-type-imports lint rule (#2886)
* Enable @typescript-eslint/consistent-type-imports lint rule

This is to help ensure that we get proper vite/rollup lazy loading by not `import`ing more than we need to.

Revert "Enable @typescript-eslint/consistent-type-imports lint rule"

This reverts commit ba385fa00b7e410cc508fd5fb9fe972233ae114f.

Enable @typescript-eslint/consistent-type-imports lint rule

This is to help ensure that we get proper vite/rollup lazy loading by not `import`ing more than we need to.

.

* Format
2024-12-11 09:27:55 +00:00
Will Hunt
a8a95c3f00 Ensure call sound effects are played over the correct sink (#2863)
* Refactor to use AudioContext

* Remove unused audio format.

* Reduce update frequency for volume

* Port to useAudioContext

* Port reactionaudiorenderer to useAudioContext

* Integrate raise hand sound into call event renderer.

* Simplify reaction sounds

* only play one sound per reaction type

* Start to build out tests

* fixup tests / comments

* Fix reaction sound

* remove console line

* Remove another debug line.

* fix lint

* Use testing library click

* lint

* fix a few things

* Change the way we as unknown the mock RTC session.

* Lint

* Fix types for MockRTCSession

* value change should always be set

* Update volume slider description.

* Only load reaction sound effects if enabled.

* cache improvements

* lowercase soundMap

* lint

* move prefetch sounds to fix hot reload

* correct docs

* add a header

* Wording change

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2024-12-09 11:39:16 +00:00
Timo
43c81a2758 Make video tiles be based on MatrixRTC member not LiveKit participants (#2701)
* 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

* Revert "Make the loading state more subtle"

This reverts commit 765f7b4f31.

* Update src/state/CallViewModel.ts

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

* Fix spelling

* Remove a non-null assertion that failed at runtime

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
2024-12-06 11:28:37 +00:00
Will Hunt
ea6f2952af Add sound effect for call joined / left (#2794)
* Add renderer for call joined / left

* lint

* Add new sounds

* Updates sounds in renderer

* lint

* move import

* pad sounds with silence

* lint

* tidy

* Drop autoplay since we now subscribe correctly.

* Comitting test files I am going to be going to lunch so will tidy up in a little while.

* finish up tests

* Add support for multiple channels per sound.

* lint
2024-12-02 15:16:58 +00:00
Timo
28da8c48da Mute state improvements including muting if skipLobby=true in SPA (Based on #2834) (#2846) 2024-11-28 18:05:12 +01:00
Hugh Nimmo-Smith
3885eefa4c Disambiguate between types of "member" (#2807)
We have Matrix room members and MatrixRTC session memberships. Livekit also has rooms.

So, this attempts to make it more obvious as to what type you are referring to.
2024-11-21 11:02:05 +00:00
Hugh Nimmo-Smith
64749d0b7a Expose TestScheduler as global (#2796) 2024-11-18 22:39:59 +00: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
Hugh Nimmo-Smith
f2ed07c258 Refactor to make encryption system available in view models (#2702) 2024-11-04 09:11:44 +00:00
Robin
4aab6cfe4e Leave an open question about whether to move test utils 2024-09-18 23:10:30 -04:00
Robin
25193f467a Factor out repeated event emitter mocks 2024-09-18 23:05:31 -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
e8278b4ed2 Merge branch 'livekit' into test-components 2024-09-10 18:05:22 -04:00