Merge pull request #3720 from element-hq/toger5/sdk-improvements-only

[MatrixRTC SDK] improvements - compatible with custom rtc application
This commit is contained in:
Timo
2026-02-09 09:50:16 +01:00
committed by GitHub
12 changed files with 204 additions and 57 deletions

View File

@@ -7,7 +7,7 @@ on:
type: string type: string
package: package:
type: string # This would ideally be a `choice` type, but that isn't supported yet type: string # This would ideally be a `choice` type, but that isn't supported yet
description: The package type to be built. Must be one of 'full' or 'embedded' description: The package type to be built. Must be one of 'full', 'embedded', or 'sdk'
required: true required: true
build_mode: build_mode:
type: string # This would ideally be a `choice` type, but that isn't supported yet type: string # This would ideally be a `choice` type, but that isn't supported yet

View File

@@ -69,3 +69,17 @@ jobs:
SENTRY_URL: ${{ secrets.SENTRY_URL }} SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
build_sdk_element_call:
# Use the embedded package vite build
uses: ./.github/workflows/build-element-call.yaml
with:
package: sdk
vite_app_version: ${{ github.event.release.tag_name || github.sha }}
build_mode: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'development build') && 'development' || 'production' }}
secrets:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -14,6 +14,10 @@ on:
deployment_ref: deployment_ref:
required: true required: true
type: string type: string
package:
required: true
type: string
description: Which package to deploy - 'full', 'embedded', or 'sdk'
artifact_run_id: artifact_run_id:
required: false required: false
type: string type: string
@@ -50,7 +54,7 @@ jobs:
with: with:
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
run-id: ${{ inputs.artifact_run_id }} run-id: ${{ inputs.artifact_run_id }}
name: build-output-full name: build-output-${{ inputs.package }}
path: webapp path: webapp
- name: Add redirects file - name: Add redirects file
@@ -58,15 +62,17 @@ jobs:
run: curl -s https://raw.githubusercontent.com/element-hq/element-call/main/config/netlify_redirects > webapp/_redirects run: curl -s https://raw.githubusercontent.com/element-hq/element-call/main/config/netlify_redirects > webapp/_redirects
- name: Add config file - name: Add config file
run: curl -s "https://raw.githubusercontent.com/${{ inputs.pr_head_full_name }}/${{ inputs.pr_head_ref }}/config/config_netlify_preview.json" > webapp/config.json run: |
if [ "${{ inputs.package }}" = "full" ]; then
curl -s "https://raw.githubusercontent.com/${{ inputs.pr_head_full_name }}/${{ inputs.pr_head_ref }}/config/config_netlify_preview_sdk.json" > webapp/config.json
fi
- name: ☁️ Deploy to Netlify - name: ☁️ Deploy to Netlify
id: netlify id: netlify
uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0 uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0
with: with:
publish-dir: webapp publish-dir: webapp
deploy-message: "Deploy from GitHub Actions" deploy-message: "Deploy from GitHub Actions"
alias: pr${{ inputs.pr_number }} alias: ${{ inputs.package == 'sdk' && format('pr{0}-sdk', inputs.pr_number) || format('pr{0}', inputs.pr_number) }}
env: env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

View File

@@ -20,7 +20,7 @@ jobs:
owner: ${{ github.event.workflow_run.head_repository.owner.login }} owner: ${{ github.event.workflow_run.head_repository.owner.login }}
branch: ${{ github.event.workflow_run.head_branch }} branch: ${{ github.event.workflow_run.head_branch }}
netlify: netlify-full:
needs: prdetails needs: prdetails
permissions: permissions:
deployments: write deployments: write
@@ -31,6 +31,24 @@ jobs:
pr_head_full_name: ${{ github.event.workflow_run.head_repository.full_name }} pr_head_full_name: ${{ github.event.workflow_run.head_repository.full_name }}
pr_head_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.ref }} pr_head_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.ref }}
deployment_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.sha || github.ref || github.head_ref }} deployment_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.sha || github.ref || github.head_ref }}
package: full
secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
netlify-sdk:
needs: prdetails
permissions:
deployments: write
uses: ./.github/workflows/deploy-to-netlify.yaml
with:
artifact_run_id: ${{ github.event.workflow_run.id || github.run_id }}
pr_number: ${{ needs.prdetails.outputs.pr_number }}
pr_head_full_name: ${{ github.event.workflow_run.head_repository.full_name }}
pr_head_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.ref }}
deployment_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.sha || github.ref || github.head_ref }}
package: sdk
secrets: secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}

View File

@@ -13,8 +13,9 @@
"build:embedded": "yarn build:full --config vite-embedded.config.js", "build:embedded": "yarn build:full --config vite-embedded.config.js",
"build:embedded:production": "yarn build:embedded", "build:embedded:production": "yarn build:embedded",
"build:embedded:development": "yarn build:embedded --mode development", "build:embedded:development": "yarn build:embedded --mode development",
"build:sdk": "yarn build:full --config vite-sdk.config.js",
"build:sdk:development": "yarn build:sdk --mode development", "build:sdk:development": "yarn build:sdk --mode development",
"build:sdk": "yarn build:full --config vite-sdk.config.js",
"build:sdk:production": "yarn build:sdk",
"serve": "vite preview", "serve": "vite preview",
"prettier:check": "prettier -c .", "prettier:check": "prettier -c .",
"prettier:format": "prettier -w .", "prettier:format": "prettier -w .",
@@ -104,7 +105,7 @@
"livekit-client": "^2.13.0", "livekit-client": "^2.13.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"loglevel": "^1.9.1", "loglevel": "^1.9.1",
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop", "matrix-js-sdk": "matrix-org/matrix-js-sdk#6e3efef0c5f660df47cf00874927dec1c75cc3cf",
"matrix-widget-api": "^1.16.1", "matrix-widget-api": "^1.16.1",
"node-stdlib-browser": "^1.3.1", "node-stdlib-browser": "^1.3.1",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",

View File

@@ -1,4 +1,4 @@
# SDK mode # SDK mode (EXPERIMENTAL)
EC can be build in sdk mode. This will result in a compiled js file that can be imported in very simple webapps. EC can be build in sdk mode. This will result in a compiled js file that can be imported in very simple webapps.

View File

@@ -12,15 +12,12 @@ Please see LICENSE in the repository root for full details.
import { logger as rootLogger } from "matrix-js-sdk/lib/logger"; import { logger as rootLogger } from "matrix-js-sdk/lib/logger";
import { scan } from "rxjs"; import { scan } from "rxjs";
import { widget as _widget } from "../src/widget"; import { type WidgetHelpers } from "../src/widget";
import { type LivekitRoomItem } from "../src/state/CallViewModel/CallViewModel"; import { type LivekitRoomItem } from "../src/state/CallViewModel/CallViewModel";
export const logger = rootLogger.getChild("[MatrixRTCSdk]"); export const logger = rootLogger.getChild("[MatrixRTCSdk]");
if (!_widget) throw Error("No widget. This webapp can only start as a widget"); export const tryMakeSticky = (widget: WidgetHelpers): void => {
export const widget = _widget;
export const tryMakeSticky = (): void => {
logger.info("try making sticky MatrixRTCSdk"); logger.info("try making sticky MatrixRTCSdk");
void widget.api void widget.api
.setAlwaysOnScreen(true) .setAlwaysOnScreen(true)

View File

@@ -6,6 +6,8 @@ Please see LICENSE in the repository root for full details.
*/ */
/** /**
* EXPERIMENTAL
*
* This file is the entrypoint for the sdk build of element call: `yarn build:sdk` * This file is the entrypoint for the sdk build of element call: `yarn build:sdk`
* use in widgets. * use in widgets.
* It exposes the `createMatrixRTCSdk` which creates the `MatrixRTCSdk` interface (see below) that * It exposes the `createMatrixRTCSdk` which creates the `MatrixRTCSdk` interface (see below) that
@@ -30,8 +32,8 @@ import {
} from "rxjs"; } from "rxjs";
import { import {
type CallMembership, type CallMembership,
MatrixRTCSession,
MatrixRTCSessionEvent, MatrixRTCSessionEvent,
MatrixRTCSessionManager,
} from "matrix-js-sdk/lib/matrixrtc"; } from "matrix-js-sdk/lib/matrixrtc";
import { import {
type Room as LivekitRoom, type Room as LivekitRoom,
@@ -50,14 +52,12 @@ import { getUrlParams } from "../src/UrlParams";
import { MuteStates } from "../src/state/MuteStates"; import { MuteStates } from "../src/state/MuteStates";
import { MediaDevices } from "../src/state/MediaDevices"; import { MediaDevices } from "../src/state/MediaDevices";
import { E2eeType } from "../src/e2ee/e2eeType"; import { E2eeType } from "../src/e2ee/e2eeType";
import { currentAndPrev, logger, TEXT_LK_TOPIC, tryMakeSticky } from "./helper";
import { import {
currentAndPrev, ElementWidgetActions,
logger, widget as _widget,
TEXT_LK_TOPIC, initializeWidget,
tryMakeSticky, } from "../src/widget";
widget,
} from "./helper";
import { ElementWidgetActions, initializeWidget } from "../src/widget";
import { type Connection } from "../src/state/CallViewModel/remoteMembers/Connection"; import { type Connection } from "../src/state/CallViewModel/remoteMembers/Connection";
interface MatrixRTCSdk { interface MatrixRTCSdk {
@@ -68,7 +68,13 @@ interface MatrixRTCSdk {
join: () => void; join: () => void;
/** @throws on leave errors */ /** @throws on leave errors */
leave: () => void; leave: () => void;
data$: Observable<{ sender: string; data: string }>; /**
* Ends the rtc sdk. This will unsubscribe any event listeners. And end the associated scope.
* No updates can be received from the rtc sdk. The sdk cannot be restarted after.
* A new sdk needs to be created via createMatrixRTCSdk.
*/
stop: () => void;
data$: Observable<{ rtcBackendIdentity: string; data: string }>;
/** /**
* flattened list of members * flattened list of members
*/ */
@@ -79,32 +85,54 @@ interface MatrixRTCSdk {
participant: LocalParticipant | RemoteParticipant | null; participant: LocalParticipant | RemoteParticipant | null;
}[] }[]
>; >;
/**
* flattened local members
*/
localMember$: Behavior<{
connection: Connection | null;
membership: CallMembership;
participant: LocalParticipant | null;
} | null>;
/** Use the LocalMemberConnectionState returned from `join` for a more detailed connection state */ /** Use the LocalMemberConnectionState returned from `join` for a more detailed connection state */
connected$: Behavior<boolean>; connected$: Behavior<boolean>;
sendData?: (data: unknown) => Promise<void>; sendData?: (data: unknown) => Promise<void>;
sendRoomMessage?: (message: string) => Promise<void>;
} }
export async function createMatrixRTCSdk( export async function createMatrixRTCSdk(
application: string = "m.call", application: string = "m.call",
id: string = "", id: string = "",
sticky: boolean = false,
): Promise<MatrixRTCSdk> { ): Promise<MatrixRTCSdk> {
initializeWidget(); const scope = new ObservableScope();
// widget client
initializeWidget(application, true);
const widget = _widget;
if (!widget) throw Error("No widget. This webapp can only start as a widget");
const client = await widget.client; const client = await widget.client;
logger.info("client created"); logger.info("client created");
const scope = new ObservableScope();
// url params
const { roomId } = getUrlParams(); const { roomId } = getUrlParams();
if (roomId === null) throw Error("could not get roomId from url params"); if (roomId === null) throw Error("could not get roomId from url params");
const room = client.getRoom(roomId); const room = client.getRoom(roomId);
if (room === null) throw Error("could not get room from client"); if (room === null) throw Error("could not get room from client");
// rtc session
const slot = { application, id };
const rtcSessionManager = new MatrixRTCSessionManager(logger, client, slot);
rtcSessionManager.start();
const rtcSession = rtcSessionManager.getRoomSession(room);
// media devices
const mediaDevices = new MediaDevices(scope); const mediaDevices = new MediaDevices(scope);
const muteStates = new MuteStates(scope, mediaDevices, { const muteStates = new MuteStates(scope, mediaDevices, {
audioEnabled: true, audioEnabled: false,
videoEnabled: true, videoEnabled: false,
}); });
const slot = { application, id };
const rtcSession = new MatrixRTCSession(client, room, slot); // call view model
const callViewModel = createCallViewModel$( const callViewModel = createCallViewModel$(
scope, scope,
rtcSession, rtcSession,
@@ -117,8 +145,9 @@ export async function createMatrixRTCSdk(
constant({ supported: false, processor: undefined }), constant({ supported: false, processor: undefined }),
); );
logger.info("CallViewModelCreated"); logger.info("CallViewModelCreated");
// create data listener // create data listener
const data$ = new Subject<{ sender: string; data: string }>(); const data$ = new Subject<{ rtcBackendIdentity: string; data: string }>();
const lkTextStreamHandlerFunction = async ( const lkTextStreamHandlerFunction = async (
reader: TextStreamReader, reader: TextStreamReader,
@@ -140,7 +169,7 @@ export async function createMatrixRTCSdk(
if (participants && participants.includes(participantInfo.identity)) { if (participants && participants.includes(participantInfo.identity)) {
const text = await reader.readAll(); const text = await reader.readAll();
logger.info(`Received text: ${text}`); logger.info(`Received text: ${text}`);
data$.next({ sender: participantInfo.identity, data: text }); data$.next({ rtcBackendIdentity: participantInfo.identity, data: text });
} else { } else {
logger.warn( logger.warn(
"Received text from unknown participant", "Received text from unknown participant",
@@ -230,6 +259,16 @@ export async function createMatrixRTCSdk(
} }
}; };
const sendRoomMessage = async (message: string): Promise<void> => {
const messageString = JSON.stringify(message);
logger.info("try sending to room: ", messageString);
try {
await client.sendTextMessage(room.roomId, message);
} catch (e) {
logger.error("failed sending to room: ", messageString, e);
}
};
// after hangup gets called // after hangup gets called
const leaveSubs = callViewModel.leave$.subscribe(() => { const leaveSubs = callViewModel.leave$.subscribe(() => {
const scheduleWidgetCloseOnLeave = async (): Promise<void> => { const scheduleWidgetCloseOnLeave = async (): Promise<void> => {
@@ -257,9 +296,6 @@ export async function createMatrixRTCSdk(
// schedule close first and then leave (scope.end) // schedule close first and then leave (scope.end)
void scheduleWidgetCloseOnLeave(); void scheduleWidgetCloseOnLeave();
// actual hangup (ending scope will send the leave event.. its kinda odd. since you might end up closing the widget too fast)
scope.end();
}); });
logger.info("createMatrixRTCSdk done"); logger.info("createMatrixRTCSdk done");
@@ -267,15 +303,40 @@ export async function createMatrixRTCSdk(
return { return {
join: (): void => { join: (): void => {
// first lets try making the widget sticky // first lets try making the widget sticky
tryMakeSticky(); if (sticky) tryMakeSticky(widget);
callViewModel.join(); callViewModel.join();
}, },
leave: (): void => { leave: (): void => {
callViewModel.hangup(); callViewModel.leave();
},
stop: (): void => {
leaveSubs.unsubscribe(); leaveSubs.unsubscribe();
livekitRoomItemsSub.unsubscribe(); livekitRoomItemsSub.unsubscribe();
scope.end();
}, },
data$, data$,
localMember$: scope.behavior(
callViewModel.localMatrixLivekitMember$.pipe(
tap((member) =>
logger.info("localMatrixLivekitMember$ next: ", member),
),
switchMap((member) => {
if (member === null) return of(null);
return combineLatest([
member.connection$,
member.membership$,
member.participant.value$,
]).pipe(
map(([connection, membership, participant]) => ({
connection,
membership,
participant,
})),
);
}),
tap((member) => logger.info("localMember$ next: ", member)),
),
),
connected$: callViewModel.connected$, connected$: callViewModel.connected$,
members$: scope.behavior( members$: scope.behavior(
callViewModel.matrixLivekitMembers$.pipe( callViewModel.matrixLivekitMembers$.pipe(
@@ -302,5 +363,6 @@ export async function createMatrixRTCSdk(
[], [],
), ),
sendData, sendData,
sendRoomMessage,
}; };
} }

View File

@@ -217,15 +217,23 @@ export interface CallViewModel {
"unknown" | "ringing" | "timeout" | "decline" | "success" | null "unknown" | "ringing" | "timeout" | "decline" | "success" | null
>; >;
/** Observable that emits when the user should leave the call (hangup pressed, widget action, error). /** Observable that emits when the user should leave the call (hangup pressed, widget action, error).
* THIS DOES NOT LEAVE THE CALL YET. The only way to leave the call (send the hangup event) is by ending the scope. * THIS DOES NOT LEAVE THE CALL YET. The only way to leave the call (send the hangup event) is
* - by ending the scope
* - or calling requestDisconnect
*
* TODO: it seems more reasonable to add a leave() method (that calls requestDisconnect) that will then update leave$ and remove the hangup pattern
*/ */
leave$: Observable<"user" | AutoLeaveReason>; leave$: Observable<"user" | AutoLeaveReason>;
/** Call to initiate hangup. Use in conbination with reconnectino state track the async hangup process. */ /** Call to initiate hangup. Use in conbination with reconnection state track the async hangup process. */
hangup: () => void; hangup: () => void;
// joining // joining
join: () => void; join: () => void;
/**
* calls requestDisconnect. The async leave state can than be observed via connected$
*/
leave: () => void;
// screen sharing // screen sharing
/** /**
* Callback to toggle screen sharing. If null, screen sharing is not possible. * Callback to toggle screen sharing. If null, screen sharing is not possible.
@@ -1497,6 +1505,7 @@ export function createCallViewModel$(
leave$: leave$, leave$: leave$,
hangup: (): void => userHangup$.next(), hangup: (): void => userHangup$.next(),
join: localMembership.requestJoinAndPublish, join: localMembership.requestJoinAndPublish,
leave: localMembership.requestDisconnect,
toggleScreenSharing: toggleScreenSharing, toggleScreenSharing: toggleScreenSharing,
sharingScreen$: sharingScreen$, sharingScreen$: sharingScreen$,

View File

@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details. Please see LICENSE in the repository root for full details.
*/ */
import { beforeAll, describe, expect, vi, it } from "vitest"; import { describe, expect, vi, it, beforeEach } from "vitest";
import { createRoomWidgetClient, EventType } from "matrix-js-sdk"; import { createRoomWidgetClient, EventType } from "matrix-js-sdk";
import { getUrlParams } from "./UrlParams"; import { getUrlParams } from "./UrlParams";
@@ -35,11 +35,14 @@ vi.mock("./UrlParams", () => ({
})), })),
})); }));
initializeWidget(); beforeEach(() => {
describe("widget", () => { createRoomWidgetClientSpy.mockClear();
beforeAll(() => {}); });
describe("widget", () => {
it("should create an embedded client with the correct params", () => { it("should create an embedded client with the correct params", () => {
initializeWidget("ANYRTCAPP");
expect(getUrlParams()).toStrictEqual({ expect(getUrlParams()).toStrictEqual({
widgetId: "id", widgetId: "id",
parentUrl: "http://parentUrl", parentUrl: "http://parentUrl",
@@ -66,13 +69,16 @@ describe("widget", () => {
]; ];
const sendState = [ const sendState = [
"myYser", // Legacy call membership events { eventType: "org.matrix.msc3401.call.member", stateKey: "myYser" }, // Legacy call membership events
`_myYser_AAAAA_m.call`, // Session membership events {
`myYser_AAAAA_m.call`, // The above with no leading underscore, for room versions whose auth rules allow it eventType: "org.matrix.msc3401.call.member",
].map((stateKey) => ({ stateKey: `_myYser_AAAAA_ANYRTCAPP`,
eventType: EventType.GroupCallMemberPrefix, }, // Session membership events
stateKey, {
})); eventType: "org.matrix.msc3401.call.member",
stateKey: `myYser_AAAAA_ANYRTCAPP`,
}, // The above with no leading underscore, for room versions whose auth rules allow it
];
const receiveState = [ const receiveState = [
{ eventType: EventType.RoomCreate }, { eventType: EventType.RoomCreate },
{ eventType: EventType.RoomName }, { eventType: EventType.RoomName },
@@ -124,4 +130,32 @@ describe("widget", () => {
}); });
expect(createRoomWidgetClientSpy.mock.calls[0][4]).toStrictEqual(false); expect(createRoomWidgetClientSpy.mock.calls[0][4]).toStrictEqual(false);
}); });
it("should request send message permission if requested", () => {
initializeWidget("ANYRTCAPP", true);
expect(createRoomWidgetClientSpy).toHaveBeenLastCalledWith(
expect.anything(),
// capabilities
expect.objectContaining({
sendEvent: expect.arrayContaining(["m.room.message"]),
}),
expect.anything(),
expect.anything(),
expect.anything(),
);
});
it("should not request send message permission when not requested", () => {
initializeWidget("", false);
expect(createRoomWidgetClientSpy).toHaveBeenLastCalledWith(
expect.anything(),
// capabilities
expect.objectContaining({
sendEvent: expect.not.arrayContaining(["m.room.message"]),
}),
expect.anything(),
expect.anything(),
expect.anything(),
);
});
}); });

View File

@@ -68,7 +68,10 @@ export let widget: WidgetHelpers | null;
*/ */
// this needs to be a seperate call and cannot be done on import to allow us to spy on methods in here before // this needs to be a seperate call and cannot be done on import to allow us to spy on methods in here before
// execution. // execution.
export const initializeWidget = (): void => { export const initializeWidget = (
rtcApplication: string = "m.call",
sendRoomEvents = false,
): void => {
try { try {
const { const {
widgetId, widgetId,
@@ -116,6 +119,9 @@ export const initializeWidget = (): void => {
EventType.CallNotify, // Sent as a deprecated fallback EventType.CallNotify, // Sent as a deprecated fallback
EventType.RTCNotification, EventType.RTCNotification,
]; ];
if (sendRoomEvents) {
sendEvent.push(EventType.RoomMessage);
}
const sendRecvEvent = [ const sendRecvEvent = [
"org.matrix.rageshake_request", "org.matrix.rageshake_request",
EventType.CallEncryptionKeysPrefix, EventType.CallEncryptionKeysPrefix,
@@ -128,8 +134,8 @@ export const initializeWidget = (): void => {
const sendState = [ const sendState = [
userId, // Legacy call membership events userId, // Legacy call membership events
`_${userId}_${deviceId}_m.call`, // Session membership events `_${userId}_${deviceId}_${rtcApplication}`, // Session membership events
`${userId}_${deviceId}_m.call`, // The above with no leading underscore, for room versions whose auth rules allow it `${userId}_${deviceId}_${rtcApplication}`, // The above with no leading underscore, for room versions whose auth rules allow it
].map((stateKey) => ({ ].map((stateKey) => ({
eventType: EventType.GroupCallMemberPrefix, eventType: EventType.GroupCallMemberPrefix,
stateKey, stateKey,

View File

@@ -8364,7 +8364,7 @@ __metadata:
livekit-client: "npm:^2.13.0" livekit-client: "npm:^2.13.0"
lodash-es: "npm:^4.17.21" lodash-es: "npm:^4.17.21"
loglevel: "npm:^1.9.1" loglevel: "npm:^1.9.1"
matrix-js-sdk: "matrix-org/matrix-js-sdk#develop" matrix-js-sdk: "matrix-org/matrix-js-sdk#6e3efef0c5f660df47cf00874927dec1c75cc3cf"
matrix-widget-api: "npm:^1.16.1" matrix-widget-api: "npm:^1.16.1"
node-stdlib-browser: "npm:^1.3.1" node-stdlib-browser: "npm:^1.3.1"
normalize.css: "npm:^8.0.1" normalize.css: "npm:^8.0.1"
@@ -11452,9 +11452,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"matrix-js-sdk@matrix-org/matrix-js-sdk#develop": "matrix-js-sdk@matrix-org/matrix-js-sdk#6e3efef0c5f660df47cf00874927dec1c75cc3cf":
version: 40.1.0 version: 40.1.0
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=f2157f28bbadf2898fe21991f69ccb2af40df326" resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=6e3efef0c5f660df47cf00874927dec1c75cc3cf"
dependencies: dependencies:
"@babel/runtime": "npm:^7.12.5" "@babel/runtime": "npm:^7.12.5"
"@matrix-org/matrix-sdk-crypto-wasm": "npm:^17.0.0" "@matrix-org/matrix-sdk-crypto-wasm": "npm:^17.0.0"
@@ -11470,7 +11470,7 @@ __metadata:
sdp-transform: "npm:^3.0.0" sdp-transform: "npm:^3.0.0"
unhomoglyph: "npm:^1.0.6" unhomoglyph: "npm:^1.0.6"
uuid: "npm:13" uuid: "npm:13"
checksum: 10c0/d646b9214abbf0b9126760105edd9c57be7ffe8b53ae4acd5fefe841a51ad7d78fa57130922b3eac65ff2266b43f31ea60b4bdda9481e6bf8f1808d96726ed8a checksum: 10c0/2c4db56fd0164d801c2f125ab2a442e3659314d4cc2fd640ea152b829d0db8b05ff808020e387a761afde4ff7a07b271c25431337de9f7c765c523c8cd837e36
languageName: node languageName: node
linkType: hard linkType: hard