Port GroupCallView to useAudioContext

This commit is contained in:
Half-Shot
2024-12-05 11:04:12 +00:00
parent 2336046539
commit 2f393d09ab

View File

@@ -41,9 +41,9 @@ import { InviteModal } from "./InviteModal";
import { useUrlParams } from "../UrlParams"; import { useUrlParams } from "../UrlParams";
import { E2eeType } from "../e2ee/e2eeType"; import { E2eeType } from "../e2ee/e2eeType";
import { Link } from "../button/Link"; import { Link } from "../button/Link";
import { useAudioContext } from "../useAudioContext";
import leftCallSoundMp3 from "../sound/left_call.mp3"; import { CallEventAudioSounds } from "./CallEventAudioRenderer";
import leftCallSoundOgg from "../sound/left_call.ogg"; import { useLatest } from "../useLatest";
declare global { declare global {
interface Window { interface Window {
@@ -74,23 +74,12 @@ export const GroupCallView: FC<Props> = ({
}) => { }) => {
const memberships = useMatrixRTCSessionMemberships(rtcSession); const memberships = useMatrixRTCSessionMemberships(rtcSession);
const isJoined = useMatrixRTCSessionJoinState(rtcSession); const isJoined = useMatrixRTCSessionJoinState(rtcSession);
const leaveSoundContext = useLatest(
// Only used in widget mode. useAudioContext({
const leaveSound = useRef<HTMLAudioElement|null>(null); sounds: CallEventAudioSounds,
const playLeaveSound = useCallback(async () => { latencyHint: "interactive",
if (!leaveSound.current) { }),
return; );
}
const ended = new Promise<void>(r => {
leaveSound.current?.addEventListener("ended", () => r());
});
console.log('Playing');
await leaveSound.current.play();
console.log('started playing');
await ended;
console.log('ended');
}, [leaveSound]);
// This should use `useEffectEvent` (only available in experimental versions) // This should use `useEffectEvent` (only available in experimental versions)
useEffect(() => { useEffect(() => {
if (memberships.length >= MUTE_PARTICIPANT_COUNT) if (memberships.length >= MUTE_PARTICIPANT_COUNT)
@@ -233,10 +222,11 @@ export const GroupCallView: FC<Props> = ({
const onLeave = useCallback( const onLeave = useCallback(
(leaveError?: Error): void => { (leaveError?: Error): void => {
const audioPromise = leaveSoundContext.current?.playSound("left");
// In embedded/widget mode the iFrame will be killed right after the call ended prohibiting the posthog event from getting sent, // In embedded/widget mode the iFrame will be killed right after the call ended prohibiting the posthog event from getting sent,
// therefore we want the event to be sent instantly without getting queued/batched. // therefore we want the event to be sent instantly without getting queued/batched.
const sendInstantly = !!widget; const sendInstantly = !!widget;
console.log('hangup!', sendInstantly); console.log("hangup!", sendInstantly);
setLeaveError(leaveError); setLeaveError(leaveError);
PosthogAnalytics.instance.eventCallEnded.track( PosthogAnalytics.instance.eventCallEnded.track(
rtcSession.room.roomId, rtcSession.room.roomId,
@@ -245,24 +235,27 @@ export const GroupCallView: FC<Props> = ({
rtcSession, rtcSession,
); );
// Wait for the sound in widget mode (it's not long) leaveRTCSession(
leaveRTCSession(rtcSession, sendInstantly ? playLeaveSound() : undefined) rtcSession,
// Only sends matrix leave event. The Livekit session will disconnect once the ActiveCall-view unmounts. // Wait for the sound in widget mode (it's not long)
.then(() => { sendInstantly && audioPromise ? audioPromise : undefined,
setLeft(true); )
if ( // Only sends matrix leave event. The Livekit session will disconnect once the ActiveCall-view unmounts.
!isPasswordlessUser && .then(() => {
!confineToRoom && setLeft(true);
!PosthogAnalytics.instance.isEnabled() if (
) { !isPasswordlessUser &&
history.push("/"); !confineToRoom &&
} !PosthogAnalytics.instance.isEnabled()
}) ) {
.catch((e) => { history.push("/");
logger.error("Error leaving RTC session", e); }
}); })
.catch((e) => {
logger.error("Error leaving RTC session", e);
});
}, },
[rtcSession, isPasswordlessUser, confineToRoom, history], [rtcSession, isPasswordlessUser, confineToRoom, leaveSoundContext, history],
); );
useEffect(() => { useEffect(() => {
@@ -328,14 +321,6 @@ export const GroupCallView: FC<Props> = ({
onDismiss={onDismissInviteModal} onDismiss={onDismissInviteModal}
/> />
); );
const callEndedAudio = <audio
ref={leaveSound}
preload="auto"
hidden
>
<source src={leftCallSoundOgg} type="audio/ogg; codecs=vorbis" />
<source src={leftCallSoundMp3} type="audio/mpeg" />
</audio>;
const lobbyView = ( const lobbyView = (
<> <>
{shareModal} {shareModal}
@@ -349,7 +334,6 @@ export const GroupCallView: FC<Props> = ({
participantCount={participantCount} participantCount={participantCount}
onShareClick={onShareClick} onShareClick={onShareClick}
/> />
{callEndedAudio}
</> </>
); );
@@ -369,7 +353,6 @@ export const GroupCallView: FC<Props> = ({
//otelGroupCallMembership={otelGroupCallMembership} //otelGroupCallMembership={otelGroupCallMembership}
onShareClick={onShareClick} onShareClick={onShareClick}
/> />
{callEndedAudio}
</> </>
); );
} else if (left && widget === null) { } else if (left && widget === null) {
@@ -395,13 +378,8 @@ export const GroupCallView: FC<Props> = ({
confineToRoom={confineToRoom} confineToRoom={confineToRoom}
leaveError={leaveError} leaveError={leaveError}
reconnect={onReconnect} reconnect={onReconnect}
/><audio />
autoPlay ;
hidden
>
<source src={leftCallSoundOgg} type="audio/ogg; codecs=vorbis" />
<source src={leftCallSoundMp3} type="audio/mpeg" />
</audio>;
</> </>
); );
} else { } else {
@@ -413,7 +391,7 @@ export const GroupCallView: FC<Props> = ({
} else if (left && widget !== null) { } else if (left && widget !== null) {
// Left in widget mode: // Left in widget mode:
if (!returnToLobby) { if (!returnToLobby) {
return callEndedAudio; return null;
} }
} else if (preload || skipLobby) { } else if (preload || skipLobby) {
return null; return null;