diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx
index 6382cb8..f921ade 100644
--- a/src/room/InCallView.tsx
+++ b/src/room/InCallView.tsx
@@ -34,7 +34,6 @@ import { useTranslation } from "react-i18next";
import useMeasure from "react-use-measure";
import type { IWidgetApiRequest } from "matrix-widget-api";
-import { Avatar } from "../Avatar";
import {
Header,
LeftNav,
@@ -236,24 +235,6 @@ export function InCallView({
const reducedControls = boundsValid && bounds.width <= 400;
const noControls = reducedControls && bounds.height <= 400;
- const renderAvatar = useCallback(
- (roomMember: RoomMember, width: number, height: number) => {
- const avatarUrl = roomMember.getMxcAvatarUrl();
- const size = Math.round(Math.min(width, height) / 2);
-
- return (
-
- );
- },
- []
- );
-
const prefersReducedMotion = usePrefersReducedMotion();
const items = useParticipantTiles(livekitRoom, participants);
@@ -273,13 +254,7 @@ export function InCallView({
layout={layout}
disableAnimations={prefersReducedMotion || isSafari}
>
- {(child) => (
-
- )}
+ {(child) => }
);
};
@@ -375,17 +350,21 @@ function useParticipantTiles(
});
const items = useMemo(() => {
- const tiles: TileDescriptor[] = [];
+ // The IDs of the participants who published membership event to the room (i.e. are present from Matrix perspective).
+ const matrixParticipants: Map = new Map(
+ [...participants.entries()].flatMap(([user, devicesMap]) => {
+ return [...devicesMap.keys()].map((deviceId) => [
+ `${user.userId}:${deviceId}`,
+ user,
+ ]);
+ })
+ );
- for (const [member, participantMap] of participants) {
- for (const [deviceId] of participantMap) {
- const id = `${member.userId}:${deviceId}`;
- const sfuParticipant = sfuParticipants.find((p) => p.identity === id);
-
- // Skip rendering participants that did not connect to the SFU.
- if (!sfuParticipant) {
- continue;
- }
+ // Iterate over SFU participants (those who actually are present from the SFU perspective) and create tiles for them.
+ const tiles: TileDescriptor[] = sfuParticipants.flatMap(
+ (sfuParticipant) => {
+ const id = sfuParticipant.identity;
+ const member = matrixParticipants.get(id);
const userMediaTile = {
id,
@@ -398,12 +377,10 @@ function useParticipantTiles(
},
};
- // 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.
+ let screenShareTile: TileDescriptor | undefined;
if (sfuParticipant.isScreenShareEnabled) {
- const screenShareTile = {
+ screenShareTile = {
...userMediaTile,
id: `${id}:screen-share`,
focused: true,
@@ -412,10 +389,13 @@ function useParticipantTiles(
content: TileContent.ScreenShare,
},
};
- tiles.push(screenShareTile);
}
+
+ return screenShareTile
+ ? [userMediaTile, screenShareTile]
+ : [userMediaTile];
}
- }
+ );
PosthogAnalytics.instance.eventCallEnded.cacheParticipantCountChanged(
tiles.length
diff --git a/src/video-grid/VideoTileContainer.tsx b/src/video-grid/VideoTileContainer.tsx
index 4f2c10e..cee56da 100644
--- a/src/video-grid/VideoTileContainer.tsx
+++ b/src/video-grid/VideoTileContainer.tsx
@@ -15,14 +15,18 @@ limitations under the License.
*/
import React from "react";
-import { RoomMember } from "matrix-js-sdk/src/models/room-member";
+import {
+ RoomMember,
+ RoomMemberEvent,
+} from "matrix-js-sdk/src/models/room-member";
import { LocalParticipant, RemoteParticipant } from "livekit-client";
-import { useRoomMemberName } from "./useRoomMemberName";
import { TileContent, VideoTile } from "./VideoTile";
+import { Avatar } from "../Avatar";
+import Styles from "../room/InCallView.module.css";
export interface ItemData {
- member: RoomMember;
+ member?: RoomMember;
sfuParticipant: LocalParticipant | RemoteParticipant;
content: TileContent;
}
@@ -31,29 +35,45 @@ interface Props {
item: ItemData;
width?: number;
height?: number;
- getAvatar: (
- roomMember: RoomMember,
- width: number,
- height: number
- ) => JSX.Element;
}
-export function VideoTileContainer({
- item,
- width,
- height,
- getAvatar,
- ...rest
-}: Props) {
- const { rawDisplayName } = useRoomMemberName(item.member);
+export function VideoTileContainer({ item, width, height, ...rest }: Props) {
+ const [displayName, setDisplayName] = React.useState("[👻]");
+
+ React.useEffect(() => {
+ const member = item.member;
+
+ if (member) {
+ setDisplayName(member.rawDisplayName);
+
+ const updateName = () => {
+ setDisplayName(member.rawDisplayName);
+ };
+
+ member!.on(RoomMemberEvent.Name, updateName);
+ return () => {
+ member!.removeListener(RoomMemberEvent.Name, updateName);
+ };
+ }
+ }, [item.member]);
+
+ const avatar = (
+
+ );
return (
<>
>
diff --git a/src/video-grid/useRoomMemberName.ts b/src/video-grid/useRoomMemberName.ts
deleted file mode 100644
index 9c1d5cb..0000000
--- a/src/video-grid/useRoomMemberName.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-Copyright 2022 New Vector Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import {
- RoomMember,
- RoomMemberEvent,
-} from "matrix-js-sdk/src/models/room-member";
-import { useState, useEffect } from "react";
-
-interface RoomMemberName {
- name: string;
- rawDisplayName: string;
-}
-export function useRoomMemberName(member: RoomMember): RoomMemberName {
- const [state, setState] = useState({
- name: member.name,
- rawDisplayName: member.rawDisplayName,
- });
-
- useEffect(() => {
- function updateName() {
- setState({ name: member.name, rawDisplayName: member.rawDisplayName });
- }
-
- updateName();
-
- member.on(RoomMemberEvent.Name, updateName);
-
- return () => {
- member.removeListener(RoomMemberEvent.Name, updateName);
- };
- }, [member]);
-
- return state;
-}