diff --git a/app/src/components/layout/sidebarLeft/Header.tsx b/app/src/components/layout/sidebarLeft/Header.tsx index 6c2a8f2..70668af 100644 --- a/app/src/components/layout/sidebarLeft/Header.tsx +++ b/app/src/components/layout/sidebarLeft/Header.tsx @@ -28,7 +28,7 @@ const Header: React.FC = () => { } }} > -
{toggleUI ? "Hide" : "Show"} sidebar (ctrl + .)
+
{toggleUI ? "Hide" : "Show"} sidebar (ctrl + \)
diff --git a/app/src/components/ui/ModuleToggle.tsx b/app/src/components/ui/ModuleToggle.tsx index 053e251..a1583e1 100644 --- a/app/src/components/ui/ModuleToggle.tsx +++ b/app/src/components/ui/ModuleToggle.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React from "react"; import useModuleStore from "../../store/useModuleStore"; import { BuilderIcon, @@ -14,45 +14,60 @@ const ModuleToggle: React.FC = () => { return (
-
{ setActiveModule("builder"); - setToggleUI(localStorage.getItem('navBarUi') ? localStorage.getItem('navBarUi') === 'true' : true) + setToggleUI( + localStorage.getItem("navBarUi") + ? localStorage.getItem("navBarUi") === "true" + : true + ); }} >
Builder
-
-
+
-
+
-
+
Market Place
-
+ ); }; diff --git a/app/src/components/ui/list/DropDownList.tsx b/app/src/components/ui/list/DropDownList.tsx index 0d93d72..2a77303 100644 --- a/app/src/components/ui/list/DropDownList.tsx +++ b/app/src/components/ui/list/DropDownList.tsx @@ -103,10 +103,9 @@ const DropDownList: React.FC = ({ return (
-
- + {/* eslint-disable-next-line */} +
+
{value}
{showFocusIcon && (
diff --git a/app/src/components/ui/simulation/simulationPlayer.tsx b/app/src/components/ui/simulation/simulationPlayer.tsx index ac49c8d..6ef8d2f 100644 --- a/app/src/components/ui/simulation/simulationPlayer.tsx +++ b/app/src/components/ui/simulation/simulationPlayer.tsx @@ -44,7 +44,7 @@ const SimulationPlayer: React.FC = () => { setReset(false); }, 0) } - }, [isReset]) + }, [isReset, setReset]) // Button functions const handleReset = () => { diff --git a/app/src/modules/collaboration/camera/collabCams.tsx b/app/src/modules/collaboration/camera/collabCams.tsx index d4bc69e..6ce26b0 100644 --- a/app/src/modules/collaboration/camera/collabCams.tsx +++ b/app/src/modules/collaboration/camera/collabCams.tsx @@ -165,6 +165,7 @@ const CamModelsGroup = () => { socket.off("userDisConnectResponse"); socket.off("cameraUpdateResponse"); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [email, loader, navigate, setActiveUsers, socket]); useFrame(() => { @@ -231,30 +232,9 @@ const CamModelsGroup = () => { }); } }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - // collide validate - const collisionThreshold = 0.001; - - const collidedCamUUIDs = new Set(); - - for (let i = 0; i < cams.length; i++) { - for (let j = i + 1; j < cams.length; j++) { - const posA = cams[i].position; - const posB = cams[j].position; - - const distSquared = - Math.pow(posA.x - posB.x, 2) + - Math.pow(posA.y - posB.y, 2) + - Math.pow(posA.z - posB.z, 2); - - if (distSquared < collisionThreshold ** 2) { - collidedCamUUIDs.add(cams[i].uuid); - collidedCamUUIDs.add(cams[j].uuid); - } - } - } - return ( {cams.map((cam, index) => ( @@ -277,6 +257,10 @@ const CamModelsGroup = () => { textAlign: "center", fontFamily: "Arial, sans-serif", display: `${activeModule !== "visualization" ? "" : "none"}`, + opacity: `${ + selectedUser?.name !== cam.userData.userName ? 1 : 0 + }`, + transition: "opacity .2s ease", }} position={[-0.015, 0, 0.7]} > diff --git a/app/src/modules/scene/camera/camMode.tsx b/app/src/modules/scene/camera/camMode.tsx index d216ee1..0a0f954 100644 --- a/app/src/modules/scene/camera/camMode.tsx +++ b/app/src/modules/scene/camera/camMode.tsx @@ -19,12 +19,10 @@ const CamMode: React.FC = () => { const handlePointerLockChange = async () => { if (document.pointerLockElement && !toggleView) { // Pointer is locked - } else { + } else if (camMode === "FirstPerson" && !toggleView) { // Pointer is unlocked - if (camMode === "FirstPerson" && !toggleView) { - setCamMode("ThirdPerson"); - await switchToThirdPerson(state.controls, state.camera); - } + setCamMode("ThirdPerson"); + await switchToThirdPerson(state.controls, state.camera); } }; diff --git a/app/src/modules/visualization/RealTimeVisulization.tsx b/app/src/modules/visualization/RealTimeVisulization.tsx index eaff2af..8bf1613 100644 --- a/app/src/modules/visualization/RealTimeVisulization.tsx +++ b/app/src/modules/visualization/RealTimeVisulization.tsx @@ -155,7 +155,7 @@ const RealTimeVisulization: React.FC = () => { height: 0, }); useEffect(() => { - const canvas = document.getElementById("real-time-vis-canvas"); + const canvas = document.getElementById("work-space-three-d-canvas"); if (!canvas) return; const updateCanvasDimensions = () => { diff --git a/app/src/modules/visualization/functions/captureVisualization.ts b/app/src/modules/visualization/functions/captureVisualization.ts index d8d3ba2..291a002 100644 --- a/app/src/modules/visualization/functions/captureVisualization.ts +++ b/app/src/modules/visualization/functions/captureVisualization.ts @@ -1,7 +1,7 @@ import html2canvas from "html2canvas"; export const captureVisualization = async (): Promise => { - const container = document.getElementById("real-time-vis-canvas"); + const container = document.getElementById("work-space-three-d-canvas"); if (!container) { console.error("Container element not found"); return null; diff --git a/app/src/modules/visualization/functions/handleUiDrop.ts b/app/src/modules/visualization/functions/handleUiDrop.ts index a70742e..0d02936 100644 --- a/app/src/modules/visualization/functions/handleUiDrop.ts +++ b/app/src/modules/visualization/functions/handleUiDrop.ts @@ -28,7 +28,7 @@ export const createHandleDrop = ({ if (!data || selectedZone.zoneName === "") return; const droppedData = JSON.parse(data); - const canvasElement = document.getElementById("real-time-vis-canvas"); + const canvasElement = document.getElementById("work-space-three-d-canvas"); if (!canvasElement) throw new Error("Canvas element not found"); const rect = canvasElement.getBoundingClientRect(); diff --git a/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx b/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx index 054757b..d73104f 100644 --- a/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx +++ b/app/src/modules/visualization/widgets/2d/DraggableWidget.tsx @@ -283,7 +283,7 @@ export const DraggableWidget = ({ // Current: Two identical useEffect hooks for canvas dimensions // Remove the duplicate and keep only one useEffect(() => { - const canvas = document.getElementById("real-time-vis-canvas"); + const canvas = document.getElementById("work-space-three-d-canvas"); if (!canvas) return; const updateCanvasDimensions = () => { diff --git a/app/src/modules/visualization/widgets/3d/Dropped3dWidget.tsx b/app/src/modules/visualization/widgets/3d/Dropped3dWidget.tsx index 4ca3c31..cf4d97b 100644 --- a/app/src/modules/visualization/widgets/3d/Dropped3dWidget.tsx +++ b/app/src/modules/visualization/widgets/3d/Dropped3dWidget.tsx @@ -89,7 +89,7 @@ export default function Dropped3dWidgets() { if (widgetSubOption === "Floating" || widgetSubOption === "2D") return; if (selectedZone.zoneName === "") return; - const canvasElement = document.getElementById("real-time-vis-canvas"); + const canvasElement = document.getElementById("work-space-three-d-canvas"); if (!canvasElement) return; @@ -601,7 +601,7 @@ export default function Dropped3dWidgets() { const handleRightClick3d = (event: React.MouseEvent, id: string) => { event.preventDefault(); - const canvasElement = document.getElementById("real-time-vis-canvas"); + const canvasElement = document.getElementById("work-space-three-d-canvas"); if (!canvasElement) throw new Error("Canvas element not found"); const canvasRect = canvasElement.getBoundingClientRect(); @@ -654,7 +654,7 @@ export default function Dropped3dWidgets() { setSelectedChartId({ id: id, type: type }) event.preventDefault(); const canvasElement = document.getElementById( - "real-time-vis-canvas" + "work-space-three-d-canvas" ); if (!canvasElement) throw new Error("Canvas element not found"); const canvasRect = canvasElement.getBoundingClientRect(); diff --git a/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx b/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx index ec86fb6..5e26975 100644 --- a/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx +++ b/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx @@ -1,8 +1,6 @@ -import { WalletIcon } from "../../../../components/icons/3dChartIcons"; import { useEffect, useRef, useState } from "react"; import { useDroppedObjectsStore, - Zones, } from "../../../../store/visualization/useDroppedObjectsStore"; import useModuleStore from "../../../../store/useModuleStore"; import { determinePosition } from "../../functions/determinePosition"; @@ -14,14 +12,12 @@ import { DeleteIcon, } from "../../../../components/icons/ExportCommonIcons"; import DistanceLines from "./DistanceLines"; // Import the DistanceLines component -import { deleteFloatingWidgetApi } from "../../../../services/visulization/zone/deleteFloatingWidget"; import TotalCardComponent from "./cards/TotalCardComponent"; import WarehouseThroughputComponent from "./cards/WarehouseThroughputComponent"; import FleetEfficiencyComponent from "./cards/FleetEfficiencyComponent"; import { useWidgetStore } from "../../../../store/useWidgetStore"; import { useSocketStore } from "../../../../store/store"; -import { useClickOutside } from "../../functions/handleWidgetsOuterClick"; import { usePlayButtonStore } from "../../../../store/usePlayButtonStore"; import { useSelectedZoneStore } from "../../../../store/visualization/useZoneStore"; interface DraggingState { @@ -54,7 +50,7 @@ const DroppedObjects: React.FC = () => { const updateObjectPosition = useDroppedObjectsStore( (state) => state.updateObjectPosition ); - const { setSelectedZone, selectedZone } = useSelectedZoneStore(); + const { selectedZone } = useSelectedZoneStore(); const deleteObject = useDroppedObjectsStore((state) => state.deleteObject); @@ -79,12 +75,8 @@ const DroppedObjects: React.FC = () => { bottom: number | "auto"; } | null>(null); // State to track the current position during drag const animationRef = useRef(null); - const { activeModule } = useModuleStore(); const chartWidget = useRef(null); - // useClickOutside(chartWidget, () => { - // setSelectedChartId(null); - // }); const kebabRef = useRef(null); // Clean up animation frame on unmount @@ -141,12 +133,6 @@ const DroppedObjects: React.FC = () => { } deleteObject(zoneName, id); - // let res = await deleteFloatingWidgetApi(id, organization); - // s - - // if (res.message === "FloatingWidget deleted successfully") { - // deleteObject(zoneName, id, index); // Call the deleteObject method from the store - // } } catch (error) {} } @@ -160,7 +146,7 @@ const DroppedObjects: React.FC = () => { const obj = zone.objects[index]; const element = event.currentTarget as HTMLElement; element.setPointerCapture(event.pointerId); - const container = document.getElementById("real-time-vis-canvas"); + const container = document.getElementById("work-space-three-d-canvas"); if (!container) return; const rect = container.getBoundingClientRect(); @@ -322,6 +308,7 @@ const DroppedObjects: React.FC = () => { updateObjectPosition(zoneName, draggingIndex.index, boundedPosition); } } catch (error) { + console.log(error); } finally { setDraggingIndex(null); setOffset(null); @@ -343,7 +330,7 @@ const DroppedObjects: React.FC = () => { const handlePointerMove = (event: React.PointerEvent) => { if (!draggingIndex || !offset) return; if (isPlaying === true) return; - const container = document.getElementById("real-time-vis-canvas"); + const container = document.getElementById("work-space-three-d-canvas"); if (!container) return; const rect = container.getBoundingClientRect(); @@ -394,12 +381,6 @@ const DroppedObjects: React.FC = () => { // Update position immediately without animation frame updateObjectPosition(zoneName, draggingIndex.index, newPosition); - // if (!animationRef.current) { - // animationRef.current = requestAnimationFrame(() => { - // updateObjectPosition(zoneName, draggingIndex.index, newPosition); - // animationRef.current = null; - // }); - // } }; const handlePointerUp = async (event: React.PointerEvent) => { @@ -407,7 +388,7 @@ const DroppedObjects: React.FC = () => { if (!draggingIndex || !offset) return; if (isPlaying === true) return; - const container = document.getElementById("real-time-vis-canvas"); + const container = document.getElementById("work-space-three-d-canvas"); if (!container) return; const rect = container.getBoundingClientRect(); @@ -450,11 +431,6 @@ const DroppedObjects: React.FC = () => { // Save to backend const email = localStorage.getItem("email") || ""; const organization = email?.split("@")[1]?.split(".")[0]; - // const response = await addingFloatingWidgets(zone.zoneId, organization, { - // ...zone.objects[draggingIndex.index], - // position: boundedPosition, - // }); - let updateFloatingWidget = { organization: organization, widget: { @@ -468,21 +444,9 @@ const DroppedObjects: React.FC = () => { visualizationSocket.emit("v2:viz-float:add", updateFloatingWidget); } - // if (response.message === "Widget updated successfully") { - updateObjectPosition(zoneName, draggingIndex.index, boundedPosition); - // } - - // // Clean up - // setDraggingIndex(null); - // setOffset(null); - // setActiveEdges(null); // Clear active edges - // setCurrentPosition(null); // Reset current position - // if (animationRef.current) { - // cancelAnimationFrame(animationRef.current); - // animationRef.current = null; - // } } catch (error) { + console.log(error); } finally { // Clean up regardless of success or failure setDraggingIndex(null); diff --git a/app/src/modules/visualization/widgets/panel/Panel.tsx b/app/src/modules/visualization/widgets/panel/Panel.tsx index ee2f730..c95ce13 100644 --- a/app/src/modules/visualization/widgets/panel/Panel.tsx +++ b/app/src/modules/visualization/widgets/panel/Panel.tsx @@ -56,7 +56,6 @@ const Panel: React.FC = ({ setZonesData, waitingPanels, }) => { - const { widgetSelect, setWidgetSelect } = useAsset3dWidget(); const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({}); const [panelDimensions, setPanelDimensions] = useState<{ [side in Side]?: { width: number; height: number }; @@ -74,7 +73,7 @@ const Panel: React.FC = ({ // Track canvas dimensions useEffect(() => { - const canvas = document.getElementById("real-time-vis-canvas"); + const canvas = document.getElementById("work-space-three-d-canvas"); if (!canvas) return; const updateCanvasDimensions = () => { @@ -186,7 +185,7 @@ const Panel: React.FC = ({ // Add widget to panel const addWidgetToPanel = async (asset: any, panel: Side) => { - const email = localStorage.getItem("email") || ""; + const email = localStorage.getItem("email") ?? ""; const organization = email?.split("@")[1]?.split(".")[0]; const newWidget = { diff --git a/app/src/pages/Project.tsx b/app/src/pages/Project.tsx index 3f82385..bb929f7 100644 --- a/app/src/pages/Project.tsx +++ b/app/src/pages/Project.tsx @@ -102,7 +102,7 @@ const Project: React.FC = () => { )}
{ )} - {activeModule != "market" &&
} + {activeModule !== "market" && !selectedUser &&
}
); }; diff --git a/app/src/styles/components/templates.scss b/app/src/styles/components/templates.scss index a71354c..eea4354 100644 --- a/app/src/styles/components/templates.scss +++ b/app/src/styles/components/templates.scss @@ -7,7 +7,7 @@ top: 0; left: 0; outline: 8px solid var(--user-color); - outline-offset: -3px; + outline-offset: -4px; border-radius: #{$border-radius-xlarge}; .follower-name { diff --git a/app/src/utils/shortcutkeys/handleShortcutKeys.ts b/app/src/utils/shortcutkeys/handleShortcutKeys.ts index 52877b9..a08834c 100644 --- a/app/src/utils/shortcutkeys/handleShortcutKeys.ts +++ b/app/src/utils/shortcutkeys/handleShortcutKeys.ts @@ -1,7 +1,4 @@ -// Importing React and useEffect from React library import React, { useEffect } from "react"; - -// Importing the necessary hooks and types from the application's state management stores import useModuleStore, { useThreeDStore } from "../../store/useModuleStore"; import useToggleStore from "../../store/useUIToggleStore"; import { @@ -14,185 +11,141 @@ import { useToolMode, } from "../../store/store"; import { usePlayButtonStore } from "../../store/usePlayButtonStore"; - -// Utility function to detect modifier keys (Ctrl, Alt, Shift) and key combinations import { detectModifierKeys } from "./detectModifierKeys"; -// KeyPressListener component to handle global keyboard shortcuts const KeyPressListener: React.FC = () => { - // Accessing state and actions from different stores - const { activeModule, setActiveModule } = useModuleStore(); // Module management (e.g., builder, simulation, visualization) - const { setActiveSubTool } = useActiveSubTool(); // Sub-tool management - const { toggleUI, setToggleUI } = useToggleStore(); // UI visibility toggle - const { setToggleThreeD } = useThreeDStore(); // 3D view toggle - const { setToolMode } = useToolMode(); // Tool mode management - const { setIsPlaying } = usePlayButtonStore(); // Play button state management + const { activeModule, setActiveModule } = useModuleStore(); + const { setActiveSubTool } = useActiveSubTool(); + const { toggleUI, setToggleUI } = useToggleStore(); + const { setToggleThreeD } = useThreeDStore(); + const { setToolMode } = useToolMode(); + const { setIsPlaying } = usePlayButtonStore(); + const { toggleView, setToggleView } = useToggleView(); + const { setDeleteTool } = useDeleteTool(); + const { setAddAction } = useAddAction(); + const { setSelectedWallItem } = useSelectedWallItem(); + const { setActiveTool } = useActiveTool(); - // Wall and tool-related actions - const { toggleView, setToggleView } = useToggleView(); // 2D/3D toggle state - const { setDeleteTool } = useDeleteTool(); // Delete tool action - const { setAddAction } = useAddAction(); // Add action management - const { setSelectedWallItem } = useSelectedWallItem(); // Selected wall item management - const { setActiveTool } = useActiveTool(); // Active tool management + const isTextInput = (element: Element | null): boolean => + element instanceof HTMLInputElement || + element instanceof HTMLTextAreaElement || + element?.getAttribute("contenteditable") === "true"; + + const handleModuleSwitch = (keyCombination: string) => { + const modules: Record = { + "1": "builder", + "2": "simulation", + "3": "visualization", + "4": "market", + }; + const module = modules[keyCombination]; + if (module && !toggleView) { + setActiveTool("cursor"); + setActiveSubTool("cursor"); + if (module === "market") setToggleUI(false); + setActiveModule(module); + } + }; + + const handlePrimaryTools = (key: string) => { + const toolMap: Record = { + V: "cursor", + X: "delete", + H: "free-hand", + }; + const tool = toolMap[key]; + if (tool) { + setActiveTool(tool); + setActiveSubTool(tool); + } + }; + + const handleBuilderShortcuts = (key: string) => { + if (activeModule !== "builder") return; + + if (key === "TAB") { + const toggleTo2D = toggleView; + setToggleView(!toggleTo2D); + setToggleThreeD(toggleTo2D); + if (toggleTo2D) { + setSelectedWallItem(null); + setDeleteTool(false); + setAddAction(null); + } + setActiveTool("cursor"); + setActiveSubTool("cursor"); + return; + } + + // These should only apply in 2D view + const twoDToolConfigs: Record = { + Q: { tool: "draw-wall", mode: "Wall" }, + "6": { tool: "draw-wall", mode: "Wall" }, + R: { tool: "draw-aisle", mode: "Aisle" }, + "7": { tool: "draw-aisle", mode: "Aisle" }, + E: { tool: "draw-zone", mode: "Zone" }, + "8": { tool: "draw-zone", mode: "Zone" }, + T: { tool: "draw-floor", mode: "Floor" }, + "9": { tool: "draw-floor", mode: "Floor" }, + }; + + const config = twoDToolConfigs[key]; + if (toggleView && config) { + setActiveTool(config.tool); + setToolMode(config.mode); + } + + // Measurement tool should work in both 2D and 3D + if (key === "M") { + setActiveTool("measure"); + setToolMode("MeasurementScale"); + } + }; + + + const handleKeyPress = (event: KeyboardEvent) => { + if (isTextInput(document.activeElement)) return; + + const keyCombination = detectModifierKeys(event); + if (!keyCombination || ["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") return; + + event.preventDefault(); + + if (keyCombination === "Ctrl+\\") { + if (activeModule !== "market") setToggleUI(!toggleUI); + return; + } + + // Active module selection (builder, simulation, etc.) + handleModuleSwitch(keyCombination); + // Common editing tools: cursor | delete | free-hand + handlePrimaryTools(keyCombination); + // Shortcuts specific to the builder module (e.g., drawing and measurement tools) + handleBuilderShortcuts(keyCombination); + + // Shortcut to enter play mode + if (keyCombination === "Ctrl+P" && !toggleView) { + setIsPlaying(true); + } + + if (keyCombination === "ESCAPE") { + setActiveTool("cursor"); + setIsPlaying(false); + } + + // Placeholder for future implementation + if (["Ctrl+Z", "Ctrl+Y", "Ctrl+Shift+Z", "Ctrl+H", "Ctrl+F", "Ctrl+?"].includes(keyCombination)) { + // Implement undo/redo/help/find/shortcuts + } + }; - // useEffect to manage global keyboard shortcuts useEffect(() => { - // Function to handle keydown events - const handleKeyPress = (event: KeyboardEvent) => { - // Identify the currently focused element - const activeElement = document.activeElement; - - // Check if the user is typing in an input field, textarea, or contenteditable element - const isTyping = - activeElement instanceof HTMLInputElement || - activeElement instanceof HTMLTextAreaElement || - (activeElement && activeElement.getAttribute("contenteditable") === "true"); - - if (isTyping) { - return; // Skip shortcut handling while typing - } - - // Detect the combination of keys pressed - const keyCombination = detectModifierKeys(event); - - // Allow browser default behavior for specific keys (e.g., F5 for refresh) - if (["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") { - return; - } - - // Prevent the default browser action for other handled key presses - event.preventDefault(); - - if (keyCombination) { - // Switch between different modules (e.g., builder, simulation) - if (keyCombination === "1" && !toggleView) { - setActiveTool("cursor"); - setActiveSubTool("cursor"); - setActiveModule("builder"); - } - if (keyCombination === "2" && !toggleView) { - setActiveTool("cursor"); - setActiveSubTool("cursor"); - setActiveModule("simulation"); - } - if (keyCombination === "3" && !toggleView) { - setActiveTool("cursor"); - setActiveSubTool("cursor"); - setActiveModule("visualization"); - } - if (keyCombination === "4" && !toggleView) { - setActiveTool("cursor"); - setActiveSubTool("cursor"); - setToggleUI(false); - setActiveModule("market"); - } - - // Toggle UI visibility - if (keyCombination === "Ctrl+." && activeModule !== "market") { - setToggleUI(!toggleUI); - } - - // Tool selection shortcuts - if (keyCombination === "V") { - setActiveTool("cursor"); - setActiveSubTool("cursor"); - } - if (keyCombination === "X") { - setActiveTool("delete"); - setActiveSubTool("delete"); - } - if (keyCombination === "H") { - setActiveTool("free-hand"); - setActiveSubTool("free-hand"); - } - - // Toggle play mode - if (keyCombination === "Ctrl+P" && !toggleView) { - setIsPlaying(true); - } - - // Builder-specific shortcuts - if (activeModule === "builder") { - if (keyCombination === "TAB") { - // Switch between 2D and 3D views - if (toggleView) { - setToggleView(false); - setToggleThreeD(true); - setActiveTool("cursor"); - } else { - setSelectedWallItem(null); - setDeleteTool(false); - setAddAction(null); - setToggleView(true); - setToggleThreeD(false); - setActiveTool("cursor"); - } - } - - // Wall-related tools - if (toggleView) { - if (keyCombination === "Q" || keyCombination === "6") { - setActiveTool("draw-wall"); - setToolMode("Wall"); - } - if (keyCombination === "R" || keyCombination === "7") { - setActiveTool("draw-aisle"); - setToolMode("Aisle"); - } - if (keyCombination === "E" || keyCombination === "8") { - setActiveTool("draw-zone"); - setToolMode("Zone"); - } - if (keyCombination === "T" || keyCombination === "9") { - setActiveTool("draw-floor"); - setToolMode("Floor"); - } - } - - // Measurement tool - if (keyCombination === "M") { - setActiveTool("measure"); - setToolMode("MeasurementScale"); - } - } - - // Undo and redo actions - if (keyCombination === "Ctrl+Z") { - // Handle undo action - } - if (keyCombination === "Ctrl+Y" || keyCombination === "Ctrl+Shift+Z") { - // Handle redo action - } - - // Helper actions - if (keyCombination === "Ctrl+H") { - // Open help - } - if (keyCombination === "Ctrl+F") { - // Open find functionality - } - if (keyCombination === "Ctrl+?") { - // Show shortcuts info - } - - // Reset to cursor tool and stop play mode - if (keyCombination === "ESCAPE") { - setActiveTool("cursor"); - setIsPlaying(false); - } - } - }; - - // Add keydown event listener window.addEventListener("keydown", handleKeyPress); + return () => window.removeEventListener("keydown", handleKeyPress); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [activeModule, toggleUI, toggleView]); - // Cleanup function to remove the event listener - return () => { - window.removeEventListener("keydown", handleKeyPress); - }; - }, [activeModule, setActiveModule, setActiveSubTool, setActiveTool, setAddAction, setDeleteTool, setIsPlaying, setSelectedWallItem, setToggleThreeD, setToggleUI, setToggleView, setToolMode, toggleUI, toggleView]); // Dependencies to reapply effect if these values change - - return null; // This component does not render any UI + return null; }; export default KeyPressListener;