fix: pass audio/video URL params to EC for correct initial device state

- Camera no longer starts enabled when user disables it in prescreen
- When PTT mode is enabled, call starts muted so PTT works immediately
  without requiring a manual mute first
- CallControlState also updated to match the forced-off audio for PTT

EC 0.16.x ignores io.element.device_mute for initial state at startup,
so audio= and video= URL params are the only reliable way to set the
initial device state before the call begins.
This commit is contained in:
root
2026-05-14 18:54:09 -04:00
parent f3c2babd4b
commit c37220eb21
2 changed files with 14 additions and 6 deletions
+9 -5
View File
@@ -45,15 +45,18 @@ export const createCallEmbed = (
themeKind: ElementCallThemeKind,
container: HTMLElement,
pref?: CallPreferences,
noiseSuppression = true
noiseSuppression = true,
forceAudioOff = false
): CallEmbed => {
const rtcSession = mx.matrixRTC.getRoomSession(room);
const ongoing =
MatrixRTCSession.sessionMembershipsForRoom(room, rtcSession.sessionDescription).length > 0;
const intent = CallEmbed.getIntent(dm, ongoing);
const widget = CallEmbed.getWidget(mx, room, intent, themeKind, noiseSuppression);
const controlState = pref && new CallControlState(pref.microphone, pref.video, pref.sound);
const initialAudio = forceAudioOff ? false : (pref?.microphone ?? true);
const initialVideo = pref?.video ?? false;
const widget = CallEmbed.getWidget(mx, room, intent, themeKind, noiseSuppression, initialAudio, initialVideo);
const controlState = pref && new CallControlState(forceAudioOff ? false : pref.microphone, pref.video, pref.sound);
const embed = new CallEmbed(mx, room, widget, container, controlState);
@@ -66,6 +69,7 @@ export const useCallStart = (dm = false) => {
const setCallEmbed = useSetAtom(callEmbedAtom);
const callEmbedRef = useCallEmbedRef();
const [callNoiseSuppression] = useSetting(settingsAtom, 'callNoiseSuppression');
const [pttMode] = useSetting(settingsAtom, 'pttMode');
const startCall = useCallback(
(room: Room, pref?: CallPreferences) => {
@@ -73,11 +77,11 @@ export const useCallStart = (dm = false) => {
if (!container) {
throw new Error('Failed to start call, No embed container element found!');
}
const callEmbed = createCallEmbed(mx, room, dm, theme.kind, container, pref, callNoiseSuppression ?? true);
const callEmbed = createCallEmbed(mx, room, dm, theme.kind, container, pref, callNoiseSuppression ?? true, !!pttMode);
setCallEmbed(callEmbed);
},
[mx, dm, theme, setCallEmbed, callEmbedRef, callNoiseSuppression]
[mx, dm, theme, setCallEmbed, callEmbedRef, callNoiseSuppression, pttMode]
);
return startCall;
+5 -1
View File
@@ -60,7 +60,9 @@ export class CallEmbed {
room: Room,
intent: ElementCallIntent,
themeKind: ElementCallThemeKind,
noiseSuppression = true
noiseSuppression = true,
initialAudio = true,
initialVideo = false
): Widget {
const userId = mx.getSafeUserId();
const deviceId = mx.getDeviceId() ?? '';
@@ -83,6 +85,8 @@ export class CallEmbed {
lang: 'en-EN',
theme: themeKind,
noiseSuppression: noiseSuppression.toString(),
audio: initialAudio.toString(),
video: initialVideo.toString(),
});
const widgetUrl = new URL(