Enhance DraggableContainer to set initial position based on bounding rectangle and update SessionUsersPanel to limit local cameras to one. Refactor UserCamera styling for consistency and improve PopoverWrapper positioning logic. Clean up unnecessary code in SessionUsersPanel for better readability.

This commit is contained in:
2025-11-01 13:27:42 +05:00
parent 871fb10cc4
commit 0964d650a4
4 changed files with 82 additions and 92 deletions
+68 -83
View File
@@ -5,7 +5,7 @@ import { useWebRTC } from "../hooks/useWebRTC";
import clsx from "clsx";
import { useEffect, useRef, useState } from "react";
const LOCAL_CAMERAS_COUNT = 10;
const LOCAL_CAMERAS_COUNT = 1;
interface SessionUsersPanelProps {
roomId: string;
@@ -157,91 +157,76 @@ function SessionUsersPanel({
windowDimensions.width >= 640 ? "bottom-right" : "top-right"
}
padding="1.111vw"
// className={clsx(
// "z-[100] 2xl:gap-[0.556vw] gap-2",
// mode === "mini"
// ? "flex"
// : `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} relative bg-black`
// )}
className={clsx(
"z-[100] 2xl:gap-[0.556vw] gap-2",
mode === "mini"
? "flex"
: `2xl:p-[2.778vw_5vw_5vw] p-[12px_12px_72px] w-full 2xl:h-dvh grid grid-cols-${gridColumns} relative 2xl:bg-black auto-rows-fr`
)}
>
<div
className={clsx(
"z-[100] 2xl:gap-[0.556vw] gap-2",
mode === "mini"
? "flex"
: `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} relative bg-black`
)}
>
{localStream &&
Array.from({ length: LOCAL_CAMERAS_COUNT }).map((_, index) => (
<UserCamera
key={index}
mode={mode}
name="Вы"
isMuted={isLocalAudioMuted}
isVideoOff={isLocalVideoMuted}
isControlDisabled={false}
isAdmin={true}
isLocal={true}
mediaStream={localStream}
onMute={toggleAudio}
onVideoOff={toggleVideo}
onCanControl={() => console.log("Toggle control")}
onSpeakingChange={handleSpeakingChange}
className={clsx(
mode === "full" && activeCamerasCount <= 2
? "m-auto"
: activeCamerasCount > 12
? "!aspect-square w-full"
: "w-full"
)}
/>
))}
{mode === "full" && <div className="fixed bg-black inset-0 2xl:hidden" />}
{localStream &&
Array.from({ length: LOCAL_CAMERAS_COUNT }).map((_, index) => (
<UserCamera
key={index}
mode={mode}
name="Вы"
isMuted={isLocalAudioMuted}
isVideoOff={isLocalVideoMuted}
isControlDisabled={false}
isAdmin={true}
isLocal={true}
mediaStream={localStream}
onMute={toggleAudio}
onVideoOff={toggleVideo}
onCanControl={() => console.log("Toggle control")}
onSpeakingChange={handleSpeakingChange}
className={clsx(
mode === "full" &&
(activeCamerasCount <= 2 ? "m-auto" : "min-w-full min-h-full")
)}
/>
))}
{/* Камеры удаленных участников - показываем только если есть поток с активными треками */}
{participants
.filter(
(participant) =>
participant.stream != null &&
participant.stream.getTracks().length > 0
)
.map((participant) => (
<UserCamera
className={clsx(
mode === "full" &&
(activeCamerasCount <= 2
? "m-auto"
: activeCamerasCount > 12
? "!aspect-square w-full"
: "w-full")
)}
key={participant.id}
mode={mode}
name={participant.id}
isMuted={participant.isMuted || false}
isVideoOff={participant.isVideoOff || false}
isSpeaking={participant.isSpeaking}
isControlDisabled={true}
isAdmin={true}
mediaStream={participant.stream}
hasLocalMediaPermission={hasLocalStream}
onMute={() => console.log(`Mute user ${participant.id}`)}
onVideoOff={() => console.log(`Video off user ${participant.id}`)}
onCanControl={() =>
console.log(`Can control user ${participant.id}`)
}
/>
))}
{/* Камеры удаленных участников - показываем только если есть поток с активными треками */}
{participants
.filter(
(participant) =>
participant.stream != null &&
participant.stream.getTracks().length > 0
)
.map((participant) => (
<UserCamera
className={clsx(
mode === "full" &&
(activeCamerasCount <= 2 ? "m-auto" : "min-w-full min-h-full")
)}
key={participant.id}
mode={mode}
name={participant.name}
isMuted={participant.isMuted || false}
isVideoOff={participant.isVideoOff || false}
isSpeaking={participant.isSpeaking}
isControlDisabled={true}
isAdmin={true}
mediaStream={participant.stream}
hasLocalMediaPermission={hasLocalStream}
onMute={() => console.log(`Mute user ${participant.id}`)}
onVideoOff={() => console.log(`Video off user ${participant.id}`)}
onCanControl={() =>
console.log(`Can control user ${participant.id}`)
}
/>
))}
<UserDevicesControls
mode={mode}
toggleAudio={toggleAudio}
toggleVideo={toggleVideo}
isAudioMuted={isLocalAudioMuted}
isVideoMuted={isLocalVideoMuted}
hasLocalStream={hasLocalStream}
/>
</div>
<UserDevicesControls
mode={mode}
toggleAudio={toggleAudio}
toggleVideo={toggleVideo}
isAudioMuted={isLocalAudioMuted}
isVideoMuted={isLocalVideoMuted}
hasLocalStream={hasLocalStream}
/>
</DraggableContainer>
);
}