Merge remote-tracking branch 'origin/main-demo' into main-dev

This commit is contained in:
2025-09-26 16:00:56 +05:30
3 changed files with 92 additions and 75 deletions

48
app/package-lock.json generated
View File

@@ -2028,7 +2028,7 @@
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/trace-mapping": "0.3.9" "@jridgewell/trace-mapping": "0.3.9"
}, },
@@ -2040,7 +2040,7 @@
"version": "0.3.9", "version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10" "@jridgewell/sourcemap-codec": "^1.4.10"
@@ -4191,26 +4191,6 @@
"url": "https://github.com/sponsors/gregberge" "url": "https://github.com/sponsors/gregberge"
} }
}, },
"node_modules/@testing-library/dom": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
"@types/aria-query": "^5.0.1",
"aria-query": "5.3.0",
"dom-accessibility-api": "^0.5.9",
"lz-string": "^1.5.0",
"picocolors": "1.1.1",
"pretty-format": "^27.0.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@testing-library/jest-dom": { "node_modules/@testing-library/jest-dom": {
"version": "5.17.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
@@ -4322,25 +4302,25 @@
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"devOptional": true "dev": true
}, },
"node_modules/@tsconfig/node12": { "node_modules/@tsconfig/node12": {
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"devOptional": true "dev": true
}, },
"node_modules/@tsconfig/node14": { "node_modules/@tsconfig/node14": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"devOptional": true "dev": true
}, },
"node_modules/@tsconfig/node16": { "node_modules/@tsconfig/node16": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"devOptional": true "dev": true
}, },
"node_modules/@turf/along": { "node_modules/@turf/along": {
"version": "7.2.0", "version": "7.2.0",
@@ -9111,7 +9091,7 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"devOptional": true "dev": true
}, },
"node_modules/cross-env": { "node_modules/cross-env": {
"version": "7.0.3", "version": "7.0.3",
@@ -9988,7 +9968,7 @@
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"devOptional": true, "dev": true,
"engines": { "engines": {
"node": ">=0.3.1" "node": ">=0.3.1"
} }
@@ -15372,7 +15352,7 @@
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"devOptional": true "dev": true
}, },
"node_modules/makeerror": { "node_modules/makeerror": {
"version": "1.0.12", "version": "1.0.12",
@@ -20926,7 +20906,7 @@
"version": "10.9.2", "version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"@cspotcode/source-map-support": "^0.8.0", "@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7", "@tsconfig/node10": "^1.0.7",
@@ -20969,7 +20949,7 @@
"version": "8.3.4", "version": "8.3.4",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"acorn": "^8.11.0" "acorn": "^8.11.0"
}, },
@@ -20981,7 +20961,7 @@
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"devOptional": true "dev": true
}, },
"node_modules/tsconfig-paths": { "node_modules/tsconfig-paths": {
"version": "3.15.0", "version": "3.15.0",
@@ -21477,7 +21457,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"devOptional": true "dev": true
}, },
"node_modules/v8-to-istanbul": { "node_modules/v8-to-istanbul": {
"version": "8.1.1", "version": "8.1.1",
@@ -22536,7 +22516,7 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"devOptional": true, "dev": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }

View File

@@ -172,15 +172,15 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
setActiveSubMenu(null); setActiveSubMenu(null);
}} }}
> >
<div className="menu-button"> <span className="menu-button">
{menu} {menu}
<span className="dropdown-icon"> <span className="dropdown-icon">
<ArrowIcon /> <ArrowIcon />
</span> </span>
</div> </span>
{activeMenu === menu && ( {activeMenu === menu && (
<div className="dropdown-menu"> <span className="dropdown-menu">
{items.map((item) => {items.map((item) =>
item.submenu ? ( item.submenu ? (
<button <button
@@ -190,19 +190,19 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
onMouseEnter={() => setActiveSubMenu(item.label)} onMouseEnter={() => setActiveSubMenu(item.label)}
onMouseLeave={() => setActiveSubMenu(null)} onMouseLeave={() => setActiveSubMenu(null)}
> >
<div className="menu-item"> <span className="menu-item">
<span>{item.label}</span> <span>{item.label}</span>
<span className="dropdown-icon"> <span className="dropdown-icon">
<ArrowIcon /> <ArrowIcon />
</span> </span>
</div> </span>
{activeSubMenu === item.label && renderSubMenu(item.submenu, item.label)} {activeSubMenu === item.label && renderSubMenu(item.submenu, item.label)}
</button> </button>
) : ( ) : (
renderMenuItem(item) renderMenuItem(item)
) )
)} )}
</div> </span>
)} )}
</button> </button>
))} ))}
@@ -222,9 +222,9 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
setActiveModule("builder"); setActiveModule("builder");
}} }}
> >
<div className="menu-button"> <span className="menu-button">
Version history <div className="value">Ctrl + H</div> Version history <span className="value">Ctrl + H</span>
</div> </span>
</button> </button>
{/* Theme */} {/* Theme */}
@@ -238,14 +238,14 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
}} }}
onClick={handleThemeChange} onClick={handleThemeChange}
> >
<div className="menu-button"> <span className="menu-button">
Theme <div className="value">{savedTheme}</div> Theme <span className="value">{savedTheme}</span>
</div> </span>
</button> </button>
{/* Log out */} {/* Log out */}
<button id="logout" className="menu-button-container" onClick={handleLogout}> <button id="logout" className="menu-button-container" onClick={handleLogout}>
<div className="menu-button">Log out</div> <span className="menu-button">Log out</span>
</button> </button>
</div> </div>
</div> </div>

View File

@@ -43,15 +43,21 @@ export default function Controls() {
useEffect(() => { useEffect(() => {
if (controlsRef.current) { if (controlsRef.current) {
(controlsRef.current as any).mouseButtons.left = CONSTANTS.thirdPersonControls.leftMouse; (controlsRef.current as any).mouseButtons.left =
(controlsRef.current as any).mouseButtons.right = CONSTANTS.thirdPersonControls.rightMouse; CONSTANTS.thirdPersonControls.leftMouse;
(controlsRef.current as any).mouseButtons.right =
CONSTANTS.thirdPersonControls.rightMouse;
} }
if (!projectId) return; if (!projectId) return;
getCameraApi(projectId) getCameraApi(projectId)
.then((data) => { .then((data) => {
if (data?.position && data?.target) { if (data?.position && data?.target) {
controlsRef.current?.setPosition(data.position.x, data.position.y, data.position.z); controlsRef.current?.setPosition(
data.position.x,
data.position.y,
data.position.z
);
controlsRef.current?.setTarget(data.target.x, data.target.y, data.target.z); controlsRef.current?.setTarget(data.target.x, data.target.y, data.target.z);
} else { } else {
controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition); controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition);
@@ -62,46 +68,68 @@ export default function Controls() {
}, [projectId]); }, [projectId]);
useEffect(() => { useEffect(() => {
if (resetCamera && projectId && (layoutType === "default" || (layoutType === "useCase" && organization === ALPHA_ORG))) { if (resetCamera && projectId) {
controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition); controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition);
controlsRef.current?.setTarget(...CONSTANTS.threeDimension.defaultTarget); controlsRef.current?.setTarget(...CONSTANTS.threeDimension.defaultTarget);
controlsRef.current?.rotateAzimuthTo(CONSTANTS.threeDimension.defaultAzimuth); controlsRef.current?.rotateAzimuthTo(CONSTANTS.threeDimension.defaultAzimuth);
if (!builderSocket?.connected) { if (
setCameraApi( layoutType === "default" ||
projectId, (layoutType === "useCase" && organization === ALPHA_ORG)
new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition), )
new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget), if (!builderSocket?.connected) {
new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation) setCameraApi(
); projectId,
} else { new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition),
const camData = { new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget),
organization, new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation)
userId: userId, );
position: new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition), } else {
target: new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget), const camData = {
rotation: new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation), organization,
socketId: builderSocket.id, userId: userId,
projectId, position: new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition),
}; target: new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget),
builderSocket.emit("v1:Camera:set", camData); rotation: new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation),
} socketId: builderSocket.id,
projectId,
};
builderSocket.emit("v1:Camera:set", camData);
}
setResetCamera(false); setResetCamera(false);
} }
}, [resetCamera, builderSocket, projectId, layoutType]); }, [resetCamera, builderSocket, projectId, layoutType]);
useEffect(() => { useEffect(() => {
controlsRef.current?.setBoundary(new THREE.Box3(new THREE.Vector3(...CONSTANTS.threeDimension.boundaryBottom), new THREE.Vector3(...CONSTANTS.threeDimension.boundaryTop))); controlsRef.current?.setBoundary(
new THREE.Box3(
new THREE.Vector3(...CONSTANTS.threeDimension.boundaryBottom),
new THREE.Vector3(...CONSTANTS.threeDimension.boundaryTop)
)
);
// state.scene.add(new THREE.Box3Helper(new THREE.Box3(new THREE.Vector3(...CONSTANTS.threeDimension.boundaryBottom), new THREE.Vector3(...CONSTANTS.threeDimension.boundaryTop)), 0xffff00)); // state.scene.add(new THREE.Box3Helper(new THREE.Box3(new THREE.Vector3(...CONSTANTS.threeDimension.boundaryBottom), new THREE.Vector3(...CONSTANTS.threeDimension.boundaryTop)), 0xffff00));
let hasInteracted = false; let hasInteracted = false;
let intervalId: NodeJS.Timeout | null = null; let intervalId: NodeJS.Timeout | null = null;
const handleRest = () => { const handleRest = () => {
if (hasInteracted && controlsRef.current && state.camera.position && !toggleView && builderSocket && camType === "perspective") { if (
hasInteracted &&
controlsRef.current &&
state.camera.position &&
!toggleView &&
builderSocket &&
camType === "perspective"
) {
const position = state.camera.position; const position = state.camera.position;
if (position.x === 0 && position.y === 0 && position.z === 0) return; if (position.x === 0 && position.y === 0 && position.z === 0) return;
updateCamPosition(controlsRef, builderSocket, position, state.camera.rotation, projectId); updateCamPosition(
controlsRef,
builderSocket,
position,
state.camera.rotation,
projectId
);
stopInterval(); stopInterval();
} }
}; };
@@ -125,7 +153,12 @@ export default function Controls() {
}; };
const controls = controlsRef.current; const controls = controlsRef.current;
if (controls && !toggleView && camType === "perspective" && (layoutType === "default" || (layoutType === "useCase" && organization === ALPHA_ORG))) { if (
controls &&
!toggleView &&
camType === "perspective" &&
(layoutType === "default" || (layoutType === "useCase" && organization === ALPHA_ORG))
) {
controls.addEventListener("sleep", handleRest); controls.addEventListener("sleep", handleRest);
controls.addEventListener("control", startInterval); controls.addEventListener("control", startInterval);
controls.addEventListener("controlend", stopInterval); controls.addEventListener("controlend", stopInterval);
@@ -146,7 +179,11 @@ export default function Controls() {
<CameraControls <CameraControls
makeDefault makeDefault
ref={controlsRef} ref={controlsRef}
minDistance={toggleView || camType === "orthographic" ? CONSTANTS.twoDimension.minDistance : CONSTANTS.threeDimension.minDistance} minDistance={
toggleView || camType === "orthographic"
? CONSTANTS.twoDimension.minDistance
: CONSTANTS.threeDimension.minDistance
}
maxDistance={CONSTANTS.thirdPersonControls.maxDistance} maxDistance={CONSTANTS.thirdPersonControls.maxDistance}
minZoom={CONSTANTS.thirdPersonControls.minZoom} minZoom={CONSTANTS.thirdPersonControls.minZoom}
maxZoom={CONSTANTS.thirdPersonControls.maxZoom} maxZoom={CONSTANTS.thirdPersonControls.maxZoom}