diff --git a/src/room/PTTCallView.jsx b/src/room/PTTCallView.jsx
index 6993ec9..2406d0b 100644
--- a/src/room/PTTCallView.jsx
+++ b/src/room/PTTCallView.jsx
@@ -16,6 +16,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,
@@ -47,21 +48,22 @@ 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;
const activeSpeakerAvatarUrl = activeSpeakerUser
? getAvatarUrl(
- client,
- activeSpeakerUser.avatarUrl,
- pttButtonSize - pttBorderWidth * 2
- )
+ client,
+ activeSpeakerUser.avatarUrl,
+ pttButtonSize - pttBorderWidth * 2
+ )
: null;
const activeSpeakerDisplayName = activeSpeakerUser
? activeSpeakerUser.displayName
@@ -77,9 +79,8 @@ export function PTTCallView({
-
{`${participants.length} ${
- participants.length > 1 ? "people" : "person"
- } connected`}
+
{`${participants.length} ${participants.length > 1 ? "people" : "person"
+ } connected`}
{showTalkOverError
? "You can't talk at the same time"
- : pttButtonHeld
- ? "Release spacebar key to stop"
- : talkOverEnabled &&
- activeSpeakerUserId &&
- !activeSpeakerIsLocalUser
- ? `Press and hold spacebar to talk over ${activeSpeakerDisplayName}`
- : "Press and hold spacebar to talk"}
+ : pttButtonHeld && activeSpeakerIsLocalUser
+ ? "Release spacebar key to stop"
+ : talkOverEnabled &&
+ activeSpeakerUserId &&
+ !activeSpeakerIsLocalUser
+ ? `Press and hold spacebar to talk over ${activeSpeakerDisplayName}`
+ : "Press and hold spacebar to talk"}
{userMediaFeeds.map((callFeed) => (
{
function onMuteStateChanged(...args) {
const activeSpeakerFeed = userMediaFeeds.find((f) => !f.isAudioMuted());
@@ -47,22 +49,26 @@ export function usePTT(client, groupCall, userMediaFeeds) {
};
}, [userMediaFeeds]);
- const startTalking = useCallback(() => {
+ const startTalking = useCallback(async () => {
+ setState((prevState) => ({ ...prevState, pttButtonHeld: true }));
+ setUnmuteError(null);
if (!activeSpeakerUserId || isAdmin || talkOverEnabled) {
if (groupCall.isMicrophoneMuted()) {
- groupCall.setMicrophoneMuted(false);
+ try {
+ await groupCall.setMicrophoneMuted(false);
+ } catch (e) {
+ setUnmuteError(e);
+ }
}
-
- setState((prevState) => ({ ...prevState, pttButtonHeld: true }));
}
- }, []);
+ }, [setUnmuteError]);
const stopTalking = useCallback(() => {
+ setState((prevState) => ({ ...prevState, pttButtonHeld: false }));
+
if (!groupCall.isMicrophoneMuted()) {
groupCall.setMicrophoneMuted(true);
}
-
- setState((prevState) => ({ ...prevState, pttButtonHeld: false }));
}, []);
useEffect(() => {
@@ -70,6 +76,8 @@ export function usePTT(client, groupCall, userMediaFeeds) {
if (event.code === "Space") {
event.preventDefault();
+ if (pttButtonHeld) return;
+
startTalking();
}
}
@@ -100,7 +108,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) => ({
@@ -117,5 +125,6 @@ export function usePTT(client, groupCall, userMediaFeeds) {
activeSpeakerUserId,
startTalking,
stopTalking,
+ unmuteError,
};
}