start moving over/removing things from the CallViewModel
This commit is contained in:
@@ -19,84 +19,116 @@ const ownMembership$ = (
|
||||
connected: Behavior<boolean>;
|
||||
transport: Behavior<LivekitTransport | null>;
|
||||
} => {
|
||||
const userId = this.matrixRoom.client.getUserId()!;
|
||||
const deviceId = this.matrixRoom.client.getDeviceId()!;
|
||||
|
||||
const connection = connectionManager.registerTransports(
|
||||
constant([transport]),
|
||||
);
|
||||
const publisher = new Publisher(connection);
|
||||
|
||||
// HOW IT WAS PREVIEOUSLY CREATED
|
||||
// new PublishConnection(
|
||||
// {
|
||||
// transport,
|
||||
// client: this.matrixRoom.client,
|
||||
// scope,
|
||||
// remoteTransports$: this.remoteTransports$,
|
||||
// livekitRoomFactory: this.options.livekitRoomFactory,
|
||||
// },
|
||||
// this.mediaDevices,
|
||||
// this.muteStates,
|
||||
// this.e2eeLivekitOptions(),
|
||||
// this.scope.behavior(this.trackProcessorState$),
|
||||
// ),
|
||||
/**
|
||||
* Lists the transports used by ourselves, plus all other MatrixRTC session
|
||||
* members. For completeness this also lists the preferred transport and
|
||||
* whether we are in multi-SFU mode or sticky events mode (because
|
||||
* advertisedTransport$ wants to read them at the same time, and bundling data
|
||||
* together when it might change together is what you have to do in RxJS to
|
||||
* avoid reading inconsistent state or observing too many changes.)
|
||||
* The transport that we would personally prefer to publish on (if not for the
|
||||
* transport preferences of others, perhaps).
|
||||
*/
|
||||
// TODO-MULTI-SFU find a better name for this. With the addition of sticky events it's no longer just about transports.
|
||||
// DISCUSS move to MatrixLivekitMerger
|
||||
const transport$: Behavior<{
|
||||
local: Async<LivekitTransport>;
|
||||
preferred: Async<LivekitTransport>;
|
||||
// DISCUSS move to ownMembership
|
||||
private readonly preferredTransport$ = this.scope.behavior(
|
||||
async$(makeTransport(this.matrixRTCSession)),
|
||||
);
|
||||
|
||||
/**
|
||||
* The transport over which we should be actively publishing our media.
|
||||
* null when not joined.
|
||||
*/
|
||||
// DISCUSSION ownMembershipManager
|
||||
private readonly localTransport$: Behavior<Async<LivekitTransport> | null> =
|
||||
this.scope.behavior(
|
||||
this.transports$.pipe(
|
||||
map((transports) => transports?.local ?? null),
|
||||
distinctUntilChanged<Async<LivekitTransport> | null>(deepCompare),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* The transport we should advertise in our MatrixRTC membership (plus whether
|
||||
* it is a multi-SFU transport and whether we should use sticky events).
|
||||
*/
|
||||
// DISCUSSION ownMembershipManager
|
||||
private readonly advertisedTransport$: Behavior<{
|
||||
multiSfu: boolean;
|
||||
preferStickyEvents: boolean;
|
||||
transport: LivekitTransport;
|
||||
} | null> = this.scope.behavior(
|
||||
this.joined$.pipe(
|
||||
switchMap((joined) =>
|
||||
joined
|
||||
? combineLatest(
|
||||
[
|
||||
this.preferredTransport$,
|
||||
this.memberships$,
|
||||
multiSfu.value$,
|
||||
preferStickyEvents.value$,
|
||||
],
|
||||
(preferred, memberships, preferMultiSfu, preferStickyEvents) => {
|
||||
// Multi-SFU must be implicitly enabled when using sticky events
|
||||
const multiSfu = preferStickyEvents || preferMultiSfu;
|
||||
this.transports$.pipe(
|
||||
map((transports) =>
|
||||
transports?.local.state === "ready" &&
|
||||
transports.preferred.state === "ready"
|
||||
? {
|
||||
multiSfu: transports.multiSfu,
|
||||
preferStickyEvents: transports.preferStickyEvents,
|
||||
// In non-multi-SFU mode we should always advertise the preferred
|
||||
// SFU to minimize the number of membership updates
|
||||
transport: transports.multiSfu
|
||||
? transports.local.value
|
||||
: transports.preferred.value,
|
||||
}
|
||||
: null,
|
||||
),
|
||||
distinctUntilChanged<{
|
||||
multiSfu: boolean;
|
||||
preferStickyEvents: boolean;
|
||||
transport: LivekitTransport;
|
||||
} | null>(deepCompare),
|
||||
),
|
||||
);
|
||||
|
||||
const oldestMembership =
|
||||
this.matrixRTCSession.getOldestMembership();
|
||||
const remote = memberships.flatMap((m) => {
|
||||
if (m.userId === this.userId && m.deviceId === this.deviceId)
|
||||
return [];
|
||||
const t = m.getTransport(oldestMembership ?? m);
|
||||
return t && isLivekitTransport(t)
|
||||
? [{ membership: m, transport: t }]
|
||||
: [];
|
||||
});
|
||||
|
||||
let local = preferred;
|
||||
if (!multiSfu) {
|
||||
const oldest = this.matrixRTCSession.getOldestMembership();
|
||||
if (oldest !== undefined) {
|
||||
const selection = oldest.getTransport(oldest);
|
||||
// TODO selection can be null if no transport is configured should we report an error?
|
||||
if (selection && isLivekitTransport(selection))
|
||||
local = ready(selection);
|
||||
}
|
||||
}
|
||||
|
||||
if (local.state === "error") {
|
||||
this._configError$.next(
|
||||
local.value instanceof ElementCallError
|
||||
? local.value
|
||||
: new UnknownCallError(local.value),
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
local,
|
||||
remote,
|
||||
preferred,
|
||||
multiSfu,
|
||||
preferStickyEvents,
|
||||
};
|
||||
},
|
||||
)
|
||||
: of(null),
|
||||
// MATRIX RELATED
|
||||
//
|
||||
/**
|
||||
* Whether we are "fully" connected to the call. Accounts for both the
|
||||
* connection to the MatrixRTC session and the LiveKit publish connection.
|
||||
*/
|
||||
// DISCUSSION own membership manager
|
||||
private readonly connected$ = this.scope.behavior(
|
||||
and$(
|
||||
this.matrixConnected$,
|
||||
this.livekitConnectionState$.pipe(
|
||||
map((state) => state === ConnectionState.Connected),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Whether we should tell the user that we're reconnecting to the call.
|
||||
*/
|
||||
// DISCUSSION own membership manager
|
||||
public readonly reconnecting$ = this.scope.behavior(
|
||||
this.connected$.pipe(
|
||||
// We are reconnecting if we previously had some successful initial
|
||||
// connection but are now disconnected
|
||||
scan(
|
||||
({ connectedPreviously }, connectedNow) => ({
|
||||
connectedPreviously: connectedPreviously || connectedNow,
|
||||
reconnecting: connectedPreviously && !connectedNow,
|
||||
}),
|
||||
{ connectedPreviously: false, reconnecting: false },
|
||||
),
|
||||
map(({ reconnecting }) => reconnecting),
|
||||
),
|
||||
);
|
||||
return { connected: true, transport$ };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user