Don't show user as 'waiting for media' if they don't intend to publish

We don't expect them to be publishing on any transport; they might be a subscribe-only bot.
This commit is contained in:
Robin
2025-12-10 17:17:37 -05:00
parent 93ab3ba1ff
commit ea6f934667
3 changed files with 25 additions and 9 deletions

View File

@@ -226,3 +226,13 @@ test("remote media is not in waiting state when participant is connected with no
); );
expect(vm.waitingForMedia$.value).toBe(false); expect(vm.waitingForMedia$.value).toBe(false);
}); });
test("remote media is not in waiting state when user does not intend to publish anywhere", () => {
const vm = createRemoteMedia(
rtcMembership,
{},
mockRemoteParticipant({}),
undefined, // No room (no advertised transport)
);
expect(vm.waitingForMedia$.value).toBe(false);
});

View File

@@ -601,7 +601,14 @@ export class RemoteUserMediaViewModel extends BaseUserMediaViewModel {
* could be because either we or the remote party are still connecting. * could be because either we or the remote party are still connecting.
*/ */
public readonly waitingForMedia$ = this.scope.behavior<boolean>( public readonly waitingForMedia$ = this.scope.behavior<boolean>(
this.participant$.pipe(map((participant) => participant === null)), combineLatest(
[this.livekitRoom$, this.participant$],
(livekitRoom, participant) =>
// If livekitRoom is undefined, the user is not attempting to publish on
// any transport and so we shouldn't expect a participant. (They might
// be a subscribe-only bot for example.)
livekitRoom !== undefined && participant === null,
),
); );
// This private field is used to override the value from the superclass // This private field is used to override the value from the superclass

View File

@@ -362,6 +362,12 @@ export function createRemoteMedia(
rtcMember: CallMembership, rtcMember: CallMembership,
roomMember: Partial<RoomMember>, roomMember: Partial<RoomMember>,
participant: RemoteParticipant | null, participant: RemoteParticipant | null,
livekitRoom: LivekitRoom | undefined = mockLivekitRoom(
{},
{
remoteParticipants$: of(participant ? [participant] : []),
},
),
): RemoteUserMediaViewModel { ): RemoteUserMediaViewModel {
const member = mockMatrixRoomMember(rtcMember, roomMember); const member = mockMatrixRoomMember(rtcMember, roomMember);
return new RemoteUserMediaViewModel( return new RemoteUserMediaViewModel(
@@ -372,14 +378,7 @@ export function createRemoteMedia(
{ {
kind: E2eeType.PER_PARTICIPANT, kind: E2eeType.PER_PARTICIPANT,
}, },
constant( constant(livekitRoom),
mockLivekitRoom(
{},
{
remoteParticipants$: of(participant ? [participant] : []),
},
),
),
constant("https://rtc-example.org"), constant("https://rtc-example.org"),
constant(false), constant(false),
constant(member.rawDisplayName ?? "nodisplayname"), constant(member.rawDisplayName ?? "nodisplayname"),