fix: re-apply desired device state after EC joins, support mid-call PTT
This commit is contained in:
@@ -58,6 +58,15 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
|||||||
const [pttKey] = useSetting(settingsAtom, 'pttKey');
|
const [pttKey] = useSetting(settingsAtom, 'pttKey');
|
||||||
const [pttActive, setPttActive] = useState(false);
|
const [pttActive, setPttActive] = useState(false);
|
||||||
|
|
||||||
|
// Mute mic immediately when PTT is enabled mid-call so the key handler can activate
|
||||||
|
const pttModeRef = useRef(pttMode);
|
||||||
|
useEffect(() => {
|
||||||
|
if (pttMode && !pttModeRef.current && microphone) {
|
||||||
|
callEmbed.control.setMicrophone(false);
|
||||||
|
}
|
||||||
|
pttModeRef.current = pttMode;
|
||||||
|
}, [pttMode, callEmbed, microphone]);
|
||||||
|
|
||||||
const handleOpenMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
|
const handleOpenMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
|
||||||
setCords(evt.currentTarget.getBoundingClientRect());
|
setCords(evt.currentTarget.getBoundingClientRect());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -101,6 +101,11 @@ export class CallControl extends EventEmitter implements CallControlState {
|
|||||||
this.emitStateUpdate();
|
this.emitStateUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async forceState(desired: CallControlState) {
|
||||||
|
this.state = new CallControlState(desired.microphone, desired.video, desired.sound, this.screenshare, this.spotlight);
|
||||||
|
await this.applyState();
|
||||||
|
}
|
||||||
|
|
||||||
public startObserving() {
|
public startObserving() {
|
||||||
this.controlMutationObserver.disconnect();
|
this.controlMutationObserver.disconnect();
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ export class CallEmbed {
|
|||||||
|
|
||||||
private readonly disposables: Array<() => void> = [];
|
private readonly disposables: Array<() => void> = [];
|
||||||
|
|
||||||
|
private readonly initialState: CallControlState;
|
||||||
|
|
||||||
static getIntent(dm: boolean, ongoing: boolean): ElementCallIntent {
|
static getIntent(dm: boolean, ongoing: boolean): ElementCallIntent {
|
||||||
if (ongoing) {
|
if (ongoing) {
|
||||||
return dm ? ElementCallIntent.JoinExistingDM : ElementCallIntent.JoinExisting;
|
return dm ? ElementCallIntent.JoinExistingDM : ElementCallIntent.JoinExisting;
|
||||||
@@ -149,6 +151,7 @@ export class CallEmbed {
|
|||||||
|
|
||||||
const controlState = initialControlState ?? new CallControlState(true, false, true);
|
const controlState = initialControlState ?? new CallControlState(true, false, true);
|
||||||
this.control = new CallControl(controlState, call, iframe);
|
this.control = new CallControl(controlState, call, iframe);
|
||||||
|
this.initialState = controlState;
|
||||||
|
|
||||||
let initialMediaEvent = true;
|
let initialMediaEvent = true;
|
||||||
this.disposables.push(
|
this.disposables.push(
|
||||||
@@ -251,6 +254,8 @@ export class CallEmbed {
|
|||||||
this.joined = true;
|
this.joined = true;
|
||||||
this.applyStyles();
|
this.applyStyles();
|
||||||
this.control.startObserving();
|
this.control.startObserving();
|
||||||
|
// EC ignores io.element.device_mute before join; re-apply desired state now that EC is live
|
||||||
|
this.control.forceState(this.initialState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private applyStyles(): void {
|
private applyStyles(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user