diff --git a/src/state/MediaViewModel.test.ts b/src/state/MediaViewModel.test.ts index 2ca14d19..92868216 100644 --- a/src/state/MediaViewModel.test.ts +++ b/src/state/MediaViewModel.test.ts @@ -226,3 +226,13 @@ test("remote media is not in waiting state when participant is connected with no ); 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); +}); diff --git a/src/state/MediaViewModel.ts b/src/state/MediaViewModel.ts index 3d0ff75b..86119caa 100644 --- a/src/state/MediaViewModel.ts +++ b/src/state/MediaViewModel.ts @@ -601,7 +601,14 @@ export class RemoteUserMediaViewModel extends BaseUserMediaViewModel { * could be because either we or the remote party are still connecting. */ public readonly waitingForMedia$ = this.scope.behavior( - 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 diff --git a/src/utils/test.ts b/src/utils/test.ts index c69a2269..b900d801 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -362,6 +362,12 @@ export function createRemoteMedia( rtcMember: CallMembership, roomMember: Partial, participant: RemoteParticipant | null, + livekitRoom: LivekitRoom | undefined = mockLivekitRoom( + {}, + { + remoteParticipants$: of(participant ? [participant] : []), + }, + ), ): RemoteUserMediaViewModel { const member = mockMatrixRoomMember(rtcMember, roomMember); return new RemoteUserMediaViewModel( @@ -372,14 +378,7 @@ export function createRemoteMedia( { kind: E2eeType.PER_PARTICIPANT, }, - constant( - mockLivekitRoom( - {}, - { - remoteParticipants$: of(participant ? [participant] : []), - }, - ), - ), + constant(livekitRoom), constant("https://rtc-example.org"), constant(false), constant(member.rawDisplayName ?? "nodisplayname"),