From e61f860d2182d12f82d61b60b072ee3cc27455ae Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Wed, 18 Jun 2025 18:13:53 +0530 Subject: [PATCH] Refactor asset management to use scene context - Updated MainSceneProvider to clear assets on mount using scene context. - Replaced useAssetsStore with useSceneContext in DropDownList, List, AssetsGroup, Model, Models, SocketResponses, and various control components. - Introduced clearAssets method in asset store for better asset management. - Updated Project component to wrap scene providers correctly. - Fixed naming inconsistencies in vehicle store methods. - Removed unnecessary state management in MaterialAnimator. - Improved code readability and organization across multiple components. --- .../layout/scenes/ComparisonSceneProvider.tsx | 9 + .../components/layout/scenes/MainScene.tsx | 7 +- .../layout/scenes/MainSceneProvider.tsx | 9 + app/src/components/ui/list/DropDownList.tsx | 9 +- app/src/components/ui/list/List.tsx | 14 +- app/src/modules/builder/asset/assetsGroup.tsx | 7 +- .../builder/asset/models/model/model.tsx | 5 +- .../modules/builder/asset/models/models.tsx | 5 +- .../socket/socketResponses.dev.tsx | 8 +- .../selectionControls/copyPasteControls.tsx | 7 +- .../selectionControls/duplicationControls.tsx | 7 +- .../selectionControls/moveControls.tsx | 7 +- .../selectionControls/rotateControls.tsx | 7 +- .../selectionControls/selectionControls.tsx | 5 +- .../transformControls/transformControls.tsx | 9 +- app/src/modules/scene/scene.tsx | 52 +-- app/src/modules/scene/sceneContext.tsx | 17 +- .../modules/simulation/products/products.tsx | 4 +- .../instances/animator/MaterialAnimator.tsx | 30 +- .../instances/storageUnitInstances.tsx | 27 +- app/src/pages/Project.tsx | 12 +- app/src/store/builder/useAssetStore.ts | 371 +++++++++--------- app/src/store/simulation/useVehicleStore.ts | 4 +- 23 files changed, 343 insertions(+), 289 deletions(-) diff --git a/app/src/components/layout/scenes/ComparisonSceneProvider.tsx b/app/src/components/layout/scenes/ComparisonSceneProvider.tsx index e47805c..46749b7 100644 --- a/app/src/components/layout/scenes/ComparisonSceneProvider.tsx +++ b/app/src/components/layout/scenes/ComparisonSceneProvider.tsx @@ -1,7 +1,16 @@ +import { useEffect } from 'react'; import { ProductProvider } from '../../../modules/simulation/products/productContext' import ComparisonScene from './ComparisonScene'; +import { useSceneContext } from '../../../modules/scene/sceneContext'; function ComparisonSceneProvider() { + const { assetStore } = useSceneContext(); + const { clearAssets } = assetStore(); + + useEffect(() => { + clearAssets(); + }, []) + return ( diff --git a/app/src/components/layout/scenes/MainScene.tsx b/app/src/components/layout/scenes/MainScene.tsx index 48d6adf..cafdf4b 100644 --- a/app/src/components/layout/scenes/MainScene.tsx +++ b/app/src/components/layout/scenes/MainScene.tsx @@ -34,9 +34,9 @@ import { useProductStore } from "../../../store/simulation/useProductStore"; import RegularDropDown from "../../ui/inputs/RegularDropDown"; import RenameTooltip from "../../ui/features/RenameTooltip"; import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; -import { useAssetsStore } from "../../../store/builder/useAssetStore"; import { useParams } from "react-router-dom"; import { getUserData } from "../../../functions/getUserData"; +import { useSceneContext } from "../../../modules/scene/sceneContext"; function MainScene() { const { products } = useProductStore(); @@ -55,10 +55,11 @@ function MainScene() { const { setFloatingWidget } = useFloatingWidget(); const { clearComparisonProduct } = useComparisonProduct(); const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem(); - const { setName } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { setName } = assetStore(); const { projectId } = useParams() const { isRenameMode, setIsRenameMode } = useRenameModeStore(); - const { userName, userId, organization, email } = getUserData(); + const { organization } = getUserData(); useEffect(() => { if (activeModule !== 'simulation') { diff --git a/app/src/components/layout/scenes/MainSceneProvider.tsx b/app/src/components/layout/scenes/MainSceneProvider.tsx index 17971fa..8dbea25 100644 --- a/app/src/components/layout/scenes/MainSceneProvider.tsx +++ b/app/src/components/layout/scenes/MainSceneProvider.tsx @@ -1,7 +1,16 @@ +import { useEffect } from 'react' import { ProductProvider } from '../../../modules/simulation/products/productContext' import MainScene from './MainScene' +import { useSceneContext } from '../../../modules/scene/sceneContext'; function MainSceneProvider() { + const { assetStore } = useSceneContext(); + const { clearAssets } = assetStore(); + + useEffect(() => { + clearAssets(); + }, []) + return ( diff --git a/app/src/components/ui/list/DropDownList.tsx b/app/src/components/ui/list/DropDownList.tsx index 3ee3764..753f154 100644 --- a/app/src/components/ui/list/DropDownList.tsx +++ b/app/src/components/ui/list/DropDownList.tsx @@ -3,7 +3,7 @@ import List from "./List"; import { AddIcon, ArrowIcon, FocusIcon } from "../../icons/ExportCommonIcons"; import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect"; import { useZones } from "../../../store/builder/store"; -import { useAssetsStore } from "../../../store/builder/useAssetStore"; +import { useSceneContext } from "../../../modules/scene/sceneContext"; interface DropDownListProps { value?: string; // Value to display in the DropDownList @@ -51,8 +51,9 @@ const DropDownList: React.FC = ({ }; const [zoneDataList, setZoneDataList] = useState([]); - const { assets } = useAssetsStore(); - + const { assetStore } = useSceneContext(); + const { assets } = assetStore(); + const isPointInsidePolygon = ( point: [number, number], polygon: [number, number][] @@ -129,7 +130,7 @@ const DropDownList: React.FC = ({ title="collapse-btn" className="collapse-icon option" style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }} - // onClick={handleToggle} + // onClick={handleToggle} > diff --git a/app/src/components/ui/list/List.tsx b/app/src/components/ui/list/List.tsx index 0dbffcb..0e15606 100644 --- a/app/src/components/ui/list/List.tsx +++ b/app/src/components/ui/list/List.tsx @@ -19,8 +19,8 @@ import { import { zoneCameraUpdate } from "../../../services/visulization/zone/zoneCameraUpdation"; import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../store/builder/useAssetStore"; import { getUserData } from "../../../functions/getUserData"; +import { useSceneContext } from "../../../modules/scene/sceneContext"; interface Asset { id: string; @@ -47,13 +47,12 @@ const List: React.FC = ({ items = [], remove }) => { const { zoneAssetId, setZoneAssetId } = useZoneAssetId(); const { zones, setZones } = useZones(); const { setSubModule } = useSubModuleStore(); - const [expandedZones, setExpandedZones] = useState>( - {} - ); + const [expandedZones, setExpandedZones] = useState>({}); const { projectId } = useParams(); + const { assetStore } = useSceneContext(); + const { setName } = assetStore(); + const { organization } = getUserData(); - const { setName } = useAssetsStore(); - const { userName, userId, organization, email } = getUserData(); useEffect(() => { useSelectedZoneStore.getState().setSelectedZone({ zoneName: "", @@ -82,7 +81,6 @@ const List: React.FC = ({ items = [], remove }) => { setSubModule("zoneProperties"); - let response = await getZoneData(id, organization, projectId); setSelectedZone({ zoneName: response?.zoneName, @@ -99,6 +97,7 @@ const List: React.FC = ({ items = [], remove }) => { console.log(error); } } + function handleAssetClick(asset: Asset) { setZoneAssetId(asset); } @@ -141,7 +140,6 @@ const List: React.FC = ({ items = [], remove }) => { projectId ); // console.log("response: ", response); - console.log(' zoneAssetId.id,: ', zoneAssetId.id,); setName(zoneAssetId.id, response.modelName); } diff --git a/app/src/modules/builder/asset/assetsGroup.tsx b/app/src/modules/builder/asset/assetsGroup.tsx index d45f02a..fdc4409 100644 --- a/app/src/modules/builder/asset/assetsGroup.tsx +++ b/app/src/modules/builder/asset/assetsGroup.tsx @@ -5,7 +5,6 @@ import { useLoadingProgress, useRenameModeStore, useSelectedFloorItem, useSelect import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; import { FloorItems, RefGroup, RefMesh } from "../../../types/world/worldTypes"; -import { useAssetsStore } from "../../../store/builder/useAssetStore"; import { useEventsStore } from "../../../store/simulation/useEventsStore"; import Models from "./models/models"; import useModuleStore from "../../../store/useModuleStore"; @@ -15,6 +14,7 @@ import addAssetModel from "./functions/addAssetModel"; import { useParams } from "react-router-dom"; import { useLeftData, useTopData } from "../../../store/visualization/useZone3DWidgetStore"; import { getUserData } from "../../../functions/getUserData"; +import { useSceneContext } from "../../scene/sceneContext"; const gltfLoaderWorker = new Worker( new URL( @@ -28,13 +28,14 @@ function AssetsGroup({ floorGroup, plane }: { readonly floorGroup: RefGroup, rea const { socket } = useSocketStore(); const { controls, gl, pointer, camera, raycaster } = useThree(); const { setLoadingProgress } = useLoadingProgress(); - const { setAssets, addAsset } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { setAssets, addAsset } = assetStore(); const { addEvent } = useEventsStore(); const { setSelectedFloorItem } = useSelectedFloorItem(); const { selectedItem, setSelectedItem } = useSelectedItem(); const { projectId } = useParams(); const { isRenameMode, setIsRenameMode } = useRenameModeStore(); - const { userId, organization, email } = getUserData(); + const { userId, organization } = getUserData(); const { setTop } = useTopData(); const { setLeft } = useLeftData(); diff --git a/app/src/modules/builder/asset/models/model/model.tsx b/app/src/modules/builder/asset/models/model/model.tsx index 7ccefdf..2a44bff 100644 --- a/app/src/modules/builder/asset/models/model/model.tsx +++ b/app/src/modules/builder/asset/models/model/model.tsx @@ -7,7 +7,6 @@ import { ThreeEvent, useFrame, useThree } from '@react-three/fiber'; import { useActiveTool, useDeletableFloorItem, useRenderDistance, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store'; import { AssetBoundingBox } from '../../functions/assetBoundingBox'; import { CameraControls } from '@react-three/drei'; -import { useAssetsStore } from '../../../../../store/builder/useAssetStore'; import { useEventsStore } from "../../../../../store/simulation/useEventsStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore"; import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore'; @@ -16,6 +15,7 @@ import { useSelectedAsset } from '../../../../../store/simulation/useSimulationS import { useProductContext } from '../../../../simulation/products/productContext'; import { useParams } from 'react-router-dom'; import { getUserData } from '../../../../../functions/getUserData'; +import { useSceneContext } from '../../../../scene/sceneContext'; function Model({ asset }: { readonly asset: Asset }) { const { camera, controls, gl } = useThree(); @@ -23,7 +23,8 @@ function Model({ asset }: { readonly asset: Asset }) { const { toggleView } = useToggleView(); const { subModule } = useSubModuleStore(); const { activeModule } = useModuleStore(); - const { removeAsset } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { removeAsset } = assetStore(); const { setTop } = useTopData(); const { setLeft } = useLeftData(); const { getIsEventInProduct } = useProductStore(); diff --git a/app/src/modules/builder/asset/models/models.tsx b/app/src/modules/builder/asset/models/models.tsx index e67a649..a7bd752 100644 --- a/app/src/modules/builder/asset/models/models.tsx +++ b/app/src/modules/builder/asset/models/models.tsx @@ -1,14 +1,15 @@ -import { useAssetsStore } from '../../../../store/builder/useAssetStore'; import Model from './model/model'; import { useThree } from '@react-three/fiber'; import { CameraControls } from '@react-three/drei'; import { Vector3 } from 'three'; import { useSelectedFloorItem } from '../../../../store/builder/store'; import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore'; +import { useSceneContext } from '../../../scene/sceneContext'; function Models() { const { controls } = useThree(); - const { assets } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { assets } = assetStore(); const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); diff --git a/app/src/modules/collaboration/socket/socketResponses.dev.tsx b/app/src/modules/collaboration/socket/socketResponses.dev.tsx index 116f74a..91c713b 100644 --- a/app/src/modules/collaboration/socket/socketResponses.dev.tsx +++ b/app/src/modules/collaboration/socket/socketResponses.dev.tsx @@ -32,10 +32,10 @@ import Layer2DVisibility from "../../builder/geomentries/layers/layer2DVisibilit import { retrieveGLTF, storeGLTF } from "../../../utils/indexDB/idbUtils"; import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../store/builder/useAssetStore"; import { useEventsStore } from "../../../store/simulation/useEventsStore"; import { useProductStore } from "../../../store/simulation/useProductStore"; import { getUserData } from "../../../functions/getUserData"; +import { useSceneContext } from "../../scene/sceneContext"; export default function SocketResponses({ floorPlanGroup, @@ -59,8 +59,10 @@ export default function SocketResponses({ const { zones, setZones } = useZones(); const { zonePoints, setZonePoints } = useZonePoints(); const { projectId } = useParams(); - const { addAsset, updateAsset, removeAsset } = useAssetsStore(); - const { userId, organization, email } = getUserData(); + const { assetStore } = useSceneContext(); + const { addAsset, updateAsset, removeAsset } = assetStore(); + const { organization } = getUserData(); + useEffect(() => { if (!socket) return; diff --git a/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx b/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx index dcd1bc1..12ea6be 100644 --- a/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx @@ -7,8 +7,8 @@ import * as Types from "../../../../types/world/worldTypes"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { getUserData } from "../../../../functions/getUserData"; +import { useSceneContext } from "../../sceneContext"; const CopyPasteControls = ({ copiedObjects, @@ -30,8 +30,9 @@ const CopyPasteControls = ({ const { socket } = useSocketStore(); const { addEvent } = useEventsStore(); const { projectId } = useParams(); - const { assets, addAsset } = useAssetsStore(); - const { userId, organization, email } = getUserData(); + const { assetStore } = useSceneContext(); + const { assets, addAsset } = assetStore(); + const { userId, organization } = getUserData(); useEffect(() => { if (!camera || !scene || toggleView) return; diff --git a/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx b/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx index 0d51930..0b105e9 100644 --- a/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx @@ -7,8 +7,8 @@ import * as Types from "../../../../types/world/worldTypes"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { getUserData } from "../../../../functions/getUserData"; +import { useSceneContext } from "../../sceneContext"; const DuplicationControls = ({ duplicatedObjects, @@ -28,8 +28,9 @@ const DuplicationControls = ({ const { socket } = useSocketStore(); const { addEvent } = useEventsStore(); const { projectId } = useParams(); - const { assets, addAsset } = useAssetsStore(); - const { userId, organization, email } = getUserData(); + const { assetStore } = useSceneContext(); + const { assets, addAsset } = assetStore(); + const { userId, organization } = getUserData(); useEffect(() => { if (!camera || !scene || toggleView) return; diff --git a/app/src/modules/scene/controls/selectionControls/moveControls.tsx b/app/src/modules/scene/controls/selectionControls/moveControls.tsx index 93ff6d3..bb811e7 100644 --- a/app/src/modules/scene/controls/selectionControls/moveControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/moveControls.tsx @@ -11,9 +11,9 @@ import { upsertProductOrEventApi } from "../../../../services/simulation/product import { snapControls } from "../../../../utils/handleSnap"; import DistanceFindingControls from "./distanceFindingControls"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { useProductContext } from "../../../simulation/products/productContext"; import { getUserData } from "../../../../functions/getUserData"; +import { useSceneContext } from "../../sceneContext"; function MoveControls({ movedObjects, @@ -36,9 +36,10 @@ function MoveControls({ const { selectedProduct } = selectedProductStore(); const { socket } = useSocketStore(); const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">(""); - const { userId, organization, email } = getUserData(); + const { userId, organization } = getUserData(); const { projectId } = useParams(); - const { updateAsset } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { updateAsset } = assetStore(); const AssetGroup = useRef(undefined); const updateBackend = ( diff --git a/app/src/modules/scene/controls/selectionControls/rotateControls.tsx b/app/src/modules/scene/controls/selectionControls/rotateControls.tsx index 9518383..8668c03 100644 --- a/app/src/modules/scene/controls/selectionControls/rotateControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/rotateControls.tsx @@ -8,9 +8,9 @@ import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useProductStore } from "../../../../store/simulation/useProductStore"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { useProductContext } from "../../../simulation/products/productContext"; import { getUserData } from "../../../../functions/getUserData"; +import { useSceneContext } from "../../sceneContext"; function RotateControls({ rotatedObjects, @@ -32,9 +32,10 @@ function RotateControls({ const { selectedProductStore } = useProductContext(); const { selectedProduct } = selectedProductStore(); const { socket } = useSocketStore(); - const { userId, organization, email } = getUserData(); + const { userId, organization } = getUserData(); const { projectId } = useParams(); - const { updateAsset } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { updateAsset } = assetStore(); const AssetGroup = useRef(undefined); const updateBackend = ( diff --git a/app/src/modules/scene/controls/selectionControls/selectionControls.tsx b/app/src/modules/scene/controls/selectionControls/selectionControls.tsx index e4ac8f2..b77c69c 100644 --- a/app/src/modules/scene/controls/selectionControls/selectionControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/selectionControls.tsx @@ -16,8 +16,8 @@ import useModuleStore from "../../../../store/useModuleStore"; import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { getUserData } from "../../../../functions/getUserData"; +import { useSceneContext } from "../../sceneContext"; const SelectionControls: React.FC = () => { const { camera, controls, gl, scene, raycaster, pointer } = useThree(); @@ -32,7 +32,8 @@ const SelectionControls: React.FC = () => { const boundingBoxRef = useRef(); const { activeModule } = useModuleStore(); const { socket } = useSocketStore(); - const { removeAsset } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { removeAsset } = assetStore(); const selectionBox = useMemo(() => new SelectionBox(camera, scene), [camera, scene]); const { toolMode } = useToolMode(); const { projectId } = useParams(); diff --git a/app/src/modules/scene/controls/transformControls/transformControls.tsx b/app/src/modules/scene/controls/transformControls/transformControls.tsx index b08db6f..4e3fdb6 100644 --- a/app/src/modules/scene/controls/transformControls/transformControls.tsx +++ b/app/src/modules/scene/controls/transformControls/transformControls.tsx @@ -8,11 +8,11 @@ import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifie import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useProductStore } from "../../../../store/simulation/useProductStore"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; -import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; +// import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; import { useParams } from "react-router-dom"; -import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { useProductContext } from "../../../simulation/products/productContext"; import { getUserData } from "../../../../functions/getUserData"; +import { useSceneContext } from "../../sceneContext"; export default function TransformControl() { const state = useThree(); @@ -24,8 +24,9 @@ export default function TransformControl() { const { socket } = useSocketStore(); const { selectedProductStore } = useProductContext(); const { selectedProduct } = selectedProductStore(); - const { updateAsset, getAssetById } = useAssetsStore(); - const { userId, organization, email } = getUserData(); + const { assetStore } = useSceneContext(); + const { updateAsset, getAssetById } = assetStore(); + const { userId, organization } = getUserData(); const { projectId } = useParams(); const updateBackend = ( diff --git a/app/src/modules/scene/scene.tsx b/app/src/modules/scene/scene.tsx index e49ab1f..4c9d757 100644 --- a/app/src/modules/scene/scene.tsx +++ b/app/src/modules/scene/scene.tsx @@ -1,7 +1,7 @@ import { useEffect, useMemo } from "react"; import { Canvas } from "@react-three/fiber"; import { KeyboardControls } from "@react-three/drei"; -import { SceneProvider } from "./sceneContext"; +import { SceneProvider, useSceneContext } from "./sceneContext"; import Builder from "../builder/builder"; import Visualization from "../visualization/visualization"; @@ -13,7 +13,6 @@ import { useParams } from "react-router-dom"; import { getAllProjects } from "../../services/dashboard/getAllProjects"; import { getUserData } from "../../functions/getUserData"; import { useLoadingProgress, useSocketStore } from "../../store/builder/store"; -import { useAssetsStore } from "../../store/builder/useAssetStore"; import { Color } from "three"; export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Comparison Layout' }) { @@ -23,12 +22,14 @@ export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Co { name: "left", keys: ["ArrowLeft", "a", "A"] }, { name: "right", keys: ["ArrowRight", "d", "D"] }, ], []); - const { assets } = useAssetsStore(); + const { assetStore } = useSceneContext(); + const { assets } = assetStore(); const { userId, organization } = getUserData(); const { projectId } = useParams(); const { projectSocket } = useSocketStore(); const { activeModule } = useModuleStore(); const { loadingProgress } = useLoadingProgress(); + const handleUpdatingProject = async () => { if (!projectId && loadingProgress > 1) return; try { @@ -51,33 +52,32 @@ export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Co } } catch (error) { } }; + useEffect(() => { handleUpdatingProject() }, [activeModule, assets, loadingProgress]) return ( - - - { - e.preventDefault(); - }} - onCreated={(e) => { - e.scene.background = layout === 'Main Layout' ? null : new Color(0x19191d); - }} - gl={{ powerPreference: "high-performance", antialias: true, preserveDrawingBuffer: true }} - > - - - - - - - - + + { + e.preventDefault(); + }} + onCreated={(e) => { + e.scene.background = layout === 'Main Layout' ? null : new Color(0x19191d); + }} + gl={{ powerPreference: "high-performance", antialias: true, preserveDrawingBuffer: true }} + > + + + + + + + ); } \ No newline at end of file diff --git a/app/src/modules/scene/sceneContext.tsx b/app/src/modules/scene/sceneContext.tsx index 0145b45..5e46b99 100644 --- a/app/src/modules/scene/sceneContext.tsx +++ b/app/src/modules/scene/sceneContext.tsx @@ -1,4 +1,7 @@ import { createContext, useContext, useMemo } from 'react'; + +import { createAssetStore, AssetStoreType } from '../../store/builder/useAssetStore'; + import { createMaterialStore, MaterialStoreType } from '../../store/simulation/useMaterialStore'; import { createArmBotStore, ArmBotStoreType } from '../../store/simulation/useArmBotStore'; import { createMachineStore, MachineStoreType } from '../../store/simulation/useMachineStore'; @@ -7,6 +10,9 @@ import { createVehicleStore, VehicleStoreType } from '../../store/simulation/use import { createStorageUnitStore, StorageUnitStoreType } from '../../store/simulation/useStorageUnitStore'; type SceneContextValue = { + + assetStore: AssetStoreType, + materialStore: MaterialStoreType; armBotStore: ArmBotStoreType; machineStore: MachineStoreType; @@ -25,6 +31,9 @@ export function SceneProvider({ readonly children: React.ReactNode; readonly layout: 'Main Layout' | 'Comparison Layout'; }) { + + const assetStore = useMemo(() => createAssetStore(), []); + const materialStore = useMemo(() => createMaterialStore(), []); const armBotStore = useMemo(() => createArmBotStore(), []); const machineStore = useMemo(() => createMachineStore(), []); @@ -32,17 +41,23 @@ export function SceneProvider({ const vehicleStore = useMemo(() => createVehicleStore(), []); const storageUnitStore = useMemo(() => createStorageUnitStore(), []); + const clearStores = useMemo(() => () => { + assetStore().clearAssets(); + }, [assetStore]); + const contextValue = useMemo(() => ( { + assetStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, + clearStores, layout } - ), [materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, layout]); + ), [assetStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, clearStores, layout]); return ( diff --git a/app/src/modules/simulation/products/products.tsx b/app/src/modules/simulation/products/products.tsx index a242f5b..986e42f 100644 --- a/app/src/modules/simulation/products/products.tsx +++ b/app/src/modules/simulation/products/products.tsx @@ -15,7 +15,7 @@ function Products() { const { selectedProductStore } = useProductContext(); const { setMainProduct } = useMainProduct(); const { selectedProduct, setSelectedProduct } = selectedProductStore(); - const { addVehicle, clearvehicles } = vehicleStore(); + const { addVehicle, clearVehicles } = vehicleStore(); const { addArmBot, clearArmBots } = armBotStore(); const { addMachine, clearMachines } = machineStore(); const { addConveyor, clearConveyors } = conveyorStore(); @@ -68,7 +68,7 @@ function Products() { if (selectedProduct.productUuid) { const product = getProductById(selectedProduct.productUuid); if (product) { - clearvehicles(); + clearVehicles(); product.eventDatas.forEach(events => { if (events.type === 'vehicle') { addVehicle(selectedProduct.productUuid, events); diff --git a/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx b/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx index 36fcee7..2a95262 100644 --- a/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx +++ b/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx @@ -1,23 +1,20 @@ -import React, { useEffect, useRef, useState, useMemo } from "react"; +import { useRef, useMemo } from "react"; import { MaterialModel } from "../../../materials/instances/material/materialModel"; import { Object3D, Box3, Vector3 } from "three"; import { useThree } from "@react-three/fiber"; +import { useLoadingProgress } from "../../../../../store/builder/store"; const MaterialAnimator = ({ storage, }: Readonly<{ storage: StorageUnitStatus }>) => { const meshRef = useRef(null!); - const [hasLoad, setHasLoad] = useState(false); const { scene } = useThree(); const padding = 0.1; - - useEffect(() => { - setHasLoad(storage.currentLoad > 0); - }, [storage.currentLoad]); + const { loadingProgress } = useLoadingProgress(); const storageModel = useMemo(() => { return scene.getObjectByProperty("uuid", storage.modelUuid) as Object3D; - }, [scene, storage.modelUuid]); + }, [scene, storage.modelUuid, loadingProgress]); const materialPositions = useMemo(() => { if (!storageModel || storage.currentMaterials.length === 0) return []; @@ -59,16 +56,15 @@ const MaterialAnimator = ({ return ( - {hasLoad && - storage.currentMaterials.map((mat, index) => ( - - ))} + {storage.currentMaterials.map((mat, index) => ( + + ))} ); }; diff --git a/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx b/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx index 278a16b..d9faf29 100644 --- a/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx +++ b/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx @@ -5,20 +5,21 @@ import { useSceneContext } from "../../../scene/sceneContext"; import { useViewSceneStore } from "../../../../store/builder/store"; function StorageUnitInstances() { - const { storageUnitStore } = useSceneContext(); - const { storageUnits } = storageUnitStore(); - const { viewSceneLabels } = useViewSceneStore(); + const { storageUnitStore } = useSceneContext(); + const { storageUnits } = storageUnitStore(); + // console.log('storageUnits: ', storageUnits); + const { viewSceneLabels } = useViewSceneStore(); - return ( - <> - {storageUnits.map((storageUnit: StorageUnitStatus) => ( - - - {viewSceneLabels && } - - ))} - - ); + return ( + <> + {storageUnits.map((storageUnit: StorageUnitStatus) => ( + + + {viewSceneLabels && } + + ))} + + ); } export default StorageUnitInstances; diff --git a/app/src/pages/Project.tsx b/app/src/pages/Project.tsx index 12a0b7d..3feaab6 100644 --- a/app/src/pages/Project.tsx +++ b/app/src/pages/Project.tsx @@ -21,17 +21,16 @@ import VersionSaved from "../components/layout/sidebarRight/versionHisory/Versio import { useProductStore } from "../store/simulation/useProductStore"; import { getAllProjects } from "../services/dashboard/getAllProjects"; import { viewProject } from "../services/dashboard/viewProject"; -import { useAssetsStore } from "../store/builder/useAssetStore"; import ComparisonSceneProvider from "../components/layout/scenes/ComparisonSceneProvider"; import MainSceneProvider from "../components/layout/scenes/MainSceneProvider"; import { getUserData } from "../functions/getUserData"; +import { SceneProvider } from "../modules/scene/sceneContext"; const Project: React.FC = () => { let navigate = useNavigate(); const echo = useLogger(); const { setToggleUI } = useToggleStore(); const { activeModule, setActiveModule } = useModuleStore(); - const { setAssets } = useAssetsStore(); const { setUserName } = useUserName(); const { setOrganization } = useOrganization(); const { setWallItems } = useWallItems(); @@ -69,7 +68,6 @@ const Project: React.FC = () => { }, [isVersionSaved]); useEffect(() => { - setAssets([]); setWallItems([]); setZones([]); setProducts([]); @@ -92,8 +90,12 @@ const Project: React.FC = () => { return (
- - + + + + + + {selectedUser && } {isLogListVisible && ( diff --git a/app/src/store/builder/useAssetStore.ts b/app/src/store/builder/useAssetStore.ts index ffa1d35..66a3bf2 100644 --- a/app/src/store/builder/useAssetStore.ts +++ b/app/src/store/builder/useAssetStore.ts @@ -8,6 +8,7 @@ interface AssetsStore { addAsset: (asset: Asset) => void; removeAsset: (modelUuid: string) => void; updateAsset: (modelUuid: string, updates: Partial) => void; + clearAssets: () => void; setAssets: (assets: Assets) => void; // Asset properties @@ -36,196 +37,206 @@ interface AssetsStore { hasAsset: (modelUuid: string) => boolean; } -export const useAssetsStore = create()( - immer((set, get) => ({ - assets: [], +export const createAssetStore = () => { + return create()( + immer((set, get) => ({ + assets: [], - // Asset CRUD operations - addAsset: (asset) => { - set((state) => { - if (!state.assets.some(a => a.modelUuid === asset.modelUuid)) { - state.assets.push(asset); - } - }); - }, - - removeAsset: (modelUuid) => { - set((state) => { - state.assets = state.assets.filter(a => a.modelUuid !== modelUuid); - }); - }, - - updateAsset: (modelUuid, updates) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - Object.assign(asset, updates); - } - }); - }, - - setAssets: (assets) => { - set((state) => { - state.assets = assets; - }); - }, - - // Asset properties - setName: (modelUuid, newName) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.modelName = newName; - } - }); - }, - - setPosition: (modelUuid, position) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.position = position; - } - }); - }, - - setRotation: (modelUuid, rotation) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.rotation = rotation; - } - }); - }, - - setLock: (modelUuid, isLocked) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.isLocked = isLocked; - } - }); - }, - - setCollision: (modelUuid, isCollidable) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.isCollidable = isCollidable; - } - }); - }, - - setVisibility: (modelUuid, isVisible) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.isVisible = isVisible; - } - }); - }, - - setOpacity: (modelUuid, opacity) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.opacity = opacity; - } - }); - }, - - // Animation controls - setAnimation: (modelUuid, animation) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - if (!asset.animationState) { - asset.animationState = { current: animation, playing: false }; - } else { - asset.animationState.current = animation; + // Asset CRUD operations + addAsset: (asset) => { + set((state) => { + if (!state.assets.some(a => a.modelUuid === asset.modelUuid)) { + state.assets.push(asset); } - } - }); - }, + }); + }, - setCurrentAnimation: (modelUuid, current, isPlaying) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset?.animationState) { - asset.animationState.current = current; - asset.animationState.playing = isPlaying; - } - }); - }, + removeAsset: (modelUuid) => { + set((state) => { + state.assets = state.assets.filter(a => a.modelUuid !== modelUuid); + }); + }, - addAnimation: (modelUuid, animation) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - if (!asset.animations) { - asset.animations = [animation]; - } else if (!asset.animations.includes(animation)) { - asset.animations.push(animation); + updateAsset: (modelUuid, updates) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + Object.assign(asset, updates); } - } - }); - }, + }); + }, - removeAnimation: (modelUuid, animation) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset?.animations) { - asset.animations = asset.animations.filter(a => a !== animation); - if (asset.animationState?.current === animation) { - asset.animationState.playing = false; - asset.animationState.current = ''; + clearAssets: () => { + set((state) => { + state.assets = []; + }); + }, + + setAssets: (assets) => { + set((state) => { + state.assets = assets; + }); + }, + + // Asset properties + setName: (modelUuid, newName) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.modelName = newName; } - } - }); - }, + }); + }, - // Event data operations - addEventData: (modelUuid, eventData) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - asset.eventData = eventData; - } - }); - }, + setPosition: (modelUuid, position) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.position = position; + } + }); + }, - updateEventData: (modelUuid, updates) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset?.eventData) { - asset.eventData = { ...asset.eventData, ...updates }; - } - }); - }, + setRotation: (modelUuid, rotation) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.rotation = rotation; + } + }); + }, - removeEventData: (modelUuid) => { - set((state) => { - const asset = state.assets.find(a => a.modelUuid === modelUuid); - if (asset) { - delete asset.eventData; - } - }); - }, + setLock: (modelUuid, isLocked) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.isLocked = isLocked; + } + }); + }, - // Helper functions - getAssetById: (modelUuid) => { - return get().assets.find(a => a.modelUuid === modelUuid); - }, + setCollision: (modelUuid, isCollidable) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.isCollidable = isCollidable; + } + }); + }, - getAssetByPointUuid: (pointUuid) => { - return get().assets.find(asset => - asset.eventData?.point?.uuid === pointUuid || - asset.eventData?.points?.some(p => p.uuid === pointUuid) - ); - }, + setVisibility: (modelUuid, isVisible) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.isVisible = isVisible; + } + }); + }, - hasAsset: (modelUuid) => { - return get().assets.some(a => a.modelUuid === modelUuid); - } - })) -); \ No newline at end of file + setOpacity: (modelUuid, opacity) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.opacity = opacity; + } + }); + }, + + // Animation controls + setAnimation: (modelUuid, animation) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + if (!asset.animationState) { + asset.animationState = { current: animation, playing: false }; + } else { + asset.animationState.current = animation; + } + } + }); + }, + + setCurrentAnimation: (modelUuid, current, isPlaying) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset?.animationState) { + asset.animationState.current = current; + asset.animationState.playing = isPlaying; + } + }); + }, + + addAnimation: (modelUuid, animation) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + if (!asset.animations) { + asset.animations = [animation]; + } else if (!asset.animations.includes(animation)) { + asset.animations.push(animation); + } + } + }); + }, + + removeAnimation: (modelUuid, animation) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset?.animations) { + asset.animations = asset.animations.filter(a => a !== animation); + if (asset.animationState?.current === animation) { + asset.animationState.playing = false; + asset.animationState.current = ''; + } + } + }); + }, + + // Event data operations + addEventData: (modelUuid, eventData) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + asset.eventData = eventData; + } + }); + }, + + updateEventData: (modelUuid, updates) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset?.eventData) { + asset.eventData = { ...asset.eventData, ...updates }; + } + }); + }, + + removeEventData: (modelUuid) => { + set((state) => { + const asset = state.assets.find(a => a.modelUuid === modelUuid); + if (asset) { + delete asset.eventData; + } + }); + }, + + // Helper functions + getAssetById: (modelUuid) => { + return get().assets.find(a => a.modelUuid === modelUuid); + }, + + getAssetByPointUuid: (pointUuid) => { + return get().assets.find(asset => + asset.eventData?.point?.uuid === pointUuid || + asset.eventData?.points?.some(p => p.uuid === pointUuid) + ); + }, + + hasAsset: (modelUuid) => { + return get().assets.some(a => a.modelUuid === modelUuid); + } + })) + ) +} + +export type AssetStoreType = ReturnType; \ No newline at end of file diff --git a/app/src/store/simulation/useVehicleStore.ts b/app/src/store/simulation/useVehicleStore.ts index 90863c4..34264da 100644 --- a/app/src/store/simulation/useVehicleStore.ts +++ b/app/src/store/simulation/useVehicleStore.ts @@ -10,7 +10,7 @@ interface VehiclesStore { modelUuid: string, updates: Partial> ) => void; - clearvehicles: () => void; + clearVehicles: () => void; setVehicleActive: (modelUuid: string, isActive: boolean) => void; setVehiclePicking: (modelUuid: string, isPicking: boolean) => void; @@ -79,7 +79,7 @@ export const createVehicleStore = () => { }); }, - clearvehicles: () => { + clearVehicles: () => { set((state) => { state.vehicles = []; });