mirror of
https://github.com/vector-im/element-call.git
synced 2026-02-11 04:27:03 +00:00
Serialize updates to the call intent
So that the value advertised in your membership can't desync from the actual value if you toggle video too fast.
This commit is contained in:
@@ -140,6 +140,7 @@ import {
|
||||
type SpotlightPortraitLayoutMedia,
|
||||
} from "./layout-types.ts";
|
||||
import { ElementCallError, UnknownCallError } from "../utils/errors.ts";
|
||||
import { ObservableScope } from "./ObservableScope.ts";
|
||||
|
||||
export interface CallViewModelOptions {
|
||||
encryptionSystem: EncryptionSystem;
|
||||
@@ -1805,18 +1806,19 @@ export class CallViewModel extends ViewModel {
|
||||
} catch (e) {
|
||||
logger.error("Error entering RTC session", e);
|
||||
}
|
||||
|
||||
// Update our member event when our mute state changes.
|
||||
const muteSubscription = this.muteStates.video.enabled$.subscribe(
|
||||
(videoEnabled) =>
|
||||
// TODO: Ensure that these calls are serialized in case of
|
||||
// fast video toggling
|
||||
void this.matrixRTCSession.updateCallIntent(
|
||||
const intentScope = new ObservableScope();
|
||||
intentScope.reconcile(
|
||||
this.muteStates.video.enabled$,
|
||||
async (videoEnabled) =>
|
||||
this.matrixRTCSession.updateCallIntent(
|
||||
videoEnabled ? "video" : "audio",
|
||||
),
|
||||
);
|
||||
|
||||
return async (): Promise<void> => {
|
||||
muteSubscription.unsubscribe();
|
||||
intentScope.end();
|
||||
// Only sends Matrix leave event. The LiveKit session will disconnect
|
||||
// as soon as either the stopConnection$ handler above gets to it or
|
||||
// the view model is destroyed.
|
||||
|
||||
@@ -114,11 +114,11 @@ export class ObservableScope {
|
||||
*/
|
||||
public reconcile<T>(
|
||||
value$: Behavior<T>,
|
||||
callback: (value: T) => Promise<(() => Promise<void>) | undefined>,
|
||||
callback: (value: T) => Promise<(() => Promise<void>) | void>,
|
||||
): void {
|
||||
let latestValue: T | typeof nothing = nothing;
|
||||
let reconciledValue: T | typeof nothing = nothing;
|
||||
let cleanUp: (() => Promise<void>) | undefined = undefined;
|
||||
let cleanUp: (() => Promise<void>) | void = undefined;
|
||||
value$
|
||||
.pipe(
|
||||
catchError(() => EMPTY), // Ignore errors
|
||||
|
||||
Reference in New Issue
Block a user