mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-29 21:15:19 +00:00
Compare commits
10 Commits
release-v0
...
hs/prefer-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8268e7527c | ||
|
|
dc293e9f97 | ||
|
|
33469f992d | ||
|
|
ba36acbc4b | ||
|
|
1f0367f21f | ||
|
|
890508ce53 | ||
|
|
8dde994275 | ||
|
|
36ea3e9eff | ||
|
|
c98397a6c8 | ||
|
|
b59275b3e1 |
@@ -88,7 +88,7 @@ services:
|
||||
|
||||
synapse:
|
||||
hostname: homeserver
|
||||
image: docker.io/matrixdotorg/synapse:latest
|
||||
image: ghcr.io/element-hq/synapse:msc4354-5
|
||||
pull_policy: always
|
||||
environment:
|
||||
- SYNAPSE_CONFIG_PATH=/data/cfg/homeserver.yaml
|
||||
@@ -106,7 +106,7 @@ services:
|
||||
|
||||
synapse-1:
|
||||
hostname: homeserver-1
|
||||
image: docker.io/matrixdotorg/synapse:latest
|
||||
image: ghcr.io/element-hq/synapse:msc4354-5
|
||||
pull_policy: always
|
||||
environment:
|
||||
- SYNAPSE_CONFIG_PATH=/data/cfg/homeserver.yaml
|
||||
|
||||
@@ -72,6 +72,7 @@ These parameters are relevant to both [widget](./embedded-standalone.md) and [st
|
||||
| `sendNotificationType` | `ring` or `notification` | No | No | Will send a "ring" or "notification" `m.rtc.notification` event if the user is the first one in the call. |
|
||||
| `autoLeaveWhenOthersLeft` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Whether the app should automatically leave the call when there is no one left in the call. |
|
||||
| `waitForCallPickup` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | When sending a notification, show UI that the app is awaiting an answer, play a dial tone, and (in widget mode) auto-close the widget once the notification expires. |
|
||||
| `multiSFU` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Enables experimental new multiSFU support. |
|
||||
|
||||
### Widget-only parameters
|
||||
|
||||
|
||||
@@ -72,12 +72,11 @@
|
||||
"livekit_server_info": "LiveKit Server Info",
|
||||
"livekit_sfu": "LiveKit SFU: {{url}}",
|
||||
"matrix_id": "Matrix ID: {{id}}",
|
||||
"multi_sfu": "Multi-SFU media transport",
|
||||
"mute_all_audio": "Mute all audio (participants, reactions, join sounds)",
|
||||
"prefer_sticky_events": {
|
||||
"description": "Improves reliability of calls (requires homeserver support)",
|
||||
"label": "Prefer sticky events"
|
||||
"multi_sfu": {
|
||||
"description": "Allows multiple SFUs to be present in a call (requires homeserver support)",
|
||||
"label": "Multi-SFU media transport"
|
||||
},
|
||||
"mute_all_audio": "Mute all audio (participants, reactions, join sounds)",
|
||||
"show_connection_stats": "Show connection statistics",
|
||||
"url_params": "URL parameters"
|
||||
},
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
"livekit-client": "^2.13.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"loglevel": "^1.9.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#head=toger5/sticky-events&commit=e7f5bec51b6f70501a025b79fe5021c933385b21",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#head=hs/rtc-slots&commit=c56fe525aa4dcb8c3b8629dc303b95f4dd4988bd",
|
||||
"matrix-widget-api": "^1.13.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"observable-hooks": "^4.2.3",
|
||||
|
||||
@@ -141,6 +141,11 @@ export interface UrlProperties {
|
||||
* can be "light", "dark", "light-high-contrast" or "dark-high-contrast".
|
||||
*/
|
||||
theme: string | null;
|
||||
/**
|
||||
* Whether or not the call should be held using the sticky event implementation,
|
||||
* where possible.
|
||||
*/
|
||||
multiSFU: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,6 +506,7 @@ export const computeUrlParams = (search = "", hash = ""): UrlParams => {
|
||||
sentryDsn: parser.getParam("sentryDsn"),
|
||||
sentryEnvironment: parser.getParam("sentryEnvironment"),
|
||||
e2eEnabled: parser.getFlagParam("enableE2EE", true),
|
||||
multiSFU: parser.getFlagParam("multiSFU", false),
|
||||
};
|
||||
|
||||
const configuration: Partial<UrlConfiguration> = {
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
multiSfu as multiSfuSetting,
|
||||
muteAllAudio as muteAllAudioSetting,
|
||||
alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting,
|
||||
preferStickyEvents as preferStickyEventsSetting,
|
||||
} from "./settings";
|
||||
import type { Room as LivekitRoom } from "livekit-client";
|
||||
import styles from "./DeveloperSettingsTab.module.css";
|
||||
@@ -59,10 +58,6 @@ export const DeveloperSettingsTab: FC<Props> = ({ client, livekitRooms }) => {
|
||||
});
|
||||
}, [client]);
|
||||
|
||||
const [preferStickyEvents, setPreferStickyEvents] = useSetting(
|
||||
preferStickyEventsSetting,
|
||||
);
|
||||
|
||||
const [showConnectionStats, setShowConnectionStats] = useSetting(
|
||||
showConnectionStatsSetting,
|
||||
);
|
||||
@@ -146,22 +141,6 @@ export const DeveloperSettingsTab: FC<Props> = ({ client, livekitRooms }) => {
|
||||
}
|
||||
/>
|
||||
</FieldRow>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="preferStickyEvents"
|
||||
type="checkbox"
|
||||
label={t("developer_mode.prefer_sticky_events.label")}
|
||||
disabled={!stickyEventsSupported}
|
||||
description={t("developer_mode.prefer_sticky_events.description")}
|
||||
checked={!!preferStickyEvents}
|
||||
onChange={useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>): void => {
|
||||
setPreferStickyEvents(event.target.checked);
|
||||
},
|
||||
[setPreferStickyEvents],
|
||||
)}
|
||||
/>
|
||||
</FieldRow>
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="showConnectionStats"
|
||||
@@ -180,10 +159,10 @@ export const DeveloperSettingsTab: FC<Props> = ({ client, livekitRooms }) => {
|
||||
<InputField
|
||||
id="multiSfu"
|
||||
type="checkbox"
|
||||
label={t("developer_mode.multi_sfu")}
|
||||
// If using sticky events we implicitly prefer use multi-sfu
|
||||
checked={multiSfu || preferStickyEvents}
|
||||
disabled={preferStickyEvents}
|
||||
label={t("developer_mode.multi_sfu.label")}
|
||||
description={t("developer_mode.multi_sfu.description")}
|
||||
checked={multiSfu}
|
||||
disabled={!stickyEventsSupported}
|
||||
onChange={useCallback(
|
||||
(event: ChangeEvent<HTMLInputElement>): void => {
|
||||
setMultiSfu(event.target.checked);
|
||||
|
||||
@@ -83,11 +83,6 @@ export const showConnectionStats = new Setting<boolean>(
|
||||
false,
|
||||
);
|
||||
|
||||
export const preferStickyEvents = new Setting<boolean>(
|
||||
"prefer-sticky-events",
|
||||
false,
|
||||
);
|
||||
|
||||
export const audioInput = new Setting<string | undefined>(
|
||||
"audio-input",
|
||||
undefined,
|
||||
|
||||
@@ -91,7 +91,6 @@ import {
|
||||
duplicateTiles,
|
||||
multiSfu,
|
||||
playReactionsSound,
|
||||
preferStickyEvents,
|
||||
showReactions,
|
||||
} from "../settings/settings";
|
||||
import { isFirefox } from "../Platform";
|
||||
@@ -282,22 +281,13 @@ export class CallViewModel {
|
||||
remote: { membership: CallMembership; transport: LivekitTransport }[];
|
||||
preferred: Async<LivekitTransport>;
|
||||
multiSfu: boolean;
|
||||
preferStickyEvents: boolean;
|
||||
} | null> = this.scope.behavior(
|
||||
this.joined$.pipe(
|
||||
switchMap((joined) =>
|
||||
joined
|
||||
? combineLatest(
|
||||
[
|
||||
this.preferredTransport$,
|
||||
this.memberships$,
|
||||
multiSfu.value$,
|
||||
preferStickyEvents.value$,
|
||||
],
|
||||
(preferred, memberships, preferMultiSfu, preferStickyEvents) => {
|
||||
// Multi-SFU must be implicitly enabled when using sticky events
|
||||
const multiSfu = preferStickyEvents || preferMultiSfu;
|
||||
|
||||
[this.preferredTransport$, this.memberships$, multiSfu.value$],
|
||||
(preferred, memberships, multiSfu) => {
|
||||
const oldestMembership =
|
||||
this.matrixRTCSession.getOldestMembership();
|
||||
const remote = memberships.flatMap((m) => {
|
||||
@@ -333,7 +323,6 @@ export class CallViewModel {
|
||||
remote,
|
||||
preferred,
|
||||
multiSfu,
|
||||
preferStickyEvents,
|
||||
};
|
||||
},
|
||||
)
|
||||
@@ -368,7 +357,6 @@ export class CallViewModel {
|
||||
*/
|
||||
private readonly advertisedTransport$: Behavior<{
|
||||
multiSfu: boolean;
|
||||
preferStickyEvents: boolean;
|
||||
transport: LivekitTransport;
|
||||
} | null> = this.scope.behavior(
|
||||
this.transports$.pipe(
|
||||
@@ -377,7 +365,6 @@ export class CallViewModel {
|
||||
transports.preferred.state === "ready"
|
||||
? {
|
||||
multiSfu: transports.multiSfu,
|
||||
preferStickyEvents: transports.preferStickyEvents,
|
||||
// In non-multi-SFU mode we should always advertise the preferred
|
||||
// SFU to minimize the number of membership updates
|
||||
transport: transports.multiSfu
|
||||
@@ -388,7 +375,6 @@ export class CallViewModel {
|
||||
),
|
||||
distinctUntilChanged<{
|
||||
multiSfu: boolean;
|
||||
preferStickyEvents: boolean;
|
||||
transport: LivekitTransport;
|
||||
} | null>(deepCompare),
|
||||
),
|
||||
@@ -1834,7 +1820,8 @@ export class CallViewModel {
|
||||
await enterRTCSession(this.matrixRTCSession, advertised.transport, {
|
||||
encryptMedia: this.options.encryptionSystem.kind !== E2eeType.NONE,
|
||||
useMultiSfu: advertised.multiSfu,
|
||||
preferStickyEvents: advertised.preferStickyEvents,
|
||||
// Multi-SFU enables sticky events.
|
||||
preferStickyEvents: advertised.multiSfu ?? this.urlParams.multiSFU,
|
||||
});
|
||||
} catch (e) {
|
||||
logger.error("Error entering RTC session", e);
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
MemoryStore,
|
||||
Preset,
|
||||
Visibility,
|
||||
EventType,
|
||||
} from "matrix-js-sdk";
|
||||
import { type ISyncStateData, type SyncState } from "matrix-js-sdk/lib/sync";
|
||||
import { logger } from "matrix-js-sdk/lib/logger";
|
||||
@@ -28,6 +29,10 @@ import {
|
||||
type EncryptionSystem,
|
||||
saveKeyForRoom,
|
||||
} from "../e2ee/sharedKeyManagement";
|
||||
import {
|
||||
DefaultCallApplicationSlot,
|
||||
RtcSlotEventContent,
|
||||
} from "matrix-js-sdk/lib/matrixrtc";
|
||||
|
||||
export const fallbackICEServerAllowed =
|
||||
import.meta.env.VITE_FALLBACK_STUN_ALLOWED === "true";
|
||||
@@ -236,6 +241,16 @@ export async function createRoom(
|
||||
preset: Preset.PublicChat,
|
||||
name,
|
||||
room_alias_name: e2ee ? undefined : roomAliasLocalpartFromRoomName(name),
|
||||
initial_state: [
|
||||
// Always create a slot
|
||||
{
|
||||
type: EventType.RTCSlot,
|
||||
content: {
|
||||
slot_id: DefaultCallApplicationSlot.slot_id,
|
||||
application: { ...DefaultCallApplicationSlot.application },
|
||||
} satisfies RtcSlotEventContent,
|
||||
},
|
||||
],
|
||||
power_level_content_override: {
|
||||
invite: 100,
|
||||
kick: 100,
|
||||
|
||||
23
yarn.lock
23
yarn.lock
@@ -7545,7 +7545,7 @@ __metadata:
|
||||
livekit-client: "npm:^2.13.0"
|
||||
lodash-es: "npm:^4.17.21"
|
||||
loglevel: "npm:^1.9.1"
|
||||
matrix-js-sdk: "github:matrix-org/matrix-js-sdk#head=toger5/sticky-events&commit=e7f5bec51b6f70501a025b79fe5021c933385b21"
|
||||
matrix-js-sdk: "github:matrix-org/matrix-js-sdk#head=hs/rtc-slots&commit=c56fe525aa4dcb8c3b8629dc303b95f4dd4988bd"
|
||||
matrix-widget-api: "npm:^1.13.0"
|
||||
normalize.css: "npm:^8.0.1"
|
||||
observable-hooks: "npm:^4.2.3"
|
||||
@@ -10343,9 +10343,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#head=toger5/sticky-events&commit=e7f5bec51b6f70501a025b79fe5021c933385b21":
|
||||
version: 38.4.0
|
||||
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=e7f5bec51b6f70501a025b79fe5021c933385b21"
|
||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#head=hs/rtc-slots&commit=c56fe525aa4dcb8c3b8629dc303b95f4dd4988bd":
|
||||
version: 39.0.0
|
||||
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=c56fe525aa4dcb8c3b8629dc303b95f4dd4988bd"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.12.5"
|
||||
"@matrix-org/matrix-sdk-crypto-wasm": "npm:^15.3.0"
|
||||
@@ -10358,10 +10358,10 @@ __metadata:
|
||||
matrix-widget-api: "npm:^1.10.0"
|
||||
oidc-client-ts: "npm:^3.0.1"
|
||||
p-retry: "npm:7"
|
||||
sdp-transform: "npm:^2.14.1"
|
||||
sdp-transform: "npm:^3.0.0"
|
||||
unhomoglyph: "npm:^1.0.6"
|
||||
uuid: "npm:13"
|
||||
checksum: 10c0/7adffdc183affd2d3ee1e8497cad6ca7904a37f98328ff7bc15aa6c1829dc9f9a92f8e1bd6260432a33626ff2a839644de938270163e73438b7294675cd954e4
|
||||
checksum: 10c0/f8267c2a1fac67076400f886259d9b58b597f975865ce49aefe774d2f56a5c7caef66307f02fe24dcad35829e747bd7e563ecbb9a694d1f80b2439eebe0724fa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -12544,7 +12544,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sdp-transform@npm:^2.14.1, sdp-transform@npm:^2.15.0":
|
||||
"sdp-transform@npm:^2.15.0":
|
||||
version: 2.15.0
|
||||
resolution: "sdp-transform@npm:2.15.0"
|
||||
bin:
|
||||
@@ -12553,6 +12553,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sdp-transform@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "sdp-transform@npm:3.0.0"
|
||||
bin:
|
||||
sdp-verify: checker.js
|
||||
checksum: 10c0/828a4595041ba64c86b29075aa4007ab384519b1fa29882db59ccb83b54b2b2a33b60848293f8da537fe151c52f5844fc17c8325396cac309fb19e2e81ec5bf4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sdp@npm:^3.2.0":
|
||||
version: 3.2.0
|
||||
resolution: "sdp@npm:3.2.0"
|
||||
|
||||
Reference in New Issue
Block a user