Compare commits

...
Author SHA1 Message Date
Johannes Marbach b53b2122a5 Merge branch 'johannes/matrix2-test' into robin/livekit-updates 2026-10-13 07:38:49 +02:00
Johannes Marbach ee7dcdee7e Cover the subscriber token path, widget fallback and server names 2026-10-12 21:28:04 +02:00
Johannes Marbach 8d1ed31b0b Cover identity matching and delegation across transport shapes 2026-10-12 21:09:15 +02:00
Johannes Marbach 54e948fdc0 Make the auth choice mode independent again 2026-10-12 20:37:14 +02:00
Johannes Marbach 37d25d4293 Merge branch 'main' into robin/livekit-updates 2026-10-12 16:29:13 +02:00
Timo 079185b232 Merge pull request #4347 from element-hq/toger5/CI-playwright-improvements
[CI Playwirght] Make reporter more verbose + fail faster
2026-10-12 16:18:13 +02:00
Johannes Marbach 022415e98e Avoid null in transport dev setting 2026-10-12 16:11:03 +02:00
Johannes Marbach a1575cb554 Share a connection between homeservers using the same JWT service 2026-10-12 16:08:56 +02:00
Johannes Marbach 97b5e61ad8 Fall back to get_token as subscriber on widget API errors 2026-10-12 16:03:00 +02:00
Johannes Marbach f8258f6a1d Switch JS SDK back to develop 2026-10-12 15:43:44 +02:00
Johannes Marbach 68107d119e Retain compatiblity in compatiblity mode 2026-10-12 15:40:27 +02:00
Timo e96f578b63 Merge pull request #4346 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v11.2.0
2026-10-12 14:12:06 +02:00
renovate[bot] cfaae8f7e2 Update dependency @vector-im/compound-design-tokens to v11.2.0 2026-10-12 11:01:00 +00:00
Timo 1a90e813e8 Merge pull request #4338 from element-hq/toger5/compound-portal-root
[ElementCallComponent] Use compound-web's PortalRoot in EC.
2026-10-12 12:59:28 +02:00
Timo K.andClaude Fable 5.1 9d0a12c38a Fix PortalRoot hiding the component's menus and tooltips
compound-web 10.4.0 treats a PortalRoot whose root is null as one whose root
is not available yet, so floating-ui never mounts the portal and every tooltip
label, and with it every icon button's accessible name, is missing. The
component defaulted portalRoot to null and wrapped the call unconditionally.

Wrap the call only when the host supplied a root, keeping null as the
not-yet-available case Compound defines, and say so on the prop. Cover it in
CallPortalRoot.test.tsx. Drop the git allowBuilds entry for compound-web now
that it is a release again.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 12:43:29 +02:00
Timo K. a1c98ac4e6 make reporter more verbose + let CI playwright fail faster 2026-10-12 12:38:10 +02:00
Timo K. b72493f47f bump compound-web to release 10.4.0 2026-10-12 11:15:03 +02:00
Johannes Marbach 49223e720b Cover url transports end to end
The specs replace the transports the e2e homeserver advertises with each
shape a migrating deployment may produce and record which token endpoints
each side used: a url-only or combined transport on both sides goes
through the CS API alone, a legacy guest joining a url host uses the
legacy endpoint to publish and the CS API to subscribe, a subscriber falls
back to the JWT service when the homeserver lacks MSC4195, a publisher
gets an error instead, a delayed leave delegated through the CS API fires
on disconnect, and subscribers get tokens for a remote homeserver's SFU
over federation.

The JWT service's app service registration has to cover users of the e2e
Synapse's real server name for the get_token flow, and lk-jwt-service
0.8.0 implements the endpoints.
2026-10-12 10:33:58 +02:00
Robin c5044119ce Deprecate the livekit.livekit_service_url config option
Homeservers should advertise their transports over the MSC4143
rtc/transports endpoint instead of relying on a fallback in the app
config.
2026-10-12 10:33:38 +02:00
Robin f366e7cbe2 Let developers override the whole transport
The developer setting that overrode the LiveKit service URL becomes a
JSON transport, so that a `url`-only or combined transport can be tested
against a homeserver that does not advertise one yet. The settings modal
shows each LiveKit room's role instead of a never-populated isLocal flag.
2026-10-12 10:33:19 +02:00
Robin e336ee5cfa Get SFU tokens and delegate delayed leaves through the MSC4195 CS API
src/livekit/auth now fronts two flows. For a transport with a LiveKit SFU
`url`, tokens come from our own homeserver's MSC4195 get_token endpoint
and delayed leaves are delegated through delegate_delayed_leave, both via
the js-sdk's unstable client methods. Transports with only a
livekit_service_url keep using the OpenID flow against the JWT service.

A transport advertising both shapes lets a subscriber fall back to the
OpenID flow when the homeserver answers get_token with a 404 (Synapse
reports M_UNRECOGNIZED for unknown routes rather than M_NOT_FOUND), so a
client can still join calls hosted on servers that have not deployed
MSC4195 yet. Publishers never fall back: a homeserver that advertises a
`url` but does not implement the endpoints is misconfigured and the
admin should hear about it, so they get NoMatrix2AuthorizationService.
Delegation uses the same flow as the token so that the participant
identity the service computes matches.

The local member only probes a transport's delegate_delayed_leave
endpoint when it has a service URL. The developer settings tab validates
a custom service URL through the same facade.
2026-10-12 10:33:00 +02:00
Robin 17c3a7cb5d Pin matrix-js-sdk to the member_id branch
Temporary, until matrix-org/matrix-js-sdk#5588 merges and this can go
back to a develop bump. The branch only changes the get_token request
body from a member object to a member_id, so this is kept separate from
the code that uses it and can be dropped without touching that code.
2026-10-12 10:32:13 +02:00
Robin 53a0e273d6 Identify transports by server name as well as URLs
A transport with only a LiveKit SFU `url` has to be authenticated through
our own homeserver, which needs to know the name of the server owning the
SFU. Carry that name alongside the transport as a TransportLocator,
derived from the member's user ID for remote transports and from the
client's domain for our own, and key the connection map on the SFU URL,
the service URL and the server name together so that `url`, service URL
and combined transport shapes are deduplicated consistently.
2026-10-12 10:31:36 +02:00
Robin 83e1396bdd Use the unstable LiveKit transport type
UnstableLivekitTransport covers every shape a homeserver may advertise
while MSC4195 evolves: a LiveKit SFU `url`, a `livekit_service_url`, or
both. Switching to it means a service URL is no longer guaranteed, so the
remaining code that relies on one checks for it explicitly: delegation
probing skips transports without one, the connection map keys transports
by whichever URL they carry, and the OpenID flow rejects transports
without a service URL until the client-server API flow lands.
2026-10-12 10:30:52 +02:00
Robin d5bbb43e3a Reduce ConnectionManager to a ConnectionMap
createConnectionMap$ now returns the behavior of connections and their
participants directly and takes an already resolved local transport
instead of an observable of it. The CallViewModel wraps it with mapScoped
so that a new map is built, in a fresh scope, whenever the local transport
changes, and swallows local transport errors there since the local member
already surfaces them in the UI.
2026-10-12 10:26:54 +02:00
Robin 24b6a632dd Let the publishing Connection authenticate itself
getLocalTransport no longer authenticates with the SFU up front and hands
the resulting config to the connection. Instead the ConnectionManager tags
the connection whose transport equals the local one as the publisher, and
every Connection fetches its own SFU config for its role.

The local member now only joins the MatrixRTC session once its connection
is authenticated, so that the LiveKit room exists before remote members
try to get a subscriber token for it. Subscribers authenticating with the
OpenID flow lack permission to create the room and would otherwise fail
without retrying, causing a cascade of leaves and rejoins at the start of
a call.
2026-10-12 10:22:33 +02:00
Robin 17c3223883 Move SFU authentication into livekit/auth and choose the endpoint by role
The OpenID flow moves to src/livekit/auth/openID.ts with the SFU config
types in a sibling file, takes an options object, and replaces the
MatrixRTC mode with the role we take on the transport plus the session's
slot ID instead of a hard-coded m.call#ROOM.

This changes behaviour: publishers on a livekit_service_url transport
always use the legacy /sfu/get endpoint, so that subscribers can predict
their user:device participant identity, and subscribers always use the
default /get_token endpoint. The MatrixRTC mode no longer influences which
endpoint is used.
2026-10-12 10:17:39 +02:00
Timo K. c79675e6a9 bump to compound-web main branch 2026-10-12 10:14:49 +02:00
Robin f260755f46 Group livekitRoomItems$ by connection
The old reducer keyed items by service URL and mutated the accumulator's
entries in place, so a transport without a service URL could not be
represented and items were not safe to compare. Group members by their
Connection object instead and carry the whole transport on the item, which
the audio renderer now receives in place of a URL.
2026-10-12 10:11:54 +02:00
Robin 3927c2b7dc Show the whole transport in debug UI and logs
A transport may soon carry a LiveKit SFU `url` instead of, or as well as,
a `livekit_service_url`, so a service URL alone no longer identifies it.
Pass the whole transport to the tiles' debug stats and print it as JSON in
log lines instead of picking out the service URL.
2026-10-12 10:09:50 +02:00
Robin 4e4ab23cda Model ConnectionState as a discriminated union
The enum mixed our own lifecycle states with a copy of livekit-client's
connection states, and errors were smuggled through the same observable as
a separate union member. A discriminated union keeps the LiveKit state
nested under "authenticated", carries the error as data, and lets the
local member represent the time before a connection exists as an
"initializing" state instead of null.
2026-10-12 10:08:22 +02:00
Robin 3f030e64dd Match LiveKit participants against all backend identities
A member authenticated through the legacy JWT endpoint publishes under a
`user:device` identity, while one authenticated through the default
endpoint publishes under a hashed identity. Both are listed in the
membership's backend identities, so match against the whole list rather
than only the primary one.
2026-10-12 10:04:47 +02:00
Johannes Marbach d8becaf868 Advertise the loopback address from the dev LiveKit SFUs
The container IP is not routable from the host when Docker runs in a VM
(colima, Docker Desktop), so calls against the dev stack drop once ICE
fails. Advertising 127.0.0.1 instead lets the browser reach the SFU through
the published ports. Firefox ignores loopback candidates, so this only
works in Chromium-based browsers.
2026-10-12 10:03:03 +02:00
Robin 994cd36c44 Fix typo in the name of the createJWTToken Playwright fixture 2026-10-12 10:03:03 +02:00
Johannes Marbach 7ac5373af9 Remove stray pause and improve logging for hung e2e tests
The list reporter is the only progress a hung CI run leaves behind, and a
global timeout under the job's 60 minute limit means a hung run still ends
with a report instead of being cancelled by GitHub.
2026-10-12 10:03:03 +02:00
renovate[bot] 32fcede65e Update ghcr.io/element-hq/element-web:develop Docker digest to d43e8d2 (#4345)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-12 02:40:40 +00:00
renovate[bot] 6438c18b73 Update ghcr.io/element-hq/element-web:develop Docker digest to 88eeb34 (#4344)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-11 00:49:17 +00:00
renovate[bot] f07e9f5c70 Update ghcr.io/element-hq/element-web:develop Docker digest to 1488790 (#4343)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-10 02:09:04 +00:00
Johannes Marbach c97e3bf7a6 Merge pull request #4337 from element-hq/johannes/remove-per-participant-e2ee-param
Remove perParticipantE2EE
2026-10-09 12:01:45 +02:00
Timo K. 674692c926 Fix breaking Ci tests due to compound-web 10.1.0 -> 10.3.1 bump 2026-10-09 11:09:41 +02:00
Timo K. c3d07b89bd review: unnecassary matchMedia overwrite on test start. 2026-10-09 11:08:03 +02:00
renovate[bot] f89cbc140e Update ghcr.io/element-hq/element-web:develop Docker digest to 181a526 (#4339)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-09 01:18:17 +00:00
Timo K. 3bd892ebd3 bump compound-web 2026-10-08 21:26:34 +02:00
Timo K. f322af2742 [ElementCallComponent] Use compound-web's PortalRoot in EC. 2026-10-08 19:14:01 +02:00
Johannes Marbach a9fa48f68c Remove perParticipantE2EE 2026-10-08 17:15:19 +02:00
Robin 471c76c0e7 Merge pull request #4336 from element-hq/robin/vite-warning
Fix Vite warning
2026-10-08 16:40:45 +02:00
Johannes Marbach 4881fd5fc6 Merge pull request #4280 from element-hq/johannes/claude
Add workflow for automated Claude review of pull requests
2026-10-08 15:27:13 +02:00
Johannes Marbach 49c29f160a Add workflow for automated Claude review of pull requests 2026-10-08 14:57:19 +02:00
Robin aa8f73e632 Fix Vite warning 2026-10-08 14:23:59 +02:00
Johannes Marbach 14c561af8d Merge pull request #4300 from element-hq/johannes/pure-layout-functions
Make the layout decisions pure / testable functions
2026-10-08 13:20:44 +02:00
Johannes Marbach 4fd2f66949 Explain why we use merge 2026-10-08 11:14:26 +02:00
Johannes Marbach 53e038b09b layoutShallowEquals -> shallowEquals 2026-10-08 10:57:03 +02:00
renovate[bot] 3b7ccb63e2 Update ghcr.io/element-hq/element-web:develop Docker digest to 53a4fe6 (#4334)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-08 02:17:28 +00:00
Johannes Marbach 5d34f57567 Set up jig for testing Matrix 2.0 2026-10-07 16:16:21 +02:00
Johannes Marbach 1f07f949b5 Merge pull request #4330 from element-hq/renovate/npm-postcss-selector-parser-vulnerability
Update dependency postcss-selector-parser to v7.1.6 [SECURITY]
2026-10-07 14:59:28 +02:00
renovate[bot] a60036b3d7 Update dependency postcss-selector-parser to v7.1.6 [SECURITY] 2026-10-07 12:37:14 +00:00
Timo 2eb3a2fd2d Merge pull request #4329 from element-hq/toger5/remove-lk-client-from-external-deps
Remove livekit-client from the list of external dependencies
2026-10-07 14:34:47 +02:00
Timo K. 8b6adf067e remove unnecassary (confused) comment 2026-10-07 14:20:42 +02:00
Timo K. b408610277 Remove livekit-client from the list of external dependencies 2026-10-07 12:01:21 +02:00
renovate[bot] 2faa6c3dac Update ghcr.io/element-hq/element-web:develop Docker digest to 589c490 (#4328)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-07 01:42:16 +00:00
renovate[bot] 9b3c3569ec Update ghcr.io/element-hq/element-web:develop Docker digest to 39c94f0 (#4327)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-06 02:57:18 +00:00
Johannes Marbach a4654d9d00 Merge pull request #4315 from element-hq/johannes/workflow-call
Allow workflow_call on lint and test workflows
2026-10-05 14:07:07 +02:00
Johannes Marbach 6e5f71c796 Revert back to negative flags 2026-10-05 13:53:52 +02:00
Johannes Marbach 067f3d3038 Fix repo selection and flags 2026-10-05 13:44:48 +02:00
Johannes Marbach 6d70221fe6 Flip boolean flags 2026-10-05 13:04:34 +02:00
renovate[bot] 427376f78b Update ghcr.io/element-hq/element-web:develop Docker digest to 573daa2 (#4323)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-05 09:47:57 +00:00
Johannes Marbach ccfd36923d Merge pull request #4324 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v11.1.0
2026-10-05 08:41:57 +02:00
Johannes Marbach 89567726f8 Fix tests 2026-10-05 08:13:58 +02:00
Robin 9cd111b5f2 Merge pull request #4318 from element-hq/redact-posthog-user-id
Redact analytics ID from rageshakes
2026-10-05 07:44:16 +02:00
renovate[bot] 096aaac9f3 Update dependency @vector-im/compound-design-tokens to v11.1.0 2026-10-05 01:27:09 +00:00
renovate[bot] 8835a6d75d Update ghcr.io/element-hq/element-web:develop Docker digest to 3cf23ff (#4322)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-04 09:34:33 +00:00
renovate[bot] bfb868aec3 Update ghcr.io/element-hq/element-web:develop Docker digest to 5371503 (#4321)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-03 01:48:09 +00:00
Robin 4e8fb6e4cb Redact analytics ID from rageshakes
To improve our minimization of external data we collect in rageshakes.
2026-10-02 16:51:00 +02:00
Robin 7c53a6be5a Merge pull request #4317 from element-hq/remove-wait-for-rotation
Remove wait_for_key_rotation_ms config option
2026-10-02 15:14:14 +02:00
Robin 64b932f128 Remove unused vite-plugin-generate-file dependency 2026-10-02 14:57:34 +02:00
Robin bfad85a3af Remove wait_for_key_rotation_ms config option
I learned that makeKeyDelay has been deprecated in matrix-js-sdk ever since the switch to the new encryption manager, so this config option has no effect.
2026-10-02 14:49:44 +02:00
Johannes Marbach be822adec8 Allow workflow_call on lint and test workflows 2026-10-02 13:33:29 +02:00
Johannes Marbach 4c0f02ef47 Merge pull request #4309 from element-hq/johannes/layered
Set up a layered build for CI similar to what EW does
2026-10-02 13:22:19 +02:00
Johannes Marbach ca6319f06d Remove layered boolean 2026-10-02 13:07:09 +02:00
Timo 1d57a8eee1 Merge pull request #4308 from element-hq/toger5/fix-component-sounds
[ElementCall Component] Decode inlined sounds directly instead of fetching them
2026-10-02 12:45:31 +02:00
Timo K. 0bb9632b60 review play sounds does not throw 2026-10-02 11:46:54 +02:00
Timo K. cbe195d449 review audio data loading 2026-10-02 11:46:40 +02:00
Robin e800fec74d Merge pull request #4314 from element-hq/renovate/element-web
Update ghcr.io/element-hq/element-web:develop Docker digest to 588f0b4
2026-10-02 11:29:05 +02:00
Robin 9d0725ad31 Fix Element Web integration tests 2026-10-02 10:51:31 +02:00
renovate[bot] 241412f29b Update ghcr.io/element-hq/element-web:develop Docker digest to 588f0b4 2026-10-02 02:54:17 +00:00
Timo K. d96d00b64a Merge branch 'main' into toger5/fix-component-sounds 2026-10-01 19:07:39 +02:00
Robin cde88a7c93 Merge pull request #4312 from element-hq/js-sdk-develop
Reset matrix-js-sdk to develop branch, adopt new join/leave signatures
2026-10-01 18:55:16 +02:00
Robin d5733e8274 Reset matrix-js-sdk to develop branch, adopt new join/leave signatures 2026-10-01 17:11:24 +02:00
Timo K. 3befe3d34b Merge branch 'main' into toger5/fix-component-sounds 2026-10-01 13:58:23 +02:00
Timo 3ad778e7e8 Merge pull request #4306 from element-hq/toger5/fix-component-tooltips
[ElementCall Component] Make compound a peer dependency with EW. (fix tooltips in embedded mode)
2026-10-01 13:57:58 +02:00
Timo K. 9a286032f2 shorten readme 2026-10-01 13:41:07 +02:00
Timo K. 363a8feab2 Stop bundling Compound, let the host supply it 2026-09-30 17:10:17 +02:00
Johannes Marbach bd8c3142a6 Set up a layered build for CI similar to what EW does 2026-09-30 11:35:06 +02:00
Timo K. 16c60c8b6b Warn when the audio context fails to set up. 2026-09-30 11:22:19 +02:00
Timo K. 63ac1ba03e Decode inlined sounds directly instead of fetching them, with the test. 2026-09-30 11:22:15 +02:00
Robin 9e190e9e57 Merge pull request #4307 from element-hq/update-js-sdk
Adapt to matrix-js-sdk removal of livekit_alias and oldest_membership
2026-09-30 10:41:37 +02:00
Robin f287fb3800 Adapt to matrix-js-sdk removal of oldest_membership support 2026-09-30 00:45:19 +02:00
Robin f9b601504b Stop sending livekit_alias in memberships
It's been many versions since anything used the value.
2026-09-30 00:45:19 +02:00
Timo K. 9140365251 Merge branch 'main' into toger5/fix-component-tooltips 2026-09-29 16:25:15 +02:00
Timo 81233e5cfb Merge pull request #4269 from element-hq/toger5/component-api-entry
Export EC component related types
2026-09-29 16:24:26 +02:00
Timo K.andClaude Fable 5.1 e296d88969 Keep the component's tooltips inside its root
Compound's Tooltip floats its bubble through floating-ui's FloatingPortal,
into the body: outside the element the component build confines its
stylesheet to, so a label tooltip shows as bare text at all times. An
enclosing FloatingPortal rooted at the container makes the nested portals
land inside it instead.

The call goes in an isolating wrapper there, standing in for the standalone
page's #root, so that its footer layer no longer paints above the modals.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 12:08:44 +02:00
Robin fbce73ae55 Merge pull request #4302 from element-hq/always-multi-sfu
Remove multi-SFU check which is always true
2026-09-29 09:14:42 +02:00
renovate[bot] ce79274ccc Update ghcr.io/element-hq/element-web:develop Docker digest to cbb7be9 (#4303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-29 01:07:59 +00:00
Robin 8db2e8ac41 Remove multi-SFU check which is always true
Compatibility and Matrix 2.0 are the only MatrixRTC modes now.
2026-09-28 22:03:16 +02:00
Johannes Marbach 12352b94f5 Merge pull request #4299 from element-hq/johannes/drop-observable-hooks
Drop observable-hooks in favor of useBehavior
2026-09-28 18:12:43 +02:00
Johannes MarbachandRobin e393b6a984 Swap conditional ordering
Co-authored-by: Robin <robin@robin.town>
2026-09-28 17:56:08 +02:00
Johannes Marbach 3f63a6fc3c Drop observable-hooks in favor of useBehavior
With this change, views now read every reactive value through `useBehavior`, as
`architecture.md` already prescribes. Where a view reads a plain stream, the view
model now exposes a `Behavior`.
2026-09-28 17:54:50 +02:00
Johannes Marbach 6600c891f3 Extract the layout decision into a pure function 2026-09-28 17:36:24 +02:00
Johannes Marbach 33cfd2d8ad Build the layout media from one snapshot of its inputs 2026-09-28 17:34:22 +02:00
Johannes Marbach 5a8714805c Extract the spotlight and PiP choice into a pure function 2026-09-28 17:29:41 +02:00
Johannes Marbach 232e3f7ad4 Extract the spotlight speaker choice into a pure function 2026-09-28 17:28:14 +02:00
Johannes Marbach 10adf6658b Let layoutShallowEquals compare any layout-shaped object 2026-09-28 17:27:04 +02:00
Johannes Marbach 29742006df Move WindowMode next to the layout types to prevent cyclic import 2026-09-28 17:26:11 +02:00
Johannes Marbach addc1b10a0 Merge pull request #4297 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v10.1.0
2026-09-28 08:23:32 +02:00
renovate[bot] ee0d7dc0cb Update ghcr.io/element-hq/element-web:develop Docker digest to cfbe7ce (#4296)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-28 01:14:27 +00:00
renovate[bot] 7b1f3f28ed Update dependency @vector-im/compound-web to v10.1.0 2026-09-28 01:03:27 +00:00
renovate[bot] 8c44ecd61b Update ghcr.io/element-hq/element-web:develop Docker digest to 8301993 (#4295)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-27 01:25:15 +00:00
renovate[bot] 7d92ddf0c9 Update ghcr.io/element-hq/element-web:develop Docker digest to d97061c (#4294)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-26 02:21:38 +00:00
Johannes Marbach 5c497cc6a8 Fix build on Windows 2026-09-25 16:15:39 +02:00
fkwpandClaude Opus 5 b7bd7d18b2 [Feature] Quick audio menu (#4275)
* Give the microphone level its own observable
* Add a microphone level meter
* Show speakers and microphones in the quick audio menu
* Wire speaker selection through the call footer
* Add stories for the meter and the device menu
* Add end-to-end specs for the quick audio menu
* Keep the footer while a menu opened from it is open
* Use the shared audio capture stub in the lobby test
---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-24 09:52:02 +00:00
fkwpandClaude Opus 5.5 b4b72432b9 Tighten the comment guidance in AGENTS.md (#4279)
* Say what earns a comment its place

- Add a comments section to the code style: no comment by default, the reason
  only, and the kinds that go stale.
- Point to it from the PR checklist in AGENTS.md.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 08:44:04 +00:00
Robin ac1f5e2c8c Merge pull request #4277 from element-hq/vitest-warning
Fix Vitest import warning
2026-09-23 16:04:47 +02:00
renovate[bot] 98d77cc816 Update ghcr.io/element-hq/element-web:develop Docker digest to 0636bbe (#4276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-23 01:55:54 +00:00
Robin d5812ddd34 Fix Vitest import warning
Fixes the following warning:

[warn] (!) Your Vite config uses features that are unsupported by `configLoader: 'native'`, which is planned to become the default in a future major version of Vite:
  - import "./vite.config" without a file extension (vitest.config.ts:3:35). Add the file extension
Set `VITE_CONFIG_NATIVE_IGNORE_WARNING=true` to suppress this warning.
2026-09-22 23:34:19 +02:00
Johannes Marbach cf7c275fb7 Merge pull request #4274 from element-hq/hs/bell
Bell reaction sound.
2026-09-22 12:32:38 +02:00
Half-Shot 93b2661513 Switch to 🛎️ 2026-09-22 11:21:11 +01:00
Robin 1f84cb9c5c Merge pull request #4273 from element-hq/simplify-local-transport
Simplify local transport code
2026-09-22 12:15:34 +02:00
Half-Shot 4269aaa163 update snap 2026-09-22 10:04:12 +01:00
Half-Shot bc62bb9565 lint 2026-09-22 10:01:22 +01:00
Half-Shot be56bbd05b lint 2026-09-22 10:01:10 +01:00
Half-Shot eb44fd545d Bell reaction sound. 2026-09-22 09:57:43 +01:00
Robin c9f911b7c9 Swallow local transport errors in connection manager 2026-09-22 10:01:14 +02:00
Robin 3a189d155b Remove references to outdated variables or types 2026-09-22 09:56:02 +02:00
Robin 0211d5c367 Remove unused shareReplay operator 2026-09-22 09:45:48 +02:00
Robin c88f884fc9 Simplify local transport code
As of the removal of 'Legacy' mode, there can no longer be a difference between the transport you advertise in your membership and the transport you publish media on, so the local transport code can be simplified considerably. For instance, the function which gets the local transport can simply return a promise rather than being reactive.

I kept the local transport as an Observable in other modules so that they could easily be tested with existing marble tests.
2026-09-21 12:51:28 +02:00
Johannes Marbach 9f7c35cd8f Merge pull request #4270 from element-hq/renovate/major-compound
Update dependency @vector-im/compound-design-tokens to v11
2026-09-21 07:51:35 +02:00
renovate[bot] ac81a7c0ab Update dependency @vector-im/compound-design-tokens to v11 2026-09-21 02:56:00 +00:00
Timo K. 8ebb0b5a90 Export component related types. 2026-09-19 08:46:30 +02:00
Timo 03f81bcd64 Merge pull request #4266 from toger5/toger5/memberId-based-on-matrixRTCMode
Make the memberId dependent on the matrixRTC mode.
2026-09-17 14:02:32 +02:00
Timo K. 9f6c8bb434 Make the memberId dependent on the matrixRTC mode.
This outherwise creates to-device messages with the uuid for members
that use the userId:deviceId memberId in the state event.
2026-09-17 13:44:25 +02:00
renovate[bot] f56c74adf9 Update ghcr.io/element-hq/element-web:develop Docker digest to 3993d53 (#4265)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-17 00:51:42 +00:00
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
renovate[bot] 967a06ba39 Update ghcr.io/element-hq/element-web:develop Docker digest to 506caaa (#4262)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-16 00:29:13 +00:00
renovate[bot] 71593f1a24 Update ghcr.io/element-hq/element-web:develop Docker digest to c76d299 (#4260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-15 02:40:31 +00:00
renovate[bot]andJohannes Marbach 5d38a13c46 Update ghcr.io/element-hq/element-web:develop Docker digest to 9d8d8fc (#4243)
* Update ghcr.io/element-hq/element-web:develop Docker digest to 1850bf6

* Adapt to latest EW

* Reformat

* Next try

* Fix regexp

* Fix DM path

* Next try

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-09-14 08:51:33 +00:00
Johannes Marbach fe91162869 Merge pull request #4257 from element-hq/matthew/log-livekit-ice
Always log LiveKit ICE candidates and states to the rageshake
2026-09-14 08:31:42 +02:00
Johannes Marbach 74328d7e42 Merge pull request #4258 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.22.3
2026-09-14 08:03:12 +02:00
renovate[bot] 6046337877 Update dependency livekit-client to v2.22.3 2026-09-14 02:37:28 +00:00
Matthew Hodgson 16b2c31ebb Always log LiveKit ICE candidates and states to the rageshake
LiveKit's livekit-ice logger records each local ICE candidate, ICE
candidate errors and ICE connection state changes, but only at debug,
which we cap to info unless extended LiveKit logs are switched on. That
means a 'could not establish pc connection' rageshake carries no way to
tell 'no relay candidates at all' from 'relay candidates that never
paired'. Keep that one logger at debug regardless of the toggle.
2026-09-11 18:30:33 +01:00
fkwpandClaude Opus 5 a58a5f615f Add AGENTS.md documenting the repo's conventions (#4256)
* Add AGENTS.md documenting the repo's conventions

Codifies what is currently tribal knowledge or only discoverable by reading CI
config: the view model / view contract, the rule that nothing reads the page,
Clean Code ordering, the three test layers, and reuse-before-you-build.

The root AGENTS.md is the always-loaded minimum and routes to docs/agents/, so
an agent loads only the detail its task needs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Allow either hand at the commit, and measure continuous redraws

Committing from the agent rules out running it where there is no git
identity, a sandbox included. Either is now fine: commit on the user's
word where the setup allows it, or write the message and hand it over.

Redrawing continuously is the other addition. A level meter reported a
fresh value every animation frame, so its whole menu reconciled sixty
times a second, silence included, and nobody noticed until review. A PR
that adds anything of the kind now says what it costs, or better, counts
the redraws — commits rather than render calls, since React runs a
component it then discards.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 15:12:15 +02:00
Robin 2cac2d7e8b Merge pull request #4231 from element-hq/matthew/blur-processor-ended-track
Don't attach the background blur processor to an ended camera track
2026-09-10 21:27:11 +02:00
Robin 1695d3f518 Use flushPromises for readability 2026-09-10 21:15:48 +02:00
Robin 96a2e9b481 Merge pull request #4230 from element-hq/matthew/connection-stop-during-connect
Don't report an aborted connect as a connection error
2026-09-10 20:25:12 +02:00
Robin 23ba8f3204 Merge pull request #4249 from element-hq/matthew/audio-renderer-warn-spam
Stop MatrixAudioRenderer warning on every render
2026-09-10 19:56:56 +02:00
Matthew HodgsonandClaude Fable 5.1 b284bb00c0 Cover the stopProcessor failure path and trackProcessorSync
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GSB8Qb89KDoTNRV83dWJHa
2026-09-10 18:28:57 +01:00
Johannes Marbach cb0ae89143 Merge pull request #4253 from element-hq/johannes/jwt-0.7.0
Bump lk-jwt-service to 0.7.0 in the docker setup and integrate it as an app service
2026-09-10 17:46:02 +02:00
Johannes Marbach 344aac21f9 Force undelegated mode in tests 2026-09-10 14:15:38 +02:00
Johannes Marbach 21d7f24f61 Bump lk-jwt-service to 0.7.0 in the docker setup and integrate it as an app service 2026-09-10 12:26:49 +02:00
Johannes Marbach 029622f07b Merge pull request #4251 from element-hq/renovate/npm-postcss-selector-parser-vulnerability
Update dependency postcss-selector-parser to v7.1.3 [SECURITY]
2026-09-10 07:42:07 +02:00
renovate[bot] 251535d371 Update dependency postcss-selector-parser to v7.1.3 [SECURITY] 2026-09-09 17:42:33 +00:00
Timo 5c6fa7c864 Merge pull request #4233 from element-hq/valere/component_ec_M1
ElementCall as a react component: refactor + a local dev harness
2026-09-09 19:39:30 +02:00
Timo K. be4023dd66 fix layout in spotlight (top inset) 2026-09-09 19:20:31 +02:00
Timo K. be5f3390f7 more tests 2026-09-09 17:01:16 +02:00
Timo K. 59ef5f5400 ci 2026-09-09 16:05:18 +02:00
Matthew Hodgson dbd2423e7b Stop MatrixAudioRenderer warning on every render
The "has no matching matrix call member" warning fired on every re-render
(i.e. every active speaker update) and also for the local participant's own
track, which is never rendered here anyway. Skip local tracks and warn once
per unexpected identity.
2026-09-09 11:20:49 +01:00
Timo K. 2ac95df75f update readmes 2026-09-09 12:15:19 +02:00
Timo K. 7821b465a5 Merge branch 'main' into valere/component_ec_M1 2026-09-09 10:23:47 +02:00
Robin b90ed5bdf7 Merge pull request #4247 from element-hq/fix-cd
Fix call.element.dev not updating after branch rename
2026-09-09 09:07:51 +02:00
Robin 1d7e2288f7 Fix call.element.dev not updating after branch rename 2026-09-09 08:49:08 +02:00
Robin 61eeb8171a Merge pull request #4242 from element-hq/delayed-leave-timings
Adapt delayed leave timings when delegation is available
2026-09-09 08:19:58 +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
Robin cff8766aa6 Delegate delayed leaves in LocalMember rather than LocalTransport
IMO this is where the delegation calls should have lived all along, since the leave event is part of the membership lifecycle, and we otherwise end up with an awkward hack to ignore transport updates.

Doing this now ensures that the client won't send any delegation requests if delegation is unsupported, and prepares the code for a future change in which we use the dedicated delegation endpoint from the CS API.
2026-09-08 21:22:52 +02:00
Robin 5cfe7ea4df Base JWT service endpoint choice directly on the MatrixRTC mode
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.)
2026-09-08 21:22:52 +02:00
Robin d38daef567 Reflect session config always being defined 2026-09-08 21:22:52 +02:00
Robin 09782a4d84 Give JWT token fetch procedures more appropriate names 2026-09-08 21:22:52 +02:00
Robin 839e36abd4 Make delegation support check fail immediately in case of CORS errors 2026-09-08 21:22:52 +02:00
Timo K. 3485ce47bc Merge branch 'main' into valere/component_ec_M1 2026-09-08 20:05:27 +02:00
Timo K. 273ee3b632 add allowJoinUnmutedViaIntent to the bridge
This allows us to control to never start unmuted in spa but be able to
start unmuted in widget and component mode.
2026-09-08 18:12:40 +02:00
Timo K.andClaude Fable 5.1 486ecbfda0 Stop offering media downloads on the component's host bridge
`downloadMedia` exists because a widget's client cannot fetch media: it
has no access token, and its only route to a file is MSC4039 over the
widget API. A component host hands over a client that does hold
credentials, so Element Call fetches media with it and the callback was
never needed there. It comes off `ElementCallHostBridge`, leaving a host
with only what it must understand, and stays on the internal HostBridge
for the widget.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 17:14:55 +02:00
Timo K.andClaude Fable 5.1 b722cc277e Make the theme a prop, next to the language
The theme is state — what Element Call should look like right now — and
so belongs beside `language` as a prop, not on the imperative handle
(where it was a request, `setTheme`, because the internal host bridge
speaks the widget API and a widget's host sends theme changes as
requests) and not in the configuration (where `config.theme` only ever
set the starting theme).

The `theme` prop feeds the same channel the rest of Element Call listens
to for a host's theme, replayed so that whatever subscribes after the
host has set it still hears the current one. Changing it re-themes the
container and nothing else; unlike the language, it is per component.
`setTheme` and `config.theme` are gone, and the harness gets a theme
picker in place of its per-pane buttons.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 17:02:24 +02:00
Timo K.andClaude Fable 5.1 f994586eeb Speak every language in the component, not just English
The component bundled English alone: the standalone app fetches its
locale files at runtime from URLs its own build emits, which a host
serving the library from elsewhere could not resolve, so bundling one
language was the self-contained option. Now every locale is a chunk of
its own that the host's bundler loads the first time it is needed, with
English still bundled in so that the fallback never waits.

Element Call starts in the browser's language and follows the host's own
setting through a `language` prop; `supportedLanguages` says what it
accepts. Translations are shared by every Element Call on the page, so
the most recently set language wins for all of them. The harness gets a
language picker, and the app and the component share the parsing of
locale paths.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 16:03:48 +02:00
Timo K.andClaude Fable 5.1 b7285064fd Let the shell say where home is, and drop the router from the call
The call reached for react-router in five places to send the user
"home": on leaving without a lobby, from the lobby's recents link, from
the post-call screen, from the error page's return button and from the
header logo. Home is the standalone app's home page; the call has no
idea where that is, and a component has no such place at all — its host
decides what follows a call. Yet the component had to mount a
MemoryRouter just so those hooks would not throw.

`useLeaveToHome` is the way home as the shell supplies it: the app
provides `navigate("/")` from inside its router, the component provides
nothing, and everything that used to link to "/" now either calls it or,
when there is none, offers no way out. The logo becomes a plain logo,
the recents and "not now" links disappear, the error page's button does
too. `ClientProvider`'s logout goes the same way. The component no
longer renders a router.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:39:00 +02:00
Timo K.andClaude Fable 5.1 f5a94ce702 Offer a component host only the configuration it can use
`ElementCallConfiguration` was every URL parameter, which put the widget
plumbing (widgetId, parentUrl, isWidget), the user's identity, the
homeserver, the analytics and Sentry settings, and the standalone app's
shared room secret in front of a host that has no business setting any
of them — the component reads none of those. It is now the behavioural
configuration a widget's URL can carry plus the two properties a host
has a say in: the theme and the background. The background is now
actually applied to the component's root, which it was not before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:39:00 +02:00
Timo K.andClaude Fable 5.1 3dc7cfe10b Say "component" for the component
"Embedded" already means something here: the embedded package is the
widget build. Where a comment meant Element Call running as a React
component inside a host application, it now says so, and the params it
starts from are `componentProperties`. "Host" stays the word for the
application on the other side, whether that is a widget container or an
application rendering the component.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:39:00 +02:00
Timo K.andClaude Fable 5.1 f70fba1dd6 Rename GroupCallView to CallView, and fold ElementCallView into it
Three layers stood between a shell and the call: `ElementCall` (the
component), `ElementCallView` and `GroupCallView`. The middle one only
held the `joined` flag and the mute state, both of which nothing outside
the call reads any more, so it is folded into the view it wrapped. That
view is now `CallView`, since "group call" is a name from before
Element Call handled anything else.

Its docstring says what it is: the whole lifecycle of a call — lobby,
the call itself, and what comes after — with the lobby and the post-call
screen each present or skipped depending on the parameters and the host.
Both the standalone RoomPage and the component render it directly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:38:59 +02:00
Timo K.andClaude Fable 5.1 8e8bc5ddde Talk to a component host in callbacks, not observables
The component exposed the internal HostBridge to hosts as-is, which
carried the host's requests as rxjs observables. That made rxjs part of
the public API of a package that bundles its own copy of it, so a host
would build bridges with a different rxjs than the one Element Call
consumed them with — and asked every host to learn rxjs to change the
theme.

A component host now implements plain async callbacks for what Element
Call tells it (`ElementCallHostBridge`, all optional), and makes its own
requests through an imperative handle on the component's `ref`
(`ElementCallHandle`: setTheme, join, hangUp, setDeviceMute), each
resolving once Element Call has acted and rejecting when nothing in
Element Call can. `component/host.ts` adapts that to the HostBridge the
rest of Element Call still speaks, with a bridge whose identity never
changes, so a host re-creating its callbacks on render restarts nothing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:38:59 +02:00
Timo K.andClaude Fable 5.1 d18e82c546 Catch the component's errors inside the component
Only the call body sat inside an error boundary; anything thrown in the
lobby, the mute state or the providers propagated into the host's React
tree, where React unmounts everything up to the nearest boundary — the
host's, or the host's whole application. The standalone app has a
boundary at its top; the component now has the same, showing the error
page inside its container and asking the host to stop keeping it on
screen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:38:59 +02:00
Timo K.andClaude Fable 5.1 779ee7a008 Finish measuring the root rather than the viewport
The move from media queries to `@container element-call` queries left a
few places still asking the viewport: the room header's compact size
and the lobby's footer placement went through `useMediaQuery`, the
lobby's video preview was `50vh` tall, the reaction picker was capped at
`100vw`, and the content insets and the gradient background were sized
from `100vw`/`100vh`. Embedded in a corner of a host's page, each of
those answered for the page rather than the corner.

`useRootSizeMatches` is `useMediaQuery` for the root element, built on
the same `observeElementSize$` the layout uses; the lengths become
container units. Container units resolve against the nearest query
container, and there are others in the tree (the spotlight layouts, the
media tiles), so base.css says when they may be used.

jsdom gives the body no size at all, which would have every such query
read as a tiny window; the test setup now gives it a desktop's, matching
what the media query mock already answered.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:38:59 +02:00
Timo K.andClaude Fable 5.1 7cd21476f7 Say outright whether the profile is ours to change
Whether to offer the profile settings was inferred from whether the host
could close Element Call. For a component with no host bridge — the
default — nothing could, so an embedded Element Call let the user edit
the profile of an account that belongs to the host application.

`HostBridge.supportsProfileChanges` states it directly: true standalone,
where Element Call signed the user in itself; false for a widget's host
and for anything embedding the component (which sets it itself, since
the client it hands over is its own). The profile tab and the profile
shortcut follow that. What a host's ability to close us still decides —
what to show after the call ends — is a question about who owns our
lifetime, and stays keyed on `close`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:38:59 +02:00
Timo K.andClaude Fable 5.1 f0359259f9 Format base.css
The formatter wants the layered import of the Compound design tokens on
one line; "de-globalise styles" left it wrapped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 15:38:59 +02:00
Timo K.andClaude Fable 5.1 7137e6ec14 Update the developer settings snapshot for the scoped pre style
"de-globalise styles" gave the tab's <pre> elements a class instead of
styling the bare element, but did not update the snapshot.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 13:56:10 +02:00
Timo K.andClaude Fable 5.1 6ae4f0539a Leave the page title to the page
The call and the lobby each set `document.title`, so a component
embedded in a host renamed the host's tab to "Element Call | <room>".
The title belongs to whoever owns the page: the standalone app's
RoomPage now sets it, for whichever room it has got as far as knowing
about, and the call itself no longer touches it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 13:53:50 +02:00
Timo K.andClaude Fable 5.1 bc58aed0d7 Keep keyboard shortcuts within Element Call's root
The call's shortcuts were listened for on the window and allowed
whenever focus was inside the standalone app's `#root` — which, for a
component embedded in a host, is the host's own root, or nothing. So m,
v and space fired while the user typed in the host's composer, and two
Element Calls on one page both answered every key.

Listen on the element Element Call treats as its root instead (the body
standalone, so nothing changes there), and judge whether a key press is
spoken for by what has focus — a dialog or a text field — rather than by
where it sits in the DOM, since the modals are now portalled to that
same root.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 13:52:34 +02:00
Timo K.andClaude Fable 5.1 608f107f8d End the component's media device scope on unmount
The component built its `MediaDevices` once, in a scope nothing ever
ended, so every mount left device observers running for the rest of the
page's life. Building it in an effect ties the scope to the component's
lifetime — and to the options it was built with, which were previously
frozen at first render.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 13:50:17 +02:00
Timo K.andClaude Fable 5.1 a010cc983f Compare the component's config by value
Everything downstream of the component's params — the mute state, the
call view model and with it the media connection — is keyed on the
identity of the params object, which was memoised on the identity of
the `config` prop. A host writing `config={{ ... }}` inline, which is
the natural way to write it, therefore tore the whole call down on
every render. The harness happened to pass a constant, so nothing
noticed.

`useStableValue` hands out the same object for as long as a deep
comparison says nothing changed, so an inline config costs nothing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 13:49:19 +02:00
Johannes Marbach 00d0adc3c4 Merge pull request #4222 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-09-08 11:40:20 +02:00
Johannes Marbach ddc5a50529 Disable new react compiler rules 2026-09-08 11:29:36 +02:00
renovate[bot] 27734a1a02 Update all non-major dependencies 2026-09-08 06:13:17 +00:00
Timo K. 489c1af426 test resizing via @container 2026-09-07 17:35:25 +02:00
Timo K. 365204d04c fix media queries in component based element call. 2026-09-07 14:50:36 +02:00
Johannes Marbach 14c61db43d Merge pull request #4241 from element-hq/matthew/encryption-mismatch-logging
Log track encryption flag and cryptor events for remote tracks
2026-09-07 13:30:50 +02:00
Johannes Marbach 65e1b845a7 Apply suggestion from @Johennes 2026-09-07 13:18:00 +02:00
Robin 6a9583a2ce Adapt delayed leave timings when delegation is available
Splits the config options for the timings of a delayed leave event into two sets: one for when delegation is available (as you can relax the timings and get more stable calls this way), and another for when it's unavailable (as we must continue to gracefully downgrade even after Matrix 2.0 is fully rolled out).

This works by bluntly hitting the delegation endpoints without auth before joining to check for a 404.
2026-09-07 13:10:54 +02:00
Matthew Hodgson eddd95ba41 Log track encryption flag and cryptor events for remote tracks
Extends the [RemoteTracks] logging from #4235 with the per-publication
encryption flag and the ParticipantEncryptionStatusChanged /
EncryptionError room events.

If a publisher encrypts frames while the subscriber believes the
publication is unencrypted, livekit-client bypasses the cryptor and hands
raw ciphertext to the decoder, which is audible as loud noise bursts.
The reverse mismatch (or a missing/invalid key) drops frames instead.
Neither case is visible in a rageshake today.
2026-09-07 11:53:01 +01:00
Johannes Marbach a376280c91 Merge pull request #4240 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.22.2
2026-09-07 08:07:34 +02:00
renovate[bot] 1e9a5cfa20 Update ghcr.io/element-hq/element-web:develop Docker digest to 6ed62b2 (#4239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-07 02:04:08 +00:00
renovate[bot] d204b36b55 Update dependency livekit-client to v2.22.2 2026-09-07 01:56:21 +00:00
renovate[bot] a03f23e720 Update ghcr.io/element-hq/element-web:develop Docker digest to a4e9c8c (#4238)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-06 02:02:35 +00:00
renovate[bot] 210d94af18 Update ghcr.io/element-hq/element-web:develop Docker digest to 3221e92 (#4237)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-05 02:55:22 +00:00
Timo K.andClaude Fable 5.1 218ee46b7d Make the component installable as a git dependency
`component/package.json` describes the built component as a package
(`@element-hq/element-call-component`: entry, stylesheet subpath, types,
peer dependencies) so that a host can depend on
`github:element-hq/element-call#<ref>&path:/component`. Its `prepare`
script builds on install, since nothing is published yet.

For that the component build now lands in `component/dist` instead of the
repository's `dist`, and `pnpm build:component` also emits the type
declarations (`component/tsconfig.build.json`, `build:component:types`),
which previously had to be produced by hand.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 15:29:55 +02:00
Timo K. 38c28a1c8f scaling based on component size instead webview size 2026-09-04 14:16:40 +02:00
Timo K. f5458bb03e de-globalise styles 2026-09-04 13:51:47 +02:00
renovate[bot]andRobin 70f6e785ce Update ghcr.io/element-hq/element-web:develop Docker digest to 724b468 (#4226)
* Update ghcr.io/element-hq/element-web:develop Docker digest to a9bd290

* Fix Element Web integration tests

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robin <robin@robin.town>
2026-09-04 09:18:19 +00:00
Johannes Marbach 0ad31cfc4d Merge pull request #4232 from element-hq/matthew/screenshare-watchdog
Surface screen share failures instead of silently doing nothing
2026-09-04 07:54:23 +02:00
Johannes Marbach bae8da3ddc Reformat 2026-09-04 07:44:16 +02:00
Johannes Marbach b22eba7af9 Add further tests 2026-09-04 07:39:58 +02:00
Robin cd7510e054 Merge pull request #4235 from element-hq/matthew/remote-track-logging
Log remote participant and track events per LiveKit connection
2026-09-03 20:22:27 +02:00
Robin 054913d17d Use testScope in ObservableScope tests 2026-09-03 20:11:18 +02:00
Matthew Hodgson dee4b05695 Diagnostics for duplicate participant matches and mid-delivery scope teardown
Warn when ConnectionManagerData merges participants from a second
connection to the same SFU URL, when more than one LiveKit participant
matches a member's backend identity, and when a scope is ended while one
of its behaviors is still delivering a value (which strands the later
bound subscribers on the old value). The per-member match log now also
names the connection the participant came from.
2026-09-03 18:43:18 +01:00
Matthew Hodgson b1393998a7 Report re-entrancy depth and tag torn behaviors
A single re-entrant emission can only strand a contiguous run of a
behavior's subscribers, so a tile that is both 'speaking' and 'waiting
for media' (a middle subscriber stranded) implies a nested re-entry.
Report the nesting depth and log each new depth once instead of only the
first re-entry, and tag splitBehavior-derived behaviors with their field
name so the warning identifies which behavior tore.
2026-09-03 18:08:53 +01:00
Matthew Hodgson 2ab2197c01 Warn when a behavior is re-entered while delivering a value
rxjs delivers a nested emission to every subscriber and then resumes
delivering the outer, older value to the remaining subscribers, which
leaves them permanently out of sync. Log the first occurrence per
behavior with a stack trace so the re-entrant path can be identified
from a rageshake.
2026-09-03 17:26:38 +01:00
Valere ace78de749 Cover Element Call as a component with end-to-end tests
The widget tests cannot reach what makes a component different, because the
iframe used to guarantee it: that Element Call stays inside the space it was
given, and that two of them can exist in one page. So the development harness
gets driven by Playwright.

Three tests. Two components in one page holding a real call between two devices
of one account. The settings dialog and the reaction picker staying inside the
container the host gave, asserted by bounding box. And the host bridge
reporting in both directions, including a host-initiated mute coming back as a
report of the new state.

The containment test is the one worth having: both of the escapes found by
running the harness by hand — the settings dialog centred on the window, and
the reaction picker at 82vh landing below the container — would have failed it,
and neither was visible to typechecking, linting or the unit tests.

Users and rooms are created through the Synapse admin and client-server APIs
rather than by driving an interface, and the harness now takes its credentials
from its own query string so that a test can say which account and room to use.
A host reading its own URL is proper; it was Element Call doing so that was the
mistake.

Playwright gains a second web server for the harness on port 3001, a Vite dev
server whether or not the app itself is served from Docker, since the harness is
a development page with nothing to build.
2026-09-03 18:09:12 +02:00
Matthew Hodgson 0b95fd5a65 Log remote member participant matching and tile waiting state
A tile shows "Waiting for media" for as long as its MatrixRTC member
cannot be matched to a LiveKit participant. Log each transition of that
match and of the tile's waitingForMedia state so rageshakes can tie a
stuck tile to the LiveKit participant and track events.
2026-09-03 17:07:08 +01:00
Matthew Hodgson f8f5caaa09 Log remote participant and track events per LiveKit connection
Rageshakes contained nothing about the state of remote tracks, so a tile
showing the wrong mute or video state for a member could not be
diagnosed. Log connect/disconnect, publish/unpublish, subscribe/
unsubscribe, subscription failures, remote mute/unmute and stream state
changes on each Connection's logger, and remove the listeners when the
connection scope ends.
2026-09-03 16:50:30 +01:00
Valere 3361ce2b60 Keep what the component draws inside the container it was given
Opening settings in an embedded call put the dialog in the middle of the host's
window, spilling outside the container, and with two calls on a page the second
drew over the first's dialog.

The container established a stacking context but not a containing block, which
are two different things and only the first had been done. `position: fixed`
resolves against the viewport unless an ancestor makes itself the containing
block, so the modal scrim and dialog in Overlay.module.css — `fixed`, `inset:
0`, centred, because in the standalone app they are meant to cover the page —
were positioned and sized against the window. Layout and paint containment
makes the container the containing block for those descendants and clips what
we paint to our own box. The second-call-on-top symptom goes with it, since the
dialog now stays inside the first call's box and there is nothing to overlap.
Two sibling components still cannot draw over one another by construction,
neither being able to leave its own stacking context, but that only shows if a
host overlaps them.

Containment clips a box measured in viewport units but cannot resize it, so
anything positioned that way is simply put somewhere outside the container and
disappears. That applied to the reactions overlay, a `100vw` by `100vh` box, and
to the reaction picker, which sits at `82vh` so as to appear near the footer it
belongs to. Both are positioned against whatever Element Call treats as its
root — `[data-overlay-container]` in the app, which is the size of the page, and
the host's container when embedded — so percentages mean the same thing there
and the right thing here. The earpiece overlay is `inset: 0` with no viewport
units, so containment is enough for it.

Three viewport-relative sizes remain, all of which need more than a change of
unit: the lobby's video preview is `50vh` on a flex item with an aspect ratio,
`--content-inset-*` ramps up to a desktop inset from the window width, and the
picker's `max-width` cap is the window's.

The clipping cuts both ways: a menu near the edge of a small container is
trimmed rather than overflowing into the host. That is the trade an embedded
component makes.
2026-09-03 17:30:16 +02:00
Valere c0a54dcaf9 Derive the component's defaults from an intent, not the host's URL
The component seeded its parameters with `computeUrlParams()`, which reads
`window.location`. Element Call is not the page any more, so what it found
there was the host's URL: no `widgetId`, therefore not a widget, therefore no
intent, therefore the standalone app's preset.

The visible symptom was the Element Call logo in the footer of a call embedded
in someone else's application, since `showLogo` follows `header ===
HeaderStyle.Standard`. The rest of that preset mattered more. A hosted call
defaulted to `perParticipantE2EE: false` and `confineToRoom: false` — so
unencrypted, and willing to take the user out of the room a host had put them
in — and a host could not correct either without naming every parameter
itself, nor even name `header`, since the enums were not exported.

So the intent presets move out of `computeUrlParams` into
`configurationForIntent`, and the component builds its parameters from an
intent plus the properties a host has no URL to supply. `intent` becomes a
prop, defaulting to joining an existing group call: the lobby first, confined
to the room, encrypted per participant, and no Element Call branding in
someone else's interface. A host that knows which button the user pressed
should say which.

One deliberate difference from the widget presets: the background defaults to
solid rather than the gradient, which is drawn by a `position: fixed`
pseudo-element and would escape the container to cover the host.

`UserIntent.Unknown` still means the standalone preset, so the app and widget
are unchanged — including a widget that names no intent, which has always been
given those defaults.
2026-09-03 16:39:14 +02:00
Valere 9f5fa6049f Add a harness for Element Call embedded as a component
`pnpm dev:component` serves a page that stands in for a host application: it
signs in twice against the development backend and shows two calls side by
side, in resizable boxes, with furniture of its own around them. Two devices of
one account, so a real call happens between the two components and anything
Element Call keeps once per process rather than once per call shows itself.

The host bridge is driven by hand and reports both directions in a log along
the bottom, which is the first exercise the theme, hang-up and device-mute
requests have had outside widget mode. Each pane can be unmounted and remounted
to see what Element Call leaves behind, and there is a `position: fixed` dialog
belonging to the host to see whether it covers the calls. The page uses none of
Element Call's design tokens, so anything that looks styled outside a pane came
from Element Call reaching out of its container. It reaches Element Call only
through the component's public interface, which is how the exports missing from
that interface came to light.

Three things about the component build the harness turned up on the way, all
too small to be worth their own commits:

- It copied `public/` into `dist/`, including the developer's own gitignored
  config.json, into output we would publish. `publicDir: false`, as the
  embedded build already does. The sdk build has the same leak; untouched.
- `pnpm lint:externals` now exists, which the build config already claimed it
  did. It reads the external list out of that config and fails if the source
  imports React, the Matrix SDK or LiveKit by a path the list does not name.
  Since the bundler silently ignores the pattern form of that option, an
  unnamed subpath is bundled with no warning at all — which is how a host would
  end up with a second React.
- `lint:oxlint` ran over `src playwright`, so nothing in `component/` had ever
  been linted.

Serving a page also meant the shared plugin list could no longer inject the
app's HTML entry point unconditionally, so that is now optional — and off for
the library build too, which never had an HTML page to inject it into.
2026-09-03 16:11:39 +02:00
Valere db0f6837ce Give the component what the app shell was providing
The component built and typechecked in the previous commit, but only because
nothing had rendered it. Everything Element Call needs that `src/main.tsx`
side-loads was missing from it.

Its stylesheet: only main.tsx imported index.css, so the library build emitted
CSS-module styles with every `--cpd-*` and `--font-size-*` unresolved. Split
into base.css, which both the app and the component import, and the rules that
are about owning a page, which only the app does. The split is a straight move
— comment-stripped and sorted, the old file and the two new ones differ by
exactly one line — and that line is the deliberate part: `.no-scroll-body`
becomes `body.no-scroll-body`. Element Call adds that class to whatever it
treats as its root, and since the root can now be a container, `position:
fixed` would have taken that container out of the host's layout. Pinning the
page is what it always meant.

Its translations: `initializeElementCall` called `i18n.init` with neither
resources nor a backend, so every key would have rendered as itself. English is
bundled in. The app fetches locale files from URLs its own build emits, which a
host serving the library from somewhere else could not resolve, so how a host
picks a language is left open.

And the types a host needs: `HostBridge` alone is not enough to implement
`HostBridge` — `HostRequest`, `DeviceMuteState`, `DeviceMuteRequest` and
`JoinCallData` all appear in its signatures, and `ConfigOptions` in
`initializeElementCall`'s.
2026-09-03 16:10:26 +02:00
Matthew Hodgson bf5482db8c Surface screen share failures instead of silently doing nothing
toggleScreenSharing only had `.catch(logger.error)`, so a getDisplayMedia
request that hangs (element-call-rageshakes#17152: Element Desktop on
Windows, the user pressed the screen share button 14 times in 25 seconds
and the log shows nothing but the toggle lines and livekit-client's
"waiting for pending publication promise timed out") left the user with
a button that does nothing and us with no evidence of why.

Log when a toggle is requested and when it completes or fails, with the
elapsed time, so a hang is visible in the logs. Explicit failures other
than the user cancelling the picker show as a non-modal "Could not start
screen sharing" toast. Nothing is inferred from a toggle taking a long
time: the user may simply be choosing what to share.
2026-09-03 15:01:35 +01:00
Matthew Hodgson 2e5b5cb186 Don't attach the background blur processor to an ended camera track
If the camera track has already ended by the time the blur processor is
applied to it, MediaStreamTrackProcessor cannot be constructed and
setProcessor rejects. Both call sites used `void`, so this surfaced as

    Unhandled promise rejection: TypeError: Failed to construct
    'MediaStreamTrackProcessor': Input track cannot be ended

(element-call-rageshakes#17225). Skip ended tracks, and catch and log
processor attach/detach failures instead of leaking them.
2026-09-03 14:50:28 +01:00
Matthew Hodgson 8060d10fcc Don't report an aborted connect as a connection error
When the ConnectionManager stops a Connection while livekitRoom.connect()
is still pending (which happens on every join, because the local
membership emits twice in quick succession and the connection set is
recomputed), livekit-client rejects the pending connect with "Client
initiated disconnect". Connection.start() then treated that as a failure:
it pushed an UnknownCallError into the state of a connection that was
already stopped and rethrew, and since start() is fire-and-forget the
throw surfaced as

    Unhandled promise rejection: Error: Failed to connect to Livekit server

in every rageshake, right after a "livekitRoom.connect FAILED ... Client
initiated disconnect" line. Nothing was actually wrong: the replacement
connection connects fine a moment later.

Mark the connection as stopped before disconnecting, and have start()
return quietly when the rejection is the abort we asked for.
2026-09-03 14:48:23 +01:00
Valere 979b521563 Build Element Call as a component a host can import
Adds component/index.tsx as a fourth build target: <ElementCall client
roomId /> and an initializeElementCall to await once beforehand. It gives
Element Call everything it would otherwise take from the page it is on —
the parameters, the host bridge, media devices, translations, a container
to confine itself to — and hands it the host's client rather than finding
one of its own.

React, the Matrix SDK and LiveKit stay external, since the host has them
and a second copy of any would not merely be wasteful: React would hold
two sets of hooks and the client would run two sync loops. Every subpath
has to be listed by name, because the pattern and callback forms of
rollupOptions.external are silently ignored here — a lesson worth the
comment that records it.

Element Call's own navigation runs in a MemoryRouter, so being embedded
cannot disturb the host's URL. ClientContext and GroupCallView both
navigate, so some router has to be present.

The bundle is not yet a reasonable size: library mode base64-inlines
assets referenced through import.meta.url, so MediaPipe's vision runtime
lands in it whole. Left for its own change, since the fix — loading the
background blur transformer lazily — is worth doing for the standalone app
too.
2026-09-03 15:18:03 +02:00
Valere a166fbbd08 Let the component own its mute state
ElementCallView took muteStates as a prop, which would have meant an
embedder building one before it could show a call. It could not simply make
its own: RoomPage created one on mount whichever branch it went on to
render, and two would both report the user's mute state to the host,
talking over each other.

Move the construction into a useMuteStates hook, and give the lobby shown
while waiting to be let into a room its own component. Each lobby now holds
mute state only while it is on screen, so there is never a second one, and
the component can own the call's.

KnockLobbyView also takes the room summary and label handling that RoomPage
was assembling on its behalf, leaving the page with arriving at a call
rather than being in one.
2026-09-03 15:15:51 +02:00
Valere 856e055d30 Find Element Call's root by attribute, not by being the body
Six selectors named `body` directly — the gradient backdrop and the
platform font overrides in index.css, and the iOS adjustments in
AppBar.module.css and Modal.module.css — so they only applied when Element
Call owned the page. A host mounting it into a container would have got an
interface decorated correctly and styled incorrectly, with nothing to show
that anything was wrong.

Mark the root element with data-element-call-root and match on that
instead. Scoping this way keeps the selectors more specific than they were,
rather than less: widening them to a bare [data-platform=…] would have
dropped specificity from (0,1,1) to (0,1,0) and changed which rules win.

The platform attribute moves with them, from the initializer's write onto
document.body to a layout effect on the root, alongside the theme — so it
still lands before anything is painted.

No visual change while Element Call owns the page: the root is the body,
which now carries the attribute, so every rewritten selector matches the
element it always did.
2026-09-03 12:55:52 +02:00
Valere 1bfb018d90 Introduce ElementCallView
Being in a call and deciding to show one are different jobs, but RoomPage
did both: routing, authentication, resolving room aliases and knocking, and
then the call itself. Only the first set belongs to whatever is hosting
Element Call.

Add ElementCallView as the seam between them. It takes a client and a call
to join, and owns whether the user has joined — which is the call's own
business rather than its host's. RoomPage keeps everything about arriving
at a call and renders this for the call itself.

Nothing else moves yet. muteStates is still passed in, because the
standalone shell shares one with the lobby it shows while waiting to be let
into a room, and two instances would both report the user's mute state to
the host.
2026-09-03 12:10:04 +02:00
Valere ebb7fe07b7 add more test 2026-09-03 11:47:35 +02:00
Johannes Marbach d765267c43 Merge pull request #4229 from element-hq/matthew/fix-rageshake-flush
Fix periodic rageshake log flush never running
2026-09-03 07:29:51 +02:00
Matthew Hodgson 698a98a9c8 Test that logs are flushed to IndexedDB periodically 2026-09-02 18:55:18 +01:00
Valere 873dfdbfbd Drop the unused root element provider
RootElementProvider was exported but never used: nothing supplies a root
element, so every consumer falls back to the document body. Knip reports
it, which is what is failing CI.

M1 adds a provider back along with the component that mounts Element Call
into a container. Until then there is nothing to provide.
2026-09-02 19:46:44 +02:00
Matthew Hodgson 2db24e2868 Fix periodic rageshake log flush never running
The throttled flush callback returned this.flush instead of calling it
(regressed in #2607), so logs were only persisted to IndexedDB on
rageshake submission or beforeunload. When the host removes the widget
iframe at hangup, the whole call's logs were lost, so a rageshake filed
from a later call carries nothing from the affected one.
2026-09-02 18:46:12 +01:00
Valere e68d1d1b5f Say what the root element seam cannot do yet
RootElementContext's documentation promised that Element Call confines its
decoration to the given element, but several selectors still name body
directly and the initializer writes data-platform onto it. A non-body root
is decorated correctly and styled incorrectly, with no error to show for
it, so the documentation should say so until the stylesheets are scoped.
2026-09-02 19:28:14 +02:00
Valere b7efa02adc review: Follow a swapped client 2026-09-02 19:27:44 +02:00
Valere c807b8ef7d Always stop the widget transport when closing
close() sent io.element.close and then stopped the transport, so a
rejected send skipped the stop. Both call sites this replaced stopped it
unconditionally — ErrorView in a finally, GroupCallView outside its
try/catch — because a host that never acknowledges the request would
otherwise leave the messaging live and the close button doing nothing.

Restore that with a finally.
2026-09-02 19:26:59 +02:00
Valere 6b5f396e1e Share the mapping from parameters to call view model options
The SDK stopped sending join notifications: it threaded callIntent into
createCallViewModel$ but not its pair sendNotificationType, which
enterRTCSession used to read for itself, so an explicit
?sendNotificationType=ring — or an intent that implies one — no longer
reached joinRTCSession.

The mechanism is worth fixing rather than the instance. The defaults on
CallViewModelOptions describe a standalone Element Call, so a widget
caller that misses a field gets standalone behaviour rather than an error,
and the SDK is only ever a widget. Give both callers one shared mapping so
they cannot drift, and cover the whole chain from URL to options in tests.

autoLeaveWhenOthersLeft and waitForCallPickup stay out of it: the view
model never read those from the parameters, so enabling them for the SDK
would be a change in its behaviour rather than a fix.
2026-09-02 19:26:33 +02:00
Valere 182be8676d Return the widget from initializeWidget instead of assigning a global
Element Call reached the widget API through a mutable module-level
binding, which every consumer imported directly. Nothing outside the app
shell needs it any more, so hand it back from initializeWidget and thread
it through: the initializer returns it, main passes it to App, and App
uses it to build the host bridge and to await the client the host is
lending us.

ClientContext's loadClient is now only about restoring or creating a
session of Element Call's own, since a widget's client arrives as a prop
like any other host's would.

Also fixes an early return added in the previous commit, which skipped
starting the analytics settings listener when a client was supplied. That
was harmless until now, but would have stopped analytics following the
user's choices in widget mode.

sdk/main.ts asked the host to close by hand; it now uses the bridge, which
also stops the transport as the app does.
2026-09-02 16:56:09 +02:00
Valere f6f47ede62 Let a host supply Element Call's client
ClientProvider found its own client: from the widget API, or by restoring
or creating a session. A host that embeds Element Call already has one,
and owns the user's session, so accept it as a prop and skip all of that.

A supplied client seeds the state synchronously, since there is no session
of ours to restore and so nothing to wait for.

Also guard the broadcast that shuts down other instances of the app. It
protects Element Call's own session and crypto stores, which is why it was
already skipped in widget mode — a host's client has the same property, so
without this an embedded Element Call would close down the user's other
tabs on mount.

Adds the first tests for ClientContext, covering both
2026-09-02 15:14:10 +02:00
Valere eb117249d1 Configure analytics explicitly instead of discovering it
PosthogAnalytics read its own configuration out of the environment on
first use: the URL parameters, config.json, and the widget global. An
embedded Element Call has none of those to offer, and analytics that
configure themselves cannot be switched off by a host that does its own
reporting.

Take an AnalyticsConfig through PosthogAnalytics.configure() instead,
called from the initializer once the config has loaded. Unconfigured
analytics stay off.

Note the two halves of that config are decided differently, and have to
be: where the credentials come from depends on the package, but who owns
the user's analytics identity depends on how Element Call is running,
since the full package can be used as a widget too.

Drop the widget check around cryptoVersion, which never did anything —
widget mode never initialises crypto, so getCrypto() is already undefined
there.

Move the tests covering which package reads which credential source onto
analyticsConfigFromEnvironment, where that decision now lives.
2026-09-02 15:05:12 +02:00
Valere f28d9e9b06 Stop asking whether Element Call is a widget
The remaining reads of the widget global were all asking one of two
different questions, so they get two different answers.

The app shell — the auth hooks, automatic guest registration, the group
call loader's diagnostic and the initial mute state — wants to know
whether Element Call was launched as a widget. That is a property of the
URL it was launched with, so expose the isWidget that computeUrlParams
already computed internally, documented as being for shell use only.

The call interface — whether to offer the profile settings tab — wants to
know something about its host, so it asks the bridge. A host that can
dismiss Element Call owns the user's account, so their profile is not ours
to edit; this reuses the close capability as a proxy, with a TODO
alongside the others.

ClientContext also takes supportsReactions from the bridge rather than
checking four widget capabilities itself, which removes widgetApi from
InitResult — a field that was always null outside widget mode.

Note this changes behaviour for a malformed widget URL: one carrying a
widget ID and parent URL but missing the room, user, device or base URL
would previously have fallen back to registering a guest user, and will
now not.
2026-09-02 15:04:24 +02:00
Valere bc6c232ef0 Move the state layer onto the host bridge
MuteStates, CallViewModel and LocalMember reached the host through the
widget global. None of them are React components, so they take the bridge
as an explicit parameter: a constructor argument for MuteStates, a field
on CallViewModelOptions, and one on createLocalMembership$'s props.

src/state no longer refers to the widget API.

The conditionals around it mostly disappear: nullHostBridge's observables
are NEVER, so there is nothing to guard, and a request carries its own
reply rather than needing the transport and the original event.

CallViewModelWidget.test.ts drove hangup by emitting on the mocked
widget's action emitter, so it now injects a bridge instead, and checks
that the request is acknowledged.
2026-09-02 13:23:01 +02:00
Valere 8e78ac76bd Drop ErrorView's widget prop in favour of the host bridge
ErrorView needed a widget only to decide whether to offer a close button
or a link home. That prop was threaded down through ErrorPage, RichError
and GroupCallErrorBoundary from seven call sites, to answer the single
question of whether the host can dismiss Element Call — which the host
bridge now answers directly through the presence of close().

Read the bridge from context in ErrorView and remove the prop, along with
the plumbing that carried it.

No functional change: the rendered output is unchanged, as the existing
snapshot confirms.

Move GroupCallView onto the host bridge

GroupCallView asked the widget API to keep it on screen, to close it, and
to tell it when a preloaded call should join. Route all three through the
host bridge and drop the widget prop.
2026-09-02 13:03:23 +02:00
Valere d8d70812b8 Read the shared room key from the parameters context
useRoomEncryptionSystem is used from GroupCallView, inside the part of
Element Call that will become the embeddable component, but it reached for
getUrlParams() via getKeyForRoom(). Extract the lookup into a helper taking
the room ID and password explicitly: the hook supplies them from the
parameters context, while getKeyForRoom keeps reading the URL for its one
remaining caller in the app shell.

No functional change.
2026-09-02 11:00:42 +02: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 bc6015eff2 Supply Element Call's parameters through a context
Element Call's parameters come from its URL, which works while it owns
the page but leaves an embedder with nowhere to put them. Add a context
so they can be provided directly, falling back to parsing
window.location when no provider is present.

This also decouples the thirteen consumers from react-router: useUrlParams
called useLocation, so each of them required a router ancestor, which the
embedded build will not have. The standalone and widget builds keep their
URL-derived behaviour via useUrlParamsFromLocation, provided in App.

No functional change.
2026-09-02 09:58:34 +02:00
Valere 0dca5835f6 Route Element Call's DOM decoration through an injectable root element
Element Call writes its theme classes, background and layout attributes
straight onto document.body, and portals its modals there too. That is
only correct while it owns the page; embedded in a host application it
has to confine itself to the container it was mounted into.

Add a RootElementContext, defaulting to document.body so that the
standalone and widget builds are unaffected, and point the theme classes,
data-background, no-scroll-body and the fullscreen target at it.

Give the Modal and Toast portals an explicit container as well. Radix and
vaul both default to document.body, so without this every modal, drawer
and toast would render outside the container and lose the theme and
platform attributes set on it.

No functional change: the root element is document.body until an embedder
provides otherwise.
2026-09-01 18:54:27 +02:00
Valere 0a8c24bca8 Allow the config to be supplied by an embedder
Config.init() derives the location of config.json from window.location,
which only makes sense while Element Call owns the page. When it is
embedded in a host application the host owns the configuration, so add
Config.initWith() to accept it directly.

Share the defaulting and validation between both paths via resolveConfig(),
so that an injected config behaves identically to a fetched one, and mark
initialization as complete so that the init() calls already on the startup
path resolve immediately instead of fetching over the top of it.

initDefault() becomes initWith({}), which also stops it handing out a
shallow copy of DEFAULT_CONFIG whose nested objects were shared with the
module-level default.
2026-09-01 18:40:53 +02:00
Valere 7485b3d71f Use a dedicated i18next instance instead of the global singleton
Element Call configured the global i18next singleton. When Element Call
runs embedded in a host application rather than as its own page, that
singleton belongs to the host, so configuring it would clobber the
host's translations.

Create Element Call's own instance in utils/i18n.ts, configure it in the
initializer, and pass it to components via <I18nextProvider>. Drop
.use(initReactI18next) from the initializer: it registers the instance
as react-i18next's global default, which is the global we are trying to
avoid. Tests and stories keep using it, so that they do not need to wrap
every render in a provider.

Two modules imported `t` directly from "i18next" and so were bound to
the global instance: utils/errors.ts now calls i18n.t() on the instance
(reached at call time, since i18next only assigns `t` during init), and
QrCode uses useTranslation() like every other component.

No functional change.
2026-09-01 18:30:05 +02:00
renovate[bot] efdee7dcdb Update ghcr.io/element-hq/element-web:develop Docker digest to c107ec3 (#4221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-01 02:53:52 +00:00
Johannes Marbach d7d3dcde58 Merge pull request #4219 from element-hq/renovate/matrix-widget-api
Update dependency matrix-widget-api to v1.19.0
2026-08-31 07:34:07 +02:00
renovate[bot] 9330b907fc Update ghcr.io/element-hq/element-web:develop Docker digest to 7c5eb96 (#4218)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-31 00:49:32 +00:00
renovate[bot] 256ff7a0b6 Update dependency matrix-widget-api to v1.19.0 2026-08-31 00:40:41 +00:00
renovate[bot] 6ddcc15206 Update ghcr.io/element-hq/element-web:develop Docker digest to e8727bb (#4216)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-30 01:09:28 +00:00
renovate[bot] a56e934841 Update ghcr.io/element-hq/element-web:develop Docker digest to e29b408 (#4215)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-29 02:25:08 +00:00
Timo efde51b8c1 Merge pull request #4172 from element-hq/toger5/add-key-rotation-participant-limit
Add key rotation participant limit to devtools and config.json
2026-08-28 16:38:20 +02:00
Timo K. 2a7c6c3c06 Oh dear test coverage... 2026-08-28 16:22:08 +02:00
Timo K. 5bab17b668 Update InCallView.tsx 2026-08-28 15:52:52 +02:00
Timo K. d7d28a1b55 formatting 2026-08-28 15:50:48 +02:00
Timo K. 790bd1e2bf Update LocalMember.test.ts 2026-08-28 15:44:46 +02:00
Timo K. 17231e545c Update DeveloperSettingsTab.test.tsx 2026-08-28 15:38:57 +02:00
Timo K. 17d9d19c91 ObservableScope -> testScope 2026-08-28 15:32:59 +02:00
Timo K. 3d37abf490 merge two tests 2026-08-28 15:31:23 +02:00
Timo K. 92f504d886 remove oldest membership mocking 2026-08-28 15:29:16 +02:00
Timo K. b0d098e065 Merge branch 'main' into toger5/add-key-rotation-participant-limit 2026-08-28 15:27:43 +02:00
Timo K. a526a8ae19 Update config.sample.json 2026-08-28 15:26:00 +02:00
Timo K. 1146d3820a review. Dont pass full vm to developer settings 2026-08-28 15:20:49 +02:00
renovate[bot] a4dda428f5 Update ghcr.io/element-hq/element-web:develop Docker digest to 133160c (#4213)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-28 03:01:16 +00:00
renovate[bot] 5982586f24 Update ghcr.io/element-hq/element-web:develop Docker digest to f163e7a (#4211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-27 01:06:37 +00:00
Robin e6b4aae714 Merge pull request #4208 from element-hq/remove-legacy-mode
Remove MatrixRTC legacy mode
2026-08-26 20:27:46 +02:00
Robin ede29bdf1b Remove MatrixRTC legacy mode
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.
2026-08-26 19:51:12 +02:00
Robin b5b2bd2193 Merge pull request #4207 from element-hq/legacy-member-events
Remove feature_use_device_session_member_events
2026-08-26 19:49:20 +02:00
Robin 21ca382306 Fix tests 2026-08-26 19:14:19 +02:00
Robin 25e379546e Retry CI 2026-08-26 18:32:14 +02:00
Robin 0443ef55d1 Remove feature_use_device_session_member_events
Support for events with an array of memberships from different devices was removed over a year ago in matrix-js-sdk ffd3c9575e9def576739baf6b1dc329b0db55c0c.
2026-08-26 17:05:38 +02:00
renovate[bot] 465c413691 Update ghcr.io/element-hq/element-web:develop Docker digest to 0332028 (#4204)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-26 09:54:28 +02:00
Timo K. 06b9105cee Update DeveloperSettingsTab.test.tsx 2026-08-25 23:32:22 +02:00
Timo K. 2b5979162a add more tests 2026-08-25 23:30:22 +02:00
Timo K. 5399f14012 add tests 2026-08-25 22:43:15 +02:00
Timo K. f2ffb06f6c use develop branch of matrix-js-sdk 2026-08-25 22:03:59 +02:00
Johannes Marbach 6cf0e1df51 Merge pull request #4196 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v10.2.4
2026-08-24 11:00:01 +02:00
renovate[bot] bfa20ef747 Update ghcr.io/element-hq/element-web:develop Docker digest to ccee84c (#4195)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-24 09:35:45 +02:00
Johannes Marbach 5955d22c1b Merge pull request #4197 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.22.0
2026-08-24 08:51:19 +02:00
renovate[bot] ce4426858b Update dependency livekit-client to v2.22.0 2026-08-24 00:37:56 +00:00
renovate[bot] 4ec75ecda4 Update dependency @vector-im/compound-design-tokens to v10.2.4 2026-08-24 00:37:19 +00:00
Timo b51a33c4e1 Merge pull request #4194 from element-hq/toger5/rtc-mode-documentation
Add docs about currently used matrixRTC mode
2026-08-21 17:44:10 +02:00
Timo K. c3837464a3 Add docs about currently used matrixRTC mode 2026-08-21 12:04:24 +02:00
Timo e7372d4c03 Merge pull request #4190 from element-hq/toger5/update-branche-ci-main
`livekit` -> `main` Update branches used in ci and tooling to main
2026-08-21 11:55:32 +02:00
renovate[bot] 69eddd7846 Update ghcr.io/element-hq/element-web:develop Docker digest to ee5b90c (#4193)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 07:10:30 +02:00
Timo K. de3e4c6a78 update branches used in ci and tooling to main 2026-08-20 15:44:13 +02:00
Robin 3abc5a0435 Merge pull request #4185 from element-hq/pip-no-modals
Hide reactions interface in PiP mode
2026-08-20 15:16:22 +02:00
Johannes Marbach 8e20d48b1d Merge pull request #4187 from element-hq/johannes/label-sync-pat
Switch label sync workflow to LABEL_SYNC_GITHUB_TOKEN
2026-08-20 10:05:12 +02:00
Johannes Marbach ff57c217aa Switch label sync workflow to LABEL_SYNC_GITHUB_TOKEN 2026-08-20 09:21:42 +02:00
renovate[bot] b60e7452b7 Update ghcr.io/element-hq/element-web:develop Docker digest to a416986 (#4186)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-20 07:14:58 +02:00
Robin 1c03ad335c Hide reactions interface in PiP mode 2026-08-19 17:44:45 +02:00
Robin 87873b726f Merge pull request #4183 from element-hq/msc4519-docs
Update docs to reflect transports endpoint moving to MSC4519
2026-08-19 15:58:28 +02:00
Robin 3448a3a2ef Update docs to reflect transports endpoint moving to MSC4519
This is linked from the 0.24.0 release notes, so even more important for it to be up to date.
2026-08-19 11:48:48 +02:00
Robin c625fb8845 Merge pull request #4180 from element-hq/background-pngs
Performance: Use PNGs for the background gradients
2026-08-19 10:40:07 +02:00
Robin cab9698fc7 Undo breakpoint change made during testing 2026-08-19 10:24:26 +02:00
Robin 7410bd8a82 Merge pull request #4181 from element-hq/lobby-video-border
Fix lobby video preview losing its rounded corners in Firefox
2026-08-19 08:54:57 +02:00
renovate[bot] f17670b731 Update ghcr.io/element-hq/element-web:develop Docker digest to 9ac7cde (#4182)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-19 08:09:58 +02:00
Robin 33a0653ea5 Fix lobby video preview losing its rounded corners in Firefox
Same fix as e1bc4a096b, but for the video preview in the lobby.
2026-08-18 17:49:14 +02:00
Robin b1c29e9a41 Performance: Use PNGs for the background gradients
It turns out that for a blurry gradient background, low-res raster images look very convincing when scaled up and interpolated. That means that we can rasterize our gradient SVGs for improved paint performance when resizing the window, while still keeping them quite lightweight (just a couple of kilobytes each).
2026-08-18 17:30:12 +02:00
Robin ad92892063 Merge pull request #4177 from element-hq/ignore-layout-updates
Performance: Ignore redundant layout updates
2026-08-18 15:39:49 +02:00
Robin 1a827e0930 Merge pull request #4178 from element-hq/tiles-debug-performance
Performance: Isolate tile store debug info in its own component
2026-08-18 13:05:02 +02:00
Robin a1b37bb3c9 Performance: Ignore redundant layout updates
When someone starts or stops speaking, the layout will often be recomputed only to find out that there is ultimately no layout change. We can ignore these redundant updates to avoid re-rendering the InCallView and Grid components, which are relatively slow.

For that specific, common case, this reduces JS CPU usage by as much as 70% in my testing.
2026-08-18 08:42:59 +02:00
renovate[bot] 061d25a54c Update ghcr.io/element-hq/element-web:develop Docker digest to 073e6a4 (#4176)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-18 07:48:41 +02:00
Robin b554fa63d1 Performance: Isolate tile store debug info in its own component
It's very uncommon to have this debug option enabled, and yet it currently causes the footer to re-render on every layout update, which is a small but avoidable cost.
2026-08-17 16:45:26 +02:00
Robin b5bcb9aeed Merge pull request #4160 from alexmaras/room-joining/assume-public
Room joining: if join_rule is absent, assume public
2026-08-17 14:40:07 +02:00
Timo 3d3e6dcdcc Merge pull request #4171 from element-hq/toger5/fix-unclose-able-error-screen
Fix: error screen cannot be closed in embedded mode.
2026-08-17 14:16:37 +02:00
Timo K. 9999a755dd Update pnpm-lock.yaml 2026-08-17 12:33:31 +02:00
Timo K. 43ce68e80a Fix: error screen cannot be closed in embedded mode. 2026-08-17 12:08:30 +02:00
Robin 6d5f698357 Merge pull request #4151 from element-hq/more-more-performance
Performance: Fit video to frame without polling RTP stats
2026-08-17 11:36:37 +02:00
Robin 64a5b2ee5c Clarify how an invalid width and height manifest 2026-08-17 11:19:43 +02:00
Timo K. 9857ed53e3 Add key roatation limit to config.json 2026-08-17 11:17:22 +02:00
Timo K. 0aa9d94826 add key rotation debug information 2026-08-17 11:17:22 +02:00
Timo K. f2622f0032 Add vm to developer settings tab 2026-08-17 11:17:22 +02:00
Robin c0d5f2d470 Merge branch 'livekit' into more-more-performance 2026-08-17 11:12:17 +02:00
Robin 4a5141406e Merge pull request #4152 from element-hq/more-more-more-performance
Performance: Disable animations when there are a large number of tiles
2026-08-17 11:11:39 +02:00
Robin b036d1c0c0 Merge pull request #4169 from element-hq/renovate/major-compound
Update dependency @vector-im/compound-web to v10
2026-08-17 09:25:18 +02:00
Robin 0cfe6cb03d Merge pull request #4168 from element-hq/renovate/livekit-components
Update LiveKit components
2026-08-17 09:21:33 +02:00
renovate[bot] 8be8cf08bf Update ghcr.io/element-hq/element-web:develop Docker digest to abd6473 (#4165)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-17 09:19:40 +02:00
renovate[bot] 9a772131b6 Update dependency @vector-im/compound-web to v10 2026-08-17 00:38:58 +00:00
renovate[bot] 1cdd5d8db0 Update LiveKit components 2026-08-17 00:38:39 +00:00
renovate[bot] fc9e13c922 Update ghcr.io/element-hq/element-web:develop Docker digest to 6176839 (#4163)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-14 12:49:32 +02:00
Robin 580897730a Merge pull request #4150 from element-hq/more-performance
Performance: Avoid re-rendering context menus so often
2026-08-12 17:30:13 +02:00
Robin 6f7dac31d6 Merge pull request #4153 from element-hq/valere/rtc/remove_well_known_fallback
Remove .well-known transport discovery
2026-08-11 18:24:03 +02:00
Robin 78e4881c37 Enable MatrixRTC transports endpoint in dev and testing configs 2026-08-11 18:03:28 +02:00
Alex Maras 1bb342e9e1 Room joining: if join_rule is absent, assume public 2026-08-11 21:24:38 +08:00
Robin 7ca68fb5bd Merge branch 'livekit' into valere/rtc/remove_well_known_fallback 2026-08-11 12:29:36 +02:00
Timo 72e7e0f406 Merge pull request #3736 from emmick4/livekit
feat: advanced media quality settings UI and config-driven defaults
2026-08-11 12:27:12 +02:00
Robin 94a1d87813 Merge pull request #4158 from element-hq/spotlight-performance
Performance: Avoid re-rendering entire spotlight layout so often
2026-08-11 12:24:42 +02:00
Robin fee54a09c3 Merge branch 'livekit' into valere/rtc/remove_well_known_fallback 2026-08-11 11:45:26 +02:00
Robin 72a327f12f Merge pull request #4135 from element-hq/valere/widget_rtc_transport_action
Use widget API action to get transports in widget mode
2026-08-11 11:41:35 +02:00
Robin 7f8d8027dc Request capability to get RTC transports over widget API 2026-08-11 11:23:50 +02:00
Ryan Emmick cbc12b0365 Merge remote-tracking branch 'upstream/livekit' into livekit 2026-08-11 02:50:16 -05:00
Robin 414ae266ab Merge branch 'livekit' into valere/widget_rtc_transport_action 2026-08-11 09:48:22 +02:00
renovate[bot] ecca5e1e13 Update ghcr.io/element-hq/element-web:develop Docker digest to f25f10f (#4159)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-11 09:25:55 +02:00
Ryan Emmick 1d12e10628 Merge remote-tracking branch 'upstream/livekit' into livekit 2026-08-10 12:12:18 -05:00
Ryan Emmick 89cabf9fa2 test: cover rageshake media quality metadata and preset edge cases 2026-08-10 11:41:26 -05:00
Robin 7ca8059b0f Remove unused access token mocks 2026-08-10 17:10:31 +02:00
Timo K. 29ea90f800 add rageshake metadata and log 2026-08-10 15:48:53 +02:00
Robin 426ea30fe1 Remove all references to .well-known transport advertisement 2026-08-10 15:10:49 +02:00
Robin 7d6a0da6a9 Remove outdated tests 2026-08-10 14:33:14 +02:00
Robin ea31f073a7 Merge branch 'valere/widget_rtc_transport_action' into valere/rtc/remove_well_known_fallback 2026-08-10 14:32:44 +02:00
Timo K. b0d08cb0b5 update order in developer settings tab 2026-08-10 14:22:04 +02:00
Timo K. 88e5a5badb More resolution tests. 2026-08-10 14:21:49 +02:00
Robin 296c735500 Merge branch 'livekit' into valere/widget_rtc_transport_action 2026-08-10 13:43:42 +02:00
Robin 341c508a42 Remove outdated tests 2026-08-10 13:22:37 +02:00
Robin 78e585c5f4 Update matrix-js-sdk to support RTC transport discovery over widget API
Pulls in commit 0d8558de2c682a8cd719d385bfa0b5c01f2fb69e from matrix-js-sdk
2026-08-10 13:14:45 +02:00
Robin 81da4c9093 Remove need to approve builds of matrix-js-sdk after every update 2026-08-10 13:13:58 +02:00
Robin 064a88b9c7 Update pnpm to 11.21.0 2026-08-10 13:11:14 +02:00
Robin 14fd8c179b Fix formatting 2026-08-10 12:55:29 +02:00
renovate[bot] 4a146ebada Update ghcr.io/element-hq/element-web:develop Docker digest to 5c9a7f0 (#4157)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-10 11:41:51 +02:00
Robin a6a02778a1 Performance: Avoid re-rendering entire spotlight layout so often
This removes a lot of unnecessary jank in spotlight layout when swapping individual speakers in and out of the spotlight tile.
2026-08-10 11:16:35 +02:00
Ryan Emmick 662259154a Merge remote-tracking branch 'upstream/livekit' into livekit 2026-08-07 03:16:12 -05:00
renovate[bot] 978ffee183 Update ghcr.io/element-hq/element-web:develop Docker digest to a23cced (#4155)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-07 09:28:35 +02:00
Ryan Emmick 3ace4ab5a3 Merge remote-tracking branch 'upstream/livekit' into livekit 2026-08-06 02:53:13 -05:00
renovate[bot] 2d64cf4b30 Update ghcr.io/element-hq/element-web:develop Docker digest to 6fb12e1 (#4154)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-06 09:38:48 +02:00
Ryan Emmick 87aee1c02c test: update developer settings snapshot after merge 2026-08-05 12:05:41 -05:00
Ryan Emmick f7cf674152 Merge remote-tracking branch 'upstream/livekit' into livekit 2026-08-05 11:55:38 -05:00
Valere 9d5ca297e3 Remove well-known discovery 2026-08-05 16:12:41 +02:00
Robin c90d1d8dda Expand GridTile test coverage 2026-08-05 12:08:18 +02:00
Robin dd59519a85 Performance: Disable animations when there are a large number of tiles
I don't believe this affects the cost of running the useSprings hook, but it at least skips the animation frames that would otherwise follow, so it's worth a try.
2026-08-05 11:49:55 +02:00
Robin 33fc8997f8 Performance: Use a shared timer for polling RTP stats
This is now only relevant in case the user has enabled the developer option to show advanced media statistics, but still an easy performance fix.
2026-08-05 11:18:25 +02:00
Robin 8aead74ab9 Performance: Lower the RTP stats refresh interval
Because we no longer use it for computing the fit to frame setting; it's only for developer tools.
2026-08-05 11:18:22 +02:00
Robin 1e128c4da0 Performance: Fit video to frame without polling RTP stats
It turns out that the timers which repeatedly poll the RTP stats of each video track all run independently of each other and can add up to a small but constant sink of CPU. Meanwhile we can replace these timers with HTMLVideoElement 'resize' event listeners, which is way more efficient and reacts instantly to orientation changes.
2026-08-05 11:18:22 +02:00
Robin eb65a28a75 Merge pull request #4146 from element-hq/performance
Performance: Enable React Compiler
2026-08-05 11:10:40 +02:00
Robin 9d400323d0 Clarify why certain tests disable the React Compiler 2026-08-05 10:54:49 +02:00
renovate[bot] 6d7d3093b3 Update ghcr.io/element-hq/element-web:develop Docker digest to b4e2d2d (#4149)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-05 10:16:05 +02:00
Robin 2b07e9e822 Merge pull request #4148 from element-hq/renovate/i18next-26.x
Update dependency i18next to v26
2026-08-04 22:49:21 +02:00
renovate[bot] 7ae1fc6cd8 Update dependency i18next to v26 2026-08-04 17:21:53 +00:00
Robin e1df71817a Performance: Avoid re-rendering context menus so often
A change in a tile's speaking indicator could cause its entire tree of context menu components to re-render, which is expensive. Isolating the behavior subscriptions in their own component avoids this.
2026-08-04 17:57:25 +02:00
Robin 608695fc95 Performance: Enable React Compiler
With the React Compiler, our component code is transformed at build time to automatically apply various forms of memoization. This changes the runtime semantics of our code a little bit and therefore could surface new bugs in the next release cycle in case any components fail to follow the rules of React. See https://react.dev/learn/react-compiler for more information.

This results in a small bundle size increase and modest performance gains, but I think it's worth it given the potential for larger performance gains once we tune the component structure a bit more.
2026-08-04 17:57:23 +02:00
Robin a08a577e18 Merge pull request #4138 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-08-04 17:19:28 +02:00
Robin 55b2d2b130 Remove possibility for CI Playwright version to get out of sync 2026-08-04 17:04:07 +02:00
renovate[bot]andRobin 5b84b2c04d Update ghcr.io/element-hq/element-web:develop Docker digest to 3daefff (#4116)
* Update ghcr.io/element-hq/element-web:develop Docker digest to 0183c0a

* Update end-to-end tests to work with auto-collapsing room list

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robin <robin@robin.town>
2026-08-04 12:35:18 +00:00
Robin 3af0744324 Merge branch 'livekit' into renovate/all-minor-patch 2026-08-04 14:20:13 +02:00
Robin 07567ed31d Merge pull request #4118 from element-hq/renovate/livekit-components
Update LiveKit components
2026-08-04 14:05:47 +02:00
Robin d6e097476e Address linter finding 2026-08-04 13:51:56 +02:00
Robin 540eb306f4 Fix unit tests 2026-08-04 13:48:52 +02:00
Robin f62428ba0d Update code formatting 2026-08-04 13:43:38 +02:00
renovate[bot] d579169d54 Update all non-major dependencies 2026-08-04 11:39:13 +00:00
Robin 8daaa649eb Merge pull request #4147 from element-hq/renovate/npm-postcss-vulnerability
Update dependency postcss to v8.5.23 [SECURITY]
2026-08-04 13:36:56 +02:00
Robin 2d5a4eefec Merge pull request #4139 from element-hq/renovate/posthog
Update dependency posthog-js to v1.408.2
2026-08-04 13:26:18 +02:00
renovate[bot] d550430c8a Update dependency postcss to v8.5.23 [SECURITY] 2026-08-04 11:11:52 +00:00
Robin 78724acfcf Merge pull request #4140 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v9.9.0
2026-08-04 13:10:48 +02:00
Robin 20c7112812 Merge pull request #4141 from element-hq/renovate/matrix-widget-api
Update dependency matrix-widget-api to v1.18.0
2026-08-04 13:09:58 +02:00
renovate[bot] a7c996f3ea Update dependency posthog-js to v1.408.2 2026-08-04 11:07:26 +00:00
Valere Fedronic 4fbcbb4849 Merge pull request #4136 from element-hq/valere/fix_4132
fix: FF mirrored self video lose rounding
2026-08-03 13:53:04 +02:00
Robin 74102ac6c2 Merge pull request #3075 from hughns/defaut-server-config
Remove default server config as it is not likely to be correct
2026-08-03 10:49:49 +02:00
Robin 11a6fa9b45 Fix tests 2026-08-03 10:32:52 +02:00
Robin 507a6f29a5 Merge branch 'livekit' into defaut-server-config 2026-08-03 10:29:41 +02:00
renovate[bot] e725bc5de3 Update dependency matrix-widget-api to v1.18.0 2026-08-03 03:03:18 +00:00
renovate[bot] c15d4c50a1 Update dependency @vector-im/compound-web to v9.9.0 2026-08-03 03:02:53 +00:00
Valere e1bc4a096b fix: FF mirrored self video lose rounding 2026-07-31 12:20:32 +02:00
renovate[bot] b524de9298 Update LiveKit components 2026-07-30 20:51:22 +00:00
Robin bfb5fb922f Merge pull request #4134 from element-hq/renovate/npm-postcss-vulnerability
Update dependency postcss to v8.5.18 [SECURITY]
2026-07-30 11:01:41 +02:00
renovate[bot] 3f4d55343a Update dependency postcss to v8.5.18 [SECURITY] 2026-07-30 08:45:15 +00:00
Robin 73d8d2c2c3 Merge pull request #4120 from element-hq/johannes/i18n-download-fixes
Apply correct GH label and fix ordering issue in i18n download
2026-07-30 10:45:09 +02:00
Robin fcfe73c50d Merge pull request #4117 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.21.0
2026-07-30 10:43:24 +02:00
Valere ffb6b0a5f6 Use rtc transport action with widgets 2026-07-30 10:43:09 +02:00
renovate[bot] 5564015a8b Update dependency livekit-client to v2.21.0 2026-07-28 18:56:05 +00:00
Robin 62eeb10d38 Merge pull request #4130 from element-hq/landscape-default-grid
Only show layout switch when it has an effect on the layout
2026-07-28 15:28:06 +02:00
Robin 2de7fdde10 Fix layout switches not showing their state on the combined docs page
On the combined Storybook docs page for the call footer, the layout switches would not show the correct state until you hovered over them because they all shared the same input name and thus were interpreted as belonging to the same radio group.
2026-07-28 15:06:15 +02:00
Robin 5a96d1769e Only show layout switch when it has an effect on the layout 2026-07-28 15:06:15 +02:00
Robin a443a55bec Factor out a layout switch view + view model
So it can easily be shown and hidden wholesale.
2026-07-28 15:06:15 +02:00
Robin 9b2d9fdd1f Merge pull request #4129 from element-hq/landscape-default-grid
Prefer grid mode in landscape on mobile
2026-07-28 14:29:30 +02:00
Robin 05ad9b2475 Merge pull request #4128 from element-hq/landscape-default-grid
Use a proper one-on-one layout for landscape mobile calls
2026-07-28 14:08:48 +02:00
Robin 7962d02be5 Prefer grid mode in landscape on mobile 2026-07-28 11:56:01 +02:00
Robin 5c35288162 Turn the local video tile landscape in landscape mobile one-on-one calls 2026-07-28 11:53:26 +02:00
Robin aa6732da19 Use an actual one-on-one layout in landscape on mobile 2026-07-28 11:53:26 +02:00
Valere Fedronic 65ac11e952 Merge pull request #4125 from element-hq/valere/bug_poster_safari
fix: Safari preview tile no video is 16px wide only
2026-07-28 10:55:01 +02:00
Robin 0b21cff020 Rename one-on-one layouts to be orientation-agnostic 2026-07-27 18:28:52 +02:00
Robin 062e0a00fb Remove unused variables from CallViewModel tests 2026-07-27 18:13:51 +02:00
Valere 53ae78c609 break ratio when tile bigger than screen 2026-07-27 17:25:56 +02:00
Valere b046c4b569 fix: Safari preview tile no video is 16px wide only 2026-07-27 15:43:35 +02:00
Johannes Marbach 46cb89b232 Apply correct GH label and fix ordering issue in i18n download 2026-07-20 17:38:14 +02:00
ElementRobot e20abb19fb Merge pull request #4119 from element-hq/actions/localazy-download
Localazy Download
2026-07-20 16:23:58 +01:00
Johannes Marbach bf76f47357 delint 2026-07-20 17:03:55 +02:00
Johennes 9c2d3d067d Translations updates 2026-07-20 14:58:37 +00:00
Robin ae7ede3201 Merge pull request #4113 from element-hq/vulnerable-dependencies
Resolve most existing Dependbot warnings
2026-07-16 09:28:13 +02:00
Robin e5ff431b7a Merge pull request #4112 from element-hq/disable-poster
Hide the browser's default placeholder image for videos
2026-07-16 09:21:27 +02:00
Robin 66a676f2f5 Resolve most existing Dependbot warnings 2026-07-15 18:05:06 +02:00
Robin d33dedd038 Hide the browser's default placeholder image for videos
Source: https://stackoverflow.com/a/79058682
2026-07-15 17:26:02 +02:00
renovate[bot]andRobin 1f2837f86a Update ghcr.io/element-hq/element-web:develop Docker digest to 07ccf47 (#4111)
* Update ghcr.io/element-hq/element-web:develop Docker digest to d184182

* Target the toast 'Join' button specifically in end-to-end tests

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robin <robin@robin.town>
2026-07-15 14:34:34 +00:00
Robin 927cf68110 Merge pull request #4109 from element-hq/service-interruptions-vm
Create service interruptions view model
2026-07-14 12:21:18 +02:00
Robin cd72ad0008 Create service interruptions view model 2026-07-14 12:02:36 +02:00
Robin 2d2e85e340 Merge pull request #4107 from element-hq/spotlight-icon
Update spotlight icon
2026-07-14 09:34:50 +02:00
Johannes Marbach 4da1b9a02a Merge pull request #4082 from element-hq/johannes/docker-compose-renovate
Make renovate track docker-compose files and pin synapse / element-web for playwright tests
2026-07-14 07:55:17 +02:00
Robin 73758f7f77 Merge pull request #4108 from element-hq/renovate/compound
Update Compound
2026-07-13 18:37:15 +02:00
Robin c433c36687 Update snapshots 2026-07-13 18:20:56 +02:00
Robin 3e9d7b7cf7 Exclude packages developed in-house from release age requirements 2026-07-13 17:00:02 +02:00
renovate[bot] 2a56d2afb8 Update Compound 2026-07-13 14:35:37 +00:00
Robin bff41ad66a Update spotlight icon 2026-07-13 12:22:44 +02:00
Robin 1d088911e1 Merge pull request #4105 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v9.7.1
2026-07-13 11:10:21 +02:00
Timo f23eb96555 Merge pull request #4025 from mvanhorn/fix/3915-settings-tabbar-announce-position
fix: announce tab count and position in settings tab bar
2026-07-13 10:16:52 +02:00
renovate[bot] 0d4e7defb6 Update dependency @vector-im/compound-web to v9.7.1 2026-07-13 00:42:33 +00:00
Timo K. 023aec22ca Update docker-compose-playwright.yml 2026-07-10 17:45:53 +02:00
Timo K. bf4cee9898 update to latest EW
(this fixes the playwright tests)
2026-07-10 17:39:36 +02:00
Timo K. 147ff131f4 Merge branch 'livekit' into johannes/docker-compose-renovate 2026-07-10 12:59:06 +02:00
Robin 3e5edd03a6 Merge pull request #4100 from element-hq/remove-stopgap-styles
Stop using colors from previous design system
2026-07-09 16:37:02 +02:00
Robin 0afefa4889 Merge branch 'livekit' into remove-stopgap-styles 2026-07-09 16:21:06 +02:00
Timo K. 49a762832b Merge branch 'livekit' into johannes/docker-compose-renovate 2026-07-09 14:03:18 +02:00
Timo K. 3cf5cab1d2 Add additional renovate packageGroup for element-web 2026-07-09 13:20:57 +02:00
Robin 5968554e4c Merge pull request #4067 from element-hq/mobile-gradient
Improve the look of voice calls and group calls on mobile
2026-07-09 13:17:12 +02:00
Robin 8d826b2f31 Avoid showing gradients in especially small windows 2026-07-09 12:59:29 +02:00
Robin 32e30dd4f5 Merge branch 'livekit' into mobile-gradient 2026-07-09 12:56:28 +02:00
Robin bb06905aa2 Merge pull request #4099 from element-hq/stable-class-names
Use vitest's default for scoped class names
2026-07-09 12:54:19 +02:00
Robin 2684fa1d62 Remove unused class for end call button 2026-07-09 12:46:45 +02:00
Robin de75a69cad Remove stopgap color variables from previous design system
They have been largely unused for a long time. This changes the colors of checkboxes and the 'end call' button to align with current designs as well.
2026-07-09 12:28:39 +02:00
Timo f2c42c314c Merge pull request #4088 from element-hq/toger5/logger-getChild-fix
fix getChild before rageshake setup
2026-07-08 18:19:04 +02:00
Robin 4b50a191ba Fix end-to-end tests 2026-07-08 17:13:15 +02:00
Robin 11fadebb87 Fix test failures due to scoped class names 2026-07-08 17:06:25 +02:00
Robin 943ce5b853 Update test snapshots to use scoped class names 2026-07-08 17:06:09 +02:00
Timo K. 137093350b Merge branch 'livekit' into toger5/logger-getChild-fix 2026-07-08 17:04:42 +02:00
Robin 000ee66cfe Use vitest's default for scoped class names
It reduces confusion when reading snapshots if class names are still scoped to their respective CSS modules. It also discourages the use of class names in tests, which is a good thing. (https://testing-library.com/docs/guiding-principles)

Thanks to Johannes for the suggestion.
2026-07-08 17:03:51 +02:00
Johannes Marbach 58a8b7316e Merge pull request #4077 from element-hq/renovate/github-actions
Update GitHub Actions
2026-07-08 16:20:07 +02:00
renovate[bot] 1e6d3d3357 Update GitHub Actions 2026-07-08 14:02:37 +00:00
Robin 9f681b87a0 Merge branch 'livekit' into mobile-gradient 2026-07-08 15:47:59 +02:00
Timo dc21233767 Merge pull request #4097 from element-hq/toger5/fix-playwright-related-to-voice-in-pip
Consider voice calls starting in pip for playwright tests
2026-07-08 15:42:50 +02:00
Robin 27315a7090 Rename bgStyle to 'background' 2026-07-08 14:01:38 +02:00
Robin bebe79d109 Create type alias for background style 2026-07-08 13:56:10 +02:00
Robin 4ca0270115 Fix broken gradient SVG 2026-07-08 13:52:24 +02:00
Timo K. 374f56651c Consider voice calls starting in pip for playwright tests 2026-07-08 13:19:23 +02:00
Timo K. eefa6f843d fmt 2026-07-07 19:52:50 +02:00
Timo K. 2b84c587f2 lint 2026-07-07 19:45:22 +02:00
Timo K. 706cddafb0 Add lint rule to make sure future child loggers are setup correctly 2026-07-07 19:34:03 +02:00
Timo K. a6921e2bfb all the other logs 2026-07-07 19:12:11 +02:00
Timo K. 3cc396f42c fix getChild before rageshake setup 2026-07-07 19:05:10 +02:00
Timo 59999b9b37 Merge pull request #4059 from element-hq/toger5/remove-blur-on-mobile
Remove blur on mobile
2026-07-07 15:30:36 +08:00
Robin e68321e16c Merge branch 'livekit' into mobile-gradient 2026-07-06 12:17:04 +02:00
Johannes Marbach ad76969ce2 Merge pull request #4084 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v9.7.0
2026-07-06 09:03:10 +02:00
Johannes Marbach c170aad364 Merge pull request #4085 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.20.0
2026-07-06 09:01:51 +02:00
renovate[bot] 9e8bebc3bf Update dependency livekit-client to v2.20.0 2026-07-06 02:54:08 +00:00
renovate[bot] d5cdbfd4d1 Update dependency @vector-im/compound-web to v9.7.0 2026-07-06 02:53:46 +00:00
Johannes Marbach 1811b36205 Make renovate track docker-compose files and pin synapse / element-web for playwright tests 2026-07-03 08:48:28 +02:00
Robin 7840f4bccb Merge branch 'livekit' into mobile-gradient 2026-07-02 13:00:38 +02:00
Johannes Marbach 9199dcb583 Merge pull request #4076 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-07-02 11:37:07 +02:00
Johannes Marbach cbc4b77a4f Dismiss Element Web release announcements 2026-07-02 11:19:16 +02:00
Johannes Marbach ffb881436a Eliminate @livekit/protocol 2026-07-02 08:47:07 +02:00
Johannes Marbach 9cf87efc6b Remove global-jsdom 2026-07-02 08:35:59 +02:00
Johannes Marbach b71454d63a Bump mcr.microsoft.com/playwright 2026-07-02 08:35:40 +02:00
renovate[bot] b0feb33ec4 Update all non-major dependencies 2026-07-01 00:31:28 +00:00
Robin 900d0abd27 Let page background shine through the footer
By visually separating it from other page content with an additional gradient background only when necessary.
2026-06-30 16:29:20 +02:00
Robin a3d3a1e951 Add "sound waves" to transparent spotlight tiles
To indicate when the user is speaking.
2026-06-30 16:29:20 +02:00
Robin 8fa3f33f37 Let page background shine through spotlight tiles
By giving spotlight tiles a transparent background in certain layouts.
2026-06-30 16:29:20 +02:00
Robin 360a4ff026 Add mobile gradient background 2026-06-30 16:29:20 +02:00
Robin 8c6a16f3d7 Add URL param to control background style 2026-06-30 16:29:20 +02:00
Robin 9d21581259 Dismiss sections release announcement in end-to-end tests 2026-06-30 16:29:20 +02:00
Robin 3837576a5f Merge pull request #4073 from element-hq/refine-scope-leak-lint
Fix some false positives flagged by ObservableScope leak lint rule
2026-06-29 14:57:50 +02:00
Johannes Marbach eb5a097999 Merge pull request #4072 from element-hq/johannes/jest
Switch to jest-style assertions to please oxlint
2026-06-29 14:36:18 +02:00
Robin db2d20ac56 Fix some false positives flagged by ObservableScope leak lint rule
The rule should only care about enclosing function/class scopes. For example if an ObservableScope is received as a parameter to a function and then simply used inside an 'if' block (technically a different scope), that's not a problem.
2026-06-29 14:33:23 +02:00
Johannes Marbach f276c51772 Switch to jest-style assertions to please oxlint
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-06-29 14:32:49 +02:00
Johannes Marbach ac2214ed77 Merge commit from fork
Restrain logging of URL properties
2026-06-29 14:21:05 +02:00
Timo 8fe7bb5329 Merge pull request #4066 from element-hq/toger5/matrixRTCMode-compatibility
Default to compatibilty mode (multi sfu) - non breaking, as multi-sfu is compatible with all versions younger 6 month
2026-06-29 19:41:23 +08:00
Timo K 8028a6aa24 Update sfu-reconnect-bug.spec.ts 2026-06-29 13:11:26 +02:00
Timo K 5b4e8865e5 Update sfu-reconnect-bug.spec.ts 2026-06-29 13:04:22 +02:00
Timo K 356d526116 Update sfu-reconnect-bug.spec.ts 2026-06-29 13:02:26 +02:00
Johannes Marbach cca69b8108 Merge pull request #4069 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v9.5.0
2026-06-29 08:00:57 +02:00
renovate[bot] 75235a7853 Update dependency @vector-im/compound-web to v9.5.0 2026-06-29 00:34:12 +00:00
Timo K 0421783ebe Update config.sample.json 2026-06-26 13:30:19 +02:00
Robin a1be4ff0f9 Merge pull request #4068 from element-hq/landscape-voice-call
Hide local tile from mobile voice calls in landscape orientation
2026-06-26 11:22:25 +02:00
Robin 8ab7f89e36 Hide local tile from mobile voice calls in landscape orientation
To match the designs. Just like in portrait, it wouldn't contribute anything meaningful.
2026-06-25 20:29:24 +02:00
Valere Fedronic ddcb0f9981 Merge pull request #4064 from element-hq/ios/default_voice_call_to_earpiece
fix(voice): Default to earpiece for voice only call
2026-06-25 16:32:59 +02:00
Timo K 6ca5ddda73 fix snapshot 2026-06-25 16:05:58 +02:00
Valere 41d0933d4d playwright: New toast 2026-06-25 15:55:08 +02:00
Johannes Marbach 5ad62c7097 Merge pull request #4053 from element-hq/johannes/oxlint
Switch from eslint to oxlint
2026-06-25 15:46:05 +02:00
Johannes Marbach 76714ac3ad Use the correct company name
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-06-25 15:29:00 +02:00
Timo K 15b40835b8 Default to compatibilty mode 2026-06-25 13:31:02 +02:00
Valere dc5b541b21 fix(voice): Default to earpiece for voice only call 2026-06-25 13:10:27 +02:00
Johannes Marbach f376ffb96b Don't redact null or undefined 2026-06-24 13:35:44 +02:00
Johannes Marbach d5ce3a955a Port over copyright rule 2026-06-24 11:08:29 +02:00
Johannes Marbach d2cb7e334e Remove duplicate paths config 2026-06-24 10:53:14 +02:00
Johannes Marbach 9d61ca13cb Use regex to test node name 2026-06-24 10:49:18 +02:00
Johannes Marbach 51bd17d335 Restrain logging of URL properties 2026-06-24 08:22:02 +02:00
Johannes Marbach 1cd2764eb2 Switch from eslint to oxlint 2026-06-23 15:13:46 +02:00
Johannes Marbach 3fb81032e0 Merge pull request #4054 from element-hq/johannes/pip-border
Add PiP border in 1on1 layouts
2026-06-23 12:38:24 +02:00
Johannes Marbach da942ea900 Fix formatting 2026-06-23 12:19:40 +02:00
Johannes Marbach d534c617d2 Eliminate noOutline constant 2026-06-23 11:42:14 +02:00
Robin ded3d0ab81 Merge pull request #4061 from element-hq/subtitle-only
Show the subtitle of the app bar on small screens
2026-06-23 10:01:55 +02:00
Robin a4b4a6b655 Remove redundant styles 2026-06-23 09:42:57 +02:00
Robin be5d8140c9 Make it clearer why the app bar elements need to be hidden individually 2026-06-23 09:42:28 +02:00
Robin 7d54487354 Merge pull request #4060 from element-hq/speaker-color
Invert the colors of the speaker toggle button
2026-06-23 09:27:39 +02:00
Johannes Marbach 93fae5dd67 Add PiP border in 1on1 layouts
Fixes: #4008
2026-06-23 08:56:41 +02:00
Robin 504888b359 Show the subtitle of the app bar on small screens
Previously we were hiding the entire app bar on mobile phones in landscape orientation. However now that the app bar supports a small 'subtitle' element, we should show only the subtitle in this case to match the designs.

The subtitle still hides on tap, just like the footer.
2026-06-22 18:21:17 +02:00
Robin 99e95658df Invert the colors of the speaker toggle button 2026-06-22 16:10:45 +02:00
Robin 5a68010022 Merge pull request #4046 from element-hq/header-subtitle
Move ringing status indicator to header on mobile
2026-06-22 13:14:55 +02:00
Robin a456e47796 Show ringing status even on spotlight tiles (except in app bar mode) 2026-06-22 12:55:37 +02:00
Robin 27abf816f5 Fix vertical alignment of ringing status icons on Chromium and Safari 2026-06-22 12:12:54 +02:00
Robin c6188a8345 Improve test coverage 2026-06-22 11:59:16 +02:00
Robin 22ff0d34b7 Merge branch 'livekit' into header-subtitle 2026-06-22 11:35:52 +02:00
Robin 96d1d1e1aa Merge pull request #4040 from element-hq/scope-leak-lint
Add lint rule to prevent ObservableScope resource leaks
2026-06-22 11:13:10 +02:00
Robin 6f75e90fcd Merge pull request #4051 from element-hq/remote-members
Clarify which Matrix-LiveKit members are remote
2026-06-22 11:05:32 +02:00
Robin f78f507745 Address remaining resource leak error 2026-06-22 10:53:08 +02:00
Robin 89c148a530 Update remaining variable names for remote Matrix-LiveKit members 2026-06-22 10:44:24 +02:00
Robin e11c04ac87 Move ringing status indicator to header on mobile
On mobile, the ringing status indicator is supposed to display in the header rather than on a tile. The exact layout differs between Android and iOS. To get it right I had to refactor AppBar to use CSS grid templates.

(Also, I changed my mind about the exact ringing data I needed out of CallViewModel - sorry. A little move of the ringtone audio renderer into its own component was necessary to accommodate that.)
2026-06-18 17:41:35 +02:00
Timo 9b070052a0 Merge pull request #4032 from element-hq/toger5/lobby-remove-minimise-add-back-button
Add primary button icon configuration and set it left arrow in lobby
2026-06-18 23:02:03 +08:00
Johannes Marbach bb3d2cd95c Merge pull request #4048 from element-hq/johannes/oxfmt
Switch from prettier to oxfmt
2026-06-18 13:06:55 +02:00
Robin d417bd8b90 Merge pull request #4052 from element-hq/auto-leave-docs
Fix docs for autoLeave URL param
2026-06-18 12:50:13 +02:00
Robin f72a593eb4 Merge branch 'livekit' into scope-leak-lint 2026-06-18 12:49:40 +02:00
Robin f6cd06fc01 Fix docs for autoLeave URL param
The parameter as seen in URLs has a different name from what's used in the code.
2026-06-18 12:14:23 +02:00
Robin e77d143ce1 Clarify which Matrix-LiveKit members are remote
It was rather confusing that matrixLivekitMembers$ gives you objects of type RemoteMatrixLivekitMembers and yet the *local* member would often be among these. I've attempted to clear this up. To my knowledge this wasn't creating any bugs.
2026-06-18 12:10:32 +02:00
Robin 256219c4bf Merge pull request #4034 from element-hq/ringing-intent
Improve internal model of ringing, expose ringing intent to call UI
2026-06-18 12:00:34 +02:00
Robin 6af72f4c90 Format 2026-06-18 11:42:02 +02:00
Robin 3a598ffe43 Restore ability to play sound with custom volume
This was missing from the revert in 8b0f5054dd.
2026-06-18 11:35:46 +02:00
Robin 05797097c6 Only consider a call accepted if the *intended* recipient picks up 2026-06-18 11:05:55 +02:00
Robin 8b0f5054dd Revert to original fix for duplicate leave sounds
My attempted simpler fix of applying takeUntil(autoLeave$) to leaveSoundEffect$ didn't work.
2026-06-18 11:05:55 +02:00
Johannes Marbach 1c760f3ec4 Merge pull request #4050 from element-hq/johannes/oxlint-f-up
Remove accidentally added file
2026-06-18 09:28:28 +02:00
Johannes Marbach 699f383b57 Remove accidentally added file
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-06-18 09:24:52 +02:00
Johannes Marbach 6009988d3c Merge pull request #4010 from element-hq/johannes/label-sync
Set up label sync
2026-06-18 08:50:42 +02:00
Robin 8cda9777a5 Merge branch 'livekit' into ringing-intent 2026-06-18 06:41:17 +02:00
Timo K 049c432fc3 update comment + fix tests 2026-06-17 18:48:26 +02:00
Johannes Marbach 3ea89e8275 Merge pull request #4043 from element-hq/johannes/update-plugin-react
Update @vitejs/plugin-react to 0.6.2
2026-06-17 16:39:19 +02:00
Timo K 19fd7f42b1 I cannot belive GH... Does this commit fix the processing situation? 2026-06-17 16:35:09 +02:00
Johannes Marbach 0410be33cd Merge branch 'livekit' into johannes/update-plugin-react 2026-06-17 16:06:54 +02:00
Johannes Marbach 002f9b0cea Merge pull request #4042 from element-hq/johannes/pnpm-11
Switch to pnpm 11.6.0
2026-06-17 15:52:18 +02:00
Johannes Marbach 669f4264c7 Reformat
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-06-17 15:35:47 +02:00
Johannes Marbach dc6511b99e Document why we override resolved versions 2026-06-17 15:33:36 +02:00
Johannes Marbach 032968ea2d Merge branch 'livekit' into johannes/pnpm-11 2026-06-17 15:07:28 +02:00
Johannes Marbach b2f02b0ff6 Switch from prettier to oxfmt 2026-06-17 12:20:42 +02:00
Timo K b31825d05b review 2026-06-16 16:54:14 +02:00
Timo K c4fe0223ab remove blur on mobile 2026-06-16 16:42:24 +02:00
Johannes Marbach 6ce79d8a52 Merge pull request #4045 from element-hq/renovate/npm-vite-vulnerability
Update dependency vite to v8.0.16 [SECURITY]
2026-06-16 15:22:21 +02:00
renovate[bot] b68abb7df4 Update dependency vite to v8.0.16 [SECURITY] 2026-06-16 12:45:26 +00:00
Timo 1281ed31df Merge pull request #3816 from element-hq/toger5/fix-depnedabot-security-alerts
Dependabot security alerts: Bump flatted and unidici
2026-06-16 20:34:17 +08:00
Timo K e7377fb104 fix prettier 2026-06-16 14:17:25 +02:00
Timo K edb4dfa9ed Merge branch 'livekit' into toger5/fix-depnedabot-security-alerts 2026-06-16 14:16:02 +02:00
Timo K 7db13e1fc0 Merge branch 'livekit' into toger5/fix-depnedabot-security-alerts 2026-06-16 14:13:16 +02:00
Timo K b9d769364d update tests 2026-06-15 14:59:39 +02:00
Timo K 164fb99ace refactor using enum vs jsx node 2026-06-15 14:42:45 +02:00
Timo K db26db266d update back arrow size 2026-06-15 14:26:24 +02:00
Johannes Marbach fc3461dd54 Set up label sync 2026-06-15 14:18:13 +02:00
Timo K 8c8c9eef24 Update LobbyView.tsx 2026-06-15 14:07:44 +02:00
Johannes Marbach df7451c2cf Update @vitejs/plugin-react to 0.6.2 2026-06-15 13:59:54 +02:00
Johannes Marbach 9537c7657c Switch to pnpm 11.6.0 2026-06-15 12:34:32 +02:00
Johannes Marbach 6c105e971e Merge pull request #4041 from element-hq/renovate/compound
Update Compound to v10.2.2
2026-06-15 08:06:20 +02:00
renovate[bot] cbbe6a812e Update Compound to v10.2.2 2026-06-15 01:03:21 +00:00
Robin 0a572a9528 Add lint rule to prevent ObservableScope resource leaks
The rule of thumb to avoid resource leaks is that you should never call ObservableScope methods in a callback unless the ObservableScope is directly passed to or created inside that callback. I had a go at codifying this as a lint rule.
2026-06-12 13:16:28 +02:00
Robin 3ef3ebe897 Merge pull request #4036 from element-hq/metadata-leak
Fix a minor resource leak with display names and avatars
2026-06-12 10:05:50 +02:00
Timo 0c284ed75b Merge pull request #4004 from element-hq/toger5/controls-api-onPipMediaOrientation
Controls api `onPipMediaOrientation`
2026-06-12 16:03:35 +08:00
TimoandJohannes Marbach 838d2f3c5d Update src/state/media/observeRtpStreamStats.ts
Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-06-12 09:47:13 +02:00
Timo 2a24fbcee1 Merge pull request #4038 from element-hq/toger5/fix-logging-indexDB
Fix Logging indexDB EC/EW collision
2026-06-12 15:29:33 +08:00
Ryan Emmick 9ef3499418 test: update developer settings snapshot after merge 2026-06-11 22:15:05 -05:00
Ryan Emmick 08d9982981 Merge upstream/livekit into branch 2026-06-11 22:11:21 -05:00
Timo K be8a76868b rename db 2026-06-11 18:38:54 +02:00
Johannes Marbach d1ea63587b Merge pull request #4035 from element-hq/johannes/knife-content-type
Remove deprecated @types/content-type dependency
2026-06-11 12:22:49 +02:00
Robin 96a9115ee7 Fix a minor resource leak with display names and avatars
I noticed that calls to createDisplayNameBehavior$ and createAvatarUrlBehavior$ were technically leaking resources since they reused the ObservableScope from their outer scope, which in practice lasts for the entire lifetime of the CallViewModel. This would not have had any noticeable effect unless you had other participants leave and rejoin the same call many thousands of times.
2026-06-11 12:21:07 +02:00
Robin 2ac6cdeb46 Improve internal model of ringing, expose ringing intent to call UI
I found our code's internal model of ringing a little overgrown (it had superfluous states like 'unknown') and difficult to extend with metadata or callbacks relating to ring attempts. By modeling ringing instead as a stream of ring attempts, where each attempt has an intent, a recipient, and an eventual outcome (accept/decline/timeout), I find it more natural to work with.

This makes room for a future 'try again' callback to allow ringing someone again after a timeout, and also forced me to look for a simpler solution to the duplicate leave sound effects. I exposed the intent of the ringing attempt to the call UI so I can later use it in the header.
2026-06-11 12:12:27 +02:00
Timo K 659da15cc2 more test coverage 2026-06-11 10:39:59 +02:00
Timo K 9b2e1279bc Update DeveloperSettingsTab.test.tsx.snap 2026-06-11 09:33:27 +02:00
Johannes Marbach 3af160bb02 Remove deprecated @types/content-type dependency 2026-06-11 08:36:25 +02:00
fkwp 73ccc5f483 Show typed error when matrix_2_0 mode is forced without homeserver MSC4354 support (#4017)
Show typed error when matrix_2_0 mode is forced without homeserver MSC4354 support
2026-06-10 18:48:16 +02:00
Johannes Marbach 3a824dfff0 Merge pull request #4029 from element-hq/johannes/i18next-cli
Replace deprecated i18next-parser with i18next-cli
2026-06-10 15:00:45 +02:00
Timo K 2b05c415c1 Merge branch 'livekit' into toger5/lobby-remove-minimise-add-back-button 2026-06-10 14:58:56 +02:00
Timo 7ffa585f0d Merge pull request #4027 from element-hq/johannes/knife-uuid-types
Remove deprecated @types/uuid
2026-06-10 20:51:11 +08:00
Johannes Marbach 0690387b70 Merge pull request #4009 from element-hq/johannes/raised-color
Fix missing text color for remote raised hand duration
2026-06-10 10:17:13 +02:00
Timo K ba1957ef52 tests 2026-06-09 18:44:27 +02:00
Timo K abf9022fd9 Add primary button icon configuration and set it left arrow in lobby 2026-06-09 17:17:25 +02:00
renovate[bot] 7fa3febf55 Update LiveKit client to v2.19.2 (#4031)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-08 21:13:59 +02:00
Johannes Marbach 11b08c9a9f Replace deprecated i18next-parser with i18next-cli 2026-06-08 15:32:34 +02:00
Johannes Marbach c1f528e120 Remove deprecated @types/uuid 2026-06-08 13:57:01 +02:00
Johannes Marbach 65bd51fe92 Merge pull request #4022 from element-hq/renovate/compound
Update Compound
2026-06-08 10:25:11 +02:00
Johannes Marbach 2dc664b323 Merge branch 'livekit' into renovate/compound 2026-06-08 10:05:00 +02:00
Johannes Marbach 65737ef4a5 Merge pull request #4023 from element-hq/renovate/livekit-client
Update LiveKit client to v2.19.1
2026-06-08 10:02:00 +02:00
Matt Van Horn 9a2fc883b6 fix: announce tab count and position in settings tab bar 2026-06-08 00:49:43 -07:00
renovate[bot] 753613dcdc Update LiveKit client to v2.19.1 2026-06-08 07:35:21 +00:00
Johannes Marbach a412d0c230 Merge branch 'livekit' into renovate/compound 2026-06-08 09:26:29 +02:00
Johannes Marbach 33e847c1a3 Merge pull request #4024 from element-hq/johannes/codecov
Update codecov-action to v7
2026-06-08 09:25:38 +02:00
Johannes Marbach ac2f5fe7d6 Update codecov-action to v7 2026-06-08 09:00:12 +02:00
Johannes Marbach 4c2c068c3a Update dev settings snapshot 2026-06-08 08:48:46 +02:00
renovate[bot] 102a7e2650 Update Compound 2026-06-08 01:07:22 +00:00
Valere Fedronic ba40490ca4 Merge pull request #4013 from element-hq/valere/fix_repeated_click_to_unmute
feat(mute): add syncing state and disable toggle during async mute
2026-06-05 12:58:23 +02:00
Valere 62a3ec8319 review: cleanup removed redundant default properties 2026-06-05 12:50:25 +02:00
Valere a430e87104 review: add test for busy behavior for Mic and Video buttons 2026-06-05 12:48:04 +02:00
Valere acc5a440c7 review: remove unneeded early return 2026-06-05 12:35:21 +02:00
fkwpandJohannes Marbach b99c8821d3 Add matrix_rtc_mode config option (#4014)
* Move MatrixRTCMode enum from settings.ts to ConfigOptions.ts

* Add matrix_rtc_mode config option

* add matrix_rtc_mode to config.sample.json

* Update src/settings/DeveloperSettingsTab.tsx

Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>

* Update src/settings/DeveloperSettingsTab.test.tsx

Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>

* reviewer comments

---------

Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-06-05 09:49:43 +00:00
Valere dc03d9b358 fix: Initial unmute is reverted 2026-06-05 10:29:36 +02:00
Valere Fedronic 3a6579f78d Merge pull request #4012 from element-hq/valere/livekit_error_boundary
feat(errors): Report livekit error as such instead of generic unknown errors
2026-06-05 09:31:46 +02:00
Valere 55b2537129 fixup: Update snapshot with button busy state 2026-06-04 19:14:12 +02:00
Valere b5b238ffd3 storybook: Add storybook for audio/video busy 2026-06-04 19:13:27 +02:00
Valere 4606373e5b feat(mute): add syncing state and disable toggle during async mute 2026-06-04 18:55:31 +02:00
Valere 4353f09e54 fixup snapshots 2026-06-04 15:48:30 +02:00
ElementRobot fc3c4bf566 Merge pull request #3911 from element-hq/actions/localazy-download
Localazy Download
2026-06-04 15:34:46 +02:00
Valere c05c523182 fixup: ensure dynamic keys are extracted by i18n parser 2026-06-04 15:30:59 +02:00
Johannes Marbach 629c012f48 Reorder entries 2026-06-04 15:17:34 +02:00
Valere e7d37f87bb feat(errors): Report livekit as such rather than like unknown errors 2026-06-04 11:54:42 +02:00
Johannes Marbach 664a10c724 Fix illegible text color for raised hand duration
Fixes: https://github.com/element-hq/voip-internal/issues/579
2026-06-04 11:33:55 +02:00
Timo K 308a042076 fix error with no media 2026-06-03 10:43:47 +02:00
Timo K b554ce4a87 Update CallViewModel.test.ts 2026-06-03 10:18:45 +02:00
Johannes Marbach 5f257da4f6 Merge pull request #4005 from element-hq/johannes/dry
Avoid usage of SWIFT_RELEASE_TOKEN in dry runs
2026-06-03 08:14:28 +02:00
Johannes Marbach 1196ba5959 Merge pull request #4000 from element-hq/johannes/pip-corners
Fix corner radius on screenshare overlay in widget mode
2026-06-03 08:12:48 +02:00
Johannes Marbach 067a70d19f Fix corner radius on screenshare overlay in widget mode
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-06-02 15:18:19 +02:00
Robin c021fc1548 Merge pull request #3995 from element-hq/toger5/fix-double-leave-sound
Fix play of second leave sound
2026-06-02 14:46:43 +02:00
Johannes Marbach 2e95c2cc15 Avoid usage of SWIFT_RELEASE_TOKEN in dry runs 2026-06-02 14:41:59 +02:00
Timo K 692a55c84c fix race 2026-06-02 14:06:28 +02:00
Timo K c5ffdea370 lint 2026-06-02 13:56:16 +02:00
Timo K 9117b40e7b fix tests 2026-06-02 13:52:43 +02:00
Timo 25a6cefa34 Merge pull request #3905 from manfrommedan/fix/promise-withresolvers-polyfill
Add Promise.withResolvers polyfill for older WebViews (Chrome < 119)
2026-06-02 19:43:12 +08:00
Robin 399b7d83da Merge pull request #3988 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.19.0
2026-06-02 11:50:10 +02:00
Timo e2128776b3 Merge pull request #3935 from element-hq/toger5/contribut-issue-first
Contributing.md explain "issue first" contribution approach
2026-06-02 17:35:56 +08:00
Timo 327a0ad9b0 Merge pull request #3951 from element-hq/valere/improve_error_message
Improve error messages for sfu auth problems
2026-06-02 17:33:56 +08:00
Robin 47326c28d3 Fix type error 2026-06-02 11:33:17 +02:00
Robin 084fa20b3d Merge pull request #4003 from element-hq/device-switch-fixes
Show the right labels in device switcher menus
2026-06-02 11:29:28 +02:00
Timo K e05af09c28 Add test 2026-06-02 11:27:59 +02:00
Robin cec78a383d Fix footer stories 2026-06-02 11:14:53 +02:00
Timo K b86909af52 temp add tests 2026-06-02 10:56:34 +02:00
Robin faa34aeaaa Merge pull request #3987 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v10.2.0
2026-06-02 10:48:44 +02:00
Robin 5fed562db2 Request full device names when device switchers are open 2026-06-02 10:36:57 +02:00
Robin 164765cd27 Show the right fallback labels in device switcher menus 2026-06-02 10:15:40 +02:00
renovate[bot] 489492d9b9 Update dependency livekit-client to v2.19.0 2026-06-02 06:50:03 +00:00
renovate[bot] bec34ee360 Update dependency @vector-im/compound-design-tokens to v10.2.0 2026-06-02 06:49:28 +00:00
Johannes Marbach 79298a6620 Merge pull request #3998 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-06-02 08:47:58 +02:00
Robin af8a876adc Merge pull request #3999 from element-hq/renovate/embedded-package-dependencies
Update Gradle to v8.14.5
2026-06-02 08:42:39 +02:00
Johannes Marbach f4d6517bbb Switch from global to globalThis to fix import issues 2026-06-02 08:29:03 +02:00
renovate[bot] 576119663f Update all non-major dependencies 2026-06-02 01:16:51 +00:00
Timo K d6635b7818 add docs 2026-06-01 16:13:03 +02:00
Timo K a6fc710d8c Add onPipMediaOrientationUpdate to controls api. 2026-06-01 16:12:57 +02:00
renovate[bot] e67d2f2f2b Update Gradle to v8.14.5 2026-06-01 03:52:15 +00:00
Valere 3799ea2b4e fixup: Missing translation 2026-05-28 14:43:42 +02:00
Valere 2bd16beccf Merge branch 'livekit' into valere/improve_error_message 2026-05-28 14:27:17 +02:00
Valere Fedronic 72b0d12d7c Merge pull request #3973 from element-hq/valere/devx/run_dev_on_phone
devx: Allow to run local dev EC on mobile in same wifi
2026-05-28 14:26:07 +02:00
Valere 6777adac54 Merge branch 'livekit' into valere/devx/run_dev_on_phone 2026-05-28 13:17:22 +02:00
Valere Fedronic 083f86b19d Merge pull request #3924 from element-hq/valere/devx/livekit_logs
dev-tool: Add option to enable extended livekit logs
2026-05-28 13:16:57 +02:00
Valere 1fafc3b1ba Merge branch 'livekit' into valere/devx/livekit_logs 2026-05-28 12:45:39 +02:00
Valere Fedronic cdbb2c92ca Merge pull request #3994 from element-hq/valere/devx/bump_playwright
bump playwright to 1.60
2026-05-28 12:45:19 +02:00
Timo K ea4144ccc7 Fix play of second leave sound 2026-05-28 12:04:42 +02:00
Valere 2928e34ee2 test: use toHaveCount instead of count()).toBe 2026-05-28 11:56:29 +02:00
Valere d98e800077 bump playwright
update playwright container image
2026-05-28 11:32:18 +02:00
Valere 8b86c1914d bump playwright
update playwright container image
2026-05-28 11:31:38 +02:00
Valere e815277fa2 touch commit to unbock gh 2026-05-28 08:59:05 +02:00
Valere 810e263cbe review: better doc 2026-05-28 08:51:00 +02:00
Valere 70a0914017 eslint 2026-05-27 14:18:34 +02:00
Valere 8011f2579c test: Add test for new option
review: Remove uneeed {" "}
2026-05-27 14:03:31 +02:00
Valere 187665748b Merge branch 'livekit' into valere/devx/livekit_logs 2026-05-27 11:46:38 +02:00
Timo ee1e8c60e7 Merge pull request #3961 from element-hq/toger5/view-model-call-footer-example
Implement fast switcher (+ ViewModel with snapshot example)
2026-05-20 23:38:00 +08:00
TimoandRobin a9fd98c563 Update src/state/ViewModel.ts
Co-authored-by: Robin <robin@robin.town>
2026-05-20 17:16:08 +02:00
Robin 0de6e94647 Merge pull request #3983 from element-hq/one-on-one-portrait-regressions
Fix a couple more regressions due to the one-on-one portrait layout
2026-05-20 17:03:54 +02:00
Timo K dc52573ce2 fix backgroundBlurToggleClick -> videoBlurToggleClick 2026-05-20 17:03:45 +02:00
Timo K 509e4d739f Update InCallView.test.tsx 2026-05-20 16:47:41 +02:00
Timo K 355ec4fe62 fix visibility test 2026-05-20 16:39:25 +02:00
Timo K d9c0de73b7 Merge branch 'livekit' into toger5/view-model-call-footer-example 2026-05-20 16:28:04 +02:00
Robin 8d07d552d7 Ensure landscape layout is always edge-to-edge on mobile
The spotlight landscape layout was edge-to-edge previously, and should remain that way.
2026-05-20 16:11:07 +02:00
Robin 8324ce2ce0 Avoid overlapping spotlight tiles with the app bar
The default inset that is given to the fixed layout layer needs to account for the app bar now.
2026-05-20 16:11:07 +02:00
Timo ae20f59dea Merge pull request #3978 from element-hq/app-bar-media-foreground
Ensure that foreground elements of media tile do not overlap app bar
2026-05-20 21:36:43 +08:00
Robin eaa049433a Merge pull request #3979 from element-hq/settings-footer-glitch
Stop the settings button from appearing while footer is fading out
2026-05-20 15:15:37 +02:00
Valere Fedronic 06b6122ec9 Merge pull request #3980 from element-hq/valere/fix_control_shown_in_PIP
fix(regression): control buttons should be hidden on mobile PIP
2026-05-20 15:07:24 +02:00
Timo K ec3b52f963 del: windowMode$ from public callViewModel
replace with edgeToEdge$
2026-05-20 15:00:28 +02:00
Valere FedronicandRobin 2fb5de3ba2 review: eqeqe
Co-authored-by: Robin <robin@robin.town>
2026-05-20 14:50:56 +02:00
Timo K c9fa586db1 merge fixups 2026-05-20 14:25:40 +02:00
Timo K 3301d2fe03 Merge branch 'livekit' into toger5/view-model-call-footer-example 2026-05-20 14:25:25 +02:00
Timo 3adddf4b70 Merge pull request #3960 from element-hq/toger5/storybook-tests
Use vite storybook plugin for storybook tests
2026-05-20 19:57:21 +08:00
Robin 4b175b814e Update and simplify tests 2026-05-20 13:43:33 +02:00
Timo bc3da2dda2 Merge pull request #3975 from Johennes/johannes/dev-deps
List additional dependencies needed for development
2026-05-20 19:34:25 +08:00
Timo K e7c87e3439 Merge branch 'livekit' into toger5/storybook-tests 2026-05-20 13:28:03 +02:00
Timo K ddde05c057 review 2026-05-20 13:26:52 +02:00
Valere 265781ea5e fix(regression): control buttons should be hidden on mobile PIP 2026-05-20 13:08:51 +02:00
Valere 1865110492 reproduce bug internal #578
Regression: Controls are shown in Mobile PIP
2026-05-20 13:08:11 +02:00
Robin 43f1b89535 Stop the settings button from appearing while footer is fading out
The designs actually never want us to show the settings button in the footer if an app bar is in use (as in Element X mobile apps), so just avoid showing it at all in that case.
2026-05-20 12:38:18 +02:00
Robin 284d76e333 Merge pull request #3977 from element-hq/posthog-updates
Allow PostHog dependency updates again
2026-05-20 12:22:51 +02:00
Robin 7b32135328 Ensure that foreground elements of media tile do not overlap app bar
Because the type of header that we use in Element X (an 'app bar') lives in a different place in the document than the other headers, it needs a special branch to propagate the right insets.
2026-05-20 11:55:27 +02:00
Robin 94ce207581 Allow PostHog dependency updates again 2026-05-20 11:50:01 +02:00
fkwpandTimo K f0db134b6e Posthog: drop $initial_person_info from outgoing events (#3968)
* Posthog: drop $initial_person_info from outgoing events

* Posthog: migrate from sanitize_properties to before_send

* strip URL fields from $set / $set_once

* enable mask_personal_data_properties

* review

* update tests to check for `delete` (not anymore `=null`)
rename: `applyPrivacyFilters`->`santizeSensitiveData`

---------

Co-authored-by: Timo K <toger5@hotmail.de>
2026-05-19 18:06:59 +02:00
Timo 0e3aaaafe8 Fix tap-to-show call controls on iOS (ReactMouseEvent -> ReactPointerEvent) (#3966) 2026-05-19 23:50:55 +08:00
Timo 78d76ad8a6 Bump babel/plugin-transform-modules-systemjs (#3974) 2026-05-19 17:03:25 +02:00
Robin 6b261611a5 Log unhandled promise rejections in rageshakes (#3972)
For more comprehensive rageshake logs. Copied from Element Web's rageshake.ts.
2026-05-19 13:44:16 +02:00
Johannes Marbach 6f7d4ec8eb List additional dependencies needed for development
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-19 11:14:53 +02:00
Timo K a494b64055 Update MediaMuteAndSwitchButton.test.tsx 2026-05-18 21:00:55 +02:00
Timo K e19d5865b0 cleanup 2026-05-18 20:08:39 +02:00
Timo K bc81da43c2 use previous device selection logic 2026-05-18 19:39:29 +02:00
Timo K 68a487c9de translation fixes 2026-05-18 19:17:43 +02:00
Timo K d5bebcc3a5 refactor video blur toggle 2026-05-18 18:11:32 +02:00
Timo K dd79ef659c lint 2026-05-18 16:28:25 +02:00
Timo K e22ab9355c Review (everything except translation feedback) 2026-05-18 14:31:03 +02:00
Robin f3c0b9ed8d Merge pull request #3969 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.18.10
2026-05-18 13:30:48 +02:00
Robin ac1297d02c Merge pull request #3916 from element-hq/one-on-one-portrait
Create a proper one-on-one call layout for portrait screens
2026-05-18 13:28:59 +02:00
Valere dfbb6c770e devx: Allow to run local dev EC on mobile in same wifi 2026-05-18 13:25:56 +02:00
Robin d66afd734d Merge pull request #3971 from Johennes/johannes/minor-docs-fixes
Minor documentation fixes
2026-05-18 13:17:34 +02:00
Robin cfbdbca5bb Fix media foreground elements being obscured by header/footer 2026-05-18 13:08:52 +02:00
Johannes Marbach 49f6c74818 Minor documentation fixes
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 11:12:26 +02:00
Robin d7acce49a3 Merge pull request #3970 from Johennes/johannes/typo
Minor README fixes
2026-05-18 10:12:59 +02:00
Johannes Marbach 18a128b865 Fix linking link
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 09:56:37 +02:00
Johannes Marbach 80f573e899 Add missing apostrophe
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 09:50:42 +02:00
Johannes Marbach 0ca2b6d4ea Remove extra space and add colon
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 09:49:58 +02:00
Johannes Marbach 198d961646 Add missing apostrophe
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 09:48:46 +02:00
Johannes Marbach 9d522913f9 Add missing colon
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 09:46:41 +02:00
Johannes Marbach 69b5209071 Fix typo
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 08:40:08 +02:00
Johannes Marbach 0160f60c6d Reorder sentence fragments for better readability
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 08:33:36 +02:00
Johannes Marbach abce4d16fc Add missing article
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 08:29:47 +02:00
Johannes Marbach b0c1c48ad4 Add missing article
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 08:26:42 +02:00
Johannes Marbach a2c6b8102a Link to self-hosting guide
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 08:21:17 +02:00
Johannes Marbach 959a55a9f8 Use correct preposition
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2026-05-18 08:21:00 +02:00
renovate[bot] 4452f3c0c6 Update dependency livekit-client to v2.18.10 2026-05-18 00:39:52 +00:00
Timo K 88f660e43f review 2026-05-15 18:37:25 +02:00
fkwp 04b0165961 Fix tap-to-show call controls on iOS (ReactMouseEvent -> ReactPointerEvent) 2026-05-15 12:29:26 +02:00
Robin 7e932d27da Merge pull request #3939 from element-hq/renovate/github-actions
Update GitHub Actions
2026-05-15 11:42:37 +02:00
Robin a1e03ea389 Merge pull request #3942 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v10.1.1
2026-05-15 11:36:20 +02:00
Robin de52ea6590 Fix tests 2026-05-15 11:29:22 +02:00
Robin 9ad5d02e31 Merge branch 'livekit' into one-on-one-portrait 2026-05-15 11:28:47 +02:00
Robin f3234b1c3e Merge branch 'livekit' into renovate/github-actions 2026-05-15 11:26:25 +02:00
Robin 53acd2596c Merge branch 'livekit' into renovate/compound 2026-05-15 11:20:55 +02:00
cec3a799af Posthog add reconnect event (#3953)
* Add Posthog events for Call reconnect including the reason

* Expose single trackCallReconnecting() entry point on PosthogAnalytics

* Track reconnect duration and align with existing analytics pattern

* Refactor combined$ to return [connected, reason] tuple

* Update firefoxUserPrefs to allow getUserMedia and enumerateDevices on CI
---------

Co-authored-by: Valere <bill.carson@valrsoft.com>
Co-authored-by: Robin <robin@robin.town>
Co-authored-by: Timo K <toger5@hotmail.de>
2026-05-14 23:07:02 +02:00
Timo K e10bc6c7cf fix unit tests 2026-05-13 13:35:12 +02:00
Timo K 0082ade234 reuse exisng mute buttons (fixes most playwright issues) 2026-05-13 13:16:24 +02:00
Robin b562a0f721 Create a proper one-on-one call layout for portrait screens 2026-05-13 09:54:58 +02:00
renovate[bot] 77f4704b20 Update dependency @vector-im/compound-design-tokens to v10.1.1 2026-05-12 15:58:30 +00:00
renovate[bot] 53e9d05587 Update GitHub Actions 2026-05-12 15:57:48 +00:00
Valere Fedronic b9f73e3e9a Merge pull request #3962 from element-hq/valere/fix_double_unmute_bug
bugfix: When starting muted, have to click twice to unmute in call
2026-05-12 17:28:27 +02:00
Timo K 07e7090cc7 fix unit tests 2026-05-12 16:50:45 +02:00
Timo K 7ad8f9f182 Fix tests (accessibility issues with new buttons) 2026-05-12 16:48:08 +02:00
Valere 408a38a7d6 bugfix: When starting muted, have to click twice to unmute in call 2026-05-12 15:46:38 +02:00
Timo K 7842f5a8d0 test coverage? 2026-05-12 14:11:48 +02:00
Timo K c3cd6248ae simple lobby snapshot tests
(we dont want this to get too invested as we plan to refactor the lobby(
2026-05-12 13:14:34 +02:00
Timo K f3ef7c074b lint 2026-05-12 12:52:23 +02:00
Timo K 246db5a820 simplifications docs and tests 2026-05-12 12:46:36 +02:00
Timo K b042f2594d fix lints and format 2026-05-11 20:09:55 +02:00
Timo K 102542c1b0 update tests 2026-05-11 20:02:56 +02:00
Timo K ff3b4c6ff4 cleanups 2026-05-11 20:02:56 +02:00
Timo K 7514bd4811 use footer view model in InCallview 2026-05-11 20:02:56 +02:00
Timo K d29b920581 use footer view model in lobby 2026-05-11 20:02:56 +02:00
Timo K 936dfb193f add the CallFooterViewModel 2026-05-11 20:02:56 +02:00
Timo K 7615e146a5 Use ViewModel approach for the CallFooterView + interaction tests
(this is just imaginary. There is no view model yet.)
2026-05-11 20:02:56 +02:00
Timo K 64d5e8ca24 Introduce ViewModel.ts 2026-05-11 20:02:56 +02:00
Timo K 9f6ae4ba55 small device selection refactor 2026-05-11 20:02:56 +02:00
Timo K d37c064df3 custom container does not work for playwright tests 2026-05-11 20:01:18 +02:00
Timo K 34486e6486 use container to skip playwright install 2026-05-11 19:57:36 +02:00
Timo K ded6e4c1a0 fix tests dep optimization issues 2026-05-11 19:50:32 +02:00
Timo K 5bdbd80f37 try storybook only 2026-05-11 19:29:07 +02:00
Timo K 4f28bac749 without playwright container 2026-05-11 19:18:10 +02:00
Timo K f37128414a try with firefox 2026-05-11 19:16:07 +02:00
Timo K 7ca890ea53 Delete vitest.setup.ts 2026-05-11 19:08:45 +02:00
Timo K 85762001a4 try file parallelism 2026-05-11 19:08:40 +02:00
Timo K aa125d917d no setup file for storybook 2026-05-11 19:01:47 +02:00
Timo K 88f14ffcde try with playwirght container 2026-05-11 18:56:52 +02:00
Timo K bc2be4dfab test in CI 2026-05-11 18:44:16 +02:00
Timo K 53626785b3 install playwright for unit tests 2026-05-11 18:22:58 +02:00
Valere f1b61a9f1c update developer settings tab snapshot 2026-05-11 18:07:40 +02:00
Valere 2ac221661b review: Use Initializer instead of creating a component 2026-05-11 17:43:34 +02:00
Valere 25ac565f8b Merge branch 'livekit' into valere/devx/livekit_logs 2026-05-11 17:28:07 +02:00
Timo K 20d14fa4e0 use vite storybook plugin for storybook tests.
run via pnpm test:storybook
2026-05-11 16:40:05 +02:00
Timo K 5dfd1648c5 remove yarn lock 2026-05-11 16:30:57 +02:00
Timo K 1d5ac67324 Merge branch 'livekit' into toger5/fix-depnedabot-security-alerts 2026-05-11 16:28:48 +02:00
Timo f4ff790d2c Add MediaMuteAndSwitchButton component (storybook only) (#3938)
* add MeidaMuteAndSwitchButton

* User button in footer

* Add tests

* update styling (dark bg on menu open + chevron white + chevron up)

* fix tests

* add storybook to CI

only add storybook with storybook label

test names

another env name test

TestName

new default name

remove label condition

Update pr-deploy.yaml

* Update pr-deploy.yaml

* add toggle example to default component

* hook up footer select actions

* fix video audio button (swapped) and lable in story
2026-05-11 11:50:33 +02:00
Robin bd2de29470 Merge pull request #3922 from element-hq/hs/compound-switch
Use Compound Switch component
2026-05-11 09:51:56 +02:00
Robin 069074d241 Merge branch 'livekit' into hs/compound-switch 2026-05-11 09:36:08 +02:00
renovate[bot] 78417ff2cb Update dependency @livekit/components-react to v2.9.21 (#3957)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 09:05:59 +02:00
renovate[bot] 1025d23ac7 Update dependency livekit-client to v2.18.9 (#3958)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 08:35:17 +02:00
Valere d0bfef0682 Improve error messages for sfu auth problems 2026-05-07 16:21:30 +02:00
Valere Fedronic 7010d546bc Merge pull request #3954 from element-hq/valere/playwright_toast_fixture
playwrigth: make dismiss toast more reliable
2026-05-07 14:16:21 +02:00
Valere Fedronic 85bdb007fc Merge pull request #3952 from element-hq/decline-call
Update Playwright test to look for 'Decline' button
2026-05-07 12:25:17 +02:00
Valere e06f717156 playwrigth: make dismiss toast more reliable 2026-05-07 11:23:59 +02:00
Robin d50c8e0ca9 Update Playwright test to look for 'Decline' button
Since the label of this button is changing in Element Web.
2026-05-06 12:37:31 +02:00
fkwp 147d0f96e0 [Feature] Support delayed event delegation for legacy JWT request (#3946)
* make `delayed_leave_event_delay_ms` and `network_error_retry_ms` mandatory

* Support delegation for legacy  jwt request

* Calculate `maximumNetworkErrorRetryCount` based on timeouts
2026-05-05 17:33:39 +02:00
Timo 95f772df2b Add storybook to CI (#3948)
* add storybook to CI

only add storybook with storybook label

test names

another env name test

TestName

new default name

remove label condition

Update pr-deploy.yaml

* rename things to check if we actually run the latests ci

* cleanup things used for testing

* Update deploy-to-netlify.yaml

* use package instead of custom environment_name

* final cleanup
2026-05-05 15:46:11 +02:00
fkwp 667723aa92 fix nginx config as the missing 50x.html escalates 502 errors to 404 errors (#3947) 2026-05-05 14:43:03 +02:00
Timo K 121d87b1d0 Merge branch 'livekit' into toger5/contribut-issue-first 2026-05-05 14:39:52 +02:00
Timo b276eeee75 Merge pull request #3927 from element-hq/toger5/back-button-press-control-on-esc
Refactor of Escape keyboard event bahvior (allow mute/emoji shortcuts after closing a modal with escape)
2026-05-05 00:39:53 +08:00
Timo K 58f430eb32 review 2026-05-04 18:25:04 +02:00
Robin 5ca50fdb63 Merge pull request #3913 from element-hq/fkwp/feature_relax_homeserver_offline
[Feature] add grace period before reporting the sync loop as disconnected
2026-05-04 18:18:27 +02:00
Robin 7916360b52 Convert all grace period tests to marble tests 2026-05-04 18:01:41 +02:00
Robin 83a9a2a86c Merge pull request #3903 from element-hq/edge-to-edge
Allow calls to display edge-to-edge on mobile
2026-05-04 15:40:08 +02:00
fkwp 0dc8fab256 linting 2026-05-04 13:36:26 +02:00
fkwp 69757b06ce prettier 2026-05-04 13:27:57 +02:00
fkwp a081b40fb2 add marble test 2026-05-04 13:24:19 +02:00
fkwp 88b5db6675 fix rtsSession initial state 2026-05-04 10:41:48 +02:00
fkwp 22f16174ef addressing review comments 2026-05-04 09:16:55 +02:00
Robin 0470dabff2 Merge pull request #3940 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-05-01 16:10:27 +02:00
renovate[bot] 5a30666939 Update all non-major dependencies 2026-05-01 13:53:45 +00:00
Robin f093946a29 Allow calls to display edge-to-edge on mobile
By adding viewport-fit=cover to the <meta name="viewport"> header, the page now requests to be displayed edge-to-edge across the entire screen. This gives us control over what we display around camera cut-outs and system navigation UI, if the user agent supports it. I then adjusted the styles of various UI elements to ensure that they still lie within the screen's safe area.
2026-05-01 12:14:40 +02:00
fkwp 6c25048b92 Merge branch 'livekit' into fkwp/feature_relax_homeserver_offline 2026-04-30 21:02:24 +02:00
fkwp 2e4ca9b761 use 10 Seconds of grace period in config.sample.json 2026-04-30 20:54:46 +02:00
fkwp 42aae307f9 use latest stable version of jwt service 2026-04-30 20:53:18 +02:00
fkwp 24c2845958 move starWith to corresponding branch in switchMap 2026-04-30 20:50:45 +02:00
renovate[bot] 51209aa825 Update dependency livekit-client to v2.18.8 (#3934)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-30 20:12:17 +02:00
Timo K e68e62bf41 Merge branch 'livekit' into toger5/back-button-press-control-on-esc 2026-04-30 18:13:03 +02:00
Timo d1dc7cd7bb Merge pull request #3936 from element-hq/valere/fix_playwight_test_web_update
Playwright Test: Update test to react to the new call notification changes on web
2026-05-01 00:06:25 +08:00
Valere 09fc38930f fixup 2026-04-30 17:07:13 +02:00
Valere e79255e23b fix accept call with latest web 2026-04-30 16:47:52 +02:00
Timo K 3caae52ac5 Merge branch 'livekit' into toger5/back-button-press-control-on-esc 2026-04-30 15:18:32 +02:00
Timo K b4dffa598e fix lint 2026-04-30 13:32:27 +02:00
Timo K d5b218283d add max reply SLA 2026-04-30 13:14:13 +02:00
Timo K df78ff6bd2 Fix drawer option 2026-04-28 15:39:17 +02:00
Timo K b5c1b36850 more logging 2026-04-28 13:53:08 +02:00
Half-Shot 5db1a20f9f update snap 2026-04-28 09:29:12 +01:00
Timo K 6b1b316ce4 fix tests 2026-04-27 18:22:06 +02:00
Half-Shot c196e9ea10 Add name 2026-04-27 14:01:04 +01:00
Half-Shot ef1e8b5d3f Merge remote-tracking branch 'origin/livekit' into hs/compound-switch 2026-04-27 13:54:46 +01:00
Will HuntandValere d335a307bb Update compound-web to 9.3.0 and update Buttons from "sm" to "md". (#3926)
* Update compound-web to 9.3.0 and update Buttons from "sm" to "md".

* Clean up the liast bits

* Update snaps too

* fix test, need to dismiss a new dialog

---------

Co-authored-by: Valere <bill.carson@valrsoft.com>
2026-04-27 13:54:00 +01:00
Timo K 89281c6d70 Refactor leveraging the fact, things blocking shortcuts are using react
portals.
2026-04-27 14:21:02 +02:00
Timo K d4a3c8bd80 Contributing.md update. Issue First policy 2026-04-27 13:57:38 +02:00
Half-Shot e3edf3a696 Merge remote-tracking branch 'origin/livekit' into hs/compound-switch 2026-04-27 10:03:41 +01:00
Half-Shot 5aa45714bf Snap updates 2026-04-27 09:34:46 +01:00
Valere 3bc8c0590d dev-tool: Add option to enable extended livekit logs 2026-04-24 18:27:05 +02:00
Half-Shot 62751787ca Use actual package 2026-04-24 13:02:47 +01:00
Half-Shot 9b71070ef8 publish lock changes 2026-04-24 11:57:13 +01:00
Half-Shot d8be069747 Fix type 2026-04-24 11:54:24 +01:00
Valere Fedronic 2ce6098085 Merge pull request #3841 from element-hq/valere/devx/use_synapse_api_for_playwright
Use synapse API to register instead doing via UI
2026-04-24 12:50:39 +02:00
Half-Shot 44b6db6ff1 Replace LayoutToggle with compound-web Switch component 2026-04-24 11:47:24 +01:00
Valere 2f2bdfce5b fixup: wrong skip 2026-04-24 12:32:41 +02:00
Valere 82b7e243eb This test does not need to run on both FF and chrome 2026-04-24 12:10:24 +02:00
Valere 0d5c71bb4e fixup 2026-04-24 11:29:34 +02:00
Valere 0864b7d828 Merge branch 'livekit' into valere/devx/use_synapse_api_for_playwright 2026-04-24 11:25:10 +02:00
Valere ca305b9da1 fix: wrong usage of poll 2026-04-24 11:24:00 +02:00
Valere 6317a06472 review: quick cleaning 2026-04-24 11:21:14 +02:00
renovate[bot] 93657ee3c4 Update dependency livekit-client to v2.18.6 (#3919)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 09:52:04 +02:00
renovate[bot] f98e6d1c08 Update dependency uuid to v14 [SECURITY] (#3918)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 09:20:42 +02:00
renovate[bot]andfkwp 8bd6b04451 Update dependency livekit-client to v2.18.5 (#3912)
* Update dependency livekit-client to v2.18.5

* reenable "Should show error screen if call creation is restricted"

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: fkwp <github-fkwp@w4ve.de>
2026-04-23 19:27:07 +02:00
fkwp 39ef815d8b Merge branch 'livekit' into fkwp/feature_relax_homeserver_offline 2026-04-23 17:29:14 +02:00
Robin 72d922468e Merge pull request #3914 from element-hq/valere/playwright/update_test_for_latest_web
Dismiss the new invite confirmation modal
2026-04-23 17:06:34 +02:00
Ryan Emmick 79b9335192 fix: update i18n translations and developer settings snapshot
Run `yarn i18n` to extract new translation keys for the media quality
settings, and update the DeveloperSettingsTab snapshot to include the
Camera quality, Screen sharing, and Audio processing sections.
2026-04-23 09:51:01 -05:00
Ryan Emmick dedf4e158e refactor: move media settings to developer tab, centralize config defaults 2026-04-23 09:49:14 -05:00
Ryan Emmick 8642646fa7 Add unit tests, revert vite base path change
Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
2026-04-23 09:47:58 -05:00
Ryan Emmick 98f63c7172 Clean up: deduplicate settings UI, fix backupCodec, remove dead export
Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
2026-04-23 09:47:58 -05:00
Ryan Emmick 297470ac2e Use relative base path for vite build
Allows Element Call to be served from a subdirectory (e.g. /widgets/element-call/
in Element Web) without breaking dynamic imports for locales, workers, and other
assets that were previously using absolute paths.

Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
2026-04-23 09:47:58 -05:00
Ryan Emmick b043230680 feat: camera quality settings, audio processing toggles, config-seeded defaults
- Add camera video quality controls (resolution/framerate/bitrate/codec)
  to Settings > Video, mirroring the screen share settings UI
- Add audio processing toggles (echo cancellation, noise suppression,
  auto gain control) to Settings > Audio, replacing URL-param-only controls
- Display raw values inline on all sliders (framerate, bitrate, volume)
- Add config-seeded defaults: config.json media_quality values now seed
  Setting defaults for users who haven't explicitly set preferences
- Camera settings are applied when joining a call via ConnectionFactory

Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
2026-04-23 09:47:58 -05:00
Ryan Emmick bc38d15b6d fix: replace InputField type="select" with native select elements
InputField only supports input/textarea, not select. Passing option
children caused React to crash rendering children inside a void input.

Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
2026-04-23 09:46:47 -05:00
Ryan Emmick 342b61f633 feat: add user-configurable screen share quality settings UI
Adds a "Screen sharing" section to Settings > Video with controls for:
- Resolution (576p to 4K)
- Framerate (5-60 fps slider)
- Bitrate (0.5-15 Mbps slider)
- Codec (VP8/VP9/H.264/AV1)

Gated behind an "Advanced screen share settings" toggle. When enabled,
settings are passed to LiveKit's setScreenShareEnabled as both capture
constraints and publish options. When disabled, falls back to
config.json media_quality defaults.

Settings are persisted in localStorage via the existing Setting<T>
system. The Slider component is extended with a tooltipFormatter prop
for custom tooltip display.

Inspired by pirosuki's advanced-screen-share-settings branch, but
reimplemented cleanly: settings are read directly in LocalMember.ts
(no signature changes), the existing Slider is extended (no component
duplication), and proper form components are used throughout.

Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
2026-04-23 09:46:47 -05:00
Ryan Emmick 390dc22c96 feat: configurable media quality via config.json
Add a `media_quality` section to config.json that allows self-hosters
to configure video codec, resolution, bitrate, framerate, and simulcast
layers for both camera and screen sharing.

This addresses the long-standing request in #249 for configurable media
quality settings. The LiveKit SDK already supports all of these options;
this change exposes them through the existing config system.

New config.json fields:
- media_quality.video_codec: preferred codec (vp8/vp9/h264/av1)
- media_quality.video: camera resolution, bitrate, framerate, simulcast layers
- media_quality.screen_share: screen share resolution, bitrate, framerate,
  simulcast layers (enables 3+ layer simulcast for screen sharing)

All fields are optional and fall back to the existing defaults (VP8,
720p camera, 1080p screen share) when not specified.

Signed-off-by: Ryan Emmick <ryanemmick4@gmail.com>
2026-04-23 09:46:47 -05:00
fkwp 0abc32b80e prettier 2026-04-23 15:47:40 +02:00
Valere 3699138eaa Dismiss the new invite confirmation modal 2026-04-23 15:36:46 +02:00
fkwp c1f821ca0f Update default sync disconnect grace period to 10000ms in configuration and related functions 2026-04-23 15:33:00 +02:00
Valere a7788a2bfa Dismiss the new invite confirmation modal 2026-04-23 11:33:52 +02:00
fkwp 90ba38d2bc setup SFU webhooks for local dev environment to be compatible with delegation of delayed events (#3717)
* setup webhooks for SFUs

* add ca certs to SFU containers such that webhooks are accepted
2026-04-23 10:06:05 +02:00
Valere d9dc61a49d mark test as slow 2026-04-23 09:50:01 +02:00
fkwp 283c606b9d Add tests for grace period handling in createHomeserverConnected$ 2026-04-22 21:46:25 +02:00
fkwp ee343935a4 Merge branch 'fkwp/delegation_of_delayed_events' into fkwp/feature_relax_homeserver_offline 2026-04-22 21:11:23 +02:00
fkwp 032ec662e9 bump lk-jwt-service 2026-04-22 21:08:49 +02:00
fkwp 9fccd49d7d Improve the handling of the grace period for the home server connection to support both immediate and delayed emissions. 2026-04-22 21:08:31 +02:00
Valere 84ac0cc47d mark test as slow 2026-04-22 20:56:42 +02:00
fkwp 9f2db7cfc3 Merge branch 'livekit' into fkwp/delegation_of_delayed_events 2026-04-22 20:42:00 +02:00
Valere e5c11eee13 fix bad assert for reconnect 2026-04-22 20:27:30 +02:00
Valere 6edc4084c6 adjust timeouts 2026-04-22 20:16:59 +02:00
Valere 6d70247acb this test should be slow (taking more than 30s) 2026-04-22 20:13:00 +02:00
Valere 21b78d6dad test something in the reconnect bug 2026-04-22 19:30:15 +02:00
Valere 4d8e4c66eb adjust time out 2026-04-22 19:30:02 +02:00
Valere 78e7adc4c6 remove redundant toBeVisible before click 2026-04-22 18:49:51 +02:00
Valere 5c4d6d0317 turn an assertion as retryable with expect.poll 2026-04-22 18:06:24 +02:00
Valere 1b9682869a adjust timeouts 2026-04-22 17:25:14 +02:00
Valere 854cfdfe1b adjust timeouts 2026-04-22 16:51:04 +02:00
Valere f355aa1ed7 adjust timeout 2026-04-22 15:40:06 +02:00
fkwp 9e2eef09d4 Add support for a grace period for /sync (aka homeserver disconnected) interruptions 2026-04-22 15:18:50 +02:00
Valere 879526ce5e adjust flaky timeouts 2026-04-22 15:17:40 +02:00
Timo 9525136c91 Merge pull request #3908 from element-hq/toger5/back-button-press-control-on-esc
Allow Android native back gesture/button to close settings in EC (only if settings are closed EC will go into pip)
2026-04-22 21:15:33 +08:00
Valere 5dd1c76d1c increase timeout of flaky test 2026-04-22 14:42:35 +02:00
Timo 2e149ad08c Merge pull request #3895 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.18.4
2026-04-22 20:30:20 +08:00
fkwp f919cfa4c8 Translations updates 2026-04-22 12:29:57 +00:00
Valere f9dc4d9b82 Update a tohaveCount() timeout that made a test flak 2 times 2026-04-22 14:14:54 +02:00
Timo K 56bab70534 add tests 2026-04-22 12:26:03 +02:00
Valere 2d9802b6f5 Merge branch 'livekit' into valere/devx/use_synapse_api_for_playwright 2026-04-22 12:10:28 +02:00
Timo K 2b46925e77 Call window.controls.onBackButtonPressed if esc is pressed without any
focus.
2026-04-22 11:51:33 +02:00
renovate[bot] 33172837e7 Update dependency livekit-client to v2.18.4 2026-04-22 07:23:47 +00:00
Valere 55de3fd216 tests optimizations 2026-04-22 09:03:57 +02:00
manfrommedan d1b14d8bfb Add Promise.withResolvers polyfill for older WebViews (Chrome < 119) 2026-04-21 23:29:47 +03:00
Timo 50ad678a42 Merge pull request #3877 from element-hq/toger5/playwright-race-await
Fix race in playwright sticky test
2026-04-22 01:07:07 +08:00
Timo 4155d4c9b3 Merge pull request #3896 from element-hq/toger5/bump-pnpm-to-v10
post pnpm transition work
2026-04-22 01:01:58 +08:00
Timo a1d0a742b2 Merge pull request #3852 from element-hq/toger5/posthog-call-ended-duration-fix
Only send posthog callEnded Event if the user has joined the call.
2026-04-22 01:01:46 +08:00
Valere 0e2d2c6f72 try paralelize registrations? 2026-04-21 18:36:40 +02:00
Valere 754a42ffd1 increase default timeout on huddle test 2026-04-21 18:14:51 +02:00
Valere 701edd9522 fixup lint 2026-04-21 17:54:10 +02:00
Valere 0127040a8c Remove slow? no registration anymore 2026-04-21 17:51:42 +02:00
Valere 24e721f572 fix web stuck problem! go to / and not to #/login 2026-04-21 17:51:42 +02:00
Valere 4211405e7b Use synapse API to register instead doing via UI 2026-04-21 17:51:42 +02:00
Timo K ea73e5881a pevara 2026-04-21 17:29:15 +02:00
Timo K bbb73b27cb fix knip 2026-04-21 17:20:58 +02:00
Timo K ecb2a6846f prettier 2026-04-21 17:13:13 +02:00
Timo K 2d16487ca1 fix sticky send race 2026-04-21 17:11:40 +02:00
Timo K d28cad3f12 fix matrix-js-sdk branch reference 2026-04-21 16:45:00 +02:00
Timo K 92338a2e7c review 2026-04-21 16:12:14 +02:00
Timo K 6ae88531ec pnpm v10.33.0 + lock file 2026-04-21 16:10:57 +02:00
Timo K 8728676eb6 update CI to ignore pnpmfile
- This is save since we never run pnpmfiles in ci
 - We can still run it locally
 - It helps us detect if we accidently commit it anyways.
2026-04-21 16:10:45 +02:00
Timo K 741b82b026 update linking realted logic
- remove post-commit hook
 - remove .links.cjs enable/disable (instead just add/rm .pnpmfile.cjs)
 - rename pnpm links:enable -> pnpm links:on
 - rename pnpm links:disable -> pnpm links:off
 - unify doc filenames `-` -> `_`
 - add linking_concept_reasoning.md to provide background why the
   linking is how it is.
2026-04-21 16:06:51 +02:00
Timo K b58076f1b9 remove pnpmfileChecksum and .pnpmfile.cjs 2026-04-21 15:06:06 +02:00
Robin ab05e8d250 Merge pull request #3900 from element-hq/invert-buttons-again
Invert the microphone and video button colors again
2026-04-21 14:09:29 +02:00
Valere Fedronic 0894659cea Merge pull request #3901 from element-hq/valere/devx/fix_playwright_netlify
fix: using secrets. instead of vars. for NETLIFY_SITE_ID
2026-04-21 13:50:51 +02:00
Valere 84ed5943ea fix: using vars. instead of secrets. for NETLIFY_SITE_ID 2026-04-21 11:55:03 +02:00
Valere Fedronic d6f6542945 Merge pull request #3891 from element-hq/valere/playwrigth/screen_share_test
test: add a screenshare test
2026-04-21 11:22:12 +02:00
Robin e9fd84816e Invert the colors of the camera and microphone buttons again
Turns out design prefers the button colors how they were prior to fa844446b6.
2026-04-21 11:21:48 +02:00
Timo K 00d6e034a0 fixup some missing yarn -> pnpm transitions 2026-04-21 10:53:56 +02:00
Timo K 4d09651fe1 Bump pnpm to v10 2026-04-21 10:00:36 +02:00
Timo 2828b92d91 Merge pull request #3887 from element-hq/fkwp/support_latest_changes_MSC4195
Transitions Element Call from yarn to pnpm.
2026-04-21 00:20:18 +08:00
Timo K ff6112826c missed version bump 2026-04-20 18:02:53 +02:00
Timo K 1f443cf739 bump jwt for dev backend back to proper release
(v0.4.4)
2026-04-20 17:12:56 +02:00
Timo K 66cea929a7 Add back our custom linking plugins to pnpm 2026-04-20 16:59:34 +02:00
fkwp 4d86580542 pin lk-jwt-service to delegation PR 2026-04-17 23:03:17 +02:00
fkwp 2adb498620 prettier 2026-04-17 18:28:02 +02:00
fkwp d75f2563c6 getting ride of shamefully-hoist=true 2026-04-17 18:23:32 +02:00
fkwp 938a03d0c1 address review comments 2026-04-17 18:21:48 +02:00
Valere 8b4762fb29 review: use role locator instead of testID 2026-04-17 17:29:35 +02:00
Valere eeafd81d31 test: add a screenshare test 2026-04-17 14:58:10 +02:00
Robin 2c65a75ba8 Merge pull request #3889 from element-hq/multiple-screen-shares
Fix visual glitches with multiple screen shares
2026-04-17 13:09:41 +02:00
Robin 7e39889f78 Fix name tags appearing in the wrong place with multiple screen shares
They were not properly being contained to where the MediaView is supposed to appear, causing them to all stack up on the first screen share in the spotlight tile.
2026-04-17 12:39:40 +02:00
Robin 96b343effc Fix forward/back buttons not showing up on desktop for multiple screen shares
6667fc54c0 changed this CSS selector that shows buttons on hover to only target the buttons in the bottom right corner of the spotlight tile, causing the forward/back buttons to stay invisible.
2026-04-17 12:23:29 +02:00
fkwp b58ad639c1 Prevents Prettier from formatting the lockfile to avoid conflicts with
pnpm's internal formatting
2026-04-17 11:14:21 +02:00
fkwp 2b42b2bdc1 fix tests after moving to pnpm 2026-04-17 11:13:41 +02:00
Jake Janicke 8eccb95fd3 Merge pull request #3859 from JakeTripplJ/screenshare-audio-filtering-removal
Remove unneeded filtering from screen share audio
2026-04-17 11:10:12 +02:00
fkwp 9c1719a22f Switching to pnpm caused module resolution errors because some dependencies rely on being hoisted to the root. This flag restores the flat node_modules structure temporarily. 2026-04-17 11:08:25 +02:00
fkwp 17ad20cd09 switching from yarn to pnpm 2026-04-17 11:07:31 +02:00
fkwp 5657036f2f Bump matrix js-sdk to support latest MSC4195 update 2026-04-16 17:02:07 +02:00
Timo 565a5ab73f Merge pull request #3885 from element-hq/toger5/bottom-bar-storybook
[Corrected merge target] Footer component -> Storybook
2026-04-16 20:26:32 +08:00
Timo K 0dcd761080 only warn about app bar provider missing on mobile 2026-04-16 11:20:24 +02:00
Valere Fedronic 60fae70a60 Merge pull request #3882 from element-hq/local-screen-share
Fix local screen share not appearing in one-on-one calls
2026-04-16 09:42:33 +02:00
renovate[bot] d31a2a4fdd Update dependency livekit-client to v2.18.3 (#3883)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 07:29:49 +00:00
Robin e8963effe2 Test that the local user can see their own screen share
To make this test work I had to extend the mocking of the CallViewModel tests to make a local connection object exist.
2026-04-15 20:03:49 +02:00
Robin b03524e25f Make screen sharing work more like speaking marbles in tests
This approach is more flexible in that it allows even the local participant to share their screen in CallViewModel tests, and more rigorous in that it ensures that application code is reacting specifically to track publications.
2026-04-15 19:56:04 +02:00
Robin 832c5784d4 Fix local screen share not appearing in one-on-one calls
This was regressed by 9dfade68ee.
2026-04-15 19:55:32 +02:00
Robin 014f645bb3 Merge pull request #3880 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.18.2
2026-04-15 17:00:28 +02:00
Timo K cea32b86a3 remove reactive url param for showFooter 2026-04-15 16:47:18 +02:00
renovate[bot] bbda8ecdcf Update dependency livekit-client to v2.18.2 2026-04-15 14:43:02 +00:00
Timo K 9fa382ed0c fix loudspeaker confusion and icons 2026-04-15 16:42:28 +02:00
Timo K 3fc823e049 Fix unit tests 2026-04-15 15:51:21 +02:00
Timo c922936777 Merge pull request #3856 from element-hq/toger5/move-settings-out-of-bottom-bar
Move settings button out of the button bar (space for loud-speaker button)
2026-04-15 21:14:19 +08:00
Timo K 486b3ea45d Merge branch 'toger5/move-settings-out-of-bottom-bar' into toger5/bottom-bar-storybook 2026-04-15 14:53:08 +02:00
Timo K 71e389cdef unit test snapshots 2026-04-15 14:45:53 +02:00
Valere Fedronic d19191a2d3 Merge pull request #3878 from element-hq/valere/fix_deploy_playwright_artifact
fixup: Looks like the upload & download action used are not compatible
2026-04-15 14:42:57 +02:00
Timo K 505e408c47 Merge branch 'toger5/move-settings-out-of-bottom-bar' into toger5/bottom-bar-storybook 2026-04-15 14:42:26 +02:00
Timo K f07bf5c520 fix lint 2026-04-15 14:37:13 +02:00
Timo K 75fb89a98a review: update styles + aria hidden 2026-04-15 14:20:19 +02:00
Valere 29ba0bdf13 make zizmore happy with exact version in comment 2026-04-15 14:13:58 +02:00
Timo K e46be38869 Make mediaDevices less confusing 2026-04-15 14:04:00 +02:00
Valere 0350f57275 fixup: Looks like the upload & download action used are not compatible 2026-04-15 14:01:26 +02:00
Valere Fedronic 6512a9d843 Merge pull request #3666 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.17.2
2026-04-15 13:39:49 +02:00
Timo K dbf76db590 cleanup ReactionData 2026-04-15 13:06:47 +02:00
Timo K 3cb092f541 Revert "fix race in playwright sticky test"
This reverts commit 57f12d3d1c.
2026-04-15 11:51:41 +02:00
Timo K b59600099d fix logo in lobby 2026-04-15 11:46:08 +02:00
Valere 7871877863 bump livekit server version 2026-04-15 11:27:13 +02:00
Valere Fedronic 9056989f0e Merge pull request #3858 from element-hq/valere/devx/netlify_playwright_report
devx: Use new action to netlify the playwright report as EW is doing
2026-04-15 11:12:47 +02:00
Robin 27a6e67ce9 Merge pull request #3870 from element-hq/delete-unused-css
Delete unused CSS file
2026-04-15 11:09:33 +02:00
Valere 68518e323e Skip NotAllowed test until livekit allows to detect that again 2026-04-15 10:28:19 +02:00
Robin eccf119afd Merge pull request #3871 from element-hq/no-app-prompt
Get rid of the 'open in app' mobile prompt
2026-04-14 18:39:06 +02:00
Timo K 242c40af14 move appBar hook to InCallView 2026-04-14 18:36:36 +02:00
Timo K dd80679ec5 test snapshot 2026-04-14 18:17:00 +02:00
Timo K 4b62ab2083 Merge branch 'toger5/move-settings-out-of-bottom-bar' into toger5/bottom-bar-storybook 2026-04-14 18:16:19 +02:00
Timo K 32823aef92 test and lints 2026-04-14 18:15:20 +02:00
Timo K 4295ae55d4 Merge branch 'toger5/move-settings-out-of-bottom-bar' into
toger5/bottom-bar-storybook
2026-04-14 18:09:59 +02:00
Timo K ab751e8c38 review: smaller changes
- use correct button styles
 - move overrides to options
 - add flex-wrap: nowrap
2026-04-14 17:44:47 +02:00
Timo K f7e1fa74cd review: hide logo at 750px already 2026-04-14 17:44:47 +02:00
Timo K a069d28f3a review: make appBar styling use IconButton (fix margins) 2026-04-14 17:44:47 +02:00
TimoandRobin ed83672720 Update src/room/InCallView.tsx
Co-authored-by: Robin <robin@robin.town>
2026-04-14 17:43:05 +02:00
Timo K 57f12d3d1c fix race in playwright sticky test 2026-04-14 16:23:05 +02:00
Timo K 2ae1df467d knip 2026-04-14 14:30:46 +02:00
Timo K 2d5de234d2 prettier 2026-04-14 14:26:00 +02:00
Timo K 3c039be7f2 lint 2026-04-14 14:11:08 +02:00
Timo K 8c5668bf1a Breaking changes detected by snapshot tests.
Add screenshare button back to snapshot test.
Remove reaction button.
2026-04-14 14:06:20 +02:00
Timo K 400259207e Also use CallFooter for lobby 2026-04-14 13:25:33 +02:00
Valere Fedronic c79251682d Merge pull request #3872 from element-hq/floating-tile-inset
Move local video tile in one-on-one layout to be flush with the edge
2026-04-14 09:44:14 +02:00
Timo K be74ebbb6c convert to from so that multiple layout switcher dont collide in
storybook.
2026-04-13 19:04:44 +02:00
Timo K 02fa29c7b2 lint 2026-04-13 18:40:56 +02:00
Timo K 7e1ee2eece Merge branch 'toger5/move-settings-out-of-bottom-bar' into toger5/bottom-bar-storybook 2026-04-13 18:40:14 +02:00
Timo K 118d11ceec Merge branch 'livekit' into toger5/move-settings-out-of-bottom-bar 2026-04-13 18:36:03 +02:00
Robin 438b6b8672 Move local video tile in one-on-one layout to be flush with the edge
Per design updates.
2026-04-13 18:30:42 +02:00
Robin 364fdb5e54 Get rid of the 'open in app' mobile prompt
We've determined that calls are working fine in mobile browsers these days and we no longer need it.
2026-04-13 18:05:00 +02:00
Timo K 5f0afd3edc Add tests to make sure we always have one settings button. 2026-04-13 15:49:28 +02:00
Valere Fedronic 23eadfcc9f Merge pull request #3869 from element-hq/footer-space
Make the footer move floating tiles out of the way when shown
2026-04-13 15:46:20 +02:00
Robin 3b0dce33a2 Merge pull request #3863 from element-hq/renovate/major-compound
Update Compound (major)
2026-04-13 15:30:29 +02:00
Robin 9df60310e4 Update test snapshots 2026-04-13 15:13:19 +02:00
Robin 4d1fbf0502 Delete unused CSS file
Seems this was mistakenly committed during initial development of the Grid component. src/grid/Grid.module.css is the one that's actually used.
2026-04-13 15:08:40 +02:00
Robin 0025d4f882 Merge pull request #3868 from element-hq/reactions-placement
Fix placement of reaction and raised hand indicators
2026-04-13 15:06:44 +02:00
Timo K 270726d446 Add tests 2026-04-13 13:38:35 +02:00
Robin 5daa110f7e Make the footer move floating tiles out of the way when shown
If you manage to move your floating video tile to the bottom of the screen in a small landscape window, the footer obscures the tile when shown. The designs want us to smoothly move the floating tile out of the way in this case.
2026-04-13 13:13:09 +02:00
Robin 0842b2b472 Fix placement of reaction and raised hand indicators 2026-04-13 13:02:15 +02:00
Robin 01bd1e3af7 Merge pull request #3842 from element-hq/voice-intents
Add intents for group voice calls
2026-04-13 12:34:45 +02:00
Valere 07e3dc1ca4 Update livekit to 2.18.1
Fix mocking in a test
Also add "skipLibCheck": true in tsconfig
2026-04-13 10:02:54 +02:00
Valere dbeae383eb update livekit again 2026-04-13 09:35:08 +02:00
fkwp 79de8dffff fix test as with the recent version of livekit-client the URL format changed 2026-04-13 09:22:24 +02:00
renovate[bot] 1b67f3d887 Update dependency livekit-client to v2.17.2 2026-04-13 09:22:24 +02:00
renovate[bot] 9ac42b240e Update Compound 2026-04-13 01:27:40 +00:00
Timo K 098a8c0c41 Improve logic for settings button show/hide.
Fix button shown in appbar
2026-04-10 18:59:17 +02:00
Timo K c59de789e5 Update AppBar.tsx 2026-04-10 18:46:44 +02:00
Timo K 9905afd2ad add appBar logging 2026-04-10 18:45:34 +02:00
Timo K 8956d55d5c dont call useAppBarSecondaryButton two times 2026-04-10 18:38:35 +02:00
Timo K 16f9c107a5 better default InCallFooter story config 2026-04-10 18:28:15 +02:00
Timo K c02f2bf140 lint 2026-04-10 18:28:15 +02:00
Timo K 251a41e7a5 fix imports 2026-04-10 18:28:15 +02:00
Timo K 8ca1b2c749 update snapshot to include the two settings buttons corner + bottom bar. 2026-04-10 18:28:15 +02:00
Timo K 9e86d517a0 move footer related css to InCallFooter.module.css 2026-04-10 18:28:13 +02:00
Timo K 134fdeef3a Fix logic for hiding the logo.
Was shown on embedded mobile on wide screens.
2026-04-10 18:27:56 +02:00
Timo K 9de5938e79 Add back the settings button to the bottom buttons group for SPA mobile.
This is an edgecase where we need the settings button but have hidden it
before.
2026-04-10 18:27:52 +02:00
Timo K f75e91fc2b move show footer logic to callViewModel
Also remove header prop. This is accesible via urlParams.
2026-04-10 18:27:24 +02:00
Timo K 6be06de153 fix tests 2026-04-10 18:27:24 +02:00
Timo K 9528c4f837 fix lints 2026-04-10 18:27:24 +02:00
Timo K 5da7dd6413 Move footer to storybook 2026-04-10 18:27:24 +02:00
Valere Fedronic fae3c4195f Merge pull request #3854 from element-hq/valere/fix_race_connection_fails
Fix a race connection causing the joiner to never publish media to the call
2026-04-10 11:12:55 +02:00
Valere 208184909e fixup: prettier 2026-04-10 10:08:57 +02:00
Valere aea5815dab Ensure we don't publish to any transport until our own transport is ok 2026-04-10 09:24:34 +02:00
Timo K 2e9c8bd3ce fix playwright tests 2026-04-09 16:47:42 +02:00
Valere 0f14da7fbb devx: Use new action to netlify the playwright report as EW is doing 2026-04-09 16:33:26 +02:00
Valere 40dacd523b review: Move the all advertised/active down to the LocalMember
And let the local member use it properly to send membership event and publish media
2026-04-09 15:22:10 +02:00
Timo K a74c8025ac fix imports 2026-04-09 13:32:29 +02:00
Timo K 9d20ec00f1 Add test for the media switch button:
- is it available in the bottom bar
 - does pressing it trigger the expected callback
2026-04-09 13:25:23 +02:00
Timo K 4356e8cdb2 Merge branch 'livekit' into toger5/move-settings-out-of-bottom-bar 2026-04-09 10:10:28 +02:00
Timo 44958db514 Merge pull request #3851 from element-hq/toger5/shodow-for-draggable
Add a shadow to draggable items to prohibit invisible PIP outlines.
2026-04-09 15:52:33 +08:00
Robin 330584ac31 Merge pull request #3827 from element-hq/storybook
Set up Storybook again
2026-04-08 17:12:16 +02:00
Timo K 00cfb8bb10 update test snapshots 2026-04-08 16:41:54 +02:00
Timo K 2bca491b0c ignore story files for coverage 2026-04-08 16:38:52 +02:00
Timo K 9764f6f5de Update .eslintrc.cjs 2026-04-08 16:18:51 +02:00
Timo K 69bcdc1bea fixup yarn after merge 2026-04-08 16:18:06 +02:00
Timo K 27b42ca641 Merge branch 'livekit' into storybook 2026-04-08 16:17:37 +02:00
Timo K cf642aa670 Move settings button out of the button bar.
User overflow button instead: at the top for mobile, bottom left for
web.
2026-04-08 16:05:46 +02:00
Robin 417164cc11 Merge pull request #3855 from element-hq/changelog-labels
Reconfirm that a PR has a changelog label when new commits are pushed
2026-04-08 16:00:07 +02:00
Robin 2a5acc0207 Reconfirm that a PR has a changelog label when new commits are pushed
Without re-running the changelog label workflow on new commits, PRs get stuck waiting for the check after new commits are pushed.
2026-04-08 15:08:54 +02:00
Valere 08006d640a fix: Ensure to publish on the correct transport 2026-04-08 11:10:27 +02:00
Valere 58d377c3f7 test: Add publishing bug reproduction test 2026-04-08 11:06:05 +02:00
Timo K 1c5b483a7e Only send callEndedEvent if the user has joined the call. 2026-04-07 14:11:55 +02:00
Timo K 6c8219a26b Add a shadow to draggable items to prohibit invisible PIP outlines. 2026-04-07 13:02:46 +02:00
Robin efd1b42da0 Merge pull request #3847 from element-hq/renovate/npm-vite-vulnerability
Update dependency vite to v8 [SECURITY]
2026-04-07 01:45:41 +02:00
Robin 31b35463fc Fix build 2026-04-07 01:31:21 +02:00
renovate[bot] 89c4485f2d Update dependency vite to v8 [SECURITY] 2026-04-06 21:16:47 +00:00
Robin 3c2c189830 Merge pull request #3838 from element-hq/valere/refactor_transport_discovery
Refactor LocalTransport discovery and validation
2026-04-06 13:24:16 +02:00
Robin 2c34e681a1 Fix tests 2026-04-06 12:58:26 +02:00
Robin 48226795de Merge pull request #3846 from element-hq/renovate/major-compound
Update dependency @vector-im/compound-design-tokens to v9
2026-04-06 12:44:47 +02:00
renovate[bot] 3503f8177d Update dependency @vector-im/compound-design-tokens to v9 2026-04-06 01:31:03 +00:00
Valere 9fe35ba822 Add back the patch to avoid reconnect glitch 2026-04-03 19:08:52 +02:00
Robin a84419c8a4 Merge pull request #3824 from element-hq/renovate/major-compound
Update dependency @vector-im/compound-design-tokens to v8
2026-04-03 19:07:59 +02:00
Valere a89d231858 review change comment to proper doc 2026-04-03 18:51:14 +02:00
Robin f0ec4b9add Add intents for group voice calls
This adds two new intents: start_call_voice and join_existing_voice. I need the latter in order to implement Element Web's new incoming call toasts, in which you can turn off your video before joining a group call. The other one, start_call_voice, exists more for completeness than anything; we don't currently want to allow users to start voice calls in group chats in our messenger clients, but maybe Cinny would, for instance.
2026-04-03 18:47:13 +02:00
Valere 6d99450d81 review: Remove un-needed initial value for behavior 2026-04-03 18:46:49 +02:00
Robin 47e14ff574 Merge pull request #3832 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-04-03 18:09:58 +02:00
Robin 55eea7a968 Fix type error 2026-04-03 17:48:42 +02:00
Robin 121160e835 Merge pull request #3837 from element-hq/renovate/npm-lodash-es-vulnerability
Update dependency lodash-es to v4.18.1 [SECURITY]
2026-04-03 14:57:35 +02:00
Valere Fedronic 47cb01ab6f Merge pull request #3839 from element-hq/valere/revert_widget_cap_workaround
revert workaround for widget permission dialog, not needed anymore
2026-04-03 11:17:46 +02:00
Valere 3d286e8ab4 revert workaround for widget permission dialog, not needed anymore 2026-04-03 09:45:59 +02:00
Valere b1f84a34a8 remove dead commented code 2026-04-02 20:42:09 +02:00
Valere 95eb8943af fixup test: Errors are now wrapped in user readable error
and proper fetchmock for doNetworkOperationWithRetry
2026-04-02 19:05:24 +02:00
Valere b5be123953 fix uncaught errors in tests 2026-04-02 16:53:51 +02:00
Valere 90bfaecd13 refact: step 2 - break down old membership local transport logic 2026-04-02 16:53:51 +02:00
Valere 4cecdda955 refact: step 1 - extract oldest membership transport into new function 2026-04-02 16:53:51 +02:00
Valere 869bab8253 fixup test since usage of doNetworkOperationWithRetry
doNetworkOperationWithRetry requires to properly mock the get_token endpoint, whereas retryNetworkOperation didn't require it.
2026-04-02 16:53:51 +02:00
Valere 23f846a308 fixup: test prettier 2026-04-02 16:53:51 +02:00
Valere 6dcb470162 Refactor local transport
- use the new domain logic to discover the transport
- then try to authenticate
- Also fix the bug in multi sfu where active$ not updated on delayId change
2026-04-02 14:38:49 +02:00
Valere c5c154c99b add self contained domain logic to discover transports 2026-04-02 14:37:25 +02:00
Valere fd08489afb add failing test showing delayId not properly used for delegation 2026-04-02 14:32:26 +02:00
renovate[bot] 67d7ec6703 Update dependency lodash-es to v4.18.1 [SECURITY] 2026-04-02 08:02:14 +00:00
Valere Fedronic a2005febd5 Merge pull request #3835 from element-hq/redundant-pip
Avoid redundantly showing the local user in the PiP tile
2026-04-02 10:01:32 +02:00
renovate[bot] 5e337a5399 Update dependency @vector-im/compound-design-tokens to v8 2026-04-01 20:36:05 +00:00
renovate[bot] e0a8e84df4 Update all non-major dependencies 2026-04-01 20:35:33 +00:00
renovate[bot] 99ba23bc96 Update GitHub Actions (#3831)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-01 17:33:25 +02:00
Robin f7488a0474 Avoid redundantly showing the local user in the PiP tile
If you are the only participant in the call, the expanded spotlight layout would redundantly show your media in both the spotlight and PiP tiles. This is a regression; in versions 0.16.1 and earlier we would avoid showing the same user twice.
2026-04-01 13:16:39 +02:00
fkwp cbb9e7a289 Merge branch 'livekit' into fkwp/delegation_of_delayed_events 2026-04-01 11:46:29 +02:00
Valere Fedronic bb7b2d1060 Merge pull request #3818 from element-hq/valere/msc_4039
msc4039 support b64 in addition to blob file download
2026-03-31 19:15:13 +02:00
Valere b5870c9e78 Merge branch 'livekit' into valere/msc_4039 2026-03-31 18:48:13 +02:00
Valere Fedronic 1fce220965 Merge pull request #3828 from element-hq/valere/fix/stop_calling_msc4143_in_widget
Stop calling rtc/transport in widget mode
2026-03-31 18:47:20 +02:00
Valere cd3c8f001f Merge branch 'livekit' into valere/msc_4039 2026-03-31 17:24:52 +02:00
Valere f316ece404 Merge branch 'livekit' into valere/fix/stop_calling_msc4143_in_widget 2026-03-31 17:15:08 +02:00
Valere Fedronic ce1cd9aefb Merge pull request #3830 from element-hq/valere/tmp_fix_download_file_permission
Workaround: EW has not yet merged the download file permission for EC
2026-03-31 17:14:15 +02:00
Valere d5ec3c342c reuse exisiting helpers to join call 2026-03-31 16:06:56 +02:00
Valere c9242148f9 add missing dismiss dialog test 2026-03-31 15:24:12 +02:00
Valere 0dabb43e0f Workaround: EW has not yet merged the download file permission for EC 2026-03-31 14:56:25 +02:00
Valere 8cee4df46e fix test: use fetchMock to avoid test interference 2026-03-31 12:03:02 +02:00
Valere 6b7467ce6d Stop calling rtc/transport in widget mode 2026-03-31 11:38:21 +02:00
Robin c9eab59161 Create a StarRatingInput story 2026-03-30 18:26:38 +02:00
Robin 4cf75c8eeb Create a LayoutToggle story 2026-03-30 18:26:38 +02:00
Robin 2de151d94d Set up Storybook again 2026-03-30 18:26:38 +02:00
fkwp 4006a8d9f9 Merge branch 'livekit' into fkwp/delegation_of_delayed_events 2026-03-27 15:29:16 +01:00
Valere 3389fb5a34 fixup linter 2026-03-26 19:39:02 +01:00
Valere 421c49e7ba fixup prettier 2026-03-26 19:10:10 +01:00
Valere 1eabb0f0aa add tests 2026-03-26 18:14:51 +01:00
Valere 8f38ecac2e msc4039 support b64 in addition to blob file download 2026-03-26 15:29:51 +01:00
Valere Fedronic 40fdef89eb Merge pull request #3780 from JephDiel/Download-Avatars-with-MC4039
Download avatars using the MC4039 Widget API
2026-03-26 09:03:15 +01:00
Timo K 2faab3280a bump flatted and unidici 2026-03-25 16:07:01 +01:00
Valere Fedronic 2ab5e07f73 Merge pull request #3801 from element-hq/valere/default_route
Audio Control | Default to using earpiece when doing audio vs speaker for video call (depending on presence of headset or not)
2026-03-25 13:16:53 +01:00
Valere 09092e97c8 fix error in test 2026-03-25 12:15:12 +01:00
Valere cb6bef3849 try extend timeout? 2026-03-25 10:10:29 +01:00
Valere 4d491be4a9 post merge fix 2026-03-25 08:21:32 +01:00
Valere aad160a715 Merge branch 'livekit' into valere/default_route 2026-03-24 18:28:54 +01:00
Valere fc61a36d4a review: improve comments 2026-03-24 18:25:09 +01: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
Robin b40feae7da Merge pull request #3810 from element-hq/robin/button-accessibility
Improve accessibility of microphone, camera, and screen share buttons
2026-03-24 17:36:36 +01:00
Robin e15761d8ee Merge pull request #3703 from element-hq/renovate/compound
Update Compound
2026-03-24 17:20:01 +01:00
Robin c60ed50a9d Attempt to fix end-to-end widget tests 2026-03-24 17:04:28 +01:00
Robin 6dcd883fc3 Update test snapshots 2026-03-24 16:10:19 +01:00
Robin c0d60b2c29 Improve accessibility of microphone, camera, and screen share buttons
Taking Valere's suggestion of giving them the 'switch' role. Also, the aria-label attributes were redundant (having tooltips already gives the buttons aria-labelledby).
2026-03-21 02:53:48 +01:00
Valere c8b8d350d5 Merge branch 'livekit' into valere/default_route 2026-03-19 18:41:36 +01:00
Valere 9c2b2d4780 fix: playwright, new web popup interfering with test to witch room 2026-03-19 10:44:38 +01:00
Valere 396225a900 fix playwright earpiece mode 2026-03-19 10:44:38 +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
Valere Fedronic 385ab0a0ed Merge pull request #3805 from element-hq/robin/ringing
New ringing UI
2026-03-19 10:43:16 +01:00
Robin 4d69565312 Merge pull request #3809 from element-hq/robin/invert-buttons
Invert the colors of the camera and microphone buttons
2026-03-18 14:49:55 +01:00
Robin fa844446b6 Invert the colors of the camera and microphone buttons
So that they use primary color tokens when unmuted, and secondary color tokens when muted. This makes them work like the screen sharing button.
2026-03-18 11:29:55 +01:00
Robin 9dfade68ee New ringing UI
This implements the new ringing UI by showing a placeholder tile for the participant being dialed, rather than an overlay.
2026-03-18 11:20:43 +01:00
renovate[bot] 32ea8f522c Update Compound 2026-03-15 01:47:49 +00:00
renovate[bot] 6d14f1d06f Update GitHub Actions (#3804)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-14 14:48:44 +00:00
JephDiel 997cc9bb27 Lint fixes v2 2026-03-13 11:41:58 -05:00
JephDielandTimo fa74aaa81e Import order lint fixes
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2026-03-13 11:33:07 -05:00
JephDielandTimo af807489f9 Import order lint fixes
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2026-03-13 11:31:55 -05:00
Robin 5cf5227eaa Merge pull request #3802 from element-hq/toger5/fix-qs-glob-js-yaml-security
Update qs, js-yaml, glob for security patches
2026-03-13 17:31:40 +01:00
Timo K 78240c2ec8 update qs, js-yaml, glob for security patches 2026-03-13 08:01:52 +01:00
Timo K bf8bf80417 Revert "update qs, js-yaml, glob for security patches"
This reverts commit 7da9bca08c.
2026-03-13 08:01:08 +01:00
Timo K 7da9bca08c update qs, js-yaml, glob for security patches 2026-03-13 07:59:49 +01:00
JephDiel b198721969 Ignore stale downloads
If src or sizePx changes while we're downloading,
discard the now-stale fetch result so we don't
override the fresh one.
2026-03-12 22:20:19 -05:00
JephDiel 8ecb1b3dbf Simplify widget detection
Use the exists check for the widget API directly
instead of a feature flag.
2026-03-12 22:18:38 -05:00
Timo 748c8e6d0d Merge pull request #3800 from element-hq/toger5/fix-tar-minimatch-security
Bump tar, minimatch
2026-03-12 23:54:10 +08:00
Timo 40ef16a55f Merge pull request #3799 from element-hq/toger5/fix-rollup-security-alert
Update vite, vitest and rollup
2026-03-12 23:51:53 +08:00
Timo 07ad8374a9 Merge pull request #3595 from element-hq/toger5/dont-trap-in-invalid-config
Reset overwrite url if it is invalid (does fail to reach sfu)
2026-03-12 22:06:26 +08:00
Timo K a0d5c79999 also update coverage 2026-03-12 14:52:16 +01:00
Timo K 3e171d9639 bump tar, minimatch
security alert
2026-03-12 14:48:05 +01:00
fkwp 413329cd26 Fix: zizmor findings (#3797)
* zizmor auto fixes

* add github action for security analysis with zizmor

* add access token to iOS push action

* fix zizmor findings

* add exceptions for dangerous-triggers including comments for reasoning

* improve comments

* prettier
2026-03-12 13:30:45 +01:00
Timo K 6b8f6e9405 update vite vitest and rollup
(rollup needs updating to fix a security alert)
2026-03-12 12:10:17 +01:00
fkwpandGaël Goinvic af54b39698 fix: typo pushing element registry OCI images now to the correct target (#3796)
* Push docker images to oci.element.io

* prettier

* add id-token permission as its required by tailscale login

* pass secrets to reusable workflows

* change secret path team -> voip

* Update .github/workflows/build-and-publish-docker.yaml

Co-authored-by: Gaël Goinvic <97093369+gaelgatelement@users.noreply.github.com>

* typo

---------

Co-authored-by: Gaël Goinvic <97093369+gaelgatelement@users.noreply.github.com>
2026-03-11 16:09:02 +01:00
Timo c05d223133 Merge pull request #3775 from element-hq/toger5/new-pip-layout
Implement new Pip Layout (with control buttons)
2026-03-11 23:07:47 +08:00
Timo K c7f25feb66 use better test condition for mute buttons 2026-03-11 15:46:19 +01:00
Timo K a20edca9a1 fix pip container query 2026-03-11 15:36:37 +01:00
Timo K d00ff78d65 fix pip interaction test (button presses) 2026-03-11 15:21:36 +01:00
fkwpandGaël Goinvic 839c4dd738 fix: OCI image push to element registry (#3795)
* Push docker images to oci.element.io

* prettier

* add id-token permission as its required by tailscale login

* pass secrets to reusable workflows

* change secret path team -> voip

* Update .github/workflows/build-and-publish-docker.yaml

Co-authored-by: Gaël Goinvic <97093369+gaelgatelement@users.noreply.github.com>

---------

Co-authored-by: Gaël Goinvic <97093369+gaelgatelement@users.noreply.github.com>
2026-03-11 15:17:12 +01:00
fkwp 41f7b643fb Add zizmor checks on CI (#3792)
* zizmor auto fixes

* add github action for security analysis with zizmor

* add access token to iOS push action
2026-03-11 14:20:05 +01:00
Timo K 3a9d394529 activate click tests 2026-03-11 14:05:17 +01:00
fkwp c9557e91d5 fix: add id-token permission as its required by tailscale login (part 3) (#3793)
* Push docker images to oci.element.io

* prettier

* add id-token permission as its required by tailscale login

* pass secrets to reusable workflows
2026-03-11 13:06:20 +01:00
Timo K 1e400bc550 remove unsused import 2026-03-10 18:26:12 +01:00
Timo K 6485da8fff add playwright tests for new pip layout 2026-03-10 15:17:41 +01:00
Timo K 54bef07b3b linter 2026-03-10 13:57:06 +01:00
Timo K 273eedd256 keep pip as it was before on mobile 2026-03-10 13:57:06 +01:00
Timo K 38382539ad fix lints 2026-03-10 13:57:06 +01:00
Timo K 8db1c4c370 Implement new Pip Layout (with control buttons) 2026-03-10 13:57:06 +01:00
Valere Fedronic c98d03e2e1 Merge pull request #3787 from element-hq/valere/fix_typo_width_height
fix: typo inverting with/height in PIP spotlight tile
2026-03-10 09:38:53 +01:00
Valere 143b560b20 Add a playwright test to ensure object fit is correct 2026-03-10 09:05:05 +01:00
JephDiel 699e31f59a Download Avatar from relevent source
Instead of relying on failures directly use the
available method to download the avatar.
2026-03-09 23:16:12 -05:00
Valere 3da762ab36 fix: typo inverting with/height in PIP spotlight tile 2026-03-09 17:49:04 +01:00
Valere Fedronic efcde9edfe Merge pull request #3756 from element-hq/valere/auto_fit_based_on_video_ratio
Auto fit video in tile depending on orientation of the tile and the source stream
2026-03-09 15:31:15 +01:00
Valere ca3837f44e fix merge issue that added back a deprecated test 2026-03-09 15:07:42 +01:00
Robin 467675ff40 Merge pull request #3785 from robintown/unpin-deps
Unpin Knip and LiveKit track processors
2026-03-09 14:35:52 +01:00
Valere 5a612fea91 Merge branch 'livekit' into valere/auto_fit_based_on_video_ratio 2026-03-09 14:30:54 +01:00
Valere Fedronic 17ec488f0b Merge pull request #3784 from element-hq/valere/pr_template
Devx: Add a PR template
2026-03-09 14:15:14 +01:00
Valere 8f418ce9fd fix cla link 2026-03-09 13:59:39 +01:00
Robin 4c7fad30c0 Silence new Knip errors 2026-03-09 13:11:48 +01:00
Robin 4922249f41 Unpin Knip and LiveKit track processors
These dependencies were held back on old versions because of issues that are now resolved (see 2fca7e3719 and 44eb8acaee).
2026-03-09 13:00:43 +01:00
Robin 06c15ded37 Merge pull request #3747 from JakeTripplJ/screenshare-volume
Add volume control to screen shares
2026-03-09 10:59:45 +01:00
Robin 885a523e91 Fix formatting 2026-03-09 10:44:22 +01:00
Robin 313b8285d9 Make the screen share volume button accessible on mobile
In landscape orientation the button would be buried underneath the footer, which would block interaction with it. This commit changes the footer to not show in cases where a button has been pressed.
2026-03-09 10:30:42 +01:00
Valere d00e1ca983 Devx: Add a PR template 2026-03-09 09:55:56 +01:00
Valere 513477d280 review: Use targetWidth/Height instead of listening to element bounds 2026-03-09 09:45:25 +01:00
Valere 273fff20bd review: add comment 2026-03-09 09:12:03 +01:00
JephDiel 005b965fba Download avatars using the Widget API
If we can't authenticate media because we're
running as a widget, use the MC4039 widget API
instead of a direct fetch to download the avatar.
2026-03-07 19:53:57 -06:00
Robin 3bbbac23a0 Adjust dimensions of screen share volume menu 2026-03-06 23:15:59 +01:00
Robin c7a16e9dfd Refactor screen share volume button into a component 2026-03-06 23:14:15 +01:00
Jake Janicke 5f2d1c8a7e Comment typo
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 17:50:31 -06:00
Jake Janicke e99e8628d6 Clean up and streamline safety checking instead of using multiple separate checks
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 17:09:07 -06:00
Jake Janicke 65045c264b Fix formatting
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 16:11:39 -06:00
Jake Janicke 3216d68470 Make screenShareVolume safer
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 16:05:56 -06:00
Jake Janicke 99401a7285 Make screenShareLocallyMuted check safer
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 15:13:20 -06:00
Jake Janicke c74d19ad33 Add more guards against undefined
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 13:56:30 -06:00
Jake Janicke ea074ceb2d Sort translation keys
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 13:16:51 -06:00
Jake Janicke b88daf0198 Add tests for screen share volume UI presence logic
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 05:07:41 -06:00
Jake Janicke a34fe7817a Add tests for screen share volume controls
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 03:52:46 -06:00
Jake Janicke 72520dbb3f Add screen share volume slider UI
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-04 03:52:38 -06:00
Jake Janicke 2cf4a38c17 Add volume logic to RemoteScreenShareViewModel
Signed-off-by: Jake Janicke <jaketripplj@gmail.com>
2026-03-03 16:47:41 -06:00
fkwp 00f880108e fix: add id-token permission as its required by tailscale login (part 2) (#3770)
* Push docker images to oci.element.io

* prettier

* add id-token permission as its required by tailscale login
2026-03-02 17:03:01 +01:00
Valere Fedronic a2ee0163b6 Merge pull request #3752 from element-hq/valere/remove_deprecated_param
remove deprecated `analyticsID` url param
2026-03-02 16:10:27 +01:00
Valere 5165e95d82 fix: default to cover is size are 0 2026-03-02 15:38:43 +01:00
fkwp 6e0f48e99b fix: add id-token permission as its required by tailscale login (#3768)
* Push docker images to oci.element.io

* prettier

* add id-token permission as its required by tailscale login
2026-03-02 15:04:18 +01:00
Valere adc329a7e7 post merge fix 2026-03-02 14:41:47 +01:00
Valere c199d00300 Merge branch 'livekit' into valere/auto_fit_based_on_video_ratio 2026-03-02 14:31:47 +01:00
Robin 38e79bb7db Merge pull request #3764 from element-hq/renovate/github-actions
Update docker/login-action digest to c94ce9f
2026-03-02 13:44:15 +01:00
Robin 23050075b7 Merge pull request #3765 from element-hq/renovate/embedded-package-dependencies
Update embedded package dependencies
2026-03-02 12:31:27 +01:00
renovate[bot] b2475e4d1d Update embedded package dependencies 2026-03-01 01:11:41 +00:00
renovate[bot] 8e7e099294 Update docker/login-action digest to c94ce9f 2026-03-01 01:11:01 +00:00
Robin dcb7143359 Merge pull request #3755 from element-hq/robin/ringing
Convert media view model classes to interfaces
2026-02-27 17:27:58 +01:00
Robin 0ce24929dc Add TODO to clean up encryption status code 2026-02-27 17:12:24 +01:00
Robin 9930288d1f Move observeInboundRtpStreamStats$ into the appropriate file 2026-02-27 17:08:04 +01:00
Valere ae8b1f840f add missing mocking 2026-02-26 17:02:43 +01:00
Valere 15aa67ebb9 remove unused fit to frame translation 2026-02-26 16:46:08 +01:00
Valere 1de8d93b4b feat: video auto fit based on video stream size 2026-02-26 16:28:37 +01:00
Robin 6b51b7dc58 Split MediaViewModel into multiple files 2026-02-25 22:41:28 +01:00
Robin d16fa4531c Merge pull request #3712 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-02-25 19:52:22 +01:00
Robin 44eb8acaee Pin Knip to 5.82.1 to work around Yarn plugin issue
We can upgrade beyond 5.82.1 once https://github.com/webpro-nl/knip/pull/1574 is merged.
2026-02-25 19:36:00 +01:00
Robin 2fca7e3719 Roll back @livekit/track-processors to fix type error (again!)
While we wait for https://github.com/livekit/track-processors-js/pull/118 to be released
2026-02-25 18:03:04 +01:00
renovate[bot] 62b408a2b3 Update all non-major dependencies 2026-02-25 16:47:27 +00:00
fkwp 465d28a1cd bumping LiveKit SFU and synapse versions for ci/cd (#3757) 2026-02-25 17:46:35 +01:00
fkwp dcf3a722a7 Push docker images to oci.element.io (#3725)
* Push docker images to oci.element.io

* prettier
2026-02-25 17:45:56 +01:00
Robin 6995388a29 Convert media view model classes to interfaces
Timo and I agreed previously that we should ditch the class pattern for view models and instead have them be interfaces which are simply created by functions. They're more straightforward to write, mock, and instantiate this way.

The code for media view models and media items is pretty much the last remaining instance of the class pattern. Since I was about to introduce a new media view model for ringing, I wanted to get this refactor out of the way first rather than add to the technical debt.

This refactor also makes things a little easier for https://github.com/element-hq/element-call/pull/3747 by extracting volume controls into their own module.
2026-02-25 14:47:43 +01:00
Robin 4039272e75 Merge pull request #3745 from element-hq/robin/ringing
Tidy up media view models a little bit
2026-02-25 14:22:03 +01:00
Valere c8f5be7e4f remove deprecated analyticsID url param 2026-02-24 11:56:54 +01:00
Robin 4a0e89730d Merge pull request #3728 from element-hq/renovate/matrix-widget-api
Update dependency matrix-widget-api to v1.17.0
2026-02-18 19:43:32 +01:00
Robin bc238778ad Make the type of participant$ stricter
It is, in fact, required to be a behavior.
2026-02-18 14:01:55 +01:00
Robin 9d37125677 Only expose RTC backend identity debug info where we actually use it
We only ever inspect the RTC backend identity of user media tiles. So it only needs to be exposed on the user media view model.
2026-02-18 13:46:18 +01:00
Robin d87c3293c9 Make one-on-one layout media types stricter 2026-02-18 13:44:20 +01:00
renovate[bot] 789de1963a Update GitHub Actions (#3711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-17 16:01:46 +01:00
Timo ba95780813 Merge pull request #3734 from element-hq/robin/local-transport
Logically separate the advertised transport from the active transport
2026-02-16 15:21:28 +01:00
Robin 4508002947 Test local transport code in oldest member mode 2026-02-13 14:06:44 +01:00
Robin 2a56830426 Fix existing LocalTransport tests 2026-02-13 14:06:44 +01:00
Robin 6cf859fd9e Fix resource leak due to unsafe scope reference 2026-02-13 12:40:12 +01:00
renovate[bot] 91da088da4 Update dependency matrix-widget-api to v1.17.0 2026-02-12 12:15:03 +00:00
Valere Fedronic 076cc035d3 Merge pull request #3733 from element-hq/valere/bug_fix_stringify_crash
Fix: crash on mobile (android) with `0.17.0-rc.2` due to a log causing stringify to crash with `TypedError: circular structure`
2026-02-11 14:46:37 +01:00
Valere 92992df7df test: ensure ragelogger resist to JSON.stringify throws 2026-02-11 13:56:42 +01:00
Robin 13d131c2e9 Logically separate the advertised transport from the active transport
To correctly implement the legacy "oldest membership" mode, we need the code to be more nuanced about the local transport. Specifically, it needs to allow for the transport we advertise in our membership to be different from the transport that we connect to and publish media on. Otherwise, if these two are yoked together, members will resend their memberships whenever an SFU hop occurs, which an attacker could use to cause an amplified wave of state changes.
2026-02-11 13:47:15 +01:00
Valere Fedronic 8ea773aa24 Merge pull request #3731 from element-hq/valere/fix_netlify_deploy
fix: Netlify preview broken
2026-02-11 13:19:50 +01:00
Valere 0d24995c3e add defensive coding against JSON.stringify 2026-02-10 17:46:58 +01:00
Valere 1e9f2e6282 fix: Simplify log causing stringify TypeError on widget mode 2026-02-10 17:24:01 +01:00
Valere 73245e875d fix: Netlify preview broken 2026-02-10 15:11:43 +01:00
Timo a329ae0ad1 Merge pull request #3720 from element-hq/toger5/sdk-improvements-only
[MatrixRTC SDK] improvements - compatible with custom rtc application
2026-02-09 09:50:16 +01:00
Timo K 652ff0060c Back to develop branck (matrix-js-skd) 2026-02-09 09:07:54 +01:00
Robin d3476c0446 Merge pull request #3726 from element-hq/robin/generate-items-logs
Add debug logs to generateItems
2026-02-06 13:45:13 +01:00
Robin a0209eb433 Add debug logs to generateItems
It's always worth having logs for when state holders are created or destroyed (these are often the most interesting things happening in the application), so I thought it would be nice to have generateItems always log for you when it's doing that.
2026-02-06 13:26:02 +01:00
fkwp 7b1eb03e2a add ca certs to SFU containers such that webhooks are accepted 2026-02-06 11:54:39 +01:00
fkwp d3a4234f4a setup webhooks for SFUs 2026-02-06 11:54:22 +01:00
Timo K e1ef28fdcc use js-sdk fixing room hack for any app 2026-02-05 09:04:03 +01:00
Timo K 2e26193c4a update leave 2026-02-05 06:33:51 +01:00
Timo K 42efc05bd0 Add more granular leave/join api 2026-02-05 06:06:15 +01:00
Valere 809186a2e7 test: test requesting send message permission in initialize widget 2026-02-04 21:16:50 +01:00
Timo K 927e8e195c add experimental label 2026-02-04 20:16:31 +01:00
Timo K 33f6271d13 sdk improvements - compatible with custom rtc application
- add local member
 - add optional make sticky
 - default to video not enabled
 - allow sending matrix events
2026-02-04 20:06:26 +01:00
Timo 2c1476f151 Merge pull request #3715 from element-hq/revert-3701-toger5/sdk-improvements
Revert "[WIP] SDK target improvements"
2026-02-04 18:41:54 +01:00
Timo 97ee4630b0 Revert "[WIP] SDK target improvements" 2026-02-04 08:51:01 +01:00
Timo 02b29f98b6 Merge pull request #3701 from element-hq/toger5/sdk-improvements
[WIP] SDK target improvements
2026-02-04 08:47:28 +01:00
Valere fdc33a223f build against js-sdk rc 40.2.0-rc.0 2026-02-03 17:37:58 +01:00
Valere 7beafcac92 Merge branch 'livekit' into toger5/sdk-improvements 2026-02-03 16:32:36 +01:00
Valere Fedronic 5563f30bf2 Merge pull request #3705 from element-hq/toger5/fix-test-no-more-legacy-ring
[Matrix2.0 compatibility] stop advertising `livekit_alias`, use `"ROOM"` slot_id (backwards compat), stop sending deprecated notify
2026-02-03 16:26:52 +01:00
Valere 9d8ebf8ef3 fix import 2026-02-03 15:37:41 +01:00
Valere a0ad238952 fix: DidSendCallNotification is not emitting array anymore 2026-02-03 15:29:19 +01:00
Timo K 18b771e620 Allow sending room events in rtc sdk 2026-02-03 11:10:57 +01:00
Timo K 461a1f1b70 add to sending room messages 2026-01-31 12:29:56 +01:00
Timo K a066495c5f bump js-sdk fixup custom applications 2026-01-31 12:09:29 +01:00
Timo K 506b85770b Merge branch 'livekit' into toger5/sdk-improvements 2026-01-31 11:53:15 +01:00
Timo K bd8c4188d0 bump js-sdk 2026-01-29 17:24:21 +01:00
Timo K c78e8c54b8 js-sdk-bump 2026-01-29 17:22:56 +01:00
Valere Fedronic c18cc964a8 Merge pull request #3706 from element-hq/valere/fix_remove_livekit_alias_signaling
The advertised livekit_alias in membership is deprecated
2026-01-29 16:13:53 +01:00
Valere 8ee098eef1 review: quick comment 2026-01-29 15:46:41 +01:00
Valere a7bd2d3668 review: comment and better type 2026-01-29 14:58:54 +01:00
Valere ca7c8a2f11 Send livekit_alias in multi sfu with state 2026-01-28 16:42:07 +01:00
Valere 146375e320 Only remove livekit_alias in sticky events 2026-01-28 16:33:52 +01:00
Valere 992fb9093c fix test and use anonymised alias 2026-01-28 15:25:19 +01:00
Valere 99ccfcfbd4 fix linter 2026-01-28 15:18:29 +01:00
Valere 420304fd9d fix test mocking 2026-01-28 15:16:02 +01:00
Valere 81cb89e599 fix test mocking 2026-01-28 15:11:10 +01:00
Valere ee8b27837a fix lint issues 2026-01-28 14:38:23 +01:00
Valere a645bbe0ba fix bad import 2026-01-28 14:29:16 +01:00
Valere 4c7db0147e The advertised livekit_alias in membership is deprecated 2026-01-28 14:22:21 +01:00
Timo K c1b2346e22 Update tests based on new js-sdk changes
(no more legacy notify event)
2026-01-27 16:49:25 +01:00
Timo K 92a4150d6d more/better logging 2026-01-26 15:43:07 +01:00
Timo K 829619cca7 fix build:sdk:production 2026-01-26 12:44:25 +01:00
Timo K 408495b07a add back permissions to pr-deploy.yaml 2026-01-26 12:43:15 +01:00
Timo K 02f1a0da82 add local member and rtcBackendIdentity to sdk target 2026-01-26 12:43:01 +01:00
Timo K 6d8ade073a use sessionManager with custom slot instead of only session. 2026-01-25 19:27:07 +01:00
Timo K 1c946f7bb2 fix package full 2026-01-25 14:38:45 +01:00
Timo K 5724c3a09c add sdk:production 2026-01-25 14:37:37 +01:00
Timo K d55464f3ab build sdk 2026-01-25 14:32:30 +01:00
Timo K 73a5a10c6d add workflow to publish sdk version to netlify 2026-01-25 14:25:15 +01:00
Timo K 112420cb5b fix widget api appliaction capabilities 2026-01-25 14:24:52 +01:00
Timo K 31823dbd53 improve widget tests
(this we might want to cherry pick in its own PR)
2026-01-25 14:24:31 +01:00
Timo 15c39372f4 Merge pull request #3697 from element-hq/renovate/npm-lodash-es-vulnerability
Update dependency lodash-es to v4.17.23 [SECURITY]
2026-01-23 10:51:41 +01:00
Timo 330ad3448d Merge pull request #3686 from element-hq/robin/sticky-widget
Make Element Call widgets compatible with Matrix 2.0 mode
2026-01-22 20:17:16 +01:00
Timo K 220fc51eb5 add initializeWidget to tests. 2026-01-22 19:38:39 +01:00
Timo K b754106feb Add widget.ts tests 2026-01-22 19:23:08 +01:00
renovate[bot] 05107a3e5c Update dependency lodash-es to v4.17.23 [SECURITY] 2026-01-22 04:37:37 +00:00
Robin d516f0f602 Make Element Call widgets compatible with Matrix 2.0 mode
This gives Element Call widgets the ability to send and receive sticky RTC membership events.
2026-01-21 19:59:34 +01:00
Timo 3eb88ec4a8 Merge pull request #3693 from element-hq/toger5/fix-sticky-rejoin-error
Fix rejoin EC crash
2026-01-20 16:30:09 +01:00
Timo K 745772f672 Fix rejoin EC crash
Due to a duplcaited key (the key not being specific enough)
2026-01-20 13:45:07 +01:00
Valere Fedronic 486c0b884b Merge pull request #3690 from element-hq/valere/playwright/improve_sticky_test
playwright: intercept send request to ensure sticky events are sent
2026-01-20 08:26:47 +01:00
Valere 9f323d21a8 review: quick comment 2026-01-20 08:10:50 +01:00
Timo a72aae0b8d Merge pull request #3679 from element-hq/toger5/fix-unnecassary-error-logs
Fix some error log lines that lead to confusion
2026-01-19 17:57:34 +01:00
Timo b1ceeda9ee Merge pull request #3687 from toger5/toger5/fix-reemitted-event-params
Fix delayId delegation. Use correct event reemitting types.
2026-01-19 16:00:16 +01:00
Valere ed8cee9f58 review: fix/clean the route interception 2026-01-19 15:28:22 +01:00
Timo K 3a5b9dd519 remove overkill log 2026-01-19 14:58:45 +01:00
Valere a985281b46 playwright: intercept send request to ensure sticky event are sent 2026-01-19 13:58:36 +01:00
Timo K a7008d37c6 better log msg 2026-01-19 13:54:46 +01:00
Timo K 94bcb1bb27 remove leftover layout action code 2026-01-19 13:54:36 +01:00
Timo 36a1aa3c59 Merge pull request #3689 from toger5/toger5/remove-deprecated-layout-widget-actions
Remove deprecated widget layout actions
2026-01-19 13:20:04 +01:00
Valere Fedronic b4ca55f7df Merge pull request #3688 from element-hq/valere/bug_deny_permissions
Do not end call with error in case of MediaDeviceError
2026-01-19 12:32:01 +01:00
Timo K a102b3f4aa Fix some error log lines that lead to confusion.
In the past those log lines often were referenced for issues but they
are no real issues.
Either they are just deprecated code running or expected.
2026-01-19 12:20:37 +01:00
Timo K d8802aa079 linter 2026-01-19 12:18:13 +01:00
Timo K 4833d4b867 Bump js-sdk to use version that properly emits delayId updates 2026-01-19 12:15:40 +01:00
Timo K abb80e4e87 Fix event reemitting types
The callback args for reemitting will change to an array including the
originals emitter.
2026-01-19 12:15:15 +01:00
Timo K 2c3365a401 remove deprecated widget layout actions 2026-01-19 12:11:32 +01:00
Valere 2817362e15 Do not end call with error in case of MediaDeviceError 2026-01-19 11:46:17 +01:00
Timo 95b730e93f Merge pull request #3683 from element-hq/valere/playwright/spa_sticky_test
playwright: Test call in SPA mode with matrix 2.0
2026-01-19 09:34:49 +01:00
Valere c2eea67b35 Merge branch 'livekit' into valere/playwright/spa_sticky_test 2026-01-16 17:41:39 +01:00
Valere 202e06a16d skip FF 2026-01-16 17:41:32 +01:00
Timo e278752942 Merge pull request #3675 from element-hq/toger5/fixing-duble-publishing
Fix Publisher cleanup procedure
2026-01-16 17:37:46 +01:00
Valere 89c878cf3f playwright: Test call in SPA mode with matrix 2.0 2026-01-16 17:11:45 +01:00
Timo K f41175444b revert changes unrelated to this PR 2026-01-16 16:23:05 +01:00
Timo K 102664482b Activate the hotswap test that was failing before. 2026-01-16 15:41:25 +01:00
Timo K d5df9e65dd Merge branch 'livekit' into toger5/fixing-duble-publishing 2026-01-16 15:38:56 +01:00
Timo f7255b3697 Merge pull request #3681 from element-hq/toger5/playwright-publisher-swap
Add playwright test for hotswatpping the transport (swap from `oldest_member` (singeSFU) to `multi_sfu`)
2026-01-16 15:34:15 +01:00
Timo K 3f8b3ba3f1 add test to check if publisher is properly destroyed 2026-01-16 14:41:11 +01:00
Timo K 22c1948a82 Add playwright test for hotswatpping transport 2026-01-16 14:27:52 +01:00
Timo K a99a413b88 temp 2026-01-16 14:07:56 +01:00
Timo K 83df152608 review 2026-01-16 13:20:03 +01:00
Timo K c376d9e5c1 fix tests 2026-01-16 13:12:31 +01:00
Timo K f09e2c8b55 Merge branch 'livekit' into toger5/dont-trap-in-invalid-config 2026-01-16 13:11:06 +01:00
Valere Fedronic 5c366320cb Merge pull request #3676 from element-hq/valere/playwright/compat_bug_reproduce
playwright: Federated call between legacy and compat
2026-01-16 13:09:02 +01:00
Valere 16b08994cc Try fixup mixed conten error loading widget 2026-01-16 12:53:10 +01:00
Timo K f5c31626a6 fix unit tests 2026-01-16 12:43:13 +01:00
Timo K 5a48820927 remove widget layout widget action for good. 2026-01-16 10:22:23 +01:00
Timo K 971d16d243 revert jwt to stable version 2026-01-16 10:21:26 +01:00
Timo K 9b40d7420a refactor to use destroy method 2026-01-15 19:04:32 +01:00
Timo K f71e483080 logging updates 2026-01-15 18:13:34 +01:00
Timo K f7590a33d7 Fix publisher clean up! This is the acutal bug we chased 2026-01-15 18:12:00 +01:00
Timo K c74accb906 remove "fetching" state again (we have to be able to deal with those
kind of switches!) Optimize to not always fetch the oldest member jwt
(only do so in legacy mode)
2026-01-15 18:11:08 +01:00
Valere a00c6501c2 fix discarding pop ups 2026-01-15 15:22:04 +01:00
Valere 9e933b74ca cleanup notifications toast on start 2026-01-15 14:31:33 +01:00
Valere d25d6d3196 Test all pairs of rtc mode in federated calls 2026-01-15 12:06:41 +01:00
Valere 243f369a24 re-use test helper in other files 2026-01-15 11:50:37 +01:00
Valere 0d1488af4c playwright: Federated call between legacy and compat 2026-01-14 18:07:12 +01:00
Timo K b49411abfa dont set localTransport while still fetching oldest member transport 2026-01-14 17:35:35 +01:00
Timo 27e351270c Merge pull request #3669 from element-hq/toger5/livekit-alias-simple-roomid
Change the livekit alias to just be the room id (for backwards compatibility)
2026-01-14 12:43:08 +01:00
Timo K 41eb45b3c4 fix comments 2026-01-14 12:29:22 +01:00
Valere Fedronic f5a6a05570 Merge pull request #3671 from element-hq/valere/playwright/huddle_test
playwright: End to end test for huddle calls in widget mode
2026-01-14 12:27:57 +01:00
Timo 31cc12eda4 Merge pull request #3670 from element-hq/toger5/livekitAlias-debugging-info
Add livekitAlias debugging info
2026-01-14 12:26:50 +01:00
Robin 39c24eb0f5 Merge pull request #3665 from element-hq/renovate/livekit-components
Update dependency @livekit/components-react to v2.9.17
2026-01-14 12:15:48 +01:00
Valere 7338a55e76 review: improve doc 2026-01-14 12:15:00 +01:00
Valere 68f04d46a9 playwright: End to end test for huddle calls in widget mode 2026-01-13 19:11:12 +01:00
Timo K dbdcde2489 fix lint 2026-01-13 18:17:37 +01:00
Timo K 636f737cd3 reduce diff 2026-01-13 18:05:05 +01:00
Timo K 93c9225e8a Merge branch 'livekit' into toger5/dont-trap-in-invalid-config 2026-01-13 18:01:30 +01:00
Valere Fedronic 16ad89df47 Merge pull request #3667 from element-hq/valere/playwright/discard_call_widget_test
playwright: Test that declining a call in DM works as expected
2026-01-13 18:00:36 +01:00
Timo 3ce0afcacc Merge pull request #3664 from element-hq/toger5/userMedia-alternative
Small refactor: User media alternative
2026-01-13 17:51:36 +01:00
Timo K 4d35b77077 bump jwt docker 2026-01-13 17:41:46 +01:00
Timo K 20e63c8dc7 fix tests 2026-01-13 17:39:55 +01:00
Timo K ff8d71380d Add livekitAlias debugging info 2026-01-13 15:14:34 +01:00
Timo K d185b52091 more docstrings to docuemnt the migration away from livekit_alias 2026-01-13 12:44:17 +01:00
Timo K 72ca3821ab Change the livekit alias to just be the room id for backwards
compatibility.
2026-01-13 12:37:46 +01:00
Valere Fedronic 4b7dc8a290 Merge pull request #3659 from element-hq/valere/initial_mute_states
Fix: Ensure voice and audio intent are respected
2026-01-13 11:50:32 +01:00
Gordnhoandfkwp f391c68055 Add Haproxy configuration for element call (#3661)
* Add Haproxy configuration for livekit SFU

---------

Co-authored-by: fkwp <fkwp@users.noreply.github.com>
2026-01-13 10:39:15 +00:00
Valere e82a048088 playwright: Test that declining a call in DM works as expected 2026-01-13 09:46:44 +01:00
Valere 7a8c2d6ca9 Merge branch 'livekit' into valere/initial_mute_states 2026-01-12 19:13:40 +01:00
Valere f3df8bc709 review: Use is_widget directly instead of using the packageType 2026-01-12 17:28:18 +01:00
Valere 534f934378 review: just inline intent and skipLobby from urlParam 2026-01-12 16:37:28 +01:00
Valere 56beb59346 review: Update copyright properly 2026-01-12 15:35:21 +01:00
Valere fbdcacb344 review: remove dead comment 2026-01-12 15:23:02 +01:00
Timo K 89e5e5b10a fix uuid 2026-01-12 12:34:50 +01:00
Timo K 8d8eb09922 Merge branch 'livekit' into toger5/userMedia-alternative 2026-01-12 12:34:03 +01:00
renovate[bot] fbdcde3058 Update dependency @livekit/components-react to v2.9.17 2026-01-12 01:33:44 +00:00
Timo f444c9bc11 Merge pull request #3638 from element-hq/toger5/delayed-event-delegation
Pseudonomous identity and use the new jwt service endpoint (with delayed event delegation)
2026-01-09 19:58:30 +01:00
Timo K 47e389678b add uuid in our own package.json 2026-01-09 19:48:11 +01:00
Timo K 7a8f5cc859 use crypto.randomUUID() 2026-01-09 19:40:21 +01:00
Timo K 45bb233673 Merge branch 'toger5/delayed-event-delegation' into toger5/userMedia-alternative 2026-01-09 19:38:21 +01:00
Timo K 341277932c fix tests 2026-01-09 19:34:41 +01:00
Timo K 735c17d3e6 fix tile flicker on video mute/unmute
(only pass rtcBackendIdenitity instead of full rtcMember)
2026-01-09 19:31:40 +01:00
Timo K 1a9e4a1a5c bump js-sdk 2026-01-09 19:12:54 +01:00
Timo K 7387a00406 lint 2026-01-09 19:04:42 +01:00
Timo K 32694fddf6 improve rtcBackendIdentity debugging 2026-01-09 19:04:02 +01:00
Timo K 444c50d8c4 Change code style of user media 2026-01-09 18:27:56 +01:00
Timo K 9a88e3dab6 review valere (more readable force new endpoint logic) 2026-01-09 18:05:26 +01:00
Timo K 39432310e3 use actual uuid for member.id
review with some renaming and removal of unnecassary if
2026-01-09 17:56:30 +01:00
Timo 0addc7c09b Merge pull request #3662 from element-hq/toger5/simplify-sdk-example
Update sdk example
2026-01-09 17:34:57 +01:00
TimoandRobin 0b766472ed Update sdk/README.md
Co-authored-by: Robin <robin@robin.town>
2026-01-09 17:30:02 +01:00
Timo K ed3d168ac3 fix tests 2026-01-09 17:29:48 +01:00
Timo K 70b7ebff80 prettier 2026-01-09 16:32:14 +01:00
Timo K b7838e4353 Update README.md 2026-01-09 16:25:06 +01:00
Timo K 0eb0169ad9 update example 2026-01-09 16:01:03 +01:00
Timo K c2e3774749 prettier 2026-01-09 15:40:39 +01:00
Valere cf579638fd skip firefox 2026-01-09 15:39:53 +01:00
Timo K c7c6dc18bf fix js-sdk dependency 2026-01-09 15:28:11 +01:00
Valere 8827ff2ea6 add option for firefox webRTC test to allow fake streams 2026-01-09 15:18:35 +01:00
Valere 8535494671 use config to unmute full package on localhost 2026-01-09 15:00:57 +01:00
Valere ad66d10c69 run playwright in dev mode 2026-01-09 14:41:07 +01:00
Valere e9ed9580db trust localhost for CI and devbuil 2026-01-09 14:18:14 +01:00
Timo K 7dbbd763b9 Refactor how we aquire the jwt token for the local user. (only fetch it
once)

The local jwt token needs to be aquired via the right endpoint. The
endpoint defines how our rtcBackendIdentity is computed. Based on us
using sticky events or state events we also need to use the right
endpoint. This cannot be done generically in the connection manager. The
jwt token now is computed in the localTransport and the resolved sfu
config is passed to the connection manager.

Add JWT endpoint version and SFU config support Pin matrix-js-sdk to a
specific commit and update dev auth image tag. Propagate SFU config and
JWT endpoint choice through local transport, ConnectionManager and
Connection; add JwtEndpointVersion enum and LocalTransportWithSFUConfig
type. Add NO_MATRIX_2 auth error and locale string, thread
rtcBackendIdentity through UI props, and include related test, CSS and
minor imports updates
2026-01-09 13:38:26 +01:00
Valere 0636678ad2 quick log for playwright problem 2026-01-09 13:25:16 +01:00
Robin a567505ef5 Merge pull request #3478 from element-hq/renovate/compound
Update Compound
2026-01-09 13:12:48 +01:00
Robin f89a7a8211 Fix tests 2026-01-09 12:58:06 +01:00
Valere Fedronic 29854a77b4 Merge pull request #3660 from element-hq/valere/add_codecov_shield
Add codecov shields.io badge
2026-01-09 12:57:56 +01:00
Valere bf19b388ea Add codecov shields.io badge 2026-01-09 12:43:33 +01:00
Valere d2907f51d3 prettier format 2026-01-09 12:35:25 +01:00
Valere 231a80d9de update snapshot, mute buttons have aria-label now 2026-01-09 12:32:36 +01:00
Valere a9153f2781 fix: Regression on default mutestate for voicecall + end-2-end tests 2026-01-09 12:03:56 +01:00
Valere f5f8bb549a delete outdated default mute state config 2026-01-09 12:03:45 +01:00
renovate[bot] 8fe49d681a Update Compound 2026-01-08 19:49:47 +00:00
Timo K d4b06b0f9c fix connection recreation which breaks EC lk connection 2026-01-08 14:27:47 +01:00
Will Hunt 0439fdefef Remove duplicate IntentAndPlatformDerivedConfiguration interface (#3658) 2026-01-08 11:51:28 +00:00
Timo K 1909aef186 temp 2026-01-08 12:27:17 +01:00
Timo K 385f63e83e fix tests 2026-01-07 17:46:39 +01:00
Timo K a5a4bb2b82 add retries inside the getLiveKitJWTWithDelayDelegation and
`getLiveKitJWT` functions.
2026-01-07 17:38:29 +01:00
Timo K 5556d363b9 add retries and be more specific when we fall back to legacy endpoint 2026-01-07 17:21:14 +01:00
Timo K 0eeed4e18e fix test snapshot 2026-01-07 17:05:00 +01:00
Timo K d5ad2e38e2 fix up tests 2026-01-07 16:09:08 +01:00
Timo K 75fca3108a cleanup an rename compatibility mode 2026-01-07 16:08:20 +01:00
Timo K d814f60f23 review (docstrings) and remove unused artifacts. 2026-01-07 15:47:44 +01:00
Timo K dd562bdaf5 dont use throw for logic. 2026-01-07 15:36:32 +01:00
Timo K d48042f522 fix lint 2026-01-07 15:18:37 +01:00
Timo K 6480df44e9 add tests for open id delay fallback 2026-01-07 15:10:32 +01:00
Timo K 83d04ac122 fix tests and remove duplicated mocks. 2026-01-07 13:26:37 +01:00
Timo K 556a87d141 fix js-doc 2026-01-05 22:20:19 +01:00
Timo K 69a4189517 self review 2026-01-05 22:00:02 +01:00
Timo 009c9e046c Merge branch 'livekit' into toger5/delayed-event-delegation 2026-01-05 21:26:15 +01:00
Timo K 1580087286 use latest js-sdk 2026-01-05 21:24:52 +01:00
Timo K 00fca6e3c7 simplify localTransport 2026-01-05 21:17:37 +01:00
Timo K 5d5d75ebdf fixup merge 2026-01-05 21:08:33 +01:00
Timo K df2bd22005 Merge branch 'livekit' into toger5/delayed-event-delegation 2026-01-05 21:08:21 +01:00
Robin de8fdcfa69 Merge pull request #3518 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2026-01-05 19:42:07 +01:00
Robin 6aaf2db626 Fix formatting 2026-01-05 19:35:09 +01:00
Robin 72b9b8231a Merge branch 'livekit' into renovate/all-minor-patch 2026-01-05 19:29:24 +01:00
Robin 7817b76a8b Downgrade react-i18next to fix type errors
Upgrade beyond 16.1.1 blocked by https://github.com/i18next/react-i18next/issues/1899
2026-01-05 19:28:07 +01:00
Robin b585af41da Fix encryption keys type error
See commit 174439c2f0c09cf9926c28435ba4db1345df4aee in matrix-js-sdk for the other part of the fix.
2026-01-05 19:27:39 +01:00
Robin 1006d06b04 Fix WebCodecs type error 2026-01-05 17:46:04 +01:00
Robin b9afaab556 Upgrade i18next to resolve a type error 2026-01-05 15:52:17 +01:00
Robin a6cdb28e45 Roll back @livekit/track-processors to fix type error
While we await https://github.com/livekit/track-processors-js/pull/118 to be released
2026-01-05 15:36:43 +01:00
Timo ce682232b8 Merge pull request #3586 from element-hq/toger5/otel-remove-experiment
Remove all `OpenTelementry` related code
2026-01-05 14:55:28 +01:00
Timo K 582d1d8495 Merge branch 'livekit' into toger5/dont-trap-in-invalid-config 2026-01-05 14:37:48 +01:00
Timo K 029c38be63 fix prettier 2026-01-05 14:30:55 +01:00
Timo K 5b1eb13d65 fix lints and add hint in the otel readme to the PR removing it. 2026-01-05 14:27:54 +01:00
Timo d1aabb05ff Merge branch 'livekit' into toger5/otel-remove-experiment 2026-01-05 14:22:11 +01:00
Timo K eb60473510 add tests 2026-01-05 14:20:16 +01:00
Valere Fedronic 49cd980ddf Merge pull request #3644 from element-hq/valere/devx_check_doc
Add script to check that the tsdoc is correct and up-to-date
2026-01-05 14:08:08 +01:00
Robin b6ca0c4cd6 Fix tests 2026-01-05 13:55:58 +01:00
Robin 5fa170c9c9 Fix builds 2026-01-05 13:54:08 +01:00
Will Hunt f260a20728 Set latest tag when publishing a docker release. (#3650)
Fixes https://github.com/element-hq/element-call/issues/3647
2026-01-05 12:41:26 +00:00
Robin 749ba103a7 Merge pull request #3641 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.16.1
2026-01-05 13:28:17 +01:00
Timo K c35b960627 fix lints 2026-01-05 10:42:08 +01:00
Timo fef4db69d8 Merge pull request #3628 from element-hq/renovate/livekit-components
Update LiveKit components
2026-01-05 10:37:18 +01:00
renovate[bot] 057bc4e2ad Update all non-major dependencies 2026-01-03 18:06:04 +00:00
renovate[bot] a6aa4526cf Update LiveKit components 2025-12-31 13:52:19 +00:00
renovate[bot] 88cfd32e51 Update dependency livekit-client to v2.16.1 2025-12-31 13:52:04 +00:00
Valere 5e715765d9 fix: un-needed tsdoc script 2025-12-30 18:17:07 +01:00
Valere da55d84bde Add script to check that the tsdoc is correct and up-to-date 2025-12-30 17:02:44 +01:00
Will Hunt 72ec1439f4 Support MSC4143 RTC Transport endpoint (#3629)
* Use rtc-focus branch of js-sdk

* Update makeTransport to fetch backend transports and validate all transports before response.

* Fix test

* Add test

* Loads more tests

* Add tests for openid errors

* improve comment

* update to develop commit

* Add JWT parsing

* Use JWT

* Cleanup

* fixup tests

* fixup tests

* lint

* lint lint

* Fix `Reconnecting`
2025-12-29 17:45:41 +00:00
Timo K 0f5c5d8be5 cleanup based on new js-sdk impl 2025-12-29 17:38:54 +01:00
Timo K 7591e2bda1 Merge branch 'livekit' into toger5/delayed-event-delegation 2025-12-28 21:04:49 +01:00
Timo K 3ba2d13e27 use the js-sdk where the hashed rtcSessionIdeintity is already part of
the event (no need to compute it in the encryption manager)
2025-12-28 21:04:46 +01:00
Timo 67d20a8f3d Merge pull request #3600 from element-hq/toger5/lib-ec-version
Element Call SDK target
2025-12-23 12:53:57 +01:00
Timo K 9bd7888fab copyright. 2025-12-23 12:48:54 +01:00
Timo K 150dda16c8 fix lint 2025-12-22 13:44:24 +01:00
Timo K 725ff31d6f reduce PR diff 2025-12-22 13:42:16 +01:00
Timo K 852d2ee375 after merge cleanup 2025-12-22 13:35:40 +01:00
Timo K e78f37a6b3 Merge branch 'livekit' into toger5/lib-ec-version 2025-12-22 12:43:09 +01:00
Timo K 55d18f10fe temp refactored membership rtcidentity 2025-12-19 19:23:41 +01:00
Timo K 50f3bf00ae use correct js-sdk 2025-12-17 10:22:46 +01:00
Timo K ab7e3486b3 Make use of the new jwt service endpoint (with delayed event delegation)
This also does all the compatibility work. When to use which endpoint to
authenticate agains a jwt service.
2025-12-17 09:53:49 +01:00
Valere Fedronic 6cfa95bcfa Merge pull request #3632 from element-hq/valere/double_pub_problems_highlevel
Fix: Races that could cause double publication or mute state desyncs
2025-12-17 08:50:00 +01:00
Valere 80e760ca55 review 2025-12-16 13:40:06 +01:00
Timo K 9bd51fdfc4 Merge branch 'livekit' into toger5/pseudonomous-identities 2025-12-16 12:18:00 +01:00
Timo a061b9f91e Merge pull request #3637 from robintown/flat-layout-switch
Allow user to switch layouts while phone is in landscape
2025-12-16 11:53:25 +01:00
Timo 26f41c434e Merge pull request #3626 from robintown/non-publishing-participants
Don't show 'waiting for media' on connected participants
2025-12-16 11:53:06 +01:00
fkwp ff3d6bd088 enable sticky events 2025-12-16 11:22:25 +01:00
fkwp 6fe6daba31 switch synapse docker image to one with sticky event support 2025-12-16 11:20:38 +01:00
Robin ed585e1d34 Merge pull request #3624 from robintown/local-remote-confusion
Dispel confusion about whether media is remote or local
2025-12-15 16:43:57 -05:00
Robin 6149dd2c9a Make the video behavior less confusing
There's no reason to allow it to take on placeholder values. It should be defined when the media has a published video track and undefined when not.
2025-12-15 15:26:42 -05:00
Robin ea6f934667 Don't show user as 'waiting for media' if they don't intend to publish
We don't expect them to be publishing on any transport; they might be a subscribe-only bot.
2025-12-15 15:26:42 -05:00
Robin 93ab3ba1ff Compute the 'waiting for media' state less implicitly
On second glance, the way that we determined a media tile to be 'waiting for media' was too implicit for my taste. It would appear on a surface reading to depend on whether a participant was currently publishing any video. But in reality, the 'video' object was always defined as long as a LiveKit participant existed, so in reality it depended on just the participant. We should show this relationship more explicitly by moving the computation into the view model, where it can depend on the participant directly.
2025-12-15 15:26:42 -05:00
Robin 2c54263b2f Don't show 'waiting for media' on connected participants
We would show 'waiting for media' on participants that were connected but had no published tracks, because we were filtering them out of the remote participants list on connections. I believe this was done in an attempt to limit our view to only the participants that have a matching MatrixRTC membership. But that's fully redundant to the "Matrix-LiveKit members" module, which actually has the right information to do this (the MatrixRTC memberships).
2025-12-15 15:26:42 -05:00
Robin 92bcc52e87 Remove unused method
The doc comment here was about to become stale, so let's just remove it.
2025-12-15 15:25:00 -05:00
Timo 3d8d0ae9dd Merge branch 'livekit' into toger5/pseudonomous-identities 2025-12-15 21:20:55 +01:00
Robin 87fbbb9a3f Make MatrixRTC mode a required input to CallViewModel 2025-12-15 15:16:47 -05:00
Robin c7e9f1ce14 Explicitly pass the MatrixRTC mode to CallViewModel 2025-12-15 15:09:46 -05:00
Robin 53cc79f738 Allow user to switch layouts while phone is in landscape
This fixes a regression on the development branch: the layout switcher would not respond to input while the window mode is 'flat' (i.e. while a mobile phone is in landscape orientation). See https://github.com/element-hq/element-call/pull/3605#discussion_r2586226422 for more context.

I was having a little trouble interpreting the emergent behavior of the layout switching code, so I refactored it in the process into a form that I think is a more direct description of the behavior we want (while not making it as terse as my original implementation).
2025-12-15 14:54:51 -05:00
Robin 15a12b2d9c Make layout tests more concise 2025-12-15 14:22:20 -05:00
Timo K 5bc6ed5885 small refactor to make it testable. 2025-12-15 20:17:57 +01:00
Robin e3b4ffb801 Merge branch 'livekit' into local-remote-confusion 2025-12-15 13:17:13 -05:00
Robin 8a18e70e20 Split MatrixLivekitMembers more verbosely into two types 2025-12-15 13:14:45 -05:00
Robin 00d4b8e985 Use a more suitable filter operator to compute local member 2025-12-15 12:52:23 -05:00
Timo K 909d980dff still with broken tests... 2025-12-15 18:23:30 +01:00
Valere 190cdfcb60 comment now dead state variant 2025-12-12 17:03:16 +01:00
Valere 8f2055b4f4 eslint fix 2025-12-12 14:46:13 +01:00
Valere 93da69983d post merge: partial mapping of tracks/publish states 2025-12-12 14:40:45 +01:00
Valere b3b76d8b3d post merge 2025-12-12 11:54:43 +01:00
Valere d052d55547 Merge branch 'livekit' into valere/double_pub_problems_highlevel 2025-12-12 11:54:35 +01:00
Valere 610af439a8 cleaning: just use LocalTrackPublished event to pause/unpause 2025-12-12 10:37:37 +01:00
Valere f8310b4611 publisher: only use highlevel participant APIs 2025-12-12 10:31:08 +01:00
Timo cf453baf5d Merge pull request #3611 from element-hq/toger5/connection-state-refactor
Unify LiveKit and Matrix connection states
2025-12-11 18:23:34 +01:00
Timo K df2f503a05 review 2025-12-11 18:00:23 +01:00
Timo K 7edc97b917 remove continue button things 2025-12-11 17:24:35 +01:00
Timo K 8225e4f260 remove page.pause 2025-12-11 17:22:02 +01:00
Timo K 207b161b3b fix logger and dismiss button presses 2025-12-11 17:17:56 +01:00
Timo K 9a7e797af4 fix lint 2025-12-11 16:17:45 +01:00
Timo K 08306d663a remove duplicated connecting state and update Test setup 2025-12-11 16:04:12 +01:00
Timo K c1c73b0f02 lint 2025-12-11 15:04:07 +01:00
Timo K 68a32fdff6 Merge branch 'livekit' into toger5/lib-ec-version 2025-12-11 13:17:26 +01:00
Timo K 328cc7133a update playwright so that we do not even need the dismiss anymore. 2025-12-11 11:32:28 +01:00
Timo K 170a38c0ba fix playwright incompatible browser toast 2025-12-11 11:30:14 +01:00
Robin 6c622fc6e7 Merge branch 'livekit' into local-remote-confusion 2025-12-10 17:21:54 -05:00
Timo K aabd76044b fix lint 2025-12-10 21:25:35 +01:00
Timo K e626698fda fix connection tests 2025-12-10 21:22:55 +01:00
Timo K 8dac0366b6 fix lints 2025-12-10 21:17:33 +01:00
Timo K b380532d30 lots of error logging and fixing playwright 2025-12-10 21:14:13 +01:00
Timo K 667a3d0e3d fix test not checking for livekit connection state anymore. 2025-12-10 19:18:16 +01:00
Timo K 1941fc9ca1 fix tests. 2025-12-10 19:12:52 +01:00
Timo K 6efce232f8 fix playwright tests 2025-12-10 18:50:19 +01:00
Timo K ef2f53c38a Merge branch 'livekit' into toger5/connection-state-refactor 2025-12-10 13:49:06 +01:00
Timo K 0ebc6078dd Update LocalMember.ts 2025-12-10 12:08:59 +01:00
Timo K 7af89b4216 fix lint 2025-12-09 17:36:56 +01:00
Robin ee2b0c6a5d Merge pull request #3625 from robintown/misc
Miscellaneous clean-up
2025-12-09 10:01:11 -05:00
Timo K bf801364a6 cleanup and tests 2025-12-09 15:23:30 +01:00
Robin 6ee3ef2795 Edit a misleading log line
The factory function is called once per item to construct the item. It is not called on future updates to the item's data.
2025-12-08 23:38:54 -05:00
Robin 2f3f9f95eb Use more compact optional chaining and coalescing notation 2025-12-08 23:38:15 -05:00
Robin 9481dc401c Remove extraneous 'scope running' check
Semantically, behaviors are only meaningful for as long as their scope is running. Setting a behavior's value to an empty array once its scope ends is not guaranteed to work (as it depends on execution order of how the scope is ended), and subscribers should be robust enough to handle clean-up of all connections at the end of the scope either way.
2025-12-08 23:34:42 -05:00
Robin d8b9568400 Stop publisher in a less brittle way 2025-12-08 23:33:41 -05:00
Robin a7a3d4e93c Remove unsound participant casts
By tagging participant behaviors with a type (local vs. remote) we can now tell what kind of participant it will be in a completely type-safe manner.
2025-12-08 23:06:19 -05:00
Robin 47cd343d44 Prove that the remote members modules only output remote members
They had loose types that were allowing them also output local members. They don't do this, it's just misleading.
2025-12-08 23:01:44 -05:00
Robin cc8e250d96 Remove a brittle cast from local member code 2025-12-08 22:54:46 -05:00
Robin 5a9a62039c Test CallViewModel in all MatrixRTC modes 2025-12-08 22:42:57 -05:00
Robin 2986f90a5f Allow MatrixRTC mode to be configured in tests 2025-12-08 22:29:15 -05:00
Timo K e4fee457cf allow to use custom applications 2025-12-08 09:41:01 +01:00
Timo K 7c40b0e177 ideas 2025-12-05 19:48:02 +01:00
Valere Fedronic e4404e5bb1 Merge pull request #3608 from robintown/initial-layout
Fix the wrong layout being used until window size changes
2025-12-04 16:44:50 +01:00
Valere Fedronic f5d4017981 Merge pull request #3606 from element-hq/valere/fix_transiant_earpiece_overlay
fix: The handset mode overlay is visible a split second for every call
2025-12-04 11:05:26 +01:00
Valere 71bf55f358 also test that video is muted when earpiece overlay is on 2025-12-04 10:37:14 +01:00
Valere 7a2c1af44b review: use simple transition instead of keyframe 2025-12-04 10:36:57 +01:00
Valere 940c787040 review: quick renaming 2025-12-04 10:06:45 +01:00
Valere 5d55f83e90 Merge branch 'livekit' into valere/fix_transiant_earpiece_overlay 2025-12-04 10:05:06 +01:00
Valere Fedronic 9e3e359445 Merge pull request #3605 from element-hq/valere/layout_switch
Fix: Allow to manually switch back to grid mode when there is a screenshare
2025-12-04 09:50:56 +01:00
Valere be7407ea3d review: quick renaming 2025-12-04 09:37:07 +01:00
Valere Fedronic 0a3483729f Merge pull request #3615 from element-hq/valere/fix_lk_server_1.9.4
keep livekit 1.9.4 as the latest is breaking the dev backend
2025-12-04 09:28:36 +01:00
Robin f599e22e94 Merge pull request #3614 from robintown/simplify-analytics-id
Simplify computation of analytics ID
2025-12-03 13:59:01 -05:00
Valere fdc66a1d62 fix: existing screenshare switching twice 2025-12-03 18:36:51 +01:00
Valere c7491c3e97 move fixture to correct folder 2025-12-03 17:25:32 +01:00
Valere af08c1830e keep livekit 1.9.4 as the latest is breaking the dev backend 2025-12-03 17:18:35 +01:00
Valere bcb2b36888 keep livekit 1.9.4 as the latest is breaking the dev backend 2025-12-03 17:17:58 +01:00
Valere Fedronic b9e346d64c Merge pull request #3596 from element-hq/valere/bugfix_earpiece_mute_video
Fix: Camera is not muted when the earpiece mode is enabled
2025-12-03 17:12:10 +01:00
Valere 0ed7194d87 fix: earpiece overlay not showing + playwright test! 2025-12-03 17:10:57 +01:00
Robin bbd92f666b Simplify computation of analytics ID
Since we now bundle a trusted Element Call widget with our messenger applications and this widget reports analytics to an endpoint determined by the messenger app, there is no longer any reason to compute a different analytics ID from the one used by the messenger app.
2025-12-03 10:42:04 -05:00
Timo K b34a75d990 fix knip 2025-12-03 13:08:51 +01:00
Timo K 8110d22c8b fix lint 2025-12-03 10:27:30 +01:00
Timo K 88721be952 cleanup 2025-12-03 10:04:22 +01:00
Valere 6e7bedbaec Merge branch 'livekit' into valere/layout_switch 2025-12-03 09:17:31 +01:00
Valere a93ceeae4b review: Keep previous behavior for now to always auto switch 2025-12-03 09:01:26 +01:00
Valere b85f36598c fix: mistake in file name 2025-12-03 08:54:52 +01:00
Timo K 2e646bfac1 Unify LiveKit and Matrix connection states 2025-12-02 19:49:13 +01:00
Valere Fedronic e0bf51b63b Merge pull request #3590 from element-hq/valere/noise_cancellation
Config: UrlParams to control noiseSuppression and echoCancellation
2025-12-02 18:36:32 +01:00
Valere f6a3a371cb fix lint 2025-12-02 17:52:27 +01:00
Valere ac9acc0158 review: refactor convert params to object for generateRoomOption 2025-12-02 17:47:00 +01:00
Valere 91f3b8b114 Merge branch 'livekit' into valere/noise_cancellation 2025-12-02 17:44:06 +01:00
Valere be0c7eb365 review: fix mock import module 2025-12-02 17:43:58 +01:00
Valere 44980a2744 review: rename deviceConnected to canControlDevices 2025-12-02 16:39:26 +01:00
Robin 83ea154e1a Fix the wrong layout being used until window size changes
While looking into what had regressed https://github.com/element-hq/element-call/issues/3588, I found that 28047217b8 had filled in a couple of behaviors with non-reactive default values, the "natural window mode" behavior being among them. This meant that the app would no longer determine the correct window mode upon joining a call, instead always guessing "normal" as the value. This change restores its reactivity.
2025-12-02 10:36:53 -05:00
Valere 0e04fd9433 fix: The handset mode overlay is visible a split second for every call 2025-12-02 14:14:28 +01:00
Timo K 93de12d79c cleanup vite.configs and simplify exported sdk props. 2025-12-02 11:31:56 +01:00
Valere b5d3f3c72a fix: Allow switching back to grid when there is a screenshare 2025-12-02 11:18:50 +01:00
Valere 60bc6f1e93 refactor: Extract layout mode switch + test 2025-12-02 11:00:32 +01:00
Timo K f76a6cb599 cleanup unnecassary packages + add connected indicator 2025-12-01 20:39:40 +01:00
Timo K ab675cf00b fix test caused by remoteParticipantsWithTracks->remoteParticipants 2025-12-01 20:26:54 +01:00
Timo K 43266e6200 Merge branch 'livekit' into toger5/lib-ec-version 2025-12-01 20:15:58 +01:00
Timo K af47002613 Refactor local membership publisher and connectionState related logic 2025-12-01 20:14:29 +01:00
Timo K c20b206ab2 i18n 2025-12-01 19:53:27 +01:00
Timo K 5ceb140d13 remove check in local transport 2025-12-01 19:51:48 +01:00
Timo K ed4517703f better UX (valiate on save) 2025-12-01 19:40:44 +01:00
Timo K bd3e91738e Reset overwrite url if it is invalid (does fail to reach sfu) 2025-12-01 19:40:44 +01:00
Timo f05d4b158e Merge pull request #3565 from element-hq/renovate/matrix-widget-api
Update dependency matrix-widget-api to v1.15.0
2025-12-01 19:14:52 +01:00
Robin 0240087afe Unpin matrix-js-sdk so it can be upgraded 2025-12-01 13:09:10 -05:00
Timo K 4ec1b19fe2 fix js-sdk tests 2025-12-01 18:54:57 +01:00
Timo K 5f6a45f0e9 also bump js-sdk 2025-12-01 18:45:47 +01:00
renovate[bot] e2916d9093 Update dependency matrix-widget-api to v1.14.0 2025-12-01 18:23:35 +01:00
Timo 90d4b6a6ce Merge pull request #3598 from element-hq/renovate/github-actions
Update GitHub Actions
2025-12-01 17:42:05 +01:00
Timo e3eb2ea12b Merge pull request #3599 from element-hq/renovate/embedded-package-dependencies
Update embedded package dependencies
2025-12-01 17:40:29 +01:00
Timo 4f45825cf2 Merge pull request #3591 from element-hq/toger5/fix-local-transport-update
Fix reactivity based on localTransport updates (Cleanup for LocalMembership.ts)
2025-12-01 17:39:55 +01:00
Timo K 8cb8357398 make logs just debug. (info -> debug) 2025-12-01 17:34:37 +01:00
Timo K 63cd4f79dd fix playwright test! (It caught an actual bug!!! so the right wording
would be: fix implementation thanks to the playwright test!
2025-12-01 17:29:35 +01:00
Valere Fedronic 7fd4424e7b Merge pull request #3601 from element-hq/valere/fix_switch_spotlight_screenshare
fix: Automatically switch to spotlight if remote screenshare
2025-12-01 15:30:24 +01:00
Valere b7fc86ee06 review: move setGridMode close to the value it sets 2025-12-01 15:25:17 +01:00
Timo K f26aa8f970 fix tests 2025-12-01 15:10:38 +01:00
Valere 1ff479a315 fix: Automatically switch to spotlight if remote screenshare 2025-12-01 15:06:17 +01:00
Timo K 47c6a17d1e review 2025-12-01 14:58:06 +01:00
Timo K 24ed43ce13 Merge branch 'livekit' into toger5/fix-local-transport-update 2025-12-01 14:23:11 +01:00
Timo K 1490359e4c cleanup changes godot->sdk add docs 2025-12-01 14:09:09 +01:00
Timo K 0664af0f1b log cleanup and expose members$ 2025-12-01 13:49:33 +01:00
Timo K 284a52c23c mvp 2025-12-01 12:44:41 +01:00
Timo K 2d8ffc0ccd almost mvp 2025-12-01 12:43:43 +01:00
Timo K 28158bfc23 temp 2025-12-01 12:43:43 +01:00
renovate[bot] 04bbf83ac5 Update GitHub Actions 2025-12-01 11:00:52 +00:00
renovate[bot] 5aa82295fd Update embedded package dependencies 2025-12-01 01:28:55 +00:00
Timo 3331af1108 Merge pull request #3592 from element-hq/valere/fix_flaky_test
test: use `setSystemTime` for better test stability
2025-11-28 22:00:24 +01:00
Timo K 66dece98a5 add more test for publisher 2025-11-28 21:50:22 +01:00
Timo K 2011aef116 skip "Should show error screen if call creation is restricted" on ff 2025-11-28 18:00:04 +01:00
Valere Fedronic f5c422c559 Merge pull request #3597 from element-hq/valere/test_reconcile
test: Add simple tests for scope.reconcile
2025-11-28 10:00:06 +01:00
Valere c6bfda94cf test: additional reconcile test 2025-11-28 09:53:18 +01:00
Valere cdd391b3a2 test: Add simple tests for scope.reconcile 2025-11-28 09:12:05 +01:00
Valere 59d21d2421 Merge branch 'livekit' into valere/bugfix_earpiece_mute_video 2025-11-27 18:47:45 +01:00
Valere 149f3d02ae fix: The force mute state was not synced to the handler 2025-11-27 18:47:33 +01:00
Valere Fedronic 5bc7b31dcd Merge pull request #3593 from element-hq/valere/quality_gate
test: Enable quality gate and touch a file
2025-11-27 18:28:30 +01:00
Timo K c0913b6546 fix playwright test 2025-11-27 18:02:46 +01:00
Timo K 46f8fe4ec7 fix test errors 2025-11-27 16:43:28 +01:00
Valere c00e332dd8 Revert "vitest: Add threshold on vitest to check locally"
This reverts commit e5509ba49b.
2025-11-27 16:43:12 +01:00
Valere e5509ba49b vitest: Add threshold on vitest to check locally 2025-11-27 16:39:45 +01:00
Valere 4c2c7d51cf revert test changes on ObservableScope 2025-11-27 16:38:51 +01:00
Valere fc39e82666 Fix: Camera is not muted when the earpiece mode is enabled 2025-11-27 15:52:25 +01:00
Timo K 4b0f6e76c4 revert complete behavior check 2025-11-27 15:38:31 +01:00
Timo K e5117f705d More testing and cleaning up 2025-11-27 14:42:23 +01:00
Valere 794585514a Revert "add untested function"
This reverts commit c078dd87fa.
2025-11-27 10:04:09 +01:00
Valere c078dd87fa add untested function 2025-11-26 19:28:44 +01:00
Valere 2b3e2f6188 test: Enable quality gate and touch a file 2025-11-26 19:13:07 +01:00
Valere acd5dde6d8 test: use setSystemTime for better test stability 2025-11-26 16:27:54 +01:00
Timo K d22d7460fe Another larger refactor to fix sfu switches and in general proper
cleanup.
2025-11-25 20:18:34 +01:00
Valere 7f3596845c fix formatting 2025-11-25 11:40:38 +01:00
Valere e2607d6399 Config: UrlParams to control noiseSuppression and echoCancellation 2025-11-25 11:10:53 +01:00
Timo K 8bf6518371 remove span processor endpoints 2025-11-24 12:42:00 +01:00
Timo K 2f92867383 remove otel deps 2025-11-24 12:36:36 +01:00
Timo K 1fda5c7920 remove otel to see what impact it has on tests. 2025-11-24 12:33:02 +01:00
Timo 3491a68362 Merge pull request #3576 from element-hq/toger5/fix-skipped-tests
Refactor local transport testing and local membership initialization
2025-11-24 11:36:27 +01:00
Valere 294b90b6dc fix fixture following web change 2025-11-24 11:29:03 +01:00
Timo K ddd015d696 fix dev EditInPlace 2025-11-24 10:04:01 +01:00
Timo K 7532f72c90 use edit in place (WIP) This is WIP since it will submite -> reload the
page onSave
2025-11-21 18:49:30 +01:00
Timo K e60bc9e98f add developer tab snapshot test 2025-11-21 17:44:35 +01:00
Timo 1aa1af2ade Merge pull request #3585 from element-hq/toger5/add-log-screenshare
Add log to screenshare
2025-11-21 16:58:04 +01:00
Timo K ccadc17406 Add log to screenshare. 2025-11-21 16:19:19 +01:00
Timo K a731981388 Cleanup transport creation and local store hack. 2025-11-21 14:02:15 +01:00
Timo K 4099c4383d move HomeserverConnected 2025-11-21 13:04:28 +01:00
Timo K d34775fc47 fix linter 2025-11-20 16:40:06 +01:00
Timo K a29f0162ad remove widget log 2025-11-20 16:34:53 +01:00
Timo K a69a50d30c add log to error boudnary 2025-11-20 16:32:40 +01:00
Timo K 89a1bfac2d remove unused test helper 2025-11-20 15:25:53 +01:00
Timo K 1fd9ac93c9 refactor local transport testing and local memberhsip initialization 2025-11-20 15:19:00 +01:00
Timo f6ef872242 Merge pull request #3575 from element-hq/hs/lint-src-imports
Restrict importing src/lib in most cases for matrix- libs
2025-11-20 14:55:41 +01:00
Half-Shot 07de8483d5 Restrict importing src/lib in most cases for matrix- libs 2025-11-20 13:32:09 +00:00
Valere Fedronic 42b4c8301f Merge pull request #3547 from element-hq/valere/fix_blank_widget_auto_leave
fix: Send close widget action on auto-leave
2025-11-20 11:41:43 +01:00
Valere c2f541ff8c split test in 2 one testing sound and one to just leave 2025-11-20 11:28:24 +01:00
Valere c1049b6088 fix import causing lint errors in node_modules 2025-11-20 10:46:24 +01:00
Valere 6577db16ce Merge branch 'livekit' into valere/fix_blank_widget_auto_leave 2025-11-20 10:41:31 +01:00
renovate[bot] cdc3c2b216 Update LiveKit components (#3573)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-19 20:18:18 +01:00
renovate[bot] 47324b52f8 Update dependency livekit-client to v2.16.0 (#3574)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-19 20:14:37 +01:00
alutarius 82706cca4f Correct Caddy reverse proxy config example (#3572) 2025-11-18 18:46:00 +01:00
Timo 665a6be484 Merge pull request #3560 from element-hq/voip-team/call-viewmodel-refactor
`CallViewmodel` refactor
2025-11-18 13:48:03 +01:00
Valere 0076b54e52 minor comments/TODO cleaning 2025-11-18 12:14:17 +01:00
Valere 614762b5f8 fixup headers 2025-11-18 10:13:10 +01:00
Timo 222982c52c Merge pull request #3571 from element-hq/toger5/createCallViewModelFunction$
`createCallViewModel$` function refactor
2025-11-17 19:46:06 +01:00
Timo K 2a19f06e4a reword docstring 2025-11-17 19:45:14 +01:00
Robin 171c289f2d Merge pull request #3564 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.15.15
2025-11-17 13:41:44 -05:00
Timo K 2e2c799f72 convert CallViewModel into create function pattern. (with much more
minimal changes thanks to the intermediate class refactor)
2025-11-17 18:24:47 +01:00
Valere FedronicandTimo K 16e1c59e11 playwright: Fix error boundary mgmt or openId errors (#3570)
* playwright: Fix error boundary mgmt or openId errors

* do not use tap for important logic

* fix lint

---------

Co-authored-by: Timo K <toger5@hotmail.de>
2025-11-17 18:22:37 +01:00
Timo b51df36a06 Move one-on-one layout into CallViewModel (#3567)
* move ononone layout into CallViewModel

* move even more into the vm.

* tests
2025-11-17 17:42:37 +01:00
Timo 49ec4b4298 Merge pull request #3568 from element-hq/toger5/createCallViewModel$
refactor to createCallViewModel$
2025-11-17 15:04:18 +01:00
Timo K f518111887 add back docstrings 2025-11-17 14:55:00 +01:00
Timo K 4414fe3c82 remove all /*PUBLIC*/ 2025-11-17 14:39:24 +01:00
Timo K e9f400e9f1 remove ReturnType 2025-11-17 14:30:16 +01:00
Timo K 7ab90d3c1f Delete unused files 2025-11-17 12:00:28 +01:00
Timo K 348f0dbfa8 CallViewModel structure change. Clear input and outputs. 2025-11-17 11:37:58 +01:00
renovate[bot] 9ad029d4ff Update dependency livekit-client to v2.15.15 2025-11-17 02:42:33 +00:00
Robin cf8298cd69 Fix lints 2025-11-14 18:57:39 -05:00
Robin bb746dc8dc Fix a resource leak in the track processor code 2025-11-14 18:45:02 -05:00
Robin 53aaa011b7 Remove stray comma
This comma was showing up in the bottom left corner of the UI.
2025-11-14 16:41:18 -05:00
Robin 494ed7c126 Fix the MatrixRTC mode developer controls
They weren't responding properly to clicks, and make more sense as radio buttons.
2025-11-14 14:15:58 -05:00
Timo K b9ad83bf3b fix a couple of more tests. 2025-11-14 18:45:07 +01:00
Valere 6d8d2d2384 refact: extract withCallViewModel in test utils file 2025-11-14 17:30:02 +01:00
Timo K b731c2e9fd dont import withCallViewModel in Lifecycle test 2025-11-14 16:53:43 +01:00
Robin da85e74596 Restore LocalMembership tests 2025-11-14 10:48:24 -05:00
Valere FedronicandTimo K 8ce8067956 Adding more logs (#3563)
* Adding more logs

* post merge fix

* fixup merge error

* review

---------

Co-authored-by: Timo K <toger5@hotmail.de>
2025-11-14 16:18:31 +01:00
Timo K f6d0d7323e fix call lifecycle and add tests. 2025-11-14 16:01:43 +01:00
Timo K fdce3ec1aa Fix a couple of CallViewModel tests. 2025-11-14 10:44:16 +01:00
Ben Banfield-Zanin a3950869fb Use the dedicated bug report sub-domain (#3557)
* Update docs for 'rageshake.submit_url' to use the dedicated subdomain

* Update Netlify preview deployment to use the dedicated subdomain for 'rageshake.submit_url'
2025-11-13 15:33:59 +00:00
Timo K 0115242a2b tests first batch 2025-11-13 11:35:37 +01:00
Robin c7f50b53f5 Fix decryption errors
The code had regressed to a state where it was attempting to use one encryption worker for all LiveKit rooms, which does not currently work.
2025-11-12 15:41:41 -05:00
Robin a62d8368a1 Fix and simplify screen sharing 2025-11-12 15:02:19 -05:00
Robin 27b76b4b1d Remove unused Async type 2025-11-12 14:28:26 -05:00
Robin 8d421899a6 Fix formatting of doc comment 2025-11-12 10:16:15 -05:00
Timo KandValere 9f4d954cfa The source of the local participant is the createLocalMembership$ and
not the MatrixLivekitMembers!

Co-authored-by: Valere <bill.carson@valrsoft.com>
2025-11-12 12:09:31 +01:00
Timo K 8671d3fd67 Very bit test overhaul. All displayname tests are now done in the
Metadata file. and not in the CallViewModel anymore.
2025-11-11 15:52:35 +01:00
Timo K 85f659bcc9 Introduce MatrixMemberMetadata and use it to simplify username and
avatar computation This removes member from the tiles entirely!
2025-11-11 15:51:48 +01:00
Timo K 93c4dc5beb make it run 2025-11-10 15:55:01 +01:00
Valere 93659931ca fixup: update integration tests 2025-11-10 11:20:20 +01:00
Valere 5c83e0dce1 test: fixup MatrixLivekitMembers tests 2025-11-10 10:43:53 +01:00
Robin 92ddc4c797 Fix avatar reactivity, simplify display names tracking 2025-11-09 01:16:39 -05:00
Robin b4c17ed26d Replace generateKeyed$ with a redesigned generateItems operator
And use it to clean up a number of code smells, fix some reactivity bugs, and avoid some resource leaks.
2025-11-09 00:46:16 -05:00
Valere 1f386a1d57 test: fix displayname tests due to Epoch change 2025-11-08 13:24:03 +01:00
Valere fc842d4be7 test: fixup ConnectionManager tests 2025-11-08 13:02:12 +01:00
Timo K b8635b52d8 Working (no local feed) 2025-11-07 19:07:45 +01:00
Timo K cf5c35bccd fix more runtime errors 2025-11-07 17:14:02 +01:00
Timo K e741285b11 Fix lints, move CallViewModel.test.ts. Fix audio renderer 2025-11-07 14:04:40 +01:00
Timo K 28047217b8 Almost running
- NEVER use undefined as the default for behaviors (FOOTGUN)
2025-11-07 12:33:07 +01:00
Timo K 92fdce33ea pull out all screen share related logic. 2025-11-07 08:44:56 +01:00
Timo K 7c41aef801 Add Epoch<T> and use it in for the memberships$ behavior and its
derivatives.
2025-11-06 22:00:48 +01:00
Valere 2e6b1767b9 Fixup base integration test 2025-11-06 16:48:20 +01:00
Timo K a55ce19048 cleanup 2025-11-06 15:26:17 +01:00
Valere 6e1a582265 fix tests compilation peer session timo - wip 2025-11-06 12:08:46 +01:00
Robin 5afc3c2598 Merge pull request #3556 from element-hq/renovate/node-24.x
Update Node.js to v24
2025-11-05 13:55:24 -05:00
Robin 8ad0cb1955 Merge pull request #3551 from element-hq/renovate/embedded-package-dependencies
Update embedded package dependencies to v8.13.0
2025-11-05 13:53:27 -05:00
Robin 9bd464a7f1 Merge pull request #3550 from element-hq/renovate/github-actions
Update softprops/action-gh-release digest to 6da8fa9
2025-11-05 13:53:08 -05:00
Robin f0adae41ef Merge pull request #3552 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.15.14
2025-11-05 13:49:44 -05:00
renovate[bot] f9cc930155 Update Node.js to v24 2025-11-05 18:49:21 +00:00
Robin eebcd133f3 Merge pull request #3553 from element-hq/robin/trusted-publishing
Remove use of npm access token now that trusted publishing is set up
2025-11-05 13:45:52 -05:00
Timo K d8e29467f6 rename merger 2025-11-05 18:58:40 +01:00
Timo K c19e2245c8 use createSomething$ mathods instead of classes
Rename several classes/behaviors to factory-style creators and adapt
call wiring and tests accordingly:
- Replace ConnectionManager class with createConnectionManager$ which
  returns transports$, connectionManagerData$, connections$
- Convert MatrixLivekitMerger to createMatrixLivekitMembers$
  (matrixLivekitMerger$)
- Rename sessionBehaviors$, localMembership$, localTransport$ to
  createSessionMembershipsAndTransports$, createLocalMembership$,
  createLocalTransport$
- Adjust participant types and hook up connectOptions$; expose join via
  localMembership.requestConnect
- Update tests to use the new factory APIs
2025-11-05 18:57:24 +01:00
Timo K 4d0de2fb71 Refactor Matrix/LiveKit session merging
- Replace MatrixLivekitItem with MatrixLivekitMember, add displayName$
  and participantId, and use explicit LiveKit participant types
- Make sessionBehaviors$ accept a props object and return a typed
  RxRtcSession
- Update CallViewModel to use the new session behaviors, rebuild media
  items from matrixLivekitMembers, handle missing connections and use
  participantId-based keys
- Change localMembership/localTransport to accept Behavior-based
  options, read options.value for enterRTCSession, and fix advertised
  transport selection order
- Update tests and minor UI adjustments (settings modal livekitRooms
  stubbed) and fix JSON formatting in locales
2025-11-05 17:55:36 +01:00
Timo K 107ef16d94 Add MatrixRTCMode and refactor local membership
Remove preferStickyEvents and multiSfu in favor of a MatrixRTCMode
enum/setting (Legacy, Compatibil, Matrix_2_0). Move session join/leave,
track pause/resume, and config error handling out of CallViewModel into
the localMembership module. Update developer settings UI, i18n strings,
and related RTC session helpers and wiring accordingly.
2025-11-05 12:56:58 +01:00
Timo K 57bf86fc4c finish up most of our helper classes. there are no lint issues in the
new classes. The CallViewModel is not done yet however
2025-11-04 20:24:15 +01:00
Valere 870b706672 Connection & Livekit integ test WIP 2025-11-04 17:13:28 +01:00
Valere 06734ae086 quick refactor, use object instead of tupple 2025-11-04 17:12:44 +01:00
Robin 79bd458dc2 Remove use of npm access token now that trusted publishing is set up
npm has recently limited the lifetime of all access tokens to 90 days (https://gh.io/npm-token-changes), so it would be a bit inconvenient to stick to our current access token-based method of publishing releases. Meanwhile npm has implemented a more secure publishing method based on OIDC in which you tell the registry that a particular GitHub Actions workflow should be a "trusted publisher" for a given package, and then the CLI will authenticate automatically. (https://docs.npmjs.com/trusted-publishers)

I've already set trusted publishing up on the registry side, and since we're already granting the job permission to generate ID tokens for provenance, there should be no additional lines of config needed to make it work. Let's take away the access token and see how this goes next time we release.
2025-11-03 17:13:03 -05:00
Valere 5961cb65df test with marbles 2025-11-03 17:19:17 +01:00
Valere a7d2a3b9db es lint fixes 2025-11-03 13:18:33 +01:00
Valere 4c5f06a8a9 Refactoring to ease testing of ConnectionManager
- Extract a ConnectionFactory
- Change Connection manager allPariticipantWithConnection$ for structure that supports members with no participant
2025-11-03 13:18:21 +01:00
renovate[bot] a4b1ce52cd Update dependency livekit-client to v2.15.14 2025-11-03 01:02:47 +00:00
renovate[bot] b22a937e7c Update softprops/action-gh-release digest to 6da8fa9 2025-11-01 02:02:21 +00:00
Timo K a44171da1c changes summary valere timo 2025-10-30 22:15:35 +01:00
Timo K 4f892e358a start onwMemberhsip.ts 2025-10-30 15:15:49 +01:00
Timo K c8ef8d6a24 start moving over/removing things from the CallViewModel 2025-10-30 01:13:06 +01:00
Timo K 6b513534f1 lots of fixup in the new classes 2025-10-30 00:09:07 +01:00
Timo K 633a0f9290 connection manager 2025-10-29 18:33:58 +01:00
Timo KandValere 62ef49ca05 temp
Co-authored-by: Valere <bill.carson@valrsoft.com>
2025-10-29 15:20:06 +01:00
Timo KandValere 3de0bbcfc9 temp
Co-authored-by: Valere <bill.carson@valrsoft.com>
2025-10-29 12:37:14 +01:00
Timo K cfe05f1ed9 more temp 2025-10-28 21:58:10 +01:00
Timo K 9cdbb1135f temp 2025-10-28 21:18:47 +01:00
Valere 0309ceb6aa fix lint 2025-10-27 15:59:01 +01:00
Valere 3ecffccd9e fix prettier 2025-10-27 15:41:16 +01:00
Valere 3dd0b156cf fix: Send close widget action on auto-leave 2025-10-27 14:31:23 +01:00
Valere Fedronic 5b21691c21 Merge pull request #3544 from element-hq/valere/fix_hangup
Fix: widget hangup action not working
2025-10-24 13:33:04 +02:00
Valere 23bcb5777c Fix: widget hangup action not working 2025-10-23 19:20:21 +02:00
renovate[bot] 5e0a3f3974 Update LiveKit components (#3533)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-23 17:31:41 +02:00
renovate[bot] 06337b9ae6 Update dependency vite to v7.1.11 [SECURITY] (#3541)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-23 17:23:07 +02:00
renovate[bot]andfkwp 1fa2eba0c0 Update dependency livekit-client to v2.15.11 (#3532)
* Update dependency livekit-client to v2.15.11

* bump livekit/protocol

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: fkwp <github-fkwp@w4ve.de>
2025-10-23 17:14:41 +02:00
Valere Fedronic f99d01fc38 Merge pull request #3512 from element-hq/voip-team/rebased-multiSFU
Multi-SFU media transport
2025-10-23 16:46:49 +02:00
Valere 301cf2f4eb Revert "CI try without USE_DOCKER"
This reverts commit d52656c553.
2025-10-23 16:26:02 +02:00
Valere 918d67b2ac CI: revert to synapse latest 2025-10-23 16:23:08 +02:00
Valere d52656c553 CI try without USE_DOCKER 2025-10-23 16:07:04 +02:00
Valere 0823936ee1 revert CI test changes 2025-10-23 16:05:24 +02:00
Valere 150cdf64c8 CI try some more logs 2025-10-23 15:55:22 +02:00
Valere 552e1215be revert CI test changes 2025-10-23 14:24:15 +02:00
Valere 185d7d1177 CI test 2025-10-23 14:13:50 +02:00
Valere c572d2e779 test CI 2025-10-23 14:02:17 +02:00
Valere 348a6fe1af test CI changing ports 2025-10-23 13:54:08 +02:00
Valere a638acde2c CI: Increase job timeout 2025-10-23 13:41:08 +02:00
Valere e06f288e93 update playwright 2025-10-23 10:41:10 +02:00
Robin db2004fb90 Remove unused string 2025-10-22 23:29:36 -04:00
Robin e0b9a85f02 Merge branch 'livekit' into voip-team/rebased-multiSFU 2025-10-22 23:28:26 -04:00
Robin 6be7749091 Remove even more dead code 2025-10-22 23:27:38 -04:00
Robin 5245b22d80 Remove dead test files
While we still ought to eventually port these tests in some way, the presence of these empty test files is causing a Vitest failure, so it's easiest to just let them go and refer to Git history when we do want to reference them next.
2025-10-22 23:18:15 -04:00
Robin 75a8dd21eb Remove some dead code 2025-10-22 23:17:07 -04:00
Robin 2c5afe82c4 Skip GroupCallView tests for now 2025-10-22 23:13:57 -04:00
Robin 58cd12b9b8 Fix a number of remaining test failures 2025-10-22 22:57:29 -04:00
Robin a1c7255cc6 Restore CallViewModel tests to working order
I've left only one of the tests behind (skipped).
2025-10-22 18:50:16 -04:00
Robin 9ca8962328 Remove unused useECConnectionState React hook
It has been replaced by Connection.
2025-10-22 18:48:28 -04:00
Timo K 8da111d39d remove option to enable/disable room transport
Signed-off-by: Timo K <toger5@hotmail.de>
2025-10-22 14:13:31 +02:00
Timo K 19daf5f5f3 update snapshot (in call view)
Signed-off-by: Timo K <toger5@hotmail.de>
2025-10-22 14:10:10 +02:00
5526cd74cb Add sticky event support (#3513)
* add sticky event support
 - use new js-sdk
 - use custom synapse
 - don't filter rooms by existing call state events

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

* enable sticky events in the joinSessionConfig

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

* Remove unused useNewMembershipmanager setting

* Add prefer sticky setting]

* Fixup call detection logic to allow sticky events

* lint

* update docker image

* More tidy

* update checksum

* bump js-sdk fix sticky events type

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

* fix demo

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

* always use multi sfu if we are using sticky events.

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

* review

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

* lint

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

* Always consider multi-SFU mode enabled when using sticky events

CallViewModel would pass the wrong transport to enterRtcSession when the user enabled sticky events but didn't manually enable multi-SFU mode as well. This likely would've added some confusion to our attempts to test these modes.

* Fix test type errors

* add todo comment

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: Half-Shot <will@half-shot.uk>
Co-authored-by: Robin <robin@robin.town>
2025-10-22 12:53:22 +02:00
Robin e7e0facaa5 Merge pull request #3536 from robintown/stable-speaker-switches
Avoid gratuitous animations when the speaker changes
2025-10-21 13:36:54 -04:00
Robin 1a26a85a78 Show that we've proved to TypeScript that the media is user media 2025-10-21 13:22:20 -04:00
Robin 4936cdfbf6 Merge pull request #3537 from robintown/connection-leaks
Fix resource leaks when we stop using a connection
2025-10-21 09:56:31 -04:00
Robin 340265a838 Enable the PiP tile in expanded spotlight layout to swap speakers without a layout shift
This was apparently left unimplemented during the first iteration of the TileStore. It's a welcome UI optimization and we can reliably test for it.
2025-10-21 01:08:46 -04:00
Robin 1b3a56427f Document generateKeyed$ more thoroughly 2025-10-21 00:27:18 -04:00
Robin 27f24ca565 Document CallViewModel and some terms used 2025-10-21 00:07:48 -04:00
fkwp a12b9ccbb4 Add another community guide (#3539)
* add another community guide
2025-10-20 09:35:50 +02:00
Robin 13894aaf3a Simplify some test helpers that no longer need continuations 2025-10-17 12:34:06 -04:00
Robin d5efba285b Fix resource leaks when we stop using a connection
The execution of certain Observables related to a local or remote connection would continue even after we stopped caring about said connection because we were failing to give these state holders a proper ObservableScope of their own, separate from the CallViewModel's longer-lived scope. With this commit they now have scopes managed by generateKeyed$.
2025-10-17 12:23:53 -04:00
Robin 717c7420f9 Require ObservableScopes of state holders to be specified explicitly
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$.
2025-10-17 12:23:53 -04:00
Robin 414322e5d9 Fix TileStore's ability to swap spotlight speakers without a layout shift
This was regressed in 79c40f198c because of the overlooked renaming of the 'speaking' field to 'speaking$'.
2025-10-17 11:25:39 -04:00
Robin 1eec7314e8 Remove unnecessary lint suppressions 2025-10-17 11:22:23 -04:00
Robin 2c66e11a0a Fix connection tests
Removing one of these tests because it was doing a lot of work to test something that was made trivial in b0eb566a4f.
2025-10-14 16:04:52 -04:00
Robin 102e581c41 Serialize updates to the call intent
So that the value advertised in your membership can't desync from the actual value if you toggle video too fast.
2025-10-14 15:20:07 -04:00
Robin b0eb566a4f Simplify local transport connection state tracking 2025-10-14 14:43:13 -04:00
Robin 2dc6134606 Stick to the term 'transport' rather than 'focus' 2025-10-14 14:38:37 -04:00
Robin ea17ed7253 Rename 'localTransport' to 'transport', since it's often remote 2025-10-14 14:34:51 -04:00
Robin 9f4e99310b Elaborate on a TODO for preloading JWT tokens 2025-10-14 14:32:56 -04:00
Robin 625cfa15ff Move sorting bin calculation into UserMedia 2025-10-14 14:31:35 -04:00
Robin 95069fd3fa Fix joining call with audio and video muted 2025-10-14 12:19:23 -04:00
Robin 13636b78d9 Replace deprecated CallMembership.sender with userId 2025-10-14 12:07:51 -04:00
Robin bcbf7a90f0 Initialize preferredTransport$ in a less unusual way 2025-10-14 12:00:00 -04:00
Robin 2de7a20d8a Remove outdated comment 2025-10-14 11:54:36 -04:00
Valere a6c4fb4148 review: count as publishing even if not yet connected to LK 2025-10-14 17:47:38 +02:00
Robin b030d304df Fix crash during focus switching 2025-10-14 09:29:48 -04:00
Robin 392c51fbf6 Merge branch 'voip-team/rebased-multiSFU' of github.com:element-hq/element-call into voip-team/rebased-multiSFU 2025-10-14 09:22:08 -04:00
Robin a18700cbcd Avoid updating membership during focus switch 2025-10-14 09:16:46 -04:00
Valere 93d763f58f devtool: quick display of focus URL in stats tile 2025-10-14 14:06:54 +02:00
Valere 58d60b35fd fix CI failing with Invalid value "iife" for option "worker.format"
UMD and IIFE output formats are not supported for code-splitting builds. see https://github.com/vitejs/vite/issues/18585
2025-10-14 12:25:31 +02:00
Valere 60332dc2db fix js-sdk dependency format 2025-10-14 12:16:24 +02:00
Valere a9db9c8b59 ErrorHandling: publish connection error handling 2025-10-14 10:46:57 +02:00
Valere a5aba928dd dependency: depends on js-sdk develop 2025-10-13 16:39:14 +02:00
Valere 0e1b61a5e8 refactor: Split out all exports of CallViewModel to their own file 2025-10-13 16:24:55 +02:00
Valere 8823be67c5 refactor extract inner classes to their own files 2025-10-13 15:43:12 +02:00
Valere 8e6eb70e5b refactor: use EnterRTCSessionOptions instead of unnamed bools 2025-10-13 13:52:01 +02:00
Valere Fedronic c846ea6447 Merge pull request #3521 from element-hq/valere/multi-sfu/connection_states
Connection State: Error Handling + Cleaning / refactoring /
2025-10-13 10:15:55 +02:00
Valere fc2384e330 post merge fixes (js-sdk changes) 2025-10-10 19:23:24 +02:00
Valere 2fc7f11bea prettier fix 2025-10-10 16:51:58 +02:00
Valere cca46bd8dd Merge branch 'voip-team/rebased-multiSFU' into valere/multi-sfu/connection_states 2025-10-10 16:51:09 +02:00
Valere 1e75f9adcc test: fix additional test with proper mutestate fix 2025-10-10 15:13:55 +02:00
Valere 4a8f5bccac post merge lint fixes 2025-10-10 15:04:12 +02:00
Valere 4608d68cd9 Merge branch 'voip-team/rebased-multiSFU' into valere/multi-sfu/connection_states 2025-10-10 15:01:49 +02:00
Timo K 0fd414358c Merge branch 'livekit' into voip-team/rebased-multiSFU
Signed-off-by: Timo K <toger5@hotmail.de>
2025-10-10 12:26:47 +02:00
Valere 1ab081d636 test: MISSING_MATRIX_RTC_FOCUS renamed as MISSING_MATRIX_RTC_TRANSPORT 2025-10-10 11:41:26 +02:00
Valere 6710f4c72a Test: Fix mocking to fix failing tests 2025-10-10 11:09:41 +02:00
Robin de5f5198dd Merge branch 'livekit' into voip-team/rebased-multiSFU
Note that this effectively *reverts* 3ac2aa8526 because this branch now has what is a better UX (at least I think so): the in-call view is presented instantly when pressing the join button. Errors that occur during initial connection procedures will be surfaced more uniformly.
2025-10-09 16:44:12 -04:00
Robin f9f2896a6a Merge branch 'voip-team/rebased-multiSFU' of github.com:element-hq/element-call into voip-team/rebased-multiSFU 2025-10-09 16:37:48 -04:00
Valere a500915c43 test: Fix mute test, behavior change from setMuted to setAudioEnabled
useCallViewKeyboardShortcuts() changed a param from `setMicrophoneMuted` to `setAudioEnabled`, the boolean arg of the callback is inverse tht it used to be
2025-10-09 19:24:44 +02:00
Valere 7cbb1ec1e8 Simplify AudioRenderer and add more tests 2025-10-09 15:33:25 +02:00
Timo K 39f8cb95ec make compatible with related_event (async CallMembership) branch
Signed-off-by: Timo K <toger5@hotmail.de>
2025-10-09 15:29:47 +02:00
Valere 4c6b960da3 fix: use correct TestEachFunction 2025-10-09 11:00:45 +02:00
Robin 85ffe68d98 Remove outdated comment 2025-10-08 19:20:21 -04:00
Robin 2c576a7477 Clean up subscriptions in Connection tests 2025-10-08 19:09:27 -04:00
Robin 64c2e5911c Update outdated comment 2025-10-08 19:09:08 -04:00
Robin 5be3b91509 Fix focus connection state typo, simplify its initialization 2025-10-08 19:09:03 -04:00
Robin 2d7e4247f3 Note a potential resource leak 2025-10-08 18:51:30 -04:00
Robin 00daf834b6 Remove local participant case (now enforced by types) from audio tests 2025-10-08 17:53:11 -04:00
Robin dcc3ab641f Remove MockedObject from mockMediaDevices type signature 2025-10-08 17:40:03 -04:00
Robin dee06a4b70 Remove unused useIsEarpiece hook 2025-10-08 17:37:54 -04:00
Robin 3691e7120d Restore a hidden 'null' state for the local transport/connection 2025-10-08 17:35:53 -04:00
Robin 8778be8351 Fix doc comment typo 2025-10-08 17:34:33 -04:00
Robin e88474452f Correct / document some missing bits in tests 2025-10-08 17:33:17 -04:00
Robin b1d143720a Add comments to Async 2025-10-08 17:08:51 -04:00
Robin 5da780ed30 Remove dead MuteStates file
It's been replaced by a refactored RxJS version living in src/state.
2025-10-08 16:43:43 -04:00
Robin c96e81bfd3 Simplify type of audio participants exposed from CallViewModel 2025-10-08 16:42:36 -04:00
Robin e346c8c148 Re-enable React strict mode 2025-10-08 16:39:27 -04:00
Robin 1a4b38cf93 Document ObservableScope.reconcile 2025-10-08 12:54:24 -04:00
Robin 5835cd423e Merge pull request #3517 from element-hq/renovate/github-actions
Update GitHub Actions
2025-10-08 10:19:22 -04:00
Valere 427a8dd644 test: Fix Audio render tests and added more 2025-10-08 14:48:40 +02:00
Valere afe004c6e7 Remove un-necessary transport field, already accessible from connection 2025-10-08 14:30:52 +02:00
Valere f5ea734a5c esLint fix 2025-10-08 14:29:59 +02:00
Valere 13fb46644c test: Fix mediaView test, ,member is not optional anymore
Updated the test because now name will be the userId instead of default display name
2025-10-08 08:50:35 +02:00
Robin 669bc76dd5 Replace calls to deprecated resolveActiveFocus 2025-10-08 01:04:58 -04:00
Valere 05e7b5a7ff fixup MediaView tests 2025-10-07 17:35:25 +02:00
Valere 18ba02c9c2 knip: remove dead code 2025-10-07 16:29:11 +02:00
Valere 529cb8a7ec prettier ! 2025-10-07 16:24:02 +02:00
Valere 7437961195 lint: fix import order 2025-10-07 16:12:23 +02:00
Valere c820ba3983 build: update lock file 2025-10-07 16:07:46 +02:00
Valere c3c0516f0d Lint: fix all the lint errors 2025-10-07 16:00:59 +02:00
Valere 597e6782a8 Merge branch 'voip-team/rebased-multiSFU' into valere/multi-sfu/connection_states 2025-10-07 10:33:31 +02:00
renovate[bot] f08805d3ed Update GitHub Actions 2025-10-07 05:31:36 +00:00
Will HuntandRobin 3ac2aa8526 Disable call button while the call is connecting. (#3531)
* Disable call button while the call is connecting.

* cleanup

* fix

* Update src/room/LobbyView.tsx

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

* fixup

* appease linter

---------

Co-authored-by: Robin <robin@robin.town>
2025-10-06 18:52:58 +00:00
Valere 91a366fa2a tests: Publish connection states 2025-10-06 10:50:10 +02:00
Robin 1fff71ace1 Actually leave the MatrixRTC session again 2025-10-03 21:00:45 -04:00
Robin 1820cac3f6 Create media items for session members not joined to LiveKit 2025-10-03 19:14:48 -04:00
Robin 86fb026be8 Turn multi-SFU media transport into a developer option 2025-10-03 14:43:22 -04:00
Valere 00401ca38a refactor: PublishConnection extract from giant constructor 2025-10-02 15:15:23 +02:00
Valere 84f95be48d test: Ensure scope for publishers observer 2025-10-02 13:08:00 +02:00
Valere 0502f66e21 tests: Add publisher observable tests 2025-10-02 12:53: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
Valere dfaa6a33f4 fix lint errors 2025-10-01 17:24:19 +02:00
Valere e8bf817f88 tests: end scope tests 2025-10-01 16:39:21 +02:00
Valere 6a1f7dd057 ConnectionState: test livekit connection states 2025-10-01 15:23:24 +02:00
Valere 22900161d6 extract common test setup 2025-10-01 14:47:45 +02:00
Valere 47c876f3df lint fixes 2025-10-01 14:37:03 +02:00
Valere 3d8639df03 Connection states tests 2025-10-01 14:21:37 +02:00
Valere 879a1d4af1 Connection: add Connection state and handle error on start 2025-10-01 11:23:16 +02:00
renovate[bot] 214bb75d27 Update embedded package dependencies to v8.13.0 2025-10-01 02:29:37 +00:00
Robin 71127a4e94 Merge pull request #3516 from element-hq/toger5/voip-team/rebased-multiSFU-bump-to-new-js-sdk-version
Use updated multi sfu js-sdk
2025-09-30 11:24:12 -04:00
Valere b00f7d5409 refactor: Remote / Publish Connection and constructor 2025-09-30 17:02:48 +02:00
Timo K 2819c79590 use updated multi sfu js-sdk
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-30 16:47:45 +02:00
Valere edf68d16b7 refactoring: prep work extract to file + documentation 2025-09-30 11:33:45 +02:00
Robin a4a0a58a72 Remove the option to show non-member ("ghost") participants
As we'd like to get the multi-SFU feature branch shipped, this is not the most important debugging tool to expend effort on at the moment.
2025-09-26 13:27:18 -04:00
Robin dbdf853d55 Stop connections on view model destroy 2025-09-26 13:20:55 -04:00
Robin 0759f9b27d Don't render audio from participants that aren't meant to be publishing 2025-09-25 21:29:02 -04:00
Robin 4980d8a622 Merge branch 'livekit' into voip-team/rebased-multiSFU 2025-09-25 18:40:59 -04:00
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
Robin 530fbaf90a Clear up the room membership confusion around reading session members 2025-09-24 21:39:36 -04:00
Robin 6cf020763e Make UI react instantly to hanging up but also wait for leave sound
This ensures that we don't see a mistaken 'reconnecting' toast while we're hanging up (and also that the leave sound gets a chance to play in widgets once again).
2025-09-24 21:26:16 -04:00
Robin edd3eb8747 Implement screen sharing 2025-09-24 13:54:54 -04:00
Robin f99a256c86 Reset matrix-js-sdk to multi SFU branch 2025-09-24 13:53:39 -04:00
Robin 8e21ea6d51 Merge branch 'livekit' into voip-team/rebased-multiSFU 2025-09-24 10:12:26 -04: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 96e96a5e43 fix leaving
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-23 12:25:05 +02:00
Timo K 7777179935 cleanup (delete files useLivekit) now covered by Connection.ts
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-23 11:40:29 +02:00
Timo K 78e9521f22 Make track processor work
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-23 11:38:34 +02:00
fkwp 342dd2e7d7 DevX: Add another Matrix site to docker-compose (#3511)
* remove redis, since we dont use it

* update localhost TLS certificat to add *.othersite.m.localhost wildcard

* allow for federation

* Add services and config files for Matrix site othersite.m.localhost

* add element web instance app.othersite.m.localhost

* update README

* exclude synapse database for othersite.m.localhost

* linting
2025-09-22 21:14:12 +02:00
Timo K 8bf24895ce TODO: settings modal with multiple connections
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-22 14:18:23 +02:00
Timo K dddda7057f add todo comments and who works on them
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-22 14:17:52 +02:00
Timo K 02f23e25fd remove todo from matrix audio renderer
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-22 14:16:24 +02:00
Timo b2c594d36c Never skip lobby for huddles (#3508)
* Never skip lobby for huddles

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

* tests

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-22 11:35:20 +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 41e152f420 dont throw disconnected error at start of the call
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:52:12 +02:00
Timo K ccfd32c9b2 move leave logic into view model
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:52:12 +02:00
Timo K 38d78ddce4 make audio work
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K cc870c3cc2 enable encryption in per sender case
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K c8098734cd one e2ee worker per session
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Robin e08f16f889 All my Friday work. Demoable! 2025-09-19 17:50:43 +02:00
Timo K 386dc6c84d temp before holiday
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Robin d46fe55a67 Import unfinished mute states refactor 2025-09-19 17:50:43 +02:00
Robin 02f4c73759 Add my own local storage SFU config stuff too 2025-09-19 17:50:43 +02:00
Timo K 598371b807 lots of work. noone knows if it works.
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K 802ebf828d refactor connection
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K e4a54e3a19 refactor connnection class
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K a617a92e88 make it work
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K 33bc78eec1 add logging
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K 8ffb360114 add local storage + more readable + remoteParticipants + use publishingParticipants
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K 55b46b3f33 introduce publishingParticipants$
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K 6bdfd7fbd8 add comment
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K a10489d7df publish audio in remote rooms
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo K 7b88420f6a first video!
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Robin cb91f1ad4f Make it actually join the session 2025-09-19 17:50:43 +02:00
Robin c6e8c94fd6 Fix makeFocus 2025-09-19 17:50:43 +02:00
Timo K 376a4b4e4a initial compiling version
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Robin d9b6302bf7 Fix crash? 2025-09-19 17:50:43 +02:00
Robin 35319dd6b5 Fix some errors in CallViewModel 2025-09-19 17:50:43 +02:00
Timo K 9011ae4e1f temp
Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:50:43 +02:00
Timo 9b9c08ed61 Refactor ring$ observable (#3504)
* Refactor ring$ observable

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

* fix ci

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

* fix regression test

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 17:43:31 +02:00
Timo 317b2dc796 Fix: never stop ring feedback on the sender side. (#3502)
* make ring$ a behavior and add code comments to justify/explain the change.

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

* Add test: reproduce "ring does not stop" race.

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-19 16:42:47 +02:00
Jorge Martin Espinosa 0774d18f92 Android: allow RCs to be published as non-SNAPSHOT versions (#3501)
* Android: allow RCs to be published as non-SNAPSHOT versions

* Fix broken string in build script
2025-09-18 19:22:24 +02:00
Timo 6e9dc34008 Add ring notification to UserIntent.StartNewCallDM (#3499)
* Add ring notification to UserIntent.StartNewCallDM

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

* Add more tests (refactor to compute + get)

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-18 17:45:49 +02:00
Timo db5c7cf9c7 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>
2025-09-18 13:21:12 +02:00
Will Hunt 63122c7f6b Log when a track is unpublished or runs into an error (#3495) 2025-09-18 12:09:54 +01:00
4be395500f 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>
2025-09-18 12:58:47 +02:00
renovate[bot] df7bd8ff2b Update dependency livekit-client to v2.15.7 (#3496)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-18 11:46:55 +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
5811794f31 Add drum/joke reaction (#3217)
* Add drum/joke reaction

* Add license information

* Update test snapshot

* update snapshot test

---------

Co-authored-by: Robin <robin@robin.town>
Co-authored-by: Davide Girardi <davideg@element.io>
Co-authored-by: fkwp <github-fkwp@w4ve.de>
2025-09-16 11:46:25 +02:00
Will HuntandTimo K 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
Timo 76465d0e63 Add "wait for pickup" overlay with sound. Leave on decline/timeout (#3489)
* 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>

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-09-15 09:58:16 +02:00
Robin a2cf4c8139 Merge pull request #3479 from robintown/fix-reconnect
Fix the reconnect button
2025-09-12 15:05:47 +02:00
Will Hunt 65d358df58 Do not use preload mode by default in embedded mode (#3488)
* Set preload=false by default for inApp

* Pull through types for params so it's easy to document

* Cleanup boolean logic

* change test
2025-09-11 14:57:26 +01:00
Robin 32cb8541f4 Actually fix the test flake 2025-09-10 16:42:09 +02:00
Robin 62cfe09c7b Merge pull request #3482 from element-hq/renovate/npm-vite-vulnerability
Update dependency vite to v6.3.6 [SECURITY]
2025-09-10 12:37:16 +02:00
Robin 8e32deaba5 Upgrade to Vite v7
To remove all the duplicate Rollup dependencies.
2025-09-10 12:31:03 +02:00
renovate[bot] 8311b1619c Update dependency vite to v6.3.6 [SECURITY] 2025-09-10 02:28:00 +00:00
Timo fc449bcfbf Merge pull request #3467 from element-hq/toger5/call-pickup-state-decline-event
View model for decline logic
2025-09-09 15:23:39 +02:00
Robin 34a8977dd1 Increase timeout to hopefully avoid test flakes 2025-09-08 15:24:46 +02:00
Robin db04cbfbfc Fix type error 2025-09-08 14:58:46 +02:00
Robin c8d3d58940 Merge pull request #3400 from element-hq/robin/reactions-small
Prefer showing the reaction button at small screen widths
2025-09-08 14:54:51 +02:00
Robin d85cf5f929 Fix the reconnect button
After a membership manager error, clicking the 'reconnect' button did nothing. This is because we were forgetting to clear the external error state, causing it to transition directly back to the same error state.
2025-09-08 14:21:38 +02:00
Robin 1e32b355ce Ignore decline events from the local user 2025-09-05 21:22:32 +02:00
Robin 1193a22658 Fix tests 2025-09-05 14:49:37 +02:00
Robin 2541f810fa Ensure that non-ringing notifications lead to a null pickup state 2025-09-05 14:36:27 +02:00
Robin 7961bb35be Merge pull request #3466 from element-hq/toger5/waitForNotificationAnswer
Add dialing/ringing state to CallViewModel (`callPickupState$`)
2025-09-05 14:11:37 +02:00
Robin c599d6eae9 Make the CallEventAudioRenderer test stricter 2025-09-05 14:06:28 +02:00
Andrew Ferrazzutti 075a4cbe0d Merge pull request #3475 from element-hq/af/docker-compose-pull-policy-always
docker compose: always pull latest image
2025-09-04 07:47:45 -04:00
Mohammed Tayeh cd845b69d2 Add Caddy configuration example and fix ConfigOptions.ts link (#3476)
Signed-off-by: Mohammed Tayeh <m.tayeh94@gmail.com>
2025-09-04 10:19:37 +02:00
Andrew Ferrazzutti 779f792cbf docker compose: always pull latest image
Otherwise, there is a risk of using outdated images for some services.
2025-09-03 15:39:27 -04:00
Robin e9c43856d0 Merge branch 'toger5/waitForNotificationAnswer' into toger5/call-pickup-state-decline-event 2025-09-03 17:59:16 +02:00
Robin 1e8b87408c Document recently added URL parameters 2025-09-03 16:59:37 +02:00
Robin 1428df8567 Tentatively rename URL parameter to waitForCallPickup 2025-09-03 16:52:40 +02:00
Robin b8acdc3cec Tidy/correct the dialing/ringing tests 2025-09-03 16:51:35 +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
Robin 58ed7ef93e Merge branch 'livekit' into toger5/waitForNotificationAnswer 2025-09-03 13:01:14 +02:00
Robin c1694fe706 Merge pull request #3470 from element-hq/af/migrate-defer
Migrate from js-sdk's `defer` in test
2025-08-28 18:21:05 +02:00
Andrew Ferrazzutti a775bcd62a Migrate from js-sdk's defer in test
See: matrix-org/matrix-js-sdk#4959
2025-08-28 10:14:32 -04: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 c15551c9f5 types
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 18:29:51 +02:00
Timo K f410a11934 unused import
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 18:13:04 +02:00
Timo K 3122ccf4e4 dont use deprecated defer
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 18:10:08 +02:00
Timo K 03527e9d7a fix participant count test
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 18:09:50 +02:00
Timo K 36be15436a fix linter
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 17:58:46 +02:00
Timo K 04c03b1e72 bump js-sdk to develop branch
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-26 17:41:58 +02:00
renovate[bot] 38e60208ef Update dependency livekit-client to v2.15.6 (#3468)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-26 13:54:25 +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 acd26c61ef use custom js-sdk from PR: https://github.com/matrix-org/matrix-js-sdk/pull/4976
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-25 14:24:32 +02:00
Timo K e475f56af5 waitForNotificationAnswer
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-25 14:11:10 +02:00
Timo 9486ed5d77 Merge pull request #3464 from robintown/reconnecting-test
Test sync loop status and membership status in reconnection test as well
2025-08-25 14:03:32 +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 db65a5308a Make most params optional for call view model test setup 2025-08-22 18:14:25 +02:00
fkwp 482e2f8f6f Refine MatrixRTC connection wording (#3463) 2025-08-22 12:34:18 +02:00
ElementRobot cd5b7cdc47 Merge pull request #3461 from element-hq/actions/localazy-download
Localazy Download
2025-08-21 19:09:14 +02:00
fkwp e097e58212 Translations updates 2025-08-21 15:39:08 +00:00
Timo 31892f46cd Merge pull request #3453 from robintown/reconnecting
Pause media tracks and show a message when reconnecting to MatrixRTC
2025-08-20 22:24:30 +02:00
Timo K c0dccf89cb lint
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-20 22:07:09 +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 25f04030fc Merge pull request #3336 from element-hq/robin/switch-camera-tile
Move the switch camera button to the local user's tile
2025-08-20 13:38:44 +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
fkwp 87574451a9 Doc: Use new naming of jwt auth service (#3455)
* use new naming of jwt auth service

* use new name of jwt service

* added links the https://github.com/element-hq/lk-jwt-service
2025-08-20 12:45:00 +02:00
Robin f8a051ee11 Address review feedback 2025-08-20 12:07:06 +02:00
fkwpandTimo K a0d778083d Allow multiple MatrixRTC sessions per room (#3451)
* bump js-sdk to Allow multiple rtc sessions per room (with different sessionDescriptions)

* Allow new state key string-packing format for widget mode

* bump js-sdk to latest version (with merged multi session PR)

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: Timo K <toger5@hotmail.de>
2025-08-19 16:13:56 +02:00
Robin 8de6ddceb0 Test that media tracks are paused while reconnecting to MatrixRTC 2025-08-15 20:20:00 +02:00
Robin 8b3b72dfb4 Consolidate yes/no marbles into one definition 2025-08-15 20:19:18 +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 dc789e63f2 Avoid using the deprecated 'room' field on MatrixRTCSession 2025-08-15 18:32:37 +02:00
Robin 30024877fc Test that the reaction button is visible at small screen widths 2025-08-14 17:00:56 +02:00
renovate[bot] 94085bff00 Update dependency livekit-client to v2.15.5 (#3452)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 16:47:34 +02:00
Robin aa0f3a1126 Merge branch 'robin/switch-camera-tile' into robin/reactions-small 2025-08-14 16:39:51 +02:00
Robin 0ed47c2588 Merge branch 'livekit' into robin/switch-camera-tile 2025-08-14 16:39:08 +02:00
Robin 770346676c Merge pull request #3443 from element-hq/toger5/js-to-ts
Use `.ts` for remaining js config files
2025-08-14 15:06:12 +02:00
Robin 8c1fa3fd70 Fix inaccurate copyright headers 2025-08-14 14:57:39 +02:00
Robin 217fa40ddb Only forbid using console in application code 2025-08-14 14:57:20 +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 6667fc54c0 Add a fullscreen button that uses the element request Fullscreen browser api (#3447)
* Add a fullscreen button that uses the element request Fullscreen browser api

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

* use body instead of root node

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-08 17:09:25 +02:00
Timo c0aab96968 Add intents for DM (#3445)
* Add intents for DM

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

* review

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-07 15:16:41 +02:00
Valere Fedronic 610032ad1d Merge pull request #3444 from element-hq/valere/force_jwt_service_before_start
Ensure that the jwt service is called before starting a call
2025-08-06 14:54:24 +02:00
Valere FedronicandTimo e4d14b4892 Update src/rtcSessionHelpers.ts
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2025-08-06 14:22:10 +02:00
Valere 8509efb48b review 2025-08-06 13:59:53 +02:00
Valere 6dcc44b631 comment 2025-08-06 09:26:07 +02:00
Valere fce7b6d456 refactor: move warmup to makePreferredLivekitFoci 2025-08-05 17:44:22 +02:00
Valere ef7c9a166a fix eslint 2025-08-05 15:58:46 +02:00
Valere dba8a43495 fixup test mock 2025-08-05 15:30:15 +02:00
Valere 1a3e88c19a Ensure that the the jwt service is called before starting a call 2025-08-05 15:13:04 +02:00
renovate[bot] 955c22c8dc Update dependency @vector-im/compound-design-tokens to v6 (#3438)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-05 11:34:24 +02:00
Timo K 02f9d0822f update knip.ts
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-05 09:17:50 +02:00
Timo Kandhughns e133289a7f Make convert remaining js config files to ts
Co-authored-by: hughns
Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-04 19:09:37 +02:00
ElementRobot 518039f7c3 Merge pull request #3441 from element-hq/actions/localazy-download
Localazy Download
2025-08-04 17:13:41 +01:00
fkwp f5094be194 Translations updates 2025-08-04 16:01:34 +00:00
Timo fd426191af Stop reading deprecated config options (DONT USE: membership_keep_alive_period, membership_server_side_expiry_timeout, key_rotation_on_leave_delay) (#3416)
* Stop reading deprecated config options

* add PR-Breaking-Change as one of the possible PR- prefix labels

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

---------

Signed-off-by: Timo K <toger5@hotmail.de>
2025-08-04 17:59:04 +02:00
renovate[bot] f9d87ea934 Update dependency livekit-client to v2.15.4 (#3425)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 17:56:33 +02: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
fkwp 8615d3adb0 improve web endpoint routing details (#3440) 2025-08-04 17:14:29 +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
Robin 5d992a398d Merge pull request #3437 from element-hq/fkwp/doc/self-hosting_cleanup_backend_announcement
Cleanup self-hosting guide
2025-08-01 17:47:22 +02:00
fkwp 1aa76925f7 removing nextgen_new_foci_type item from foci array since it introduces confusion 2025-08-01 15:39:58 +02:00
Robin 4888efe2f7 Merge pull request #3436 from robintown/default-timeout
Reset LiveKit connection timeouts to their defaults
2025-08-01 15:13:41 +02:00
Robin 879816ac6d Reset LiveKit connection timeouts to their defaults
I believe that the issue we were originally investigating using these increased timeouts was the fault of my earlier ISP in SW Virginia. I can't recall reproducing the exact issue on other networks.
2025-08-01 14:52:47 +02:00
Robin 6de8820590 Merge pull request #3432 from element-hq/renovate/embedded-package-dependencies
Update embedded package dependencies
2025-08-01 14:03:45 +02:00
Valere Fedronic 415f83ace5 Merge pull request #3428 from element-hq/valere/restricted_room_creation_error
Display a custom error for restricted SFU config error
2025-08-01 13:04:27 +02:00
Robin c9fb80f702 Migrate away from Sonatype repo for embedded builds
It's been shut down and we can no longer publish to it.
2025-08-01 12:38:41 +02:00
Valere 9bf63cce25 fix the test to properly fail 2025-08-01 11:58:05 +02:00
renovate[bot] 16947e7c39 Update all non-major dependencies (#3433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 11:07:01 +02:00
renovate[bot] b84c8ab82b Update embedded package dependencies 2025-08-01 02:31:35 +00:00
Valere 078c67bfb2 fix bad copy paste comment 2025-07-31 17:47:13 +02:00
Valere 81555c8d51 add a playwright test 2025-07-31 17:46:09 +02:00
Valere d294be8bd4 custom error for restricted SFU config error 2025-07-31 17:18:02 +02:00
Timo 51672599ba Patch base-x and undici to versions without known vulnerabilities (#3431)
Signed-off-by: Timo K <toger5@hotmail.de>
2025-07-31 17:16:49 +02:00
Valere Fedronic 2ade9b5c1e Merge pull request #3429 from element-hq/valere/devx/update_dev_config
DevX: update dev backend to support jwt-token v3
2025-07-31 17:15:44 +02:00
Valere b0503f41ef use latest lk-jwt-service for CI 2025-07-31 17:10:40 +02:00
fkwp d59e794bdf add alias to nginx 2025-07-31 17:05:57 +02:00
Valere b35fcf9076 DevX: update dev backend to support jwt-token v3 2025-07-31 17:05:57 +02:00
Valere Fedronic 029827488c Merge pull request #3430 from element-hq/valere/fix_snapshot
fix snapshot test following commit 007a50d
2025-07-31 17:04:51 +02:00
Valere 4ee67fa4e5 keep lk-jwt-service on 0.2.3 for now 2025-07-31 16:58:14 +02:00
Valere 446a2d4080 fix snapshot test following commit 007a50d 2025-07-31 16:37:09 +02:00
Valere 007a50d0f1 Fix missing button styling on error dialog 2025-07-31 15:00:21 +02:00
Timo c7b0f9783d expose delayed_leave_event_restart_local_timeout_ms to config.json (#3415) 2025-07-30 14:58:45 +02:00
Valere Fedronic 391ca63b7e Merge pull request #3422 from element-hq/valere/bump-js-sdk-28-07-2025
bump js-sdk version 28/07/2025
2025-07-28 17:59:56 +02:00
Valere 5dfa420135 bump js-sdk version 2025-07-28 17:45:38 +02:00
Robin ff3f727c80 Merge pull request #3418 from element-hq/robin/notification-capability
Request capability to send call notifications
2025-07-28 16:04:21 +02:00
Robin f7565ef104 Request capability to send call notifications
0e0fba6575 added the ability to send call notification events when starting a call, but I forgot to give the widget the right capabilities to do this. The effect was that notifications just wouldn't send in widget mode.
2025-07-24 18:50:03 +02:00
TimoandRobin 2f55d8e30c UrlParams: Intent system update, split into configuration and propreties (#3376)
* refactor UrlParams to use a preset intent system

* change defaults for intend headers

* add: getEnumParam to ParamParser

* remove deprecated url params

* only allow skip lobby in widget (more strict needs test adjustment)

* fix tests that now require the url to be a widget url

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

Co-authored-by: Robin <robin@robin.town>
2025-07-24 17:46:26 +02:00
Will Hunt 3145bafd5e Trim extra characters from roomId parameter in URL (#3412)
* Trim roomId when parsing from URL

* fix char

* fixup

* limit to roomId

* Add a comment
2025-07-22 20:11:53 +01:00
Robin 7dd45acd29 Update matrix-js-sdk
To include https://github.com/matrix-org/matrix-js-sdk/pull/4927.
2025-07-21 21:01:00 +02:00
Valere Fedronic 8f561c0319 bump js-sdk to matrix-js-sdk 0ce944f3daa2c8926c673af33ae24e89b1e6796a (#3414) 2025-07-21 17:46:45 +02:00
Robin 4104db3e7a Merge pull request #3411 from element-hq/renovate/major-compound
Update dependency @vector-im/compound-design-tokens to v5
2025-07-21 14:16:24 +02:00
Robin d530997725 Merge pull request #3410 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v8.2.0
2025-07-21 14:15:58 +02:00
renovate[bot] fb0fefae10 Update dependency @vector-im/compound-design-tokens to v5 2025-07-21 00:47:44 +00:00
renovate[bot] 8bb79e6f33 Update dependency @vector-im/compound-web to v8.2.0 2025-07-21 00:47:32 +00:00
RobinandTimo 0e0fba6575 Send notification events when starting a call (#3248)
* Send notification events when starting a call

Previously this has been the responsibility of the hosting application (Element Web / Element X), but I would like to move this responsibility to Element Call itself to make it even more lightweight to integrate Element Call into a widget-capable client.

* use RTCNotification event

* add url param

* bump to latest js-sdk

* remove everything decline related

* use notification type in url params

* fix url .md docs

* back to `head=develop` and using js-sdk with send notification feature

* format

---------

Co-authored-by: Timo <toger5@hotmail.de>
2025-07-18 16:58:50 +02:00
Timo 5ea0759427 Earpiece follow up: Change labels and icons (#3401)
* fix collapse icon on android

* update wording `earpiece` -> `headset`

* update icon `earpiece` -> `phone`

* i18n

* update icons to solid (top right) and non solid (overlay)

* update snapshots

* add config.json to gitignore

* add offset for earpice overlay

* update snapshots to include offset spacer
2025-07-18 15:19:53 +02:00
Valere Fedronic 7ac378037f Merge pull request #3408 from element-hq/valere/bump-js-sdk
Bump js-sdk resolved commit to the latest develop
2025-07-18 10:59:11 +02:00
Valere ff7a00ed3d Bump js-sdk resolved commit 2025-07-18 10:43:06 +02:00
Robin e4915b5bd3 Merge pull request #3346 from element-hq/robin/behaviors
Create a type-level distinction between raw Observables and Behaviors
2025-07-17 19:14:35 -04:00
renovate[bot] 38fc34667c Update LiveKit components (#3407)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-17 13:41:10 +02:00
renovate[bot] 6873ef8dd6 Update dependency livekit-client to v2.15.3 (#3406)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-17 13:40:36 +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
Robin 586a923be3 Fix remaining tests 2025-07-11 23:53:31 -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 7e81eca068 Create a Behavior type 2025-07-10 17:39:18 -04:00
Robin dbcc0e2c18 Merge pull request #3395 from element-hq/renovate/livekit-components
Update dependency @livekit/components-react to v2.9.13
2025-07-10 16:26:13 -04:00
Robin 3bdb71ee40 Merge pull request #3392 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v4.0.5
2025-07-10 16:23:19 -04:00
Robin 735d63d393 Prefer showing the reaction button at small screen widths
Rather than the 'share screen' button. Small screens are most likely to be mobile devices which wouldn't have the ability to share their screen, anyways.
2025-07-10 16:07:14 -04:00
Robin 31bb46485f Put a switch camera button on the local user's tile 2025-07-10 15:29:59 -04:00
Robin f53558cb81 Fix bug in drag handler which breaks buttons inside tiles 2025-07-10 15:29:39 -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
Valere Fedronic 2e23bbbb94 Merge pull request #3398 from element-hq/valere/enable_new_encryption_mgr
Bump js-sdk dependency to have new encryption mgr
2025-07-09 19:01:50 +02:00
Valere f0d753e58d Bump js-sdk dependency to have new encryption mgr 2025-07-09 18:47:33 +02:00
renovate[bot] aad59ea624 Update dependency livekit-client to v2.15.2 (#3396)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-09 12:46:20 +02:00
renovate[bot] 23ff26a988 Update dependency @livekit/components-react to v2.9.13 2025-07-09 10:39:41 +00:00
renovate[bot] 8c1e69f15a Update dependency @vector-im/compound-design-tokens to v4.0.5 2025-07-07 01:31:26 +00:00
renovate[bot] 01ede7629e Update all non-major dependencies (#3377)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 10:28:43 +02:00
renovate[bot] ff382ec283 Update embedded package dependencies (#3378)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-01 10:28:19 +02:00
Timo 31355ba7af Update earpiece overlay button text for clarity (#3370)
* Update earpiece overlay button text for clarity

* update test snapshots
2025-06-27 15:24:46 +02:00
renovate[bot] 1ac9630964 Update dependency livekit-client to v2.14.0 (#3371)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-27 14:14:51 +02:00
Timo db3477ea17 Increase opacity of the EarpieceOverlay background for better visibility (#3369) 2025-06-27 11:55:15 +02:00
Robin 30eea63aae Merge pull request #3337 from element-hq/robin/error-fixes
Touch up some error screens
2025-06-26 09:52:35 -04:00
fkwp 825b83dc03 reduce wait after network error timeout down to 100 ms (#3365) 2025-06-26 11:54:41 +02: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
Robin c012aec909 Merge pull request #3353 from element-hq/toger5/device-permissions-request-possible-fix
Skip unnecassary media devices permissions requests (video feed flicker when opening settings)
2025-06-25 15:56:10 -04:00
Timo d08a180c54 Simplify and improve locality of the device name request logic 2025-06-25 15:50:53 -04:00
Robin db948cb718 Merge pull request #3364 from element-hq/renovate/livekit-components
Update LiveKit components
2025-06-25 15:49:25 -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
renovate[bot] 93cb7955c9 Update LiveKit components 2025-06-25 18:41:41 +00:00
Robin 8f841dfb59 Merge pull request #3363 from element-hq/toger5/fix-initial-device-selection-in-controlled-devices-mode
Fix initial selection when using controlled media
2025-06-25 13:47:42 -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
Timo a53585c96d Fix white borders in PiP mode android (Fix scroll issues in small documents) (#3362)
* Fix scroll issues in small documents (PiP mode android)
This scroll issue resulted in white borders on android PiP mode.
2025-06-25 19:38:51 +02:00
Robin 3b1ce22b71 Fold map operation into combineLatest 2025-06-25 13:38:47 -04:00
Valere FedronicandRobin 9787ac3abc bugfix: #3344 Reconnecting to the same SFU on membership change (#3361)
* bugfix: #3344 Reconnecting to the same SFU on membership change

* fixup! commit error

* Keep useActiveLivekitFocus from changing focus spuriously

* Remove redundant fix for spurious focus changes

We've now fixed it at the source by prohibiting state changes in useActiveLivekitFocus itself.

---------

Co-authored-by: Robin <robin@robin.town>
2025-06-25 19:35:50 +02:00
Timo 131bdc3522 fix initial selection when using controlled media 2025-06-25 12:14:05 +02:00
Robin daa931c3c4 Merge pull request #3358 from element-hq/robin/remove-forward-ref
Remove usages of forwardRef
2025-06-24 08:32:03 -04:00
Robin 0f8c4675cf Make condition simpler 2025-06-24 08:28:15 -04:00
Timo 337d09cd4d Use the platform property for ios detection (#3360) 2025-06-24 14:25:05 +02:00
Timo 6b6b679774 Make camera unavailable if using earpice mode (#3351) 2025-06-24 08:59:16 +00:00
Robin 3ffb118dc7 Modernize how we use React contexts (#3359)
* Replace useContext with use

The docs recommend the use hook because it is simpler and allows itself to be called conditionally.

* Simplify our context providers

React 19 lets you omit the '.Provider' bit.
2025-06-24 10:48:35 +02:00
TimoandRobin a507bcde90 Add onBackButtonPressed controls api (#3357)
* Add `onBackButtonPressed` controls api

* Update docs/controls.md

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

---------

Co-authored-by: Robin <robin@robin.town>
2025-06-24 08:46:04 +00:00
Robin 0c27610119 Remove usages of forwardRef
It has been deprecated in React 19, which allows functional components to receive refs just like any other prop.
2025-06-23 23:06:33 -04:00
Robin f86c9fe0a0 Merge pull request #3355 from element-hq/renovate/major-compound
Update dependency @vector-im/compound-web to v8
2025-06-23 22:10:07 -04:00
renovate[bot] 3ae535bf31 Update dependency @vector-im/compound-web to v8 2025-06-23 00:39:22 +00: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
renovate[bot] 5bf7361d01 Update dependency livekit-client to v2.13.8 (#3352)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-20 10:01:31 +02:00
renovate[bot] 0fe8d16740 Update dependency @livekit/components-react to v2.9.10 (#3349)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-19 16:42:15 +02:00
renovate[bot] f1a2002072 Update dependency livekit-client to v2.13.7 (#3350)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-19 16:40:28 +02:00
renovate[bot] 1af1a8ed0b Update dependency livekit-client to v2.13.6 (#3348)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-19 13:19:31 +02:00
renovate[bot] 0970db8297 Update dependency livekit-client to v2.13.5 (#3343)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 13:59:35 +02:00
Robin a36e72147c Hide error screen icon from accessibility technologies
It does not have any meaningful accessible label to contribute beyond what is already stated in the heading.
2025-06-16 16:48:13 -04:00
Robin 7f4a5a8bab Merge pull request #3338 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v4.0.4
2025-06-16 08:50:53 -04:00
renovate[bot] 442fc1fc16 Update dependency @vector-im/compound-design-tokens to v4.0.4 2025-06-16 01:46:00 +00:00
Robin 905177f0b6 Don't present internal error messages as if they are localized 2025-06-13 00:15:25 -04:00
Robin 31c35583fb Replace technical & unlocalized error message with "Connection lost" 2025-06-13 00:15:25 -04:00
Robin 764c6fce24 Fix missing text on "Call not found" screen 2025-06-12 23:54:40 -04:00
Robin 86aa459a84 Center the heading on the error screen 2025-06-12 23:47:33 -04:00
fkwp 32b6250cc3 fix: Force the docker image for lk-jwt-service to be pulled everytime (#3325)
lk-jwt-service latest-ci to be force pulled every time
2025-06-12 16:42:06 +02:00
Timo 4a6dbf350f bump js-sdk to latest develop (containing a fix for membership manager resend join event issue) (#3333)
Signed-off-by: Timo K <toger5@hotmail.de>
2025-06-12 16:28:00 +02:00
fkwp 29968a3eba Apply new timing constants to MatrixRTC session (#3332)
Apply new timing constants
2025-06-12 14:10:54 +02:00
fkwp aa092c2195 Merge pull request #3323 from element-hq/fkwp/dev_build
Add developer build mode to GitHub action build-element-call.yaml
2025-06-11 22:56:38 +02:00
fkwp 0bf5c4a835 simplify package.json scripts and remove NODE_ENV variables since we dont use them 2025-06-11 16:54:10 +02:00
fkwp 3d47609cff Since we are now using templating anyhow we can also combine full and embedded build into one step 2025-06-10 18:17:16 +02:00
Timo 1425de8726 Expose keep alive event configurarion in ec config and update defaults. (#3303) 2025-06-10 18:09:52 +02:00
fkwp c1aa1888f0 Merge pull request #3327 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.13.4
2025-06-10 16:12:11 +02:00
fkwp 58ebbfeed7 Merge pull request #3326 from element-hq/fkwp/doc_self-hosting_update
Add tools section to self-hosting guide and adding Matrixtester to it
2025-06-10 15:59:12 +02:00
Timo 02f3f1b71a Improvements to audio renderer codebase. (#3308)
* Improvements to audio renderer codebase.

* review
2025-06-10 13:00:21 +00:00
renovate[bot] f7a6e20ae4 Update dependency livekit-client to v2.13.4 2025-06-10 12:31:41 +00:00
fkwp 378d59e948 prettier 2025-06-10 14:27:15 +02:00
fkwp a07dbe645e tools section to self-hosting guide and adding Matrixtester to it 2025-06-10 14:24:59 +02:00
Timo a596eb71a9 add onAudioPlaybackStarted callback for controls (#3309)
* add onAudioTrackReady callback for controls

* more details in controls.md for `onAudioPlaybackStarted`
2025-06-10 12:35:04 +02:00
Robin c8a1cae18b Merge pull request #2874 from element-hq/renovate/major-react-monorepo
Update react monorepo to v19 (major)
2025-06-09 11:59:26 -04:00
Robin 4f1450aaf0 Replace react-use-clipboard with copy-to-clipboard
We didn't need the complexity of the (admittedly very small) React hook, and the package hasn't declared compatibility with React 19, so let's just switch to copying things manually via copy-to-clipboard.
2025-06-09 11:53:58 -04:00
Robin 8704b44b78 Update test snapshots for React 19 changes 2025-06-09 11:48:01 -04:00
Robin 0ee11af3c5 Upgrade react-spring to v10
For React 19 compatibility.
2025-06-09 11:47:47 -04:00
Andrew Ferrazzuttiandfkwp 13fac57b01 Build Docker image on slim base (#3204)
* Build Docker image on slim base

* Run Playwright tests against Docker container

For Playwright end-to-end tests in CI, instead of running a development
webserver with `yarn dev`, build and deploy a Docker container for
Element Call and use that as the webserver to test against.

* Shut down playwright webserver gracefully

When using a containerized webserver, this stops the container once
tests finish.

* Increase Playwright timeout in CI

---------

Co-authored-by: fkwp <github-fkwp@w4ve.de>
2025-06-06 12:04:57 -04:00
Robin e0ce58b2a2 Merge pull request #3320 from element-hq/revert-3319-revert-3313-misc/migrate-to-maven-central-portal
Upgrade Android publishing to use Maven Central Portal (again)
2025-06-06 10:18:20 -04:00
fkwp 6f9adfe3e8 fix: add misssing yarn 2025-06-06 00:21:23 +02:00
fkwp d47e579994 add build_mode also to build_embedded_element_call 2025-06-06 00:20:11 +02:00
fkwp 61d8f9a412 Merge branch 'livekit' into fkwp/dev_build 2025-06-06 00:14:45 +02:00
fkwp 31185ae365 make build_mode optional 2025-06-06 00:13:49 +02:00
fkwp e07c7c864b prettier 2025-06-06 00:02:19 +02:00
fkwp b88bce5220 add production and developt build scripts to package.json 2025-06-05 23:58:51 +02:00
fkwp 775e110ca3 Add build_mode to inputs of build_full_element_call. derive build_mode from PR label 'development build' 2025-06-05 23:58:24 +02:00
fkwp 97d548ee3a add build_mode input and use it in run commands 2025-06-05 23:51:02 +02:00
Timo 34724b7a8c revert "custom compare logic" 2025-06-05 14:39:06 +02:00
Timo b005f36ac7 custom compare logic 2025-06-05 14:36:43 +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
fkwp b8eccc6d7a use vite minify depending on vite mode 2025-06-05 12:16:22 +02:00
Jorge Martin Espinosa 34df584366 Revert "Revert "Upgrade Android publishing to use Maven Central Portal"" 2025-06-05 11:20:47 +02:00
Jorge Martin Espinosa a62b0be831 Merge pull request #3319 from element-hq/revert-3313-misc/migrate-to-maven-central-portal 2025-06-05 11:20:36 +02:00
Jorge Martin Espinosa 01240fb59d Revert "Upgrade Android publishing to use Maven Central Portal" 2025-06-05 11:10:03 +02:00
Robin 7851b9c289 Merge pull request #3318 from element-hq/robin/deep-compare
Use the same function for deep equality everywhere
2025-06-04 18:12:08 -04:00
Robin 15bcaef3a5 Use the same function for deep equality everywhere 2025-06-04 17:41:42 -04:00
Timo 3c831fc5e6 Fix react errors in settings tab (#3314)
* Fix react errors in settings tab

* review
2025-06-04 23:29:49 +02:00
Robin 26efbc1389 Merge pull request #3317 from element-hq/robin/reactive-members
Always render audio from the current set of participants
2025-06-04 17:25:29 -04:00
Robin 929367c9ce Always render audio from the current set of participants
We forgot to tell React that we need the audio renderer to react to changes in the set of MatrixRTC participants; instead we had it referencing rtcSession.memberships non-reactively.

Now, I'm not 100% confident that this is going to fix the "speaking from the void" issues observed in the wild, because I can't reproduce them and, in my testing, the InCallView component always seemed to be rendered redundantly when the MatrixRTC participants change, even though we hadn't explicitly stated that it needs to react. (This makes sense as we haven't memoized the component.) But it's worth a shot.
2025-06-04 17:21:48 -04:00
TimoandRobin 2f3e0b419d Leave issue refactor (#3302)
* Simplify key local storage management.

* Refactor useLivekit to only ever connect to one room.
This change also tries to make the code more explicit so that we only do the things we really need to do and rely less on react updating everything correctly.

It also surfaces, that we are currently implementing useLivekit in a way, so that we can change the encryption system on the fly and recreate the room. I am not sure this is a case we need to support?

* simplify the useLivekit hook even more
This is possible because we concluded that we do not need to be able to hot reload the e2ee system.

* review

* linter

* Update src/room/InCallView.tsx

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

---------

Co-authored-by: Robin <robin@robin.town>
2025-06-04 20:51:13 +00:00
Robin ef41ef85eb Merge pull request #3311 from element-hq/robin/break-safari-loop
Break loop in acquiring media on Safari
2025-06-04 11:58:56 -04:00
Robin d9b91778b1 Merge pull request #3304 from element-hq/renovate/embedded-package-dependencies
Update embedded package dependencies
2025-06-04 11:56:52 -04:00
Robin 2f6bae5e5e Merge pull request #3313 from element-hq/misc/migrate-to-maven-central-portal
Upgrade Android publishing to use Maven Central Portal
2025-06-04 11:56:11 -04:00
Robin 40b351d76d Ignore spurious 'devicechange' events
This gives us the additional insurance of breaking the Safari media acquisition loop at the source by admitting that they can be spurious in practice. Safari, why!?
2025-06-04 11:23:20 -04:00
Jorge Martín 8bc914a70f Upgrade Android publishing to use Maven Central Portal
- Upgrade maven publishing plugin to `v0.32.0`.
- Change the `SonatypeHost` to point to `CENTRAL_PORTAL`.
2025-06-04 12:21:14 +02:00
Robin 83bfb721e7 Break loop in acquiring media on Safari 2025-06-03 17:22:20 -04:00
Robin 64e27152c6 Merge pull request #3307 from element-hq/renovate/livekit-components
Update dependency @livekit/components-react to v2.9.9
2025-06-03 09:40:48 -04:00
Robin f4a5ca9e84 Merge pull request #3306 from element-hq/renovate/compound
Update dependency @vector-im/compound-design-tokens to v4.0.3
2025-06-03 09:39:26 -04:00
renovate[bot] 789f37611b Update react monorepo to v19 2025-06-03 13:28:48 +00:00
Robin 931cc9ddd7 Merge pull request #3305 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2025-06-03 09:27:44 -04:00
Robin 65846dcf7d Revert eslint-plugin-matrix-org to 2.1.0
See 7eae5b0ffb.
2025-06-03 09:22:44 -04:00
renovate[bot] aa1b690b11 Update dependency @livekit/components-react to v2.9.9 2025-06-03 12:53:27 +00:00
renovate[bot] e5561dbd20 Update all non-major dependencies 2025-06-03 12:53:08 +00:00
renovate[bot] e68b403808 Update embedded package dependencies 2025-06-02 19:19:33 +00:00
renovate[bot] 85d91de2e7 Update dependency @vector-im/compound-design-tokens to v4.0.3 2025-06-02 01:32:10 +00:00
Robin 5f8a8d4c5b Merge pull request #3294 from element-hq/fkwp/docker_compose/resolve_conflicting_ports
Fix Playwright tests
2025-05-30 10:42:05 -04:00
Robin d2534748eb Merge pull request #3300 from element-hq/robin/synchronize-blocked
Run the 'Prevent blocked' check whenever a PR branch is updated
2025-05-30 10:26:10 -04:00
fkwp a548c5d592 test.skip() does only skip the test call back but not the fiturex. Hence, disabling the whole test 2025-05-30 15:03:43 +02:00
fkwp 08ab38280a prettier 2025-05-30 14:49:29 +02:00
fkwp a732fcc604 linting 2025-05-30 14:46:35 +02:00
fkwp 7e19b58976 define the widget test as a slow test 2025-05-30 14:29:17 +02:00
fkwp e56fb7cfc8 use .toBeVisible instead of continueButton.isVisible 2025-05-30 14:10:57 +02:00
fkwp aabfe16021 prettier 2025-05-30 13:51:55 +02:00
fkwp d572977922 refactor: splitout registerUser into its own function. Make the'Confirm your identity by entering your account password below.' flow optional 2025-05-30 13:38:45 +02:00
fkwp 6e0eee3509 Merge pull request #3283 from element-hq/fkwp/docker_compose_allow_local_lk_service
Add nginx upstream group of servers for JWT Service
2025-05-30 12:43:05 +02:00
Timo 87186058ab Only use ios platform logic when in controlled media device condition (#3295) 2025-05-30 12:03:22 +02:00
Robin fbafc9f3f6 Merge pull request #3301 from element-hq/renovate/npm-vite-vulnerability
Update dependency vite to v6.2.7 [SECURITY]
2025-05-28 18:20:30 -04:00
renovate[bot] 4f944ea72e Update dependency vite to v6.2.7 [SECURITY] 2025-05-28 22:14:42 +00:00
Robin 61d2da2259 Merge pull request #3036 from element-hq/renovate/major-compound
Update dependency @vector-im/compound-design-tokens to v4
2025-05-28 18:13:37 -04:00
Robin 0661486676 Merge branch 'livekit' into renovate/major-compound 2025-05-28 18:07:30 -04:00
Robin 07a4244c05 Upgrade Compound Web to v7.12.0 2025-05-28 18:04:29 -04:00
Robin 03f92ed6e4 Merge pull request #3172 from element-hq/renovate/livekit-components
Update LiveKit components
2025-05-28 17:43:07 -04:00
Robin 469ec63fec Fix LiveKit types import 2025-05-28 17:34:33 -04:00
Robin 50caca7bd3 Merge branch 'livekit' into renovate/livekit-components 2025-05-28 17:26:03 -04:00
Robin 81caa3321f Merge pull request #3186 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2025-05-28 17:22:38 -04:00
Robin 3c3fce96e7 Upgrade to OpenTelemetry v2 SDKs
Necessitated by our minor version upgrade of @opentelemetry/exporter-trace-otlp-http.
2025-05-28 17:17:31 -04:00
Robin e757f7af6b Run the 'Prevent blocked' check whenever a PR branch is updated
Because we're now requiring the 'Prevent blocked' check to pass before merging a PR, GitHub Actions now expects it to be associated with the latest Git ref of the PR's branch whenever the branch is updated. Therefore we need to re-run the workflow on the 'synchronize' event.
2025-05-28 17:00:57 -04:00
Robin 7eae5b0ffb Revert eslint-plugin-matrix-org to 2.1.0
Because the latest version requires eslint-plugin-unicorn v57, which requires eslint v9, and eslint-plugin-matrix-org is not yet compatible with eslint v9.
2025-05-28 16:25:21 -04:00
renovate[bot] d82b91ad4a Update all non-major dependencies 2025-05-28 07:09:25 +00:00
renovate[bot] 82b41ae86c Update LiveKit components 2025-05-28 07:08:55 +00:00
Timo 68396f8a83 Merge pull request #3293 from element-hq/toger5/more-disconnect-logging
Fix creating two lk rooms if there is no local store setup (fixes a resulting disconnect bug)
2025-05-28 09:01:00 +02:00
fkwp ebc714b73f force to pull the latest docker images 2025-05-27 20:06:28 +02:00
fkwp e4fd630f37 fix element web fixture 2025-05-27 19:03:53 +02:00
Timo a52b723414 code styling 2025-05-27 18:17:41 +02:00
fkwp 99fc7162e2 fix widget fixture 2025-05-27 18:04:34 +02:00
fkwp 8953936d3d fix docker compose playwright override 2025-05-27 17:53:06 +02:00
Timo a1110af6d5 Fix the actual leaving issue 2025-05-27 17:38:54 +02:00
Timo b8951944ab start with a couple of more logs 2025-05-27 17:38:45 +02:00
fkwp 16aa4ae3a9 Merge branch 'fkwp/docker_compose/resolve_conflicting_ports' into fkwp/docker_compose_allow_local_lk_service 2025-05-27 16:40:28 +02:00
fkwp d585f6232e change JWT port ot 6080 to not conflict with the playwright tests. 2025-05-27 16:30:06 +02:00
Timo b1ca464c58 Merge pull request #3292 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.13.1
2025-05-26 12:42:32 +02:00
renovate[bot] 0b8e7e9cae Update dependency livekit-client to v2.13.1 2025-05-26 03:06:25 +00:00
TimoandRobin 5374342d98 Disable device switching when in controlled audio devices mode (#3290)
* Disable device switching when in controlled audio devices mode

* Temporarily switch matrix-js-sdk to robin/embedded-no-update-state

To allow us to test this change on Element X, which does not yet support the update_state action.

* Also add a check for controlled audio devices in useAudioContext

* use develop branch

* fix tests

---------

Co-authored-by: Robin <robin@robin.town>
2025-05-23 15:54:47 +00:00
Robin 0971a15c40 Merge pull request #3270 from element-hq/robin/audio-output-controls
Audio device controls for mobile native audio device selection
2025-05-22 14:09:04 -04:00
Robin 78c59bb41c Fix formatting 2025-05-22 14:03:33 -04:00
Robin 045d861ad1 Merge branch 'livekit' into robin/audio-output-controls 2025-05-22 14:00:19 -04:00
TimoandRobin 269565d317 Update docs/url-params.md
Co-authored-by: Robin <robin@robin.town>
2025-05-22 19:28:20 +02:00
Timo f0403c80bc also add non deprecated audio url parameter 2025-05-22 19:18:04 +02:00
Robin a21da9417c Merge pull request #3285 from element-hq/robin/reset-develop
Reset to develop branch of matrix-js-sdk
2025-05-22 13:10:56 -04:00
TimoandRobin fa0b5210fe Update docs/controls.md
Co-authored-by: Robin <robin@robin.town>
2025-05-22 19:07:47 +02:00
Timo 9f84a5cae0 Deprecate old naming and introduce new words 2025-05-22 18:58:18 +02:00
Robin 821c6e3763 Reset to develop branch of matrix-js-sdk
Now that the toger5/add-room-key-fallback-on-encryption-manager-not-supported branch has been merged, we can reset to develop. (And need to, actually, because that branch is deleted.)
2025-05-22 11:59:36 -04:00
Timo 4eb867436a Merge branch 'livekit' into robin/audio-output-controls 2025-05-22 14:10:03 +02:00
Timo 323e088378 use js-sdk branch as in livekit branch 2025-05-22 14:08:35 +02:00
Timo ab9dfc75f0 Comment to explain the usage/impact of: controlledMediaDevices 2025-05-22 13:04:42 +02:00
fkwp b969857583 Allow the jwt service to be running locallay rather than part of the docker-compose. This helps with developing the lk-jwt-service 2025-05-22 12:49:37 +02:00
Robin aeae964e97 Merge pull request #3177 from element-hq/robin/reintroduce-update-state
Improve the reliability of state changes in widget mode
2025-05-21 13:09:13 -04:00
Robin e4924df8fb Reference matrix-js-sdk by branch name
Rather than by commit, which makes it hard to tell whether we're using mainline matrix-js-sdk or not.
2025-05-21 12:59:31 -04:00
fkwp cd48139fc3 Merge pull request #3279 from element-hq/af/backend-compose-fix-lk-port-cfg
Fix lk-jwt-service config in example compose file
2025-05-21 14:22:34 +02:00
Andrew Ferrazzutti 2ec4b4ee87 Fix lk-jwt-service config in example compose file
The port config name was changed in v0.2.0
2025-05-21 08:06:04 -04:00
Timo a056a28423 review 2025-05-21 12:53:17 +02:00
Robin c473d1fa8f Update matrix-widget-api to support update_state action 2025-05-20 17:54:57 -04:00
Robin 57f312494f Update matrix-js-sdk to support update_state action 2025-05-20 17:54:30 -04:00
Timo 435a7d0adb earpice -> earpiece 2025-05-20 16:37:14 +02:00
Timo a1759a46de rename everything to controlledMediaDevices to make it consistent with the actual name in the url parameters (controlledOutput is now only used for the hook that provides the output handle) 2025-05-20 15:30:02 +02:00
Timo 1cf11b91c1 Back to translated button 2025-05-20 10:17:25 +02:00
Timo 0412629871 fix start with for output devices. 2025-05-20 10:14:08 +02:00
Timo c11a37ca61 back to non translated label 2025-05-19 20:01:59 +02:00
Timo fb95ba278e make the button prettty again 2025-05-19 19:59:35 +02:00
Timo aa00a951b6 ITS A FORM NOOOOO 2025-05-19 19:56:12 +02:00
Timo 7fd7dc3794 use normal button 2025-05-19 19:52:08 +02:00
Timo ed234a1ad1 change label on button 2025-05-19 19:44:19 +02:00
Timo 8497f008c8 Bump js-sdk to support to-device fallback (#3277) 2025-05-19 19:27:08 +02:00
Timo d7e0abc55c remove the whole button on click logic 2025-05-19 19:26:50 +02:00
Timo e8c6d79a89 logger instead of native window picker 2025-05-19 19:20:26 +02:00
Timo d94feaa8db smaller diff 2025-05-19 19:08:39 +02:00
Timo 6d0697cf2f inform ios about earpice mode 2025-05-19 18:44:48 +02:00
Timo 28246ef86b Update RTCSession configuration to non deprecated names. (#3267)
* Update RTCSession configuration to non deprecated names.

* bump js-sdk

* es2024 and array buffer adaptions

* Alternative without `createKeyMaterialFromBuffer`
2025-05-19 18:04:07 +02:00
Timoandfkwp 0110465b38 Docker-compose: do not access ports <443 (#3261)
* Do not try accessing ports <1024

* adapt nginx reverse proxy for element web

---------

Co-authored-by: fkwp <github-fkwp@w4ve.de>
2025-05-19 14:18:03 +02:00
Timo 5d6ec19ca0 Allow some controls to be set before the call view is loaded. 2025-05-19 14:14:08 +02:00
Timo 956b7fc480 actually test the impl 2025-05-19 13:42:13 +02:00
Timo 2946b307c2 fix no audio thinko. 2025-05-19 13:35:21 +02:00
Timo c22e0cb7e2 better logging 2025-05-19 13:03:16 +02:00
Timo 01a2cd1410 bump livekit client (the current version has an issue on safari) 2025-05-16 19:12:18 +02:00
Timo 7f4b0a33f6 isBluetooth -> isExternalHeadset 2025-05-16 17:06:54 +02:00
Timo 35963bbc9e Add flags to optimize EC device handling 2025-05-16 15:50:19 +02:00
Timo abf683f275 Hide the input list on both, android+ios.
This will now be decided based on controlled media devices.
2025-05-16 15:23:44 +02:00
Timo acaf69ca1b add change audio button with callback on ios 2025-05-16 12:28:49 +02:00
Timo 7a4c189249 test for mute all audio 2025-05-16 11:56:07 +02:00
Timo 7227c7b368 Merge branch 'livekit' into robin/audio-output-controls 2025-05-16 11:36:33 +02:00
Timo 2012b09845 review cleanup 2025-05-16 11:32:32 +02:00
fkwp cc8ab0ac93 Merge pull request #3241 from element-hq/renovate/github-actions
Update GitHub Actions
2025-05-16 09:57:30 +02:00
renovate[bot] da2ce68348 Update GitHub Actions 2025-05-15 23:01:56 +00:00
ElementRobot 471917b16a Merge pull request #3273 from element-hq/actions/localazy-download
Localazy Download
2025-05-15 15:15:05 -05:00
fkwp f6870ae5b4 Translations updates 2025-05-15 20:10:41 +00: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 abd66f50db fix mute all audio via controls 2025-05-15 20:21:43 +02:00
Timo 610e792394 rename setOutputDevices-> setAvailableOutputDevices 2025-05-15 17:20:12 +02:00
Timo 7fa534d70d refactor
- `MediaDevice`->`MediaDeviceHandle`
 - use just one provider and switch inside the
 MediaDevicesProvider between: controlledAudioOutput, webViewAudioOutput
 - fix muteAllAudio
2025-05-15 15:34:35 +02:00
Timo c8091ac111 Quickfix for testing 2025-05-15 11:37:01 +02:00
Timo 86beaeb20f apply mute from mobile controls 2025-05-14 20:09:39 +02:00
Timo 6b39d0a5fd turn on url flag by default 2025-05-14 19:58:34 +02:00
Timo f69c75322f add earpice mode 2025-05-14 19:55:08 +02:00
Timo f9b04ae38e temp 2025-05-14 19:07:36 +02:00
Robin 53adfa4497 WIP 2025-05-14 19:07:36 +02:00
Valere FedronicandTimo 86d80630c1 Fix connection leaks: Ensure that any pending connection open are cancelled/undo when ActiveCall is unmounted (#3255)
* Better logs for connection/component lifecycle

* fix: `AudioCaptureOptions` was causing un-necessary effect render

AudioCaptureOptions was a different object but with same internal values, use directly deviceId so that Object.is works properly

* fix: Livekit openned connection leaks

* review: rename to AbortHandles

* review: rename variable

---------

Co-authored-by: Timo <toger5@hotmail.de>
2025-05-14 18:41:22 +02:00
Timo 18a59dd7db use optional audio context and effect to initiate it + review 2025-05-14 17:23:42 +02:00
renovate[bot] 4569d01353 Update dependency vite to v6.2.7 [SECURITY] (#3240)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-14 12:09:53 +02:00
Timo 6b8c620bbb Add tests 2025-05-14 10:59:23 +02:00
Timo 56328108ca 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
2025-05-14 10:41:03 +02:00
Valere FedronicandTimo 1ff2fb3fff only show to-device transport label in dev mode (#3221)
* Only show to device encryption label if developer mode on

* Add tests for developer mode to device label

---------

Co-authored-by: Timo <toger5@hotmail.de>
2025-05-13 22:22:56 +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
Timo 04bc6c77a3 developer option to mute all audio (#3239) 2025-05-13 21:11:12 +02:00
fkwp 34b3b9d733 Merge pull request #3265 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.12.0
2025-05-13 09:44:26 +02:00
fkwp 44ed04475d bump livekit protocol version 2025-05-13 09:38:43 +02:00
renovate[bot] de8a2cb533 Update dependency livekit-client to v2.12.0 2025-05-13 07:25:55 +00:00
fkwp 4344f1dd1e Merge pull request #3260 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.11.4
2025-05-13 09:23:49 +02:00
renovate[bot] 9f8dd000e0 Update embedded package dependencies (#3242)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-12 14:20:03 +02:00
renovate[bot] b681e53c35 Update dependency livekit-client to v2.11.4 2025-05-12 01:54:04 +00:00
Robin 6281628e4e Merge pull request #3258 from element-hq/robin/webcodecs-update
Remove patched version of WebCodecs types
2025-05-09 10:54:23 -04:00
Robin 9f727b904b Remove patched version of WebCodecs types
The patch has now been upstreamed to @types/dom-webcodecs.
2025-05-09 10:48:09 -04:00
Quentin Gliech 380880137e Keep the HTML lang attribute in sync with the i18next language (#3247) 2025-05-05 17:12:00 +02:00
fkwp 8828b705d9 Merge pull request #3235 from element-hq/fkwp/refactor_dev_backend
DevX: Properly server .well-known and use endpoint routing as described in self-hosting.md
2025-05-05 16:30:02 +02:00
fkwp b7e5b81dbf update yarn.lock to remove plugin-basic-ssl 2025-05-05 16:25:18 +02:00
fkwp e12dfa9a9f prettier 2025-05-05 16:17:16 +02:00
fkwp 48b4fd63fe prettier 2025-05-05 16:09:34 +02:00
fkwp f2b68e6dee add localhost domain to certificate 2025-05-05 16:02:19 +02:00
fkwp 128851263b use ssl cert from mini localhost CA 2025-05-05 16:01:58 +02:00
fkwp 679ff8c2af adapt to TLS setup 2025-05-05 15:47:03 +02:00
fkwp 9dcaa60982 added app.m.localhost for element web 2025-05-05 15:26:47 +02:00
fkwp 34a223f04b add yarn dev --host hint 2025-05-05 14:54:14 +02:00
fkwp 005402d8d1 prettier 2025-05-05 14:48:45 +02:00
fkwp 76fb16dbfd update README.md to reflect TLS settings 2025-05-05 14:44:21 +02:00
fkwp 1a3ac826b2 Merge branch 'livekit' into fkwp/refactor_dev_backend 2025-05-05 14:22:10 +02:00
fkwp 25afbf4303 base playwright backend on dev-backend 2025-05-05 14:20:51 +02:00
fkwp 9c65b40225 adapt new hostname schema and move to https URLs 2025-05-05 13:07:37 +02:00
fkwp fb63e64eb4 removed old localhost tls certificates 2025-05-05 13:06:58 +02:00
fkwp 8679b90bd7 add new certs to nginx section 2025-05-05 13:06:02 +02:00
fkwp 14ff6dce93 localhost TLS mini CA including wildcard certs for *.m.localhost 2025-05-05 13:05:07 +02:00
fkwp 08f034251c Add call.m.localhost pointing to yarn dev --host 2025-05-05 13:02:58 +02:00
fkwp 06e1a4eb1e Adapt new naming schema *.m.localhost 2025-05-05 12:57:23 +02:00
Timo aee30d8402 Fix release notes (#3244) 2025-05-02 11:49:49 +02:00
Robin a4a6a16482 Merge pull request #2812 from element-hq/toger5/track-processor-blur
Add background blur feature for supported devices
2025-04-29 22:25:02 +02:00
Robin eeb3a1a991 Add license notices to inlined type declarations 2025-04-29 22:19:00 +02:00
Robin c0c498aa04 Merge branch 'livekit' into toger5/track-processor-blur 2025-04-29 13:02:23 +02:00
Robin 9f5eae0ac1 Clean up a string 2025-04-29 13:02:02 +02:00
Robin f92c683bc1 Merge pull request #3237 from element-hq/robin/fix-playwright-invite
Fix Playwright tests in Firefox
2025-04-29 13:01:45 +02:00
Robin dfb9eb4b1f Upgrade Playwright to fix Element's unsupported browser warning 2025-04-29 12:41:23 +02:00
Robin fa0af6403e Fix Playwright tests in Firefox
As explained by the comment.
2025-04-29 12:25:35 +02:00
Robin 9df0f58117 Inline a patched version of WebCodecs types 2025-04-29 12:07:16 +02:00
Robin 0b82dcf701 Upgrade TypeScript for ImageBufferSource support 2025-04-28 18:10:58 +02:00
Robin 8f1761442b Fix tests 2025-04-28 16:37:53 +02:00
Robin 7d0117903e Don't lie about the type of the video track 2025-04-28 16:01:34 +02:00
Robin cd9035b5fc Make background blurring actually react to track restarts 2025-04-28 16:00:03 +02:00
Robin 02ce1f701a Document the background transformer a bit better 2025-04-28 15:59:32 +02:00
Robin e88e0b1901 Import the segmenter model in a more statically-analyzable way 2025-04-28 15:58:50 +02:00
Robin c91cc79162 Remove unneeded Knip override for MediaPipe 2025-04-28 15:57:29 +02:00
fkwp edd8373649 Merge pull request #3236 from element-hq/fkwp/fix_nginx_syntax_highlighting
Fix syntax highlighting of Nginx snippets
2025-04-25 18:00:03 +02:00
Robin 31032994a5 Merge branch 'livekit' into toger5/track-processor-blur 2025-04-25 17:23:20 +02:00
fkwp 984383b60d typo 2025-04-25 00:32:19 +02:00
fkwp de4875ac7c replace jsonc with nginx highlighting 2025-04-25 00:31:13 +02:00
fkwp 9416c41d62 added note about certificate exceptions 2025-04-25 00:18:27 +02:00
fkwp b61bed0197 cleanup used ports, reflect endpoint routing of JWT service and SFU websocket connection 2025-04-25 00:18:27 +02:00
fkwp 8ad1d60975 remove NOTE wrt. legacy livekit key from README.md 2025-04-25 00:18:19 +02:00
fkwp 1ae876de26 remove legacy livekit key 2025-04-25 00:18:19 +02:00
fkwp 09177b90d3 added matrix-rtc server to route jwt and sfu traffic. renamed file to dev_nginx.conf 2025-04-25 00:18:01 +02:00
Robin dc5d1369bf Merge pull request #3229 from element-hq/robin/upgrade-livekit
Return to latest livekit-client version (2.11.3)
2025-04-24 11:35:29 +02:00
Robin a6696c2304 Return to latest livekit-client version (2.11.3)
This latest release of livekit-client fixes the regression observed in https://github.com/element-hq/element-call/issues/3219.
2025-04-23 11:59:13 +02:00
Timo a1d6eef12a Set ratchetWindowSize to > 0 enable rachet compatibility. (#3224) 2025-04-23 09:22:54 +02:00
Timo 78a41c09de Fix MatrixRTC js-sdk logs in rageshakes (#3226) 2025-04-22 21:24:09 +02:00
Robin 3fc4cc908e Cleanup + use a better check for blurring support 2025-04-22 19:20:43 +02:00
Robin 63ad4a3ad3 Get blurring working again 2025-04-22 18:32:01 +02:00
Robin 7142122a74 Dedupe Mediapipe dependencies 2025-04-22 18:05:31 +02:00
Robin b7b3fde202 Upgrade LiveKit track processors 2025-04-22 18:00:41 +02:00
Robin 8fd99ed23e Merge pull request #3222 from element-hq/robin/revert-livekit
Revert livekit-client to 2.10.0
2025-04-22 17:21:45 +02:00
Robin e751248fee Revert livekit-client to 2.10.0
Closes https://github.com/element-hq/element-call/issues/3219.
2025-04-22 16:31:44 +02:00
Robin 3243afd061 Merge branch 'livekit' into toger5/track-processor-blur 2025-04-18 12:32:03 +02:00
fkwp 733279f010 Merge pull request #3215 from element-hq/fkwp/add_information_about_synapse_listeners
add information about required synapse listeners
2025-04-17 19:06:59 +02:00
fkwp a5036ee291 Merge branch 'livekit' into fkwp/add_information_about_synapse_listeners 2025-04-17 18:58:09 +02:00
fkwpandRobin 2cf2e090f6 Update docs/self-hosting.md
Co-authored-by: Robin <robin@robin.town>
2025-04-17 16:31:52 +02:00
Timo 78a88a9e0b Add a .links.temp-disabled.yaml state explicitly for when the pre-commit hook disabled the yaml file. otherwise we end up with a linked repo after every commit. (#3210) 2025-04-16 19:39:08 +02:00
fkwp 4694354f69 add informatino about required synapse listeners 2025-04-15 17:53:27 +02:00
Timo a839cde34f Add PR- label requirement action (#3171)
* Add PR- label requirement action

* also add dependencies

* review
2025-04-15 12:10:48 +02:00
Hugh Nimmo-Smith 8b63813e51 Improve tagging of Release versions of platform specific embedded packages (#3203)
* Refactor version calculation to use separate step and track version for each platform

* Set tag for NPM and SNAPSHOT for AAR appropriately

* Log output versions for each platform

* Fix tarball name

* Just use npm tag of `latest` or `other`

* Attempt to fix AAR snapshot publishing
2025-04-15 11:41:47 +02:00
Timo e63aff3e9b Bump js-sdk to develop branch (#3205) 2025-04-15 10:05:00 +02:00
Timo d5407a4fde Update developer key transport setting description (#3194) 2025-04-14 09:56:53 +02:00
fkwp b813a3c95b Merge pull request #3193 from element-hq/renovate/npm-vite-vulnerability
Update dependency vite to v6.2.6 [SECURITY]
2025-04-11 20:21:00 +02:00
fkwp 0f69ace92a Merge pull request #3187 from element-hq/toger5/packageName-to-depName
Update renovate.json
2025-04-11 20:19:13 +02:00
Hugh Nimmo-Smith f5615f2e26 Set the correct license on docker images (#3197) 2025-04-11 19:01:04 +02:00
fkwp cb64c311c5 Merge pull request #3196 from element-hq/hughns/raw-docker-version
Explicitly set docker image version for releases
2025-04-11 18:32:44 +02:00
Hugh Nimmo-Smith ee45e58903 Meh 2025-04-11 17:23:56 +01:00
Hugh Nimmo-Smith 4b247540ef value!=pattern 2025-04-11 17:16:47 +01:00
Hugh Nimmo-Smith fc281c516c Fix error
> Unrecognized named-value: 'env'. Located at position 1 within expression: env.VERSION
2025-04-11 17:12:58 +01:00
Hugh Nimmo-Smith 8858e4003a Explicitly set docker image version for releases
Otherwise we end up with inconsistency across RCs and Releases.
2025-04-11 17:08:08 +01:00
renovate[bot] 58e542e15d Update dependency vite to v6.2.6 [SECURITY] 2025-04-11 15:06:47 +00:00
Timo 770b94eb44 Add RoomAndToDeviceKeyTransport and enable as default. (#3185) 2025-04-11 17:05:57 +02:00
Andrew Ferrazzutti 8c8a5e28a0 Fix Docker image tag in release notes (#3190)
The version tag of published Docker images includes a leading "v", so
include it in release notes.
2025-04-11 08:45:55 -04:00
fkwp d0c76139a8 Merge pull request #3189 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.11.2
2025-04-11 13:52:13 +02:00
renovate[bot] 9c9d38cd95 Update dependency livekit-client to v2.11.2 2025-04-11 11:47:19 +00:00
Timo 13f12779dc default for yarn updates 2025-04-11 12:39:51 +02:00
Timo c305fb8604 use matchFileNames 2025-04-11 12:37:35 +02:00
Timo 054d6a9e48 Update renvovate.json 2025-04-11 12:26:25 +02:00
Timo 3c0d81844f Add option to enable to-device-encryption (#3167)
* enable to-device-encryption

* add logging for key provider

* make rooms encrypted

* add dev setting to choose to-device or room encryption

* add indicator when to-device is used.
2025-04-11 10:07:50 +02:00
fkwp 1702b15abe Merge pull request #3179 from element-hq/fkwp/doc_update
Update  self-hosting.md
2025-04-11 00:15:31 +02:00
fkwp e98b0ed1ed indentation 2025-04-11 00:06:03 +02:00
fkwp ba22be175d Merge pull request #3183 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.11.1
2025-04-10 21:15:27 +02:00
renovate[bot] e166f36ab5 Update dependency livekit-client to v2.11.1 2025-04-10 19:10:55 +00:00
fkwp 055f4d0193 Merge pull request #3181 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.11.0
2025-04-10 16:23:47 +02:00
renovate[bot] 7977101578 Update dependency livekit-client to v2.11.0 2025-04-10 14:09:33 +00:00
ElementRobot 5267940a8a Merge pull request #3180 from element-hq/actions/localazy-download
Localazy Download
2025-04-09 23:34:40 +02:00
fkwp cb174aeaa6 Translations updates 2025-04-09 21:30:25 +00:00
fkwp d97332f47a Merge branch 'livekit' into fkwp/doc_update 2025-04-09 20:30:24 +02:00
fkwp 6551ce8e18 Merge pull request #3178 from nordeck/fix-selfhosting-docs
Update self-hosting.md docs formatting
2025-04-09 20:30:01 +02:00
fkwp 3c5594b7e1 prettier 2025-04-09 13:34:58 +02:00
fkwp eb9593a4e5 add information about CORS headers 2025-04-09 13:16:25 +02:00
fkwp 078f36c14a add Community Guides & How-Tos section 2025-04-09 13:04:41 +02:00
Kim Brose 7297dbcc00 Update self-hosting.md docs formatting 2025-04-09 11:32:56 +02:00
fkwp ba382eef75 Merge pull request #3175 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.10.0
2025-04-08 16:45:36 +02:00
fkwp 23b1a5fff5 cleanup yarn.lock 2025-04-08 16:39:09 +02:00
fkwp 95fed3fc2d bump to 2.10.0 2025-04-08 09:52:48 +02:00
renovate[bot] 6398fd2783 Update dependency livekit-client to v2.9.9 2025-04-08 07:15:13 +00:00
fkwp e8f0398f59 Merge pull request #3165 from element-hq/fkwp/update_readme
Update readme
2025-04-08 08:52:01 +02:00
Timo a7dc289b2d Add yarn and bundled element call renovate group. (#3173) 2025-04-07 17:52:19 +02:00
fkwpandTimo db10903ea0 Update README.md
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2025-04-07 16:58:07 +02:00
fkwp ca1410bc85 hint towards cs api 2025-04-07 11:30:34 +02:00
fkwpandTimo c78360fce2 Update README.md
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2025-04-05 19:29:08 +02:00
Timo 6884b19a73 package and lock file 2025-04-05 00:01:56 +02:00
Timo 75933a508c Merge branch 'livekit' into toger5/track-processor-blur 2025-04-05 00:00:00 +02:00
Timo 2a3271b8b3 Merge branch 'livekit' into defaut-server-config 2025-04-04 23:27:45 +02:00
renovate[bot] e5358e8609 Update dependency vite to v6.2.5 [SECURITY] (#3169)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-04 23:26:09 +02:00
bc0ea20343 Default vite config to support using local build of crypto wasm (#3038)
* Devex: Default vite config to support using local build of crypto wasm

* use realpathSync and make it work with linked and not-linked
We need to use sync because an async defineConfig fails for the embedded exports.

* also allow just linking matrix-sdk-crypto-wasm (without js-sdk linking)
---------

Co-authored-by: Timo <toger5@hotmail.de>
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
Co-authored-by: Robin <robin@robin.town>
2025-04-04 23:24:42 +02:00
fkwp ab8a86e451 prettier 2025-04-04 23:12:41 +02:00
fkwp 45b0a5c2a6 reordering 2025-04-04 23:12:41 +02:00
fkwp c20aa5c1c8 rephrase Packaging and adding Figures 2025-04-04 23:12:41 +02:00
fkwp d5481d8c20 indentation 2025-04-04 23:12:41 +02:00
fkwp bef57b677c center images 2025-04-04 23:12:41 +02:00
fkwp ce1c5437fc add note about in-app calling requirements 2025-04-04 23:12:41 +02:00
fkwp 46f059947b Merge pull request #3168 from element-hq/toger5/add-link-disable-enable-scripts
Add yarn scripts for disabling/enabling `.links.yaml`
2025-04-04 15:31:00 +02:00
fkwp cf0cb2ebd2 Merge pull request #3153 from element-hq/renovate/github-actions
Pin dependencies
2025-04-04 15:28:57 +02:00
fkwp 2b35db3f39 Merge pull request #3145 from element-hq/toger5/github-release-note-categories
Add simple release note automation
2025-04-04 15:26:51 +02:00
Timo a3f01a35c8 Add yarn scripts for disabling/enabling .links.yaml 2025-04-04 12:35:21 +02:00
Timo 14b3e49de6 Use PR- labels 2025-04-04 11:34:44 +02:00
Timo 6ceaa073a9 Add simple release note automation 2025-04-04 11:34:44 +02:00
Valere Fedronic deac07dd13 Merge pull request #3163 from element-hq/valere/add_missing_to_device_permission
Widget: Add missing to device permission for encryption keys
2025-04-04 09:37:40 +02:00
Valere f0126f41fb Widget: Add missing to device permission for encryption keys 2025-04-04 09:32:34 +02:00
Valere Fedronic 8bd44344e7 Merge pull request #3164 from element-hq/toger5/fix-src-js-sdk-imports
Fix lint and playwright errors caused by matrix-js-sdk/src import
2025-04-04 09:31:24 +02:00
Valere 9b945d00f7 cleaning: Remove deprecated config option for EC url 2025-04-04 09:18:58 +02:00
Valere e9e82ca3e1 Cleaning + update docker compose pull policy for eweb 2025-04-04 09:12:27 +02:00
Timo c91d9e5790 do the setting set later 2025-04-03 18:06:38 +02:00
Timo 7561e33e38 use localhost ew 2025-04-03 18:01:43 +02:00
Timo afced3eb73 test fix experiment 2025-04-03 17:02:48 +02:00
Timo 70c97fa8be Fix lint errors caused by matrix-js-sdl/src import 2025-04-03 15:51:47 +02:00
Valere Fedronic 9acc1d1fe9 Merge pull request #3123 from element-hq/valere/playwright_widget_tests
Test: End to end integrated test for ElementCall in widget mode
2025-04-03 09:52:45 +02:00
renovate[bot] 622d91d7cc Update dependency vite to v6.2.4 [SECURITY] (#3151)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-02 11:12:25 +02:00
renovate[bot] e7086ff8fc Pin dependencies 2025-04-01 02:20:37 +00:00
ElementRobot 5f0c3435fa Merge pull request #3152 from element-hq/actions/localazy-download
Localazy Download
2025-03-31 22:36:50 +02:00
fkwp 18972c2fb9 Translations updates 2025-03-31 20:33:53 +00:00
Hugh Nimmo-Smith d1753c33f5 Use correct rageshake URL when running in embedded package + tests (#3132)
* Use correct rageshake URL when running in embedded package

It was incorrectly trying to use the one from config.json

* Refactor to add tests

* Empty mock config
2025-03-31 16:38:25 +01:00
Hugh Nimmo-SmithandJorge Martín e4c222a4e8 Expose version string in embedded SwiftPM and AAR (#3144)
* Expose version string in embedded SwiftPM and AAR

Implements https://github.com/element-hq/element-call/issues/3143

* Fix filename

* Fix location of `Version.kt`

* Use the right path for the sed replacement in the publishing workflow for Android

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
2025-03-31 14:55:20 +01:00
fkwp d12d616e28 Merge pull request #3136 from element-hq/fkwp/update_readme
Fix example JWT service .well-known endpoints in self-hosting.md
2025-03-31 15:08:57 +02:00
Timo 2073cd3ac1 Rename EULA to SSLA (#3135)
* Change EULA to SSLA
 - rename i18n fields
 - update the config property to `ssla` and deprecate `eula`
 - use `eula` instead of ssla in case it is provided in the config.

* fix default config

* completely remove eula fallback
2025-03-31 14:18:45 +02:00
Hugh Nimmo-Smith 9f2f1d8641 Improve documentation for how to use the embedded package (#3146) 2025-03-28 18:26:22 +00:00
Hugh Nimmo-Smith fd2c1f6410 Clarify who is responsible for compliance and consent in relation to analytics (#3116)
It varies depending on if you are using the full or embedded package.
2025-03-28 14:18:53 +00:00
Hugh Nimmo-Smith 1be0733011 Always run build CI workflow (#3139)
As identified in https://github.com/element-hq/element-call/pull/3116#issuecomment-2759148857 depending on the contents of a PR it may not be possible to merge due to required workflows not actually being run.

This change will mean that the build CI workflow is run irrespective of the contents.
2025-03-28 15:06:00 +01:00
Hugh Nimmo-Smith bfd4bb2ec1 Show URL params and environment variables in developer tab (#3134) 2025-03-27 16:35:31 -04:00
Robin f845397b87 Merge pull request #3093 from element-hq/toger5/src-to-lib-import
Transition from consuming js-sdk source to `lib` (build output)
2025-03-27 16:13:05 -04:00
Robin aab4efe03a Use type imports consistently 2025-03-27 16:09:59 -04:00
Robin eb18cbef78 Consolidate imports 2025-03-27 16:04:03 -04:00
Robin ae339ea5cc Fix formatting issues 2025-03-27 14:47:01 -04:00
Robin 33700d1529 Merge branch 'livekit' into toger5/src-to-lib-import 2025-03-27 14:35:08 -04:00
renovate[bot] f78b8dd153 Update dependency @vector-im/compound-design-tokens to v4 2025-03-27 18:22:52 +00:00
Robin 21140f6f2c Merge pull request #3095 from element-hq/robin/berry
Upgrade to Yarn v4 (Berry)
2025-03-27 14:21:10 -04:00
Robin 6927a92ad3 Improve comments in linker plugin 2025-03-27 14:16:16 -04:00
Robin f99eb3c88f Merge branch 'livekit' into robin/berry 2025-03-27 14:07:24 -04:00
Robin a993d8cd26 Streamline the linker hook messages 2025-03-27 14:05:10 -04:00
fkwp 53fa21b97a update .well-known example using the proposed endpoint routing 2025-03-26 22:36:47 +01:00
fkwp a4f86492f9 Merge pull request #3130 from element-hq/fkwp/update_readme
Add endpoint routing to README.md
2025-03-26 13:48:09 +01:00
fkwpandTimo 79404fcb18 Update README.md
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2025-03-26 13:20:51 +01:00
fkwpandTimo defe880515 Update README.md
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2025-03-26 13:20:27 +01:00
fkwp fa0365c409 added MatrixRTC backend for completness 2025-03-26 00:07:13 +01:00
Timo 6a5b79143e Make pre-commit message more alerting 2025-03-25 20:26:23 +01:00
Timo f868eca938 Add docs and git hooks 2025-03-25 20:13:34 +01:00
Timo 6fa218dd91 add links.disabled.yaml to yarn lock 2025-03-25 19:34:30 +01:00
fkwp 117b99d967 prettier 2025-03-25 17:14:18 +01:00
fkwp 7003e1f7d2 add section about endpoint routing 2025-03-25 17:09:54 +01:00
fkwp ae7188cd65 added endpoint routing 2025-03-25 17:09:31 +01:00
fkwp 7de7886453 indentation 2025-03-25 17:07:58 +01:00
fkwp efd08b4997 use MatrixRTC suggestion wrt. hostname and endpoints 2025-03-25 17:03:25 +01:00
Valere 0fbde40359 test: End to end integrated test for call widget 2025-03-25 16:09:38 +01:00
renovate[bot] 3ce9d71983 Update dependency vite to v6.2.3 [SECURITY] (#3125)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-25 15:53:30 +01:00
Hugh Nimmo-Smith 238bdea2b0 Fix compilation error when trying to use SwiftPM embedded package (#3124)
* Test SwiftPM build as part of release process

* Fix iOS embedded platform version as v17
2025-03-25 14:26:28 +00:00
Robin fe382cfc0b Merge pull request #3053 from element-hq/robin/posthog-logout
Enable analytics only while authenticated
2025-03-24 10:14:48 -04:00
Robin 0ed1564d3e Merge branch 'livekit' into robin/posthog-logout 2025-03-24 10:10:28 -04:00
Robin 1138a21b57 Merge pull request #3118 from element-hq/robin/errors-outside-boundary
Fix join errors mistakenly showing a generic error screen
2025-03-21 17:20:52 -04:00
Robin cd5ecb2352 Rename error boundary hook
It doesn't check whether it's actually used inside a GroupCallErrorBoundary, and it's generally useful for interacting with any error boundary, so I'm giving it a generic name to reflect this.
2025-03-21 15:17:41 -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
fkwp eaf067f0dc Merge pull request #3117 from element-hq/fkwp/remove_fallback_matrixrtc-backend_from_netlify
remove fallback MatrixRTC backend from netlify PR builds
2025-03-21 19:00:32 +01:00
fkwp 41044ce974 remove fallback MatrixRTC backend 2025-03-21 18:55:43 +01:00
Hugh Nimmo-Smith ff6365cfed One more --immutable 2025-03-21 17:19:34 +00:00
Hugh Nimmo-Smith f820506184 Fix up CI 2025-03-21 17:17:23 +00:00
Hugh Nimmo-Smith 9bf046b714 Merge branch 'livekit' into robin/berry 2025-03-21 17:14:10 +00: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
Hugh Nimmo-SmithandMichael Telatynski 7ca70cf4ab Publish embedded package for releases of Element Call (#3086)
* Publish embedded package for releases of Element Call

Part of https://github.com/element-hq/element-call/issues/2994

This PR:

- Publishes embedded builds as Tarball, NPM, AAR, SwiftPM for releases
- Publishes full builds as Tarball for releases
- Adds comments to release notes with the built artifact locations

* Update embedded/web/package.json

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>

* Update .github/workflows/publish-embedded-packages.yaml

* Update embedded/ios/Package.swift

* Apply suggestions from code review

* Try dry-run of gradlew

* Whitespace

* Fix more instances of unpinned GHA

* Minimise permissions

* Upload release notes once

To reduce concurrency

* Fix npm publish permissions

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2025-03-19 21:33:09 +00:00
Robin 246e6a6322 Merge pull request #3111 from element-hq/robin/test-ci
Move all tests into one workflow, give them clear names
2025-03-19 09:57:55 -04:00
Valere Fedronic 41132a85a7 Merge pull request #3076 from element-hq/valere/async_error_show_boundary
Error management: Handle fail to get JWT token
2025-03-19 09:41:00 +01:00
Valere b6ad6aee2a post merge fix: es lint 2025-03-19 09:33:06 +01:00
Valere fd20ac4022 Merge branch 'livekit' into valere/async_error_show_boundary 2025-03-19 09:30:16 +01:00
Valere 96ce6a2dc6 ui test: Skip video visibility test on firefox 2025-03-19 09:22:07 +01:00
Robin 4a2f44a0de Merge pull request #3112 from element-hq/robin/blocked-conflicts
Run the 'prevent blocked' workflow even if PR has conflicts
2025-03-18 15:43:21 -04:00
Robin a304f37705 Run the 'prevent blocked' workflow even if PR has conflicts
See the description of pull_request versus pull_request_target documented at https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request.
2025-03-18 14:45:07 -04:00
Robin f2ff1919cb Move all tests into one workflow, give them clear names
The Playwright tests had no name before, making it confusing to add them to the branch protection requirements.
2025-03-18 13:48:52 -04:00
Robin 7d6a60a6ad Merge pull request #3110 from element-hq/robin/participant-limits
Show "insufficient capacity" when hitting participant limits
2025-03-18 13:37:43 -04:00
Robin 45c3c7a37e Show "insufficient capacity" when hitting participant limits 2025-03-18 13:33:36 -04:00
Robin 22977dcf65 Merge pull request #3109 from element-hq/robin/livekit-2.9.1
Downgrade to livekit-client v2.9.1
2025-03-18 11:41:26 -04:00
Robin 213f234e94 Downgrade to livekit-client v2.9.1
livekit-client v2.9.2 regresses switching between the front/back cameras.
2025-03-18 11:36:08 -04:00
fkwp 990d5727d4 Merge pull request #3104 from element-hq/fkwp/update_readme
deleted old demo.jpg
2025-03-18 10:01:29 +01:00
Valere Fedronic 4653be86b3 Merge pull request #3101 from element-hq/valere/dev_ex_eslint_tests
Eslint: Ensure playwright files are checked by eslint
2025-03-18 09:57:02 +01:00
Valere 8c5f5b156c code review: improve test 2025-03-18 09:48:18 +01:00
fkwp 7a0010dd36 deleted old demo.jpg 2025-03-18 09:33:05 +01:00
Valere 6a8abeb609 Eslint: Ensure playwright files are checked by eslint 2025-03-17 15:23:51 +01:00
Valere 007ea89cd7 fixup eslint 2025-03-17 12:36:14 +01:00
Valere 598152a3d7 Add playwright test for JWT token error 2025-03-17 12:15:16 +01:00
Valere 83c6ec3497 Merge branch 'livekit' into valere/async_error_show_boundary 2025-03-17 11:26:54 +01:00
Valere 03b5f0f2f9 Fixup: error boundary context not needed, local error resets already 2025-03-17 11:26:16 +01:00
fkwp ef2fee708e Merge pull request #3099 from element-hq/fkwp/update_readme
Update readme with new Element Call screenshot
2025-03-17 10:33:23 +01:00
fkwp ef8e894c0b update Element Call screenshot 2025-03-17 09:55:04 +01:00
fkwp d01a0de568 fix JSON blob 2025-03-17 09:54:37 +01:00
Valere Fedronic a204dbe1d4 Merge pull request #3098 from element-hq/valere/playwright_dev_backend_no_ratelimit
Keep rate limits for dev backend, disable only for playwright tests
2025-03-17 09:51:30 +01:00
Valere bd38a56ccc Keep rate limits for dev backend, disable only for playwright tests 2025-03-17 09:45:43 +01:00
Valere Fedronic af58161f21 Merge pull request #3097 from element-hq/valere/playwright_initial_setup
Integration Test: Add test for register, login, logout and guest create and join call
2025-03-17 09:43:21 +01:00
Valere Fedronic ad8ad218f1 Merge pull request #3096 from element-hq/valere/playwright_access_tests
Integration Test: Add test for register, login, logout and guest create and join call
2025-03-17 09:31:44 +01:00
Robin cb14b727ba Merge branch 'livekit' into robin/berry 2025-03-14 11:59:21 -04:00
fkwp c4747dd177 Merge pull request #3026 from element-hq/fkwp/add_rc_delayed_event_mgmt_to_readme
README.md add information about rc_delayed_event_mgmt
2025-03-14 16:18:55 +01:00
Valere Fedronic 39c64afb77 Merge pull request #3091 from element-hq/valere/playwright_initial_setup
First integration tests with playwright
2025-03-14 16:02:46 +01:00
Valere b9700b9986 code review 2025-03-14 14:50:47 +01:00
Valere 20ba3e9573 Merge branch 'livekit' into valere/async_error_show_boundary 2025-03-14 11:25:30 +01:00
Valere 83198c061a Disable rate limiting on dev homeserver to avoid flaky tests 2025-03-14 11:01:25 +01:00
Valere b5fff42adc Test: Add more integrations test
Testing access, register, login, logout. Create and join as guest
2025-03-14 11:01:19 +01:00
Robin d633ec5fcd Update docs for Yarn Berry 2025-03-14 03:23:37 -04:00
Robin 0b26dc2f43 Create a plugin for linking other packages 2025-03-14 03:23:37 -04:00
Robin 31fb916b9d Enable CI to use Yarn Berry 2025-03-14 03:23:37 -04:00
Robin 95b37ea341 Upgrade to Yarn Berry 2025-03-14 03:23:37 -04:00
Robin fee9841183 Remove the dependency on buffer
It's not generally available in browser environments / certain Yarn modes and can easily be replaced by TextEncoder.
2025-03-14 02:09:48 -04:00
Timo 6f93a037cf import cleanups 2025-03-13 18:00:24 -04:00
Timo f0545ced65 make it work withotu js-sdk changes 2025-03-13 18:00:24 -04:00
Timo 46f5c44db0 temp2 2025-03-13 18:00:07 -04:00
Timo adb5934f0b temp 2025-03-13 17:51:41 -04:00
Valere 9dc515f45d Fixup: bad copy in the text 2025-03-13 20:04:26 +01:00
Valere 4c477bc4b1 fix: github action, missing config file for dev env 2025-03-13 20:04:26 +01:00
Valere 45d3a5e332 playwright add ignoreHTTPSErrors option 2025-03-13 20:04:26 +01:00
Valere 4efc32f8e2 fix: local element-call not running 2025-03-13 20:04:26 +01:00
Valere a7af470549 yml: try docker compose instead of dash compose 2025-03-13 20:04:26 +01:00
Valere 102aaa80e2 typo in playwright.yml timeout 2025-03-13 20:04:26 +01:00
Valere 6eb1a02937 fix: vitest --coverage was running playwright tests 2025-03-13 20:04:26 +01:00
Valere 687dafab3e First integration tests with playwright 2025-03-13 20:04:26 +01:00
Timo 46e7e8e9cd Fix: js-sdk version that uses expected value for isJoined (isJoined will now be false before we left as expected by EC) (#3092) 2025-03-13 19:09:18 +01:00
Hugh Nimmo-Smith a924c7ffbb Separate widget-only URL parameters in the documentation (#3088) 2025-03-13 10:28:38 +00:00
Valere 188fe75534 Merge branch 'livekit' into valere/async_error_show_boundary 2025-03-13 11:20:32 +01:00
Valere Fedronic 90a282b46c Merge pull request #3063 from element-hq/valere/fix_add_close_button_in_widget_mode
Error: use a close button instead of go to home when in widget mode
2025-03-13 10:16:26 +01:00
Valere Fedronic 79e294755c Merge pull request #3058 from element-hq/valere/refactor_error_handling
refactor: Centralize group call errors in custom GroupCallErrorBoundary
2025-03-13 10:12:11 +01:00
Hugh Nimmo-Smith 7aac56aac0 Vite embedded build of Element Call (#3077)
* Embedded package build of Element Call

Part of https://github.com/element-hq/element-call/issues/2994

This creates a new "embedded" build (vs "full" build) at the vite level. It will be used by a later PR that actually provides platform specific packages.

Embedded build:

- Uses relative URLs
- Uses relative config.json path and other resource loading
- Has a config.json built in
- Doesn't include the public folder (e.g. favicon)

Out of scope:

- this doesn't attempt to exclude SPA functionality, so technically the build could be used in SPA
- the above means that the crypto-wasm binary is included in the build

* CI artifact name based on type of build

* Update src/config/Config.ts
2025-03-12 17:00:44 +00:00
Hugh Nimmo-Smith 520c0f4925 Fix typing on config: EULA is optional as it has a default (#3074) 2025-03-12 13:52:13 +01:00
Valere b02ad8871e review: Make widget prop mandatory 2025-03-12 10:27:45 +01:00
Valere b0a4a954f8 Error: use a close button instead of go to home when in widget mode 2025-03-12 10:12:34 +01:00
Robin 5547e838d3 Merge pull request #3080 from element-hq/robin/pin-matrix-js-sdk
Pin matrix-js-sdk to a specific commit
2025-03-12 05:06:10 -04:00
Valere 612ace137a code review: recoveryActionHandler should not be optional 2025-03-12 09:44:41 +01:00
Robin 3cf0ce3dcb Pin matrix-js-sdk to a specific commit
Whenever we use a Git dependency, we should reference a specific tag or commit rather than a branch name, because Yarn Classic is bad at recognizing when a Git dependency needs to be re-installed due to it resolving to a new version. (It seems to simply use the version from package.json as a cache key.)

This is relevant only for developers who run 'yarn install' on top of a previously up-to-date working copy, not for CI which re-installs the project on every run.
2025-03-11 16:25:03 -04:00
Valere 8584521ade fixup: post rebase fix 2025-03-11 20:19:14 +01:00
Timo 93ae2aed98 New Membership Manager js-sdk develop (#3067)
* fix experimentalDecorators like we do in the js-sdk

* bump-js-sdk

* update to develop branch of js-sdk (new membership manager)
2025-03-11 19:48:02 +01:00
Valere c0ef6e5e4d fix: Error recover/retry buttons should reset error state 2025-03-11 16:54:19 +01:00
Valere 4c27551014 refactor: Centralize group call errors in custom GroupCallErrorBoundary 2025-03-11 16:54:19 +01:00
ElementRobot a97c36a335 Merge pull request #3078 from element-hq/actions/localazy-download
Localazy Download
2025-03-11 15:40:53 +00:00
fkwp 1db3e3cbc4 Translations updates 2025-03-11 15:39:33 +00:00
Hugh Nimmo-Smith 1a692b983a Use fetch() in a way that works for file URLs (#3071)
fetch returns a response code of 0 when it successfully loads a `file://` resource.

This means we can't just rely on `response.ok`.

Required for https://github.com/element-hq/element-call/issues/2994
2025-03-11 10:39:51 +01:00
Valere 04a46ebabe error management: Handle fail to get JWT token 2025-03-11 09:07:19 +01:00
fkwp f9ced9f10d typo 2025-03-10 20:58:12 +01:00
fkwp e39fe3bc7f add information about rc_delayed_event_mgmt 2025-03-10 20:55:59 +01:00
fkwp 2885e7e42e Merge pull request #3059 from element-hq/fkwp/doc_update
Refactor README.md
2025-03-10 20:31:09 +01:00
Hugh Nimmo-Smith f45aa85aef Remove default server config as it is not likely to be correct 2025-03-10 18:14:25 +00:00
Hugh Nimmo-Smith 88b862b5fd Update README.md 2025-03-10 18:10:25 +00:00
Valere 343da0db14 network: Utility to retry network operation with backoff 2025-03-10 17:54:50 +01:00
Valere c22412c045 error management: showError API for async error handling 2025-03-10 15:20:51 +01:00
Hugh Nimmo-Smith 30b5bcdfb6 Cache calls to removeHiddenChars() to fix performance bottleneck in Safari (#3066)
* Cache calls to removeHiddenChars() as very slow on Safari

Fixes #3065

* Test

* Split testing for removeHiddenChars
2025-03-10 13:55:03 +00:00
Timo b635b00b0c Expose setLKLogLevel to window for debugging. (#3064)
* Expose setLKLogLevel to window for debugging.

* fix es lint
2025-03-10 08:59:27 +00:00
750db09156 Use the New MatrixRTCSession MembershipManager (#3015)
* provide option to use the New MembershipManager

* fix cryptoApi import change

* add error screen

* bump js-sdk

* rename to `setUnrecoverableError` and remove onLeave call because that will be handled by an effect.

* this was doing nothing (it is a fragment back when there was no deprecated `rtcSession.room`)

* rename to error

* Update src/utils/errors.ts

Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>

* Update src/utils/errors.ts

Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>

* review

* bump js-sdk

* expose lk log level changing in `window`

* bump js-sdk
 - always log "Missing own membership: force re-join"
 - also check insertions queue

* change lk log level to warn

* Bump js-sdk

* Bump js-sdk

* .

* Bump js-sdk

* show user count based on meberships not users.

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

* bump js-sdk

* rename setting name

* remove unused import

* js sdk bump

* remove `window.setLKLogLevel`

* bump js sdk with reverted incompatible change

* bump js-sdk with one less merge

---------

Signed-off-by: Timo K <toger5@hotmail.de>
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-03-07 16:27:04 +00:00
Valere 13a19ed751 fix: Error recover/retry buttons should reset error state 2025-03-07 15:18:32 +01:00
TimoandHugh Nimmo-Smith 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
fkwp 1958b658c3 make colours dark theme compatible 2025-03-05 21:53:41 +01:00
fkwp 542d36f893 prettier 2025-03-05 21:43:09 +01:00
fkwp ad10b6c2fa add self-hosting section 2025-03-05 21:20:08 +01:00
fkwp c29eeff450 indentation 2025-03-05 21:19:56 +01:00
fkwp af57834c87 format Copyright & License 2025-03-05 21:19:12 +01:00
fkwp e87e1a8f25 Update documentation 2025-03-05 21:18:17 +01:00
fkwp 5583f621ba Update Development Section 2025-03-05 21:17:54 +01:00
fkwp 1df5872215 update Translation section 2025-03-05 21:16:49 +01:00
fkwp 32a3c9ea5d Add section about MatrixRTC Backend Discovery and Selection 2025-03-05 21:15:57 +01:00
fkwp 93fb299770 add self-hosting section 2025-03-05 21:13:55 +01:00
fkwp f79d7cfaea Add deployment options section 2025-03-05 21:12:23 +01:00
fkwp 1c233b88f0 add feature section 2025-03-05 21:10:45 +01:00
Valere 28c7c9dd38 refactor: Centralize group call errors in custom GroupCallErrorBoundary 2025-03-05 20:50:19 +01:00
fkwp 52b40d3116 add Overview section 2025-03-05 19:35:02 +01:00
fkwp f7379b5683 Add short description of Element Call 2025-03-05 19:34:39 +01:00
fkwp 2c21423f1a add License shield 2025-03-05 19:33:39 +01:00
Robin b5f5ab329a Merge pull request #3051 from element-hq/robin/return-to-lobby
Respect the returnToLobby flag
2025-03-05 12:17:53 -05:00
Robin 308d42980f Merge pull request #3054 from element-hq/robin/og-brand
Use the configured brand name in OpenGraph tags
2025-03-05 12:09:25 -05:00
Robin 0ca2627bd4 Merge pull request #3055 from element-hq/robin/join-action
Send a 'join' action when entering the call
2025-03-05 12:09:16 -05:00
Robin 359812d8b1 Explain why returnToLobby is false in SPA 2025-03-05 10:40:37 -05:00
Robin 5b1ea4501d Send a 'join' action when entering the call
Following a75952cf77, this is one more upgrade to the widget communication that I'd like to make within this release cycle.

The motivating issue is https://github.com/element-hq/element-web/issues/29429. Fundamentally, without a 'join' action, the only info Element Web can use to determine whether it's joined the call is whether a MatrixRTC membership exists. But membership state events can inaccurately represent the client's actual state (whether because delayed events aren't supported, or because the delayed event hasn't timed out yet), so I suggest we send a 'join' action here just as we do in the Element Web Jitsi wrapper (https://github.com/element-hq/element-web/blob/e9a3625bd6e9a64f216e3caeabca66f48b649332/src/vector/jitsi/index.ts#L503) to let Element Web tap directly into the widget's local state. (This will need additional Element Web changes, but is certainly backwards compatible.)
2025-03-05 09:25:52 -05:00
Robin ec73e7fa86 Use the configured brand name in OpenGraph tags
Overlooked some of these when reviewing https://github.com/element-hq/element-call/pull/3006.
2025-03-05 09:18:31 -05:00
Robin 65304473df Enable analytics only while authenticated
The one place where we should log out of PostHog and reset our analytics ID is when the user is logging out. This matches the behavior in Element Web and makes sense, I think, because logging out is essentially a request for the app to forget who you are. This means we should also start analytics at the point of logging in / reauthenticating.

I noticed while making this change that there was an unused branch in setClient, so I cleaned it up rather than making myself update it.
2025-03-05 09:12:18 -05:00
Robin 4919410ff0 Don't reset analytics ID when leaving calls
We shouldn't be calling PosthogAnalytics.instance.logout() when leaving the call in widget mode, because all this does is reset your analytics ID. In the big picture this is probably inflating our user count metrics.
2025-03-05 08:55:47 -05:00
fkwp c579904f29 added rule for ignoring draw.io backup files 2025-03-05 13:37:04 +01:00
Robin 28c45c6107 Avoid closing the widget in returnToLobby mode
If returnToLobby is enabled then we obviously want to keep the widget open once the user leaves the call.
2025-03-05 07:32:25 -05:00
Robin b5f5edba09 Fix the control flow of GroupCallView render function
2bb5b020e6 refactored the end of the GroupCallView render function to not use any early returns, and clumsily failed to account for the fall-through case that makes returnToLobby work (as opposed to sitting on a blank screen).
2025-03-05 07:29:56 -05:00
Robin 771397389c Prevent PRs with the X-Blocked label from being merged (#3041)
Copied from matrix-js-sdk (https://github.com/matrix-org/matrix-js-sdk/blob/develop/.github/workflows/pull_request.yaml#L31)
2025-03-05 10:44:10 +00:00
Timo 939eac5a66 change lk log level to warn (#3049) 2025-03-04 19:37:51 +01:00
Robin e783339557 Merge pull request #3035 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2025-03-04 00:14:56 -05:00
Robin 36203c2017 Work around LiveKit's overly constrained dependencies
We need compatible versions of RxJS in our dependencies and LiveKit's dependencies, but LiveKit has pinned it to a very specific version which is now holding us back from updating. See https://github.com/livekit/components-js/issues/1101 for a request for a proper solution.
2025-03-04 00:13:00 -05:00
Robin db9f255a4a Update formatting 2025-03-03 23:41:29 -05:00
Robin 6d6852d5b0 Merge pull request #3006 from Harshal-Taori-11/livekit
Added OpenGraph and Twitter meta tags for better link previews
2025-03-03 23:37:10 -05:00
Valere Fedronic f80e9452ec Merge pull request #3037 from element-hq/valere/fix_i18n_test_not_configured
Fix: i18n not properly configured in vitest
2025-03-03 17:17:53 +01:00
fkwp 815b013d53 Merge pull request #3034 from element-hq/renovate/github-actions
Update GitHub Actions
2025-03-03 17:04:57 +01:00
renovate[bot] 518f1f7bee Update all non-major dependencies 2025-03-03 15:55:00 +00:00
renovate[bot] 8aa95d1ddd Update GitHub Actions 2025-03-03 15:54:20 +00:00
Valere 4c91326edb fix, testing: i18n not properly configured 2025-03-03 14:41:31 +01:00
ElementRobot 05e81a8143 Merge pull request #3030 from element-hq/actions/localazy-download
Localazy Download
2025-02-28 13:40:30 +00:00
fkwp 4fa1b26827 Translations updates 2025-02-28 13:38:53 +00:00
Valere Fedronic 66899f33e2 Merge pull request #3027 from element-hq/valere/missing_livekit_url_config
Error Handling: gracefully handle missing MatrixRTC focus configuration
2025-02-28 13:43:01 +01:00
Valere f38adf12d9 review: remove not yet used case ErrorCategory in rich error 2025-02-28 12:25:35 +01:00
Valere 5dfc89d36c fixup: lint error 2025-02-28 12:24:43 +01:00
Valere 1fbf8e2686 review: Report unknown exceptions when entering RTC session 2025-02-28 12:17:28 +01:00
Valere 2b35573672 review: Upate error.unexpected_ec_error for consistency 2025-02-28 12:06:31 +01:00
Valere f8a5de604f review: rename ec-error file to error 2025-02-28 12:04:49 +01:00
fkwp b355615236 Merge pull request #3029 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.9.5
2025-02-28 11:58:24 +01:00
renovate[bot] 4ebbb3382a Update dependency livekit-client to v2.9.5 2025-02-28 10:56:09 +00:00
Hugh Nimmo-Smith 7761e042fb Update readme to reflect latest config.json and matrix-js-sdk dependency (#3028) 2025-02-28 10:05:36 +00:00
acc0b64968 Update config.sample.json (#3001)
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-02-27 18:25:24 +00:00
Valere 4701e413fd fixup: MissingRTCFocus error, fix confusion between domain/brand 2025-02-27 10:09:26 +01:00
Valere b43defedfd fixup: i18n incorrect ordering of keys 2025-02-27 09:32:43 +01:00
Valere 2ba803fcef review: Improve error structure + better RTCFocus error message 2025-02-27 09:26:38 +01:00
Valere 109809182f fixup: Unused (yet) ErrorCode enum value 2025-02-26 15:37:28 +01:00
Valere 3c23e5a4e6 Error Handling: gracefully handle missing livekit service url in config 2025-02-26 15:19:08 +01:00
Valere 7423dfa527 refactor: Introduce specific ElementCall error type with code 2025-02-26 14:58:31 +01:00
31577d7263 Show an error screen when the SFU is at capacity (#3022)
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
Co-authored-by: fkwp <fkwp@users.noreply.github.com>
2025-02-26 12:00:56 +00:00
RobinandHugh Nimmo-Smith 2bb5b020e6 Leave session when error occurs and show error screens in widget mode (#3021)
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
2025-02-26 10:20:30 +00:00
Robin cd05df3e33 Merge pull request #3020 from element-hq/robin/clarify-use-latest
Clarify what useLatest is for
2025-02-24 18:22:46 +07:00
Robin 9b59544db2 Clarify what useLatest is for
I was touching this file and noticed a chance to clean up this little TODO comment by swapping in our useLatest hook and giving it better documentation.
2025-02-24 18:18:15 +07:00
Robin 91671d9ff1 Merge pull request #3019 from element-hq/robin/actually-hide-header
Actually hide the header on error pages
2025-02-24 17:47:22 +07:00
Robin e4d7baf7bb Actually hide the header on error pages
Currently, if you set hideHeader to true, you get a big empty <header> on error pages which serves no purpose except to push the screen's content off center.
2025-02-24 17:37:11 +07:00
Robin 832a5aaf57 Merge pull request #3011 from element-hq/robin/close-action
Send a 'close' action when the widget is ready to close
2025-02-24 17:23:33 +07:00
fkwp 5e8395262c Merge pull request #3017 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.9.3
2025-02-24 08:28:40 +01:00
Robin 518c8eadca Finish the hangup procedure even if widget API throws errors 2025-02-24 11:48:05 +07:00
renovate[bot] ad461a7643 Update dependency livekit-client to v2.9.3 2025-02-24 02:54:51 +00:00
Robin 028b3104e4 Merge pull request #3009 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.9.1
2025-02-20 13:24:17 +07: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
Timo 4015efa6c6 fix lk usage in test 2025-02-20 06:33:01 +03:00
Harshal Taori c276af7006 Merge branch 'livekit' of https://github.com/Harshal-Taori-11/element-call into livekit 2025-02-19 14:25:05 +05:30
Harshal-Taori-11 64d33426e4 Merge branch 'element-hq:livekit' into livekit 2025-02-19 14:19:02 +05:30
Harshal Taori aafae258ac Changed the title to env variable and removed url and domain tags. 2025-02-19 14:17:33 +05:30
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
renovate[bot] f111c64264 Update dependency livekit-client to v2.9.1 2025-02-18 15:52:41 +00:00
Harshal Taori 292095abf0 Added OpenGraph and Twitter meta tags for better link previews 2025-02-13 21:29:08 +05:30
Hugh Nimmo-Smith 294e67a5ba Show current SFU and Server Info in developer tab (#3000)
* Show current SFU and Server Info in developer tab

* Lint
2025-02-10 18:22:19 +01:00
Hugh Nimmo-Smith 6e3fd10268 Explicitly build and publish docker for develop/livekit branch (#2996)
We don't need the tarball artifact and we have already done a build
2025-02-07 16:31:44 +00:00
Hugh Nimmo-Smith 0128f2f258 Don't produce compressed assets at build time and instead do it as part of the nginx build (#2995)
The core vite build shouldn't be responsible for implementing optimisations that are specific to a particular distribution mechanism. e.g. static compressed files for nginx.

This way the core build is "clean".

Instead, the packager/distributor of the build should be responsible for it. e.g. the nginx docker distribution should do any optimisations that it chooses.
2025-02-06 15:16:55 +01:00
Hugh Nimmo-Smith e23d8828ad GitHub Action workflows cannot be in a sub folder 2025-02-06 12:55:28 +00:00
Hugh Nimmo-Smith 613675553f Fix typo in license filename 2025-02-06 12:52:11 +00:00
Hugh Nimmo-Smith 6dcfdf8d39 Cleanup GitHub Actions (#2983)
This is mostly just about naming. Plus removing an unused end-to-end testing workflow.
2025-02-06 13:13:08 +01:00
Hugh Nimmo-Smith 4fc7fbe8fe Use --frozen-lockfile when install deps in CI (#2992) 2025-02-05 17:28:52 +01:00
renovate[bot] f49355a51f Update LiveKit components (#2962)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-05 16:14:04 +00:00
renovate[bot] c3ad7844fb Update dependency vitest to v3.0.5 [SECURITY] (#2986)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-05 16:07:33 +00:00
Matthew HodgsonandHugh Nimmo-Smith 1fa4a6f2e4 dual license AGPL + Commercial (#2984)
* dual license AGPL + Commercial

* Lint

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-02-05 16:01:51 +00:00
Timo e25e6caa89 Resolve version clash in matrix-widget-api dependency (#2988)
* Downgrade widget api version to v1.11.0 to not include STATE_UPDATE api version

* Downgrade to v1.10.0 for js-sdk compatibility

* Add "matrix-widget-api" to resolutions block

* bump matrix-widget-api to v1.11.0 for theme change compatibility
2025-02-05 10:11:13 +00:00
TimoandHugh Nimmo-Smith bff2b73c85 Bump matrix-js-sdk to v36.1.0 (#2967)
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-02-03 12:28:12 +00:00
Will Hunt 1dde54daa9 Use matrixIdentifier for screenshare (#2981) 2025-02-03 10:17:19 +00:00
Hugh Nimmo-Smith 1d1289b7bf Fix renovate schedule settings (#2979) 2025-01-29 18:21:08 +00:00
Hugh Nimmo-Smith 7ba7ddcdc5 Adjust renovate bot schedule and enable vulnerability updates (#2977) 2025-01-29 17:27:21 +01:00
Hugh Nimmo-Smith 31e59c1da1 Do run build action in CI when GHA workflows change (#2976) 2025-01-28 12:13:30 +01:00
Hugh Nimmo-Smith 7d444fc261 Automatically deploy livekit branch to call.element.dev via workflow dispatch (#2974) 2025-01-28 10:15:44 +00:00
renovate[bot] 26ce899548 Update dependency @stylistic/eslint-plugin to v3 (#2968)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-28 09:46:36 +01:00
renovate[bot] 06d4206524 Update dependency livekit-client to v2.8.1 (#2970)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-28 09:45:25 +01:00
renovate[bot] a16391c342 Update all non-major dependencies (#2969)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-27 13:55:46 +01:00
Will Hunt 3506ca7feb Fix calculation of local membership identifier (#2966) 2025-01-23 13:42:29 +00:00
renovate[bot] 5f78f544b7 Update all non-major dependencies (#2961)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-23 09:25:49 +01:00
renovate[bot] d862466bb0 Update dependency vite to v6.0.9 [SECURITY] (#2964)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-22 17:58:32 +00:00
Robin e636542b1e Prevent new devices from automatically starting unmuted in call (#2959) 2025-01-17 15:30:28 +00:00
Robin cda802a2e9 Make error screens more visually consistent (#2951) 2025-01-17 09:35:39 +00:00
Robin c218dc2f36 Remember previous mute states when devices disappear and reappear (#2957) 2025-01-17 09:11:17 +00:00
Robin 74d4556878 Merge pull request #2954 from element-hq/renovate/major-vitest-monorepo
Update vitest monorepo to v3 (major)
2025-01-16 15:49:34 -05:00
Robin e68593ec47 Upgrade to vitest 3.0.1 2025-01-16 15:47:53 -05:00
Robin e79a32ac63 Merge pull request #2950 from element-hq/renovate/sentry-vite-plugin-3.x
Update dependency @sentry/vite-plugin to v3
2025-01-16 15:34:45 -05:00
Will Hunt 3189bdba2a Fix displayname calculation around RTL / unhomoglyth. (#2953) 2025-01-16 17:26:58 +00:00
renovate[bot] a1eb5a9770 Update vitest monorepo to v3 2025-01-16 15:31:49 +00:00
Hugh Nimmo-SmithandTimo 723fa290ff Bump matrix-js-sdk to latest (#2946)
Co-authored-by: Timo <toger5@hotmail.de>
2025-01-16 10:31:05 -05:00
renovate[bot] d2e5514928 Update dependency @sentry/vite-plugin to v3 2025-01-15 10:37:27 +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
Hugh Nimmo-Smith d9e0c67315 Use correct Sentry entrypoints for react router v7 (#2943) 2025-01-13 16:34:44 +00:00
renovate[bot] 497ee3c7f7 Update GitHub Actions (#2945)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-13 17:07:38 +01:00
Hugh Nimmo-Smith 2f5f0978ad Type fixes for react v19 compatibility (#2937) 2025-01-13 15:54:42 +01:00
renovate[bot] c8b30dd8a7 Update dependency eslint-config-prettier to v10 (#2944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-13 15:52:11 +01:00
renovate[bot] 3d2663d740 Update dependency jsdom to v26 (#2938)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-13 12:05:26 +00:00
renovate[bot] 2206ad287e Update all non-major dependencies (#2942)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-13 12:03:57 +00:00
renovate[bot] 402d028696 Update dependency global-jsdom to v26 (#2941)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-13 12:01:51 +00:00
Robin 0f40cb77ad Merge pull request #2940 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.8.0
2025-01-10 11:43:43 -05:00
renovate[bot] df92f4814b Update dependency livekit-client to v2.8.0 2025-01-10 13:55:07 +00:00
Robin 8bfdd1f455 Merge pull request #2910 from robintown/widget-theme-change
React to theme changes in widget mode
2025-01-08 15:56:02 -05:00
renovate[bot]andHugh Nimmo-Smith d985bd3b3f Update dependency strip-ansi to v7 (#2639)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-01-08 17:17:55 +00:00
renovate[bot]andHugh Nimmo-Smith 54c669126f Update dependency eslint-plugin-matrix-org to v2 (#2677)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-01-08 17:08:28 +00:00
renovate[bot]andHugh Nimmo-Smith dc784e95cd Update dependency react-router-dom to v7 (#1624)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-01-08 16:42:07 +00:00
Robin acd4a1f179 Fix tests 2025-01-08 11:41:44 -05:00
Robin c66b8c0fd3 Merge branch 'livekit' into widget-theme-change 2025-01-08 11:27:46 -05:00
Robin cdde53cc44 Bump matrix-widget-api 2025-01-08 11:27:33 -05:00
Hugh Nimmo-Smith 00d724a3a9 Bump @livekit/track-processors to ignore empty frames 2025-01-08 14:27:19 +00:00
Hugh Nimmo-Smith 4c4d01211c Fix @matrix-org/matrix-sdk-crypto-wasm version 2025-01-08 14:20:12 +00:00
Hugh Nimmo-Smith ba2e7a7462 Merge branch 'livekit' into toger5/track-processor-blur 2025-01-08 14:08:49 +00:00
d5bf65057a Add wave/hello reaction (#2921)
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
Co-authored-by: Davide Girardi <davideg@element.io>
2025-01-08 14:05:07 +00:00
7e507d6310 Set the document title to the current call name. (#2928)
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2025-01-08 13:24:23 +00:00
renovate[bot] 00759e2431 Update all non-major dependencies (#2934)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 13:26:03 +01:00
renovate[bot] 9bfc08ab53 Update dependency vaul to v1.1.2 (#2935)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 12:13:55 +00:00
renovate[bot] 7a03adb054 Update docker/build-push-action action to v6.11.0 (#2936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 12:13:06 +00:00
renovate[bot] 50d30809ef Update codecov/codecov-action action to v5 (#2933)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 09:26:00 +00:00
renovate[bot] 123942901d Update dependency @vector-im/compound-web to v7.6.2 (#2932)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-07 17:21:30 +00:00
fkwp 9dcd7aaf50 Merge pull request #2930 from element-hq/renovate/github-actions
Update GitHub Actions
2025-01-07 16:59:07 +01:00
renovate[bot] 6420e211c6 Update GitHub Actions 2025-01-07 15:53:36 +00:00
Hugh Nimmo-Smith 8c2844e0b5 Use documented @sentry/vite-plugin config options (#2925) 2025-01-07 10:21:56 -05:00
Hugh Nimmo-Smith 939aaa39eb Remove unnecessary dependency on @testing-library/react-hooks (#2926) 2025-01-07 10:18:45 -05:00
Hugh Nimmo-Smith 38110749cd Merge branch 'livekit' into toger5/track-processor-blur 2025-01-06 17:21:30 +00:00
698a38a265 Update dependency i18next to v24 (#2822)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
2025-01-06 17:14:17 +00:00
Quentin Gliech b5f4a07868 Upgrade to React Router v6 (#2919) 2025-01-06 17:00:20 +00:00
Hugh Nimmo-Smith 96ea920e98 Try reenabling local implementation of BlurBackgroundTransformer 2025-01-06 15:53:31 +00:00
Hugh Nimmo-Smith bb0e1f38dc Exclude tasks-vision from knip 2025-01-06 15:48:43 +00:00
Hugh Nimmo-Smith 77ff3583b0 Merge branch 'livekit' into toger5/track-processor-blur 2025-01-06 14:48:54 +00:00
renovate[bot] 46a82b2c39 Update dependency @vector-im/compound-design-tokens to v3 (#2896)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-06 12:18:12 +00:00
renovate[bot] d6942bc71d Update all non-major dependencies (#2924)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-06 11:34:37 +00:00
Hugh Nimmo-SmithandTimo 2c33d65824 Add developer mode option to show RTC connection statistics (#2904)
* Add developer mode option to show RTC connection statistics

* Add note about localization

* Add titles to help explain what the numbers are

* Workaround horizontal scrolling

* Use modal to show detailed stats instead of alert

* Changed styling and fixed fps = 0 (#2916)

(React rendered 0 instead of <Text /> for fps && <Text>{fps}</text>)

---------

Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2025-01-06 09:47:39 +00:00
fkwp f521e260b6 Merge pull request #2923 from element-hq/renovate/livekit-components
Update LiveKit components
2025-01-06 10:11:15 +01:00
renovate[bot] 89e33743ae Update LiveKit components 2025-01-06 02:39:08 +00:00
renovate[bot] dc904fdbd2 Update dependency @livekit/components-react to v2.6.10 (#2920)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 14:01:44 +01:00
renovate[bot] 6776c2af35 Update Compound (#2895)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 14:00:32 +01:00
Robin e477c16a0b Fix lint errors 2025-01-02 13:32:39 -05:00
Timo e0f4bf8eab working version 2024-12-19 17:39:34 +01:00
Timo 7c985b0d9c Revert "Bump matrix-js-sdk for bundle improvements (#2911)"
This reverts commit 6b8dddfaaa.
2024-12-19 17:26:14 +01: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 6d5dc0dfb7 Fix loading of matrix-sdk-crypto-wasm when running in local development mode (#2915)
Fixes problem loading rust crypto when using `yarn dev`
2024-12-18 17:03:29 +00:00
Hugh Nimmo-Smith ba5da7e9af Inform user that their camera is starting in Lobby (#2869)
* Inform user that their camera is starting

Instead of just showing a grey box.

* Review feedback

* Show spinner from design suggestion

* useMemo

* Lint

* Lint

* Feedback from review

* Use colour that actually exists

* Refactor into Avatar superclass

* .

* Remove size limit behaviour

* Add VideoPreview tests
2024-12-18 15:31:45 +00:00
Hugh Nimmo-Smith 19d0f84f02 Introduce intent URL param and make it change the default lobby behaviour (#2828)
* Introduce `intent` URL param and make it change the default lobby behaviour

* Mark skipLobby as deprecated

* Add support for unknown intent which is default for when not specified
2024-12-18 15:30:33 +00:00
Hugh Nimmo-Smith 7983adb98e Lint 2024-12-18 09:42:52 +00:00
Hugh Nimmo-Smith 6accf088bf Merge branch 'livekit' into toger5/track-processor-blur 2024-12-18 09:41:38 +00:00
Hugh Nimmo-Smith 6b8dddfaaa Bump matrix-js-sdk for bundle improvements (#2911)
Brings in updated version of matrix-sdk-crypto-wasm which helps to reduce bundle size and lazy loading.

Full diff https://github.com/matrix-org/matrix-js-sdk/compare/d1de32ea2773df4c6f8a956678bbd19b6d022475...e4182eb75227c283a18704727021e99ced72868d
2024-12-18 09:35:42 +00:00
Robin 5d8804d7e8 React to theme changes in widget mode 2024-12-17 20:03:17 -05:00
Hugh Nimmo-Smith 53fff37d5d Use AutoDiscovery.getRawClientConfig() instead of MatrixClient.getClientWellKnown() (#2906)
I'm open to suggestions on what is sensible to test around this...
2024-12-17 17:44:50 +01:00
Hugh Nimmo-Smith 2b6acb9cce Use afterEach from vitest for consistency (#2908)
This slipped through the PR review. Whilst not harmful, for consistency we use it from vitest.
2024-12-17 11:17:37 +01: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 e4bd9d7cf9 Merge pull request #2816 from robintown/firefox-audio-output
Support selection of audio output device when using Firefox
2024-12-16 10:14:27 -05:00
Robin 65cf8bf3ee Merge pull request #2899 from robintown/array-performance
Skip some redundant updates to the grid and spotlight
2024-12-16 10:06:52 -05:00
Timo ed269e0711 Revert "Wait for .well-known/matrix/client to load before determining MatrixRTC foci" (#2902)
This reverts commit 92afd5d63a.
2024-12-16 14:12:12 +00:00
renovate[bot] b822b9f80d Update all non-major dependencies (#2900)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-16 13:44:57 +01:00
ElementRobot f1fa814fa2 Merge pull request #2898 from element-hq/actions/localazy-download
Localazy Download
2024-12-16 11:53:47 +00:00
Hugh Nimmo-Smith 92afd5d63a Wait for .well-known/matrix/client to load before determining MatrixRTC foci (#2901) 2024-12-16 11:22:23 +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
Robin f9e3fe3176 Use observables for more of the media devices logic 2024-12-13 15:37:29 -05:00
Robin de276b1fc3 Annotate the default device with a label 2024-12-13 15:22:44 -05:00
Robin 9c57720852 Merge branch 'livekit' into firefox-audio-output 2024-12-13 14:55:27 -05:00
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
robintown 31be6cc804 Translations updates 2024-12-13 14:28:28 +00:00
Robin 0c66ec5d71 Merge pull request #2894 from robintown/stable-visibility
Determine which tiles are on screen in a more stable manner
2024-12-13 09:16:49 -05:00
Hugh Nimmo-Smith 92813bd3ca Bump matrix-js-sdk (#2897)
So that we get https://github.com/matrix-org/matrix-js-sdk/pull/4575

Full diff: https://github.com/matrix-org/matrix-js-sdk/compare/edac6a9983bd604c17535a9ae673dc979c7b61c4...d1de32ea2773df4c6f8a956678bbd19b6d022475
2024-12-13 14:12:29 +00:00
Hugh Nimmo-Smith e84ecc68b3 Refactor preferences tab strings for consistency (#2888)
* Refactor preferences tab strings for consistency

* Lint
2024-12-13 13:23:32 +00:00
Hugh Nimmo-Smith 7807c44fdc Clean up useMuteStates test (#2891)
We don't need to be mocking React for this test.
2024-12-13 10:09:27 +00:00
Timo 3f48810034 bump components-js (not yet working) 2024-12-13 09:57:55 +01:00
Timo 843f081d78 Merge branch 'livekit' into toger5/track-processor-blur 2024-12-13 03:37:48 +01:00
fkwp 1cbb6dff81 Merge pull request #2855 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.7.1
2024-12-13 03:24:44 +01:00
Timo b993c5eb12 fix linter 2024-12-13 03:23:20 +01:00
Robin 53565ddb76 Test that participants adjust order when screen size changes 2024-12-12 19:16:01 -05: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
renovate[bot] 4d6740cf2c Update dependency livekit-client to v2.7.5 2024-12-12 19:40:55 +00:00
Will HuntandHugh Nimmo-Smith 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 6c81f69590 Rename developerSettingsTab to developerMode for consistency (#2889) 2024-12-11 14:30:16 +00:00
Hugh Nimmo-Smith f18ce5adf1 Format 2024-12-11 10:34:24 +00:00
Hugh Nimmo-Smith c860be73f6 . 2024-12-11 10:30:45 +00:00
Hugh Nimmo-Smith 5ead61d406 Merge branch 'livekit' into toger5/track-processor-blur 2024-12-11 10:29:49 +00:00
RobinandHugh Nimmo-Smith b834d8f679 Add some quick-and-dirty debug info for TileStore (#2887)
* Add some quick-and-dirty debug info for TileStore

I'm still in need of more detailed data in order to understand why big layout shifts happen in large calls. This adds a developer option to enable logging and a visual indicator for the state of the TileStore. The indicator should be useful for matching up the behavior I'm seeing in my recordings with the right timestamps.

* Reduce performance impact of checking for whether debug mode is enabled

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2024-12-11 10:23:42 +00:00
Hugh Nimmo-SmithandRobin 54149a496c Simplify settings tabs (#2875)
* Simplify settings tabs

- Move Analytics to Feedback tab
- Rename Developer Settings to Developer Mode and move to Preferences tab
- Clean up Preferences tab
- Only way to see version number is by enabling Developer Mode

* Remove extra label

* Lint

* Lint

* Update locales/en/app.json

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

---------

Co-authored-by: Robin <robin@robin.town>
2024-12-11 09:36:59 +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
Hugh Nimmo-Smith 8558f0349f Check for parentUrl when deciding whether a SPA specific url parameter should be ignored (#2881) 2024-12-11 09:26:55 +00:00
Hugh Nimmo-Smith 45564fd629 Ignore URL params where they are not applicable for the mode (widget vs SPA) (#2882) 2024-12-11 09:23:37 +00:00
Hugh Nimmo-Smith da63db26d6 Add missing full stops from end of settings descriptions (#2883)
For consistency
2024-12-11 09:22:12 +00:00
Robin f8f054a4f9 Merge pull request #2853 from element-hq/renovate/vite-6.x
Update dependency vite to v6
2024-12-10 13:23:52 -05:00
Robin 22678a7c71 Merge pull request #2880 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2024-12-10 13:06:36 -05:00
Robin 8b19beae68 Fix lint errors 2024-12-10 13:05:09 -05:00
renovate[bot] 69ed91d6d4 Update all non-major dependencies 2024-12-10 15:15:57 +00:00
Hugh Nimmo-Smith b6cc9c534b Lint 2024-12-09 22:12:49 +00:00
Hugh Nimmo-Smith aa5cf2f591 Wording change 2024-12-09 22:11:30 +00:00
Hugh Nimmo-Smith 18606462bb Lint 2024-12-09 22:09:26 +00:00
Hugh Nimmo-Smith 59bc73cedf Use local assets for blurring 2024-12-09 22:09:16 +00:00
Timo b77c4afff2 refactor
- still should not work without a fixing upstream LK:
https://github.com/livekit/components-js/pull/1042
https://github.com/livekit/components-js/pull/1043
2024-12-09 22:09:16 +00:00
Timo 574c89529a disable blur in local track again 2024-12-09 22:08:51 +00:00
Timo c6d48446f4 review 2024-12-09 22:08:51 +00:00
Timo 95c3ca8859 review 2024-12-09 22:08:51 +00:00
Timo d179db1e8f more detailed error message 2024-12-09 22:08:51 +00:00
Timo 9eae919050 make default false 2024-12-09 22:08:51 +00:00
Timo 7d8e9a7969 fixes and gpu based blurring 2024-12-09 22:08:51 +00:00
Timo c2b6518027 dont update if processor already set 2024-12-09 22:08:51 +00:00
Timo a6745ef34a properly add @livekit/track-processors 2024-12-09 22:08:51 +00:00
Timo ae71c6e679 add @types/dom-mediacapture-transform for the remaining type errors 2024-12-09 22:08:51 +00:00
Timo aade8f94a6 eslint + prettier 2024-12-09 22:08:51 +00:00
Timo 0be312a5e3 i18n 2024-12-09 22:08:51 +00:00
Timo 95bc7db28a update blur checkbox (disabled state) 2024-12-09 22:08:51 +00:00
Timo d23beefb60 remove unused dependencies. 2024-12-09 22:08:51 +00:00
Timo 70ff435a8c add types 2024-12-09 22:08:51 +00:00
Timo 140fe484d7 make compatible with unsopported browsers 2024-12-09 22:08:51 +00:00
Timo c798c79f41 Add background Blur 2024-12-09 22:08:51 +00:00
Hugh Nimmo-Smith d698705ffa Configure sentry integration for netlify PR previews (#2884) 2024-12-09 14:01:06 +00:00
Will HuntandHugh Nimmo-Smith 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
Will HuntandHugh Nimmo-Smith 9d4cd211ed Authenticate media requests when loading avatars (#2856)
* Load authenicated media

* lint

* Add tests

* Add widget behaviour and test.

* Update src/Avatar.test.tsx

Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>

---------

Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
2024-12-06 18:30:05 +00:00
Hugh Nimmo-Smith 4fab1a25b4 Use specific Node.js version (22) instead of latest LTS (#2879)
This way we can manage the upgrade cycle ourselves.
2024-12-06 18:15:49 +00:00
ElementRobot 2fe199de71 Merge pull request #2877 from element-hq/actions/localazy-download
Localazy Download
2024-12-06 15:13:50 +00:00
fkwp 65cc583c8a Translations updates 2024-12-06 15:04:29 +00:00
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
Hugh Nimmo-Smith 21b62dbd89 Use a consistent background colour for video tiles and avatars (#2868) 2024-12-05 13:26:31 +00:00
fkwp d09efa3cfe Merge pull request #2872 from element-hq/renovate/github-actions
Update GitHub Actions
2024-12-05 12:34:55 +01:00
renovate[bot] 818abaac0f Update GitHub Actions 2024-12-05 11:32:31 +00:00
renovate[bot] 76ba02584d Update dependency vaul to v1.1.1 (#2656)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-05 12:10:35 +01:00
Hugh Nimmo-Smith 27620b9148 Rename en-GB language to en (#2866)
Fixes https://github.com/element-hq/element-call/issues/2865

If we want to have GB and US specific terms later on we can then add then in as `en-GB` and `en-US`.
2024-12-04 14:51:29 +00:00
fkwp 68867810f7 Merge pull request #2864 from element-hq/fkwp/update_README_state_after
add information about MSC4222 state_after
2024-12-03 17:23:35 +01:00
fkwp 3495f5b472 linting 2024-12-03 16:57:53 +01:00
fkwp 260a1df21b linting 2024-12-03 16:55:30 +01:00
fkwp 44e5d2ea91 add MSC4222 2024-12-03 16:54:37 +01:00
fkwp 5e449bd03f typo 2024-12-03 16:54:28 +01:00
fkwp cf0bb4676a add information about MSC4222 state_after 2024-12-03 16:51:14 +01:00
renovate[bot] 97fd1f3696 Update dependency @vector-im/compound-design-tokens to v2 (#2671)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-03 10:08:01 +01:00
renovate[bot] f4883ac098 Update dependency @types/node to v22 (#2695)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-03 10:07:31 +01:00
Will Hunt cc260811e2 Add a lower limit to duplicate tiles. (#2854)
* Add a limit to duplicate tiles.

* missed a change
2024-12-02 17:15:33 +00:00
Hugh Nimmo-Smith a37c3bfb48 Show hostname in developer settings (#2857)
Also refactored developer settings labels into own locale section
2024-12-02 15:43:19 +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
renovate[bot] cc58e4d429 Update dependency vite to v6 2024-12-02 11:11:39 +00:00
renovate[bot]andTimo e142493380 Update all non-major dependencies (#2852)
* Update all non-major dependencies

* prettier

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Timo <toger5@hotmail.de>
2024-12-02 12:10:20 +01:00
fkwp 34cc50b84d Merge pull request #2851 from element-hq/toger5/light-raise-hand
Use light background
2024-11-29 18:22:38 +01:00
Timo 84b2dc8680 Use light background
- the icons and the font is dark so the bg should not be darkened. But making it lighter is making it easier to read.
2024-11-29 17:48:18 +01:00
Timo e12f4fada0 Bump js-sdk (#2850)
-  This fixes, that clients dont resend keys if other join right after someone else just left.
2024-11-29 11:58:36 +01:00
fkwp 8cd681c6cc Merge pull request #2849 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.7.0
2024-11-29 11:51:05 +01:00
renovate[bot] 82360c674c Update dependency livekit-client to v2.7.0 2024-11-29 10:44:54 +00:00
Hugh Nimmo-Smith 32ccfe8813 Fix Cache-Control header for docker images (#2847) 2024-11-28 17:40:06 +00:00
Timo 65e962bf1b Fix wrong hand raise margins in pip tile. (#2840) 2024-11-28 17:24:24 +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 f7c7f41afd Upgrade js-sdk to develop with MSC4222 state_after support (#2841)
Diff https://github.com/matrix-org/matrix-js-sdk/compare/2210255d6ffc909c574fb8ef16f92140b2fb7797...8fc77c595aa651db9f402df798b868ed076590e3
2024-11-27 20:43:56 +00:00
Hugh Nimmo-Smith cf174261c9 Some simple initial tests for MediaView (#2813)
* Some simple tests for MediaView

* Use jest-dom assertions

* Add tests for videoMuted

* Add test case for placeholder video track

* Revert yarn.lock changes

* More revert

* Deduplicate test case logic and improve names

* Use role and label
2024-11-25 20:22:02 +00:00
renovate[bot] e36029c9c0 Update all non-major dependencies (#2835)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-25 18:46:30 +01:00
Hugh Nimmo-Smith 0469d8ef56 Add explicit code split on matrix-sdk-crypto-wasm to allow caching between deploys (#2823)
* Add explicit code split on matrix-sdk-crypto-wasm to allow caching between deploys

* Comment on removing once https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/167 lands
2024-11-23 09:00:43 +00:00
Hugh Nimmo-Smith fc8da6ef58 Use hot marbles for speaker tests (#2815)
* Refactor the speaker detection logic into observeSpeaker and add tests

@robintown the tests pass, but some of the values were off by 1ms from what I was expecting. Please can you sanity check them?

* Extra test cases and clean up

* Make distinctUntilChanged part of the observable itself

* More suggestions from code review

* Use hot marbles for speaker tests

This was originally part of https://github.com/element-hq/element-call/pull/2810

* Only feed speaking mocks to observables that ask for IsSpeakingChanged
2024-11-23 08:59:33 +00:00
Hugh Nimmo-Smith 4e1b4fae19 Refactor the speaker detection logic into observeSpeaker and add tests (#2814)
* Refactor the speaker detection logic into observeSpeaker and add tests

@robintown the tests pass, but some of the values were off by 1ms from what I was expecting. Please can you sanity check them?

* Extra test cases and clean up

* Make distinctUntilChanged part of the observable itself

* More suggestions from code review
2024-11-23 08:59:15 +00:00
Hugh Nimmo-Smith 5c18868aa4 The preload URL param shouldn't be used in SPA mode, so ignore it if not in widget (#2832)
* Refactor URL parameters into table

This is for readability and ahead of some possible changes

* Whitespace

* Lint

* The preload URL param shouldn't be used in SPA mode, so ignore it
2024-11-23 08:55:03 +00:00
Hugh Nimmo-Smith 9ce16b68e9 Refactor URL parameters into table (#2827)
* Refactor URL parameters into table

This is for readability and ahead of some possible changes

* Whitespace

* Lint

* Cleanup and correct fontScale
2024-11-23 08:51:27 +00:00
Robin ad9114a6e4 Merge pull request #2833 from robintown/depluralize
Fix a singular string using the plural form
2024-11-22 13:58:12 -05:00
Robin 44e1c136df Fix a singular string using the plural form 2024-11-22 13:45:39 -05:00
Robin 1bbbd519c7 Merge pull request #2831 from robintown/shortcut-modifiers
Don't trigger keyboard shortcuts if modifiers are held
2024-11-22 13:25:24 -05:00
Robin 51e4a3b14b Don't trigger keyboard shortcuts if modifiers are held
None of these keyboard shortcuts expect modifier keys, so they should in fact expect the absence of modifiers.
2024-11-22 13:17:05 -05:00
Hugh Nimmo-Smith 8da38d173a Remove .well-known files from build process (#2830)
These don't get included in the docker images anyhow (due to them being excluded by defautl by https://github.com/actions/upload-artifact#uploading-hidden-files).

We need to inject the right values into our managed deployments elsewhere.
2024-11-22 18:12:29 +00:00
Robin 13887a8943 Merge pull request #2817 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v7.4.0
2024-11-22 09:31:35 -05:00
fkwp 03721f078b Merge pull request #2819 from element-hq/renovate/livekit-components
Update dependency @livekit/components-react to v2.6.9
2024-11-22 12:43:25 +01:00
renovate[bot] d146bedf05 Update dependency @livekit/components-react to v2.6.9 2024-11-22 11:08:25 +00:00
fkwp 63f595f958 Merge pull request #2820 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.6.3
2024-11-22 12:07:10 +01:00
renovate[bot] 279912d951 Update dependency livekit-client to v2.6.3 2024-11-22 09:14:56 +00:00
renovate[bot] 94e5d032a1 Update dependency @vector-im/compound-web to v7.4.0 2024-11-22 02:01:23 +00:00
Robin f249b7d463 Create a virtual default audio output
Managing your audio output manually is kind of cumbersome; Chrome creates a default audio output for us, but now that audio outputs are enabled on Firefox as well, I find it necessary for a good user experience that there always be a way to set it to "whatever the default is".
2024-11-21 14:43:30 -05:00
Robin e5117b962c Enable audio output support on Firefox 2024-11-21 12:53:27 -05:00
Robin 720c400e5f Merge pull request #2802 from robintown/device-fall-back
Don't fall back as eagerly to unselected devices
2024-11-21 11:39:10 -05:00
Robin 0718774cef Clarify how preferred devices work 2024-11-21 11:32:15 -05:00
Robin a2b452c1d8 Don't override the camera without pressing "switch camera" 2024-11-21 11:24:45 -05:00
Robin 465a784345 Merge branch 'livekit' into device-fall-back 2024-11-21 11:04:36 -05:00
Robin 8de96878c0 Merge pull request #2803 from robintown/device-radio
Replace device dropdowns with radio buttons
2024-11-21 10:47:44 -05:00
Hugh Nimmo-Smith b7b9771577 Use hot test input marbles instead of cold (#2810)
* Use hot test input marbles instead of cold

These will be needed for https://github.com/element-hq/element-call/pull/2701

* Revert for "spotlight speakers swap places" test
2024-11-21 11:03:16 +00: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 9176e06195 Some tsdoc and explicit typing (#2809)
* Some tsdoc and explicit typing

Pulled out of https://github.com/element-hq/element-call/pull/2701

* Extra typing
2024-11-21 11:01:43 +00:00
Robin 380fa67f57 Merge pull request #2811 from robintown/revert-memory-store
Revert memory store and update matrix-js-sdk
2024-11-20 10:42:41 -05:00
Robin 8830bd74cb Update matrix-js-sdk
Return matrix-js-sdk to the develop branch.
2024-11-20 10:40:08 -05:00
Robin 3ab9bb72e2 Revert "Init client with a memory store (for MSC4222) (#2764)"
This reverts commit 83fa9661cf. We won't need this hack once we're no longer using a matrix-js-sdk branch with MSC4222 support.
2024-11-20 10:22:42 -05:00
Robin 38085baab8 Replace device dropdowns with radio buttons
This is closer to what the designs actually want device settings to look like, and it avoids the visual glitch in which the dropdown would render underneath the slider.
2024-11-20 09:44:32 -05:00
Hugh Nimmo-Smith 8891a9a70e Make it clearer what are inputs and what are expected outputs in test cases (#2808)
Rationale: try and make the marbles section of each test case more readable
2024-11-20 14:44:23 +00:00
Hugh Nimmo-Smith 826d0ee40d Rxjs subjects should not be exposed (#2805)
This rule will encourage us to do the right thing and better abstract.

See https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-exposed-subjects.md
2024-11-20 10:32:21 +00:00
Hugh Nimmo-Smith fbc2cd3e97 Remove redundant distinctUntilChanged (#2804)
Because this.scope.state() does this for us
2024-11-20 10:31:36 +00:00
Robin 770730ba6c Don't fall back as eagerly to unselected devices
Somewhere around version 131 or 132, Firefox has started being more paranoid about media device fingerprinting, and will not even give you the IDs of available devices until you've requested a media stream. Instead you only get a single audio input and video input each with the empty string as their device ID, representing the system's default device. We can recognize this case and avoid resetting the device selection.
2024-11-19 13:26:40 -05:00
Will Hunt b3ceb5300c Add keyboard shortcuts for raised hand / reactions (#2784)
* Add support for reactions / raised-hands via keyboard shortcuts.

* Add tests

* Fixup shortcuts

* update snapshotr

* fix type

* keyshortcuts

* remove mistakenly commited file

* fix label logic

* Add renderer for call joined / left

* Use caption

* lint

* remove unexpected file

* remove other unexpected change

* Remove other other unexpected change.
2024-11-19 16:57:57 +00:00
ElementRobot ffbc48fe86 Merge pull request #2801 from element-hq/actions/localazy-download
Localazy Download
2024-11-19 16:00:11 +00:00
fkwp 4655da3c35 Translations updates 2024-11-19 15:58:53 +00:00
Robin 585998cb87 Merge pull request #2800 from robintown/reactions-button
Update icon and label of reactions button
2024-11-19 10:44:58 -05:00
Robin 8ec2f9bb31 Update tests 2024-11-19 10:43:42 -05:00
Robin 2ee468ba44 Update icon and label of reactions button
They've been updated in the designs.
2024-11-19 09:56:46 -05:00
fkwp 17eb435a7a Merge pull request #2799 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.6.2
2024-11-19 15:55:19 +01:00
renovate[bot] 1678ca71c1 Update dependency livekit-client to v2.6.2 2024-11-19 14:53:23 +00:00
Robin 90fe8e0529 Merge pull request #2734 from element-hq/renovate/compound
Update Compound
2024-11-19 09:48:17 -05:00
Hugh Nimmo-Smith 64749d0b7a Expose TestScheduler as global (#2796) 2024-11-18 22:39:59 +00:00
fkwp 79cd3047e9 Merge pull request #2798 from element-hq/renovate/livekit-components
Update dependency @livekit/components-react to v2.6.8
2024-11-18 20:40:30 +01:00
renovate[bot] 9078c35e06 Update dependency @livekit/components-react to v2.6.8 2024-11-18 19:39:01 +00:00
renovate[bot] 2833d9a816 Update Compound 2024-11-18 19:37:15 +00:00
fkwp 8598be1d92 Merge pull request #2797 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.6.1
2024-11-18 20:36:18 +01:00
renovate[bot] 02d2de3831 Update dependency livekit-client to v2.6.1 2024-11-18 19:34:22 +00:00
fkwp 6d1aa0087b Merge pull request #2729 from element-hq/renovate/migrate-config
Migrate renovate config
2024-11-18 13:17:07 +01:00
renovate[bot] 8b4b9f4494 Update all non-major dependencies (#2795)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-18 10:09:21 +01:00
Timo a551cde47b Make reactions background use the frosted glass look (#2792)
* Make reactions background use the frosted glass look

* fix spacing if there is raise hand + reaction.
2024-11-15 18:58:40 +01:00
ElementRobot 01b9d7a70e Merge pull request #2793 from element-hq/actions/localazy-download
Localazy Download
2024-11-15 16:23:56 +00:00
fkwp f56d4a32a3 Translations updates 2024-11-15 16:22:27 +00:00
Will Hunt eed1b98cf9 Update reactions to new design (#2751)
* Replace search strings

* Add expander for reactions view

* lint

* Remove useless list

* Update tests

* lint

* Only shrink buttons on web version, mobile never shrinks

* Revert accidental change.

* Remove border from button

* Tidy up views.

* Finish matching designs.

* Fix height

* Remove a unneeded class

* Remove more cruft

* Remove unnessacery chunk

* Evenly space reactions

* lint

* Disable reaction buttons when busy

* Try to make menu a bit more responsive

* Update test

* further screen size tweaks
2024-11-15 16:02:06 +00:00
Will Hunt c1208ac7b6 Small improvements to settings tab (#2789)
* align profile tab.

* Fix descriptions
2024-11-15 14:09:52 +00:00
Quentin Gliech d77e9e8f08 Merge pull request #2790 from element-hq/quenting/preload-config
Pre-fetch the config.json to improve startup time
2024-11-15 13:55:41 +01:00
Quentin Gliech 2e172aa3be Pre-fetch the config.json to improve startup time 2024-11-15 13:36:36 +01:00
fkwp 9650ca9687 Merge pull request #2787 from element-hq/quenting/docker-vary-encoding
Send 'Vary: Content-Encoding' header from nginx
2024-11-15 09:22:25 +01:00
Quentin Gliech f7e4b79502 Send 'Vary: Content-Encoding' header from nginx 2024-11-15 09:19:45 +01:00
fkwp 20840d901e Merge pull request #2786 from element-hq/quenting/docker-cache-headers
Precompress assets and set the right cache headers
2024-11-15 08:52:12 +01:00
Quentin Gliech 4c1c818ba9 Merge pull request #2776 from element-hq/quenting/locales-as-assets
Handle locales as Vite assets
2024-11-15 08:41:56 +01:00
Quentin Gliech f022eb09a2 Precompress assets and set the right cache headers 2024-11-15 00:59:26 +01:00
Hugh Nimmo-Smith 50934a53cd Lazy load matrix-js-sdk when running as SPA (#2785) 2024-11-14 21:54:02 +00:00
Quentin Gliech 99d5886e32 Handles locales as Vite assets 2024-11-14 19:12:11 +01:00
Quentin Gliech 137a53dbee Load the Intl.Segmenter and Intl.DurationFormat polyfills only if needed (#2778)
* Load the Intl.Segmenter polyfill only if needed

* Also polyfill Intl.DurationFormat only if needed

* Polyfill Intl.* in tests

* Load the default translations in tests

* Instanciate the Intl.DurationFormat in the component
2024-11-14 18:06:38 +00:00
Hugh Nimmo-Smith 6e5c468780 Use more explicit names and types for LayoutMedia observables (#2781) 2024-11-14 14:23:50 +01:00
Quentin Gliech 1478dbe6a1 Sync the Vaul version with the one used by Compound (#2783) 2024-11-14 13:11:17 +00:00
Quentin Gliech 85d8e036d5 Lazy-load pako when submitting rageshake (#2782) 2024-11-14 13:00:01 +00:00
ElementRobot 84e172a2ba Merge pull request #2779 from element-hq/actions/localazy-download
Localazy Download
2024-11-14 11:42:36 +00:00
fkwp 7fddad02e0 Translations updates 2024-11-14 11:40:09 +00:00
Quentin Gliech 3b3f7762a7 Use optimized font from fontsource (#2775) 2024-11-14 11:23:09 +00:00
Quentin Gliech 2297675b06 Replace lodash with lodash-es (#2777) 2024-11-14 11:18:43 +00:00
Quentin Gliech 8f4b932c3c Enable Codecov bundle analysis plugin (#2774) 2024-11-14 10:07:21 +00:00
Robin 88782a0332 Merge pull request #2772 from robintown/local-mute-icon
Show a different icon for participants that you've muted
2024-11-13 13:34:39 -05:00
Robin 9eae1f4145 Show a different icon for participants that you've muted
As a non-intrusive way to help you remember when you've locally muted a participant (so you're less likely to be confused about not hearing their audio), we can show a different icon on the tile.
2024-11-13 11:10:26 -05:00
Will Hunt 3d096426be Quieten rock sound effect. (#2768) 2024-11-12 15:59:58 +00:00
Will HuntandRobin 83fa9661cf Init client with a memory store (for MSC4222) (#2764)
* Bump matrix-js-sdk for MSC4222 support

* Init client with a memory store.

---------

Co-authored-by: Robin <robin@robin.town>
2024-11-12 12:27:49 +00:00
Robin 6c24763196 Merge pull request #2759 from robintown/msc4222
Bump matrix-js-sdk for MSC4222 support
2024-11-12 07:22:49 -05:00
Will Hunt c4c266536b Sound effect volume adjustment & tooltip (#2762)
* Set the default sound effect volume to 50%.

* Add a tooltip to describe the current volume level.

* lint import
2024-11-12 10:18:45 +00:00
ElementRobot 3535cbe2e6 Merge pull request #2763 from element-hq/actions/localazy-download
Localazy Download
2024-11-12 09:29:50 +00:00
fkwp dac89b97ae Translations updates 2024-11-12 09:28:30 +00:00
Robin 854e0ab7ae Decrypt potential reaction events before checking their type (#2761)
By rights, this fix I had made to decrypt reaction events shouldn't have appeared successful, because I was requiring the event to have a certain type before asking matrix-js-sdk to decrypt it, and you can't know an event's type before it's decrypted. Probably what was happening is that another code path was requesting the events to be decrypted so that this mistake didn't matter.
2024-11-12 10:05:01 +01:00
Robin 20976e1ee3 Bump matrix-js-sdk for MSC4222 support 2024-11-11 18:01:28 -05:00
Andrew Ferrazzutti f12e6601fe Refactor if expression (#2758)
Split the check on a boolean into another branch
2024-11-11 12:51:31 -05:00
Robin 4b2d8403d7 Merge pull request #2748 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2024-11-11 12:37:41 -05:00
renovate[bot] 03f0fffa57 Update all non-major dependencies 2024-11-11 17:33:23 +00:00
Andrew Ferrazzutti 6486ffe777 Explicitly bump matrix-widget-api (#2757)
Was already present in yarn.lock
2024-11-11 12:32:34 -05:00
TimoandRobin 3dad62f9e3 Skip lobby when coming from waitForInvite state. (#2753)
* Skip lobby if when coming from waitForInvite state.

* knock reject wording update (shorter/simpler)

* Automatically enter session also in non widget mode when skipLobby = true

* Update public/locales/en-GB/app.json

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

* review

* review andrew

---------

Co-authored-by: Robin <robin@robin.town>
2024-11-11 18:30:15 +01:00
Robin 8465bb4c13 Switch back to a normal Compound Web release (#2755)
https://github.com/element-hq/compound-web/pull/272 got merged and released.
2024-11-11 16:56:13 +00:00
Hugh Nimmo-Smith 8be6655d8b Add matrix_rtc_session config options + bump js-sdk (#2756)
* Add matrix_rtc_session config options
* Bump js-sdk

https://github.com/matrix-org/matrix-js-sdk/compare/6971e7bebaad643c233e5057da7a0d42441c0789...fcb69b16ad8d170c67ea844f83543d467bbd7707

Also brings in:

- https://github.com/matrix-org/matrix-js-sdk/pull/4342
- https://github.com/matrix-org/matrix-js-sdk/pull/4494
2024-11-11 16:53:37 +00:00
Robin 464cb16409 Merge pull request #2754 from robintown/footer-fix
Fix footer not adapting to narrow windows
2024-11-11 11:11:23 -05:00
Robin a045cc042b Fix footer not adapting to narrow windows
This CSS block was added last week but seems to have become lost along the way in a merge.
2024-11-11 11:04:49 -05:00
Robin 29469501db Merge pull request #2749 from element-hq/hs/css-fixes-for-reactions
Small improvements for reaction rendering
2024-11-11 09:19:51 -05:00
Robin a6efdf004f Merge pull request #2752 from robintown/one-on-one-crash
Make one-on-one layout less prone to crashing
2024-11-11 09:06:05 -05: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
Will Hunt 6830744096 Don't adjust reaction time.
That was just for testing
2024-11-11 12:53:39 +00:00
Will Hunt 4f9333ca0c lint 2024-11-11 12:11:53 +00:00
Will Hunt 699b69f019 Move reactions to own component. 2024-11-11 12:07:02 +00:00
Will Hunt 67e5abcf31 shrink the reaction buttons on low screen widths 2024-11-11 11:29:59 +00:00
Robin b22d2dba5f Merge pull request #2747 from robintown/decrypt-reactions
Decrypt reaction events
2024-11-10 13:15:21 -05:00
Robin 97aeb18a24 Decrypt reaction events 2024-11-10 11:20:04 -05:00
Robin e79cae820f Merge pull request #2744 from robintown/element-call-nov-preview
Bump matrix-js-sdk and matrix-widget-api
2024-11-09 08:31:35 -05:00
Robin 2bf08c8fb3 Merge pull request #2743 from robintown/mobile-tooltips
Use temporary Compound Web release for mobile tooltip improvements
2024-11-09 08:31:31 -05:00
Robin ca63035dc1 Bump matrix-js-sdk and matrix-widget-api
This bumps matrix-js-sdk to a preview branch that includes https://github.com/matrix-org/matrix-js-sdk/pull/4498 and https://github.com/matrix-org/matrix-js-sdk/pull/4494, and matrix-widget-api to 1.10.0.
2024-11-09 08:11:06 -05:00
Robin 942e07f103 Use temporary Compound Web release for mobile tooltip improvements
I put up a temporary build of https://github.com/element-hq/compound-web/pull/272 for us to use.
2024-11-08 16:39:29 -05:00
ElementRobot 18daf446c8 Merge pull request #2742 from element-hq/actions/localazy-download
Localazy Download
2024-11-08 20:59:37 +00:00
fkwp 8771a06986 Translations updates 2024-11-08 20:58:21 +00:00
ElementRobot b3da45612e Merge pull request #2741 from element-hq/actions/localazy-download
Localazy Download
2024-11-08 20:29:32 +00:00
fkwp 2d262d27dd Translations updates 2024-11-08 20:28:17 +00:00
Robin 022367ec2e Merge pull request #2737 from robintown/footer-hide-show
Improve interactions to hide/show the footer
2024-11-08 14:31:17 -05:00
Robin 56e736b0ee Merge pull request #2732 from element-hq/hs/add-volume-effect-level
Add sound effect volume slider
2024-11-08 13:19:58 -05:00
Robin 3e1e08c883 Fix type error 2024-11-08 13:18:36 -05:00
Half-Shot 6645a6e5a2 sort 2024-11-08 13:09:28 -05:00
Half-Shot a6683b230c Ensure hand raised uses the same volume 2024-11-08 13:09:28 -05:00
Half-Shot 06a02b4dd8 Add test 2024-11-08 13:09:28 -05:00
Half-Shot c560b58811 lint 2024-11-08 13:05:05 -05:00
Half-Shot 7b57fc2942 Add ability to adjust sound effect volume. 2024-11-08 13:05:05 -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
Robin 1df2e0c48f Merge pull request #2738 from robintown/narrow-footer
Make the footer display more nicely on narrow screens
2024-11-08 12:46:29 -05:00
Robin f1233cad20 Merge branch 'livekit' into narrow-footer 2024-11-08 12:45:09 -05:00
5d88c52e30 Support for generic reactions (#2708)
* Initial support for Hand Raise feature

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Refactored to use reaction and redaction events

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Replacing button svg with raised hand emoji

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* SpotlightTile should not duplicate the raised hand

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Update src/room/useRaisedHands.tsx

Element Call recently changed to AGPL-3.0

* Use relations to load existing reactions when joining the call

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Links to sha commit of matrix-js-sdk that exposes the call membership event id and refactors some async code

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Removing RaiseHand.svg

* Check for reaction & redaction capabilities in widget mode

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Fix failing GridTile test

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Center align hand raise.

* Add support for displaying the duration of a raised hand.

* Add a sound for when a hand is raised.

* Refactor raised hand indicator and add tests.

* lint

* Refactor into own files.

* Redact the right thing.

* Tidy up useEffect

* Lint tests

* Remove extra layer

* Add better sound. (woosh)

* Add a small mode for spotlight

* Fix timestamp calculation on relaod.

* Fix call border resizing video

* lint

* Fix and update tests

* Allow timer to be configurable.

* Add preferences tab for choosing to enable timer.

* Drop border from raised hand icon

* Handle cases when a new member event happens.

* Prevent infinite loop

* Major refactor to support various state problems.

* Tidy up and finish test rewrites

* Add some explanation comments.

* Even more comments.

* Use proper duration formatter

* Remove rerender

* Fix redactions not working because they pick up events in transit.

* More tidying

* Use deferred value

* linting

* Add tests for cases where we got a reaction from someone else.

* Be even less brittle.

* Transpose border to GridTile.

* First PoC for reactions

* hide menu by default

* Add lightbulb.

* Add reaction indicator.

* Add sounds.

* Tidy up + add support for floating emoji.

* Linting and general stability improvements.

* Subscribe to the ecall reaction event type.

* fix import

* Center emoji picker

* Overflow buttons when screen is too narrow

* lint

* Add settings for disabling animations / sounds.

* Make vertical divider more visually distinct.

* Make event listener more resillient.

* lint

* Fix some tests.

* Remove old raised hand component

* Add new icon

* Update text

* Update compound hand raised icon.

* Add deer.

* Fix case where you could send larger strings as emoji

* Const the active time.

* Document time in css.

* Add rock emoji

* Add licence file.

* Add type def for custom reaction type.

* better reaction description

* Factor out reactions test structure to utils file.

* Add tests for ReactionToggleButton

* Add keyboard shortcuts for reaction sending.

* type tidyups

* lint

* Add tests for ReactionAudioRenderer

* lint

* prettier

* i18n sort

* final lint?

* Preload reaction sounds to prevent delays.

* Update rock sounds

* add onclick back

* Fix test

* lint

* simplify

* Tweak line height

* modal impl

* Modal refactor attempts.

* Remove closed menu test since we're using Modal.

* Swap icon, make mobile view better.

* Fix mobile view for emoji picker.

* Use Intl.Segmenter

* Clear timeouts on component close.

* Remove useless useCallback

* Use prefers-reduced-motion

* Add toggle for raise hand.

* Add lower hand text

* Add lower motion mode.

* Decomplicate className system for Modal

* Add error for failured to send reaction.

* i18n

* Spacing for emoji buttons search

* Remove unrequired media query

* Fix generic sound not playing.

* Clear reactions if we're clearing timeouts.

* Fix tests

* Relabel lower hand

* More translations

* Add comments on reaction interface

* Move polyfill.

* lint

* Replace deer sound

* Another attempt to fix the sizing of the reactions

* cleanup

* fix button

* fix

---------

Signed-off-by: Milton Moura <miltonmoura@gmail.com>
Co-authored-by: Milton Moura <miltonmoura@gmail.com>
Co-authored-by: fkwp <fkwp@users.noreply.github.com>
2024-11-08 17:36:40 +00:00
Robin c7e220e310 Make the footer display more nicely on narrow screens
It needed a bit of tweaking now that we have up to 6 buttons in the footer. I tried to do everything in CSS this time.
2024-11-08 12:16:59 -05:00
Robin 5b94dd6f1a Merge pull request #2736 from robintown/disable-encryption-status
Disable the encryption status indicators
2024-11-08 09:35:15 -05:00
Robin 0ffb4cc23d Disable the encryption status indicators
Currently they're a bit broken and we don't have the time to fix them.
2024-11-08 09:34:02 -05:00
fkwp f4096a6d43 Merge pull request #2733 from element-hq/fkwp/fix_nginx_conf
fix nginx config
2024-11-07 23:12:01 +01:00
fkwp c9676f2466 fix nginx config 2024-11-07 23:01:50 +01:00
fkwp 640ba8b79f Merge pull request #2719 from element-hq/fkwp/docker_compose_non_hostnetwork
docker compose non hostnetwork setup
2024-11-07 21:45:36 +01:00
fkwpandAndrew Ferrazzutti 34abca0c0b Update dev-backend-docker-compose.yml
Co-authored-by: Andrew Ferrazzutti <andrewf@element.io>
2024-11-07 19:16:55 +01:00
fkwpandAndrew Ferrazzutti bea9a24b14 Update dev-backend-docker-compose.yml
Co-authored-by: Andrew Ferrazzutti <andrewf@element.io>
2024-11-07 19:16:48 +01:00
fkwpandAndrew Ferrazzutti fd383328e2 Update dev-backend-docker-compose.yml
Co-authored-by: Andrew Ferrazzutti <andrewf@element.io>
2024-11-07 19:16:40 +01:00
Will Hunt 938beccb6e Add tests for Modal (#2731)
* Add Modal tests.

* fix type

* apply review feedback

* lint

* remove act
2024-11-07 17:06:49 +00:00
Timo 9bf40eda25 Prohibit .preview to be 0 width (#2730) 2024-11-07 13:15:12 +01:00
fkwp 05eb2a06f4 prettier 2024-11-06 21:18:24 +01:00
fkwp 2961cfa52c update README.md 2024-11-06 20:20:29 +01:00
fkwp 65742db4f2 use less common port for JWT service 2024-11-06 20:07:52 +01:00
fkwp 430337e725 update dev env setup 2024-11-06 20:00:21 +01:00
fkwp 4a71283826 update docker-compose cmd line 2024-11-06 20:00:21 +01:00
fkwp 7440f39fef add base_url 2024-11-06 20:00:21 +01:00
fkwp 69776ba08e add .well-known section including a note that this is not effective for the local dev environment 2024-11-06 20:00:21 +01:00
fkwp bf4596dfc5 add dedicated config for local development environment 2024-11-06 20:00:21 +01:00
fkwp 4877474b7d remove livekit.livekit_service_url from sample config since SFU foci should be announced by homeserver's well-known 2024-11-06 20:00:21 +01:00
fkwpandAndrew Ferrazzutti 4705ab4218 Update dev-backend-docker-compose.yml
Co-authored-by: Andrew Ferrazzutti <andrewf@element.io>
2024-11-06 19:46:59 +01:00
renovate[bot] e37f36937e Migrate config renovate.json 2024-11-06 18:46:12 +00:00
Timo bbdb48a7d2 bump js sdk (#2728) 2024-11-06 19:01:14 +01:00
Hugh Nimmo-Smith bfffddfa92 Fix minature => miniature spelling (#2727) 2024-11-06 15:54:58 +00:00
Timo a041a7bf7e Bump js-sdk (local echo fix) (#2723) 2024-11-06 16:35:29 +01:00
Hugh Nimmo-Smith f611554c31 Don't hide video on encryption status error (#2726) 2024-11-06 15:31:31 +00:00
ElementRobot 137c2fad0b Merge pull request #2725 from element-hq/actions/localazy-download
Localazy Download
2024-11-06 15:24:48 +00:00
fkwp 0954188097 Translations updates 2024-11-06 15:23:38 +00:00
Hugh Nimmo-Smith 7fd344385d Add rxjs/recommend eslint rules (#2724)
We will probably want to tweak these as we get more used to them.
2024-11-06 14:33:06 +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
Will Hunt bc0ab92394 Add feature to release hand raised when the tile indicator is clicked. (#2721)
* Refactor to add support for lowering hand on indicator click.

* Cleanup and lint.

* fix icon being a little off
2024-11-06 11:00:19 +00:00
fkwp d1774d63ab make dev-backend-docker-compose.yaml work wiht podman compose 2024-11-06 10:55:13 +01:00
RobinandHugh Nimmo-Smith 110914a4d6 Replace some custom React hooks with observable-hooks (#2710)
The observable-hooks package provides hooks that do exactly the same thing as these custom React hooks I had written a while back. (even the names are the same, wow)

Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
2024-11-06 09:43:27 +00:00
RobinandHugh Nimmo-Smith 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
ElementRobot 22cca2874a Merge pull request #2722 from element-hq/actions/localazy-download
Localazy Download
2024-11-05 22:58:33 +00:00
fkwp a9b15c1ec2 Translations updates 2024-11-05 22:51:22 +00:00
fkwp 88a8277694 Merge pull request #2716 from element-hq/fkwp/enable_feature_use_device_session_member_events
default to flat structre of m.call.member evenst (one event per sessi…
2024-11-05 10:51:38 +01:00
renovate[bot] b7d7180335 Update all non-major dependencies (#2713)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-05 10:42:02 +01:00
fkwp c33c703570 adapt config.sample.json to development environment settings 2024-11-05 00:36:18 +01:00
fkwp 82c6db1f94 linting 2024-11-05 00:35:40 +01:00
fkwp 44cb16d0b8 prefix docker-compose with dev to make clear its only for development purposes. In addition added minimum synapse config to it in order to have a fully selfcontained dev setup 2024-11-05 00:25:41 +01:00
fkwp a672224324 rename livekit.conf to dev_livekit.conf to make clear that its for the development environment 2024-11-05 00:23:02 +01:00
fkwp c5bd68f7db update gitignore to irgnore temp synapse state 2024-11-05 00:18:33 +01:00
fkwp 2de105c9fd minimum homeserver configuration for development environment 2024-11-05 00:15:26 +01:00
fkwp 275e0bdb00 minimum nginx tls reverse proxy configuration for synapse homeserver 2024-11-05 00:14:02 +01:00
fkwp 377ccf8f45 add localhost tls certificates for dev environment 2024-11-05 00:05:02 +01: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
fkwp e95106a431 fix linting 2024-11-04 15:13:32 +01:00
fkwp 16129d8154 fix test to reflect new m.call.member format 2024-11-04 14:35:12 +01:00
fkwp 895c52ed06 default to flat structre of m.call.member evenst (one event per session rather than an array) 2024-11-04 14:24:13 +01:00
1897210a60 Hand raise feature (#2542)
* Initial support for Hand Raise feature

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Refactored to use reaction and redaction events

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Replacing button svg with raised hand emoji

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* SpotlightTile should not duplicate the raised hand

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Update src/room/useRaisedHands.tsx

Element Call recently changed to AGPL-3.0

* Use relations to load existing reactions when joining the call

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Links to sha commit of matrix-js-sdk that exposes the call membership event id and refactors some async code

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Removing RaiseHand.svg

* Check for reaction & redaction capabilities in widget mode

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Fix failing GridTile test

Signed-off-by: Milton Moura <miltonmoura@gmail.com>

* Center align hand raise.

* Add support for displaying the duration of a raised hand.

* Add a sound for when a hand is raised.

* Refactor raised hand indicator and add tests.

* lint

* Refactor into own files.

* Redact the right thing.

* Tidy up useEffect

* Lint tests

* Remove extra layer

* Add better sound. (woosh)

* Add a small mode for spotlight

* Fix timestamp calculation on relaod.

* Fix call border resizing video

* lint

* Fix and update tests

* Allow timer to be configurable.

* Add preferences tab for choosing to enable timer.

* Drop border from raised hand icon

* Handle cases when a new member event happens.

* Prevent infinite loop

* Major refactor to support various state problems.

* Tidy up and finish test rewrites

* Add some explanation comments.

* Even more comments.

* Use proper duration formatter

* Remove rerender

* Fix redactions not working because they pick up events in transit.

* More tidying

* Use deferred value

* linting

* Add tests for cases where we got a reaction from someone else.

* Be even less brittle.

* Transpose border to GridTile.

* lint

---------

Signed-off-by: Milton Moura <miltonmoura@gmail.com>
Co-authored-by: fkwp <fkwp@users.noreply.github.com>
Co-authored-by: Half-Shot <will@half-shot.uk>
Co-authored-by: Will Hunt <github@half-shot.uk>
2024-11-04 09:54:13 +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 19c4696a0d Merge pull request #2692 from robintown/hide-profile
Hide the 'profile' menu option in widget mode
2024-11-02 18:37:45 -04:00
Robin b3441ed4a0 Merge pull request #2711 from robintown/lobby-unmirror
Don't mirror rear-facing cameras in the lobby
2024-11-02 18:26:31 -04:00
Robin 7b0bdd320a Don't mirror rear-facing cameras in the lobby 2024-11-01 17:26:45 -04:00
Robin c9cf7aa7db Merge pull request #2709 from robintown/app-prompt-config
Add a config option to disable the app prompt
2024-11-01 17:05:09 -04:00
Robin 8f8e2b42e1 Merge pull request #2694 from robintown/switch-camera
Add a button to switch the camera on mobile
2024-11-01 17:04:36 -04:00
Robin 7ad70064a3 Add a config option to disable the app prompt 2024-11-01 16:57:48 -04: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 90681b16e0 Merge pull request #2705 from element-hq/renovate/github-actions
Update GitHub Actions
2024-10-31 21:37:37 -04:00
renovate[bot] 05b06ce3e2 Update GitHub Actions 2024-11-01 01:16:40 +00:00
fkwp 39a451e764 Merge pull request #2704 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.6.0
2024-10-31 23:23:03 +01:00
renovate[bot] 592ed1f0cf Update dependency livekit-client to v2.6.0 2024-10-31 22:19:15 +00:00
Robin ef320636e2 Merge pull request #2661 from element-hq/renovate/eslint-plugin-unicorn-56.x
Update dependency eslint-plugin-unicorn to v56
2024-10-30 10:29:47 -04:00
renovate[bot] 9fa7bf976f Update dependency eslint-plugin-unicorn to v56 2024-10-30 14:27:38 +00:00
Robin a38862b0b9 Merge pull request #2682 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2024-10-30 10:26:19 -04:00
renovate[bot] 823ffd96b3 Update all non-major dependencies 2024-10-30 13:52:21 +00:00
Robin 0d45c25eb8 Merge pull request #2693 from robintown/join-guest-strings
Update the strings on the join as guest screen
2024-10-29 20:49:46 -04:00
Robin 0784a30ef0 Update the strings on the join as guest screen
Hugh pointed out that the button labeled "Join call now" on this screen is misleading, because it does not join you to the call but rather send you to the lobby. Meanwhile, the designs call for this screen to use the words "Join as guest" and "Continue", so let's go with that.
2024-10-28 15:59:53 -04:00
Robin d2aa6d561f Hide the 'profile' menu option in widget mode
The profile settings tab is non-functional in widget mode so we need to hide its other points of entry.
2024-10-28 15:15:02 -04:00
Robin e06aaf6fd4 Merge pull request #2691 from robintown/duplicate-devices
Remove duplicate media devices from the list
2024-10-28 15:05:47 -04:00
Robin 0ec56014c3 Remove duplicate media devices from the list
Somehow on my system Firefox always manages to create multiple entries for my webcam. This was an easy enough thing to fix.
2024-10-28 15:02:01 -04:00
Robin 3a706ea3e0 Show speaking indicators in spotlight during screen sharing 2024-10-28 14:45:06 -04:00
Robin 7edc8af9a0 Merge pull request #2687 from robintown/media-devices-config
Add config options for starting with audio and video enabled
2024-10-28 09:08:04 -04:00
Robin 551c3f4104 Add config options for starting with audio and video enabled 2024-10-27 21:47:13 -04:00
Robin 5907bf7c33 Merge pull request #2662 from element-hq/renovate/compound
Update Compound
2024-10-25 12:27:32 -04:00
Hugh Nimmo-Smith d8bbd93294 Bump js-sdk for MatrixRTC fixes (#2688)
Full diff https://github.com/matrix-org/matrix-js-sdk/compare/v34.7.0...0a29063bc9e61ee70ca43820d4bb91f6a27f1237

Relevant PRs included:

- Do not rotate MatrixRTC media encryption key when a new member joins a session #4472
- Refactor/simplify Promises in MatrixRTCSession #4466
- Prepare delayed call leave events more reliably #4447
- Fix DelayedEventInfo type #4446
- Fix MatrixRTC sender key wrapping #4441
2024-10-25 17:23:34 +01:00
Robin bb95d9e414 Merge pull request #2686 from robintown/keep-local-tile
Don't cause the local tile to disappear when joining
2024-10-25 08:22:37 -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
fkwp fbf754972b Merge pull request #2685 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.10
2024-10-24 09:01:21 +02:00
renovate[bot] 7974c04dd9 Update dependency livekit-client to v2.5.10 2024-10-24 06:58:57 +00:00
Robin a4faafb3e0 Merge pull request #2681 from robintown/volume-slider
Make the volume slider less silly
2024-10-22 17:25:18 -04:00
Robin d901045e55 Address review comments 2024-10-22 17:23:40 -04:00
renovate[bot] 5aba2a00a5 Update Compound 2024-10-22 19:25:12 +00:00
fkwp 33401171a8 Merge pull request #2684 from element-hq/renovate/livekit-components
Update LiveKit components
2024-10-22 21:24:33 +02:00
renovate[bot] 480b62a5d8 Update LiveKit components 2024-10-22 19:16:22 +00:00
Robin 0c6e53cda4 Make the volume slider less silly
Previously, dragging it all the way to the left would *not* mute the participant but rather bottom out at 10% volume, and people have found this unintuitive. Let's make it less silly by giving the slider a range of 0% to 100%, and making the mute toggle button have the same effect as dragging the slider to zero. When unmuting, it will reset to the last non-zero "committed" volume, similar to how the volume sliders in desktop environments work.
2024-10-18 17:51:37 -04:00
Robin bfe6da6be7 Merge pull request #2680 from robintown/disable-codecov-annotations
Disable Codecov annotations
2024-10-18 17:01:48 -04:00
Robin 250291315e Disable Codecov annotations
Don't mark up the diffs on PRs with warnings about untested lines; we're not aiming for 100% test coverage and they just get in the way of reviewing.
2024-10-18 16:39:02 -04:00
Robin 75c7516f0a Merge pull request #2673 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2024-10-17 15:54:21 -04:00
renovate[bot] d1570466d2 Update all non-major dependencies 2024-10-17 19:15:31 +00:00
Andrew Ferrazzutti 6094627d8d Fix typo in example config (#2679) 2024-10-17 15:14:12 -04:00
fkwp d252b0a06b Merge pull request #2676 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.9
2024-10-14 15:48:42 +02:00
fkwp b630dad4a3 Merge pull request #2675 from element-hq/renovate/github-actions
Update GitHub Actions
2024-10-14 15:48:19 +02:00
renovate[bot] d3d8500431 Update dependency livekit-client to v2.5.9 2024-10-14 13:47:11 +00:00
renovate[bot] 3bd3e947ad Update GitHub Actions 2024-10-14 13:47:02 +00:00
fkwp 771bf00b66 Merge pull request #2674 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.8
2024-10-14 09:14:48 +02:00
renovate[bot] e9baf3ccfa Update dependency livekit-client to v2.5.8 2024-10-14 01:31:56 +00:00
Robin 8e20be42e0 Merge pull request #2672 from element-hq/renovate/major-react-monorepo
Update dependency eslint-plugin-react-hooks to v5
2024-10-11 11:36:43 -04:00
renovate[bot] 89702da488 Update dependency eslint-plugin-react-hooks to v5 2024-10-11 15:35:19 +00:00
Hugh Nimmo-Smith 8a84c6c45e Use non-deprecated method of re-processing MatrixRTCSession keys (#2646)
* Handle case of encryption key for an index to be undefined

As per https://github.com/matrix-org/matrix-js-sdk/pull/4423 the key can be undefined and so we should handle this rather than waiting for SubtleCrypto.importKey() to fail.

* Use release version of matrix-js-sdk

Diff is https://github.com/matrix-org/matrix-js-sdk/compare/baa6d135065637c9769c61325c69709d3618f5f1...v34.7.0

* Use RTCSession. reemitEncryptionKeys()

* Add some test coverage whilst we are here

* Add some test coverage whilst we are here

* Lint
2024-10-11 11:34:45 -04:00
Hugh Nimmo-Smith 8272c54177 Set LiveKit keyring size to 256 (#2660) 2024-10-10 10:34:38 +01:00
renovate[bot] 697e1a6d81 Update all non-major dependencies (#2665)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-10 11:26:26 +02:00
fkwp 46379c4895 Merge pull request #2669 from element-hq/renovate/livekit-components
Update LiveKit components
2024-10-09 12:04:38 +02:00
fkwp 697b4a326e Merge pull request #2668 from element-hq/renovate/github-actions
Update GitHub Actions
2024-10-09 12:04:16 +02:00
renovate[bot] 5bb5fe4c7f Update LiveKit components 2024-10-09 10:02:39 +00:00
renovate[bot] 8fcdfdf5e6 Update GitHub Actions 2024-10-09 10:02:22 +00:00
fkwp a56ecfd373 Merge pull request #2667 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.7
2024-10-07 17:46:12 +02:00
renovate[bot] 0723ba1d3e Update dependency livekit-client to v2.5.7 2024-10-07 12:28:07 +00:00
fkwp 2e71f3c9da Merge pull request #2666 from element-hq/renovate/github-actions
Update docker/setup-buildx-action action to v3.7.1
2024-10-07 13:23:25 +02:00
renovate[bot] f4c601a2f5 Update docker/setup-buildx-action action to v3.7.1 2024-10-07 11:22:19 +00:00
fkwp 4caee1737f Merge pull request #2663 from element-hq/renovate/github-actions
Update GitHub Actions
2024-10-04 09:07:29 +02:00
renovate[bot] a9d63c577d Update GitHub Actions 2024-10-04 07:06:17 +00:00
fkwp 0b47d9bd86 Merge pull request #2658 from element-hq/renovate/livekit-components
Update LiveKit components
2024-10-02 14:04:09 +02:00
renovate[bot] 95e3efc66e Update LiveKit components 2024-10-02 12:02:43 +00:00
fkwp 3bf4892ccf Merge pull request #2659 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.6
2024-10-02 14:01:33 +02:00
renovate[bot] 01af0b1a64 Update dependency livekit-client to v2.5.6 2024-10-02 11:57:37 +00:00
Robin 1fff785853 Merge pull request #2655 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2024-10-01 11:08:50 -04:00
renovate[bot] b53737adda Update all non-major dependencies 2024-10-01 15:05:29 +00:00
fkwp f23b9d1952 Merge pull request #2657 from element-hq/renovate/github-actions
Update docker/build-push-action action to v6.9.0
2024-10-01 08:22:26 +02:00
renovate[bot] 35908a51d0 Update docker/build-push-action action to v6.9.0 2024-10-01 01:42:46 +00:00
Alexander Mnich 84d3a02a3f update Synapse documentation link to point to element-hq docs (#2653) 2024-09-30 14:09:01 +02:00
fkwp f350032b9f Merge pull request #2654 from element-hq/renovate/livekit-components
Update LiveKit components
2024-09-30 08:59:57 +02:00
renovate[bot] fc56dfd337 Update LiveKit components 2024-09-30 00:24:39 +00:00
fkwp 0a7394cd7b Merge pull request #2652 from element-hq/renovate/github-actions
Update GitHub Actions
2024-09-27 23:32:15 +02:00
renovate[bot] cd1bdb66bb Update GitHub Actions 2024-09-27 21:30:48 +00:00
Robin 55548afa3c Merge pull request #2648 from robintown/compose-config
Make it possible to use the JWT service with a local homeserver
2024-09-27 17:07:49 -04:00
Robinandfkwp 5cf1cf9e54 Make port types explicit
Co-authored-by: fkwp <fkwp@users.noreply.github.com>
2024-09-27 16:35:39 -04:00
Robin 877be03328 Merge pull request #2635 from element-hq/renovate/global-jsdom-25.x
Update dependency global-jsdom to v25
2024-09-27 16:05:03 -04:00
Robin 27a24cd7a3 Merge pull request #2631 from element-hq/renovate/all-minor-patch
Update all non-major dependencies
2024-09-27 16:04:10 -04:00
Robin a74d170586 Hold back PostHog updates for now
https://github.com/PostHog/posthog-js/issues/1437
2024-09-27 16:02:12 -04:00
Robin 482b46fed2 Merge pull request #2649 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v6.2.1
2024-09-27 15:33:39 -04:00
fkwp cf832972bf Merge pull request #2651 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.5
2024-09-27 21:29:33 +02:00
renovate[bot] bb3ab73b8c Update all non-major dependencies 2024-09-27 19:28:16 +00:00
renovate[bot] 367330b324 Update dependency livekit-client to v2.5.5 2024-09-27 19:27:53 +00:00
fkwp d6c5d0bb17 Merge pull request #2650 from element-hq/hughns/js-sdk-bump
Upgrade matrix-js-sdk
2024-09-27 21:26:49 +02:00
Hugh Nimmo-Smith e8288d07a4 Bump js-sdk 2024-09-27 17:20:45 +01:00
renovate[bot] 19479a005f Update dependency @vector-im/compound-web to v6.2.1 2024-09-27 01:33:40 +00:00
Robin f0e59baad4 Make the SFU actually usable 2024-09-26 16:53:45 -04:00
Robin e98740d6f2 Make it possible to use the JWT service with a local homeserver
I recently tried to use the dev configs with a local homeserver and found that the configuration was not compatible with this. We need to relax the network isolation and TLS cert verification requirements for fully local development to be possible.
2024-09-26 14:19:06 -04:00
fkwp 0fabbabed2 Merge pull request #2647 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.4
2024-09-25 20:32:49 +02:00
renovate[bot] d9d368cd74 Update dependency livekit-client to v2.5.4 2024-09-25 18:31:10 +00:00
Timo d7b06760ad Test useTheme hook (#2625)
* Test useTheme hook
2024-09-24 22:15:16 +02:00
Hugh Nimmo-Smith ed35d6b377 Posthog improvements (#2630) 2024-09-23 14:35:41 +01:00
Hugh Nimmo-SmithandAndrew Ferrazzutti d14b43487a Intercept matrix_sdk logging via console and include in rageshake (#2623)
Co-authored-by: Andrew Ferrazzutti <andrewf@element.io>
2024-09-23 14:35:10 +01:00
fkwp d089ff67b7 Merge pull request #2645 from element-hq/renovate/livekit-components
Update dependency @livekit/components-react to v2.6.0
2024-09-23 08:53:04 +02:00
renovate[bot] d68de40ce4 Update dependency @livekit/components-react to v2.6.0 2024-09-23 00:24:22 +00:00
Robin a491b1fdf0 Merge pull request #2644 from robintown/fix-cookie-policy
Make the cookie policy link show up again
2024-09-19 16:01:11 -04:00
Robin 90043508ce Update cookie policy links in translations 2024-09-19 15:54:21 -04:00
Robin 1e2e4c8e7b Make the cookie policy link show up again
For some reason yarn i18next didn't catch that the string had to be changed? I removed the string and regenerated it, and now the cookie policy is back.
2024-09-19 15:35:46 -04:00
Robin ac42d4a69a Merge pull request #2643 from robintown/log-in-links
Make the links on the log in page visually consistent
2024-09-19 14:33:30 -04:00
Robin 8b3c94b120 Make the links on the log in page visually consistent
Timo was totally right in his previous review of my typography component work that these didn't have the right styling. I just didn't notice!
2024-09-19 12:09:14 -04:00
Robin cec7fc8f5b Merge pull request #2629 from robintown/test-call-vm
Test CallViewModel
2024-09-18 23:13:22 -04: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 156f1e3a10 Merge branch 'livekit' into test-call-vm 2024-09-18 22:37:15 -04:00
fkwp cb7f25278a Merge pull request #2641 from element-hq/renovate/livekit-components
Update LiveKit components
2024-09-18 15:30:41 +02:00
renovate[bot] 99dc2d2f2d Update LiveKit components 2024-09-18 13:29:15 +00:00
fkwp 167ce6ce10 Merge pull request #2642 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.2
2024-09-18 15:27:43 +02:00
renovate[bot] da5c8f9ad6 Update dependency livekit-client to v2.5.2 2024-09-18 13:26:07 +00:00
Hugh Nimmo-Smith bd866945fd Bump js-sdk (#2638) 2024-09-18 13:18:28 +01:00
Will Hunt 4bf6509109 Merge pull request #2637 from element-hq/hs/workaround-federation-bug
Retry a join on invite if the response was M_FORBIDDEN
2024-09-18 12:31:20 +01:00
Half-Shot c19645c710 consts 2024-09-18 10:10:29 +01:00
Half-Shot 7e5a8b8feb Retry a join on invite if the response was M_FORBIDDEN 2024-09-18 10:08:03 +01:00
Robin 745533f061 Merge pull request #2636 from element-hq/renovate/npm-vite-vulnerability
Update dependency vite to v5.4.6 [SECURITY]
2024-09-17 16:56:33 -04:00
renovate[bot] a2c3f24b4e Update dependency vite to v5.4.6 [SECURITY] 2024-09-17 20:54:21 +00:00
Robin a8b9c1ea33 Merge pull request #2633 from element-hq/renovate/compound
Update dependency @vector-im/compound-web to v6.2.0
2024-09-17 16:53:52 -04:00
renovate[bot] e4578dfb4f Update dependency global-jsdom to v25 2024-09-17 18:55:12 +00:00
renovate[bot] 3ee224de9c Update dependency @vector-im/compound-web to v6.2.0 2024-09-17 01:58:00 +00:00
fkwp eb6719d32e Merge pull request #2618 from Johennes/johannes/remove-call
Add button to remove call from recents
2024-09-13 13:24:05 +02:00
Johannes Marbach d2fb1e566f Merge branch 'livekit' into johannes/remove-call 2024-09-13 12:47:18 +02: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
fkwp 41a0887365 Merge pull request #2627 from element-hq/renovate/livekit-components
Update LiveKit components
2024-09-12 19:43:00 +02:00
fkwp 22883816b0 Merge pull request #2628 from element-hq/renovate/major-github-actions
Update peter-evans/create-pull-request action to v7
2024-09-12 19:42:21 +02:00
fkwp 02ca623c7f Merge pull request #2626 from element-hq/renovate/github-actions
Update actions/upload-artifact digest to 5076954
2024-09-12 19:41:54 +02:00
renovate[bot] ace4289a97 Update peter-evans/create-pull-request action to v7 2024-09-12 17:40:58 +00:00
renovate[bot] 7794f8f75f Update LiveKit components 2024-09-12 17:40:54 +00:00
renovate[bot] 14cb0e03bb Update actions/upload-artifact digest to 5076954 2024-09-12 17:40:40 +00:00
Robin e699cb6411 Merge pull request #2624 from robintown/compound-typography
Replace typography components with Compound components
2024-09-12 13:04:09 -04:00
Robin 3ded8bec47 Add more comments 2024-09-12 12:59:02 -04:00
Johannes Marbach 8e21453887 Use i18next hook 2024-09-12 09:35:23 +02:00
Johannes Marbach b1b226d79b Disable link and button while leaving 2024-09-12 09:35:17 +02:00
Robin e5e6233efb Replace typography components with Compound components 2024-09-11 13:44:43 -04:00
Hugh Nimmo-Smith a5aeb6f324 Give user feedback if the rageshake submission failed (#2621) 2024-09-11 14:53:50 +01:00
Robin 5fda7fa220 Merge pull request #2619 from robintown/copyright-header
Update the copyright header template
2024-09-11 09:53:16 -04:00
Robin 3df12be95c Merge pull request #2620 from robintown/missing-members
Diagnose the missing room members situation
2024-09-11 09:33:42 -04:00
Hugh Nimmo-Smith 7e5b70d439 Rageshake logging improvements (#2622) 2024-09-11 14:02:59 +01:00
Robin ca135d471e React more actively to changes in room membership 2024-09-11 01:27:24 -04:00
Robin 1b5b9342fe Warn about duplicate rooms 2024-09-11 01:27:02 -04:00
Robin d12a01b1c4 Test StarRating 2024-09-10 18:21:19 -04:00
Robin e15296427c Update the copyright header template
This updates the text suggested by our copyright header lint rule.
2024-09-10 18:19:55 -04:00
Robin e8278b4ed2 Merge branch 'livekit' into test-components 2024-09-10 18:05:22 -04:00
Robin d6985e0053 Test SpotlightTile more thoroughly
Catching two accessibility issues along the way: we were putting the wrong accessible labels on the 'expand' button, and even the off-screen pages of the spotlight tile were being exposed to accessibility technologies rather than hidden.
2024-09-10 17:42:18 -04:00
Robin 8872b879d8 Explain why I've added aria-describedby={undefined} 2024-09-10 16:24:58 -04:00
Robin fa36fcd3a2 Exclude test utilities from coverage report 2024-09-10 16:23:00 -04:00
Johannes Marbach 09af614fb8 Switch to close icon 2024-09-10 16:21:56 +02:00
Johannes Marbach 9766cb2ca2 Add button to remove call from recents
Fixes: #2243
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2024-09-10 13:33:12 +02:00
renovate[bot] 460aa7618a Update dependency @vector-im/compound-web to v6.1.2 (#2617)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-10 09:50:24 +02:00
TimoandHugh Nimmo-Smith 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
Hugh Nimmo-Smith c30c8ac7d6 Include the hostname of where EC is running in rageshakes (#2616) 2024-09-09 11:14:46 +01:00
renovate[bot] 0f63e2a181 Update all non-major dependencies (#2615)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-09 12:03:09 +02:00
Robin 982bd6d06b Test SpotlightTile 2024-09-06 18:41:47 -04:00
Robin ba36cfa239 Test GridTile 2024-09-06 18:41:47 -04:00
Robin 0c0be8a862 Test InviteModal 2024-09-06 18:41:47 -04:00
Robin d9333d6829 Test RoomHeaderInfo 2024-09-06 18:41:47 -04:00
Robin 40fc1aa46b Upgrade Compound Web
This patch release fixes a bug where tooltips would label non-interactive triggers in an inaccessible way.
2024-09-06 18:40:35 -04:00
Robin 251918a6ad Enable test isolation
I had experimented with turning this off in order to improve test performance, and apparently that ended up being merged. Now if we're to do component testing, we'll be changing things globally on the document, so isolation is very much necessary.
2024-09-06 18:40:18 -04:00
fkwp 040930c8d3 Merge pull request #2612 from element-hq/fkwp/change_license
Fkwp/change license
2024-09-06 10:40:29 +02:00
fkwp f517099f27 The New Vector Ltd. -> New Vector Ltd 2024-09-06 10:35:10 +02:00
fkwp 9add3e52c4 Update file headers copyright and change licence to AGPL-3.0-only 2024-09-06 10:22:13 +02:00
fkwp 7f03116b65 Update LICENCE file 2024-09-06 10:21:49 +02:00
Robin cc813fd3cb Merge pull request #2610 from robintown/update-js-sdk
Update matrix-js-sdk
2024-09-03 16:28:21 -04:00
Robin 4157ad071a Merge pull request #2608 from robintown/fix-rageshakes
Fix rageshakes
2024-09-03 16:23:30 -04:00
Robin bc157c6dc4 Update matrix-js-sdk
There's no particular change that we need to pull in, but I like to keep my linked copy of matrix-js-sdk up to date—a TypeScript config change is required by recent versions, so I'd like to update this now.
2024-09-03 16:18:34 -04:00
Robin 57e1434fec Merge pull request #2609 from robintown/coverage-barrier
Make the test coverage target non-blocking
2024-09-03 16:14:00 -04:00
ElementRobot bfbc5980b7 Merge pull request #2439 from element-hq/actions/localazy-download
Localazy Download
2024-09-03 15:10:42 -05:00
Robin 27394f9710 Make the test coverage target non-blocking
Sadly Codecov doesn't give us a way to relax the coverage requirements for changes that touch very few lines of code, which has been an invaluable feature of SonarCloud. I suggest we make the check non-blocking.
2024-09-03 16:07:43 -04:00
Robin 0d007f49ec Fix rageshakes
We were relying on deprecated APIs that are not supported when using Rust crypto. Since this entire file was copied and pasted from matrix-react-sdk originally, I just copied and pasted some of its more recent code in.
2024-09-03 16:00:17 -04:00
Robin 8e72ad597b Merge pull request #2473 from robintown/resize-observer
Remove ResizeObserver polyfill
2024-09-03 15:37:54 -04:00
Robin c8a2ef6a1d Merge branch 'livekit' into resize-observer 2024-09-03 15:35:10 -04:00
renovate[bot]andTimo c2cc0937c1 Update typescript-eslint monorepo to v8 (major) (#2523)
* Update typescript-eslint monorepo to v8

* es lint fixes

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Timo <toger5@hotmail.de>
2024-09-03 17:14:27 +02:00
Robin 1784cb284c Merge pull request #2598 from robintown/test-media-vm
Test MediaViewModel
2024-09-03 10:40:02 -04:00
Robin 55038065c7 Remove a test debug log (#2597) 2024-09-03 11:04:59 +02:00
fkwp 49ebb1cf4c Merge pull request #2601 from element-hq/renovate/matrix-widget-api
Update dependency matrix-widget-api to v1.9.0
2024-09-03 09:08:03 +02:00
fkwp b973e7446d Merge pull request #2606 from element-hq/renovate/livekit-client
Update dependency livekit-client to v2.5.1
2024-09-03 09:07:35 +02:00
renovate[bot] 5ebbb7b711 Update dependency livekit-client to v2.5.1 2024-09-02 20:29:29 +00:00
Timo 922fe5bafd Fix (registration flow): logout old before creating new client as required by initClient. (#2604) 2024-09-02 21:42:50 +02:00
fkwp 5f8081bebb Merge pull request #2602 from Johennes/johannes/qr
Display QR code when sharing invite link
2024-09-02 18:56:42 +02:00
Johannes MarbachandTimo 12237c469f Update src/QrCode.module.css
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
2024-09-02 17:52:01 +02:00
renovate[bot] 7ee3fbd832 Update all non-major dependencies (#2600)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-02 17:48:56 +02:00
Timo 040288790c Fix (rust crypto): Adjust login procedures to account for rust crypto behaviour. (#2603)
* Fix for missing client store (caused by: #2587)

* Fix interactive login with authenticated guest user.
Fix clearing storage before logging in a new account.
2024-09-02 17:48:15 +02:00
Johannes Marbach cba5eb5c07 Run prettier 2024-09-02 16:30:37 +02:00
Johannes Marbach 6ae0c0988d Add simplistic rendering test 2024-09-02 16:28:53 +02:00
Johannes Marbach 088d4d93a0 Re-add types package 2024-09-02 09:10:42 +02:00
fkwp ead5f63a02 Merge pull request #2599 from element-hq/renovate/github-actions
Update actions/upload-artifact action to v4.4.0
2024-09-02 09:07:57 +02:00
Johannes Marbach 8655b41c05 Run prettier 2024-09-02 08:44:33 +02:00
Johannes Marbach 5b09a5ebd8 Merge branch 'livekit' into johannes/qr 2024-09-02 08:40:15 +02:00
Johannes Marbach 354382d498 Display QR code when sharing invite link
Fixes: #2495
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2024-09-02 08:25:10 +02:00
renovate[bot] 353987ca12 Update dependency matrix-widget-api to v1.9.0 2024-09-02 01:59:12 +00:00
renovate[bot] fa6b8b3f0b Update actions/upload-artifact action to v4.4.0 2024-09-01 00:30:19 +00:00
Robin 9d5145a7a6 Test MediaViewModel
This was the result of me playing around with RxJS marble testing to understand how to get things done with its TestScheduler. I discovered that it lacks a clear way to fire arbitrary actions during the test, so I built a small helper function called schedule which does this for us.
2024-08-30 19:09:42 -04:00
Timo 3e57a7692c Add back keyboard toast tests (#2582)
* Fix global-jsdom initialization

* add back toast tests

* fix keyboard input events.

* add jsdom types
2024-08-30 15:40:09 +02:00
Robin e9fc5dadd9 Merge pull request #2594 from robintown/upgrade-compound
Upgrade Compound Web
2024-08-30 09:38:17 -04:00
Andrew Ferrazzutti 86bacd2b47 Depend on a tagged js-sdk release (#2593)
which is possible since:
- matrix-org/matrix-js-sdk@ee94e9335
- element-hq/element-call@b79a405e
2024-08-30 09:37:15 -04:00
Robin cb28fa715a Upgrade Compound Web 2024-08-30 09:35:34 -04:00
Timo 172af1dce3 Add missing productName string (#2596) 2024-08-30 15:29:14 +02:00
Timo 270540f125 Update README.md (#2589) 2024-08-30 15:07:15 +02:00
Andrew Ferrazzutti 0974488c4e Make one more js-sdk import consistent (#2595)
Update an import that was missed in b79a405e
2024-08-30 08:57:15 -04:00
Timo a2dd538237 Fix for missing client store (caused by: #2587) (#2591) 2024-08-30 11:28:00 +02:00
Richard van der Hoff b79a405ed6 Make js-sdk imports consistent (#2590)
We need to be consistent about whether we import matrix-js-sdk from `src` or
`lib`, otherwise we get two copies of matrix-js-sdk, and everything explodes.
2024-08-29 12:37:52 -04:00
Timo 159ae603aa Remove shadow for layout switcher. (#2588) 2024-08-29 17:59:28 +02:00
Timo 559fc4851c Fix rust crypto: dont use legacy crypto store anymore. (#2587)
The logic for the legacy store was intercepting with the rustCrypto that handles all the cases itself.
2024-08-29 16:59:47 +02:00
Robin b5f6343a5e Remove ResizeObserver polyfill
All major browsers support it out of the box, nowadays.
2024-08-23 15:07:40 -04:00
robintown c3379f2d0f Translations updates 2024-06-20 18:32:56 +00:00
758 changed files with 88173 additions and 23389 deletions
-48
View File
@@ -1,48 +0,0 @@
const COPYRIGHT_HEADER = `/*
Copyright %%CURRENT_YEAR%% New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
`;
module.exports = {
plugins: ["matrix-org"],
extends: [
"plugin:matrix-org/react",
"plugin:matrix-org/a11y",
"plugin:matrix-org/typescript",
"prettier",
],
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
project: ["./tsconfig.json"],
},
env: {
browser: true,
node: true,
},
rules: {
"matrix-org/require-copyright-header": ["error", COPYRIGHT_HEADER],
"jsx-a11y/media-has-caption": "off",
// We should use the js-sdk logger, never console directly.
"no-console": ["error"],
"react/display-name": "error",
},
settings: {
react: {
version: "detect",
},
},
};
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Checks if there currently is linking configured. Informs the user to disable linking before committing.
PNPMFILE=.pnpmfile.cjs
if test -f "$PNPMFILE"; then
echo "[pnpm-linker] The pre-commit hook detected $PNPMFILE which implies you have linked packages in your pnpm-lock.yaml. Run pnpm links:off and commit again. See also linking.md."
exit 1
fi
+46
View File
@@ -0,0 +1,46 @@
<!-- Thanks for submitting a PR! Please read CONTRIBUTING.md before you start. -->
> [!IMPORTANT]
> **Features and UI changes require a pre-approved issue.**
> Every PR must have a linked issue
> that a maintainer has reviewed and approved **before you started writing code**.
> PRs that don't meet this requirement will not be reviewed.
> See [CONTRIBUTING.md](https://github.com/element-hq/element-call/blob/main/CONTRIBUTING.md) for ElementCall decided for this approach.
## Content
<!-- Describe shortly what has been changed -->
## Motivation and context
<!-- Provide a link to the pre-approved issue, or explain the context for a bug fix -->
## Screenshots / GIFs
<!--
You can use a table like this to show a before/after comparison.
Uncomment the markdown table below and fill in the last line:
|Before|After|
|-|-|
|||
-->
## Tests
<!-- Explain how you tested your changes -->
- Step 1
- Step 2
- Step ...
## Checklist
- [ ] A linked, pre-approved issue exists for this feature or UI change.
- [ ] I have read [CONTRIBUTING.md](https://github.com/element-hq/element-call/blob/main/CONTRIBUTING.md) in full.
- [ ] Pull request includes screenshots or videos for any UI changes.
- [ ] Tests written for new code (and existing touched code where feasible).
- [ ] Linter and other CI checks pass.
- [ ] I have licensed the changes to Element by completing the [Contributor License Agreement (CLA)](https://cla-assistant.io/element-hq/element-call)
+256
View File
@@ -0,0 +1,256 @@
- name: "A-1:1"
description: "Calls between two people"
color: "bfd4f2"
- name: "A-Big-Grid"
description: "The freedom layout system used for >12 participants"
color: "bfd4f2"
- name: "A-Developer-Experience"
description: "Workflow of developing: building, linting, debugging, profiling, etc."
color: "c5def5"
- name: "A-E2EE"
description: "End-to-end encryption"
color: "bfd4f2"
- name: "A-Embedded"
description: "Using the app embedded within other Matrix clients (as a widget)"
color: "bfd4f2"
- name: "A-Feedback-Reporting"
description: "Reporting process for bugs, debug logs (rageshakes), suggestions"
color: "bfd4f2"
- name: "A-Freedom"
description: "Freedom layout, where participants can be rearranged and resized"
color: "bfd4f2"
- name: "A-Handset"
description: "Audio playback through the earpiece of a phone. Also known as 'earpiece mode' or 'handset mode'."
color: "bfd4f2"
- name: "A-Huddle"
description: "Ad-hoc calls in a room notifying others"
color: "bfd4f2"
- name: "A-Lobby"
description: "The page before joining a call"
color: "bfd4f2"
- name: "A-Login"
color: "bfd4f2"
- name: "A-Matrix2.0"
description: "Issues relating to the Matrix 2.0 / MSC4143 work, such as sticky events and multi-sfu"
color: "bfd4f2"
- name: "A-Media-Devices"
color: "BFD4F2"
- name: "A-Media-Quality"
description: "Distortions or glitches in audio/video"
color: "bfd4f2"
- name: "A-Meeting"
description: "Scheduled call on the calendar"
color: "bfd4f2"
- name: "A-Mobile"
description: "Using the app on a mobile device"
color: "bfd4f2"
- name: "A-Moderation"
description: "Access to calls and powers within calls"
color: "bfd4f2"
- name: "A-Performance"
color: "bfd4f2"
- name: "A-Reactions"
color: "bfd4f2"
- name: "A-Registration"
color: "bfd4f2"
- name: "A-Screen-Sharing"
color: "bfd4f2"
- name: "A-SDK"
description: "SDK for building MatrixRTC + LiveKit widgets"
color: "c5def5"
- name: "A-Settings"
color: "bfd4f2"
- name: "A-SFU"
description: "Routing calls through a selective forwarding unit"
color: "bfd4f2"
- name: "A-Signaling"
description: "Call signaling"
color: "bfd4f2"
- name: "A-Simulcast"
description: "Automatic selection of variable video resolutions"
color: "bfd4f2"
- name: "A-SPA"
description: "Standalone application accessed via call links"
color: "bfd4f2"
- name: "A-Spatial-Audio"
description: "Directional audio based on where a speaker appears on screen"
color: "bfd4f2"
- name: "A-Speech-Enhancement"
description: "Techniques to enhance the intelligibility of speech in calls"
color: "c5def5"
- name: "A-Split-Grid"
description: "The freedom layout system used for ≤12 participants"
color: "bfd4f2"
- name: "A-Spotlight"
description: "Spotlight layout, where the active speaker is foregrounded"
color: "bfd4f2"
- name: "A-Telemetry-Posthog"
description: "Share opt in usage data for optimizing the app via posthog"
color: "bfd4f2"
- name: "A-Testing"
description: "Integration tests, unit tests, etc."
color: "bfd4f2"
- name: "A-Video-Rooms"
description: "Rooms reserved exclusively for calling"
color: "bfd4f2"
- name: "A-Walkie-Talkie"
description: "Walkie-talkie / PTT (push-to-talk) mode"
color: "bfd4f2"
- name: "A11y"
description: "Accessibility"
color: "4ADEC0"
- name: "backport-candidate"
description: "Something that is a candidate for backport to a particular release branch"
color: "0B8D85"
- name: "Claude-Review"
description: "Request code review from Claude"
color: "e57157"
- name: "customer-retainer"
color: "F44A5F"
- name: "dependencies"
description: "Pull requests that update a dependency file"
color: "0366d6"
- name: "development build"
description: "runs yarn build process in development mode"
color: "1d76db"
- name: "Discord"
description: "Use case familiar to Discord users"
color: "3670d2"
- name: "docker build"
description: "Creates a docker image for this PR"
color: "0e8a16"
- name: "EPIC"
color: "5319E7"
- name: "good first issue"
description: "Good for newcomers"
color: "7057ff"
- name: "Help Wanted"
description: "Community contributions are welcome!"
color: "159818"
- name: "I18n"
description: "Internationalisation"
color: "d4c5f9"
- name: "O-Frequent"
description: "Affects or can be seen by most users regularly or impacts most users' first experience"
color: "0052CC"
- name: "O-Occasional"
description: "Affects or can be seen by some users regularly or most users rarely"
color: "1D76DB"
- name: "O-Uncommon"
description: "Most users are unlikely to come across this or unexpected workflow"
color: "C5DEF5"
- name: "p1"
description: "Must fix/implement before this is usable as a product"
color: "D93F0B"
- name: "p2"
description: "Should fix/implement, but not at the expense of p1s"
color: "FBCA04"
- name: "p3"
description: "Could fix/implement when time allows"
color: "0E8A16"
- name: "PR-Breaking-Change"
description: "A Pull request that changes EC in a way that is incompatible to the previous version."
color: "D93F0B"
- name: "PR-Bug-Fix"
description: "Release note category. A PR that fixes a bug."
color: "C2E0C6"
- name: "PR-Developer-Experience"
description: "Release note category. A PR that does not change EC but improves working with the repository."
color: "C2E0C6"
- name: "PR-Documentation"
description: "Release note category. A PR that improves the documentation."
color: "C2E0C6"
- name: "PR-Feature"
description: "Release note category. A PR that introduces a new user facing feature."
color: "C2E0C6"
- name: "PR-Improvement"
description: "Release note category. A PR that improves EC's performance or stability."
color: "C2E0C6"
- name: "PR-Task"
description: "Release note category. A PR that is hidden from release note."
color: "C2E0C6"
- name: "Privacy"
color: "f41192"
- name: "Roadmap"
color: "57457E"
- name: "S-Critical"
description: "Prevents work, causes data loss and/or has no workaround"
color: "bd0026"
- name: "S-Major"
description: "Severely degrades major functionality or product features, with no satisfactory workaround"
color: "fc4e2a"
- name: "S-Minor"
description: "Impairs non-critical functionality or suitable workarounds exist"
color: "feb24c"
- name: "S-Tolerable"
description: "Low/no impact on users"
color: "ffeda0"
- name: "Security"
color: "b3e5fc"
- name: "storybook build"
description: "Build and deploy the storybook frontend to netlify."
color: "45cd61"
- name: "T-Defect"
description: "Something isn't working: bugs, crashes, hangs, vulnerabilities, or other reported problems"
color: "98e6ae"
- name: "T-Enhancement"
description: "New features, changes in functionality, performance boosts, user-facing improvements"
color: "98e6ae"
- name: "T-Other"
description: "Questions, user support, anything else"
color: "98e6ae"
- name: "T-Task"
description: "Refactoring, enabling or disabling functionality, other engineering tasks"
color: "98e6ae"
- name: "X-Blocked"
description: "Cannot be merged due to external dependencies"
color: "ff7979"
- name: "X-Cannot-Reproduce"
description: "Needs reproduction steps"
color: "ff7979"
- name: "X-Needs-Design"
description: "May require input from the design team"
color: "ff7979"
- name: "X-Needs-Info"
description: "This issue is blocked awaiting information from the reporter"
color: "ff7979"
- name: "X-Needs-Investigation"
color: "ff7979"
- name: "X-Needs-Product"
description: "More input needed from the Product team"
color: "ff7979"
- name: "X-Regression"
color: "ff7979"
- name: "X-Release-Blocker"
color: "ff7979"
- name: "X-Spec-Changes"
description: "May require spec changes"
color: "ff7979"
- name: "X-Won't-Fix"
description: "This will not be worked on"
color: "ff7979"
- name: "Z-Community-Testing"
description: "Issues found during the community testing sessions"
color: "efefef"
- name: "Z-Could"
color: "ededed"
- name: "Z-Design"
color: "ededed"
- name: "Z-Flaky-Test"
color: "aaaaaa"
- name: "Z-Media-Failure"
description: "Someone's audio or video isn't coming through"
color: "ededed"
- name: "Z-Must"
color: "ededed"
- name: "Z-Platform-Specific"
color: "ededed"
- name: "Z-Power-Users"
color: "ededed"
- name: "Z-ProductPolish"
color: "aaaaaa"
- name: "Z-Should"
color: "ededed"
- name: "Z-Splitbrain"
description: "Someone who should be on the call isn't showing up"
color: "ededed"
+30
View File
@@ -0,0 +1,30 @@
changelog:
categories:
- title: 🛠 Breaking Changes
labels:
- PR-Breaking-Change
- title: ✨ Features
labels:
- PR-Feature
- title: 🙌 Improvements
labels:
- PR-Improvement
- title: 📄 Documentation
labels:
- PR-Documentation
- title: 🐛 Bugfixes
labels:
- PR-Bug-Fix
- title: 💾 Developer Experience
labels:
- PR-Developer-Experience
- title: Others
labels:
- "*"
exclude:
labels:
- PR-Task
- dependencies
- title: 👒 Dependencies
labels:
- dependencies
+26
View File
@@ -0,0 +1,26 @@
name: Prevent blocked
on:
# zizmor: ignore[dangerous-triggers]
# Reason: This workflow does not checkout code or use secrets.
# It only reads labels to set a failure status on the PR.
pull_request_target:
types: [opened, labeled, unlabeled, synchronize]
permissions:
pull-requests: read
# Required to fail the check on the PR
statuses: write
jobs:
prevent-blocked:
name: Prevent blocked
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- name: Add notice
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
if: contains(github.event.pull_request.labels.*.name, 'X-Blocked')
with:
script: |
core.setFailed("PR has been labeled with X-Blocked; it cannot be merged.");
@@ -0,0 +1,103 @@
name: Build and publish docker image
on:
workflow_call:
inputs:
docker_tags:
required: true
type: string
artifact_run_id:
required: false
type: string
default: ${{ github.run_id }}
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build_and_deploy:
name: Build & publish docker
runs-on: ubuntu-latest
permissions:
contents: write # required to upload release asset
packages: write # needed for publishing packages to GHCR
id-token: write # needed for login into tailscale with GitHub OIDC Token
steps:
- name: Check it out
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: 📥 Download artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ inputs.artifact_run_id }}
name: build-output-full
path: dist
- name: Log in to container registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Connect to Tailscale
uses: tailscale/github-action@306e68a486fd2350f2bfc3b19fcd143891a4a2d8 # v4
if: github.event_name != 'pull_request'
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
audience: ${{ secrets.TS_AUDIENCE }}
tags: tag:github-actions
- name: Compute vault jwt role name
id: vault-jwt-role
if: github.event_name != 'pull_request'
run: |
echo "role_name=github_service_management_$( echo "${{ github.repository }}" | sed -r 's|[/-]|_|g')" | tee -a "$GITHUB_OUTPUT"
- name: Get team registry token
id: import-secrets
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3
if: github.event_name != 'pull_request'
with:
url: https://vault.infra.ci.i.element.dev
role: ${{ steps.vault-jwt-role.outputs.role_name }}
path: service-management/github-actions
jwtGithubAudience: https://vault.infra.ci.i.element.dev
method: jwt
secrets: |
services/voip-repositories/secret/data/oci.element.io username | OCI_USERNAME ;
services/voip-repositories/secret/data/oci.element.io password | OCI_PASSWORD ;
- name: Login to oci.element.io Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
if: github.event_name != 'pull_request'
with:
registry: oci-push.vpn.infra.element.io
username: ${{ steps.import-secrets.outputs.OCI_USERNAME }}
password: ${{ steps.import-secrets.outputs.OCI_PASSWORD }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
oci-push.vpn.infra.element.io/element-call
tags: ${{ inputs.docker_tags }}
labels: |
org.opencontainers.image.licenses=AGPL-3.0-only OR LicenseRef-Element-Commercial
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Build and push Docker image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+68
View File
@@ -0,0 +1,68 @@
name: Build Element Call
on:
workflow_call:
inputs:
vite_app_version:
required: true
type: string
package:
type: string # This would ideally be a `choice` type, but that isn't supported yet
description: The package type to be built. Must be one of 'full', 'embedded', or 'sdk'
required: true
build_mode:
type: string # This would ideally be a `choice` type, but that isn't supported yet
description: The build mode for vite. Must be either 'development' or 'production'
required: false
default: production
secrets:
SENTRY_ORG:
required: true
SENTRY_PROJECT:
required: true
SENTRY_URL:
required: true
SENTRY_AUTH_TOKEN:
required: true
CODECOV_TOKEN:
required: false
jobs:
build:
name: Build Element Call
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Enable Corepack
run: corepack enable
- name: pnpm cache
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
cache: "pnpm"
node-version-file: ".node-version"
- name: Install dependencies
# ignore-pnpmfile should never be commited. Make CI crash if it happened (`pnpmfileChecksum` is present)
run: "scripts/layered.sh --ignore-pnpmfile"
env:
PR_HEAD_REPO_OWNER: ${{ github.event.pull_request.head.repo.owner.login }}
- name: Build Element Call
run: pnpm run build:"$PACKAGE":"$BUILD_MODE"
env:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
VITE_APP_VERSION: ${{ inputs.vite_app_version }}
NODE_OPTIONS: "--max-old-space-size=4096"
PACKAGE: ${{ inputs.package }}
BUILD_MODE: ${{ inputs.build_mode }}
- name: Upload Artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: build-output-${{ inputs.package }}
path: dist
# We'll only use this in a triggered job, then we're done with it
retention-days: 1
+99 -9
View File
@@ -5,21 +5,111 @@ on:
- synchronize
- opened
- labeled
paths-ignore:
- ".github/**"
- "docs/**"
push:
branches: [livekit, full-mesh]
paths-ignore:
- ".github/**"
- "docs/**"
branches: [main]
jobs:
build_element_call:
uses: ./.github/workflows/element-call.yaml
build_full_element_call:
# Use the full package vite build
uses: ./.github/workflows/build-element-call.yaml
with:
package: full
vite_app_version: ${{ github.event.release.tag_name || github.sha }}
build_mode: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'development build') && 'development' || 'production' }}
secrets:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
deploy_develop:
# Deploy main branch to call.element.dev after build completes
if: github.ref == 'refs/heads/main'
needs: build_full_element_call
runs-on: ubuntu-latest
steps:
- name: Deploy to call.element.dev
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
with:
github-token: ${{ secrets.DEVELOP_DEPLOYMENT_TOKEN }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: 'element-hq',
repo: 'element-call-webapp-deployments',
workflow_id: 'deploy.yml',
ref: 'main',
inputs: {
target: 'call.element.dev',
version: '${{ github.sha }}'
}
})
docker_for_develop:
# Build docker and publish docker for main branch after build completes
if: github.ref == 'refs/heads/main'
needs: build_full_element_call
permissions:
contents: write
packages: write
id-token: write
uses: ./.github/workflows/build-and-publish-docker.yaml
secrets: inherit
with:
artifact_run_id: ${{ github.run_id }}
docker_tags: |
type=sha,format=short,event=branch
type=raw,value=latest-ci
type=raw,value=latest-ci_{{date 'X' }}
build_embedded_element_call:
# Use the embedded package vite build
uses: ./.github/workflows/build-element-call.yaml
with:
package: embedded
vite_app_version: ${{ github.event.release.tag_name || github.sha }}
build_mode: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'development build') && 'development' || 'production' }}
secrets:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
build_sdk_element_call:
# Use the embedded package vite build
uses: ./.github/workflows/build-element-call.yaml
with:
package: sdk
vite_app_version: ${{ github.event.release.tag_name || github.sha }}
build_mode: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'development build') && 'development' || 'production' }}
secrets:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
build_storybook:
name: Build Storybook
if: contains(github.event.pull_request.labels.*.name, 'storybook build')
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Enable Corepack
run: corepack enable
- name: pnpm cache
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
cache: "pnpm"
node-version-file: ".node-version"
- name: Install dependencies
run: "pnpm install --frozen-lockfile --ignore-pnpmfile"
- name: Build Storybook
run: pnpm run build-storybook
- name: Upload Artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: build-output-storybook
path: storybook-static
# We'll only use this in a triggered job, then we're done with it
retention-days: 1
+22
View File
@@ -0,0 +1,22 @@
name: PR changelog label
on:
# zizmor: ignore[dangerous-triggers]
# This is safe because we do not use actions/checkout or execute untrusted code.
# Using pull_request_target is necessary to allow status writes for PRs from forks.
pull_request_target:
types: [labeled, unlabeled, opened, synchronize]
permissions:
pull-requests: read
statuses: write
jobs:
pr-changelog-label:
runs-on: ubuntu-latest
steps:
- uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2
with:
REQUIRED_LABELS_ANY: "PR-Bug-Fix,PR-Documentation,PR-Task,PR-Feature,PR-Improvement,PR-Developer-Experience,dependencies,PR-Breaking-Change"
REQUIRED_LABELS_ANY_DESCRIPTION: "Select at least one 'PR-' label"
BANNED_LABELS: "banned"
+90
View File
@@ -0,0 +1,90 @@
name: Claude
on:
pull_request:
types: [labeled]
permissions:
# The action exchanges the GitHub OIDC token for a short-lived Anthropic
# access token. GitHub API access goes through CLAUDE_GH_TOKEN instead.
id-token: write
jobs:
review:
name: Review
# Only run on labelling and skip forks.
if: github.event.label.name == 'Claude-Review' && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
# The review looks at the individual commits, not just the combined diff
fetch-depth: 0
persist-credentials: false
- name: Review
uses: anthropics/claude-code-action@6fed3ca145920b639991cb756090506e1bcaf515 # v1.0.245
with:
anthropic_federation_rule_id: fdrl_01XQmWo4nka1ZTqZdsdeScyr
anthropic_organization_id: dfbc9a23-d636-4653-8970-035204ef60fa
anthropic_service_account_id: svac_018Ay5qaA7ZW8X7XsbdekqUM
anthropic_workspace_id: wrkspc_01Aw8LHjBS6fZysu9yqzYifW
# The token used here must grant read access to code, issues, and metadata as well as
# read and write access to pull requests.
github_token: ${{ secrets.CLAUDE_GH_TOKEN }}
use_sticky_comment: true
track_progress: true
prompt: |
Review this pull request under the following (and no further) angles:
1. Scope:
- Does the PR do one thing?
- Is the PR free of unrelated fixes and drive-by refactorings?
- If the PR is large, could it reasonably be split into smaller PRs
that still deliver value?
2. Commits:
- Is the work split into self-contained commits of reasonable size?
- Are the commits arranged in a sensible order?
- Have required refactorings been split out into separate commits?
- Is the history free of "wip", checkpoint and fixup-style commits
which only correct an earlier commit in the same PR?
3. Code:
- Are the code changes functionally correct?
- Do the changes introduce new security vulnerabilities or metadata
leaks?
- Is the new code performant enough?
- Don't check anything that is already validated via other GitHub
workflows like linting, formatting or tests passing.
Read the commits themselves with `git log` and `git diff` against
the base branch of the PR.
Drop any findings that are outside the above review angles or that don't
require resolution. Grade the severity of each finding as either "🟡 low",
"🟠 medium" or "🔴 high". Devise at least one possible resolution for each
finding.
Report the graded findings and resolutions from the "Code" angle as inline
comments. Add a footer "_-- Finding from automated review_" to each inline
comment.
Finally, report your overall result as PR comment. Start your message with
"# Automated review". Then add one section per review angle with:
- A verdict of "✅ PASS" or "❌ NEEDS WORK"
- A bullet list summarizing the remaining non-inlined graded findings and
resolutions (as nested bullets).
Be brief and concise in all your communication. Do not mention what you have
not covered and don't bring up issues that have already been fixed.
Use Markdown links for anything that can be navigated to on GitHub such
as files, commits, issues, pull requests, workflow runs, etc.
claude_args: |
--model claude-fable-5-1
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(git log:*),Bash(git diff:*),Bash(git show:*)"
--max-turns 50
@@ -1,4 +1,4 @@
name: Netlify - Deploy
name: Deploy to Netlify
on:
workflow_call:
inputs:
@@ -14,6 +14,10 @@ on:
deployment_ref:
required: true
type: string
package:
required: true
type: string
description: Which package to deploy - 'full', 'embedded', 'sdk', or 'storybook'
artifact_run_id:
required: false
type: string
@@ -39,34 +43,46 @@ jobs:
with:
step: start
token: ${{ secrets.GITHUB_TOKEN }}
env: Netlify
env: ${{ inputs.package}}
ref: ${{ inputs.deployment_ref }}
desc: |
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
Exercise caution. Use test accounts.
- name: 📥 Download artifact
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
run-id: ${{ inputs.artifact_run_id }}
name: build-output
name: build-output-${{ inputs.package }}
path: webapp
- name: Add redirects file
# We fetch from github directly as we don't bother checking out the repo
# Not needed for storybook deployments
if: inputs.package != 'storybook'
run: curl -s https://raw.githubusercontent.com/element-hq/element-call/main/config/netlify_redirects > webapp/_redirects
- name: Add config file
run: curl -s "https://raw.githubusercontent.com/${{ inputs.pr_head_full_name }}/${{ inputs.pr_head_ref }}/config/config_netlify_preview.json" > webapp/config.json
# Not needed for storybook deployments
if: inputs.package != 'storybook'
run: |
if [ "${INPUTS_PACKAGE}" = "full" ]; then
curl -s "https://raw.githubusercontent.com/${INPUTS_PR_HEAD_FULL_NAME}/${INPUTS_PR_HEAD_REF}/config/config_netlify_preview.json" > webapp/config.json
else
curl -s "https://raw.githubusercontent.com/${INPUTS_PR_HEAD_FULL_NAME}/${INPUTS_PR_HEAD_REF}/config/config_netlify_preview_sdk.json" > webapp/config.json
fi
env:
INPUTS_PACKAGE: ${{ inputs.package }}
INPUTS_PR_HEAD_FULL_NAME: ${{ inputs.pr_head_full_name }}
INPUTS_PR_HEAD_REF: ${{ inputs.pr_head_ref }}
- name: ☁️ Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0
with:
publish-dir: webapp
deploy-message: "Deploy from GitHub Actions"
alias: pr${{ inputs.pr_number }}
alias: ${{ inputs.package == 'sdk' && format('pr{0}-sdk', inputs.pr_number) || inputs.package == 'storybook' && format('pr{0}-storybook', inputs.pr_number) || format('pr{0}', inputs.pr_number) }}
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
-60
View File
@@ -1,60 +0,0 @@
name: Docker - Deploy
on:
workflow_call:
inputs:
docker_tags:
required: true
type: string
artifact_run_id:
required: false
type: string
default: ${{ github.run_id }}
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build_and_deploy:
name: Build & publish docker
runs-on: ubuntu-latest
permissions:
contents: write # required to upload release asset
packages: write
steps:
- name: Check it out
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- name: 📥 Download artifact
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ inputs.artifact_run_id }}
name: build-output
path: dist
- name: Log in to container registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: ${{ inputs.docker_tags}}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
- name: Build and push Docker image
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
-24
View File
@@ -1,24 +0,0 @@
name: Run E2E tests
on:
workflow_run:
workflows: ["deploy"]
types:
- completed
branches-ignore:
- "livekit"
jobs:
e2e:
name: E2E tests runs on Element Call
runs-on: ubuntu-latest
steps:
- name: Check out test private repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
repository: element-hq/static-call-participant
ref: refs/heads/main
path: static-call-participant
token: ${{ secrets.GH_E2E_TEST_TOKEN }}
- name: Build E2E Image
run: "cd static-call-participant && docker build --no-cache --tag matrixdotorg/chrome-node-static-call-participant:latest ."
- name: Run E2E tests in container
run: "docker run --rm -v '${{ github.workspace }}/static-call-participant/callemshost-users.txt:/opt/app/callemshost-users.txt' matrixdotorg/chrome-node-static-call-participant:latest ./e2e.sh"
-47
View File
@@ -1,47 +0,0 @@
name: Element Call - Build
on:
workflow_call:
inputs:
vite_app_version:
required: true
type: string
secrets:
SENTRY_ORG:
required: true
SENTRY_PROJECT:
required: true
SENTRY_URL:
required: true
SENTRY_AUTH_TOKEN:
required: true
jobs:
build:
name: Build Element Call
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- name: Yarn cache
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
with:
cache: "yarn"
node-version: "lts/*"
- name: Install dependencies
run: "yarn install"
- name: Build
run: "yarn run build"
env:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
VITE_APP_VERSION: ${{ inputs.vite_app_version }}
NODE_OPTIONS: "--max-old-space-size=4096"
- name: Upload Artifact
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4
with:
name: build-output
path: dist
# We'll only use this in a triggered job, then we're done with it
retention-days: 1
+30 -14
View File
@@ -1,27 +1,43 @@
name: Lint, format & type check
on:
pull_request: {}
workflow_call:
inputs:
matrix-js-sdk-sha:
type: string
required: false
description: The matrix-js-sdk commit to build against instead of the locked one
jobs:
prettier:
lint:
name: Lint, format & type check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- name: Yarn cache
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
cache: "yarn"
node-version: "lts/*"
# Inside a called workflow, github.repository is the caller so we need to make sure to still check out the EC repo here.
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-call' || github.repository }}
persist-credentials: false
- name: Enable Corepack
run: corepack enable
- name: pnpm cache
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
cache: "pnpm"
node-version-file: ".node-version"
- name: Install dependencies
run: "yarn install"
- name: Prettier
run: "yarn run prettier:check"
# ignore-pnpmfile should never be commited. Make CI crash if it happened (`pnpmfileChecksum` is present)
run: "scripts/layered.sh --ignore-pnpmfile"
env:
PR_HEAD_REPO_OWNER: ${{ github.event.pull_request.head.repo.owner.login }}
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
- name: Formatting
run: "pnpm run format:check"
- name: i18n
run: "yarn run i18n:check"
- name: ESLint
run: "yarn run lint:eslint"
run: "pnpm run i18n:check"
- name: Lint
run: "pnpm run lint:oxlint"
- name: Type check
run: "yarn run lint:types"
run: "pnpm run lint:types"
- name: Dead code analysis
run: "yarn run lint:knip"
run: "pnpm run lint:knip"
+52 -5
View File
@@ -1,5 +1,7 @@
name: PR Preview Deployments
name: Deploy previews for PRs
on:
# zizmor: ignore[dangerous-triggers]
# Reason: This is now restricted to internal PRs only using the 'if' condition below.
workflow_run:
workflows: ["Build"]
types:
@@ -7,7 +9,14 @@ on:
jobs:
prdetails:
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' }}
# Logic:
# 1. Build must be successful
# 2. Event must be a pull_request
# 3. Head repository must be the SAME as the base repository (No Forks!)
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.head_repository.full_name == github.repository
runs-on: ubuntu-latest
outputs:
pr_number: ${{ steps.prdetails.outputs.pr_id }}
@@ -20,17 +29,53 @@ jobs:
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
branch: ${{ github.event.workflow_run.head_branch }}
netlify:
netlify-full:
needs: prdetails
permissions:
deployments: write
uses: ./.github/workflows/netlify.yaml
uses: ./.github/workflows/deploy-to-netlify.yaml
with:
artifact_run_id: ${{ github.event.workflow_run.id || github.run_id }}
pr_number: ${{ needs.prdetails.outputs.pr_number }}
pr_head_full_name: ${{ github.event.workflow_run.head_repository.full_name }}
pr_head_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.ref }}
deployment_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.sha || github.ref || github.head_ref }}
package: full
secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
netlify-sdk:
needs: prdetails
permissions:
deployments: write
uses: ./.github/workflows/deploy-to-netlify.yaml
with:
artifact_run_id: ${{ github.event.workflow_run.id || github.run_id }}
pr_number: ${{ needs.prdetails.outputs.pr_number }}
pr_head_full_name: ${{ github.event.workflow_run.head_repository.full_name }}
pr_head_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.ref }}
deployment_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.sha || github.ref || github.head_ref }}
package: sdk
secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
netlify-storybook:
needs: prdetails
if: ${{ needs.prdetails.outputs.pr_data_json && contains(fromJSON(needs.prdetails.outputs.pr_data_json).labels.*.name, 'storybook build') }}
permissions:
deployments: write
uses: ./.github/workflows/deploy-to-netlify.yaml
with:
artifact_run_id: ${{ github.event.workflow_run.id || github.run_id }}
pr_number: ${{ needs.prdetails.outputs.pr_number }}
pr_head_full_name: ${{ github.event.workflow_run.head_repository.full_name }}
pr_head_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.ref }}
deployment_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.sha || github.ref || github.head_ref }}
package: storybook
secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
@@ -42,7 +87,9 @@ jobs:
permissions:
contents: write
packages: write
uses: ./.github/workflows/docker.yaml
id-token: write
uses: ./.github/workflows/build-and-publish-docker.yaml
secrets: inherit
with:
artifact_run_id: ${{ github.event.workflow_run.id || github.run_id }}
docker_tags: |
@@ -0,0 +1,328 @@
name: Build & publish embedded packages for releases
on:
release:
types: [published]
pull_request:
types:
- synchronize
- opened
- labeled
push:
branches: [main]
jobs:
versioning:
name: Versioning
runs-on: ubuntu-latest
outputs:
DRY_RUN: ${{ steps.dry_run.outputs.DRY_RUN }}
PREFIXED_VERSION: ${{ steps.prefixed_version.outputs.PREFIXED_VERSION }}
UNPREFIXED_VERSION: ${{ steps.unprefixed_version.outputs.UNPREFIXED_VERSION }}
TAG: ${{ steps.tag.outputs.TAG }}
steps:
- name: Calculate VERSION
# Safely store dynamic values in environment variables
# to prevent shell injection (template-injection)
run: |
# The logic is executed within the shell using the env variables
if [ "$EVENT_NAME" = "release" ]; then
echo "VERSION=$RELEASE_TAG" >> "$GITHUB_ENV"
else
echo "VERSION=v0.0.0-pre.0" >> "$GITHUB_ENV"
fi
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
EVENT_NAME: ${{ github.event_name }}
- id: dry_run
name: Set DRY_RUN
# We perform a dry run for all events except releases.
# This is to help make sure that we notice if the packaging process has become
# broken ahead of a release.
run: echo "DRY_RUN=${{ github.event_name != 'release' }}" >> "$GITHUB_OUTPUT"
- id: prefixed_version
name: Set PREFIXED_VERSION
run: echo "PREFIXED_VERSION=${VERSION}" >> "$GITHUB_OUTPUT"
- id: unprefixed_version
name: Set UNPREFIXED_VERSION
# This just strips the leading character
run: echo "UNPREFIXED_VERSION=${VERSION:1}" >> "$GITHUB_OUTPUT"
- id: tag
# latest = a proper release
# other = anything else
name: Set tag
run: |
if [[ "${VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "TAG=latest" >> "$GITHUB_OUTPUT"
elif [[ "${VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+\-rc\.[0-9]+$ ]]; then
echo "TAG=rc" >> "$GITHUB_OUTPUT"
else
echo "TAG=other" >> "$GITHUB_OUTPUT"
fi
build_element_call:
needs: versioning
uses: ./.github/workflows/build-element-call.yaml
with:
vite_app_version: embedded-${{ needs.versioning.outputs.PREFIXED_VERSION }}
package: embedded
secrets:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
publish_tarball:
needs: [build_element_call, versioning]
if: always()
name: Publish tarball
runs-on: ubuntu-latest
permissions:
contents: write # required to upload release asset
steps:
- name: Determine filename
run: echo "FILENAME_PREFIX=element-call-embedded-${NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION}" >> "$GITHUB_ENV"
env:
NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION: ${{ needs.versioning.outputs.UNPREFIXED_VERSION }}
- name: 📥 Download built element-call artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id || github.run_id }}
name: build-output-embedded
path: ${{ env.FILENAME_PREFIX}}
- name: Create Tarball
run: tar --numeric-owner -cvzf ${FILENAME_PREFIX}.tar.gz ${FILENAME_PREFIX}
- name: Create Checksum
run: find ${FILENAME_PREFIX} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${FILENAME_PREFIX}.sha256
- name: Upload
if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }}
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
files: |
${{ env.FILENAME_PREFIX }}.tar.gz
${{ env.FILENAME_PREFIX }}.sha256
publish_npm:
needs: [build_element_call, versioning]
if: always()
name: Publish NPM
runs-on: ubuntu-latest
outputs:
ARTIFACT_VERSION: ${{ steps.artifact_version.outputs.ARTIFACT_VERSION }}
permissions:
contents: read
id-token: write # Allow npm to authenticate as a trusted publisher
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: 📥 Download built element-call artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id || github.run_id }}
name: build-output-embedded
path: embedded/web/dist
# n.b. We don't enable corepack here because we are using plain npm
- name: Setup node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version-file: .node-version
registry-url: "https://registry.npmjs.org"
- name: Publish npm
working-directory: embedded/web
run: |
npm version ${NEEDS_VERSIONING_OUTPUTS_PREFIXED_VERSION} --no-git-tag-version
echo "ARTIFACT_VERSION=$(jq '.version' --raw-output package.json)" >> "$GITHUB_ENV"
npm publish --provenance --access public --tag ${NEEDS_VERSIONING_OUTPUTS_TAG} ${{ needs.versioning.outputs.DRY_RUN == 'true' && '--dry-run' || '' }}
env:
NEEDS_VERSIONING_OUTPUTS_PREFIXED_VERSION: ${{ needs.versioning.outputs.PREFIXED_VERSION }}
NEEDS_VERSIONING_OUTPUTS_TAG: ${{ needs.versioning.outputs.TAG }}
- id: artifact_version
name: Output artifact version
run: echo "ARTIFACT_VERSION=${ARTIFACT_VERSION}" >> "$GITHUB_OUTPUT"
publish_android:
needs: [build_element_call, versioning]
if: always()
name: Publish Android AAR
runs-on: ubuntu-latest
outputs:
ARTIFACT_VERSION: ${{ steps.artifact_version.outputs.ARTIFACT_VERSION }}
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: 📥 Download built element-call artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id || github.run_id }}
name: build-output-embedded
path: embedded/android/lib/src/main/assets/element-call
- name: ☕️ Setup Java
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
distribution: "temurin"
java-version: "17"
- name: Get artifact version
# Anything that is not a final release will be tagged as a snapshot
run: |
if [[ "${NEEDS_VERSIONING_OUTPUTS_TAG}" == "latest" ]]; then
echo "ARTIFACT_VERSION=${NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION}" >> "$GITHUB_ENV"
elif [[ "${NEEDS_VERSIONING_OUTPUTS_TAG}" == "rc" ]]; then
echo "ARTIFACT_VERSION=${NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION}" >> "$GITHUB_ENV"
else
echo "ARTIFACT_VERSION=${NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION}-SNAPSHOT" >> "$GITHUB_ENV"
fi
env:
NEEDS_VERSIONING_OUTPUTS_TAG: ${{ needs.versioning.outputs.TAG }}
NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION: ${{ needs.versioning.outputs.UNPREFIXED_VERSION }}
- name: Set version string
run: sed -i "s/0.0.0/${ARTIFACT_VERSION}/g" embedded/android/lib/src/main/kotlin/io/element/android/call/embedded/Version.kt
- name: Publish AAR
working-directory: embedded/android
env:
EC_VERSION: ${{ env.ARTIFACT_VERSION }}
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_RELEASE_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_RELEASE_PASSWORD }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }}
run: ./gradlew publishToMavenCentral --no-daemon ${{ needs.versioning.outputs.DRY_RUN == 'true' && '--dry-run' || '' }}
- id: artifact_version
name: Output artifact version
run: echo "ARTIFACT_VERSION=${ARTIFACT_VERSION}" >> "$GITHUB_OUTPUT"
publish_ios:
needs: [build_element_call, versioning]
if: always()
name: Publish SwiftPM Library
runs-on: ubuntu-latest
outputs:
ARTIFACT_VERSION: ${{ steps.artifact_version.outputs.ARTIFACT_VERSION }}
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
path: element-call
persist-credentials: false
- name: 📥 Download built element-call artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id || github.run_id }}
name: build-output-embedded
path: element-call/embedded/ios/Sources/dist
- name: Checkout element-call-swift
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
repository: element-hq/element-call-swift
path: element-call-swift
persist-credentials: false
- name: Copy files
run: rsync -a --delete --exclude .git element-call/embedded/ios/ element-call-swift
- name: Get artifact version
run: echo "ARTIFACT_VERSION=${NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION}" >> "$GITHUB_ENV"
env:
NEEDS_VERSIONING_OUTPUTS_UNPREFIXED_VERSION: ${{ needs.versioning.outputs.UNPREFIXED_VERSION }}
- name: Set version string
run: sed -i "s/0.0.0/${ARTIFACT_VERSION}/g" element-call-swift/Sources/EmbeddedElementCall/EmbeddedElementCall.swift
- name: Test build
working-directory: element-call-swift
run: swift build
- name: Commit and tag
working-directory: element-call-swift
run: |
git config --global user.email "ci@element.io"
git config --global user.name "Element CI"
git add -A
git commit -am "Release ${NEEDS_VERSIONING_OUTPUTS_PREFIXED_VERSION}"
git tag -a ${ARTIFACT_VERSION} -m "${GITHUB_EVENT_RELEASE_HTML_URL}"
env:
NEEDS_VERSIONING_OUTPUTS_PREFIXED_VERSION: ${{ needs.versioning.outputs.PREFIXED_VERSION }}
GITHUB_EVENT_RELEASE_HTML_URL: ${{ github.event.release.html_url }}
- name: Push
if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }}
working-directory: element-call-swift
run: |
git push "https://x-access-token:${SWIFT_RELEASE_TOKEN}@github.com/element-hq/element-call-swift.git" --tags
env:
SWIFT_RELEASE_TOKEN: ${{ secrets.SWIFT_RELEASE_TOKEN }}
- id: artifact_version
name: Output artifact version
run: echo "ARTIFACT_VERSION=${ARTIFACT_VERSION}" >> "$GITHUB_OUTPUT"
release_notes:
needs: [versioning, publish_npm, publish_android, publish_ios]
if: always()
name: Update release notes
runs-on: ubuntu-latest
permissions:
contents: write # to update release notes
steps:
- name: Log versions
run: |
echo "NPM: ${NEEDS_PUBLISH_NPM_OUTPUTS_ARTIFACT_VERSION}"
echo "Android: ${NEEDS_PUBLISH_ANDROID_OUTPUTS_ARTIFACT_VERSION}"
echo "iOS: ${NEEDS_PUBLISH_IOS_OUTPUTS_ARTIFACT_VERSION}"
env:
NEEDS_PUBLISH_NPM_OUTPUTS_ARTIFACT_VERSION: ${{ needs.publish_npm.outputs.ARTIFACT_VERSION }}
NEEDS_PUBLISH_ANDROID_OUTPUTS_ARTIFACT_VERSION: ${{ needs.publish_android.outputs.ARTIFACT_VERSION }}
NEEDS_PUBLISH_IOS_OUTPUTS_ARTIFACT_VERSION: ${{ needs.publish_ios.outputs.ARTIFACT_VERSION }}
- name: Add release notes
if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }}
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
append_body: true
body: |
## Embedded packages
This release includes the following embedded packages that allow Element Call to be used as an embedded widget
within another application.
### NPM
```
npm install @element-hq/element-call-embedded@${{ needs.publish_npm.outputs.ARTIFACT_VERSION }}
```
### Android AAR
```
dependencies {
implementation 'io.element.android:element-call-embedded:${{ needs.publish_android.outputs.ARTIFACT_VERSION }}'
}
```
### SwiftPM
```
.package(url: "https://github.com/element-hq/element-call-swift.git", from: "${{ needs.publish_ios.outputs.ARTIFACT_VERSION }}")
```
+46 -33
View File
@@ -1,72 +1,85 @@
name: Build & publish images to the package registry for tags
name: Build & publish full packages for releases
on:
release:
types: [published]
workflow_run:
workflows: ["Build"]
branches: [livekit]
types:
- completed
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
VERSION: ${{ github.event.release.tag_name }}
jobs:
build_element_call:
if: ${{ github.event_name == 'release' }}
uses: ./.github/workflows/element-call.yaml
uses: ./.github/workflows/build-element-call.yaml
with:
vite_app_version: ${{ github.event.release.tag_name || github.sha }}
package: full
vite_app_version: ${{ github.event.release.tag_name }} # Using ${{ env.VERSION }} here doesn't work
secrets:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
publish_tarball:
needs: build_element_call
if: always()
name: Publish tarball
runs-on: ubuntu-latest
outputs:
unix_time: ${{steps.current-time.outputs.unix_time}}
permissions:
contents: write # required to upload release asset
packages: write
steps:
- name: Get current time
id: current-time
run: echo "unix_time=$(date +'%s')" >> $GITHUB_OUTPUT
- name: 📥 Download artifact
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
- name: Determine filename
run: echo "FILENAME_PREFIX=element-call-${VERSION:1}" >> "$GITHUB_ENV"
- name: 📥 Download built element-call artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id || github.run_id }}
name: build-output
path: dist
name: build-output-full
path: ${{ env.FILENAME_PREFIX }}
- name: Create Tarball
env:
TARBALL_VERSION: ${{ github.event.release.tag_name || github.sha }}
run: |
tar --numeric-owner --transform "s/dist/element-call-${TARBALL_VERSION}/" -cvzf element-call-${TARBALL_VERSION}.tar.gz dist
run: tar --numeric-owner --transform "s/dist/${FILENAME_PREFIX}/" -cvzf ${FILENAME_PREFIX}.tar.gz ${FILENAME_PREFIX}
- name: Create Checksum
run: find ${FILENAME_PREFIX} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${FILENAME_PREFIX}.sha256
- name: Upload
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
env:
GITHUB_TOKEN: ${{ github.token }}
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
path: "./element-call-*.tar.gz"
files: |
${{ env.FILENAME_PREFIX }}.tar.gz
${{ env.FILENAME_PREFIX }}.sha256
publish_docker:
needs: publish_tarball
needs: build_element_call
if: always()
name: Publish docker
permissions:
contents: write
packages: write
uses: ./.github/workflows/docker.yaml
id-token: write
uses: ./.github/workflows/build-and-publish-docker.yaml
secrets: inherit
with:
artifact_run_id: ${{ github.event.workflow_run.id || github.run_id }}
docker_tags: |
type=sha,format=short,event=branch
type=semver,pattern=v{{version}}
type=raw,value=latest-ci,enable={{is_default_branch}}
type=raw,value=latest-ci_${{needs.publish_tarball.outputs.unix_time}},enable={{is_default_branch}}
type=raw,value=${{ github.event.release.tag_name }}
type=raw,value=latest
# Like before, using ${{ env.VERSION }} above doesn't work
add_docker_release_note:
needs: publish_docker
name: Add docker release note
runs-on: ubuntu-latest
steps:
- name: Add release note
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
append_body: true
body: |
## Docker full package
Element Call is available as a Docker image from the [GitHub Container Registry](https://github.com/element-hq/element-call/pkgs/container/element-call).
The image provides a full build of Element Call that can be used both in standalone and as a widget (on a remote URL).
```
docker pull ghcr.io/element-hq/element-call:${{ env.VERSION }}
```
+23
View File
@@ -0,0 +1,23 @@
name: Sync labels
on:
workflow_dispatch: {}
push:
branches:
- main
paths:
- .github/labels.yml
- .github/workflows/sync-labels.yml
permissions: {} # We use LABEL_SYNC_GITHUB_TOKEN instead
jobs:
sync-labels:
uses: element-hq/element-meta/.github/workflows/sync-labels.yml@7f2f93fb9b52ece7a0998f60e64862aa203c1746
with:
LABELS: |
.github/labels.yml
DELETE: true
WET: true
secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.LABEL_SYNC_GITHUB_TOKEN }}
+48
View File
@@ -0,0 +1,48 @@
# Triggers after the playwright tests have finished,
# taking the artifact and uploading it to Netlify for easier viewing
name: Upload End to End Test report to Netlify
on:
# Privilege escalation necessary to publish to Netlify
# 🚨 We must not execute any checked out code here.
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: ["Test"]
types:
- completed
concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
cancel-in-progress: ${{ github.event.workflow_run.event == 'pull_request' }}
permissions: {}
jobs:
report:
if: github.event.workflow_run.conclusion != 'cancelled'
name: Report results
runs-on: ubuntu-24.04
environment: Netlify
permissions:
statuses: write
deployments: write
actions: read
steps:
- name: Download HTML report
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
name: html-report
path: playwright-report
- name: 📤 Deploy to Netlify
uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3
with:
path: playwright-report
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
branch: ${{ github.event.workflow_run.head_branch }}
revision: ${{ github.event.workflow_run.head_sha }}
token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
site_id: ${{ secrets.NETLIFY_SITE_ID }}
desc: Playwright Report
deployment_env: EndToEndTests
prefix: "e2e-"
+106 -11
View File
@@ -1,28 +1,123 @@
name: Run unit tests
name: Test
on:
pull_request: {}
push:
branches: [livekit, full-mesh]
branches: [main]
workflow_call:
inputs:
matrix-js-sdk-sha:
type: string
required: false
description: The matrix-js-sdk commit to build against instead of the locked one
disable_coverage:
type: boolean
required: false
default: false
description: Skip generating and uploading coverage reports
disable_e2e_tests:
type: boolean
required: false
default: false
description: Skip the end-to-end tests
secrets:
CODECOV_TOKEN:
required: false
jobs:
vitest:
name: Run vitest tests
name: Run unit tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- name: Yarn cache
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
cache: "yarn"
node-version: "lts/*"
# Inside a called workflow, github.repository is the caller so we need to make sure to still check out the EC repo here.
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-call' || github.repository }}
persist-credentials: false
- name: Enable Corepack
run: corepack enable
- name: pnpm cache
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
cache: "pnpm"
node-version-file: ".node-version"
- name: Install dependencies
run: "yarn install"
# ignore-pnpmfile should never be commited. Make CI crash if it happened (`pnpmfileChecksum` is present)
run: "scripts/layered.sh --ignore-pnpmfile"
env:
PR_HEAD_REPO_OWNER: ${{ github.event.pull_request.head.repo.owner.login }}
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
- name: Get Playwright version
run: echo "PLAYWRIGHT_VERSION=$(pnpm list @playwright/test --depth=0 --json | jq -r '.[0].devDependencies["@playwright/test"].version')" >> $GITHUB_ENV
- name: Cache Playwright binaries
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
- name: Install Playwright binaries
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: pnpm playwright install --with-deps
- name: Vitest
run: "yarn run test:coverage"
run: pnpm vitest --coverage.enabled="$ENABLE_COVERAGE"
env:
ENABLE_COVERAGE: ${{ !inputs.disable_coverage }}
- name: Upload to codecov
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4
if: ${{ !inputs.disable_coverage }}
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
flags: unittests
fail_ci_if_error: true
playwright:
name: Run end-to-end tests
if: ${{ !inputs.disable_e2e_tests }}
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# Inside a called workflow, github.repository is the caller so we need to make sure to still check out the EC repo here.
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-call' || github.repository }}
persist-credentials: false
- name: Enable Corepack
run: corepack enable
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
cache: "pnpm"
node-version-file: ".node-version"
- name: Install dependencies
# ignore-pnpmfile should never be commited. Make CI crash if it happened (`pnpmfileChecksum` is present)
run: scripts/layered.sh --ignore-pnpmfile
env:
PR_HEAD_REPO_OWNER: ${{ github.event.pull_request.head.repo.owner.login }}
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
- name: Get Playwright version
run: echo "PLAYWRIGHT_VERSION=$(pnpm list @playwright/test --depth=0 --json | jq -r '.[0].devDependencies["@playwright/test"].version')" >> $GITHUB_ENV
- name: Cache Playwright binaries
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
- name: Install Playwright binaries
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: pnpm playwright install --with-deps
- name: Run backend components
run: |
docker compose -f docker-compose-dev.yml -f docker-compose-playwright.yml pull
docker compose -f docker-compose-dev.yml -f docker-compose-playwright.yml up -d
docker ps
- name: Run Playwright tests
env:
USE_DOCKER: 1
run: pnpm exec playwright test
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ !cancelled() }}
with:
name: html-report
path: playwright-report
if-no-files-found: error
retention-days: 4
+23 -12
View File
@@ -13,18 +13,24 @@ jobs:
steps:
- name: Checkout the code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
cache: "yarn"
node-version: "lts/*"
persist-credentials: false
- name: Enable Corepack
run: corepack enable
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
cache: "pnpm"
node-version-file: ".node-version"
- name: Install Deps
run: "yarn install --frozen-lockfile"
# ignore-pnpmfile should never be commited. Make CI crash if it happened (`pnpmfileChecksum` is present)
run: "pnpm install --frozen-lockfile --ignore-pnpmfile"
- name: Prune i18n
run: "rm -R public/locales"
run: "rm -R locales"
- name: Download translation files
uses: localazy/download@0a79880fb66150601e3b43606fab69c88123c087 # v1.1.0
@@ -32,14 +38,19 @@ jobs:
groups: "-p includeSourceLang:true"
- name: Fix the owner of the downloaded files
run: "sudo chown runner:docker -R public/locales"
run: "sudo chown runner:docker -R locales"
- name: Prettier
run: yarn prettier:format
# Localazy doesn't write file contents in the same order that i18next-cli's
# extractor uses. We re-run the extractor after downloading to fix the order.
- name: i18n
run: pnpm i18n
- name: Formatting
run: pnpm format
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11
with:
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
branch: actions/localazy-download
@@ -47,7 +58,7 @@ jobs:
title: Localazy Download
commit-message: Translations updates
labels: |
T-Task
PR-Task
- name: Enable automerge
run: gh pr merge --merge --auto "$PR_NUMBER"
+4 -2
View File
@@ -2,7 +2,7 @@ name: Upload translation files to Localazy
on:
push:
branches:
- livekit
- main
paths-ignore:
- ".github/**"
@@ -14,7 +14,9 @@ jobs:
steps:
- name: Checkout the code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Upload
uses: localazy/upload@27e6b5c0fddf4551596b42226b1c24124335d24a # v1
+23
View File
@@ -0,0 +1,23 @@
name: GitHub Actions Security Analysis with zizmor 🌈
on:
push:
branches: ["main", "full-mesh"]
pull_request: {}
permissions: {}
jobs:
zizmor:
name: Run zizmor 🌈
runs-on: ubuntu-latest
permissions:
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Run zizmor 🌈
uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7
+37
View File
@@ -2,9 +2,46 @@ node_modules
.DS_Store
.env
dist
dist-embedded
dist-ssr
*.local
*.bkp
.idea/
public/config.json
backend/synapse_tmp/*
backend/synapse_tmp_othersite/*
/coverage
# Transient agent scratch files
/agent-workspace/
config.json
# Yarn
yarn-error.log
/.pnp.*
/.yarn/*
!/.yarn/patches
!/.yarn/plugins
!/.yarn/releases
!/.yarn/sdks
!/.yarn/versions
# old yarn based linking
/.links.yaml
/.links.disabled.yaml
/.links.temp-disabled.yaml
# pnpm based linking
/.links.cjs
/.links.disabled.cjs
/.links.temp-disabled.cjs
# Playwright
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
*storybook.log
storybook-static
# Nested checkout made by scripts/layered.sh
/matrix-js-sdk/
+1
View File
@@ -0,0 +1 @@
24
+6
View File
@@ -0,0 +1,6 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"printWidth": 80,
"sortPackageJson": false,
"ignorePatterns": ["pnpm-lock.yaml", "node_modules", "dist"]
}
+165
View File
@@ -0,0 +1,165 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": [
"eslint",
"import",
"jsdoc",
"jsx-a11y",
"promise",
"react",
"typescript",
"unicorn",
"vitest"
],
"jsPlugins": [
"eslint-plugin-storybook",
"eslint-plugin-element-call"
// TODO: Re-enable once oxlint supports lint rules that rely on TypeScript type-awareness.
// "eslint-plugin-rxjs"
],
"categories": {
"correctness": "error",
"perf": "error"
},
"options": {
"denyWarnings": true,
"typeAware": true
},
"env": {
"builtin": true
},
"rules": {
"element-call/copyright-header": [
"error",
"/*\nCopyright %%CURRENT_YEAR%% Element Creations Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE in the repository root for full details.\n*/\n\n"
],
"element-call/no-observablescope-leak": "error",
"element-call/no-top-level-logger-get-child": "error",
"jsdoc/empty-tags": "error",
"jsdoc/check-property-names": "error",
"jsdoc/require-param-description": "warn",
"react/display-name": "error",
// TODO: These React Compiler-based rules joined oxlint's correctness
// category in v1.81 and flag many pre-existing patterns, including hooks
// like useLatest/useInitial/useReactiveState that intentionally access
// refs during render. Re-evaluate them when adopting the React Compiler.
"react/immutability": "off",
"react/no-deriving-state-in-effects": "off",
"react/preserve-manual-memoization": "off",
"react/refs": "off",
"react/set-state-in-effect": "off",
"react/static-components": "off",
"react/use-memo": "off",
// TODO: Re-enable once oxlint supports lint rules that rely on TypeScript type-awareness.
// "rxjs/no-exposed-subjects": "error",
// "rxjs/finnish": [
// "error",
// {
// "names": {
// "^this$": false
// }
// }
// ],
"no-restricted-imports": [
"error",
{
"patterns": [
{
"group": [
"matrix-widget-api/src",
"matrix-widget-api/src/",
"matrix-widget-api/src/**",
"matrix-widget-api/lib",
"matrix-widget-api/lib/",
"matrix-widget-api/lib/**"
],
"message": "Please use matrix-widget-api instead"
},
{
"group": [
"matrix-js-sdk/src",
"matrix-js-sdk/src/",
"matrix-js-sdk/src/**",
"matrix-js-sdk/lib",
"matrix-js-sdk/lib/",
"matrix-js-sdk/lib/index"
],
"message": "Please use matrix-js-sdk instead"
}
]
}
],
"typescript/no-floating-promises": "error",
"typescript/no-misused-promises": "error",
"typescript/promise-function-async": "error",
"typescript/require-await": "error",
"typescript/await-thenable": "error",
// To help ensure that we get proper vite/rollup lazy loading (e.g. for matrix-js-sdk).
"typescript/consistent-type-imports": [
"error",
{
"fixStyle": "inline-type-imports"
}
],
// TODO: These had to be disabled in the eslint -> oxlint migration. Would be nice to
// enable them in future or at least document why we're disabling them.
"eslint/no-await-in-loop": "off",
"eslint/no-unused-vars": ["error", { "args": "none" }],
"import/default": "off",
"jsdoc/check-tag-names": "off",
"jsx-a11y/prefer-tag-over-role": "off",
"promise/no-callback-in-promise": "off",
"react/jsx-key": "off",
"react/jsx-no-constructed-context-values": "off",
"react/no-array-index-key": "off",
"react/no-children-prop": "off",
"react/no-object-type-as-default-prop": "off",
"typescript/no-misused-spread": "off",
"typescript/no-useless-default-assignment": "off",
"typescript/restrict-template-expressions": "off",
"typescript/unbound-method": "off",
"vitest/expect-expect": "off",
"vitest/no-conditional-expect": "off",
"vitest/no-disabled-tests": "off",
"vitest/require-mock-type-parameters": "off",
"vitest/require-to-throw-message": "off"
},
"overrides": [
{
"files": ["src/*/**"],
"rules": {
// In application code we should use the js-sdk logger, never console directly.
"no-console": "error"
}
},
{
"files": [
"**/*.test.ts",
"**/*.test.tsx",
"**/test.ts",
"**/test.tsx",
"**/test-**"
],
"rules": {
// Tests often initialize an ObservableScope in an outer scope in
// beforeEach, which is not actually a problem
"element-call/no-observablescope-leak": "off",
"jsdoc/empty-tags": "off",
"jsdoc/check-property-names": "off",
"jsdoc/require-param-description": "off",
"jsx-a11y/media-has-caption": "off"
// TODO: Enable once oxlint supports them.
// "jsdoc/check-values": "off",
// "jsdoc/check-param-names": "off",
// "jsdoc/no-types": "off",
}
},
{
"files": ["playwright/**"],
"rules": {
// Playwright as a `use` function that has nothing to do with React hooks.
"react-hooks/rules-of-hooks": "off"
}
}
]
}
-2
View File
@@ -1,2 +0,0 @@
node_modules
dist
-1
View File
@@ -1 +0,0 @@
{}
+36
View File
@@ -0,0 +1,36 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import type { StorybookConfig } from "@storybook/react-vite";
const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: ["@storybook/addon-docs", "@storybook/addon-vitest"],
framework: "@storybook/react-vite",
// THIS IS IMPORTANT
// vitest runs without Vite's normal dependency optimization, so we need to manually include the polyfills for the stories to work.
// otherwise we will get: new dependencies optimized: ...
// and
// ```
// [vitest] Vite unexpectedly reloaded a test. This may cause tests to fail, lead to flaky behaviour or duplicated test runs.
// For a stable experience, please add mentioned dependencies to your config's `optimizeDeps.include` field manually.
// ```
// which breaks the storybook ci on the first and only run.
viteFinal(config) {
config.optimizeDeps = {
...config.optimizeDeps,
include: [
...(config.optimizeDeps?.include ?? []),
"vite-plugin-node-polyfills/shims/buffer",
"vite-plugin-node-polyfills/shims/global",
"vite-plugin-node-polyfills/shims/process",
],
};
return config;
},
};
export default config;
+31
View File
@@ -0,0 +1,31 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { create } from "storybook/theming";
import { addons } from "storybook/manager-api";
addons.setConfig({
theme: create({
base: "light",
colorPrimary: "#1b1d22",
colorSecondary: "#0467dd",
// Typography
fontBase: '"Inter", sans-serif',
fontCode: '"Inconsolata", monospace',
// Text colors
textColor: "#1b1d22",
appBg: "#ffffff",
barBg: "#ffffff",
brandTitle: "Element Call",
brandUrl: "https://element.io/",
brandImage: "/src/icons/Logo.svg",
brandTarget: "_self",
}),
});
+58
View File
@@ -0,0 +1,58 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import type { Preview } from "@storybook/react-vite";
import { TooltipProvider } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/lib/logger";
import EN from "../locales/en/app.json";
import { initReactI18next } from "react-i18next";
import { i18n } from "../src/utils/i18n";
import "../src/index.css";
// Bare-minimum i18n config.
// Unlike the app, stories register the instance as react-i18next's default
// rather than wrapping every story in an <I18nextProvider>.
i18n
.use(initReactI18next)
.init({
lng: "en",
fallbackLng: "en",
supportedLngs: ["en"],
// We embed the translations, so that it never needs to fetch
resources: {
en: {
translation: EN,
},
},
interpolation: {
escapeValue: false, // React has built-in XSS protections
},
})
.catch((e) => logger.warn("Failed to init i18n for stories", e));
const preview: Preview = {
parameters: {
layout: "centered",
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
tags: ["autodocs"],
decorators: [
(Story) => (
<TooltipProvider>
<Story />
</TooltipProvider>
),
],
};
export default preview;
+56
View File
@@ -0,0 +1,56 @@
# AGENTS.md — Element Call
MatrixRTC (MSC4143) + LiveKit video calling, shipped standalone, as a widget in
Element Web and Element X, as embedded packages, and as a React component in a
host's page. It is the MatrixRTC reference implementation.
## Non-negotiables
- Features and UI changes need a pre-approved issue. No issue, no review.
- Exactly one `PR-*` label per PR. CI enforces it; it drives the changelog.
- New behaviour ships with unit tests, a story if it renders, and an e2e spec if it
is user-facing. All three.
- Reuse an existing component. If you genuinely cannot, say so in the PR body and
name what you rejected — never add a new one silently.
- Nothing reads the page. No `window.location`, `document.body`, `window.inner*`,
`@media`, global `i18next` or the `widget` global — take it from a provider.
- The change works standalone, as a widget and as a component. Say what you checked.
- Every gate below is green before you push.
- Hand off after the first implementation, before the quality pass. Then commit on
the user's word where the setup allows it, or hand them the message.
## Read before you
| … | … |
| -------------------------------- | ---------------------------------------------------------- |
| start a task of any size | [docs/agents/workflow.md](docs/agents/workflow.md) |
| touch call logic or a view model | [docs/agents/architecture.md](docs/agents/architecture.md) |
| write any code | [docs/agents/code-style.md](docs/agents/code-style.md) |
| write a test, story or e2e spec | [docs/agents/testing.md](docs/agents/testing.md) |
| open a PR | [CONTRIBUTING.md](CONTRIBUTING.md) |
| implement from a feature spec | [FEATURES_SPEC/AGENTS.md](FEATURES_SPEC/AGENTS.md) |
## Gates
```sh
pnpm lint # tsc, oxlint, knip, component externals
pnpm format # oxfmt
pnpm test # vitest: unit and storybook projects
pnpm i18n:check
```
`knip` fails on dead code; a file deliberately inert ahead of its consumer goes in
`knip.ts` `ignoreFiles` with a reason.
## A good PR
- One slice, under ~400 changed lines, green on its own, linked to its issue.
- View model + marble tests, thin view, a story per state, an e2e spec.
- Any new shared component called out explicitly, with why nothing existing fit.
- Template filled for real: what, why, before/after screenshots, repro steps.
- Comments only where the code can't give the reason — see
[code-style.md](docs/agents/code-style.md#comments).
- Anything that redraws continuously — an animation frame, a stream — says what it
costs, or better, counts the redraws in a test.
- Branch `<handle>/<topic>`. Plain imperative commit subjects, no prefixes.
- Once review starts, fix forward. Never force-push a regeneration over a review.
+68
View File
@@ -1,3 +1,71 @@
# Contributing code to Element
Element follows the same pattern as the [matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/blob/develop/CONTRIBUTING.md).
# Contributing to Element Call
Element Call is a native Matrix video conferencing application built on
[MatrixRTC (MSC4143)](https://github.com/matrix-org/matrix-spec-proposals/pull/4143)
and [LiveKit](https://livekit.io/). It runs in multiple deployment contexts — as a
standalone web app and as a widget embedded in Element Web, Element X iOS, and
Element X Android. It is also the primary R&D foundation for MatrixRTC, which means
its architecture, maintainability, and flexibility are held to a high standard.
We welcome contributions from the community. This document explains how to
contribute effectively so that both you and the maintainers get the best outcome.
## Issue First Policy
> [!IMPORTANT]
> Before writing a single line of code for a new feature or UI change, you **must**
> open an issue and have the approach agreed with the maintainers.
>
> **We will not review or merge feature or UI pull requests that arrive without a
> corresponding, pre-approved issue.**
This is not gatekeeping — it's how we prevent wasted effort on both sides. Element
Call must work correctly across multiple deployment contexts and meet specific product
and design requirements. It is also a fast-moving codebase that underpins ongoing
MatrixRTC development. A PR that looks reasonable in isolation can easily conflict
with in-progress work, planned architecture changes, or design decisions that haven't
been publicly documented yet.
The issue is where we resolve all of that **before** anyone writes code.
**Bug fixes** are no exception — most confirmed bugs should already have an issue anyways, existing issues that are marked as bugs have an implicit maintainer approval. If the solution for the bug is controversial it is highly recommended to discuss the approach in the issue before opening a PR.
## Contribution Workflow
1. **Open an issue** using the [Enhancement request](https://github.com/element-hq/element-call/issues/new?template=enhancement.yml) template.
2. **Wait for feedback.** A maintainer will comment on the issue **within two weeks**. The use case and approach will get dicussed.
This may involve questions, suggestions, or a request to adjust scope.
This also allows to bring design and product into the loop before code gets created.
3. **Get a green light.** Wait for explicit approval from a maintainer before starting
implementation.
4. **Implement.** Write the code against the agreed approach.
5. **Open a PR.** Link to the issue in your PR description and satisfy the checklist
in the PR template.
## Code Quality
Element Call moves fast and the codebase must stay clean and maintainable.
- **Take responsibility for AI-generated code.** AI tools can be a useful aid, but we expect all the generated code to be understood and reasoned about by the contributor. Questions by the maintainers should be answered without just forwarding them to AI. The maintainers also have access to AI tools. If your contribution is just transporting messages between LLM <-> maintaines all our time is better used if the maintainers decide to interact with AI for this specific problem by themselves.
- **Think across deployment contexts.** Changes must work correctly in both standalone
and widget modes. Consider how your change interacts with Element Web, Element X
iOS, and Element X Android.
- **Write tests.** New functionality should be covered by tests. Where it is feasible,
existing uncovered code touched by your PR should also gain tests.
## Contributor License Agreement
All contributors must sign the
[Element Contributor License Agreement](https://cla-assistant.io/element-hq/element-call)
before their contribution can be merged. The CLA assistant bot will prompt you
automatically when you open a PR.
## Getting Help
The best place to ask questions about Element Call development is the MatrixRTC room:
**[#matrixRtc:matrix.org](https://matrix.to/#/#matrixrtc:matrix.org)**
+11 -8
View File
@@ -1,10 +1,13 @@
FROM nginxinc/nginx-unprivileged:alpine
FROM alpine AS builder
COPY ./dist /dist
# Compress assets to work with nginx-gzip-static-module
WORKDIR /dist/assets
RUN gzip -k ../index.html *.js *.map *.css *.wasm *-app-*.json
FROM nginxinc/nginx-unprivileged:alpine-slim
COPY --from=builder ./dist /app
COPY ./dist /app
COPY config/nginx.conf /etc/nginx/conf.d/default.conf
USER root
RUN rm -rf /usr/share/nginx/html
USER 101
-177
View File
@@ -1,177 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
+661
View File
@@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.
+6
View File
@@ -0,0 +1,6 @@
Licensees holding a valid commercial license with Element may use this
software in accordance with the terms contained in a written agreement
between you and Element.
To purchase a commercial license please contact our sales team at
licensing@element.io
+462 -95
View File
@@ -2,151 +2,486 @@
[![Chat](https://img.shields.io/matrix/webrtc:matrix.org)](https://matrix.to/#/#webrtc:matrix.org)
[![Localazy](https://img.shields.io/endpoint?url=https%3A%2F%2Fconnect.localazy.com%2Fstatus%2Felement-call%2Fdata%3Fcontent%3Dall%26title%3Dlocalazy%26logo%3Dtrue)](https://localazy.com/p/element-call)
[![License](https://img.shields.io/github/license/element-hq/element-call)](LICENSE-AGPL-3.0)
[![Codecov](https://img.shields.io/codecov/c/github/element-hq/element-call)](https://app.codecov.io/gh/element-hq/element-call)
Group calls with WebRTC that leverage [Matrix](https://matrix.org) and an open-source WebRTC toolkit from [LiveKit](https://livekit.io/).
[🎬 Live Demo 🎬](https://call.element.io)
For prior version of the Element Call that relied solely on full-mesh logic, check [`full-mesh`](https://github.com/element-hq/element-call/tree/full-mesh) branch.
The world's first 🌐 decentralized and 🤝 federated video conferencing solution
powered by **the Matrix protocol**.
![A demo of Element Call with six people](demo.jpg)
## 📌 Overview
To try it out, visit our hosted version at [call.element.io](https://call.element.io). You can also find the latest development version continuously deployed to [call.element.dev](https://call.element.dev/).
**Element Call** is a native Matrix video conferencing application developed by
[Element](https://element.io/), designed for **secure**, **scalable**,
**privacy-respecting**, and **decentralized** video and voice calls over the
Matrix protocol. Built on **MatrixRTC**
([MSC4143](https://github.com/matrix-org/matrix-spec-proposals/pull/4143)), it
utilizes
**[MSC4195](https://github.com/hughns/matrix-spec-proposals/blob/hughns/matrixrtc-livekit/proposals/4195-matrixrtc-livekit.md)**
with **[LiveKit](https://livekit.io/)** as its backend.
## Host it yourself
![A demo of Element Call with six people](demo.gif)
Until prebuilt tarballs are available, you'll need to build Element Call from source. First, clone and install the package:
You can find the latest development version continuously deployed to
[call.element.dev](https://call.element.dev/).
```
git clone https://github.com/element-hq/element-call.git
cd element-call
yarn
yarn build
```
> [!NOTE]
> For prior version of the Element Call that relied solely on full-mesh logic,
> check [`full-mesh`](https://github.com/element-hq/element-call/tree/full-mesh)
> branch.
If all went well, you can now find the build output under `dist` as a series of static files. These can be hosted using any web server that can be configured with custom routes (see below).
## ✨ Key Features
You may also wish to add a configuration file (Element Call uses the domain it's hosted on as a Homeserver URL by default,
but you can change this in the config file). This goes in `public/config.json` - you can use the sample as a starting point:
✅ **Decentralized & Federated** – No central authority; works across Matrix
homeservers.
✅ **End-to-End Encrypted** – Secure and private calls.
✅ **Standalone, Widget & Component Mode** – Use as an independent app, embed
in Matrix clients as a widget, or (experimentally) mount it as a React component
inside your own application.
✅ **WebRTC-based** – No additional software required.
✅ **Scalable with LiveKit** – Supports large meetings via SFU
([MSC4195: MatrixRTC using LiveKit backend](https://github.com/hughns/matrix-spec-proposals/blob/hughns/matrixrtc-livekit/proposals/4195-matrixrtc-livekit.md)).
✅ **Raise Hand** – Participants can signal when they want to speak, helping to
organize the flow of the meeting.
✅ **Emoji Reactions** – Users can react with emojis 👍️ 🎉 👏 🤘, adding
engagement and interactivity to the conversation.
```
cp config/config.sample.json public/config.json
# edit public/config.json
```
## 🚀 Deployment & Packaging Options
Because Element Call uses client-side routing, your server must be able to route any requests to non-existing paths back to `/index.html`. For example, in Nginx you can achieve this with the `try_files` directive:
Element Call is developed using the
[Matrix js-sdk](https://github.com/matrix-org/matrix-js-sdk) with Matroska mode.
This allows the app to run either as a Standalone App directly connected to a
homeserver with login interfaces or it can be used as a widget within a Matrix
client.
```
server {
...
location / {
...
try_files $uri /$uri /index.html;
### 🖥️ Standalone Mode
<p align="center">
<img src="./docs/element_call_standalone.drawio.png" alt="Element Call in Standalone Mode">
</p>
In Standalone mode, Element Call operates as an independent, full-featured video
conferencing web application, enabling users to join or host calls without
requiring a separate Matrix client.
### 📲 In-App Calling (Widget Mode in Messenger Apps)
When used as a widget 🧩, Element Call is solely responsible for the core calling
functionality (MatrixRTC). Authentication, event handling, and room state
updates (via the Client-Server API) are handled by the hosting client.
Communication between Element Call and the client is managed through the widget
API.
<p align="center">
<img src="./docs/element_call_widget.drawio.png" alt="Element Call in Widget Mode">
</p>
Element Call can be embedded as a widget inside apps like
[**Element Web**](https://github.com/element-hq/element-web) or **Element X
([iOS](https://github.com/element-hq/element-x-ios),
[Android](https://github.com/element-hq/element-x-android))**, bringing
**MatrixRTC** capabilities to messenger apps for seamless decentralized video
and voice calls within Matrix rooms.
> [!IMPORTANT]
> Embedded packaging is recommended for Element Call in widget mode!
### 📦 Element Call Packaging
Element Call offers two packaging options: one for standalone or widget
deployment, and another for seamless widget-based integration into messenger
apps. A third, experimental option builds it as a React component library for
applications that want to render a call inside their own page rather than in an
iframe. Below is an overview of each option.
**Full Package** – Supports both **Standalone** and **Widget** mode. It is
hosted as a static web page and can be accessed via a URL when used as a widget.
<p align="center">
<img src="./docs/full_package.drawio.png" alt="Element Call Full Package">
</p>
**Embedded Package** – Designed specifically for **Widget mode** only. It is
bundled with a messenger app for seamless integration and this is the
recommended method for embedding Element Call.
<p align="center">
<img src="./docs/embedded_package.drawio.png" alt="Element Call Embedded Package">
</p>
**Component Package (experimental)** – A library build of Element Call as a
React component, consumed as a dependency by a host application that already
has a Matrix client. See
[Element Call as a component](#element-call-as-a-component-experimental) below.
For more details on the packages, see the
[Embedded vs. Standalone Guide](./docs/embedded_standalone.md).
## 🛠️ Self-Hosting
For operating and deploying Element Call on your own server, refer to the
[**Self-Hosting Guide**](./docs/self_hosting.md).
## MatrixRTC Transports
For proper operation of Element Call, each deployment needs to set up a
MatrixRTC transport in the form of a LiveKit server as outlined in the
[Self-Hosting Guide](./docs/self_hosting.md). A typical federated site
deployment for three different sites A, B and C is depicted below.
<p align="center">
<img src="./docs/Federated_Setup.drawio.png" alt="Element Call federated setup">
</p>
### Transport Discovery
Element Call discovers the available MatrixRTC transports (as defined by
[MSC4519](https://github.com/matrix-org/matrix-spec-proposals/pull/4519)) by
hitting the `GET /_matrix/client/unstable/org.matrix.msc4143/rtc/transports`
endpoint of the Client-Server API. An example response:
```json
{
"rtc_transports": [
{
"type": "livekit",
"livekit_service_url": "https://matrix-rtc.example.com/livekit/jwt"
}
]
}
```
By default, the app expects you to have a Matrix homeserver (such as [Synapse](https://matrix-org.github.io/synapse/latest/setup/installation.html)) installed locally and running on port 8008. If you wish to use a homeserver on a different URL or one that is hosted on a different server, you can add a config file as above, and include the homeserver URL that you'd like to use.
where the format for MatrixRTC using LiveKit backend is defined in
[MSC4195](https://github.com/hughns/matrix-spec-proposals/blob/hughns/matrixrtc-livekit/proposals/4195-matrixrtc-livekit.md).
In the example above Matrix clients do discover a focus of type `livekit` which
points them to a [MatrixRTC Authorization Service](https://github.com/element-hq/lk-jwt-service)
via `livekit_service_url`.
Element Call requires a homeserver with registration enabled without any 3pid or token requirements, if you want it to be used by unregistered users. Furthermore, it is not recommended to use it with an existing homeserver where user accounts have joined normal rooms, as it may not be able to handle those yet and it may behave unreliably.
### Backend Selection
Therefore, to use a self-hosted homeserver, this is recommended to be a new server where any user account created has not joined any normal rooms anywhere in the Matrix federated network. The homeserver used can be setup to disable federation, so as to prevent spam registrations (if you keep registrations open) and to ensure Element Call continues to work in case any user decides to log in to their Element Call account using the standard Element app and joins normal rooms that Element Call cannot handle.
- Each call participant proposes their discovered MatrixRTC transport from
`org.matrix.msc4143.rtc_foci` in their `org.matrix.msc3401.call.member` state event.
- For the **LiveKit** MatrixRTC backend
([MSC4195](https://github.com/hughns/matrix-spec-proposals/blob/hughns/matrixrtc-livekit/proposals/4195-matrixrtc-livekit.md)),
the **first participant who joined the call** defines which backend will be used for this call via
the `foci_preferred` key in their `org.matrix.msc3401.call.member` state event.
- During the actual call join flow, the **[MatrixRTC Authorization Service](https://github.com/element-hq/lk-jwt-service)**
provides the client with the **LiveKit SFU WebSocket URL** and an
**access JWT token** in order to exchange media via WebRTC.
## Configuration
The example below illustrates how backend selection works across **Matrix
federation**, using the setup from sites A, B, and C. It demonstrates backend
selection for **Matrix rooms 123 and 456**, which include users from different
homeservers.
There are currently two different config files. `.env` holds variables that are used at build time, while `public/config.json` holds variables that are used at runtime. Documentation and default values for `public/config.json` can be found in [ConfigOptions.ts](src/config/ConfigOptions.ts).
<p align="center">
<img src="./docs/SFU_selection.drawio.png" alt="Element Call SFU selection over Matrix federation">
</p>
If you're using [Synapse](https://github.com/element-hq/synapse/), you'll need to additionally add the following to `homeserver.yaml` or Element Call won't work:
## 🌍 Translation
```
experimental_features:
msc3266_enabled: true
```
If you'd like to help translate Element Call, head over to
[Localazy](https://localazy.com/p/element-call). You're also encouraged to join
the [Element Translators](https://matrix.to/#/#translators:element.io) space to
discuss and coordinate translation efforts.
MSC3266 allows to request a room summary of rooms you are not joined.
The summary contains the room join rules. We need that to decide if the user gets prompted with the option to knock ("ask to join"), a cannot join error or the join view.
## 🛠️ Development
Element Call requires a Livekit SFU behind a Livekit jwt service to work. The url to the Livekit jwt service can either be configured in the config of Element Call (fallback/legacy configuration) or be configured by your homeserver via the `.well-known`.
This is the recommended method.
### Dependencies
The configuration is a list of Foci configs:
```json
"org.matrix.msc4143.rtc_foci": [
{
"type": "livekit",
"livekit_service_url": "https://someurl.com"
},
{
"type": "livekit",
"livekit_service_url": "https://livekit2.com"
},
{
"type": "another_foci",
"props_for_another_foci": "val"
},
]
```
## Translation
If you'd like to help translate Element Call, head over to [Localazy](https://localazy.com/p/element-call). You're also encouraged to join the [Element Translators](https://matrix.to/#/#translators:element.io) space to discuss and coordinate translation efforts.
## Development
- Node.js (e.g. via [nvm](https://github.com/nvm-sh/nvm))
- [Corepack](https://github.com/nodejs/corepack) (not bundled with Node.js anymore starting from 25.0.0)
- Docker client and runtime + Docker Compose (for the backend)
- On macOS you can install everything with `brew install colima docker docker-compose`
### Frontend
Element Call is built against [matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/pull/2553). To get started, clone, install, and link the package:
To get started clone and set up this project:
```
git clone https://github.com/matrix-org/matrix-js-sdk.git
cd matrix-js-sdk
yarn
yarn link
```
Next, we can set up this project:
```
```sh
git clone https://github.com/element-hq/element-call.git
cd element-call
yarn
yarn link matrix-js-sdk
corepack enable
pnpm install
```
To use it, create a local config by, e.g.,
`cp ./config/config.devenv.json ./public/config.json` and adapt it if necessary.
The `config.devenv.json` config should work with the backend development
environment as outlined in the next section out of box.
You're now ready to launch the development server:
```sh
pnpm dev
```
yarn dev
See also:
- [Developing with linked packages](./docs/linking.md)
#### Element Call as a component (experimental)
Element Call can also be embedded directly into another React application
rather than being loaded in an iframe as a widget. `pnpm build:component`
builds it as a library into `component/dist` (the bundle, its stylesheet and
type declarations), and
```sh
pnpm dev:component
```
serves a harness on port 3001 that stands in for such an application: it signs
in twice against the development backend and shows two calls side by side, in
resizable boxes, with page furniture of its own around them. Use it to see how
Element Call behaves when it does not own the page — the size it is given,
whether it stays inside its container, and what it says to its host, which is
logged along the bottom. The harness is served with the same development
certificate as the app, so unless the development CA is trusted, the browser
needs a certificate exception for `https://localhost:3001` as well (see the
note under [Backend](#backend)). It reads the same `public/config.json` as
`pnpm dev` if one exists, and runs with Element Call's defaults otherwise.
The call lays itself out for the size of the element it is mounted in, not the
window: a host that shrinks the container to a corner of its page gets the
picture-in-picture layout, just as a host that shrank the whole iframe used to.
The breakpoints in the stylesheets the component uses are
`@container element-call` queries against its root element for the same reason;
for the standalone app the root is the page, so they mean what the media queries
they replaced did. (The standalone-only views, such as the home and login pages,
still use plain media queries, since the component never shows them.)
The component's stylesheet is confined to the element it is mounted in: the
build rewrites every selector so that it matches only Element Call's root or
what is inside it, with `html`, `body` and `:root` standing for that root (see
`component/build/scopeStylesToRoot.ts`). A host's own page keeps its styles,
and Element Call brings its own fonts and design tokens along.
The component speaks every language the app does. English is bundled in; the
other locales are split into chunks the host's bundler loads the first time
they are needed. It starts in the browser's language, and follows the host's
own language setting through the `language` prop (`supportedLanguages` lists
the tags it accepts, and anything else falls back to its base language or to
English). The `theme` prop works the same way and takes the same values as the
widget's `theme` URL parameter: `light`, `dark`, `light-high-contrast` or
`dark-high-contrast`. Both can change while a call is running without
disturbing it.
A host must call and await `initializeElementCall(config)` once before
rendering the component: it loads the `Intl` polyfills, applies the
deployment-wide `config.json`-style configuration and sets up translations.
The component itself takes the host's `client` and the `roomId` to call in, an
`intent` saying what the user asked for (which decides whether to show the
lobby, ring, and so on), an optional `config` overriding what the intent
implies, and an optional `hostBridge` through which Element Call tells the host
that the user has joined or hung up, that it wants to stay on screen, and so
on. The host makes its own requests (`join`, `hangUp`, `setDeviceMute`) through
the handle exposed on `ref`. The full API is documented in the type declarations
(`component/index.tsx` and `component/host.ts`).
A few things differ from the widget on purpose: the component draws a solid
background rather than a gradient unless told otherwise, never offers to edit
the user's profile (the account is the host's), scopes its keyboard shortcuts to
its own root element so that several instances can share a page, and only shows
its own post-call and error screens when the host has not supplied a `close()`
callback; with one, it asks the host to unmount it instead. The
[global JS controls](./docs/controls.md) on `window` are unchanged and remain
page-wide, so with several instances on one page they apply to all of them.
The package is not published yet. A host installs it as a git dependency on the
`component` directory of this repository,
```json
"@element-hq/element-call-component": "github:element-hq/element-call#main&path:/component"
```
whose `prepare` script runs the build on install. That build needs pnpm (via
Corepack) on the host's machine, runs a full `pnpm install` of this repository,
since it inherits the `--max-old-space-size` setting of
the app build; the host's pnpm also has to allow it to run at all
(`allowBuilds` in its `pnpm-workspace.yaml`). Note that `component/` is a pnpm
project of its own for this reason, so pnpm commands run from inside that
directory target it rather than the repository; run them from the repository
root. The host imports the component from
`@element-hq/element-call-component` and the stylesheet from
`@element-hq/element-call-component/style.css`, and has to provide `react`,
`react-dom`, `matrix-js-sdk`, `@vector-im/compound-web` and
`@vector-im/compound-design-tokens` itself, since the bundle leaves them
external.
Compound's stylesheet are the host's to load too: the component shares
the host's copy of Compound, (required for example for tooltips)
The component is large, and a host will usually load it lazily, only once a
call is shown. Everything a host needs in order to talk about a call before
then is also exported
from `@element-hq/element-call-component/api` (a small entry point that does not
load the component).
- props and the types they are made of
- the handle
- the host bridge
- `UserIntent`
- `HeaderStyle`
- `BackgroundStyle` enums
- `configurationForIntent`, the defaults each intent implies
Import from it wherever a value such as
`BackgroundStyle.Solid` is needed on a path that must stay light; the main
entry point re-exports all of it too.
### Backend
A docker compose file is provided to start a LiveKit server and auth
service for development. These use a test 'secret' published in this
repository, so this must be used only for local development and
**_never be exposed to the public Internet._**
A docker compose file `docker-compose-dev.yml` is provided to start the
whole stack of components which is required for a local development environment
including federation:
To use it, add a SFU parameter in your local config `./public/config.json`:
(Be aware, that this is only the fallback Livekit SFU. If the homeserver
advertises one in the client well-known, this will not be used.)
- Minimum Synapse Setup (servernames: `synapse.m.localhost`, `synapse.othersite.m.localhost`)
- MatrixRTC Authorization Service (Note: requires Federation API and hence a TLS reverse proxy)
- Minimum LiveKit SFU setup using dev defaults for config
- Minimum `localhost` Certificate Authority (CA) for Transport Layer Security (TLS)
- Hostnames: `m.localhost`, `*.m.localhost`, `*.othersite.m.localhost`
- Add [./backend/dev_tls_local-ca.crt](./backend/dev_tls_local-ca.crt) to your web browser's trusted
certificates
- Minimum TLS reverse proxy for
- Synapse homeserver: `synapse.m.localhost` and `synapse.othersite.m.localhost`
- MatrixRTC backend: `matrix-rtc.m.localhost` and `matrix-rtc.othersite.m.localhost`
- Local Element Call development `call.m.localhost` via `pnpm dev --host `
- Element Web `app.m.localhost` and `app.othersite.m.localhost`
- Note certificates will expire on Thr, 20 September 2035 14:27:35 CEST
```json
"livekit": {
"livekit_service_url": "http://localhost:7881"
},
These use a test 'secret' published in this repository, so this must be used
only for local development and **_never be exposed to the public Internet._**
Make sure your Docker runtime is running (e.g. via `colima start`) and then start
the backend components:
```sh
pnpm backend
# or for podman-compose:
# podman-compose -f docker-compose-dev.yml up
```
Run backend components:
The two Element Web instances load the Element Call widget from
`./dist-embedded`, which is mounted over the copy bundled in the Element Web
image. Build it from the current sources before starting the backend, and keep
it rebuilding on change:
```sh
VITE_MATRIX_RTC_MODE=matrix_2_0 pnpm build:embedded:development --outDir dist-embedded --watch
```
Build it at least once before the first `pnpm backend`, since Docker otherwise
creates an empty `dist-embedded` directory that the build cannot write to.
Reload the page after a rebuild to pick up the new widget. The widget has no
`config.json` in this setup, so `VITE_MATRIX_RTC_MODE` sets the default
MatrixRTC mode of the build instead (see
[docs/matrix_rtc_modes.md](docs/matrix_rtc_modes.md)); it can still be changed
under Settings → Developer. Do not delete `dist-embedded` while the backend is
running: the containers hold a mount of the directory, and a new directory of
the same name is not picked up until they are recreated.
> [!NOTE]
> When Docker runs in a VM (colima, Docker Desktop), the SFUs' container IPs
> are not routable from the host, so they advertise `127.0.0.1` as their ICE
> candidate instead and the browser reaches them through the published ports.
> This only works in Chromium-based browsers: Firefox ignores loopback
> candidates, and calls drop about fifteen seconds after joining. Media runs
> over ICE-TCP, since the UDP port ranges are not forwarded out of the VM.
> [!NOTE]
> To ensure your local development frontend functions properly, you’ll need to
> add certificate exceptions in your browser for `https://localhost:3000` and
> `https://matrix-rtc.m.localhost/livekit/jwt/healthz`. This can be done either
> by adding the minimum localhost CA
> ([./backend/dev_tls_local-ca.crt](./backend/dev_tls_local-ca.crt)) to your web
> browser's trusted certificates or by simply copying and pasting each URL into
> your browser’s address bar and follow the prompts to add the exception.
### Updating snapshots
To update snapshots used in tests, use Vitest's `-u` flag, e.g.:
```sh
pnpm test DeveloperSettingsTab -u
```
### Playwright tests
Our Playwright tests run automatically as part of our CI along with our other
tests, on every pull request.
You may need to follow instructions to set up your development environment for
running Playwright by following
<https://playwright.dev/docs/browsers#install-browsers> and
<https://playwright.dev/docs/browsers#install-system-dependencies>.
However the Playwright tests are run, an element-call instance must be running
on https://localhost:3000 (this is configured in `playwright.config.ts`) - this
is what will be tested. The tests under `playwright/component` instead drive
the component harness (`pnpm dev:component`) on https://localhost:3001, which
Playwright starts as a second web server; it is always a Vite dev server, even
when the app itself is served from Docker with `USE_DOCKER`.
The local backend environment should be running for the test to work:
`pnpm backend`
There are a few different ways to run the tests yourself. The simplest is to
run:
```shell
pnpm run test:playwright
```
This will run the Playwright tests once, non-interactively.
There is a more user-friendly way to run the tests in interactive mode:
```shell
pnpm run test:playwright:open
```
The easiest way to develop new test is to use the codegen feature of Playwright:
```shell
npx playwright codegen
```
This will record your action and write the test code for you. Use the tool bar
to test visibility, text content and clicking.
##### Investigate a failed test from the CI
In the failed action page, click on the failed job, then scroll down to the
`upload-artifact` step. You will find a link to download the zip report, as per:
```
yarn backend
Artifact playwright-report has been successfully uploaded! Final size is 1360358 bytes. Artifact ID is 2746265841
Artifact download URL: https://github.com/element-hq/element-call/actions/runs/13837660687/artifacts/2746265841
```
Unzip the report then use this command to open the report in your browser:
```shell
npx playwright show-report ~/Downloads/playwright-report/
```
Under the failed test there is a small icon looking like "3 columns" (next to
the test name file name), click on it to see the live screenshots/console
output.
### Test Coverage
<img src="https://codecov.io/github/element-hq/element-call/graphs/tree.svg?token=O6CFVKK6I1"></img>
### Add a new translation key
To add a new translation key you can do these steps:
1. Add the new key entry to the code where the new key is used: `t("some_new_key")`
1. Run `yarn i18n` to extract the new key and update the translation files. This will add a skeleton entry to the `public/locales/en-GB/app.json` file:
1. Add the new key entry to the code where the new key is used:
`t("some_new_key")`
1. Run `pnpm i18n` to extract the new key and update the translation files. This
will add a skeleton entry to the `locales/en/app.json` file:
```jsonc
{
...
@@ -154,7 +489,10 @@ To add a new translation key you can do these steps:
...
}
```
1. Update the skeleton entry in the `public/locales/en-GB/app.json` file with the English translation:
1. Update the skeleton entry in the `locales/en/app.json` file with the English
translation:
```jsonc
{
...
@@ -163,8 +501,37 @@ To add a new translation key you can do these steps:
}
```
## Documentation
## 📖 Documentation
Usage and other technical details about the project can be found here:
[**Docs**](./docs/README.md)
## GitHub Labels
GitHub labels in this repository are maintained in the [`labels.yml`](.github/labels.yml) file and
automatically synced to GitHub using the [`sync-labels` workflow](.github/workflows/sync-labels.yml).
We do this so that we can reuse the labels between repositories.
> [!WARNING]
> Do not manually edit labels in the GitHub UI. Any manual changes will be overridden by the
> workflow on its next invocation.
## 📝 Copyright & License
Copyright 2021-2026 New Vector Ltd
This software is dual-licensed by New Vector Ltd (Element). It can be used
either:
(1) for free under the terms of the GNU Affero General Public License (as
published by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version); OR
(2) under the terms of a paid-for Element Commercial License agreement between
you and Element (the terms of which may vary depending on what you and Element
have agreed to). Unless required by applicable law or agreed to in writing,
software distributed under the Licenses is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
Licenses for the specific language governing permissions and limitations under
the Licenses.
+28
View File
@@ -0,0 +1,28 @@
# Testing Element-Call in widget mode
When running `pnpm backend` the latest element-web develop will be deployed and served on `http://localhost:8081`.
In a development environment, you might prefer to just use the `element-web` repo directly, but this setup is useful for CI/CD testing.
## Setup
The element-web configuration is modified to:
- Enable to use the local widget instance (`element_call.url` https://localhost:3000).
- Enable the labs features (`feature_group_calls`, `feature_element_call_video_rooms`).
The default configuration used by docker-compose is in `test-container/config.json`. There is a fixture for playwright
that uses
## Running the element-web instance
It is part of the existing backend setup. To start the backend, run:
```sh
pnpm backend
```
Then open `http://localhost:8081` in your browser.
## Basic fixture
A base fixture is provided in `/playwright/fixtures/widget-user.ts` that will register two users that shares a room.
-20
View File
@@ -1,20 +0,0 @@
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
node: "current",
},
},
],
[
"@babel/preset-react",
{
runtime: "automatic",
},
],
"@babel/preset-typescript",
],
plugins: ["babel-plugin-transform-vite-meta-env"],
};
-44
View File
@@ -1,44 +0,0 @@
version: "3.9"
networks:
lkbackend:
services:
auth-service:
image: ghcr.io/element-hq/lk-jwt-service:latest-ci
hostname: auth-server
ports:
- 8881:8080
environment:
- LIVEKIT_URL=ws://localhost:7880
- LIVEKIT_KEY=devkey
- LIVEKIT_SECRET=secret
deploy:
restart_policy:
condition: on-failure
networks:
- lkbackend
livekit:
image: livekit/livekit-server:latest
command: --dev --config /etc/livekit.yaml
restart: unless-stopped
ports:
- "7880:7880"
- "7881:7881"
- "7882:7882"
- "50100-50200:50100-50200"
volumes:
- ./backend/livekit.yaml:/etc/livekit.yaml
networks:
- lkbackend
redis:
image: redis:6-alpine
command: redis-server /etc/redis.conf
ports:
- 6379:6379
volumes:
- ./backend/redis.conf:/etc/redis.conf
networks:
- lkbackend
+17
View File
@@ -0,0 +1,17 @@
id: "lk-jwt-service-othersite"
as_token: "ec_dev_as_token_othersite_0123456789ab"
hs_token: "ec_dev_hs_token_othersite_0123456789ab"
sender_localpart: "_lk_jwt_service"
namespaces:
users:
- exclusive: false
regex: "@.*:synapse\\.othersite\\.m\\.localhost" # Cover all local users
# Required for Synapse to call POST /_matrix/app/v1/ping on this service.
url: "http://auth-server-1:16080"
# Enable membership look-ups via /is_joined.
io.element.msc4502.scopes:
["urn:matrix:client:io.element.msc4502:rooms:is_joined"]
# Route /_matrix/client/(v*|unstable/*)/rtc/livekit/* C-S and S-S requests to this
# service.
io.element.msc4512.proxy_prefix: "rtc/livekit"
io.element.msc4512.proxy_url: "http://auth-server-1:16080"
+17
View File
@@ -0,0 +1,17 @@
id: "lk-jwt-service"
as_token: "ec_dev_as_token_main_0123456789ab"
hs_token: "ec_dev_hs_token_main_0123456789ab"
sender_localpart: "_lk_jwt_service"
namespaces:
users:
- exclusive: false
regex: "@.*:synapse\\.m\\.localhost" # Cover all local users
# Required for Synapse to call POST /_matrix/app/v1/ping on this service.
url: "http://auth-server:6080"
# Enable membership look-ups via /is_joined.
io.element.msc4502.scopes:
["urn:matrix:client:io.element.msc4502:rooms:is_joined"]
# Route /_matrix/client/(v*|unstable/*)/rtc/livekit/* C-S and S-S requests to this
# service.
io.element.msc4512.proxy_prefix: "rtc/livekit"
io.element.msc4512.proxy_url: "http://auth-server:6080"
+82
View File
@@ -0,0 +1,82 @@
server_name: "synapse.othersite.m.localhost"
public_baseurl: https://synapse.othersite.m.localhost/
pid_file: /data/homeserver.pid
listeners:
- port: 18008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation, openid]
compress: false
database:
name: sqlite3
args:
database: /data/homeserver.db
media_store_path: /data/media_store
signing_key_path: "/data/SERVERNAME.signing.key"
# Due to custom TLS certificate with domains
# - m.localhost, localhost
# - *.m.localhost
# - *.othersite.m.localhost
# we disable certificate verification to allow for federation
# WARNING: DO NOT USE IN PRODUCTION!!!
federation_verify_certificates: false
ip_range_blacklist: []
trusted_key_servers:
- server_name: "synapse.m.localhost"
accept_keys_insecurely: true
experimental_features:
# MSC3266: Room summary API. Used for knocking over federation
msc3266_enabled: true
# MSC4222 needed for syncv2 state_after. This allow clients to
# correctly track the state of the room.
msc4222_enabled: true
# sticky events for MatrixRTC user state
msc4354_enabled: true
# MatrixRTC
msc4143_enabled: true
# Enable membership look-up via /is_joined.
msc4502_enabled: true
# Enable C-S & S-S request proxying for application services.
msc4512_enabled: true
app_service_config_files:
- /data/cfg/app-service.yaml
# The maximum allowed duration by which sent events can be delayed, as
# per MSC4140. Must be a positive value if set. Defaults to no
# duration (null), which disallows sending delayed events.
max_event_delay_duration: 24h
# Required for Element Call in Single Page Mode due to on-the-fly user registration
enable_registration: true
enable_registration_without_verification: true
# Shared secret for admin user registration via API (for testing only!)
registration_shared_secret: "test_shared_secret_for_local_dev_only"
report_stats: false
# Ratelimiting settings for client actions (registration, login, messaging).
#
# Each ratelimiting configuration is made of two parameters:
# - per_second: number of requests a client can send per second.
# - burst_count: number of requests a client can send before being throttled.
rc_message:
# This needs to match at least the heart-beat frequency plus a bit of headroom
# Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
per_second: 0.5
burst_count: 30
matrix_rtc:
transports:
- type: livekit
livekit_service_url: https://matrix-rtc.othersite.m.localhost/livekit/jwt
+82
View File
@@ -0,0 +1,82 @@
server_name: "synapse.m.localhost"
public_baseurl: https://synapse.m.localhost/
pid_file: /data/homeserver.pid
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation, openid]
compress: false
database:
name: sqlite3
args:
database: /data/homeserver.db
media_store_path: /data/media_store
signing_key_path: "/data/SERVERNAME.signing.key"
# Due to custom TLS certificate with domains
# - m.localhost, localhost
# - *.m.localhost
# - *.othersite.m.localhost
# we disable certificate verification to allow for federation.
# WARNING: DO NOT USE IN PRODUCTION!!!
federation_verify_certificates: false
ip_range_blacklist: []
trusted_key_servers:
- server_name: "synapse.othersite.m.localhost"
accept_keys_insecurely: true
experimental_features:
# MSC3266: Room summary API. Used for knocking over federation
msc3266_enabled: true
# MSC4222 needed for syncv2 state_after. This allow clients to
# correctly track the state of the room.
msc4222_enabled: true
# sticky events for MatrixRTC user state
msc4354_enabled: true
# MatrixRTC
msc4143_enabled: true
# Enable membership look-up via /is_joined.
msc4502_enabled: true
# Enable C-S & S-S request proxying for application services.
msc4512_enabled: true
app_service_config_files:
- /data/cfg/app-service.yaml
# The maximum allowed duration by which sent events can be delayed, as
# per MSC4140. Must be a positive value if set. Defaults to no
# duration (null), which disallows sending delayed events.
max_event_delay_duration: 24h
# Required for Element Call in Single Page Mode due to on-the-fly user registration
enable_registration: true
enable_registration_without_verification: true
# Shared secret for admin user registration via API (for testing only!)
registration_shared_secret: "test_shared_secret_for_local_dev_only"
report_stats: false
# Ratelimiting settings for client actions (registration, login, messaging).
#
# Each ratelimiting configuration is made of two parameters:
# - per_second: number of requests a client can send per second.
# - burst_count: number of requests a client can send before being throttled.
rc_message:
# This needs to match at least the heart-beat frequency plus a bit of headroom
# Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
per_second: 0.5
burst_count: 30
matrix_rtc:
transports:
- type: livekit
livekit_service_url: https://matrix-rtc.m.localhost/livekit/jwt
+29
View File
@@ -0,0 +1,29 @@
port: 17880
bind_addresses:
- "0.0.0.0"
rtc:
tcp_port: 17881
port_range_start: 50300
port_range_end: 50400
use_external_ip: false
# Advertise the loopback address instead of the container IP, which is not
# routable from the host when Docker runs in a VM (colima, Docker Desktop).
# The browser then reaches the SFU through the published ports. Firefox
# ignores loopback candidates, so this only works in Chromium-based browsers.
node_ip: 127.0.0.1
turn:
enabled: false
domain: localhost
cert_file: ""
key_file: ""
tls_port: 5349
udp_port: 443
external_tls: true
keys:
devkey: secret
room:
auto_create: false
webhook:
api_key: devkey
urls:
- https://matrix-rtc.othersite.m.localhost/livekit/jwt/sfu_webhook
+29
View File
@@ -0,0 +1,29 @@
port: 7880
bind_addresses:
- "0.0.0.0"
rtc:
tcp_port: 7881
port_range_start: 50100
port_range_end: 50200
use_external_ip: false
# Advertise the loopback address instead of the container IP, which is not
# routable from the host when Docker runs in a VM (colima, Docker Desktop).
# The browser then reaches the SFU through the published ports. Firefox
# ignores loopback candidates, so this only works in Chromium-based browsers.
node_ip: 127.0.0.1
turn:
enabled: false
domain: localhost
cert_file: ""
key_file: ""
tls_port: 5349
udp_port: 443
external_tls: true
keys:
devkey: secret
room:
auto_create: false
webhook:
api_key: devkey
urls:
- https://matrix-rtc.m.localhost/livekit/jwt/sfu_webhook
+277
View File
@@ -0,0 +1,277 @@
# Synapse reverse proxy
# domain synapse.m.localhost
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen 8448 ssl;
listen [::]:443 ssl;
listen [::]:8448 ssl;
server_name synapse.m.localhost;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
# Reverse proxy for Matrix Synapse Homeserver
# This is also required for development environment.
# Reason: the lk-jwt-service uses the federation API for the openid token
# verification, which requires TLS
location ~ ^(/_matrix|/_synapse/client) {
proxy_pass "http://homeserver:8008";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
}
location ~ ^(/_matrix|/_synapse/admin) {
proxy_pass "http://homeserver:8008";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
}
}
# Synapse reverse proxy
# domain synapse.othersite.m.localhost
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen 8448 ssl;
listen [::]:443 ssl;
listen [::]:8448 ssl;
server_name synapse.othersite.m.localhost;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
# Reverse proxy for Matrix Synapse Homeserver
# This is also required for development environment.
# Reason: the lk-jwt-service uses the federation API for the openid token
# verification, which requires TLS
location ~ ^(/_matrix|/_synapse/client) {
proxy_pass "http://homeserver-1:18008";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
}
location ~ ^(/_matrix|/_synapse/admin) {
proxy_pass "http://homeserver-1:18008";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
}
}
# MatrixRTC reverse proxy
# domain matrix-rtc.m.localhost
# - MatrixRTC Authorization Service
# - LiveKit SFU websocket signaling connection
upstream jwt-auth-services {
server auth-server:6080;
server host.docker.internal:6080;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name matrix-rtc.m.localhost;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
http2 on;
location ^~ /livekit/jwt/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# JWT Service running at port 6080
proxy_pass http://jwt-auth-services/;
}
location ^~ /livekit/sfu/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_send_timeout 120;
proxy_read_timeout 120;
proxy_buffering off;
proxy_set_header Accept-Encoding gzip;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# LiveKit SFU websocket connection running at port 7880
proxy_pass http://livekit-sfu:7880/;
}
}
# MatrixRTC reverse proxy
# domain matrix-rtc.othersite.m.localhost
# - MatrixRTC Authorization Service
# - LiveKit SFU websocket signaling connection
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name matrix-rtc.othersite.m.localhost;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
http2 on;
location ^~ /livekit/jwt/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# JWT Service running at port 16080
proxy_pass http://auth-service-1:16080/;
}
location ^~ /livekit/sfu/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_send_timeout 120;
proxy_read_timeout 120;
proxy_buffering off;
proxy_set_header Accept-Encoding gzip;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# LiveKit SFU websocket connection running at port 17880
proxy_pass http://livekit-sfu-1:17880/;
}
}
# Convenience reverse proxy for the call.m.localhost domain to element call
# running on the host either via
# - pnpm dev --host or
# - falling back to http (the element call docker container)
server {
listen 80;
listen [::]:80;
server_name call.m.localhost;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name call.m.localhost;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
# 1. Attempt HTTPS first
location ^~ / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://host.docker.internal:3000;
proxy_ssl_verify off;
# 2. Redirect specific errors (e.g., 502 Bad Gateway or 504 Timeout)
# to the named fallback location
error_page 502 503 504 = @http_fallback;
}
# 3. Fallback location using HTTP
location @http_fallback {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://host.docker.internal:8080;
}
}
# Convenience reverse proxy app.m.localhost for element web
server {
listen 80;
listen [::]:80;
server_name app.m.localhost;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name app.m.localhost;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
location ^~ / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://element-web:8081;
proxy_ssl_verify off;
}
}
# Convenience reverse proxy app.othersite.m.localhost for element web
server {
listen 80;
listen [::]:80;
server_name app.othersite.m.localhost;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name app.othersite.m.localhost;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
location ^~ / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://element-web-1:18081;
proxy_ssl_verify off;
}
}
+19
View File
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDGjCCAgKgAwIBAgIUOlA2wgQUGZkKqNDvvifFWEsJfvYwDQYJKoZIhvcNAQEL
BQAwHjEcMBoGA1UEAwwTRWxlbWVudCBDYWxsIERldiBDQTAeFw0yNjA1MTgwOTM0
MzFaFw0yODA3MjYwOTM0MzFaMB4xHDAaBgNVBAMME0VsZW1lbnQgQ2FsbCBEZXYg
Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcImv3pStfIUo7PbOO
XRVUXuDlApBOrg2dCnvZQ1Jfaf4MftGHj/pURkF4eoBuyH4k4+NLzWD0VcU1cM74
RnxowJt4AceCGe5RK/rqal5fapXc2vYMM8P6xaQR86gkxohpufsLgTnSweh74yqN
B5WHUnCX00/X0bh1ho2BMUvGM9+dI4MdgKdaQDgWK4zg9hwp2Z6Yq7SkJ/D8+sGW
WGpn3osDakL8HTBqop+YVJgF40db50yFurfcfQ0gjVtT4JW8ejO9j8PS/S2oQ/s5
mA1B470XhLtT5qTjGm2bp3WpYkTi5widps8PDzBp5eNr0HrvJqcw7BGpbvBlLa+3
7dhLAgMBAAGjUDBOMB0GA1UdDgQWBBRDfyRM4yKUqW6vu/2KUSXGb8vswDAfBgNV
HSMEGDAWgBRDfyRM4yKUqW6vu/2KUSXGb8vswDAMBgNVHRMEBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQBoAhD4W4Yi/VJ2pTKrzhstn1UF1rgQnRddnn97v5BaEV/X
uuBXbSO+/ewjQUupRjePZFp9FFe9co1OiduKcDExlvPU1eIqkWAwDWjMDpI+Lw5q
KI5yHzplmMrT/7jn9Tepl9atrIcfDeFkP1dGtdRPyU6ARJEEWJSKeH9ftmImAsbM
ykXAqSyRl8+bPx1ISG4cNihOxFd38VPDHIW53umaRBgRcN4GcvloKBGrVtRFNM//
H+md8HmNQMP+e7FamETxs28DxjsdpygxjiFNY/T2eD67dH50ZxC3qCxEG6TJsoAg
TYJafnqEcGDfiWQyNZRBypuaRsRmmTR27hCPVgi8
-----END CERTIFICATE-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCcImv3pStfIUo7
PbOOXRVUXuDlApBOrg2dCnvZQ1Jfaf4MftGHj/pURkF4eoBuyH4k4+NLzWD0VcU1
cM74RnxowJt4AceCGe5RK/rqal5fapXc2vYMM8P6xaQR86gkxohpufsLgTnSweh7
4yqNB5WHUnCX00/X0bh1ho2BMUvGM9+dI4MdgKdaQDgWK4zg9hwp2Z6Yq7SkJ/D8
+sGWWGpn3osDakL8HTBqop+YVJgF40db50yFurfcfQ0gjVtT4JW8ejO9j8PS/S2o
Q/s5mA1B470XhLtT5qTjGm2bp3WpYkTi5widps8PDzBp5eNr0HrvJqcw7BGpbvBl
La+37dhLAgMBAAECggEAEsS4gc5jBk50I+bo3KYn2DqHgj/qpOqbTFNkS9uh3UJa
fZoJCeiuyM6hNCBVq/uB3mFeg1Au5XAiAqiK2KFwdw8gIS7lkqgXU76brO4YZhPj
6+aOSS03079KV7YYckNDRqJKoTlpgAI7Nhk6ljVhLiEk07tdD65wJACGpg8M8sg9
dyAz+ANs9gs65iF5LYjH61O/AFlLqCRQh5/z0mjGX6G9uN27nxeUY4+n4QMAcd9D
Gcygxjt+4nlQayNAlKMwVfps9bWNtI3Ye9knY4WGkrv5cJbW3bgjV6qrvQsbukbq
xEYzcIlUiWGO9Tv7MN6rk5uQOyoKT/KUnfRmdVd3YQKBgQDMhWm6Q+WuI7Pyn57R
tmY4rs+fSqTmv6xAOcozKJxffGaEwSUuNA15NvR/7iedcNqmH3XT9j90ZNVHe090
ocm1HDUvzC9G5GRrdO6JTTksRaIMZEhosWxqH3DIuBJPLGbF/4obGE7//PJtmDEp
QVL9Aa0WrcwAWhRzUdvCE+taMwKBgQDDbyZIvtlEr1w2V0bjXO536rRksBapc2ZJ
XRKtrXivuVtiZYNDB0I7CCJ52cka61n3kyZz2mhQmLq4cAZXyKYWE2i643O+kc3S
lpZEFSfDZ+3YlhxMxG9oEcgUSwVdbPlAhd/UR8V6n8o2Fm+gug9h6E2zY4fgHLJF
8hOWoD4hiQKBgA7YXD1F8mT6eHRS+78zIyZYIf/o9iE9pm4fA7tE5lzT9ckLD/zT
kGrM/2BN1BhMecJ3JCFXjXGQZB7FJ5ZKrA52VrH6ezAFIfjeyvWyYkUBZOrLWKoo
vrrRP2mCWuneSjNzAf5HfGx+WsZztpXNBQ4SUhMEWHtqDnP0bCQhOAMbAoGAPfLv
qcOFT3ZevoLv34ZHuQ9W20vOAyynUb4E+7SvOtSAmTIgZ5DXd6recs2MJ9JOlGG6
oKKsyk9/cJNiD1V1AC5q1kLfH5tMKOK/AxnJnvFEvZDnq5Xg0pZAW95j9vdiEwfc
qYeOm44nJPn7rHEOCzT93E1CdtHh2LYha2+kAjECgYEAh4qODleBi+2fnf2eq494
/tAot3szu2+gjyCN00vGjtzoAuDKTYgo0cbU1ILk0Pgpp1NcIvdHz/wQnG9RLX7e
Dfy1Q+UkyBK67SJUPvcYqBEaZ6ddyijJDunqh+U3nIBGP+IntKIKMIKiLF6wzTKz
NRpK1HNmllp+O692ZtxoNDU=
-----END PRIVATE KEY-----
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDijCCAnKgAwIBAgIUWkx2ad/F7QIj1JDaYfbLhiRV+EswDQYJKoZIhvcNAQEL
BQAwHjEcMBoGA1UEAwwTRWxlbWVudCBDYWxsIERldiBDQTAeFw0yNjA1MTgwOTM0
MzFaFw0yODA3MjYwOTM0MzFaMBgxFjAUBgNVBAMMDSoubS5sb2NhbGhvc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0hora/UCYMtrLJc6BOjonPUPi
bYpbNiZYnvnqI4doKbV0LBT2TfokT7tpgdPCtHKV0RknsVSL8vhlXpkRqIiWPml8
sZaa0+5NDGCQxexS2WVBlsoNCmAaqi/HNSFop6xaxGpQ3bu0iV3oIkUihveXAl6H
C0VYyGifQ8D5onzepW2ayhemu47YRNSo8wETY5vIi0i/iajTTaw6JvwS+8Kv5/QV
5prdvcFlG/oBs12p0+KoRyxskyzcdBdyIarvfY+9nDZwym5GfN32xO/iqtDuDQzw
Q09h2OsfHJCw70IpHcgXLlEQF2DsFbmbVpWSU6HcMm6B7Yw1YeE64W4PRJp3AgMB
AAGjgcUwgcIwHwYDVR0jBBgwFoAUQ38kTOMilKlur7v9ilElxm/L7MAwCQYDVR0T
BAIwADALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwUwYDVR0RBEww
SoIJbG9jYWxob3N0ggttLmxvY2FsaG9zdIINKi5tLmxvY2FsaG9zdIIXKi5vdGhl
cnNpdGUubS5sb2NhbGhvc3SCCCoubmlwLmlvMB0GA1UdDgQWBBSd0sKIKmZzTnxT
gNHHjsJNnFcYaTANBgkqhkiG9w0BAQsFAAOCAQEAeffRTrD9o9PVRIoul5r2chwP
WF7JtvPdC5xWy9rlCfmIKRNzNRnpVw/mDF/jdhlWcENt3psN8Vb1NM3SECKve9KL
8bDD2rJEoLBHIFQPS+XpEPqVGLHQcfBtGgs2XdILKvgXJyBHY/pgNZkQmXxYDVoc
bH9PjJJ4V3t6+tiVWZ792739EU/pHaSz7tab+ycTiggs7mo18E5jpYILhWsDqIVs
Kz3uczK2OR8537Ix64Z9kmKiklVAqE53odV7Qx2B+7DoOD/7KBN7SMy1KvR1ae6I
p1ivtDKpBZWbb1ccFxp2cQ30qRHLJrt2YRwz268gx/A6rGXuW6UQPYf4ISNR4Q==
-----END CERTIFICATE-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0hora/UCYMtrL
Jc6BOjonPUPibYpbNiZYnvnqI4doKbV0LBT2TfokT7tpgdPCtHKV0RknsVSL8vhl
XpkRqIiWPml8sZaa0+5NDGCQxexS2WVBlsoNCmAaqi/HNSFop6xaxGpQ3bu0iV3o
IkUihveXAl6HC0VYyGifQ8D5onzepW2ayhemu47YRNSo8wETY5vIi0i/iajTTaw6
JvwS+8Kv5/QV5prdvcFlG/oBs12p0+KoRyxskyzcdBdyIarvfY+9nDZwym5GfN32
xO/iqtDuDQzwQ09h2OsfHJCw70IpHcgXLlEQF2DsFbmbVpWSU6HcMm6B7Yw1YeE6
4W4PRJp3AgMBAAECggEAIgdIbk4VmnrfjjKCsg5JPvNH9AsE7PuQj9zrq+xljkdq
aksS6ni5YZXb9F/iDE4aWU4waTB+iODUXLtPrCnyESwTk0sgYe/39/MQ0slUKivL
b+keDgY6JlyVI/5KXWFZ1kQ27CZXxwiruGGZWZBKZF8wdVE1Ea65Neg+HHA6DHee
Jck002gtgO/J1MMbB1MzdtGcsejYLrA+mO6YddQhA65xdQMljTEfyUwgTVv0pWde
biyKegGK77vlsOyoCkMpVYORG5NMV1Kxs+htA79yuIW71tWHqVbcRMyoM+BaHzPh
7uprs+8vYDFrO39LseczA8gURWwUsCgQ0yQ6Ix5W7QKBgQDnSK4AzjPpDEArdHuV
VGKyzrfPtzH0VV/yTH9hvByNG6i/x8sE/r2KPi5nRMi4PAjjqmxyO1G5qwDOfzvK
sBvwFrTRpmbnqGITVKPPivdoI9+RveN+FxhOXVA8NylAOv/dtSoakYwg3e507UsC
RuFW3Re0Oc+0XFq4C8rQyLkIOwKBgQDH0T9gww+XbwIGCtiNpnEziU9FXBKSVwXf
dCxYcTLPATq3BqHmP4OUA0v+sa3wPcnBkXF7q6eoB9+S6ZYQA/b2BXGU5/j9xYd4
29cF4DlPkhTwF9S8b+h1zhlGIn96Lw/vZuj7Bc3wuwxvB17d8dpyo8bZynIe7BvF
KSPJz+2O9QKBgFFyd8xS0VcFeGeVKpwozmUXhQWCBvZ7RkGGjOk3HHrYvbFjw2vr
5YWUZjT5tRGkGqFJ98y2dQ5EWRFfHwg+wmfnJyAZUG3OD1OtX86Lqpqi321siHtz
2JxoIgRCjKVQ4aAK11vp24YLgZjto5eWrG4xh9Jw9WMXjt73UCH8PaTXAoGBAIff
TY1qlmuO3H1nWqHXkBpPQEwVs7s22ZN817q8HqSMXXSfWe/LOJmpND/YakJ2gX7S
e6xwqOylje3EUHpLd98LDJUIuFM3wkr4klo4gkANQZeRXONV5WhV4PHD+5MF9XwB
KmOnKsaLKoVFKckZ8EUMAOePtdI5ExkaRG+yqAMRAoGAJyUFK+V9ST1N/6wYgqor
vywMSRE2cF2WvVIxdMvWffmpoj40bG6lAlaSWm29E2T8SVvAKsRid0wDgCQ4QTEn
ft7yUDjqVALCJVCrOFHDY0BPStkm6njMWagr/0lGr9zUWqbBOKJhNfDJlykv8gaF
8kWTgabrMCKmpTi7fBWbzZA=
-----END PRIVATE KEY-----
+40
View File
@@ -0,0 +1,40 @@
#!/bin/bash
# Step 1: Create a Root CA key and cert
openssl genrsa -out dev_tls_local-ca.key 2048
openssl req -x509 -new -nodes \
-days 800 \
-subj "/CN=Element Call Dev CA" \
-key dev_tls_local-ca.key \
-out dev_tls_local-ca.crt \
-sha256 -addext "basicConstraints=CA:TRUE"
# Step 2: Create a private key and CSR for *.m.localhost
openssl req -new -nodes -newkey rsa:2048 \
-keyout dev_tls_m.localhost.key \
-out dev_tls_m.localhost.csr \
-subj "/CN=*.m.localhost"
# Step 3: Sign the CSR with your CA
openssl x509 \
-req -in dev_tls_m.localhost.csr \
-CA dev_tls_local-ca.crt -CAkey dev_tls_local-ca.key \
-CAcreateserial \
-out dev_tls_m.localhost.crt \
-days 800 \
-sha256 \
-extfile <( cat <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = m.localhost
DNS.3 = *.m.localhost
DNS.4 = *.othersite.m.localhost
DNS.5 = *.nip.io
EOF
)
+53
View File
@@ -0,0 +1,53 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://synapse.m.localhost",
"server_name": "synapse.m.localhost"
}
},
"disable_custom_urls": false,
"disable_guests": false,
"disable_login_language_selector": false,
"disable_3pid_login": false,
"force_verification": false,
"brand": "Element",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.riot.im/scalar/api"
],
"default_widget_container_height": 280,
"default_country_code": "GB",
"show_labs_settings": false,
"features": {
"feature_element_call_video_rooms": true,
"feature_video_rooms": true,
"feature_group_calls": true,
"feature_release_announcement": false
},
"default_federate": true,
"default_theme": "light",
"room_directory": {
"servers": ["matrix.org"]
},
"enable_presence_by_hs_url": {
"https://matrix.org": false,
"https://matrix-client.matrix.org": false
},
"setting_defaults": {
"breadcrumbs": true,
"feature_group_calls": true
},
"jitsi": {
"preferred_domain": "meet.element.io"
},
"element_call": {
"participant_limit": 8,
"brand": "Element Call"
},
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
}
+53
View File
@@ -0,0 +1,53 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://synapse.othersite.m.localhost",
"server_name": "synapse.othersite.m.localhost"
}
},
"disable_custom_urls": false,
"disable_guests": false,
"disable_login_language_selector": false,
"disable_3pid_login": false,
"force_verification": false,
"brand": "Element",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.riot.im/scalar/api"
],
"default_widget_container_height": 280,
"default_country_code": "GB",
"show_labs_settings": false,
"features": {
"feature_element_call_video_rooms": true,
"feature_video_rooms": true,
"feature_group_calls": true,
"feature_release_announcement": false
},
"default_federate": true,
"default_theme": "light",
"room_directory": {
"servers": ["matrix.org"]
},
"enable_presence_by_hs_url": {
"https://matrix.org": false,
"https://matrix-client.matrix.org": false
},
"setting_defaults": {
"breadcrumbs": true,
"feature_group_calls": true
},
"jitsi": {
"preferred_domain": "meet.element.io"
},
"element_call": {
"participant_limit": 8,
"brand": "Element Call"
},
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
}
-23
View File
@@ -1,23 +0,0 @@
port: 7880
bind_addresses:
- "0.0.0.0"
rtc:
tcp_port: 7881
port_range_start: 50100
port_range_end: 50200
use_external_ip: false
#redis:
# address: redis:6379
# username: ""
# password: ""
# db: 0
turn:
enabled: false
domain: localhost
cert_file: ""
key_file: ""
tls_port: 5349
udp_port: 443
external_tls: true
keys:
devkey: secret
@@ -0,0 +1,99 @@
server_name: "synapse.othersite.m.localhost"
public_baseurl: https://synapse.othersite.m.localhost/
pid_file: /data/homeserver.pid
listeners:
- port: 18008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation, openid]
compress: false
database:
name: sqlite3
args:
database: /data/homeserver.db
media_store_path: /data/media_store
signing_key_path: "/data/SERVERNAME.signing.key"
# Due to custom TLS certificate with domains
# - m.localhost, localhost
# - *.m.localhost
# - *.othersite.m.localhost
# we disable certificate verification to allow for federation.
# WARNING: DO NOT USE IN PRODUCTION!!!
federation_verify_certificates: false
ip_range_blacklist: []
trusted_key_servers:
- server_name: "synapse.m.localhost"
accept_keys_insecurely: true
experimental_features:
# MSC3266: Room summary API. Used for knocking over federation
msc3266_enabled: true
# MSC4222 needed for syncv2 state_after. This allow clients to
# correctly track the state of the room.
msc4222_enabled: true
# sticky events for MatrixRTC user state
msc4354_enabled: true
# MatrixRTC
msc4143_enabled: true
# Enable membership look-up via /is_joined.
msc4502_enabled: true
# Enable C-S & S-S request proxying for application services.
msc4512_enabled: true
app_service_config_files:
- /data/cfg/app-service.yaml
# The maximum allowed duration by which sent events can be delayed, as
# per MSC4140. Must be a positive value if set. Defaults to no
# duration (null), which disallows sending delayed events.
max_event_delay_duration: 24h
# Required for Element Call in Single Page Mode due to on-the-fly user registration
enable_registration: true
enable_registration_without_verification: true
# Shared secret for admin user registration via API (for testing only!)
registration_shared_secret: "test_shared_secret_for_local_dev_only"
report_stats: false
# Ratelimiting settings for client actions (registration, login, messaging).
#
# Each ratelimiting configuration is made of two parameters:
# - per_second: number of requests a client can send per second.
# - burst_count: number of requests a client can send before being throttled.
rc_message:
per_second: 10000
burst_count: 10000
rc_delayed_event_mgmt:
per_second: 10000
burst_count: 10000
rc_login:
address:
per_second: 10000
burst_count: 10000
account:
per_second: 10000
burst_count: 10000
failed_attempts:
per_second: 10000
burst_count: 10000
rc_registration:
per_second: 10000
burst_count: 10000
matrix_rtc:
transports:
- type: livekit
livekit_service_url: https://matrix-rtc.othersite.m.localhost/livekit/jwt
+99
View File
@@ -0,0 +1,99 @@
server_name: "synapse.m.localhost"
public_baseurl: https://synapse.m.localhost/
pid_file: /data/homeserver.pid
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation, openid]
compress: false
database:
name: sqlite3
args:
database: /data/homeserver.db
media_store_path: /data/media_store
signing_key_path: "/data/SERVERNAME.signing.key"
# Due to custom TLS certificate with domains
# - m.localhost, localhost
# - *.m.localhost
# - *.othersite.m.localhost
# we disable certificate verification to allow for federation.
# WARNING: DO NOT USE IN PRODUCTION!!!
federation_verify_certificates: false
ip_range_blacklist: []
trusted_key_servers:
- server_name: "synapse.othersite.m.localhost"
accept_keys_insecurely: true
experimental_features:
# MSC3266: Room summary API. Used for knocking over federation
msc3266_enabled: true
# MSC4222 needed for syncv2 state_after. This allow clients to
# correctly track the state of the room.
msc4222_enabled: true
# sticky events for MatrixRTC user state
msc4354_enabled: true
# MatrixRTC
msc4143_enabled: true
# Enable membership look-up via /is_joined.
msc4502_enabled: true
# Enable C-S & S-S request proxying for application services.
msc4512_enabled: true
app_service_config_files:
- /data/cfg/app-service.yaml
# The maximum allowed duration by which sent events can be delayed, as
# per MSC4140. Must be a positive value if set. Defaults to no
# duration (null), which disallows sending delayed events.
max_event_delay_duration: 24h
# Required for Element Call in Single Page Mode due to on-the-fly user registration
enable_registration: true
enable_registration_without_verification: true
# Shared secret for admin user registration via API (for testing only!)
registration_shared_secret: "test_shared_secret_for_local_dev_only"
report_stats: false
# Ratelimiting settings for client actions (registration, login, messaging).
#
# Each ratelimiting configuration is made of two parameters:
# - per_second: number of requests a client can send per second.
# - burst_count: number of requests a client can send before being throttled.
rc_message:
per_second: 10000
burst_count: 10000
rc_delayed_event_mgmt:
per_second: 10000
burst_count: 10000
rc_login:
address:
per_second: 10000
burst_count: 10000
account:
per_second: 10000
burst_count: 10000
failed_attempts:
per_second: 10000
burst_count: 10000
rc_registration:
per_second: 10000
burst_count: 10000
matrix_rtc:
transports:
- type: livekit
livekit_service_url: https://matrix-rtc.m.localhost/livekit/jwt
-5
View File
@@ -1,5 +0,0 @@
bind 0.0.0.0
protected-mode yes
port 6379
timeout 0
tcp-keepalive 300
+6 -1
View File
@@ -1,6 +1,10 @@
# Don't post comments on PRs; they're noisy and the same information can be
# gotten through the checks section at the bottom of the PR anyways
comment: false
github_checks:
# Don't mark up the diffs on PRs with warnings about untested lines; we're not
# aiming for 100% test coverage and they just get in the way of reviewing
annotations: false
coverage:
status:
project:
@@ -9,5 +13,6 @@ coverage:
informational: true
patch:
default:
# Expect 80% coverage on all lines that a PR touches
# Enforce 80% coverage on all lines that a PR
# touches
target: 80%
+57
View File
@@ -0,0 +1,57 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { expect, test } from "vitest";
import { render, screen } from "@testing-library/react";
import { type ReactNode } from "react";
import { Tooltip, TooltipProvider } from "@vector-im/compound-web";
import { CallPortalRoot } from "./CallPortalRoot";
// A button whose accessible name comes from its tooltip, as every icon button
// in the call does: the name is lost whenever the tooltip has nowhere to go.
const LabelledButton = (): ReactNode => (
<TooltipProvider>
<Tooltip label="Microphone">
<button>🎤</button>
</Tooltip>
</TooltipProvider>
);
test("floats into the host document with no root", () => {
render(
<CallPortalRoot root={undefined}>
<LabelledButton />
</CallPortalRoot>,
);
expect(screen.getByRole("button", { name: "Microphone" })).toBeTruthy();
});
test("floats into the root it is given", () => {
const root = document.createElement("div");
document.body.appendChild(root);
render(
<CallPortalRoot root={root}>
<LabelledButton />
</CallPortalRoot>,
);
const button = screen.getByRole("button", { name: "Microphone" });
const label = document.getElementById(
button.getAttribute("aria-labelledby")!,
);
expect(root.contains(label)).toBe(true);
root.remove();
});
test("waits for a root that is not available yet", () => {
render(
<CallPortalRoot root={null}>
<LabelledButton />
</CallPortalRoot>,
);
expect(screen.queryByRole("button", { name: "Microphone" })).toBeNull();
});
+26
View File
@@ -0,0 +1,26 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { type FC, type ReactNode } from "react";
import { PortalRoot } from "@vector-im/compound-web";
interface Props {
root: HTMLElement | null | undefined;
children: ReactNode;
}
/**
* Where Compound floats the call's menus and tooltips. With no `root` the call
* is not wrapped at all and they go into the host document's body; `null` is
* Compound's "not available yet", and the floating parts wait for it.
*/
export const CallPortalRoot: FC<Props> = ({ root, children }): ReactNode =>
root === undefined ? (
children
) : (
<PortalRoot root={root}>{children}</PortalRoot>
);
+51
View File
@@ -0,0 +1,51 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
/* The container a host mounts us into. It fills whatever space the host gives
it, and nothing we draw may leave it.
That takes two separate things, which are easy to mistake for one. `isolation`
gives us a stacking context, so nothing inside can be layered above the host's
own interface. Containment makes us the containing block for `position: fixed`
descendants, and clips what we paint to our own box: without it, the modal
scrim and dialog — which are positioned `fixed` and centred, since in the app
they are meant to cover the page — resolve against the viewport and appear in
the middle of the host's window rather than in the middle of the call.
The clipping cuts both ways: a menu near the edge of a small container is
trimmed rather than overflowing into the host. That is the trade being a
component rather than a page makes. */
.root {
display: flex;
flex-direction: column;
inline-size: 100%;
block-size: 100%;
isolation: isolate;
contain: layout paint;
position: relative;
background-color: var(--cpd-color-bg-canvas-default);
color: var(--cpd-color-text-primary);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-tap-highlight-color: transparent;
}
/* The call itself. It is a stacking context of its own, as the standalone
page's `#root` is, so that the layers the call view uses for its header, footer
and overlays stay below the modals and toasts, which are portalled into the
root and carry no layer of their own.
What Compound floats — tooltips, menus — is not in here at all: it goes into
the host's body, as it would for any other component on the host's page, and is
styled and layered by the host's copy of Compound. */
.content {
display: flex;
flex-direction: column;
block-size: 100%;
position: relative;
isolation: isolate;
}
+138
View File
@@ -0,0 +1,138 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
/**
* EXPERIMENTAL
*
* What a host needs in order to talk about Element Call, without Element Call:
* the component's props and the types they are made of, the handle and the
* host bridge, the intents a call can be started with and the configuration
* each implies.
*
* This is an entry point of its own, `@element-hq/element-call-component/api`,
* so that a host can import it on a path that must stay light — a call model
* that needs `BackgroundStyle.Solid` as a value, say — and load the component
* itself, and everything it brings, only when a call is shown. The main entry
* point re-exports all of it, so a host that does not care may import
* everything from there.
*
* Nothing in here may reach anything that is not a type or a constant: the
* point of this module is what it does not import.
*/
import type { Ref } from "react";
import type { MatrixClient } from "matrix-js-sdk";
import type { UrlProperties } from "../src/UrlParams";
import type { ElementCallHandle, ElementCallHostBridge } from "./host";
import {
BackgroundStyle,
configurationForIntent,
HeaderStyle,
type UrlConfiguration,
UserIntent,
} from "../src/UrlConfiguration";
// How the host and Element Call talk to each other, and what they say
export type { ElementCallHandle, ElementCallHostBridge } from "./host";
export type { DeviceMuteRequest, DeviceMuteState } from "../src/HostBridge";
export type { JoinCallData } from "../src/widget";
// The deployment-wide configuration, as distinct from ElementCallConfiguration
// below, which is per call
export type { ConfigOptions } from "../src/config/ConfigOptions";
// The values that appear in ElementCallConfiguration and in the intent, and
// what each intent means by default
export {
BackgroundStyle,
configurationForIntent,
HeaderStyle,
type UrlConfiguration,
UserIntent,
};
/**
* How Element Call should behave. Everything is optional; anything left out
* takes the default that {@link ElementCallProps.intent} implies.
*
* This is the behaviour a widget can be configured with through its URL, plus
* the one fact about the call a host has a say in here, the background. The
* rest of what a widget's URL carries — who the user is, how to reach the
* homeserver, where to report analytics, the shared secret of a room that is
* encrypted with one — a component host supplies by other routes, or not at
* all; and what can change while the call is running, the theme and the
* language, is a prop of its own.
*/
export type ElementCallConfiguration = Partial<UrlConfiguration> &
Partial<Pick<UrlProperties, "background">>;
export interface ElementCallProps {
/**
* The client to place the call with. Element Call does not authenticate
* anyone or manage a session of its own; this one is the host's.
*/
client: MatrixClient;
/** The room to call in. The host's client must already know about it. */
roomId: string;
/**
* What the user asked for — whether they started the call or joined one that
* was already running, and whether it is a call in a group or a DM. Element
* Call decides what each of those means: whether to show the lobby first,
* whether to ring, and so on.
*
* Defaults to joining an existing group call, which is the most conservative
* reading, but a host that knows which button the user pressed should say so.
*/
intent?: UserIntent;
/**
* How Element Call should behave, overriding whatever {@link intent} implies.
* A host that finds itself setting a lot of these probably wants a different
* intent instead.
*
* Compared by value, so it is fine to write this inline; only a change to
* what it says restarts anything.
*/
config?: ElementCallConfiguration;
/**
* What Element Call tells the host while the call is running: that the user
* has joined or hung up, that it would like to be kept on screen, and so on.
* Without one, Element Call assumes nobody is listening.
*/
hostBridge?: ElementCallHostBridge;
/**
* What the host tells Element Call: to hang up, to mute, to join. Available
* once the component has rendered.
*/
ref?: Ref<ElementCallHandle>;
/**
* The theme to show Element Call in, `light` or `dark`. Left out, Element
* Call picks. Changes take effect at once, and cost nothing else.
*/
theme?: string;
/**
* The language to show Element Call in, as a BCP 47 tag: one of the
* `supportedLanguages` the main entry point exports, or something that falls
* back to one (`de-AT` to `de`). Left out, the browser's language is used.
*
* Translations are one thing shared by every Element Call on the page, so
* the most recently set language wins for all of them.
*/
language?: string;
/**
* Where the parts of Element Call that float above it — its menus and
* tooltips, which Compound portals out of the call — are rendered. Left out,
* they go into the host document's body, as they do for any other component
* on the host's page.
*
* A host that moves Element Call's DOM into another document, such as a
* Document Picture-in-Picture window, passes that document's body here so
* that a menu opens in the window its button is in. Changes take effect at
* once. `null` means the root is not available yet, as from a callback ref
* that has not fired: menus and tooltips wait for it rather than falling
* back to the body.
*/
portalRoot?: HTMLElement | null;
}
+112
View File
@@ -0,0 +1,112 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { describe, expect, it } from "vitest";
import postcss from "postcss";
import { ROOT_SELECTOR, scopeStylesToRoot } from "./scopeStylesToRoot";
const inRoot = `:where(${ROOT_SELECTOR}, ${ROOT_SELECTOR} *)`;
const isRoot = `:where(${ROOT_SELECTOR})`;
async function scope(css: string, file = "base.css"): Promise<string> {
const result = await postcss([scopeStylesToRoot()]).process(css, {
from: file,
});
return result.css;
}
describe("scopeStylesToRoot", () => {
it("makes the root stand in for the document", async () => {
expect(await scope("html { line-height: 1.15 }")).toBe(
`${isRoot} { line-height: 1.15 }`,
);
expect(await scope("body { margin: 0 }")).toBe(`${isRoot} { margin: 0 }`);
expect(await scope(":root { --a: 1 }")).toBe(`${isRoot} { --a: 1 }`);
expect(await scope("body.no-scroll-body { position: fixed }")).toBe(
`${isRoot}.no-scroll-body { position: fixed }`,
);
expect(await scope("body .x { color: red }")).toBe(
`${isRoot} .x { color: red }`,
);
});
it("collapses selectors that all became the root", async () => {
expect(await scope("html, body, input { font: inherit }")).toBe(
`${isRoot},input${inRoot} { font: inherit }`,
);
});
it("confines everything else to the root and what is inside it", async () => {
expect(await scope("h1 { margin: 0 }")).toBe(`h1${inRoot} { margin: 0 }`);
expect(await scope(".cpd-theme-dark { --a: 1 }")).toBe(
`.cpd-theme-dark${inRoot} { --a: 1 }`,
);
expect(await scope("* { box-sizing: border-box }")).toBe(
`*${inRoot} { box-sizing: border-box }`,
);
expect(await scope(".a > .b + .c { color: red }")).toBe(
`.a>.b+.c${inRoot} { color: red }`,
);
});
it("keeps pseudo-elements last", async () => {
expect(await scope("button::-moz-focus-inner { border: 0 }")).toBe(
`button${inRoot}::-moz-focus-inner { border: 0 }`,
);
expect(await scope(".a .b:hover::after { content: '' }")).toBe(
`.a .b:hover${inRoot}::after { content: '' }`,
);
expect(await scope("p:first-letter { color: red }")).toBe(
`p${inRoot}:first-letter { color: red }`,
);
});
it("leaves alone what already names the root", async () => {
const css = `${ROOT_SELECTOR}[data-platform="ios"] { --a: 1 }`;
expect(await scope(css)).toBe(css);
});
it("reaches into layers and media queries", async () => {
expect(
await scope(
"@layer normalize { h1 { margin: 0 } } @media (min-width: 1px) { p { margin: 0 } }",
),
).toBe(
`@layer normalize { h1${inRoot} { margin: 0 } } @media (min-width: 1px) { p${inRoot} { margin: 0 } }`,
);
});
it("does not touch keyframes or nested rules", async () => {
expect(
await scope("@keyframes spin { from { opacity: 0 } to { opacity: 1 } }"),
).toBe("@keyframes spin { from { opacity: 0 } to { opacity: 1 } }");
expect(
await scope(
".a { color: red; &:hover { color: blue } .b { color: green } }",
),
).toBe(
`.a${inRoot} { color: red; &:hover { color: blue } .b { color: green } }`,
);
});
it("only touches the bare selectors of a CSS module", async () => {
const file = "Settings.module.css";
expect(await scope("pre { font-size: 1px }", file)).toBe(
`pre${inRoot} { font-size: 1px }`,
);
expect(await scope(".modal pre { font-size: 1px }", file)).toBe(
`.modal pre${inRoot} { font-size: 1px }`,
);
expect(await scope(".box_abc12 { border: 0 }", file)).toBe(
".box_abc12 { border: 0 }",
);
expect(await scope(".a .b_abc12:hover { border: 0 }", file)).toBe(
".a .b_abc12:hover { border: 0 }",
);
});
});
+162
View File
@@ -0,0 +1,162 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import {
type AtRule,
type Container,
type Document,
type Plugin,
type Rule,
} from "postcss";
import selectorParser, {
type Node,
type Pseudo,
type Selector,
} from "postcss-selector-parser";
/**
* How the stylesheets find Element Call's root element. The attribute is put
* there by `useTheme`, on the container the host gives the component.
*/
export const ROOT_SELECTOR = "[data-element-call-root]";
// Both are `:where()`, which has no specificity of its own, so the rules keep
// exactly the weight they had before being scoped and nothing in Element Call's
// cascade changes — only where it applies.
//
// The root, or anything inside it. Appended to the element a rule is about,
// rather than prepended to the whole selector, so that a rule about the root
// itself (its theme class, say) still matches.
const IN_ROOT = `:where(${ROOT_SELECTOR}, ${ROOT_SELECTOR} *)`;
// The root itself, standing in for the document.
const IS_ROOT = `:where(${ROOT_SELECTOR})`;
/**
* Confines a stylesheet to Element Call's root element, for the build of
* Element Call as a component.
*
* As a page of its own, Element Call can style the document: normalize.css and
* its own base styles speak of `html`, `body` and bare elements, and its custom
* properties are declared on `:root`. As a component, all of that would land on
* the host's document too. This rewrites every selector so that it matches only
* the root or its descendants:
*
* - `html`, `body` and `:root` become the root element, which is what stands in
* for the document inside a host.
* - Everything else keeps its selector and gains `:where([data-element-call-root],
* [data-element-call-root] *)` on the element it styles.
* - Selectors that already name the root are left alone, as are keyframe
* selectors and rules nested inside another rule, which are relative to it.
*
* CSS modules are scoped by their class names already, so only their selectors
* that would match by element alone — `pre` rather than `.pre` — are touched.
*
* The root's custom properties are still inherited by everything inside it,
* the way they were from `:root`. Compound's own stylesheet — the design
* tokens, the component styles, the fonts — is not in this build at all: the
* host supplies it, unscoped, along with its copy of Compound.
*/
export function scopeStylesToRoot(): Plugin {
return {
postcssPlugin: "element-call-scope-styles-to-root",
Once(root) {
const isModule =
root.source?.input.file?.endsWith(".module.css") ?? false;
root.walkRules((rule) => {
if (isRelative(rule)) return;
rule.selector = (isModule ? scopeBare : scopeAll).processSync(
rule.selector,
{ lossless: false },
);
});
},
};
}
/** Whether a rule's selectors are relative to something other than the document. */
function isRelative(rule: Rule): boolean {
let parent: Container | Document | undefined = rule.parent;
while (parent !== undefined) {
if (parent.type === "rule") return true;
if (parent.type === "atrule") {
const { name } = parent as AtRule;
if (name.endsWith("keyframes") || name === "page") return true;
}
parent = parent.parent;
}
return false;
}
const processor = (isModule: boolean): ReturnType<typeof selectorParser> =>
selectorParser((selectors) => {
selectors.each((selector) => {
scopeSelector(selector, isModule);
});
// Mapping `html, body` onto the root leaves the same selector twice
const seen = new Set<string>();
selectors.each((selector) => {
const text = String(selector).trim();
if (seen.has(text)) selector.remove();
else seen.add(text);
});
});
// Everything, for stylesheets that speak of the document; only what a class
// does not already confine, for CSS modules
const scopeAll = processor(false);
const scopeBare = processor(true);
function scopeSelector(selector: Selector, isModule: boolean): void {
if (String(selector).includes(ROOT_SELECTOR)) return;
const compounds = splitCompounds(selector);
if (compounds.length === 0) return;
// Something said of the document is said of the root instead
const document = compounds[0].find(isDocumentSelector);
if (document !== undefined) {
document.replaceWith(pseudo(IS_ROOT));
return;
}
const subject = compounds.at(-1)!;
if (isModule && subject.some((node) => node.type === "class")) return;
// Pseudo-elements have to come last in a compound selector
const pseudoElement = subject.find(isPseudoElement);
if (pseudoElement === undefined) selector.append(pseudo(IN_ROOT));
else selector.insertBefore(pseudoElement, pseudo(IN_ROOT));
}
/** The compound selectors making up a complex selector, in order. */
function splitCompounds(selector: Selector): Node[][] {
const compounds: Node[][] = [[]];
for (const node of selector.nodes) {
if (node.type === "combinator") compounds.push([]);
else if (node.type !== "comment") compounds.at(-1)!.push(node);
}
return compounds.filter((compound) => compound.length > 0);
}
function isDocumentSelector(node: Node): boolean {
return (
(node.type === "tag" && (node.value === "html" || node.value === "body")) ||
(node.type === "pseudo" && node.value === ":root")
);
}
function isPseudoElement(node: Node): node is Pseudo {
if (node.type !== "pseudo") return false;
return (
node.value.startsWith("::") ||
[":before", ":after", ":first-line", ":first-letter"].includes(node.value)
);
}
function pseudo(text: string): Pseudo {
return selectorParser().astSync(text).nodes[0].nodes[0].clone() as Pseudo;
}
+46
View File
@@ -0,0 +1,46 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { type ElementCallHostBridge } from "../index";
/**
* A host bridge that reports everything it is told, so that the harness can
* watch what Element Call says to its host. (What the host says to Element
* Call goes through the component's handle, and is logged by the pane.)
*/
export function createDevHostBridge(
log: (message: string) => void,
/** What the host does when Element Call asks to be closed. */
onClose: () => void,
): ElementCallHostBridge {
/**
* Records something Element Call told the host. Nothing is sent anywhere, so
* this is only asynchronous because a real host's answer would have to be.
*/
const told = async (message: string): Promise<void> => {
log(`→ ${message}`);
await Promise.resolve();
};
return {
setAlwaysOnScreen: async (alwaysOnScreen): Promise<void> =>
await told(`setAlwaysOnScreen(${alwaysOnScreen})`),
contentLoaded: async (): Promise<void> => await told("contentLoaded"),
notifyJoined: async (): Promise<void> => await told("notifyJoined"),
notifyHungUp: async (): Promise<void> => await told("notifyHungUp"),
notifyDeviceMute: async (state): Promise<void> =>
await told(
`notifyDeviceMute(audio: ${state.audio_enabled}, video: ${state.video_enabled})`,
),
// Present because this host really can dismiss Element Call, which is what
// makes it offer a close affordance at all
close: async (): Promise<void> => {
await told("close");
onClose();
},
};
}
+140
View File
@@ -0,0 +1,140 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
.credentials {
display: flex;
flex-direction: column;
gap: 8px;
max-inline-size: 420px;
margin: 48px auto;
padding: 24px;
background-color: #ffffff;
border: 1px solid #d4d4d8;
border-radius: 8px;
}
.field {
display: flex;
flex-direction: column;
gap: 4px;
}
.error {
color: #b91c1c;
}
.harness {
display: grid;
grid-template-rows: auto 1fr auto;
block-size: 100%;
}
.header,
.paneBar {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 12px;
border-block-end: 1px solid #d4d4d8;
background-color: #ffffff;
}
.header h1 {
font-size: 16px;
margin: 0;
}
.middle {
display: flex;
min-block-size: 0;
}
.sidebar {
flex: 0 0 220px;
padding: 12px;
border-inline-end: 1px solid #d4d4d8;
background-color: #ffffff;
overflow-y: auto;
}
.panes {
display: flex;
flex-wrap: wrap;
/* So that a pane is the size it was dragged to, rather than being stretched
to fill the row */
align-items: flex-start;
align-content: flex-start;
gap: 16px;
padding: 16px;
flex: 1;
min-inline-size: 0;
overflow: auto;
}
.pane {
display: flex;
flex-direction: column;
border: 1px solid #d4d4d8;
border-radius: 8px;
overflow: hidden;
background-color: #ffffff;
}
.paneBar {
flex-wrap: wrap;
gap: 6px;
border-block-end: none;
}
/* The space the host gives Element Call. Resizable so that the sizes it has to
cope with can be found by dragging rather than by rebuilding, and `overflow:
hidden` both to enable the resize handle and to show up anything inside Element
Call that does not fit the box it was given. */
.paneCall {
inline-size: 560px;
block-size: 420px;
min-inline-size: 180px;
min-block-size: 180px;
resize: both;
overflow: hidden;
}
.log {
max-block-size: 180px;
overflow-y: auto;
padding: 8px 12px;
border-block-start: 1px solid #d4d4d8;
background-color: #ffffff;
font-size: 12px;
}
.log h2 {
font-size: 13px;
margin: 0 0 4px;
}
.log ol {
margin: 0;
padding: 0;
list-style: none;
}
/* A host overlay, which Element Call must not be able to draw over */
.dialogScrim {
position: fixed;
inset: 0;
display: grid;
place-items: center;
background-color: rgb(0 0 0 / 50%);
z-index: 10;
}
.dialog {
padding: 24px;
border-radius: 8px;
background-color: #ffffff;
}
+380
View File
@@ -0,0 +1,380 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import {
type FC,
type FormEvent,
type ReactNode,
useCallback,
useMemo,
useRef,
useState,
} from "react";
import { type MatrixClient } from "matrix-js-sdk";
import { logger } from "matrix-js-sdk/lib/logger";
import {
ElementCall,
type ElementCallHandle,
supportedLanguages,
} from "../index";
import { createDevHostBridge } from "./DevHostBridge";
import { createSession, joinRoom } from "./session";
import styles from "./Harness.module.css";
interface Credentials {
homeserver: string;
username: string;
password: string;
room: string;
}
const CREDENTIALS_KEY = "element-call-component-harness";
const DEFAULT_CREDENTIALS: Credentials = {
homeserver: "https://synapse.m.localhost",
username: "",
password: "",
room: "",
};
/**
* The credentials to start with: the last ones used, so that a reload does not
* mean typing them again, overridden by anything in the query string.
*
* A host reading its own URL is entirely proper — it was Element Call doing so
* that was the mistake. It lets the end-to-end tests, or a shared link, say
* which account and room to use.
*/
function loadCredentials(): Credentials {
let stored: Partial<Credentials> = {};
try {
const json = localStorage.getItem(CREDENTIALS_KEY);
if (json !== null) stored = JSON.parse(json) as Credentials;
} catch (e) {
logger.warn("Could not read the stored harness credentials", e);
}
const query = new URLSearchParams(location.search);
const fromUrl = Object.fromEntries(
(["homeserver", "username", "password", "room"] as const)
.map((name) => [name, query.get(name)])
.filter(([, value]) => value !== null),
) as Partial<Credentials>;
return { ...DEFAULT_CREDENTIALS, ...stored, ...fromUrl };
}
interface Session {
label: string;
client: MatrixClient;
}
type State =
| { phase: "credentials" }
| { phase: "starting"; progress: string }
| { phase: "started"; roomId: string; sessions: Session[] }
| { phase: "failed"; error: string };
interface LogEntry {
pane: string;
message: string;
at: string;
}
/**
* One Element Call component, with the controls a host would have over it: the
* requests it can make of Element Call, and the ability to take it off screen
* altogether.
*/
const Pane: FC<{
session: Session;
roomId: string;
theme: string | undefined;
language: string | undefined;
log: (pane: string, message: string) => void;
}> = ({ session, roomId, theme, language, log }): ReactNode => {
const [mounted, setMounted] = useState(true);
const bridge = useMemo(
() =>
createDevHostBridge(
(message) => log(session.label, message),
() => setMounted(false),
),
[log, session.label],
);
// What the host asks of Element Call goes through the component's handle.
// Worth saying out loud when a request is refused — asking to hang up when
// there is no call, say — since that is the sort of thing the harness is for.
const handle = useRef<ElementCallHandle>(null);
const ask = (
name: string,
make: (handle: ElementCallHandle) => Promise<unknown>,
): void => {
if (handle.current === null) {
log(session.label, `← ${name}: not mounted`);
return;
}
log(session.label, `← ${name}`);
make(handle.current).then(
(reply) =>
log(
session.label,
`→ ${name} acknowledged${reply === undefined ? "" : `: ${JSON.stringify(reply)}`}`,
),
(e: unknown) => log(session.label, `→ ${name} refused: ${e}`),
);
};
return (
<section className={styles.pane} data-testid="call-pane">
<div className={styles.paneBar}>
<strong>{session.label}</strong>
<code>{session.client.getDeviceId()}</code>
<button onClick={(): void => setMounted((m) => !m)}>
{mounted ? "Unmount" : "Mount"}
</button>
<button
onClick={(): void =>
ask(
"setDeviceMute(audio: false)",
async (h) => await h.setDeviceMute({ audio_enabled: false }),
)
}
>
Mute
</button>
<button
onClick={(): void => ask("hangUp", async (h) => await h.hangUp())}
>
Hang up
</button>
</div>
{/* Resizable, because how Element Call copes with the size it is given is
one of the things we cannot find out from the standalone app */}
<div className={styles.paneCall} data-testid="call-container">
{mounted && (
<ElementCall
ref={handle}
client={session.client}
roomId={roomId}
hostBridge={bridge}
theme={theme}
language={language}
/>
)}
</div>
</section>
);
};
/** Host furniture, to make it visible if Element Call styles anything but itself. */
const HostChrome: FC = (): ReactNode => (
<nav className={styles.sidebar}>
<h2>Host chrome</h2>
<p>
This column belongs to the host. If Element Call&apos;s stylesheet reaches
outside its own container, it shows up here.
</p>
<hr />
<ul>
<li>Some room</li>
<li>Another room</li>
</ul>
<button>A host button</button>
</nav>
);
/**
* A dialog of the host's own, over the top of the calls. Element Call as a
* component has to sit underneath this — being unable to is one of the reasons
* for a component rather than an iframe.
*/
const HostDialog: FC<{ onClose: () => void }> = ({ onClose }): ReactNode => (
<div className={styles.dialogScrim}>
<div className={styles.dialog}>
<h2>A dialog belonging to the host</h2>
<p>This should cover the calls completely.</p>
<button onClick={onClose}>Close</button>
</div>
</div>
);
/**
* Stands in for a host application using the Element Call component: it owns the Matrix
* clients, the page and the space each call is given, and reaches Element Call
* only through the component's public interface.
*
* Two calls at once, from two devices of the same account, so that a real call
* happens between them and anything Element Call keeps once per process rather
* than once per call shows itself.
*/
export const Harness: FC = (): ReactNode => {
const [credentials, setCredentials] = useState(loadCredentials);
const [state, setState] = useState<State>({ phase: "credentials" });
const [entries, setEntries] = useState<LogEntry[]>([]);
const [dialogOpen, setDialogOpen] = useState(false);
// The host's language setting, which Element Call follows. Undefined means
// the host has none and Element Call uses the browser's.
const [language, setLanguage] = useState<string | undefined>(undefined);
const [theme, setTheme] = useState<string | undefined>(undefined);
const log = useCallback((pane: string, message: string): void => {
setEntries((entries) =>
[
...entries,
{ pane, message, at: new Date().toLocaleTimeString() },
].slice(-100),
);
}, []);
const start = useCallback(
(event: FormEvent): void => {
event.preventDefault();
localStorage.setItem(CREDENTIALS_KEY, JSON.stringify(credentials));
const { homeserver, username, password, room } = credentials;
const progress = (message: string): void =>
setState({ phase: "starting", progress: message });
progress("Starting");
void (async (): Promise<void> => {
try {
// One at a time: two logins at once from the same account is the
// shape of request homeservers rate limit
const sessions: Session[] = [];
for (const label of ["Call A", "Call B"])
sessions.push({
label,
client: await createSession(
homeserver,
username,
password,
(message) => progress(`${label}: ${message}`),
),
});
progress("Joining the room");
let roomId = room;
for (const { client } of sessions)
roomId = await joinRoom(client, roomId);
setState({ phase: "started", roomId, sessions });
} catch (e) {
logger.error("The harness could not start", e);
setState({ phase: "failed", error: `${e}` });
}
})();
},
[credentials],
);
const field = (
name: keyof Credentials,
label: string,
type = "text",
): ReactNode => (
<label className={styles.field}>
{label}
<input
type={type}
value={credentials[name]}
onChange={(e): void =>
setCredentials((c) => ({ ...c, [name]: e.target.value }))
}
/>
</label>
);
if (state.phase !== "started")
return (
<form className={styles.credentials} onSubmit={start}>
<h1>Element Call component harness</h1>
<p>
Signs in twice and shows the Element Call component twice, in a page
that is not Element Call&apos;s own.
</p>
{field("homeserver", "Homeserver")}
{field("username", "Username")}
{field("password", "Password", "password")}
{field("room", "Room ID or alias")}
<button type="submit" disabled={state.phase === "starting"}>
Start
</button>
{state.phase === "starting" && <p>{state.progress}</p>}
{state.phase === "failed" && (
<p className={styles.error}>{state.error}</p>
)}
</form>
);
return (
<div className={styles.harness}>
<header className={styles.header}>
<h1>Element Call component harness</h1>
<code>{state.roomId}</code>
<button onClick={(): void => setDialogOpen(true)}>
Open a host dialog
</button>
<label>
Theme{" "}
<select
value={theme ?? ""}
onChange={(e): void => setTheme(e.target.value || undefined)}
>
<option value="">Element Call&apos;s choice</option>
<option value="light">light</option>
<option value="dark">dark</option>
</select>
</label>
<label>
Language{" "}
<select
value={language ?? ""}
onChange={(e): void => setLanguage(e.target.value || undefined)}
>
<option value="">Browser default</option>
{supportedLanguages.map((tag) => (
<option key={tag} value={tag}>
{tag}
</option>
))}
</select>
</label>
</header>
<div className={styles.middle}>
<HostChrome />
<main className={styles.panes}>
{state.sessions.map((session) => (
<Pane
key={session.label}
session={session}
roomId={state.roomId}
theme={theme}
language={language}
log={log}
/>
))}
</main>
</div>
<section className={styles.log} data-testid="bridge-log">
<h2>Host bridge</h2>
<ol>
{entries.map((entry, i) => (
<li key={i}>
<code>{entry.at}</code> <strong>{entry.pane}</strong>{" "}
{entry.message}
</li>
))}
</ol>
</section>
{dialogOpen && <HostDialog onClose={(): void => setDialogOpen(false)} />}
</div>
);
};
+23
View File
@@ -0,0 +1,23 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
/* The host page's own styles. Deliberately plain, and deliberately not using
Element Call's design tokens: the harness should look like it does because of
this file, not because Element Call styled it. */
html,
body,
#root {
height: 100%;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
background-color: #f4f4f5;
color: #18181b;
}
+21
View File
@@ -0,0 +1,21 @@
<!doctype html>
<!--
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
-->
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Element Call component harness</title>
</head>
<body>
<!-- Deliberately plain: this page stands in for a host application, so
anything it looks like must have come from the host's own styles or from
Element Call reaching outside its container. -->
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
+52
View File
@@ -0,0 +1,52 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { logger } from "matrix-js-sdk/lib/logger";
// What a host provides along with its copy of Compound: its stylesheet, the
// design tokens and the fonts they name. The component does not bundle them.
import "@fontsource/inter/400.css";
import "@fontsource/inter/500.css";
import "@fontsource/inter/600.css";
import "@fontsource/inter/700.css";
import "@fontsource/inconsolata/400.css";
import "@fontsource/inconsolata/700.css";
import "@vector-im/compound-design-tokens/assets/web/css/compound-design-tokens.css";
import "@vector-im/compound-web/dist/style.css";
import { type ConfigOptions, initializeElementCall } from "../index";
import { Harness } from "./Harness";
// After Element Call's, so that the host has the last word on its own page
import "./host.css";
/**
* The development app's own `config.json`, so that the harness runs Element
* Call the way `pnpm dev` does. It is not in the repository — developers copy
* it from `config/config.devenv.json` — so its absence is expected rather than
* an error.
*/
async function loadConfig(): Promise<ConfigOptions> {
try {
const response = await fetch("/config.json");
if (response.ok) return (await response.json()) as ConfigOptions;
logger.warn(
`No config.json (${response.status}); running with Element Call's defaults`,
);
} catch (e) {
logger.warn("Could not read config.json", e);
}
return {};
}
await initializeElementCall(await loadConfig());
createRoot(document.getElementById("root")!).render(
<StrictMode>
<Harness />
</StrictMode>,
);
+79
View File
@@ -0,0 +1,79 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import {
ClientEvent,
createClient,
type MatrixClient,
MemoryStore,
SyncState,
} from "matrix-js-sdk";
/**
* Logs in and brings up a client the way a host application would, so that the
* component is handed a real one rather than something Element Call built for
* itself.
*
* Everything is kept in memory and a fresh login happens on every reload. That
* costs a device on the development homeserver each time, which is harmless,
* and buys the harness two clients that cannot tread on each other's storage.
* Persisting the login to make reloads quicker would mean persisting the
* crypto store too: reusing a device ID with a fresh crypto store generates new
* device keys, and uploading them conflicts with the ones the server already
* holds.
*/
export async function createSession(
homeserver: string,
username: string,
password: string,
onProgress: (message: string) => void,
): Promise<MatrixClient> {
onProgress("Logging in");
const login = await createClient({ baseUrl: homeserver }).login(
"m.login.password",
{ identifier: { type: "m.id.user", user: username }, password },
);
const client = createClient({
baseUrl: homeserver,
accessToken: login.access_token,
userId: login.user_id,
deviceId: login.device_id,
store: new MemoryStore(),
useAuthorizationHeader: true,
fallbackICEServerAllowed: true,
});
onProgress(`Setting up crypto for ${login.device_id}`);
await client.initRustCrypto({ useIndexedDB: false });
onProgress(`Syncing ${login.device_id}`);
await client.startClient();
await new Promise<void>((resolve) => {
const onSync = (state: SyncState): void => {
if (state !== SyncState.Prepared && state !== SyncState.Syncing) return;
client.off(ClientEvent.Sync, onSync);
resolve();
};
client.on(ClientEvent.Sync, onSync);
});
return client;
}
/**
* The room to call in, joining it if this session is not in it yet — a host
* hands Element Call a room it already knows about, so the harness has to get
* itself into that position first.
*/
export async function joinRoom(
client: MatrixClient,
roomIdOrAlias: string,
): Promise<string> {
const room = await client.joinRoom(roomIdOrAlias);
return room.roomId;
}
+161
View File
@@ -0,0 +1,161 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { renderHook } from "@testing-library/react";
import { createRef } from "react";
import { describe, expect, test, vi } from "vitest";
import {
type ElementCallHandle,
type ElementCallHostBridge,
useComponentHostBridge,
} from "./host";
describe("useComponentHostBridge", () => {
test("keeps one identity while the host supplies new objects", () => {
const { result, rerender } = renderHook(
({ supplied }: { supplied: ElementCallHostBridge }) =>
useComponentHostBridge(supplied, undefined, undefined),
{ initialProps: { supplied: {} } },
);
const first = result.current;
rerender({ supplied: { notifyJoined: async () => {} } });
expect(result.current).toBe(first);
});
test("forwards to whatever the host most recently supplied", async () => {
const before = vi.fn().mockResolvedValue(undefined);
const after = vi.fn().mockResolvedValue(undefined);
const { result, rerender } = renderHook(
({ supplied }: { supplied: ElementCallHostBridge }) =>
useComponentHostBridge(supplied, undefined, undefined),
{ initialProps: { supplied: { notifyJoined: before } } },
);
rerender({ supplied: { notifyJoined: after } });
await result.current.notifyJoined();
expect(before).not.toHaveBeenCalled();
expect(after).toHaveBeenCalledOnce();
});
test("is quiet about what the host did not implement", async () => {
const { result } = renderHook(() =>
useComponentHostBridge(undefined, undefined, undefined),
);
await expect(result.current.contentLoaded()).resolves.toBeUndefined();
await expect(
result.current.notifyDeviceMute({
audio_enabled: true,
video_enabled: false,
}),
).resolves.toBeUndefined();
expect(result.current.supportsReactions).toBe(true);
// Starting the user unmuted unasked is something a host has to opt into
expect(result.current.allowJoinUnmutedViaIntent).toBe(false);
});
test("lets the host allow joining unmuted on the intent", () => {
const { result, rerender } = renderHook(
({ supplied }: { supplied: ElementCallHostBridge }) =>
useComponentHostBridge(supplied, undefined, undefined),
{ initialProps: { supplied: {} } },
);
expect(result.current.allowJoinUnmutedViaIntent).toBe(false);
// Read through to whatever the host most recently said
rerender({ supplied: { allowJoinUnmutedViaIntent: true } });
expect(result.current.allowJoinUnmutedViaIntent).toBe(true);
});
test("only has a close when the host has one, since that is a signal", () => {
const { result, rerender } = renderHook(
({ supplied }: { supplied: ElementCallHostBridge }) =>
useComponentHostBridge(supplied, undefined, undefined),
{ initialProps: { supplied: {} } },
);
expect(result.current.close).toBeUndefined();
const close = vi.fn().mockResolvedValue(undefined);
rerender({ supplied: { close } });
expect(result.current.close).toBeDefined();
});
test("never offers profile changes, since the account is the host's", () => {
const { result } = renderHook(() =>
useComponentHostBridge(undefined, undefined, undefined),
);
expect(result.current.supportsProfileChanges).toBe(false);
});
describe("the handle", () => {
test("delivers a request to what is listening and resolves on its reply", async () => {
const ref = createRef<ElementCallHandle>();
const { result } = renderHook(() =>
useComponentHostBridge(undefined, ref, undefined),
);
const received = vi.fn();
result.current.deviceMute$.subscribe(({ data, reply }) => {
received(data);
reply({ audio_enabled: data.audio_enabled!, video_enabled: true });
});
await expect(
ref.current!.setDeviceMute({ audio_enabled: false }),
).resolves.toEqual({ audio_enabled: false, video_enabled: true });
expect(received).toHaveBeenCalledWith({ audio_enabled: false });
});
test("refuses a request nothing in Element Call is listening for", async () => {
const ref = createRef<ElementCallHandle>();
renderHook(() => useComponentHostBridge(undefined, ref, undefined));
await expect(ref.current!.hangUp()).rejects.toThrow(
"Nothing in Element Call can hang up right now",
);
});
});
describe("the theme", () => {
test("reaches a subscriber that arrives after it was set", () => {
const { result } = renderHook(() =>
useComponentHostBridge(undefined, undefined, "light"),
);
const names: (string | undefined)[] = [];
result.current.themeChange$.subscribe(({ data }) =>
names.push(data.name),
);
expect(names).toEqual(["light"]);
});
test("follows the prop", () => {
const { result, rerender } = renderHook(
({ theme }: { theme: string | undefined }) =>
useComponentHostBridge(undefined, undefined, theme),
{ initialProps: { theme: "light" } },
);
const names: (string | undefined)[] = [];
result.current.themeChange$.subscribe(({ data }) =>
names.push(data.name),
);
rerender({ theme: "dark" });
expect(names).toEqual(["light", "dark"]);
});
test("says nothing when the host leaves the theme to Element Call", () => {
const { result } = renderHook(() =>
useComponentHostBridge(undefined, undefined, undefined),
);
const names: (string | undefined)[] = [];
result.current.themeChange$.subscribe(({ data }) =>
names.push(data.name),
);
expect(names).toEqual([]);
});
});
});
+201
View File
@@ -0,0 +1,201 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
/**
* How a host application and the Element Call component talk to each other.
*
* Inside Element Call the host is a {@link HostBridge}, which carries the
* host's requests as rxjs observables because that is what the widget API and
* the view models work in. A host should not have to know about rxjs, or agree
* with us on a version of it, so a component host sees neither: it implements
* plain async callbacks for what Element Call tells it, and makes its own
* requests through an imperative handle on the component, the way it would
* call `play()` on a video element. This module adapts the one to the other.
*/
import { type Ref, useEffect, useImperativeHandle } from "react";
import { ReplaySubject, Subject } from "rxjs";
import {
type DeviceMuteRequest,
type DeviceMuteState,
type HostBridge,
type HostRequest,
} from "../src/HostBridge";
import { type JoinCallData } from "../src/widget";
import { useInitial } from "../src/useInitial";
import { useLatest } from "../src/useLatest";
/**
* What Element Call tells the application hosting it as a component.
* Everything is optional: a host implements what it wants to hear about.
*
* Compared by nothing — Element Call always calls whichever one it was most
* recently given, so this may be written inline.
*/
export interface ElementCallHostBridge {
/**
* Asks the host to keep Element Call on screen (or stop doing so), so that a
* call in progress is not torn down when the user navigates elsewhere.
*/
setAlwaysOnScreen?(alwaysOnScreen: boolean): Promise<void>;
/** Tells the host that Element Call has finished loading. */
contentLoaded?(): Promise<void>;
/** Tells the host that the user has joined the call. */
notifyJoined?(): Promise<void>;
/** Tells the host that the user has hung up. */
notifyHungUp?(): Promise<void>;
/** Tells the host the user's current audio and video mute state. */
notifyDeviceMute?(state: DeviceMuteState): Promise<void>;
/**
* Asks the host to close Element Call: to unmount the component. Its
* presence is what makes Element Call offer a close button on its error
* screens, and leave the host to decide what is shown once a call has ended.
* Without it, Element Call shows its own post-call screen, if it has one for
* the situation, or nothing.
*/
close?(): Promise<void>;
/**
* Whether Element Call may send and receive reactions in this room.
* Defaults to true.
*/
readonly supportsReactions?: boolean;
/**
* Whether the user may start unmuted when the intent skips the lobby, so
* that they never see their devices before joining. Defaults to false: the
* user starts muted and unmutes themselves. A host that chose the intent on
* the user's behalf, and is sure they expect to be heard and seen at once,
* says so here — as a Matrix client hosting Element Call as a widget does.
*/
readonly allowJoinUnmutedViaIntent?: boolean;
}
/**
* What a host can ask of a mounted Element Call, reached through the
* component's `ref`. Each request resolves once Element Call has acted on it,
* and rejects if nothing in Element Call is in a position to act: hanging up
* when there is no call, say.
*/
export interface ElementCallHandle {
/**
* Joins the call, when Element Call was configured to `preload` and is
* waiting to be told to. Says which devices to join with.
*/
join(devices: JoinCallData): Promise<void>;
/** Leaves the call. */
hangUp(): Promise<void>;
/**
* Changes the mute state, for whichever of audio and video is given, and
* reports the state that results.
*/
setDeviceMute(request: DeviceMuteRequest): Promise<DeviceMuteState>;
}
/** Hands a request to Element Call and waits for it to be acknowledged. */
async function request<Data, Reply>(
listeners: Subject<HostRequest<Data, Reply>>,
what: string,
data: Data,
): Promise<Reply> {
if (!listeners.observed)
throw new Error(`Nothing in Element Call can ${what} right now`);
return await new Promise((resolve) =>
listeners.next({ data, reply: resolve }),
);
}
/**
* The {@link HostBridge} the rest of Element Call sees, built from what a
* component host supplies and wired to the handle it is given.
*
* The bridge is created once and never changes identity — everything that
* depends on it would otherwise restart when the host re-rendered with a new
* object — and forwards each call to whatever the host most recently passed.
*/
export function useComponentHostBridge(
supplied: ElementCallHostBridge | undefined,
ref: Ref<ElementCallHandle> | undefined,
/** The theme the host wants, or undefined to leave it to Element Call. */
theme: string | undefined,
): HostBridge {
const latest = useLatest(supplied ?? {});
const requests = useInitial(() => ({
// The theme is state, not an event: a `theme` prop rather than a request
// on the handle. It travels this channel because that is how the rest of
// Element Call hears about a host's theme, and replays so that whatever
// subscribes after the host has set it — everything, on first render —
// still hears the current one.
themeChange$: new ReplaySubject<HostRequest<{ name?: string }>>(1),
join$: new Subject<HostRequest<JoinCallData>>(),
hangUp$: new Subject<HostRequest<Record<string, never>>>(),
deviceMute$: new Subject<HostRequest<DeviceMuteRequest, DeviceMuteState>>(),
}));
useEffect(() => {
if (theme !== undefined)
requests.themeChange$.next({ data: { name: theme }, reply: () => {} });
}, [requests, theme]);
const bridge = useInitial((): HostBridge => ({
setAlwaysOnScreen: async (alwaysOnScreen) => {
await latest.current.setAlwaysOnScreen?.(alwaysOnScreen);
},
contentLoaded: async () => {
await latest.current.contentLoaded?.();
},
notifyJoined: async () => {
await latest.current.notifyJoined?.();
},
notifyHungUp: async () => {
await latest.current.notifyHungUp?.();
},
notifyDeviceMute: async (state) => {
await latest.current.notifyDeviceMute?.(state);
},
// Whether these exist is itself information, so they are read through
// rather than wrapped unconditionally
get close() {
const close = latest.current.close;
return close === undefined
? undefined
: async (): Promise<void> => await close();
},
// Not offered to a component host: the client it hands over holds the
// credentials to fetch media itself. A widget's client does not, which
// is what the internal bridge's `downloadMedia` is for.
get supportsReactions(): boolean {
return latest.current.supportsReactions ?? true;
},
get allowJoinUnmutedViaIntent(): boolean {
return latest.current.allowJoinUnmutedViaIntent ?? false;
},
// Whatever the host says or does not say, the account is its own: it
// signed the user in and handed us the client. So Element Call never
// offers to edit the profile from inside a component.
supportsProfileChanges: false,
...requests,
}));
useImperativeHandle(
ref,
(): ElementCallHandle => ({
join: async (devices) =>
await request(requests.join$, "join a call", devices),
hangUp: async () => await request(requests.hangUp$, "hang up", {}),
setDeviceMute: async (muteRequest) =>
await request(
requests.deviceMute$,
"change the mute state",
muteRequest,
),
}),
[requests],
);
return bridge;
}
+282
View File
@@ -0,0 +1,282 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
/**
* EXPERIMENTAL
*
* Element Call as a React component, for an application that wants to show a
* call inside itself rather than in an iframe.
*
* The host supplies the client and says which room to call in; Element Call
* supplies the call. Everything it would otherwise take from the page it is on
* — the URL, the document body, a Matrix session of its own — comes from the
* host instead, or is confined to the container it is mounted in.
*/
// The element defaults and custom properties every Element Call stylesheet
// builds on. Written for a page, they speak of `html`, `body` and bare
// elements; the component build confines them, and every other stylesheet in
// this bundle, to the root element below (see build/scopeStylesToRoot.ts), so
// that the host's document is left as it was.
//
// Compound is not in here. The component uses the host's copy of it (a peer
// dependency, left external by the build), and the host loads Compound's
// stylesheet, design tokens and fonts along with it: what Compound floats into
// the host's body — tooltips, menus — is then styled by the same stylesheet as
// everything else there, and Element Call's root takes the tokens and fonts of
// the theme class it carries, as any element on the host's page would.
//
// Where these land relative to the component stylesheets is the bundler's
// choice — the standalone app puts them first, this build puts them in the
// middle — so nothing in base.css may depend on winning or losing against a
// component's own rules at equal specificity. It currently does not: what it
// declares unlayered is custom properties on Element Call's root, which
// components inherit rather than compete with.
import "../src/base.css";
import {
type FC,
type JSX,
type ReactNode,
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from "react";
import { logger } from "matrix-js-sdk/lib/logger";
import { I18nextProvider } from "react-i18next";
import { TooltipProvider } from "@vector-im/compound-web";
import { ErrorBoundary } from "@sentry/react";
import { shouldPolyfill as shouldPolyfillSegmenter } from "@formatjs/intl-segmenter/should-polyfill";
import { shouldPolyfill as shouldPolyfillDurationFormat } from "@formatjs/intl-durationformat/should-polyfill.js";
import LanguageDetector from "i18next-browser-languagedetector";
import EN from "../locales/en/app.json";
import { CallView } from "../src/room/CallView";
import { ErrorPage } from "../src/FullScreenView";
import { ClientProvider } from "../src/ClientContext";
import { HostBridgeProvider } from "../src/HostBridge";
import { RootElementProvider, useRootElement } from "../src/RootElementContext";
import {
configurationForIntent,
componentProperties,
type UrlParams,
UrlParamsProvider,
UserIntent,
useUrlParams,
} from "../src/UrlParams";
import { MediaDevicesContext } from "../src/MediaDevicesContext";
import { MediaDevices } from "../src/state/MediaDevices";
import { ObservableScope } from "../src/state/ObservableScope";
import { ProcessorProvider } from "../src/livekit/TrackProcessorContext";
import { Config } from "../src/config/Config";
import { type ConfigOptions } from "../src/config/ConfigOptions";
import { i18n } from "../src/utils/i18n";
import { useTheme } from "../src/useTheme";
import { useStableValue } from "../src/useStableValue";
import styles from "./ElementCall.module.css";
import { useComponentHostBridge } from "./host";
import { CallPortalRoot } from "./CallPortalRoot";
import { type ElementCallProps } from "./api";
import { supportedLanguages, translationsBackend } from "./localization";
// The languages Element Call can be shown in
export { supportedLanguages } from "./localization";
// Everything a host needs to talk about Element Call — the props, the handle,
// the host bridge, the intents and what each means — also available without
// the component itself from `@element-hq/element-call-component/api`
export * from "./api";
/**
* Prepares the things Element Call needs before it can be shown: translations,
* `Intl` polyfills for older browsers, and its configuration.
*
* Await this once, before rendering {@link ElementCall}.
*/
export async function initializeElementCall(
config: ConfigOptions = {},
): Promise<void> {
const polyfills: Promise<unknown>[] = [];
if (shouldPolyfillSegmenter())
polyfills.push(import("@formatjs/intl-segmenter/polyfill-force"));
if (shouldPolyfillDurationFormat())
polyfills.push(import("@formatjs/intl-durationformat/polyfill-force.js"));
await Promise.all(polyfills);
Config.initWith(config);
await i18n
.use(translationsBackend)
.use(new LanguageDetector())
.init({
fallbackLng: "en",
defaultNS: "app",
keySeparator: ".",
nsSeparator: false,
pluralSeparator: "_",
contextSeparator: "|",
supportedLngs: [...supportedLanguages],
interpolation: { escapeValue: false },
// English is bundled in, so the fallback never has to be loaded; every
// other language arrives from the backend when first asked for.
partialBundledLanguages: true,
resources: { en: { app: EN } },
detection: {
// The browser's language, until the host says otherwise through the
// `language` prop. Nothing is remembered: the choice is the host's.
order: ["navigator"],
caches: [],
},
});
}
/** Applies the theme and background to the container, before it is painted. */
const Decoration: FC<{ children: JSX.Element }> = ({ children }) => {
useTheme();
const { background } = useUrlParams();
const rootElement = useRootElement();
useLayoutEffect(() => {
rootElement.setAttribute("data-background", background);
}, [rootElement, background]);
return children;
};
export const ElementCall: FC<ElementCallProps> = ({
client,
roomId,
intent = UserIntent.JoinExistingCall,
config,
hostBridge: suppliedHostBridge,
ref,
theme,
language,
portalRoot,
}): ReactNode => {
const hostBridge = useComponentHostBridge(suppliedHostBridge, ref, theme);
useEffect(() => {
if (language !== undefined)
i18n
.changeLanguage(language)
.catch((e) => logger.error(`Could not switch to ${language}`, e));
}, [language]);
// The container is what Element Call decorates and portals into, so nothing
// inside can render until we have it.
const [container, setContainer] = useState<HTMLDivElement | null>(null);
// Element Call has no URL of its own to read any of this from, and the
// host's URL is not Element Call's business, so the defaults come from the
// intent with the host's wishes over the top.
//
// Everything downstream — the mute state, the call view model and with it
// the media connection — is keyed on the identity of this object, so it has
// to be stable for as long as its contents are. A host writing `config`
// inline would otherwise tear the call down on every render.
const stableConfig = useStableValue(config);
const params = useMemo(
(): UrlParams => ({
...componentProperties,
roomId,
...configurationForIntent(intent),
...stableConfig,
}),
[roomId, intent, stableConfig],
);
// Created in an effect so that the scope it lives in ends when the component
// is unmounted (or these options change), rather than keeping its device
// observers running for the rest of the page's life. Null until then, which
// is one render.
const { controlledAudioDevices, callIntent } = params;
const [mediaDevices, setMediaDevices] = useState<MediaDevices | null>(null);
useEffect(() => {
const scope = new ObservableScope();
setMediaDevices(
new MediaDevices(scope, { controlledAudioDevices, callIntent }),
);
return (): void => {
setMediaDevices(null);
scope.end();
};
}, [controlledAudioDevices, callIntent]);
const room = client.getRoom(roomId);
const rtcSession = useMemo(
() => (room === null ? null : client.matrixRTC.getRoomSession(room)),
[client, room],
);
if (rtcSession === null)
logger.error(
`Element Call was asked to call in ${roomId}, which its host's client does not know about`,
);
// Everything the call needs is in hand once these exist, and the first
// render with them is where the call itself appears: the moment the host
// is told that Element Call has loaded, as the widget tells its client once
// its own initialisation is over. Once per mount, however often the pieces
// are later swapped out.
const ready =
container !== null && rtcSession !== null && mediaDevices !== null;
const announcedLoaded = useRef(false);
useEffect(() => {
if (!ready || announcedLoaded.current) return;
announcedLoaded.current = true;
hostBridge
.contentLoaded()
.catch((e) => logger.error("Could not tell the host we had loaded", e));
}, [ready, hostBridge]);
return (
<I18nextProvider i18n={i18n}>
<HostBridgeProvider value={hostBridge}>
<UrlParamsProvider value={params}>
<div ref={setContainer} className={styles.root}>
{ready && (
// Stands in for the standalone page's `#root`: see `.content`
// in ElementCall.module.css
<div className={styles.content}>
<CallPortalRoot root={portalRoot}>
<RootElementProvider value={container}>
{/* Whatever goes wrong in here is shown in here. Left to
propagate, an error would unmount the host's own tree. */}
<ErrorBoundary
fallback={(error) => <ErrorPage error={error} />}
// A broken call should not hold the host on screen
onError={() => void hostBridge.setAlwaysOnScreen(false)}
>
<Decoration>
<TooltipProvider>
<ClientProvider client={client}>
<MediaDevicesContext value={mediaDevices}>
<ProcessorProvider>
<CallView
client={client}
rtcSession={rtcSession}
isPasswordlessUser={false}
confineToRoom={params.confineToRoom}
preload={params.preload}
skipLobby={params.skipLobby}
/>
</ProcessorProvider>
</MediaDevicesContext>
</ClientProvider>
</TooltipProvider>
</Decoration>
</ErrorBoundary>
</RootElementProvider>
</CallPortalRoot>
</div>
)}
</div>
</UrlParamsProvider>
</HostBridgeProvider>
</I18nextProvider>
);
};
+46
View File
@@ -0,0 +1,46 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { describe, expect, test } from "vitest";
import { supportedLanguages, translationsBackend } from "./localization";
const read = async (
language: string,
namespace = "app",
): Promise<Record<string, unknown>> =>
await new Promise((resolve, reject) =>
translationsBackend.read(language, namespace, (error, data) => {
if (error) reject(error);
else resolve(data as Record<string, unknown>);
}),
);
describe("component translations", () => {
test("offer every language in locales/, tagged as its directory is", () => {
expect(supportedLanguages).toContain("en");
expect(supportedLanguages).toContain("de");
expect(supportedLanguages).toContain("zh-Hans");
expect(new Set(supportedLanguages).size).toBe(supportedLanguages.length);
});
test("load a language's translations on demand", async () => {
const de = await read("de");
expect(de).toHaveProperty("action");
expect(de).not.toEqual(await read("en"));
});
test("refuse a language there are no translations for", async () => {
await expect(read("xx")).rejects.toThrow("No app translations for xx");
});
test("refuse a namespace there are no translations for", async () => {
await expect(read("en", "other")).rejects.toThrow(
"No other translations for en",
);
});
});
+55
View File
@@ -0,0 +1,55 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
/**
* Translations for Element Call as a component.
*
* The standalone app fetches its locale files at runtime from URLs its own
* build emits, which a host serving the library from somewhere else could not
* resolve. The component instead has the bundler split every locale into a
* chunk of its own, loaded the first time its language is asked for; English,
* the fallback, is bundled in so that the first paint never waits for it.
*/
import { type BackendModule, type ResourceKey } from "i18next";
import { languageOfLocalePath } from "../src/utils/i18n";
/** Every locale, as a lazily imported module. */
const translations = import.meta.glob<{ default: ResourceKey }>(
"../locales/*/app.json",
);
/**
* The languages Element Call can be shown in, as BCP 47 tags — `en`, `de`,
* `zh-Hans` and so on. A language that is not one of these falls back to its
* base language where there is one (`de-AT` to `de`), and to English otherwise.
*/
export const supportedLanguages: readonly string[] = [
...new Set(Object.keys(translations).map(languageOfLocalePath)),
];
/** Loads translations on demand. */
export const translationsBackend: BackendModule = {
type: "backend",
init(): void {},
read(language: string, namespace: string, callback): void {
const load = translations[`../locales/${language}/${namespace}.json`];
if (load === undefined) {
callback(new Error(`No ${namespace} translations for ${language}`), null);
return;
}
load().then(
(module) => callback(null, module.default),
(error: unknown) =>
callback(
error instanceof Error ? error : new Error(String(error)),
null,
),
);
},
};
+47
View File
@@ -0,0 +1,47 @@
{
"name": "@element-hq/element-call-component",
"version": "0.0.0",
"description": "Element Call as a React component. Consumed straight from the repository as a git dependency (github:element-hq/element-call#<ref>&path:/component): the host's package manager runs `prepare`, which builds `dist/`.",
"license": "SEE LICENSE IN ../README.md",
"repository": {
"type": "git",
"url": "https://github.com/element-hq/element-call",
"directory": "component"
},
"type": "module",
"devEngines": {
"packageManager": {
"name": "pnpm"
}
},
"files": [
"dist"
],
"main": "./dist/element-call.js",
"module": "./dist/element-call.js",
"types": "./dist/types/component/index.d.ts",
"exports": {
".": {
"types": "./dist/types/component/index.d.ts",
"default": "./dist/element-call.js"
},
"./api": {
"types": "./dist/types/component/api.d.ts",
"default": "./dist/api.js"
},
"./style.css": "./dist/element-call.css"
},
"sideEffects": [
"*.css"
],
"scripts": {
"prepare": "cd .. && pnpm install --frozen-lockfile && pnpm build:component"
},
"peerDependencies": {
"@vector-im/compound-design-tokens": "^11.0.0",
"@vector-im/compound-web": "^10.3.1",
"matrix-js-sdk": "*",
"react": "^19",
"react-dom": "^19"
}
}
+9
View File
@@ -0,0 +1,9 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: false
excludeLinksFromLockfile: false
importers:
.: {}
+14
View File
@@ -0,0 +1,14 @@
# Makes `component/` a pnpm project of its own rather than a directory inside
# the repository's workspace. That matters when a host installs the component
# straight from this repository (`github:element-hq/element-call#…&path:/component`):
# pnpm prepares such a dependency by running `pnpm install` in this directory,
# and only a project root gets its `prepare` script (see package.json) run, which
# is what builds `dist/`. Inside the repository's own workspace the install
# would silently target the repository instead and build nothing.
#
# Consequence for development: pnpm commands run from within this directory see
# this project, not the repository; run them from the repository root.
# Nothing to install here: the peers in package.json are the host's, and the
# build runs against the repository's own node_modules (see `prepare`).
autoInstallPeers: false
+20
View File
@@ -0,0 +1,20 @@
{
// Declaration output for the component package (`pnpm build:component:types`).
// The root tsconfig only type-checks; this one emits `.d.ts` files, and nothing
// else, for everything the component's entry point reaches. The layout under
// `dist/types` mirrors the repository (`component/index.d.ts`, `src/…`), which
// is what `package.json` points its `types` at.
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": false,
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": false,
"rootDir": "..",
"outDir": "./dist/types"
},
// The entry points, plus the ambient declarations (CSS modules, `?react` SVGs,
// `import.meta.env`, …) that the sources they reach rely on.
"include": ["./index.tsx", "./api.ts", "../src/@types/*.d.ts"],
"exclude": []
}
+13
View File
@@ -0,0 +1,13 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://synapse.m.localhost",
"server_name": "synapse.m.localhost"
}
},
"ssla": "https://static.element.io/legal/element-software-and-services-license-agreement-uk-1.pdf",
"matrix_rtc_session": {
"membership_event_expiry_ms": 180000000,
"network_error_retry_ms": 100
}
}
+9 -7
View File
@@ -1,15 +1,17 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://call.ems.host",
"server_name": "call.ems.host"
"base_url": "https://mydomain.com",
"server_name": "mydomain.com"
}
},
"livekit": {
"livekit_service_url": "http://localhost:7881"
"livekit_service_url": "https://livekit-jwt.mydomain.com"
},
"features": {
"feature_use_device_session_member_events": true
},
"eula": "https://static.element.io/legal/online-EULA.pdf"
"ssla": "https://static.element.io/legal/element-software-and-services-license-agreement-uk-1.pdf",
"matrix_rtc_mode": "compatibility",
"matrix_rtc_session": {
"membership_event_expiry_ms": 180000000,
"network_error_retry_ms": 100
}
}
+9 -6
View File
@@ -5,17 +5,20 @@
"server_name": "call-unstable.ems.host"
}
},
"livekit": {
"livekit_service_url": "https://livekit-jwt.call.element.dev"
},
"features": {
"feature_use_device_session_member_events": true
"ssla": "https://static.element.io/legal/element-software-and-services-license-agreement-uk-1.pdf",
"matrix_rtc_session": {
"membership_event_expiry_ms": 180000000,
"network_error_retry_ms": 100
},
"posthog": {
"api_key": "phc_rXGHx9vDmyEvyRxPziYtdVIv0ahEv8A9uLWFcCi1WcU",
"api_host": "https://posthog-element-call.element.io"
},
"rageshake": {
"submit_url": "https://element.io/bugreports/submit"
"submit_url": "https://rageshakes.element.io/api/submit"
},
"sentry": {
"environment": "netlify-pr-preview",
"DSN": "https://b1e328d49be3402ba96101338989fb35@sentry.tools.element.io/41"
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://call-unstable.ems.host",
"server_name": "call-unstable.ems.host"
}
},
"ssla": "https://static.element.io/legal/element-software-and-services-license-agreement-uk-1.pdf",
"matrix_rtc_session": {
"membership_event_expiry_ms": 180000000,
"network_error_retry_ms": 100
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
<Location "/">
# disable cache entriely by default (apart from Etag which is accurate enough)
Header add Cache-Control "private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
Header add Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
CacheDisable on
ExpiresActive off
+5 -11
View File
@@ -3,23 +3,17 @@ server {
server_name localhost;
root /app;
gzip_static on;
gzip_vary on;
location / {
# disable cache entriely by default (apart from Etag which is accurate enough)
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
# also turn off last-modified since they are just the timestamps of the file in the docker image
# and may or may not bear any resemblance to when the resource changed
add_header Last-Modified "";
try_files $uri /$uri /index.html;
try_files $uri $uri/ /index.html;
add_header Cache-Control "public, max-age=30, stale-while-revalidate=30";
}
# assets can be cached because they have hashed filenames
location /assets {
expires 1w;
add_header Cache-Control "public, no-transform";
add_header Cache-Control "public, immutable, max-age=31536000";
}
location /apple-app-site-association {
+7
View File
@@ -1,5 +1,12 @@
# OpenTelemetry Collector for development
## Edit:
Open telemetry has been removed in: https://github.com/element-hq/element-call/pull/3586
Check this PR to get back the implementation or to use it as reference to add it back.
---
This directory contains a docker compose file that starts a jaeger all-in-one instance
with an in-memory database, along with a standalone OpenTelemetry collector that forwards
traces into the jaeger. Jaeger has a built-in OpenTelemetry collector, but it can't be
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

+213
View File
@@ -0,0 +1,213 @@
networks:
ecbackend:
services:
auth-service:
image: ghcr.io/element-hq/lk-jwt-service:0.8.0
pull_policy: always
hostname: auth-server
environment:
- LIVEKIT_JWT_PORT=6080
- LIVEKIT_URL=wss://matrix-rtc.m.localhost/livekit/sfu
- LIVEKIT_KEY=devkey
- LIVEKIT_SECRET=secret
# If the configured homeserver runs on localhost, it'll probably be using
# a self-signed certificate
- LIVEKIT_INSECURE_SKIP_VERIFY_TLS=YES_I_KNOW_WHAT_I_AM_DOING
- LIVEKIT_FULL_ACCESS_HOMESERVERS=*
# Registers this instance as an application service on the main homeserver
- LIVEKIT_AS_REGISTRATION_FILE=/etc/lk-jwt-service/app-service.yaml
- LIVEKIT_HS_SERVER_NAME=synapse.m.localhost
# Neither homeserver serves /.well-known/matrix/client, so the C-S API
# location has to be given explicitly.
- LIVEKIT_CS_API_URL_OVERRIDES=synapse.m.localhost=http://homeserver:8008,synapse.othersite.m.localhost=http://homeserver-1:18008
volumes:
- ./backend/app-service.yaml:/etc/lk-jwt-service/app-service.yaml:Z
deploy:
restart_policy:
condition: on-failure
ports:
# HOST_PORT:CONTAINER_PORT
- 6080:6080
networks:
- ecbackend
auth-service-1:
image: ghcr.io/element-hq/lk-jwt-service:0.8.0
pull_policy: always
hostname: auth-server-1
environment:
- LIVEKIT_JWT_PORT=16080
- LIVEKIT_URL=wss://matrix-rtc.othersite.m.localhost/livekit/sfu
- LIVEKIT_KEY=devkey
- LIVEKIT_SECRET=secret
# If the configured homeserver runs on localhost, it'll probably be using
# a self-signed certificate
- LIVEKIT_INSECURE_SKIP_VERIFY_TLS=YES_I_KNOW_WHAT_I_AM_DOING
- LIVEKIT_FULL_ACCESS_HOMESERVERS=*
# Registers this instance as an application service on the other homeserver.
- LIVEKIT_AS_REGISTRATION_FILE=/etc/lk-jwt-service/app-service.yaml
- LIVEKIT_HS_SERVER_NAME=synapse.othersite.m.localhost
# Neither homeserver serves /.well-known/matrix/client, so the C-S API
# location has to be given explicitly.
- LIVEKIT_CS_API_URL_OVERRIDES=synapse.m.localhost=http://homeserver:8008,synapse.othersite.m.localhost=http://homeserver-1:18008
volumes:
- ./backend/app-service-othersite.yaml:/etc/lk-jwt-service/app-service.yaml:Z
deploy:
restart_policy:
condition: on-failure
ports:
# HOST_PORT:CONTAINER_PORT
- 16080:16080
networks:
- ecbackend
livekit:
image: livekit/livekit-server:v1.13.4
pull_policy: always
hostname: livekit-sfu
command: --dev --config /etc/livekit.yaml
restart: unless-stopped
# The SFU seems to work far more reliably when we let it share the host
# network rather than opening specific ports (but why?? we're not missing
# any…)
ports:
# HOST_PORT:CONTAINER_PORT
- 7880:7880/tcp
- 7881:7881/tcp
- 7882:7882/tcp
- 50100-50200:50100-50200/udp
volumes:
- ./backend/dev_tls_m.localhost.crt:/local_cert.pem:Z
- ./backend/dev_livekit.yaml:/etc/livekit.yaml:Z
environment:
- SSL_CERT_FILE=/local_cert.pem
networks:
- ecbackend
livekit-1:
image: livekit/livekit-server:v1.13.4
pull_policy: always
hostname: livekit-sfu-1
command: --dev --config /etc/livekit.yaml
restart: unless-stopped
# The SFU seems to work far more reliably when we let it share the host
# network rather than opening specific ports (but why?? we're not missing
# any…)
ports:
# HOST_PORT:CONTAINER_PORT
- 17880:17880/tcp
- 17881:17881/tcp
- 17882:17882/tcp
- 50300-50400:50300-50400/udp
volumes:
- ./backend/dev_tls_m.localhost.crt:/local_cert.pem:Z
- ./backend/dev_livekit-othersite.yaml:/etc/livekit.yaml:Z
environment:
- SSL_CERT_FILE=/local_cert.pem
networks:
- ecbackend
synapse:
hostname: homeserver
# develop (not latest) is required for application service C-S/S-S proxying
# (MSC4512) and membership look-ups (MSC4502), which are not in a stable
# release yet.
image: ghcr.io/element-hq/synapse:develop
pull_policy: always
environment:
- SYNAPSE_CONFIG_PATH=/data/cfg/homeserver.yaml
# Needed for rootless podman-compose such that the uid/gid mapping does
# fit local user uid. If the container runs as root (uid 0) it is fine as
# it actually maps to your non-root user on the host (e.g. 1000).
# Otherwise uid mapping will not match your non-root user.
- UID=0
- GID=0
volumes:
- ./backend/synapse_tmp:/data:Z
- ./backend/dev_homeserver.yaml:/data/cfg/homeserver.yaml:Z
- ./backend/app-service.yaml:/data/cfg/app-service.yaml:Z
networks:
- ecbackend
synapse-1:
hostname: homeserver-1
# develop (not latest) is required for application service C-S/S-S proxying
# (MSC4512) and membership look-ups (MSC4502), which are not in a stable
# release yet.
image: ghcr.io/element-hq/synapse:develop
pull_policy: always
environment:
- SYNAPSE_CONFIG_PATH=/data/cfg/homeserver.yaml
# Needed for rootless podman-compose such that the uid/gid mapping does
# fit local user uid. If the container runs as root (uid 0) it is fine as
# it actually maps to your non-root user on the host (e.g. 1000).
# Otherwise uid mapping will not match your non-root user.
- UID=0
- GID=0
volumes:
- ./backend/synapse_tmp_othersite:/data:Z
- ./backend/dev_homeserver-othersite.yaml:/data/cfg/homeserver.yaml:Z
- ./backend/app-service-othersite.yaml:/data/cfg/app-service.yaml:Z
networks:
- ecbackend
element-web:
image: ghcr.io/element-hq/element-web:develop
pull_policy: always
volumes:
- ./backend/ew.test.config.json:/app/config.json:Z
# Replaces the Element Call widget bundled in the image with the embedded
# build of the current sources. See "Backend" in README.md.
- ./dist-embedded:/app/widgets/element-call:ro,Z
environment:
ELEMENT_WEB_PORT: 8081
ports:
- "8081:8081"
networks:
- ecbackend
element-web-1:
image: ghcr.io/element-hq/element-web:develop
pull_policy: always
volumes:
- ./backend/ew.test.othersite.config.json:/app/config.json:Z
# Replaces the Element Call widget bundled in the image with the embedded
# build of the current sources. See "Backend" in README.md.
- ./dist-embedded:/app/widgets/element-call:ro,Z
environment:
ELEMENT_WEB_PORT: 18081
ports:
# HOST_PORT:CONTAINER_PORT
- "18081:18081"
networks:
- ecbackend
nginx:
# see backend/dev_tls_setup for how to generate the tls certs
hostname: synapse.m.localhost
image: nginx:latest@sha256:4ae259ae64fbedb67918c07d167fdcb0e05855a1615480ca445bea485e7d65ff
pull_policy: always
volumes:
- ./backend/dev_nginx.conf:/etc/nginx/conf.d/default.conf:Z
- ./backend/dev_tls_m.localhost.key:/root/ssl/key.pem:Z
- ./backend/dev_tls_m.localhost.crt:/root/ssl/cert.pem:Z
ports:
# HOST_PORT:CONTAINER_PORT
- "443:443"
- "8008:80"
- "4443:443"
- "8448:8448"
extra_hosts:
- "host.docker.internal:host-gateway"
- "auth-server:127.0.0.1"
- "auth-server-1:127.0.0.1"
depends_on:
- synapse
networks:
ecbackend:
aliases:
- synapse.m.localhost
- synapse.othersite.m.localhost
- matrix-rtc.m.localhost
- matrix-rtc.othersite.m.localhost
+25
View File
@@ -0,0 +1,25 @@
# This file contains overrides to docker-compose-dev.yml and should
# only be used in combination with that file.
services:
synapse:
# Pin to a SHA so that upstream cannot break our tests. Renovate handles regular updates.
# develop (not latest) is required for application service C-S/S-S proxying
# (MSC4512) and membership look-ups (MSC4502), which are not in a stable
# release yet.
image: ghcr.io/element-hq/synapse:develop@sha256:337921fd22be310d453344b2265f6c9942315446595df3cf81866f71ca2055a7
volumes:
- ./backend/playwright_homeserver.yaml:/data/cfg/homeserver.yaml:Z
synapse-1:
# Pin to a SHA so that upstream cannot break our tests. Renovate handles regular updates.
# develop (not latest) is required for application service C-S/S-S proxying
# (MSC4512) and membership look-ups (MSC4502), which are not in a stable
# release yet.
image: ghcr.io/element-hq/synapse:develop@sha256:337921fd22be310d453344b2265f6c9942315446595df3cf81866f71ca2055a7
volumes:
- ./backend/playwright_homeserver-othersite.yaml:/data/cfg/homeserver.yaml:Z
element-web:
# Pin to a SHA so that upstream cannot break our tests. Renovate handles regular updates.
image: ghcr.io/element-hq/element-web:develop@sha256:d43e8d26361b546a9ceed13602cc13892ff212df7024b2282147ee8ec370977e
element-web-1:
# Pin to a SHA so that upstream cannot break our tests. Renovate handles regular updates.
image: ghcr.io/element-hq/element-web:develop@sha256:d43e8d26361b546a9ceed13602cc13892ff212df7024b2282147ee8ec370977e
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

+16 -3
View File
@@ -1,7 +1,20 @@
## Element Call Docs
This folder contains documentation for Element Call setup and usage.
This folder contains documentation for setup, usage, and development of Element Call.
- [Embedded vs standalone mode](./embedded-standalone.md)
- [Url format and parameters](./url-params.md)
- [Embedded vs standalone mode](./embedded_standalone.md)
- [Element Call as a React component (experimental)](../README.md#element-call-as-a-component-experimental)
- [Url format and parameters](./url_params.md)
- [Global JS controls](./controls.md)
- [MatrixRTC modes](./matrix_rtc_modes.md)
- [Self-Hosting](./self_hosting.md)
- [Developing with linked packages](./linking.md)
### Writing code for Element Call (agent-readable conventions)
Entry point: [AGENTS.md](../AGENTS.md).
- [Agent workflow](./agents/workflow.md)
- [Architecture](./agents/architecture.md)
- [Code style](./agents/code-style.md)
- [Testing](./agents/testing.md)
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Some files were not shown because too many files have changed in this diff Show More