Refactor SessionUsersPanel to display multiple local cameras based on a defined count, enhance grid column calculations for better responsiveness, and update UserCamera component styling. Adjust ControlsPopover z-index for improved visibility and clean up SessionPage layout for consistency.
This commit is contained in:
@@ -5,6 +5,8 @@ import { useWebRTC } from "../hooks/useWebRTC";
|
||||
import clsx from "clsx";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
const LOCAL_CAMERAS_COUNT = 10;
|
||||
|
||||
interface SessionUsersPanelProps {
|
||||
roomId: string;
|
||||
autoJoin?: boolean;
|
||||
@@ -114,7 +116,7 @@ function SessionUsersPanel({
|
||||
|
||||
// Вычисляем количество камер для grid
|
||||
const activeCamerasCount =
|
||||
(localStream ? 1 : 0) +
|
||||
(localStream ? LOCAL_CAMERAS_COUNT : 0) +
|
||||
participants.filter(
|
||||
(p) => p.stream != null && p.stream.getTracks().length > 0
|
||||
).length;
|
||||
@@ -129,7 +131,7 @@ function SessionUsersPanel({
|
||||
|
||||
const getMobilePortraitGridColumns = (count: number): number => {
|
||||
if (count <= 3) return 1;
|
||||
if (count <= 8) return 2;
|
||||
if (count <= 12) return 2;
|
||||
return 3;
|
||||
};
|
||||
|
||||
@@ -159,11 +161,13 @@ function SessionUsersPanel({
|
||||
"z-[999] 2xl:gap-[0.556vw] gap-2",
|
||||
mode === "full"
|
||||
? "flex"
|
||||
: `2xl:p-[5vw] p-4 w-full 2xl:h-dvh max-2xl:portrait:h-[calc(100dvh-17.778vw)] max-2xl:landscape:h-[calc(100dvh-8.75vw)] grid grid-cols-${gridColumns}`
|
||||
: `2xl:p-[5vw] p-4 w-full 2xl:h-dvh max-2xl:portrait:max-h-[calc(100dvh-17.778vw)] max-2xl:landscape:max-h-[calc(100dvh-8.75vw)] grid grid-cols-${gridColumns}`
|
||||
)}
|
||||
>
|
||||
{localStream && (
|
||||
{localStream &&
|
||||
Array.from({ length: LOCAL_CAMERAS_COUNT }).map((_, index) => (
|
||||
<UserCamera
|
||||
key={index}
|
||||
mode={mode}
|
||||
name="Вы"
|
||||
isMuted={isLocalAudioMuted}
|
||||
@@ -178,10 +182,14 @@ function SessionUsersPanel({
|
||||
onSpeakingChange={handleSpeakingChange}
|
||||
className={clsx(
|
||||
mode === "mini" &&
|
||||
(activeCamerasCount <= 2 ? "2xl:m-auto" : "w-full")
|
||||
(activeCamerasCount <= 2
|
||||
? "m-auto"
|
||||
: activeCamerasCount > 12
|
||||
? "!aspect-square w-full"
|
||||
: "w-full")
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
))}
|
||||
|
||||
{/* Камеры удаленных участников - показываем только если есть поток с активными треками */}
|
||||
{participants
|
||||
@@ -194,7 +202,11 @@ function SessionUsersPanel({
|
||||
<UserCamera
|
||||
className={clsx(
|
||||
mode === "mini" &&
|
||||
(activeCamerasCount <= 2 ? "2xl:m-auto" : "w-full")
|
||||
(activeCamerasCount <= 2
|
||||
? "m-auto"
|
||||
: activeCamerasCount > 12
|
||||
? "!aspect-square w-full"
|
||||
: "w-full")
|
||||
)}
|
||||
key={participant.id}
|
||||
mode={mode}
|
||||
|
||||
@@ -56,7 +56,7 @@ function ControlsPopover({ session }: ControlsPopoverProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="order-3 2xl:hidden" ref={ref}>
|
||||
<div className="order-3 2xl:hidden z-[9999]" ref={ref}>
|
||||
<FloatingActionButton
|
||||
ref={buttonRef}
|
||||
className={clsx(isOpened && "!bg-[#7B60F3]")}
|
||||
|
||||
@@ -280,7 +280,7 @@ export default function UserCamera({
|
||||
className={clsx(
|
||||
mode === "full"
|
||||
? "aspect-square h-fit group 2xl:rounded-[1.667vw] rounded-2xl relative flex-shrink-0 pointer-events-auto 2xl:hover:w-[10.833vw] 2xl:w-[6.944vw] sm:w-[15.625vw] w-[27.778vw] overflow-hidden"
|
||||
: "aspect-video 2xl:rounded-[2.222vw] rounded-[32px] overflow-hidden group relative pointer-events-auto max-w-full h-full object-cover",
|
||||
: "aspect-video 2xl:rounded-[2.222vw] rounded-[32px] overflow-hidden group relative pointer-events-auto max-w-full h-full self-center object-cover",
|
||||
isLocal && "order-last",
|
||||
isVideoOff ? "bg-green-500" : "bg-yellow-500/10",
|
||||
className
|
||||
|
||||
@@ -93,7 +93,7 @@ function SessionPage() {
|
||||
setPopup(<SharePopup link={`${window.location.origin}/sessions/${id}`} />);
|
||||
}
|
||||
|
||||
const [mode, setMode] = useState<"full" | "mini">("full");
|
||||
const [mode, setMode] = useState<"full" | "mini">("mini");
|
||||
|
||||
function toggleMode() {
|
||||
setMode(mode === "full" ? "mini" : "full");
|
||||
@@ -155,8 +155,7 @@ function SessionPage() {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
// "flex overflow-hidden relative order-3 w-screen h-dvh bg-black touch-none"
|
||||
"overflow-hidden relative order-3 w-screen h-dvh bg-black touch-none",
|
||||
"overflow-hidden relative order-3 w-screen h-dvh bg-black touch-none max-2xl:flex max-2xl:portrait:items-center",
|
||||
mode === "full" && "flex"
|
||||
)}
|
||||
>
|
||||
@@ -200,7 +199,7 @@ function SessionPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ActionsSidebarWrapper className="z-[99]">
|
||||
<ActionsSidebarWrapper className="z-[9999]">
|
||||
<FloatingActionButton onClick={toggleMode}>
|
||||
<div className="2xl:size-[1.111vw] size-4 text-white">
|
||||
{mode === "mini" ? <FullscreenExitIcon /> : <FullscreenIcon />}
|
||||
|
||||
Reference in New Issue
Block a user