Send notification events when starting a call

Previously this has been the responsibility of the hosting application (Element Web / Element X), but I would like to move this responsibility to Element Call itself to make it even more lightweight to integrate Element Call into a widget-capable client.
This commit is contained in:
Robin
2025-03-11 19:39:13 -04:00
committed by Timo
parent 8458d198c9
commit f1c2945eff
2 changed files with 34 additions and 2 deletions

View File

@@ -18,8 +18,9 @@ import { AutoDiscovery } from "matrix-js-sdk/lib/autodiscovery";
import { PosthogAnalytics } from "./analytics/PosthogAnalytics"; import { PosthogAnalytics } from "./analytics/PosthogAnalytics";
import { Config } from "./config/Config"; import { Config } from "./config/Config";
import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget"; import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget";
import { MatrixRTCFocusMissingError } from "./utils/errors.ts"; import { MatrixRTCFocusMissingError } from "./utils/errors";
import { getUrlParams } from "./UrlParams.ts"; import { getUrlParams } from "./UrlParams";
import { getJoinedNonFunctionalMembers } from "./utils/matrix";
const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci"; const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci";
@@ -94,6 +95,12 @@ async function makePreferredLivekitFoci(
// if (focusOtherMembers) preferredFoci.push(focusOtherMembers); // if (focusOtherMembers) preferredFoci.push(focusOtherMembers);
} }
function getNotifyType(room: Room): CallNotifyType | undefined {
if (room.isCallRoom()) return undefined;
if (getJoinedNonFunctionalMembers(room).length === 2) return "ring";
return "notify";
}
export async function enterRTCSession( export async function enterRTCSession(
rtcSession: MatrixRTCSession, rtcSession: MatrixRTCSession,
encryptMedia: boolean, encryptMedia: boolean,
@@ -116,6 +123,7 @@ export async function enterRTCSession(
await makePreferredLivekitFoci(rtcSession, livekitAlias), await makePreferredLivekitFoci(rtcSession, livekitAlias),
makeActiveFocus(), makeActiveFocus(),
{ {
notifyType: getNotifyType(rtcSession.room),
useNewMembershipManager, useNewMembershipManager,
manageMediaKeys: encryptMedia, manageMediaKeys: encryptMedia,
...(useDeviceSessionMemberEvents !== undefined && { ...(useDeviceSessionMemberEvents !== undefined && {

View File

@@ -12,7 +12,10 @@ import {
IndexedDBStore, IndexedDBStore,
MemoryStore, MemoryStore,
Preset, Preset,
type RoomMember,
UNSTABLE_ELEMENT_FUNCTIONAL_USERS,
Visibility, Visibility,
Direction,
} from "matrix-js-sdk"; } from "matrix-js-sdk";
import { type ISyncStateData, type SyncState } from "matrix-js-sdk/lib/sync"; import { type ISyncStateData, type SyncState } from "matrix-js-sdk/lib/sync";
import { logger } from "matrix-js-sdk/lib/logger"; import { logger } from "matrix-js-sdk/lib/logger";
@@ -336,6 +339,27 @@ export function getRelativeRoomUrl(
return `/room/#${roomPart}?${generateUrlSearchParams(roomId, encryptionSystem, viaServers).toString()}`; return `/room/#${roomPart}?${generateUrlSearchParams(roomId, encryptionSystem, viaServers).toString()}`;
} }
/**
* Returns all room members that are non-functional (all actual room members).
* A functional user is a user that is not a real user, but a bot, assistant, etc.
*/
export function getJoinedNonFunctionalMembers(room: Room): RoomMember[] {
const functionalUsersStateEvent = room
.getLiveTimeline()
.getState(Direction.Forward)
?.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, "");
const functionalMembers = Array.isArray(
functionalUsersStateEvent?.getContent().service_members,
)
? functionalUsersStateEvent.getContent().service_members
: [];
return room
.getJoinedMembers()
.filter((m) => !functionalMembers.includes(m.userId));
}
/** /**
* Perform a network operation with retries on ConnectionError. * Perform a network operation with retries on ConnectionError.
* If the error is not retryable, or the max number of retries is reached, the error is rethrown. * If the error is not retryable, or the max number of retries is reached, the error is rethrown.