Merge pull request #3664 from element-hq/toger5/userMedia-alternative

Small refactor: User media alternative
This commit is contained in:
Timo
2026-01-13 17:51:36 +01:00
committed by GitHub
2 changed files with 30 additions and 57 deletions

View File

@@ -124,9 +124,9 @@ import {
} from "./remoteMembers/ConnectionManager.ts";
import {
createMatrixLivekitMembers$,
type TaggedParticipant,
type LocalMatrixLivekitMember,
type RemoteMatrixLivekitMember,
type MatrixLivekitMember,
} from "./remoteMembers/MatrixLivekitMembers.ts";
import {
type AutoLeaveReason,
@@ -717,65 +717,38 @@ export function createCallViewModel$(
matrixLivekitMembers,
duplicateTiles,
]) {
let localUserMediaId: string | undefined = undefined;
// add local member if available
if (localMatrixLivekitMember) {
const computeMediaId = (m: MatrixLivekitMember): string =>
`${m.userId}:${m.membership$.value.deviceId}`;
const localUserMediaId = localMatrixLivekitMember
? computeMediaId(localMatrixLivekitMember)
: undefined;
const localAsArray = localMatrixLivekitMember
? [localMatrixLivekitMember]
: [];
const remoteWithoutLocal = matrixLivekitMembers.value.filter(
(m) => computeMediaId(m) !== localUserMediaId,
);
const allMatrixLivekitMembers = [
...localAsArray,
...remoteWithoutLocal,
];
for (const matrixLivekitMember of allMatrixLivekitMembers) {
const { userId, participant, connection$, membership$ } =
localMatrixLivekitMember;
localUserMediaId = `${userId}:${membership$.value.deviceId}`;
const rtcBackendIdentity = membership$.value.rtcBackendIdentity;
matrixLivekitMember;
const rtcId = membership$.value.rtcBackendIdentity; // rtcBackendIdentity
const mediaId = computeMediaId(matrixLivekitMember);
for (let dup = 0; dup < 1 + duplicateTiles; dup++) {
yield {
keys: [
dup,
localUserMediaId,
userId,
participant satisfies TaggedParticipant as TaggedParticipant, // Widen the type safely
connection$,
rtcBackendIdentity,
],
data: undefined,
};
}
}
// add remote members that are available
for (const {
userId,
participant,
connection$,
membership$,
} of matrixLivekitMembers.value) {
const userMediaId = `${userId}:${membership$.value.deviceId}`;
const rtcBackendIdentity = membership$.value.rtcBackendIdentity;
// skip local user as we added them manually before
if (userMediaId === localUserMediaId) continue;
for (let dup = 0; dup < 1 + duplicateTiles; dup++) {
yield {
keys: [
dup,
userMediaId,
userId,
participant,
connection$,
rtcBackendIdentity,
],
keys: [dup, mediaId, userId, participant, connection$, rtcId],
data: undefined,
};
}
}
},
(
scope,
_data$,
dup,
userMediaId,
userId,
participant,
connection$,
rtcBackendIdentity,
) => {
(scope, _, dup, mediaId, userId, participant, connection$, rtcId) => {
const livekitRoom$ = scope.behavior(
connection$.pipe(map((c) => c?.livekitRoom)),
);
@@ -790,9 +763,9 @@ export function createCallViewModel$(
return new UserMedia(
scope,
`${userMediaId}:${dup}`,
`${mediaId}:${dup}`,
userId,
rtcBackendIdentity,
rtcId,
participant,
options.encryptionSystem,
livekitRoom$,
@@ -801,8 +774,8 @@ export function createCallViewModel$(
localMembership.reconnecting$,
displayName$,
matrixMemberMetadataStore.createAvatarUrlBehavior$(userId),
handsRaised$.pipe(map((v) => v[userMediaId]?.time ?? null)),
reactions$.pipe(map((v) => v[userMediaId] ?? undefined)),
handsRaised$.pipe(map((v) => v[mediaId]?.time ?? null)),
reactions$.pipe(map((v) => v[mediaId] ?? undefined)),
);
},
),

View File

@@ -33,7 +33,7 @@ export type TaggedParticipant =
| LocalTaggedParticipant
| RemoteTaggedParticipant;
interface MatrixLivekitMember {
export interface MatrixLivekitMember {
membership$: Behavior<CallMembership>;
connection$: Behavior<Connection | null>;
// participantId: string; We do not want a participantId here since it will be generated by the jwt