Dwinzo_dev/app/src/utils/shortcutkeys/handleShortcutKeys.ts

241 lines
7.2 KiB
TypeScript

import React, { useEffect } from "react";
import useModuleStore, { useThreeDStore } from "../../store/useModuleStore";
import { usePlayerStore, useToggleStore } from "../../store/useUIToggleStore";
import {
useActiveSubTool,
useActiveTool,
useAddAction,
useDeleteTool,
useSaveVersion,
useSelectedWallItem,
useShortcutStore,
useToggleView,
useToolMode,
useViewSceneStore,
} from "../../store/builder/store";
import useCameraModeStore, {
usePlayButtonStore,
} from "../../store/usePlayButtonStore";
import { detectModifierKeys } from "./detectModifierKeys";
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
import { useLogger } from "../../components/ui/log/LoggerContext";
const KeyPressListener: React.FC = () => {
const { activeModule, setActiveModule } = useModuleStore();
const { setActiveSubTool } = useActiveSubTool();
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
const { setToggleThreeD } = useThreeDStore();
const { setToolMode } = useToolMode();
const { isPlaying, setIsPlaying } = usePlayButtonStore();
const { toggleView, setToggleView } = useToggleView();
const { setDeleteTool } = useDeleteTool();
const { setAddAction } = useAddAction();
const { setSelectedWallItem } = useSelectedWallItem();
const { setActiveTool } = useActiveTool();
const { clearSelectedZone } = useSelectedZoneStore();
const { showShortcuts, setShowShortcuts } = useShortcutStore();
const { setWalkMode } = useCameraModeStore();
const { setIsVersionSaved } = useSaveVersion();
const { isLogListVisible, setIsLogListVisible } = useLogger();
const { hidePlayer, setHidePlayer } = usePlayerStore();
const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore();
const isTextInput = (element: Element | null): boolean =>
element instanceof HTMLInputElement ||
element instanceof HTMLTextAreaElement ||
element?.getAttribute("contenteditable") === "true";
const handleModuleSwitch = (keyCombination: string) => {
const modules: Record<string, string> = {
"1": "builder",
"2": "simulation",
"3": "visualization",
"4": "market",
};
const module = modules[keyCombination];
if (module && !toggleView) {
console.log("hi");
setActiveTool("cursor");
setActiveSubTool("cursor");
if (module === "market") setToggleUI(false, false);
setActiveModule(module);
}
};
const handlePrimaryTools = (key: string) => {
const toolMap: Record<string, string> = {
V: "cursor",
X: "delete",
H: "free-hand",
};
const tool = toolMap[key];
if (tool) {
setActiveTool(tool);
setActiveSubTool(tool);
}
};
const handleBuilderShortcuts = (key: string) => {
if (activeModule !== "builder" || isPlaying) return;
if (key === "TAB") {
const toggleTo2D = toggleView;
setToggleView(!toggleTo2D);
setToggleThreeD(toggleTo2D);
setToggleUI(toggleTo2D, toggleTo2D);
if (toggleTo2D) {
setSelectedWallItem(null);
setDeleteTool(false);
setAddAction(null);
}
setActiveTool("cursor");
setActiveSubTool("cursor");
return;
}
// These should only apply in 2D view
const twoDToolConfigs: Record<string, { tool: string; mode: string }> = {
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 handleSidebarShortcuts = (key: string) => {
if (activeModule === "market") return;
const updateLocalStorage = (left: boolean, right: boolean) => {
localStorage.setItem("navBarUiLeft", JSON.stringify(left));
localStorage.setItem("navBarUiRight", JSON.stringify(right));
};
switch (key) {
case "Ctrl+\\":
if (toggleUILeft === toggleUIRight) {
const newState = !toggleUILeft;
setToggleUI(newState, newState);
updateLocalStorage(newState, newState);
} else {
setToggleUI(true, true);
updateLocalStorage(true, true);
}
break;
case "Ctrl+]":
setToggleUI(toggleUILeft, !toggleUIRight);
updateLocalStorage(toggleUILeft, !toggleUIRight);
break;
case "Ctrl+[":
setToggleUI(!toggleUILeft, toggleUIRight);
updateLocalStorage(!toggleUILeft, toggleUIRight);
break;
default:
break;
}
};
const handleKeyPress = (event: KeyboardEvent) => {
console.log(
"isTextInput(document.activeElement): ",
isTextInput(document.activeElement)
);
if (isTextInput(document.activeElement)) return;
const keyCombination = detectModifierKeys(event);
if (
!keyCombination ||
["F5", "F11", "F12"].includes(event.key) ||
keyCombination === "Ctrl+R"
)
return;
console.log("keyCombination: ", keyCombination);
event.preventDefault();
// Shortcuts specific for sidebar visibility toggle and others specific to sidebar if added
handleSidebarShortcuts(keyCombination);
// 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 === "L") {
setIsLogListVisible(!isLogListVisible);
}
if (keyCombination === "H") {
setHidePlayer(!hidePlayer);
}
if (keyCombination === "ESCAPE") {
setWalkMode(false);
setActiveTool("cursor");
setActiveSubTool("cursor");
setIsPlaying(false);
clearSelectedZone();
setShowShortcuts(false);
setIsVersionSaved(false);
setIsLogListVisible(false);
}
if (keyCombination === "Ctrl+Shift+?") {
setShowShortcuts(!showShortcuts);
}
if (keyCombination === "U") {
console.log("viewSceneLabels: ", viewSceneLabels);
setViewSceneLabels((prev) => !prev);
}
// Placeholder for future implementation
if (
["Ctrl+Z", "Ctrl+Y", "Ctrl+Shift+Z", "Ctrl+F"].includes(keyCombination)
) {
// Implement undo/redo/help/find/shortcuts
}
};
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => window.removeEventListener("keydown", handleKeyPress);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
activeModule,
toggleUIRight,
toggleUILeft,
toggleView,
showShortcuts,
isPlaying,
isLogListVisible,
hidePlayer,
]);
return null;
};
export default KeyPressListener;