diff --git a/client/.env b/client/.env index 0f22f67..5e374be 100644 --- a/client/.env +++ b/client/.env @@ -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 \ No newline at end of file +# 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 \ No newline at end of file diff --git a/client/src/components/DraggableContainer.tsx b/client/src/components/DraggableContainer.tsx index 9ba2011..a6a00e5 100644 --- a/client/src/components/DraggableContainer.tsx +++ b/client/src/components/DraggableContainer.tsx @@ -152,6 +152,24 @@ export default function DraggableContainer({ initialPosition: { top: 0, left: 0 }, }); + // Функция для преобразования padding в пиксели + const parsePadding = (paddingValue: number | string): number => { + if (typeof paddingValue === "number") return paddingValue; + + const value = parseFloat(paddingValue); + if (paddingValue.endsWith("vw")) { + return (value / 100) * window.innerWidth; + } else if (paddingValue.endsWith("vh")) { + return (value / 100) * window.innerHeight; + } else if (paddingValue.endsWith("%")) { + // Для процентов берем среднее между шириной и высотой + return (value / 100) * Math.min(window.innerWidth, window.innerHeight); + } else { + // По умолчанию считаем что это пиксели + return value; + } + }; + // Функция для преобразования угла в позицию const getPositionFromCorner = (corner: Corner): Position => { switch (corner) { @@ -446,14 +464,75 @@ export default function DraggableContainer({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [isDragging]); + // Конвертируем позицию из transform-based в absolute только после стабилизации размеров + // Это нужно для корректной работы внутренних поповеров useEffect(() => { - if (!containerRef.current || enableSnapping) return; - const rect = containerRef.current.getBoundingClientRect(); - setPosition({ - top: rect.top, - left: rect.left, + if (!containerRef.current || enableSnapping || !position.transform) return; + + const container = containerRef.current; + let timeoutId: NodeJS.Timeout; + let lastHeight = 0; + + // Используем ResizeObserver для отслеживания изменений размера + const resizeObserver = new ResizeObserver((entries) => { + const entry = entries[0]; + const currentHeight = entry.contentRect.height; + + // Если высота изменилась, перезапускаем таймер + if (currentHeight !== lastHeight) { + lastHeight = currentHeight; + clearTimeout(timeoutId); + + timeoutId = setTimeout(() => { + if (!containerRef.current) return; + const rect = containerRef.current.getBoundingClientRect(); + let { top, left } = rect; + + // Проверяем, не выходит ли попап за границы экрана + const windowHeight = window.innerHeight; + const windowWidth = window.innerWidth; + + // Корректируем вертикальную позицию если нужно + if (centerVertical) { + if (rect.bottom > windowHeight) { + // Попап выходит за нижнюю границу - прижимаем к низу с отступом + top = windowHeight - rect.height - parsePadding(padding); + } else if (rect.top < 0) { + // Попап выходит за верхнюю границу - прижимаем к верху с отступом + top = parsePadding(padding); + } + } + + // Корректируем горизонтальную позицию если нужно + if (centerHorizontal) { + if (rect.right > windowWidth) { + left = windowWidth - rect.width - parsePadding(padding); + } else if (rect.left < 0) { + left = parsePadding(padding); + } + } + + setPosition({ + top, + left, + }); + }, 100); + } }); - }, [enableSnapping]); + + resizeObserver.observe(container); + + return () => { + resizeObserver.disconnect(); + clearTimeout(timeoutId); + }; + }, [ + enableSnapping, + position.transform, + centerVertical, + centerHorizontal, + padding, + ]); // Устанавливаем cursor стили на элемент-хэндл useEffect(() => { diff --git a/client/src/components/PopupWrapper.tsx b/client/src/components/PopupWrapper.tsx index d6a9f57..e69af85 100644 --- a/client/src/components/PopupWrapper.tsx +++ b/client/src/components/PopupWrapper.tsx @@ -20,7 +20,7 @@ function PopupWrapper({ return (