diff --git a/src/room/PTTCallView.jsx b/src/room/PTTCallView.jsx index 0893da4a..517b9e68 100644 --- a/src/room/PTTCallView.jsx +++ b/src/room/PTTCallView.jsx @@ -32,6 +32,7 @@ import { Timer } from "./Timer"; import { Toggle } from "../input/Toggle"; import { getAvatarUrl } from "../matrix-utils"; import { ReactComponent as AudioIcon } from "../icons/Audio.svg"; +import { OtherUserSpeakingError } from "matrix-js-sdk/src/webrtc/groupCall"; export function PTTCallView({ client, @@ -63,12 +64,14 @@ export function PTTCallView({ activeSpeakerUserId, startTalking, stopTalking, + unmuteError, } = usePTT(client, groupCall, userMediaFeeds); + const showTalkOverError = + pttButtonHeld && unmuteError instanceof OtherUserSpeakingError; + const activeSpeakerIsLocalUser = activeSpeakerUserId && client.getUserId() === activeSpeakerUserId; - const showTalkOverError = - pttButtonHeld && !activeSpeakerIsLocalUser && !talkOverEnabled; const activeSpeakerUser = activeSpeakerUserId ? client.getUser(activeSpeakerUserId) : null; @@ -139,7 +142,7 @@ export function PTTCallView({

{showTalkOverError ? "You can't talk at the same time" - : pttButtonHeld + : pttButtonHeld && activeSpeakerIsLocalUser ? "Release spacebar key to stop" : talkOverEnabled && activeSpeakerUserId && diff --git a/src/room/usePTT.js b/src/room/usePTT.js index f1889d24..c3c2f76e 100644 --- a/src/room/usePTT.js +++ b/src/room/usePTT.js @@ -18,7 +18,13 @@ import { useCallback, useEffect, useState } from "react"; export function usePTT(client, groupCall, userMediaFeeds) { const [ - { pttButtonHeld, isAdmin, talkOverEnabled, activeSpeakerUserId }, + { + pttButtonHeld, + isAdmin, + talkOverEnabled, + activeSpeakerUserId, + unmuteError, + }, setState, ] = useState(() => { const roomMember = groupCall.room.getMember(client.getUserId()); @@ -30,6 +36,7 @@ export function usePTT(client, groupCall, userMediaFeeds) { talkOverEnabled: false, pttButtonHeld: false, activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null, + unmuteError: null, }; }); @@ -63,22 +70,29 @@ export function usePTT(client, groupCall, userMediaFeeds) { }; }, [userMediaFeeds]); - const startTalking = useCallback(() => { + const startTalking = useCallback(async () => { + setState((prevState) => ({ + ...prevState, + pttButtonHeld: true, + unmuteError: null, + })); if (!activeSpeakerUserId || isAdmin || talkOverEnabled) { if (groupCall.isMicrophoneMuted()) { - groupCall.setMicrophoneMuted(false); + try { + await groupCall.setMicrophoneMuted(false); + } catch (e) { + setState((prevState) => ({ ...prevState, unmuteError: null })); + } } - - setState((prevState) => ({ ...prevState, pttButtonHeld: true })); } - }, []); + }, [setState]); const stopTalking = useCallback(() => { + setState((prevState) => ({ ...prevState, pttButtonHeld: false })); + if (!groupCall.isMicrophoneMuted()) { groupCall.setMicrophoneMuted(true); } - - setState((prevState) => ({ ...prevState, pttButtonHeld: false })); }, []); useEffect(() => { @@ -86,6 +100,8 @@ export function usePTT(client, groupCall, userMediaFeeds) { if (event.code === "Space") { event.preventDefault(); + if (pttButtonHeld) return; + startTalking(); } } @@ -116,7 +132,7 @@ export function usePTT(client, groupCall, userMediaFeeds) { window.removeEventListener("keyup", onKeyUp); window.removeEventListener("blur", onBlur); }; - }, [activeSpeakerUserId, isAdmin, talkOverEnabled]); + }, [activeSpeakerUserId, isAdmin, talkOverEnabled, pttButtonHeld]); const setTalkOverEnabled = useCallback((talkOverEnabled) => { setState((prevState) => ({ @@ -133,5 +149,6 @@ export function usePTT(client, groupCall, userMediaFeeds) { activeSpeakerUserId, startTalking, stopTalking, + unmuteError, }; }