Stop connections on view model destroy

This commit is contained in:
Robin
2025-09-26 13:20:55 -04:00
parent 0759f9b27d
commit dbdf853d55
3 changed files with 21 additions and 9 deletions

View File

@@ -359,7 +359,6 @@ class UserMedia {
public destroy(): void { public destroy(): void {
this.scope.end(); this.scope.end();
this.vm.destroy(); this.vm.destroy();
} }
} }

View File

@@ -55,6 +55,7 @@ export class Connection {
} }
public stop(): void { public stop(): void {
if (this.stopped) return;
void this.livekitRoom.disconnect(); void this.livekitRoom.disconnect();
this.stopped = true; this.stopped = true;
} }
@@ -117,6 +118,8 @@ export class Connection {
this.connectionState$ = this.scope.behavior<ConnectionState>( this.connectionState$ = this.scope.behavior<ConnectionState>(
connectionStateObserver(this.livekitRoom), connectionStateObserver(this.livekitRoom),
); );
this.scope.onEnd(() => this.stop());
} }
} }
@@ -137,11 +140,6 @@ export class PublishConnection extends Connection {
} }
} }
public stop(): void {
void this.livekitRoom.disconnect();
this.stopped = true;
}
public constructor( public constructor(
focus: LivekitFocus, focus: LivekitFocus,
livekitAlias: string, livekitAlias: string,
@@ -220,7 +218,10 @@ export class PublishConnection extends Connection {
} }
return this.livekitRoom.localParticipant.isCameraEnabled; return this.livekitRoom.localParticipant.isCameraEnabled;
}); });
// TODO-MULTI-SFU: Unset mute state handlers on destroy this.scope.onEnd(() => {
this.muteStates.audio.unsetHandler();
this.muteStates.video.unsetHandler();
});
const syncDevice = ( const syncDevice = (
kind: MediaDeviceKind, kind: MediaDeviceKind,

View File

@@ -36,11 +36,16 @@ export class ObservableScope {
return this.bindImpl; return this.bindImpl;
} }
private readonly shareImpl: MonoTypeOperator = share({ resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false }) private readonly shareImpl: MonoTypeOperator = share({
resetOnError: false,
resetOnComplete: false,
resetOnRefCountZero: false,
});
/** /**
* Shares (multicasts) the Observable as a hot Observable. * Shares (multicasts) the Observable as a hot Observable.
*/ */
public readonly share: MonoTypeOperator = (input$) => input$.pipe(this.bindImpl, this.shareImpl) public readonly share: MonoTypeOperator = (input$) =>
input$.pipe(this.bindImpl, this.shareImpl);
/** /**
* Converts an Observable to a Behavior. If no initial value is specified, the * Converts an Observable to a Behavior. If no initial value is specified, the
@@ -76,6 +81,13 @@ export class ObservableScope {
this.ended$.next(); this.ended$.next();
this.ended$.complete(); this.ended$.complete();
} }
/**
* Register a callback to be executed when the scope is ended.
*/
public onEnd(callback: () => void): void {
this.ended$.subscribe(callback);
}
} }
/** /**