From d87c3293c91b3039dee9fb145a5df2e91a0e9ae5 Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 18 Feb 2026 13:44:20 +0100 Subject: [PATCH 1/3] Make one-on-one layout media types stricter --- src/state/layout-types.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/state/layout-types.ts b/src/state/layout-types.ts index 3796715c..f32869df 100644 --- a/src/state/layout-types.ts +++ b/src/state/layout-types.ts @@ -10,6 +10,8 @@ import { type SpotlightTileViewModel, } from "./TileViewModel.ts"; import { + type LocalUserMediaViewModel, + type RemoteUserMediaViewModel, type MediaViewModel, type UserMediaViewModel, } from "./MediaViewModel.ts"; @@ -40,8 +42,8 @@ export interface SpotlightExpandedLayoutMedia { export interface OneOnOneLayoutMedia { type: "one-on-one"; - local: UserMediaViewModel; - remote: UserMediaViewModel; + local: LocalUserMediaViewModel; + remote: RemoteUserMediaViewModel; } export interface PipLayoutMedia { From 9d3712567757b9c2e938f91d89e5413f8e1eab65 Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 18 Feb 2026 13:46:18 +0100 Subject: [PATCH 2/3] Only expose RTC backend identity debug info where we actually use it We only ever inspect the RTC backend identity of user media tiles. So it only needs to be exposed on the user media view model. --- src/state/MediaViewModel.ts | 9 ++++----- src/state/ScreenShare.ts | 2 -- src/state/UserMedia.ts | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/state/MediaViewModel.ts b/src/state/MediaViewModel.ts index 3da69c46..87288424 100644 --- a/src/state/MediaViewModel.ts +++ b/src/state/MediaViewModel.ts @@ -257,7 +257,6 @@ abstract class BaseMediaViewModel { * The Matrix user to which this media belongs. */ public readonly userId: string, - public readonly rtcBackendIdentity: string, // We don't necessarily have a participant if a user connects via MatrixRTC but not (yet) through // livekit. protected readonly participant$: Observable< @@ -407,7 +406,10 @@ abstract class BaseUserMediaViewModel extends BaseMediaViewModel { scope: ObservableScope, id: string, userId: string, - rtcBackendIdentity: string, + /** + * The expected identity of the LiveKit participant. Exposed for debugging. + */ + public readonly rtcBackendIdentity: string, participant$: Observable, encryptionSystem: EncryptionSystem, livekitRoom$: Behavior, @@ -421,7 +423,6 @@ abstract class BaseUserMediaViewModel extends BaseMediaViewModel { scope, id, userId, - rtcBackendIdentity, participant$, encryptionSystem, Track.Source.Microphone, @@ -779,7 +780,6 @@ export class ScreenShareViewModel extends BaseMediaViewModel { scope: ObservableScope, id: string, userId: string, - rtcBackendIdentity: string, participant$: Observable, encryptionSystem: EncryptionSystem, livekitRoom$: Behavior, @@ -793,7 +793,6 @@ export class ScreenShareViewModel extends BaseMediaViewModel { scope, id, userId, - rtcBackendIdentity, participant$, encryptionSystem, Track.Source.ScreenShareAudio, diff --git a/src/state/ScreenShare.ts b/src/state/ScreenShare.ts index e4f5de1f..0a241cdf 100644 --- a/src/state/ScreenShare.ts +++ b/src/state/ScreenShare.ts @@ -28,7 +28,6 @@ export class ScreenShare { private readonly scope: ObservableScope, id: string, userId: string, - rtcBackendIdentity: string, participant: LocalParticipant | RemoteParticipant, encryptionSystem: EncryptionSystem, livekitRoom$: Behavior, @@ -41,7 +40,6 @@ export class ScreenShare { this.scope, id, userId, - rtcBackendIdentity, of(participant), encryptionSystem, livekitRoom$, diff --git a/src/state/UserMedia.ts b/src/state/UserMedia.ts index 74d24e2f..2adc9134 100644 --- a/src/state/UserMedia.ts +++ b/src/state/UserMedia.ts @@ -143,7 +143,6 @@ export class UserMedia { scope, `${this.id}:${key}`, this.userId, - this.rtcBackendIdentity, p, this.encryptionSystem, this.livekitRoom$, From bc238778ad2461c53fd938156845bba5fe500d90 Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 18 Feb 2026 14:01:55 +0100 Subject: [PATCH 3/3] Make the type of participant$ stricter It is, in fact, required to be a behavior. --- src/state/MediaViewModel.ts | 8 ++++---- src/state/ScreenShare.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/state/MediaViewModel.ts b/src/state/MediaViewModel.ts index 87288424..7f806697 100644 --- a/src/state/MediaViewModel.ts +++ b/src/state/MediaViewModel.ts @@ -259,7 +259,7 @@ abstract class BaseMediaViewModel { public readonly userId: string, // We don't necessarily have a participant if a user connects via MatrixRTC but not (yet) through // livekit. - protected readonly participant$: Observable< + protected readonly participant$: Behavior< LocalParticipant | RemoteParticipant | null >, @@ -410,7 +410,7 @@ abstract class BaseUserMediaViewModel extends BaseMediaViewModel { * The expected identity of the LiveKit participant. Exposed for debugging. */ public readonly rtcBackendIdentity: string, - participant$: Observable, + participant$: Behavior, encryptionSystem: EncryptionSystem, livekitRoom$: Behavior, focusUrl$: Behavior, @@ -678,7 +678,7 @@ export class RemoteUserMediaViewModel extends BaseUserMediaViewModel { id: string, userId: string, rtcBackendIdentity: string, - participant$: Observable, + participant$: Behavior, encryptionSystem: EncryptionSystem, livekitRoom$: Behavior, focusUrl$: Behavior, @@ -780,7 +780,7 @@ export class ScreenShareViewModel extends BaseMediaViewModel { scope: ObservableScope, id: string, userId: string, - participant$: Observable, + participant$: Behavior, encryptionSystem: EncryptionSystem, livekitRoom$: Behavior, focusUrl$: Behavior, diff --git a/src/state/ScreenShare.ts b/src/state/ScreenShare.ts index 0a241cdf..6c908b1f 100644 --- a/src/state/ScreenShare.ts +++ b/src/state/ScreenShare.ts @@ -4,7 +4,7 @@ Copyright 2025 New Vector Ltd. SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { of } from "rxjs"; + import { type LocalParticipant, type RemoteParticipant, @@ -14,7 +14,7 @@ import { import { type ObservableScope } from "./ObservableScope.ts"; import { ScreenShareViewModel } from "./MediaViewModel.ts"; import type { EncryptionSystem } from "../e2ee/sharedKeyManagement.ts"; -import type { Behavior } from "./Behavior.ts"; +import { constant, type Behavior } from "./Behavior.ts"; /** * A screen share media item to be presented in a tile. This is a thin wrapper @@ -40,7 +40,7 @@ export class ScreenShare { this.scope, id, userId, - of(participant), + constant(participant), encryptionSystem, livekitRoom$, focusUrl$,