Update environment variables for production URLs, refactor DraggableContainer to wrap children in a div when disabled, and enhance SessionUsersPanel layout with responsive adjustments for camera display. Improve UserCamera component's class handling and clean up SessionPage layout for better structure.
This commit is contained in:
+4
-4
@@ -1,4 +1,4 @@
|
||||
VITE_API_URL=http://localhost:3000
|
||||
VITE_WEBRTC_URL=http://localhost:3001
|
||||
# VITE_API_URL=https://stream.graff.estate/api
|
||||
# VITE_WEBRTC_URL=https://stream.graff.estate
|
||||
# VITE_API_URL=http://localhost:3000
|
||||
# VITE_WEBRTC_URL=http://localhost:3001
|
||||
VITE_API_URL=https://stream.graff.estate/api
|
||||
VITE_WEBRTC_URL=https://stream.graff.estate
|
||||
@@ -496,7 +496,7 @@ export default function DraggableContainer({
|
||||
|
||||
// Если компонент отключен, просто рендерим children без стилей и логики
|
||||
if (!enabled) {
|
||||
return <>{children}</>;
|
||||
return <div className={className}>{children}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -66,7 +66,7 @@ function SessionUsersPanel({
|
||||
|
||||
// Вычисляем количество камер для grid
|
||||
const activeCamerasCount =
|
||||
(localStream ? 8 : 0) +
|
||||
(localStream ? 1 : 0) +
|
||||
participants.filter(
|
||||
(p) => p.stream != null && p.stream.getTracks().length > 0
|
||||
).length;
|
||||
@@ -76,19 +76,28 @@ function SessionUsersPanel({
|
||||
if (count <= 2) return 1;
|
||||
if (count <= 4) return 2;
|
||||
if (count <= 9) return 3;
|
||||
if (count <= 16) return 4;
|
||||
return 5;
|
||||
return 4;
|
||||
};
|
||||
|
||||
const gridColumns = getGridColumns(activeCamerasCount);
|
||||
|
||||
// Вычисляем количество рядов для правильного расчета высоты
|
||||
const gridRows = Math.ceil(activeCamerasCount / gridColumns);
|
||||
// const gridRows = Math.ceil(activeCamerasCount / gridColumns);
|
||||
|
||||
// Рендерим камеры
|
||||
const camerasContent = (
|
||||
<>
|
||||
{/* Локальная камера пользователя - показываем только если есть разрешение */}
|
||||
return (
|
||||
<DraggableContainer
|
||||
enableSnapping={mode === "full"}
|
||||
enabled={mode === "full"}
|
||||
autoAlign={true}
|
||||
initialCorner={innerWidth >= 640 ? "bottom-right" : "top-right"}
|
||||
padding="1.111vw"
|
||||
className={clsx(
|
||||
"z-[999]",
|
||||
mode === "full"
|
||||
? "flex 2xl:gap-[0.556vw] gap-2"
|
||||
: `2xl:p-[5vw] w-full max- h-dvh grid grid-cols-${gridColumns} 2xl:gap-[0.556vw] gap-2`
|
||||
)}
|
||||
>
|
||||
{localStream && (
|
||||
<UserCamera
|
||||
mode={mode}
|
||||
@@ -103,6 +112,7 @@ function SessionUsersPanel({
|
||||
onVideoOff={toggleVideo}
|
||||
onCanControl={() => console.log("Toggle control")}
|
||||
onSpeakingChange={handleSpeakingChange}
|
||||
className={activeCamerasCount <= 2 ? "m-auto" : " w-full"}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -115,6 +125,7 @@ function SessionUsersPanel({
|
||||
)
|
||||
.map((participant) => (
|
||||
<UserCamera
|
||||
className={activeCamerasCount <= 2 ? "m-auto" : " w-full"}
|
||||
key={participant.id}
|
||||
mode={mode}
|
||||
name={participant.id}
|
||||
@@ -141,47 +152,32 @@ function SessionUsersPanel({
|
||||
isVideoMuted={isLocalVideoMuted}
|
||||
hasLocalStream={hasLocalStream}
|
||||
/>
|
||||
</>
|
||||
</DraggableContainer>
|
||||
);
|
||||
|
||||
// Для режима full используем DraggableContainer
|
||||
if (mode === "full") {
|
||||
return (
|
||||
<DraggableContainer
|
||||
enableSnapping={true}
|
||||
enabled={true}
|
||||
autoAlign={true}
|
||||
initialCorner={innerWidth >= 640 ? "bottom-right" : "top-right"}
|
||||
padding="1.111vw"
|
||||
className="z-[999] flex gap-4"
|
||||
>
|
||||
{camerasContent}
|
||||
</DraggableContainer>
|
||||
);
|
||||
}
|
||||
// }
|
||||
|
||||
// Для режима mini используем flex-обертку для центрирования и внутри grid
|
||||
return (
|
||||
<div className="flex justify-center items-center w-full h-full z-[99]a">
|
||||
<div
|
||||
className={clsx(
|
||||
"grid 2xl:gap-[0.556vw] gap-2",
|
||||
gridColumns === 1 && "grid-cols-1 2xl:w-[45vw] w-[calc(50vw-1rem)]",
|
||||
gridColumns === 2 && "grid-cols-2 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
gridColumns === 3 && "grid-cols-3 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
gridColumns === 4 && "grid-cols-4 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
gridColumns === 5 && "grid-cols-5 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
gridRows === 1 && "auto-rows-[calc((86vh-1.111vw)/1)]",
|
||||
gridRows === 2 && "auto-rows-[calc((86vh-1.667vw)/2)]",
|
||||
gridRows === 3 && "auto-rows-[calc((86vh-2.222vw)/3)]",
|
||||
gridRows === 4 && "auto-rows-[calc((86vh-2.778vw)/4)]",
|
||||
gridRows === 5 && "auto-rows-[calc((86vh-3.333vw)/5)]"
|
||||
)}
|
||||
>
|
||||
{camerasContent}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
// return (
|
||||
// <div className="flex justify-center items-center w-full h-full z-[99]a">
|
||||
// <div
|
||||
// className={clsx(
|
||||
// "grid 2xl:gap-[0.556vw] gap-2",
|
||||
// gridColumns === 1 && "grid-cols-1 2xl:w-[45vw] w-[calc(50vw-1rem)]",
|
||||
// gridColumns === 2 && "grid-cols-2 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
// gridColumns === 3 && "grid-cols-3 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
// gridColumns === 4 && "grid-cols-4 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
// gridColumns === 5 && "grid-cols-5 2xl:w-[90vw] w-[calc(100vw-2rem)]",
|
||||
// gridRows === 1 && "auto-rows-[calc((86vh-1.111vw)/1)]",
|
||||
// gridRows === 2 && "auto-rows-[calc((86vh-1.667vw)/2)]",
|
||||
// gridRows === 3 && "auto-rows-[calc((86vh-2.222vw)/3)]",
|
||||
// gridRows === 4 && "auto-rows-[calc((86vh-2.778vw)/4)]",
|
||||
// gridRows === 5 && "auto-rows-[calc((86vh-3.333vw)/5)]"
|
||||
// )}
|
||||
// >
|
||||
// {camerasContent}
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
}
|
||||
|
||||
export default SessionUsersPanel;
|
||||
|
||||
@@ -75,9 +75,13 @@ export default function UserCamera({
|
||||
// Отправляем изменения состояния для локального пользователя
|
||||
// Используем ref для отслеживания предыдущего состояния, чтобы избежать лишних вызовов
|
||||
const prevLocalSpeakingRef = useRef<boolean>(localSpeaking);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (isLocal && onSpeakingChange && prevLocalSpeakingRef.current !== localSpeaking) {
|
||||
if (
|
||||
isLocal &&
|
||||
onSpeakingChange &&
|
||||
prevLocalSpeakingRef.current !== localSpeaking
|
||||
) {
|
||||
prevLocalSpeakingRef.current = localSpeaking;
|
||||
onSpeakingChange(localSpeaking);
|
||||
}
|
||||
@@ -276,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 flex-shrink-0 pointer-events-auto w-full h-full object-contain",
|
||||
: "aspect-video 2xl:rounded-[2.222vw] rounded-[32px] overflow-hidden group relative pointer-events-auto max-w-full h-full object-cover",
|
||||
isLocal && "order-last",
|
||||
isVideoOff ? "bg-green-500" : "bg-yellow-500/10",
|
||||
className
|
||||
@@ -290,7 +294,9 @@ export default function UserCamera({
|
||||
window.innerWidth >= 1536 ? "0.069vw" : "1px"
|
||||
} rgba(255, 255, 255, 0.3)`,
|
||||
transition:
|
||||
"box-shadow 0.1s ease-out, width 0.3s, background-color 0.3s",
|
||||
mode === "full"
|
||||
? "box-shadow 0.1s ease-out, width 0.3s, background-color 0.3s"
|
||||
: undefined,
|
||||
}}
|
||||
onClick={handleVideoClick}
|
||||
>
|
||||
|
||||
@@ -80,7 +80,6 @@ function SessionPage() {
|
||||
const session = sessionData?.session;
|
||||
|
||||
function handleChatOpen() {
|
||||
console.log("handleChatOpen");
|
||||
setPopup(<ChatPopup sessionId={id} />);
|
||||
}
|
||||
|
||||
@@ -156,9 +155,9 @@ function SessionPage() {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
mode === "full"
|
||||
? "flex overflow-hidden relative order-3 w-screen h-dvh bg-black justify-center_items-center touch-none"
|
||||
: "2xl:px-[5vw] grid 2xl:gap-[0.556vw] gap-2 bg-black relative w-screen h-dvh overflow-hidden"
|
||||
// "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",
|
||||
mode === "full" && "flex"
|
||||
)}
|
||||
>
|
||||
{/* Pixel Streaming - показывается только когда сессия активна */}
|
||||
@@ -166,7 +165,7 @@ function SessionPage() {
|
||||
session.mode === "stream" &&
|
||||
session.server?.localIp &&
|
||||
session.playerPort && (
|
||||
<div className="absolute w-full h-full aspect-video">
|
||||
<div className="absolute w-full h-full aspect-video bg-green-950">
|
||||
<PixelStreamingWrapper
|
||||
initialSettings={{
|
||||
ss: `ws://${session.server.localIp}:${session.playerPort}`,
|
||||
|
||||
Reference in New Issue
Block a user