({
return (
- {springs.map((style, i) => {
+ {springs.map((spring, i) => {
const tile = tiles[i];
const tilePosition = tilePositions[tile.order];
- return createChild({
- ...bindTile(tile.key),
- ...style,
- key: tile.key,
- data: tile.item.data,
- targetWidth: tilePosition.width,
- targetHeight: tilePosition.height,
- });
+ return (
+
+ {children as (props: ChildrenProperties) => ReactNode}
+
+ );
})}
);
diff --git a/src/video-grid/VideoTile.module.css b/src/video-grid/VideoTile.module.css
index adcc57a..62d4545 100644
--- a/src/video-grid/VideoTile.module.css
+++ b/src/video-grid/VideoTile.module.css
@@ -18,12 +18,10 @@ limitations under the License.
position: absolute;
contain: strict;
top: 0;
- width: var(--tileWidth);
- height: var(--tileHeight);
+ container-name: videoTile;
+ container-type: size;
--tileRadius: 8px;
border-radius: var(--tileRadius);
- box-shadow: rgba(0, 0, 0, 0.5) 0px var(--tileShadow)
- calc(2 * var(--tileShadow)) var(--tileShadowSpread);
overflow: hidden;
cursor: pointer;
diff --git a/src/video-grid/VideoTile.tsx b/src/video-grid/VideoTile.tsx
index f73590d..beff7ec 100644
--- a/src/video-grid/VideoTile.tsx
+++ b/src/video-grid/VideoTile.tsx
@@ -1,5 +1,5 @@
/*
-Copyright 2022 New Vector Ltd
+Copyright 2022-2023 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.
@@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React, { ForwardedRef, forwardRef } from "react";
-import { animated, SpringValue } from "@react-spring/web";
+import React, { ComponentProps, forwardRef } from "react";
+import { animated } from "@react-spring/web";
import classNames from "classnames";
import { useTranslation } from "react-i18next";
import { LocalParticipant, RemoteParticipant, Track } from "livekit-client";
@@ -24,10 +24,19 @@ import {
VideoTrack,
useMediaTrack,
} from "@livekit/components-react";
+import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import styles from "./VideoTile.module.css";
import { ReactComponent as MicIcon } from "../icons/Mic.svg";
import { ReactComponent as MicMutedIcon } from "../icons/MicMuted.svg";
+import { useRoomMemberName } from "./useRoomMemberName";
+
+export interface ItemData {
+ id: string;
+ member: RoomMember;
+ sfuParticipant: LocalParticipant | RemoteParticipant;
+ content: TileContent;
+}
export enum TileContent {
UserMedia = "user-media",
@@ -35,52 +44,37 @@ export enum TileContent {
}
interface Props {
- avatar?: JSX.Element;
+ data: ItemData;
className?: string;
- name: string;
- sfuParticipant: LocalParticipant | RemoteParticipant;
- content: TileContent;
- showOptions?: boolean;
- isLocal?: boolean;
- disableSpeakingIndicator?: boolean;
- opacity?: SpringValue;
- scale?: SpringValue;
- shadow?: SpringValue;
- shadowSpread?: SpringValue;
- zIndex?: SpringValue;
- x?: SpringValue;
- y?: SpringValue;
- width?: SpringValue;
- height?: SpringValue;
+ showSpeakingIndicator: boolean;
+ style?: ComponentProps["style"];
+ targetWidth: number;
+ targetHeight: number;
+ getAvatar: (
+ roomMember: RoomMember,
+ width: number,
+ height: number
+ ) => JSX.Element;
}
-export const VideoTile = forwardRef(
+export const VideoTile = forwardRef(
(
{
- name,
- sfuParticipant,
- content,
- avatar,
+ data,
className,
- showOptions,
- isLocal,
- // TODO: disableSpeakingIndicator is not used atm.
- disableSpeakingIndicator,
- opacity,
- scale,
- shadow,
- shadowSpread,
- zIndex,
- x,
- y,
- width,
- height,
- ...rest
+ showSpeakingIndicator,
+ style,
+ targetWidth,
+ targetHeight,
+ getAvatar,
},
- ref
+ tileRef
) => {
const { t } = useTranslation();
+ const { content, sfuParticipant } = data;
+ const { rawDisplayName: name } = useRoomMemberName(data.member);
+
const audioEl = React.useRef(null);
const { isMuted: microphoneMuted } = useMediaTrack(
content === TileContent.UserMedia
@@ -92,36 +86,25 @@ export const VideoTile = forwardRef(
}
);
+ // Firefox doesn't respect the disablePictureInPicture attribute
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1611831
+
return (
`${w}px`),
- "--tileHeight": height?.to((h) => `${h}px`),
- "--tileShadow": shadow?.to((s) => `${s}px`),
- "--tileShadowSpread": shadowSpread?.to((s) => `${s}px`),
- }}
- ref={ref as ForwardedRef}
+ style={style}
+ ref={tileRef}
data-testid="videoTile"
- {...rest}
>
{!sfuParticipant.isCameraEnabled && (
<>
- {avatar}
+ {getAvatar(data.member, targetWidth, targetHeight)}
>
)}
{!false &&
diff --git a/src/video-grid/VideoTileContainer.tsx b/src/video-grid/VideoTileContainer.tsx
deleted file mode 100644
index 9be2bff..0000000
--- a/src/video-grid/VideoTileContainer.tsx
+++ /dev/null
@@ -1,86 +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 { LocalParticipant, RemoteParticipant } from "livekit-client";
-import React, { FC, memo, RefObject, useRef } from "react";
-import { RoomMember } from "matrix-js-sdk/src/models/room-member";
-import { SpringValue } from "@react-spring/web";
-import { EventTypes, Handler, useDrag } from "@use-gesture/react";
-
-import { useRoomMemberName } from "./useRoomMemberName";
-import { TileContent, VideoTile } from "./VideoTile";
-
-export interface ItemData {
- id: string;
- member: RoomMember;
- sfuParticipant: LocalParticipant | RemoteParticipant;
- content: TileContent;
-}
-
-interface Props {
- item: ItemData;
- targetWidth: number;
- targetHeight: number;
- getAvatar: (
- roomMember: RoomMember,
- width: number,
- height: number
- ) => JSX.Element;
- disableSpeakingIndicator: boolean;
- maximised: boolean;
- opacity?: SpringValue;
- scale?: SpringValue;
- shadow?: SpringValue;
- shadowSpread?: SpringValue;
- zIndex?: SpringValue;
- x?: SpringValue;
- y?: SpringValue;
- width?: SpringValue;
- height?: SpringValue;
- onDragRef?: RefObject<
- (
- tileId: string,
- state: Parameters>[0]
- ) => void
- >;
-}
-
-export const VideoTileContainer: FC = memo(
- ({ item, targetWidth, targetHeight, getAvatar, onDragRef, ...rest }) => {
- const { rawDisplayName } = useRoomMemberName(item.member);
- const tileRef = useRef(null);
-
- useDrag((state) => onDragRef?.current!(item.id, state), {
- target: tileRef,
- filterTaps: true,
- preventScroll: true,
- });
-
- // Firefox doesn't respect the disablePictureInPicture attribute
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1611831
-
- return (
-
- );
- }
-);