From fadc8c4afdd0a248985b07579332e5b42ba3cc9d Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Fri, 12 Sep 2025 15:11:12 +0100 Subject: [PATCH] Ensure leave sound does not play --- src/room/InCallView.tsx | 1 - src/state/CallViewModel.ts | 39 ++++++++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 5417d233..8783c0de 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -117,7 +117,6 @@ import { Avatar, Size as AvatarSize } from "../Avatar"; import waitingStyles from "./WaitingForJoin.module.css"; import { prefetchSounds } from "../soundUtils"; import { useAudioContext } from "../useAudioContext"; - import ringtoneMp3 from "../sound/ringtone.mp3?url"; import ringtoneOgg from "../sound/ringtone.ogg?url"; import declineMp3 from "../sound/call_declined.mp3?url"; diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index 3802d6dd..6ee3de47 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -37,6 +37,7 @@ import { concat, distinctUntilChanged, endWith, + every, filter, forkJoin, fromEvent, @@ -49,6 +50,7 @@ import { race, scan, skip, + skipWhile, startWith, switchAll, switchMap, @@ -853,17 +855,6 @@ export class CallViewModel extends ViewModel { throttleTime(THROTTLE_SOUND_EFFECT_MS), ); - public readonly leaveSoundEffect$ = this.userMedia$.pipe( - pairwise(), - filter( - ([prev, current]) => - current.length <= MAX_PARTICIPANT_COUNT_FOR_SOUND && - current.length < prev.length, - ), - map(() => {}), - throttleTime(THROTTLE_SOUND_EFFECT_MS), - ); - /** * The number of participants currently in the call. * @@ -963,7 +954,9 @@ export class CallViewModel extends ViewModel { * - "success": Someone else joined. The call is in a normal state. No audiovisual feedback. * - null: EC is configured to never show any waiting for answer state. */ - public readonly callPickupState$ = this.options.waitForCallPickup + public readonly callPickupState$: Behavior< + "unknown" | "ringing" | "timeout" | "decline" | "success" | null + > = this.options.waitForCallPickup ? this.scope.behavior< "unknown" | "ringing" | "timeout" | "decline" | "success" >( @@ -983,6 +976,28 @@ export class CallViewModel extends ViewModel { ) : constant(null); + public readonly callWasSuccessful$ = this.callPickupState$.pipe( + every((x) => x !== "success"), + map((v) => !v), + ); + + public readonly leaveSoundEffect$ = combineLatest([ + this.callWasSuccessful$, + this.userMedia$, + ]).pipe( + // Until the call is successful, do not play a leave sound. + skipWhile(([c]) => c === false), + map(([, userMedia]) => userMedia), + pairwise(), + filter( + ([prev, current]) => + current.length <= MAX_PARTICIPANT_COUNT_FOR_SOUND && + current.length < prev.length, + ), + map(() => {}), + throttleTime(THROTTLE_SOUND_EFFECT_MS), + ); + /** * List of MediaItems that we want to display, that are of type ScreenShare */