(
@@ -311,7 +289,7 @@ export function InCallView({
} = useRageshakeRequestModal(groupCall.room.roomId);
const containerClasses = classNames(styles.inRoom, {
- [styles.maximised]: maximisedParticipant,
+ [styles.maximised]: undefined,
});
let footer: JSX.Element | null;
@@ -337,16 +315,14 @@ export function InCallView({
onPress={toggleScreenSharing}
/>
)}
- {!maximisedParticipant && (
-
- )}
+
);
@@ -354,7 +330,7 @@ export function InCallView({
return (
- {!hideHeader && !maximisedParticipant && (
+ {!hideHeader && (
>,
- local: ParticipantID
+ participants: Map>
): TileDescriptor[] {
const sfuParticipants = useParticipants({
room: livekitRoom,
});
- const [localUserId, localDeviceId] = [local.userId, local.deviceId];
-
const items = useMemo(() => {
const tiles: TileDescriptor[] = [];
+
for (const [member, participantMap] of participants) {
for (const [deviceId] of participantMap) {
const id = `${member.userId}:${deviceId}`;
const sfuParticipant = sfuParticipants.find((p) => p.identity === id);
- const hasScreenShare =
- sfuParticipant?.getTrack(Track.Source.ScreenShare) !== undefined;
+ // Skip rendering participants that did not connect to the SFU.
+ if (!sfuParticipant) {
+ continue;
+ }
- const descriptor = {
+ const userMediaTile = {
id,
- focused: hasScreenShare && !sfuParticipant?.isLocal,
- local: member.userId == localUserId && deviceId == localDeviceId,
+ focused: false,
+ local: sfuParticipant.isLocal,
data: {
member,
sfuParticipant,
+ content: TileContent.UserMedia,
},
};
- tiles.push(descriptor);
+ // Add a tile for user media.
+ tiles.push(userMediaTile);
+
+ // If there is a screen sharing enabled for this participant, create a tile for it as well.
+ if (sfuParticipant.isScreenShareEnabled) {
+ const screenShareTile = {
+ ...userMediaTile,
+ id: `${id}:screen-share`,
+ focused: true,
+ data: {
+ ...userMediaTile.data,
+ content: TileContent.ScreenShare,
+ },
+ };
+ tiles.push(screenShareTile);
+ }
}
}
@@ -434,7 +421,7 @@ function useParticipantTiles(
);
return tiles;
- }, [localUserId, localDeviceId, participants, sfuParticipants]);
+ }, [participants, sfuParticipants]);
return items;
}
diff --git a/src/video-grid/VideoTile.tsx b/src/video-grid/VideoTile.tsx
index 4c3838f..0855264 100644
--- a/src/video-grid/VideoTile.tsx
+++ b/src/video-grid/VideoTile.tsx
@@ -29,20 +29,29 @@ import styles from "./VideoTile.module.css";
import { ReactComponent as MicMutedIcon } from "../icons/MicMuted.svg";
import { ReactComponent as VideoMutedIcon } from "../icons/VideoMuted.svg";
+export enum TileContent {
+ UserMedia = "user-media",
+ ScreenShare = "screen-share",
+}
+
interface Props {
- name: string;
avatar?: JSX.Element;
className?: string;
+
+ name: string;
sfuParticipant: LocalParticipant | RemoteParticipant;
+ content: TileContent;
}
export const VideoTile = forwardRef(
- ({ name, avatar, className, sfuParticipant, ...rest }, ref) => {
+ ({ name, avatar, className, sfuParticipant, content, ...rest }, ref) => {
const { t } = useTranslation();
const audioEl = React.useRef(null);
const { isMuted: microphoneMuted } = useMediaTrack(
- Track.Source.Microphone,
+ content === TileContent.UserMedia
+ ? Track.Source.Microphone
+ : Track.Source.ScreenShareAudio,
sfuParticipant,
{
element: audioEl,
@@ -56,7 +65,6 @@ export const VideoTile = forwardRef(
[styles.speaking]: sfuParticipant.isSpeaking,
[styles.muted]: microphoneMuted,
[styles.screenshare]: false,
- [styles.maximised]: false,
})}
ref={ref}
{...rest}
@@ -80,7 +88,14 @@ export const VideoTile = forwardRef(
))}
-
+
);
diff --git a/src/video-grid/VideoTileContainer.tsx b/src/video-grid/VideoTileContainer.tsx
index 86cceaa..4f2c10e 100644
--- a/src/video-grid/VideoTileContainer.tsx
+++ b/src/video-grid/VideoTileContainer.tsx
@@ -19,11 +19,12 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { LocalParticipant, RemoteParticipant } from "livekit-client";
import { useRoomMemberName } from "./useRoomMemberName";
-import { VideoTile } from "./VideoTile";
+import { TileContent, VideoTile } from "./VideoTile";
export interface ItemData {
member: RoomMember;
- sfuParticipant?: LocalParticipant | RemoteParticipant;
+ sfuParticipant: LocalParticipant | RemoteParticipant;
+ content: TileContent;
}
interface Props {
@@ -35,7 +36,6 @@ interface Props {
width: number,
height: number
) => JSX.Element;
- maximised: boolean;
}
export function VideoTileContainer({
@@ -43,22 +43,19 @@ export function VideoTileContainer({
width,
height,
getAvatar,
- maximised,
...rest
}: Props) {
const { rawDisplayName } = useRoomMemberName(item.member);
return (
<>
- {!item.sfuParticipant && null}
- {item.sfuParticipant && (
-
- )}
+
>
);
}