Acknowledge `DeviceMute` widget actions (#12790)

* acknowledge DeviceMute widget actions (to prevent sending the  default error response to the widget)

* rephrase comment

* test for widget action ack
pull/24763/head
Timo 2024-07-25 11:29:01 +02:00 committed by GitHub
parent 6e9fc55cb4
commit 72e7df0f13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 5 deletions

View File

@ -892,6 +892,10 @@ export class ElementCall extends Call {
this.messaging!.on(`action:${ElementWidgetActions.TileLayout}`, this.onTileLayout);
this.messaging!.on(`action:${ElementWidgetActions.SpotlightLayout}`, this.onSpotlightLayout);
this.messaging!.on(`action:${ElementWidgetActions.HangupCall}`, this.onHangup);
this.messaging!.on(`action:${ElementWidgetActions.DeviceMute}`, async (ev) => {
ev.preventDefault();
await this.messaging!.transport.reply(ev.detail, {}); // ack
});
if (!this.widget.data?.skipLobby) {
// If we do not skip the lobby we need to wait until the widget has

View File

@ -21,10 +21,6 @@ export enum ElementWidgetActions {
JoinCall = "io.element.join",
HangupCall = "im.vector.hangup",
CallParticipants = "io.element.participants",
MuteAudio = "io.element.mute_audio",
UnmuteAudio = "io.element.unmute_audio",
MuteVideo = "io.element.mute_video",
UnmuteVideo = "io.element.unmute_video",
StartLiveStream = "im.vector.start_live_stream",
// Actions for switching layouts
@ -32,11 +28,28 @@ export enum ElementWidgetActions {
SpotlightLayout = "io.element.spotlight_layout",
OpenIntegrationManager = "integration_manager_open",
/**
* @deprecated Use MSC2931 instead
*/
ViewRoom = "io.element.view_room",
// This action type is used as a `fromWidget` and a `toWidget` action.
// fromWidget: updates the client about the current device mute state
// toWidget: the client requests a specific device mute configuration
// The reply will always be the resulting configuration
// It is possible to sent an empty configuration to retrieve the current values or
// just one of the fields to update that particular value
// An undefined field means that EC will keep the mute state as is.
// -> this will allow the client to only get the current state
//
// The data of the widget action request and the response are:
// {
// audio_enabled?: boolean,
// video_enabled?: boolean
// }
// NOTE: this is currently unused. Its only here to make EW aware
// of this action so it does not throw errors.
DeviceMute = "io.element.device_mute",
}
export interface IHangupCallApiRequest extends IWidgetApiRequest {

View File

@ -965,6 +965,18 @@ describe("ElementCall", () => {
expect(messaging.transport.send).toHaveBeenCalledWith(ElementWidgetActions.TileLayout, {});
});
it("acknowledges mute_device widget action", async () => {
await callConnectProcedure(call);
const preventDefault = jest.fn();
const mockEv = {
preventDefault,
detail: { video_enabled: false },
};
messaging.emit(`action:${ElementWidgetActions.DeviceMute}`, mockEv);
expect(messaging.transport.reply).toHaveBeenCalledWith({ video_enabled: false }, {});
expect(preventDefault).toHaveBeenCalled();
});
it("emits events when connection state changes", async () => {
// const wait = jest.spyOn(CallModule, "waitForEvent");
const onConnectionState = jest.fn();