Don't show toolbar buttons on connecting tiles
Because connecting tiles don't have a feed, clicking the local volume button would cause a soft crash. This also fixes a few strict mode errors in the surrounding area while we're at it.
This commit is contained in:
parent
7b71e9b20f
commit
84a92845c3
5 changed files with 21 additions and 20 deletions
|
@ -72,7 +72,7 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const toolbarButtons: JSX.Element[] = [];
|
const toolbarButtons: JSX.Element[] = [];
|
||||||
if (!isLocal) {
|
if (hasFeed && !isLocal) {
|
||||||
toolbarButtons.push(
|
toolbarButtons.push(
|
||||||
<AudioButton
|
<AudioButton
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
|
|
|
@ -68,7 +68,7 @@ export function VideoTileContainer({
|
||||||
} = useCallFeed(item.callFeed);
|
} = useCallFeed(item.callFeed);
|
||||||
const { rawDisplayName } = useRoomMemberName(item.member);
|
const { rawDisplayName } = useRoomMemberName(item.member);
|
||||||
const [tileRef, mediaRef] = useSpatialMediaStream(
|
const [tileRef, mediaRef] = useSpatialMediaStream(
|
||||||
stream,
|
stream ?? null,
|
||||||
audioContext,
|
audioContext,
|
||||||
audioDestination,
|
audioDestination,
|
||||||
isLocal,
|
isLocal,
|
||||||
|
@ -109,7 +109,7 @@ export function VideoTileContainer({
|
||||||
onFullscreen={onFullscreenCallback}
|
onFullscreen={onFullscreenCallback}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
{videoTileSettingsModalState.isOpen && !maximised && (
|
{videoTileSettingsModalState.isOpen && !maximised && item.callFeed && (
|
||||||
<VideoTileSettingsModal
|
<VideoTileSettingsModal
|
||||||
{...videoTileSettingsModalProps}
|
{...videoTileSettingsModalProps}
|
||||||
feed={item.callFeed}
|
feed={item.callFeed}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { RefObject, useEffect } from "react";
|
||||||
|
|
||||||
export function useAudioOutputDevice(
|
export function useAudioOutputDevice(
|
||||||
mediaRef: RefObject<MediaElement>,
|
mediaRef: RefObject<MediaElement>,
|
||||||
audioOutputDevice: string
|
audioOutputDevice: string | undefined
|
||||||
): void {
|
): void {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -19,17 +19,18 @@ import { CallFeed, CallFeedEvent } from "matrix-js-sdk/src/webrtc/callFeed";
|
||||||
import { SDPStreamMetadataPurpose } from "matrix-js-sdk/src/webrtc/callEventTypes";
|
import { SDPStreamMetadataPurpose } from "matrix-js-sdk/src/webrtc/callEventTypes";
|
||||||
|
|
||||||
interface CallFeedState {
|
interface CallFeedState {
|
||||||
callFeed: CallFeed;
|
callFeed: CallFeed | undefined;
|
||||||
isLocal: boolean;
|
isLocal: boolean;
|
||||||
speaking: boolean;
|
speaking: boolean;
|
||||||
videoMuted: boolean;
|
videoMuted: boolean;
|
||||||
audioMuted: boolean;
|
audioMuted: boolean;
|
||||||
localVolume: number;
|
localVolume: number;
|
||||||
disposed: boolean;
|
disposed: boolean | undefined;
|
||||||
stream: MediaStream;
|
stream: MediaStream | undefined;
|
||||||
purpose: SDPStreamMetadataPurpose;
|
purpose: SDPStreamMetadataPurpose | undefined;
|
||||||
}
|
}
|
||||||
function getCallFeedState(callFeed: CallFeed): CallFeedState {
|
|
||||||
|
function getCallFeedState(callFeed: CallFeed | undefined): CallFeedState {
|
||||||
return {
|
return {
|
||||||
callFeed,
|
callFeed,
|
||||||
isLocal: callFeed ? callFeed.isLocal() : false,
|
isLocal: callFeed ? callFeed.isLocal() : false,
|
||||||
|
@ -43,7 +44,7 @@ function getCallFeedState(callFeed: CallFeed): CallFeedState {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useCallFeed(callFeed: CallFeed): CallFeedState {
|
export function useCallFeed(callFeed: CallFeed | undefined): CallFeedState {
|
||||||
const [state, setState] = useState<CallFeedState>(() =>
|
const [state, setState] = useState<CallFeedState>(() =>
|
||||||
getCallFeedState(callFeed)
|
getCallFeedState(callFeed)
|
||||||
);
|
);
|
||||||
|
|
|
@ -64,8 +64,8 @@ export const useMediaStreamTrackCount = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useMediaStream = (
|
export const useMediaStream = (
|
||||||
stream: MediaStream,
|
stream: MediaStream | null,
|
||||||
audioOutputDevice: string,
|
audioOutputDevice: string | null,
|
||||||
mute = false,
|
mute = false,
|
||||||
localVolume?: number
|
localVolume?: number
|
||||||
): RefObject<MediaElement> => {
|
): RefObject<MediaElement> => {
|
||||||
|
@ -158,7 +158,7 @@ const createLoopback = async (stream: MediaStream): Promise<MediaStream> => {
|
||||||
await loopbackConn.setRemoteDescription(offer);
|
await loopbackConn.setRemoteDescription(offer);
|
||||||
const answer = await loopbackConn.createAnswer();
|
const answer = await loopbackConn.createAnswer();
|
||||||
// Rewrite SDP to be stereo and (variable) max bitrate
|
// Rewrite SDP to be stereo and (variable) max bitrate
|
||||||
const parsedSdp = parseSdp(answer.sdp);
|
const parsedSdp = parseSdp(answer.sdp!);
|
||||||
parsedSdp.media.forEach((m) =>
|
parsedSdp.media.forEach((m) =>
|
||||||
m.fmtp.forEach(
|
m.fmtp.forEach(
|
||||||
(f) => (f.config += `;stereo=1;cbr=0;maxaveragebitrate=510000;`)
|
(f) => (f.config += `;stereo=1;cbr=0;maxaveragebitrate=510000;`)
|
||||||
|
@ -206,11 +206,11 @@ export const useAudioContext = (): [
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return [context.current, destination.current, audioRef];
|
return [context.current!, destination.current!, audioRef];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSpatialMediaStream = (
|
export const useSpatialMediaStream = (
|
||||||
stream: MediaStream,
|
stream: MediaStream | null,
|
||||||
audioContext: AudioContext,
|
audioContext: AudioContext,
|
||||||
audioDestination: AudioNode,
|
audioDestination: AudioNode,
|
||||||
mute = false,
|
mute = false,
|
||||||
|
@ -219,7 +219,7 @@ export const useSpatialMediaStream = (
|
||||||
const tileRef = useRef<HTMLDivElement>();
|
const tileRef = useRef<HTMLDivElement>();
|
||||||
const [spatialAudio] = useSpatialAudio();
|
const [spatialAudio] = useSpatialAudio();
|
||||||
// We always handle audio separately form the video element
|
// We always handle audio separately form the video element
|
||||||
const mediaRef = useMediaStream(stream, undefined, true, undefined);
|
const mediaRef = useMediaStream(stream, null, true);
|
||||||
const [audioTrackCount] = useMediaStreamTrackCount(stream);
|
const [audioTrackCount] = useMediaStreamTrackCount(stream);
|
||||||
|
|
||||||
const gainNodeRef = useRef<GainNode>();
|
const gainNodeRef = useRef<GainNode>();
|
||||||
|
@ -240,7 +240,7 @@ export const useSpatialMediaStream = (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!sourceRef.current) {
|
if (!sourceRef.current) {
|
||||||
sourceRef.current = audioContext.createMediaStreamSource(stream);
|
sourceRef.current = audioContext.createMediaStreamSource(stream!);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tile = tileRef.current;
|
const tile = tileRef.current;
|
||||||
|
@ -252,12 +252,12 @@ export const useSpatialMediaStream = (
|
||||||
const bounds = tile.getBoundingClientRect();
|
const bounds = tile.getBoundingClientRect();
|
||||||
const windowSize = Math.max(window.innerWidth, window.innerHeight);
|
const windowSize = Math.max(window.innerWidth, window.innerHeight);
|
||||||
// Position the source relative to its placement in the window
|
// Position the source relative to its placement in the window
|
||||||
pannerNodeRef.current.positionX.value =
|
pannerNodeRef.current!.positionX.value =
|
||||||
(bounds.x + bounds.width / 2) / windowSize - 0.5;
|
(bounds.x + bounds.width / 2) / windowSize - 0.5;
|
||||||
pannerNodeRef.current.positionY.value =
|
pannerNodeRef.current!.positionY.value =
|
||||||
(bounds.y + bounds.height / 2) / windowSize - 0.5;
|
(bounds.y + bounds.height / 2) / windowSize - 0.5;
|
||||||
// Put the source in front of the listener
|
// Put the source in front of the listener
|
||||||
pannerNodeRef.current.positionZ.value = -2;
|
pannerNodeRef.current!.positionZ.value = -2;
|
||||||
};
|
};
|
||||||
|
|
||||||
gainNode.gain.value = localVolume;
|
gainNode.gain.value = localVolume;
|
||||||
|
|
Loading…
Add table
Reference in a new issue