209 lines
7.0 KiB
TypeScript
209 lines
7.0 KiB
TypeScript
import React, { useState, useRef, useEffect, Suspense } from "react";
|
|
import {
|
|
CompareLayoutIcon,
|
|
LayoutIcon,
|
|
ResizerIcon,
|
|
} from "../../icons/SimulationIcons";
|
|
import {
|
|
useLoadingProgress,
|
|
useSaveVersion,
|
|
} from "../../../store/builder/store";
|
|
import Search from "../inputs/Search";
|
|
import OuterClick from "../../../utils/outerClick";
|
|
import Scene from "../../../modules/scene/scene";
|
|
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
|
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
|
import { useVersionHistoryStore } from "../../../store/builder/useVersionHistoryStore";
|
|
import { useVersionContext } from "../../../modules/builder/version/versionContext";
|
|
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
|
import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi";
|
|
import { useParams } from "react-router-dom";
|
|
|
|
const CompareLayOut = () => {
|
|
const { clearComparisonProduct, comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
|
const { productStore } = useSceneContext();
|
|
const { products } = productStore();
|
|
const { versionHistory } = useVersionHistoryStore();
|
|
const { selectedVersionStore } = useVersionContext();
|
|
const { selectedVersion, setSelectedVersion, clearSelectedVersion } = selectedVersionStore();
|
|
const { setLoadingProgress } = useLoadingProgress();
|
|
const [width, setWidth] = useState("50vw");
|
|
const [isResizing, setIsResizing] = useState(false);
|
|
const [showLayoutDropdown, setShowLayoutDropdown] = useState(false);
|
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
const startWidthRef = useRef<number>(0);
|
|
const startXRef = useRef<number>(0);
|
|
const { setIsVersionSaved } = useSaveVersion();
|
|
const { loadingProgress } = useLoadingProgress();
|
|
const { setIsPlaying } = usePlayButtonStore();
|
|
const { projectId } = useParams();
|
|
|
|
useEffect(() => {
|
|
if (!comparisonProduct) {
|
|
clearSelectedVersion();
|
|
}
|
|
}, [comparisonProduct])
|
|
|
|
OuterClick({
|
|
contextClassName: ["displayLayouts-container", "selectLayout"],
|
|
setMenuVisible: () => setShowLayoutDropdown(false),
|
|
});
|
|
|
|
const handleStartResizing = (e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
setIsResizing(true);
|
|
startXRef.current = e.clientX;
|
|
if (wrapperRef.current) {
|
|
startWidthRef.current = wrapperRef.current.getBoundingClientRect().width;
|
|
}
|
|
};
|
|
|
|
const handleMouseMove = (e: MouseEvent) => {
|
|
if (!isResizing || !wrapperRef.current) return;
|
|
|
|
const dx = startXRef.current - e.clientX;
|
|
const newWidthPx = startWidthRef.current + dx;
|
|
const viewportWidth = window.innerWidth;
|
|
const newWidthVw = (newWidthPx / viewportWidth) * 100;
|
|
|
|
if (newWidthVw <= 10) {
|
|
setWidth("0px");
|
|
} else if (newWidthVw <= 90) {
|
|
setWidth(`${newWidthPx}px`);
|
|
}
|
|
};
|
|
|
|
const handleMouseUp = () => {
|
|
if (!isResizing) return;
|
|
|
|
if (wrapperRef.current) {
|
|
const finalWidthPx = wrapperRef.current.getBoundingClientRect().width;
|
|
const viewportWidth = window.innerWidth;
|
|
const finalWidthVw = (finalWidthPx / viewportWidth) * 100;
|
|
|
|
if (finalWidthVw <= 10) {
|
|
setWidth("0px");
|
|
setIsVersionSaved(false);
|
|
clearComparisonProduct();
|
|
setIsPlaying(false);
|
|
} else {
|
|
setWidth(`${finalWidthVw}vw`);
|
|
}
|
|
}
|
|
|
|
setIsResizing(false);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (isResizing) {
|
|
window.addEventListener("mousemove", handleMouseMove);
|
|
window.addEventListener("mouseup", handleMouseUp);
|
|
document.body.classList.add("resizing-active");
|
|
}
|
|
|
|
return () => {
|
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
document.body.classList.remove("resizing-active");
|
|
};
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [isResizing]);
|
|
|
|
// Maintain proportional width on window resize
|
|
useEffect(() => {
|
|
const handleResize = () => {
|
|
if (!wrapperRef.current || isResizing) return;
|
|
|
|
const currentWidth = wrapperRef.current.style.width;
|
|
if (currentWidth === "0px" || currentWidth.endsWith("vw")) return;
|
|
|
|
const pxWidth = parseFloat(currentWidth);
|
|
const vwWidth = (pxWidth / window.innerWidth) * 100;
|
|
setWidth(`${vwWidth}vw`);
|
|
};
|
|
|
|
window.addEventListener("resize", handleResize);
|
|
return () => window.removeEventListener("resize", handleResize);
|
|
}, [isResizing]);
|
|
|
|
const handleSelectLayout = (version: Version) => {
|
|
getAllProductsApi(projectId || '', version.versionId || '').then((data) => {
|
|
if (data && data.length > 0) {
|
|
setSelectedVersion(version);
|
|
setComparisonProduct(data[0].productUuid, data[0].productName);
|
|
setLoadingProgress(1);
|
|
}
|
|
})
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={`compareLayOut-wrapper ${width === "0px" ? "closed" : ""}`}
|
|
ref={wrapperRef}
|
|
style={{ width }}
|
|
>
|
|
{loadingProgress == 0 && selectedVersion?.versionId && (
|
|
<button
|
|
title="resize-canvas"
|
|
id="compare-resize-slider-btn"
|
|
className="resizer"
|
|
onMouseDown={handleStartResizing}
|
|
>
|
|
<ResizerIcon />
|
|
</button>
|
|
)}
|
|
<div className="chooseLayout-container">
|
|
{selectedVersion?.versionId && (
|
|
<div className="compare-layout-canvas-container">
|
|
<Suspense fallback={null}>
|
|
<Scene layout="Comparison Layout" />
|
|
</Suspense>
|
|
</div>
|
|
)}
|
|
|
|
{width !== "0px" &&
|
|
!selectedVersion?.versionId && ( // Show only if no layout selected
|
|
<div className="chooseLayout-wrapper">
|
|
<div className="icon">
|
|
<CompareLayoutIcon />
|
|
</div>
|
|
<div className="value">Choose Version to compare</div>
|
|
<button
|
|
className="selectLayout"
|
|
onClick={() => setShowLayoutDropdown(!showLayoutDropdown)}
|
|
>
|
|
Select Version
|
|
</button>
|
|
|
|
{showLayoutDropdown && (
|
|
<div className="displayLayouts-container">
|
|
<div className="header">Versions</div>
|
|
<Search onChange={() => { }} />
|
|
<div className="layouts-container">
|
|
{versionHistory.map((version) => (
|
|
<button
|
|
key={version.versionId}
|
|
className="layout-wrapper"
|
|
onClick={() => {
|
|
handleSelectLayout(version);
|
|
setShowLayoutDropdown(false);
|
|
}}
|
|
>
|
|
<LayoutIcon />
|
|
<div className="layout">{version.versionName}</div>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{/* Always show after layout is selected */}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CompareLayOut;
|