diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index 76352523..ea57bd10 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -452,6 +452,7 @@ export const GroupCallView: FC = ({ client={client} matrixInfo={matrixInfo} rtcSession={rtcSession as MatrixRTCSession} + matrixRoom={room} participantCount={participantCount} onLeave={onLeave} header={header} diff --git a/src/room/InCallView.test.tsx b/src/room/InCallView.test.tsx index b88aaad7..ec057e94 100644 --- a/src/room/InCallView.test.tsx +++ b/src/room/InCallView.test.tsx @@ -175,6 +175,7 @@ function createInCallView(): RenderResult & { kind: E2eeType.NONE, }, }} + matrixRoom={room} livekitRoom={livekitRoom} participantCount={0} onLeave={function (): void { diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 5aa270d2..2061289a 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -7,8 +7,8 @@ Please see LICENSE in the repository root for full details. import { RoomContext, useLocalParticipant } from "@livekit/components-react"; import { IconButton, Text, Tooltip } from "@vector-im/compound-web"; -import { ConnectionState, type Room } from "livekit-client"; -import { type MatrixClient } from "matrix-js-sdk"; +import { ConnectionState, type Room as LivekitRoom } from "livekit-client"; +import { type MatrixClient, type Room as MatrixRoom } from "matrix-js-sdk"; import { type FC, type PointerEvent, @@ -166,6 +166,7 @@ export const ActiveCall: FC = (props) => { const reactionsReader = new ReactionsReader(props.rtcSession); const vm = new CallViewModel( props.rtcSession, + props.matrixRoom, livekitRoom, mediaDevices, { @@ -184,6 +185,7 @@ export const ActiveCall: FC = (props) => { } }, [ props.rtcSession, + props.matrixRoom, livekitRoom, mediaDevices, props.e2eeSystem, @@ -212,7 +214,8 @@ export interface InCallViewProps { vm: CallViewModel; matrixInfo: MatrixInfo; rtcSession: MatrixRTCSession; - livekitRoom: Room; + matrixRoom: MatrixRoom; + livekitRoom: LivekitRoom; muteStates: MuteStates; participantCount: number; /** Function to call when the user explicitly ends the call */ @@ -228,6 +231,7 @@ export const InCallView: FC = ({ vm, matrixInfo, rtcSession, + matrixRoom, livekitRoom, muteStates, participantCount, @@ -272,7 +276,7 @@ export const InCallView: FC = ({ const [useExperimentalToDeviceTransport] = useSetting( useExperimentalToDeviceTransportSetting, ); - const encryptionSystem = useRoomEncryptionSystem(rtcSession.room.roomId); + const encryptionSystem = useRoomEncryptionSystem(matrixRoom.roomId); const memberships = useMatrixRTCSessionMemberships(rtcSession); const showToDeviceEncryption = useMemo( @@ -642,7 +646,7 @@ export const InCallView: FC = ({ }; const rageshakeRequestModalProps = useRageshakeRequestModal( - rtcSession.room.roomId, + matrixRoom.roomId, ); const toggleScreensharing = useCallback(() => { @@ -800,7 +804,7 @@ export const InCallView: FC = ({ of()); - const liveKitRoom = mockLivekitRoom( + const livekitRoom = mockLivekitRoom( { localParticipant }, { remoteParticipants$ }, ); @@ -288,7 +288,8 @@ function withCallViewModel( const vm = new CallViewModel( rtcSession as unknown as MatrixRTCSession, - liveKitRoom, + room, + livekitRoom, mediaDevices, options, connectionState$, diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index 70183a37..80076cb2 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -18,7 +18,11 @@ import { type RemoteParticipant, Track, } from "livekit-client"; -import { RoomStateEvent, type Room, type RoomMember } from "matrix-js-sdk"; +import { + RoomStateEvent, + type Room as MatrixRoom, + type RoomMember, +} from "matrix-js-sdk"; import { BehaviorSubject, EMPTY, @@ -368,7 +372,7 @@ type MediaItem = UserMedia | ScreenShare; function getRoomMemberFromRtcMember( rtcMember: CallMembership, - room: Room, + room: MatrixRoom, ): { id: string; member: RoomMember | undefined } { // WARN! This is not exactly the sender but the user defined in the state key. // This will be available once we change to the new "member as object" format in the MatrixRTC object. @@ -481,7 +485,7 @@ export class CallViewModel extends ViewModel { // Handle call membership changes. fromEvent(this.matrixRTCSession, MatrixRTCSessionEvent.MembershipsChanged), // Handle room membership changes (and displayname updates) - fromEvent(this.matrixRTCSession.room, RoomStateEvent.Members), + fromEvent(this.matrixRoom, RoomStateEvent.Members), ).pipe( startWith(this.matrixRTCSession.memberships), map(() => { @@ -497,7 +501,7 @@ export class CallViewModel extends ViewModel { public readonly memberDisplaynames$ = this.memberships$.pipe( map((memberships) => { const displaynameMap = new Map(); - const { room } = this.matrixRTCSession; + const room = this.matrixRoom; // We only consider RTC members for disambiguation as they are the only visible members. for (const rtcMember of memberships) { @@ -565,7 +569,7 @@ export class CallViewModel extends ViewModel { ) => { const newItems = new Map( function* (this: CallViewModel): Iterable<[string, MediaItem]> { - const room = this.matrixRTCSession.room; + const room = this.matrixRoom; // m.rtc.members are the basis for calculating what is visible in the call for (const rtcMember of this.matrixRTCSession.memberships) { const { member, id: livekitParticipantId } = @@ -783,7 +787,7 @@ export class CallViewModel extends ViewModel { public readonly allOthersLeft$ = this.matrixUserChanges$.pipe( map(({ userIds, leftUserIds }) => { - const userId = this.matrixRTCSession.room.client.getUserId(); + const userId = this.matrixRoom.client.getUserId(); if (!userId) { logger.warn("Could access client.getUserId to compute allOthersLeft"); return false; @@ -1485,6 +1489,7 @@ export class CallViewModel extends ViewModel { public constructor( // A call is permanently tied to a single Matrix room and LiveKit room private readonly matrixRTCSession: MatrixRTCSession, + private readonly matrixRoom: MatrixRoom, private readonly livekitRoom: LivekitRoom, private readonly mediaDevices: MediaDevices, private readonly options: CallViewModelOptions, diff --git a/src/utils/test-viewmodel.ts b/src/utils/test-viewmodel.ts index 4781bf3d..7978bd96 100644 --- a/src/utils/test-viewmodel.ts +++ b/src/utils/test-viewmodel.ts @@ -15,7 +15,7 @@ import { vitest } from "vitest"; import { type RelationsContainer } from "matrix-js-sdk/lib/models/relations-container"; import EventEmitter from "events"; -import type { RoomMember, MatrixClient } from "matrix-js-sdk"; +import type { RoomMember, MatrixClient, Room } from "matrix-js-sdk"; import { E2eeType } from "../e2ee/e2eeType"; import { CallViewModel } from "../state/CallViewModel"; import { @@ -37,6 +37,7 @@ export function getBasicRTCSession( initialRemoteRtcMemberships: CallMembership[] = [aliceRtcMember], ): { rtcSession: MockRTCSession; + matrixRoom: Room; remoteRtcMemberships$: BehaviorSubject; } { const matrixRoomId = "!myRoomId:example.com"; @@ -102,6 +103,7 @@ export function getBasicRTCSession( return { rtcSession, + matrixRoom, remoteRtcMemberships$, }; } @@ -122,7 +124,7 @@ export function getBasicCallViewModelEnvironment( handRaisedSubject$: BehaviorSubject>; reactionsSubject$: BehaviorSubject>; } { - const { rtcSession, remoteRtcMemberships$ } = getBasicRTCSession( + const { rtcSession, matrixRoom, remoteRtcMemberships$ } = getBasicRTCSession( members, initialRemoteRtcMemberships, ); @@ -130,13 +132,14 @@ export function getBasicCallViewModelEnvironment( const reactionsSubject$ = new BehaviorSubject({}); const remoteParticipants$ = of([aliceParticipant]); - const liveKitRoom = mockLivekitRoom( + const livekitRoom = mockLivekitRoom( { localParticipant }, { remoteParticipants$ }, ); const vm = new CallViewModel( rtcSession as unknown as MatrixRTCSession, - liveKitRoom, + matrixRoom, + livekitRoom, mockMediaDevices({}), { encryptionSystem: { kind: E2eeType.PER_PARTICIPANT },