refactor(MenuBar): replace divs with spans for menu buttons to improve semantics

refactor(Controls): format code for better readability and maintainability
This commit is contained in:
2025-09-22 13:20:19 +05:30
parent 34205f930b
commit 09027fe9f1
2 changed files with 78 additions and 41 deletions

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

@@ -37,15 +37,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);
@@ -56,46 +62,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();
} }
}; };
@@ -119,7 +147,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);
@@ -140,7 +173,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}