mirror of
https://github.com/vector-im/element-call.git
synced 2026-07-12 18:39:19 +00:00
Make video tiles be based on MatrixRTC member not LiveKit participants (#2701)
* make tiles based on rtc member
* display missing lk participant + fix tile multiplier
* add show_non_member_participants config option
* per member tiles
* merge fixes
* linter
* linter and tests
* tests
* adapt tests (wip)
* Remove unused keys
* Fix optionality of nonMemberItemCount
* video is optional
* Mock RTC members
* Lint
* Merge fixes
* Fix user id
* Add explicit types for public fields
* isRTCParticipantAvailable => isLiveKitParticipantAvailable
* isLiveKitParticipantAvailable
* Readonly
* More keys removal
* Make local field based on view model class not observable
* Wording
* Fix RTC members in tes
* Tests again
* Lint
* Disable showing non-member tiles by default
* Duplicate screen sharing tiles like we used to
* Lint
* Revert function reordering
* Remove throttleTime from bad merge
* Cleanup
* Tidy config of show non-member settings
* tidy up handling of local rtc member in tests
* tidy up test init
* Fix mocks
* Cleanup
* Apply local override where participant not yet known
* Handle no visible media id
* Assertions for one-on-one view
* Remove isLiveKitParticipantAvailable and show via encryption status
* Handle no local media (yet)
* Remove unused effect for setting
* Tidy settings
* Avoid case of one-to-one layout with missing local or remote
* Iterate
* Remove option to show non-member tiles to simplify code review
* Remove unused code
* Remove more remnants of show-non-member-tiles
* iterate
* back
* Fix unit test
* Refactor
* Expose TestScheduler as global
* Fix incorrect type assertion
* Simplify speaking observer
* Fix
* Whitespace
* Make it clear that we are mocking MatrixRTC memberships
* Test case for only showing tiles for MatrixRTC session members
* Simplify diff
* Simplify diff
These changes are in https://github.com/element-hq/element-call/pull/2809
* .
* Whitespaces
* Use asObservable when exposing subject
* Show "waiting for media..." when no participant
* Additional test case
* Don't show "waiting for media..." in case of local participant
* Make the loading state more subtle
- instead of a label we show a animated gradient
* Use correct key for matrix rtc foci in code comment. (#2838)
* Update src/tile/SpotlightTile.tsx
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
* Update src/state/CallViewModel.ts
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
* Make the purpose of BaseMediaViewModel.local explicit
* Use named object instead of unnamed array for spotlightAndPip
* Refactor spotlightAndPip into spotlight and pip
* Use if statement instead of ternary for readability in spotlight and pip logic
* Review feedback
* Fix tests for CallEventAudioRenderer
* Lint
* Revert "Make the loading state more subtle"
This reverts commit 765f7b4f31.
* Update src/state/CallViewModel.ts
Co-authored-by: Timo <16718859+toger5@users.noreply.github.com>
* Fix spelling
* Remove a non-null assertion that failed at runtime
---------
Co-authored-by: Hugh Nimmo-Smith <hughns@element.io>
Co-authored-by: Hugh Nimmo-Smith <hughns@users.noreply.github.com>
This commit is contained in:
@@ -7,7 +7,20 @@ Please see LICENSE in the repository root for full details.
|
||||
import { map, Observable, of, SchedulerLike } from "rxjs";
|
||||
import { RunHelpers, TestScheduler } from "rxjs/testing";
|
||||
import { expect, vi } from "vitest";
|
||||
import { RoomMember, Room as MatrixRoom } from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
RoomMember,
|
||||
Room as MatrixRoom,
|
||||
MatrixEvent,
|
||||
Room,
|
||||
TypedEventEmitter,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
CallMembership,
|
||||
Focus,
|
||||
MatrixRTCSessionEvent,
|
||||
MatrixRTCSessionEventHandlerMap,
|
||||
SessionMembershipData,
|
||||
} from "matrix-js-sdk/src/matrixrtc";
|
||||
import {
|
||||
LocalParticipant,
|
||||
LocalTrackPublication,
|
||||
@@ -100,11 +113,40 @@ function mockEmitter<T>(): EmitterMock<T> {
|
||||
};
|
||||
}
|
||||
|
||||
export function mockRtcMembership(
|
||||
user: string | RoomMember,
|
||||
deviceId: string,
|
||||
callId = "",
|
||||
fociPreferred: Focus[] = [],
|
||||
focusActive: Focus = { type: "oldest_membership" },
|
||||
membership: Partial<SessionMembershipData> = {},
|
||||
): CallMembership {
|
||||
const data: SessionMembershipData = {
|
||||
application: "m.call",
|
||||
call_id: callId,
|
||||
device_id: deviceId,
|
||||
foci_preferred: fociPreferred,
|
||||
focus_active: focusActive,
|
||||
...membership,
|
||||
};
|
||||
const event = new MatrixEvent({
|
||||
sender: typeof user === "string" ? user : user.userId,
|
||||
});
|
||||
return new CallMembership(event, data);
|
||||
}
|
||||
|
||||
// Maybe it'd be good to move this to matrix-js-sdk? Our testing needs are
|
||||
// rather simple, but if one util to mock a member is good enough for us, maybe
|
||||
// it's useful for matrix-js-sdk consumers in general.
|
||||
export function mockMatrixRoomMember(member: Partial<RoomMember>): RoomMember {
|
||||
return { ...mockEmitter(), ...member } as RoomMember;
|
||||
export function mockMatrixRoomMember(
|
||||
rtcMembership: CallMembership,
|
||||
member: Partial<RoomMember> = {},
|
||||
): RoomMember {
|
||||
return {
|
||||
...mockEmitter(),
|
||||
userId: rtcMembership.sender,
|
||||
...member,
|
||||
} as RoomMember;
|
||||
}
|
||||
|
||||
export function mockMatrixRoom(room: Partial<MatrixRoom>): MatrixRoom {
|
||||
@@ -174,14 +216,15 @@ export function mockLocalParticipant(
|
||||
}
|
||||
|
||||
export async function withLocalMedia(
|
||||
member: Partial<RoomMember>,
|
||||
localRtcMember: CallMembership,
|
||||
roomMember: Partial<RoomMember>,
|
||||
continuation: (vm: LocalUserMediaViewModel) => void | Promise<void>,
|
||||
): Promise<void> {
|
||||
const localParticipant = mockLocalParticipant({});
|
||||
const vm = new LocalUserMediaViewModel(
|
||||
"local",
|
||||
mockMatrixRoomMember(member),
|
||||
localParticipant,
|
||||
mockMatrixRoomMember(localRtcMember, roomMember),
|
||||
of(localParticipant),
|
||||
{
|
||||
kind: E2eeType.PER_PARTICIPANT,
|
||||
},
|
||||
@@ -208,15 +251,16 @@ export function mockRemoteParticipant(
|
||||
}
|
||||
|
||||
export async function withRemoteMedia(
|
||||
member: Partial<RoomMember>,
|
||||
localRtcMember: CallMembership,
|
||||
roomMember: Partial<RoomMember>,
|
||||
participant: Partial<RemoteParticipant>,
|
||||
continuation: (vm: RemoteUserMediaViewModel) => void | Promise<void>,
|
||||
): Promise<void> {
|
||||
const remoteParticipant = mockRemoteParticipant(participant);
|
||||
const vm = new RemoteUserMediaViewModel(
|
||||
"remote",
|
||||
mockMatrixRoomMember(member),
|
||||
remoteParticipant,
|
||||
mockMatrixRoomMember(localRtcMember, roomMember),
|
||||
of(remoteParticipant),
|
||||
{
|
||||
kind: E2eeType.PER_PARTICIPANT,
|
||||
},
|
||||
@@ -244,3 +288,30 @@ export function mockMediaPlay(): string[] {
|
||||
};
|
||||
return audioIsPlaying;
|
||||
}
|
||||
|
||||
export class MockRTCSession extends TypedEventEmitter<
|
||||
MatrixRTCSessionEvent,
|
||||
MatrixRTCSessionEventHandlerMap
|
||||
> {
|
||||
public constructor(
|
||||
public readonly room: Room,
|
||||
private localMembership: CallMembership,
|
||||
public memberships: CallMembership[] = [],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public withMemberships(
|
||||
rtcMembers: Observable<Partial<CallMembership>[]>,
|
||||
): MockRTCSession {
|
||||
rtcMembers.subscribe((m) => {
|
||||
const old = this.memberships;
|
||||
// always prepend the local participant
|
||||
const updated = [this.localMembership, ...(m as CallMembership[])];
|
||||
this.memberships = updated;
|
||||
this.emit(MatrixRTCSessionEvent.MembershipsChanged, old, updated);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user