2026-03-07 18:03:32 +11:00
|
|
|
import {
|
|
|
|
|
type Capability,
|
|
|
|
|
EventDirection,
|
|
|
|
|
MatrixCapabilities,
|
|
|
|
|
WidgetEventCapability,
|
|
|
|
|
} from 'matrix-widget-api';
|
|
|
|
|
import { EventType } from 'matrix-js-sdk';
|
|
|
|
|
|
|
|
|
|
export function getCallCapabilities(
|
|
|
|
|
roomId: string,
|
|
|
|
|
userId: string,
|
2026-05-21 23:30:50 -04:00
|
|
|
deviceId: string,
|
2026-03-07 18:03:32 +11:00
|
|
|
): Set<Capability> {
|
|
|
|
|
const capabilities: Set<Capability> = new Set();
|
|
|
|
|
|
|
|
|
|
capabilities.add(MatrixCapabilities.Screenshots);
|
|
|
|
|
capabilities.add(MatrixCapabilities.AlwaysOnScreen);
|
2026-05-14 19:41:12 +10:00
|
|
|
capabilities.add(MatrixCapabilities.MSC4039UploadFile);
|
|
|
|
|
capabilities.add(MatrixCapabilities.MSC4039DownloadFile);
|
2026-03-07 18:03:32 +11:00
|
|
|
capabilities.add(MatrixCapabilities.MSC3846TurnServers);
|
|
|
|
|
capabilities.add(MatrixCapabilities.MSC4157SendDelayedEvent);
|
|
|
|
|
capabilities.add(MatrixCapabilities.MSC4157UpdateDelayedEvent);
|
2026-09-14 19:11:41 -04:00
|
|
|
// MSC4515: Element Call >= 0.22 in widget mode discovers its LiveKit
|
|
|
|
|
// transport by asking the host (it no longer reads .well-known itself), so
|
|
|
|
|
// without this capability every call fails with MISSING_MATRIX_RTC_TRANSPORT.
|
|
|
|
|
capabilities.add(MatrixCapabilities.MSC4515RtcTransports);
|
2026-03-07 18:03:32 +11:00
|
|
|
capabilities.add(`org.matrix.msc2762.timeline:${roomId}`);
|
|
|
|
|
capabilities.add(`org.matrix.msc2762.state:${roomId}`);
|
|
|
|
|
|
|
|
|
|
capabilities.add(
|
2026-05-21 23:30:50 -04:00
|
|
|
WidgetEventCapability.forStateEvent(EventDirection.Receive, EventType.RoomMember).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
2026-05-21 23:30:50 -04:00
|
|
|
WidgetEventCapability.forStateEvent(EventDirection.Receive, 'org.matrix.msc3401.call').raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
2026-05-21 23:30:50 -04:00
|
|
|
WidgetEventCapability.forStateEvent(EventDirection.Receive, EventType.RoomEncryption).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
2026-05-21 23:30:50 -04:00
|
|
|
WidgetEventCapability.forStateEvent(EventDirection.Receive, EventType.RoomName).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
capabilities.add(
|
|
|
|
|
WidgetEventCapability.forStateEvent(
|
|
|
|
|
EventDirection.Send,
|
|
|
|
|
'org.matrix.msc3401.call.member',
|
2026-05-21 23:30:50 -04:00
|
|
|
userId,
|
|
|
|
|
).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
|
|
|
|
WidgetEventCapability.forStateEvent(
|
|
|
|
|
EventDirection.Send,
|
|
|
|
|
'org.matrix.msc3401.call.member',
|
2026-05-21 23:30:50 -04:00
|
|
|
`_${userId}_${deviceId}_m.call`,
|
|
|
|
|
).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
|
|
|
|
WidgetEventCapability.forStateEvent(
|
|
|
|
|
EventDirection.Send,
|
|
|
|
|
'org.matrix.msc3401.call.member',
|
2026-05-21 23:30:50 -04:00
|
|
|
`${userId}_${deviceId}_m.call`,
|
|
|
|
|
).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
|
|
|
|
WidgetEventCapability.forStateEvent(
|
|
|
|
|
EventDirection.Send,
|
|
|
|
|
'org.matrix.msc3401.call.member',
|
2026-05-21 23:30:50 -04:00
|
|
|
`_${userId}_${deviceId}`,
|
|
|
|
|
).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
|
|
|
|
WidgetEventCapability.forStateEvent(
|
|
|
|
|
EventDirection.Send,
|
|
|
|
|
'org.matrix.msc3401.call.member',
|
2026-05-21 23:30:50 -04:00
|
|
|
`${userId}_${deviceId}`,
|
|
|
|
|
).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
capabilities.add(
|
|
|
|
|
WidgetEventCapability.forStateEvent(EventDirection.Receive, 'org.matrix.msc3401.call.member')
|
2026-05-21 23:30:50 -04:00
|
|
|
.raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
capabilities.add(
|
2026-05-21 23:30:50 -04:00
|
|
|
WidgetEventCapability.forStateEvent(EventDirection.Receive, EventType.RoomCreate).raw,
|
2026-03-07 18:03:32 +11:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
[
|
|
|
|
|
'io.element.call.encryption_keys',
|
|
|
|
|
'org.matrix.rageshake_request',
|
|
|
|
|
EventType.Reaction,
|
|
|
|
|
EventType.RoomRedaction,
|
|
|
|
|
'io.element.call.reaction',
|
2026-05-14 19:41:12 +10:00
|
|
|
'org.matrix.msc4075.rtc.notification',
|
2026-03-07 18:03:32 +11:00
|
|
|
'org.matrix.msc4310.rtc.decline',
|
|
|
|
|
].forEach((type) => {
|
|
|
|
|
capabilities.add(WidgetEventCapability.forRoomEvent(EventDirection.Send, type).raw);
|
|
|
|
|
capabilities.add(WidgetEventCapability.forRoomEvent(EventDirection.Receive, type).raw);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
[
|
|
|
|
|
EventType.CallInvite,
|
|
|
|
|
EventType.CallCandidates,
|
|
|
|
|
EventType.CallAnswer,
|
|
|
|
|
EventType.CallHangup,
|
|
|
|
|
EventType.CallReject,
|
|
|
|
|
EventType.CallSelectAnswer,
|
|
|
|
|
EventType.CallNegotiate,
|
|
|
|
|
EventType.CallSDPStreamMetadataChanged,
|
|
|
|
|
EventType.CallSDPStreamMetadataChangedPrefix,
|
|
|
|
|
EventType.CallReplaces,
|
|
|
|
|
EventType.CallEncryptionKeysPrefix,
|
|
|
|
|
].forEach((type) => {
|
|
|
|
|
capabilities.add(WidgetEventCapability.forToDeviceEvent(EventDirection.Send, type).raw);
|
|
|
|
|
capabilities.add(WidgetEventCapability.forToDeviceEvent(EventDirection.Receive, type).raw);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return capabilities;
|
|
|
|
|
}
|