- The camera menu leads with the user's own camera, with the effect in
force, full width at sixteen by nine: a background is judged by how it
looks rather than by its thumbnail.
- It shows the pipeline's own track again, not a second capture. Each
provider keeps the camera its pipeline is synced to, before joining and
after, and hands it out with its state, so two calls on a page keep
their own. It is reported again only when it changes, which keeps the
preview from blanking on every change of state.
- It and the pre-join preview share useAttachedTrack, which detaches only
its own element: the pre-join preview detached every element showing
its track, the menu's among them.
- Paid for out of the list's share of the call, so a menu with it is no
taller: at the top where the list keeps its floor after paying, else
first among the options, scrolling away with them. Its size comes from
the tokens the stylesheets draw it with, so it is placed once.
- While the first effect is prepared the preview shows the wait; with the
camera off it says so, and an effect can still be chosen.
- The video is rounded itself as well as clipped by its frame: Firefox
composites it on a layer of its own, which the frame's rounded clip
didn't reach at 100% zoom. Confirmed by hand, as headless Firefox draws
it rounded either way.
- Every camera story shows the preview, with a stand-in camera drawn to a
stream. End to end on Chromium and Firefox, the lobby's menu shows the
camera and then the chosen picture.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The first effect chosen in a session shows a spinner on its own tile,
in place of the tick, until a frame carrying it is drawn. Later changes
show nothing, having nothing to prepare.
- Ended by the frame, not the promises, which resolve while the segmenter
is still being built. The transformer reports the first frame that went
through the segmenter; one passed through untouched doesn't count.
- The pipeline publishes the wait with its state, and both footer view
models take it as an input.
- The lobby tests' provider mock gains the observable hook, built once: a
fresh observable per render rebuilt the footer on every render.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Since we removed the extra 'legacy' mode, meaning there's nothing simplified anymore by translating things over to a JWT service version.
(Also, simplify some things by making the mode static for the duration of a call.)
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.
This is the mode in which we sent membership events with the 'oldest membership' transport selection algorithm, which stopped being the default back in version 0.21.0. Users will no longer be able to select this mode in developer settings, and admins will no longer be able to select legacy mode through the config either. The app will still continue to support *receiving* membership events with the 'oldest membership' transport selection algorithm from others, however.
Previously we had a ViewModel class which was responsible for little more than creating an ObservableScope. However, since this ObservableScope would be created implicitly upon view model construction, it became a tad bit harder for callers to remember to eventually end the scope (as you wouldn't just have to remember to end ObservableScopes, but also to destroy ViewModels). Requiring the scope to be specified explicitly by the caller also makes it possible for the caller to reuse the scope for other purposes, reducing the number of scopes mentally in flight that need tending to, and for all state holders (not just view models) to be handled uniformly by helper functions such as generateKeyed$.
* 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>
* 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>
* 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>
* 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