Unify LiveKit and Matrix connection states

This commit is contained in:
Timo K
2025-12-02 19:40:08 +01:00
parent f05d4b158e
commit 2e646bfac1
10 changed files with 238 additions and 233 deletions

View File

@@ -452,18 +452,14 @@ export function createCallViewModel$(
const localMembership = createLocalMembership$({
scope: scope,
homeserverConnected$: createHomeserverConnected$(
homeserverConnected: createHomeserverConnected$(
scope,
client,
matrixRTCSession,
),
muteStates: muteStates,
joinMatrixRTC: async (transport: LivekitTransport) => {
return enterRTCSession(
matrixRTCSession,
transport,
connectOptions$.value,
);
joinMatrixRTC: (transport: LivekitTransport) => {
enterRTCSession(matrixRTCSession, transport, connectOptions$.value);
},
createPublisherFactory: (connection: Connection) => {
return new Publisher(
@@ -573,17 +569,6 @@ export function createCallViewModel$(
),
);
/**
* Whether various media/event sources should pretend to be disconnected from
* all network input, even if their connection still technically works.
*/
// We do this when the app is in the 'reconnecting' state, because it might be
// that the LiveKit connection is still functional while the homeserver is
// down, for example, and we want to avoid making people worry that the app is
// in a split-brained state.
// DISCUSSION own membership manager ALSO this probably can be simplifis
const reconnecting$ = localMembership.reconnecting$;
const audioParticipants$ = scope.behavior(
matrixLivekitMembers$.pipe(
switchMap((membersWithEpoch) => {
@@ -631,7 +616,7 @@ export function createCallViewModel$(
);
const handsRaised$ = scope.behavior(
handsRaisedSubject$.pipe(pauseWhen(reconnecting$)),
handsRaisedSubject$.pipe(pauseWhen(localMembership.reconnecting$)),
);
const reactions$ = scope.behavior(
@@ -644,7 +629,7 @@ export function createCallViewModel$(
]),
),
),
pauseWhen(reconnecting$),
pauseWhen(localMembership.reconnecting$),
),
);
@@ -735,7 +720,7 @@ export function createCallViewModel$(
livekitRoom$,
focusUrl$,
mediaDevices,
reconnecting$,
localMembership.reconnecting$,
displayName$,
matrixMemberMetadataStore.createAvatarUrlBehavior$(userId),
handsRaised$.pipe(map((v) => v[participantId]?.time ?? null)),
@@ -827,11 +812,17 @@ export function createCallViewModel$(
}),
);
const leave$: Observable<"user" | "timeout" | "decline" | "allOthersLeft"> =
merge(
autoLeave$,
merge(userHangup$, widgetHangup$).pipe(map(() => "user" as const)),
).pipe(scope.share);
const shouldLeave$: Observable<
"user" | "timeout" | "decline" | "allOthersLeft"
> = merge(
autoLeave$,
merge(userHangup$, widgetHangup$).pipe(map(() => "user" as const)),
).pipe(scope.share);
shouldLeave$.pipe(scope.bind()).subscribe((reason) => {
logger.info(`Call left due to ${reason}`);
localMembership.requestDisconnect();
});
const spotlightSpeaker$ = scope.behavior<UserMediaViewModel | null>(
userMedia$.pipe(
@@ -1453,7 +1444,7 @@ export function createCallViewModel$(
autoLeave$: autoLeave$,
callPickupState$: callPickupState$,
ringOverlay$: ringOverlay$,
leave$: leave$,
leave$: shouldLeave$,
hangup: (): void => userHangup$.next(),
join: localMembership.requestConnect,
toggleScreenSharing: toggleScreenSharing,
@@ -1500,7 +1491,7 @@ export function createCallViewModel$(
showFooter$: showFooter$,
earpieceMode$: earpieceMode$,
audioOutputSwitcher$: audioOutputSwitcher$,
reconnecting$: reconnecting$,
reconnecting$: localMembership.reconnecting$,
};
}