Skip to content

Commit

Permalink
Render local participant in grid
Browse files Browse the repository at this point in the history
  • Loading branch information
thyal committed Jan 15, 2024
1 parent 0d7b306 commit 1216803
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 15 deletions.
20 changes: 11 additions & 9 deletions src/lib/react/Grid/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { RemoteParticipant, VideoView } from "..";
import { LocalParticipant, RemoteParticipant, VideoView } from "..";
import { calculateLayout } from "./helpers/stageLayout";
import { makeBounds, makeFrame } from "./helpers/layout";
import { makeVideoCellView } from "./helpers/cellView";
Expand All @@ -12,7 +12,7 @@ function GridVideoCellView({
render,
}: {
cell: { clientId: string; bounds: { width: number; height: number }; origin: { top: number; left: number } };
participant: RemoteParticipant;
participant: RemoteParticipant | LocalParticipant;
render?: () => React.ReactNode;
}) {
return (
Expand All @@ -38,19 +38,20 @@ interface GridProps {
participant,
}: {
cell: { clientId: string; bounds: { width: number; height: number }; origin: { top: number; left: number } };
participant: RemoteParticipant;
participant: RemoteParticipant | LocalParticipant;
}) => React.ReactNode;
videoGridGap?: number;
}

function Grid({ roomConnection, renderParticipant }: GridProps) {
const { remoteParticipants } = roomConnection.state;
function Grid({ roomConnection, renderParticipant, videoGridGap = 0 }: GridProps) {
const { remoteParticipants, localParticipant } = roomConnection.state;
const gridRef = React.useRef<HTMLDivElement>(null);
const [videos, setVideos] = React.useState<ReturnType<typeof makeVideoCellView>[]>([]);
const [stageLayout, setStageLayout] = React.useState<ReturnType<typeof calculateLayout> | null>(null);

React.useEffect(() => {
setVideos(
remoteParticipants.map((participant) =>
[localParticipant, ...remoteParticipants].map((participant) =>
makeVideoCellView({
aspectRatio: 16 / 9,
avatarSize: 0,
Expand All @@ -59,7 +60,7 @@ function Grid({ roomConnection, renderParticipant }: GridProps) {
})
)
);
}, [remoteParticipants]);
}, [remoteParticipants, localParticipant]);

React.useEffect(() => {
if (!gridRef.current || !videos.length) {
Expand All @@ -82,6 +83,7 @@ function Grid({ roomConnection, renderParticipant }: GridProps) {
height: gridRef.current?.clientHeight,
}),
videos,
videoGridGap,
});
});
},
Expand All @@ -104,10 +106,10 @@ function Grid({ roomConnection, renderParticipant }: GridProps) {
position: "relative",
}}
>
{remoteParticipants.map((participant, i) => {
{[localParticipant, ...remoteParticipants].map((participant, i) => {
const cell = stageLayout?.videoGrid.cells[i];

if (!cell) return null;
if (!cell || !participant) return null;

return (
<GridVideoCellView
Expand Down
23 changes: 17 additions & 6 deletions src/stories/custom-ui.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,11 @@ export const GridStory = ({ roomUrl }: { roomUrl: string; displayName?: string }
return <p>Set room url on the Controls panel</p>;
}

const roomConnection = useRoomConnection(roomUrl, { localMediaOptions: { audio: false, video: false } });
const roomConnection = useRoomConnection(roomUrl, { localMediaOptions: { audio: false, video: true } });

return (
<div style={{ height: "100vh" }}>
<VideoGrid roomConnection={roomConnection} />
<VideoGrid roomConnection={roomConnection} videoGridGap={10} />
</div>
);
};
Expand All @@ -193,28 +193,39 @@ export const GridWithCustomVideosStory = ({ roomUrl }: { roomUrl: string; displa
return <p>Set room url on the Controls panel</p>;
}

const roomConnection = useRoomConnection(roomUrl, { localMediaOptions: { audio: false, video: false } });
const roomConnection = useRoomConnection(roomUrl, { localMediaOptions: { audio: false, video: true } });

return (
<div style={{ height: "100vh" }}>
<VideoGrid
roomConnection={roomConnection}
videoGridGap={10}
renderParticipant={({ participant }) => {
if (!participant.stream) return null;
if (!participant.stream) {
return null;
}

return (
<div
style={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100%" }}
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
height: "100%",
}}
>
<VideoView
style={{
border: "4px dashed red",
boxSizing: "border-box",
borderRadius: "100%",
objectFit: "cover",
width: "60%",
border: "10px striped red",
}}
stream={participant.stream}
/>
<p>{participant.displayName}</p>
</div>
);
}}
Expand Down

0 comments on commit 1216803

Please sign in to comment.