Commit Graph
28 Commits
Author SHA1 Message Date
Johannes Marbach 3c88d217f2 Merge pull request #4244 from element-hq/matthew/default-output-first
Prefer the browser default audio output when no output has been chosen
2026-09-16 15:39:12 +02:00
Matthew Hodgson 426acd222e Prefer the browser default audio output when no output has been chosen
On browsers without a "default" pseudo-device (Firefox, Safari), the
virtual default output entry was appended after the physical devices, so
with no saved preference EC selected the first physical device and pinned
every remote audio element to it with setSinkId. Pinned sinks are not
re-routed by the browser: on Firefox/Linux a Bluetooth headset switching
from A2DP to HFP when its microphone is opened (i.e. on unmute) destroys
the pinned sink and all remote audio goes silent, with no error and no
fallback (rageshake 17320).

List the virtual default first so it is the fallback both when nothing was
chosen and when the chosen output disappears, and stop labelling it with
the first device's name since the browser default is not necessarily that
device.
2026-09-08 23:22:44 +01:00
Valere 6e44332fd1 Stop reading URL parameters from inside the call path
The view models reached for getUrlParams() — and so window.location —
from deep inside the call path: CallViewModel, MediaDevices, Publisher,
LocalMember and the footer view model. An embedded Element Call has no URL
of its own, so these values have to arrive as arguments instead.

Add the relevant options to CallViewModelOptions, to the MediaDevices and
Publisher constructors, to createLocalMembership$ and enterRTCSession, and
to createCallFooterViewModel. The remaining React consumers read the
context added in the previous commit. AppViewModel now takes its audio
output options too, moving that URL read out to main.tsx, where the app
shell can act as the adapter.

The new CallViewModelOptions fields are optional, defaulting to what the
URL parameters resolve to outside widget mode; the MediaDevices and
Publisher arguments are required, so that every construction site has to
be explicit.

useTheme.test.ts mocked the UrlParams module with a factory, so it needed
updating to mock the hook rather than getUrlParams.

No functional change.
2026-09-02 10:31:48 +02:00
Valere dc5b541b21 fix(voice): Default to earpiece for voice only call 2026-06-25 13:10:27 +02:00
Valere 1bc2abb84f rename ControlledAudioOutput to iOSControlledAudioOutput 2026-03-24 18:03:33 +01:00
Valere 4f518819d3 review: extract ControlledAudioOutput in its own file 2026-03-24 18:02:27 +01:00
Valere c4ec52ae15 add some test for normal AudiOutput 2026-03-19 10:44:38 +01:00
Valere 4be2bc7560 android: Select default output device based on callIntent
Add comments on existing code
Extracted a specific android controller for isolation and better testing

lint fixes

Fix device update logic and more tests

better typescript
2026-03-19 10:44:38 +01:00
Robin 6aaf2db626 Fix formatting 2026-01-05 19:35:09 +01:00
Timo 77ba88b76c Set available devices to empty map on safari. Safari does not allow changing output devices so the output device dialog is confusing. (#3426)
* Set available devices to empty map on safari.

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

* better safari check

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-04 17:46:56 +02:00
Timo 7971ea76cd Dont construct logger before rageshake initialization (#3434)
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-04 16:43:08 +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 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
RobinandTimo 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 d08a180c54 Simplify and improve locality of the device name request logic 2025-06-25 15:50:53 -04:00
Timo c03e2c4bde simple subject instead of derived observable 2025-06-25 15:47:56 -04:00
Timo e47a743f1e Also fix camera reloading in widget mode 2025-06-25 15:47:56 -04:00
Timo 73ccb38c11 comment 2025-06-25 15:47:56 -04:00
Timo ab4eadf58f Only rerequest permissions if we do not yet get labels when enumerating 2025-06-25 15:47:56 -04:00
Robin f4d590c703 Use consistent name for preferred device IDs 2025-06-25 13:42:31 -04:00
Robin f3419f94c3 Fix empty string IDs not counting as devices 2025-06-25 13:40:39 -04:00
Robin 3b1ce22b71 Fold map operation into combineLatest 2025-06-25 13:38:47 -04:00
Timo 131bdc3522 fix initial selection when using controlled media 2025-06-25 12:14:05 +02:00
Timo 337d09cd4d Use the platform property for ios detection (#3360) 2025-06-24 14:25:05 +02:00
RobinandTimo 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