import { useParams } from "react-router-dom"; import { getUserData } from "../../../../../functions/getUserData"; import { useSceneContext } from "../../../sceneContext"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; import { useSelectedAction, useSelectedEventData } from "../../../../../store/simulation/useSimulationStore"; import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { updateEventToBackend } from "../../../../../components/layout/sidebarRight/properties/eventProperties/functions/handleUpdateEventToBackend"; import { setAssetsApi } from "../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; import { deleteFloorAssetApi } from "../../../../../services/factoryBuilder/asset/floorAsset/deleteFloorAssetApi"; function use3DRedoHandler() { const { undoRedo3DStore, productStore, versionStore } = useSceneContext(); const { deleteEvent, selectedProduct, getEventByModelUuid, peekUpdateEvent, updateEvent } = productStore(); const { addAssetToScene, removeAssetFromScene, updateAssetInScene } = useAssetResponseHandler(); const { redo3D, peekRedo3D } = undoRedo3DStore(); const { selectedEventData, setSelectedEventData } = useSelectedEventData(); const { setSelectedAction, selectedAction } = useSelectedAction(); const { selectedVersion } = versionStore(); const { userId, organization } = getUserData(); const { projectId } = useParams(); const { builderSocket, simulationSocket } = useSocketStore(); const updateBackend = (eventData: EventsSchema) => { updateEventToBackend({ productName: selectedProduct.productName, productUuid: selectedProduct.productUuid, projectId: projectId || "", eventData, simulationSocket, selectedVersion, pointData: { selectedEventData, setSelectedEventData, selectedAction, setSelectedAction, getEventByModelUuid, }, updateEvent, }); }; const handleRedo = () => { const redoData = peekRedo3D(); if (!redoData) return; if (redoData.type === "Scene") { const { actions } = redoData; actions.forEach((action) => { const { actionType } = action; if ("asset" in action) { const asset = action.asset; if (actionType === "Asset-Add") { handleAdd(asset); } else if (actionType === "Asset-Delete") { handleDelete(asset); } else if (actionType === "Asset-Update") { handleUpdate(asset); } else if (actionType === "Asset-Copied") { handleCopy(asset); } else if (actionType === "Asset-Duplicated") { handleDuplicate(asset); } } else if ("assets" in action) { const assets = action.assets; if (actionType === "Assets-Add") { assets.forEach(handleAdd); } else if (actionType === "Assets-Delete") { assets.forEach(handleDelete); } else if (actionType === "Assets-Update") { assets.forEach(handleUpdate); } else if (actionType === "Assets-Copied") { assets.forEach(handleCopy); } else if (actionType === "Assets-Duplicated") { assets.forEach(handleDuplicate); } } }); } else if (redoData.type === "UI") { // Handle UI actions if needed } redo3D(); }; const handleAdd = (asset: AssetData) => { switch (asset.type) { case "Asset": addAssetToBackend(asset.assetData); break; case "WallAsset": addWallAssetToBackend(asset.assetData); break; } }; const handleDelete = (asset: AssetData) => { switch (asset.type) { case "Asset": deleteAssetToBackend(asset.assetData); break; case "WallAsset": deleteWallAssetToBackend(asset.assetData); break; } }; const handleUpdate = (asset: AssetData) => { if (!asset.newData) return; switch (asset.type) { case "Asset": updateAssetToBackend(asset.newData.modelUuid, asset.newData); break; case "WallAsset": updateWallAssetToBackend(asset.newData.modelUuid, asset.newData); break; } }; const handleCopy = (asset: AssetData) => { switch (asset.type) { case "Asset": copyAssetToBackend(asset.assetData); break; case "WallAsset": copyWallAssetToBackend(asset.assetData); break; } }; const handleDuplicate = (asset: AssetData) => { switch (asset.type) { case "Asset": duplicateAssetToBackend(asset.assetData); break; case "WallAsset": duplicateWallAssetToBackend(asset.assetData); break; } }; const addAssetToBackend = (assetData: Asset) => { if (projectId) { const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: assetData.rotation, scale: assetData.scale, isCollidable: assetData.isCollidable, opacity: assetData.opacity, isLocked: assetData.isLocked, isVisible: assetData.isVisible, eventData: {}, socketId: builderSocket?.id, versionId: selectedVersion?.versionId || "", projectId, userId, }; if (assetData.eventData) { data.eventData = assetData.eventData; } if (!builderSocket?.connected) { // REST setAssetsApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: assetData.rotation, scale: assetData.scale, isCollidable: assetData.isCollidable, opacity: assetData.opacity, isLocked: assetData.isLocked, isVisible: assetData.isVisible, eventData: data.eventData, versionId: selectedVersion?.versionId || "", projectId: projectId, }).then((data) => { if (!data.message || !data.data) { echo.error(`Error adding asset`); return; } if (data.message === "Model created successfully" && data.data) { const model: Asset = { modelUuid: data.data.modelUuid, modelName: data.data.modelName, assetId: data.data.assetId, position: data.data.position, rotation: data.data.rotation, scale: data.data.scale, isLocked: data.data.isLocked, isVisible: data.data.isVisible, isCollidable: data.data.isCollidable, opacity: data.data.opacity, ...(data.data.eventData ? { eventData: data.data.eventData } : {}), }; addAssetToScene(model, () => { echo.info(`Added asset: ${model.modelName}`); }); } else { removeAssetFromScene(data.data.modelUuid, () => { echo.error(`Error adding asset: ${data?.data?.modelName}`); }); } }); } else { // SOCKET builderSocket.emit("v1:model-asset:add", data); } } }; const deleteAssetToBackend = (assetData: Asset) => { if (!builderSocket?.connected) { // REST deleteFloorAssetApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, versionId: selectedVersion?.versionId || "", projectId: projectId || "", }).then((data) => { if (!data.message || !data.data) { echo.error(`Error removing asset`); return; } if (data.message === "Model deleted successfully") { removeAssetFromScene(data.data.modelUuid, () => { echo.info(`Removed asset: ${data.data.modelName}`); }); } else { echo.error(`Error removing asset: ${data?.data?.modelName}`); } }); } else { // SOCKET const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, socketId: builderSocket.id, userId, versionId: selectedVersion?.versionId || "", projectId, }; builderSocket.emit("v1:model-asset:delete", data); } const updatedEvents = deleteEvent(assetData.modelUuid); updatedEvents.forEach((event) => { updateBackend(event); }); }; const updateAssetToBackend = (modelUuid: string, updatedData: Asset) => { if (projectId) { const data = { organization, modelUuid: modelUuid, modelName: updatedData.modelName, assetId: updatedData.assetId, position: updatedData.position, rotation: updatedData.rotation, scale: updatedData.scale, isCollidable: updatedData.isCollidable, opacity: updatedData.opacity, isLocked: updatedData.isLocked, isVisible: updatedData.isVisible, socketId: builderSocket?.id, versionId: selectedVersion?.versionId || "", projectId, userId, }; if (!builderSocket?.connected) { // REST setAssetsApi({ modelUuid: modelUuid, modelName: updatedData.modelName, assetId: updatedData.assetId, position: updatedData.position, rotation: updatedData.rotation, scale: updatedData.scale, isCollidable: updatedData.isCollidable, opacity: updatedData.opacity, isLocked: updatedData.isLocked, isVisible: updatedData.isVisible, versionId: selectedVersion?.versionId || "", projectId: projectId, }).then((data) => { if (!data.message || !data.data) { echo.error(`Error updating asset`); return; } if (data.message === "Model updated successfully" && data.data) { const model: Asset = { modelUuid: data.data.modelUuid, modelName: data.data.modelName, assetId: data.data.assetId, position: data.data.position, rotation: data.data.rotation, scale: data.data.scale, isLocked: data.data.isLocked, isVisible: data.data.isVisible, isCollidable: data.data.isCollidable, opacity: data.data.opacity, ...(data.data.eventData ? { eventData: data.data.eventData } : {}), }; updateAssetInScene(model, () => { echo.info(`Updated asset: ${model.modelName}`); }); } else { removeAssetFromScene(data.data.modelUuid, () => { echo.error(`Error updating asset: ${data?.data?.modelName}`); }); } }); } else { // SOCKET builderSocket.emit("v1:model-asset:add", data); } if (updatedData.eventData) { const productData = getEventByModelUuid(selectedProduct.productUuid, updatedData.modelUuid); if (productData) { const event = peekUpdateEvent(selectedProduct.productUuid, updatedData.modelUuid, { position: updatedData.position, rotation: updatedData.rotation, }); if (event) { updateBackend(event); } } } } }; const copyAssetToBackend = (assetData: Asset) => { if (projectId) { const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: assetData.rotation, scale: assetData.scale, isCollidable: assetData.isCollidable, opacity: assetData.opacity, isLocked: assetData.isLocked, isVisible: assetData.isVisible, eventData: {}, socketId: builderSocket?.id, versionId: selectedVersion?.versionId || "", projectId, userId, }; if (assetData.eventData) { data.eventData = assetData.eventData; } if (!builderSocket?.connected) { // REST setAssetsApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: assetData.rotation, scale: assetData.scale, isCollidable: assetData.isCollidable, opacity: assetData.opacity, isLocked: assetData.isLocked, isVisible: assetData.isVisible, eventData: data.eventData, versionId: selectedVersion?.versionId || "", projectId: projectId, }).then((data) => { if (!data.message || !data.data) { echo.error(`Error adding asset`); return; } if (data.message === "Model created successfully" && data.data) { const model: Asset = { modelUuid: data.data.modelUuid, modelName: data.data.modelName, assetId: data.data.assetId, position: data.data.position, rotation: data.data.rotation, scale: data.data.scale, isLocked: data.data.isLocked, isVisible: data.data.isVisible, isCollidable: data.data.isCollidable, opacity: data.data.opacity, ...(data.data.eventData ? { eventData: data.data.eventData } : {}), }; addAssetToScene(model, () => { echo.info(`Added asset: ${model.modelName}`); }); } else { removeAssetFromScene(data.data.modelUuid, () => { echo.error(`Error adding asset: ${data?.data?.modelName}`); }); } }); } else { // SOCKET builderSocket.emit("v1:model-asset:add", data); } } }; const duplicateAssetToBackend = (assetData: Asset) => { if (projectId) { const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: assetData.rotation, scale: assetData.scale, isCollidable: assetData.isCollidable, opacity: assetData.opacity, isLocked: assetData.isLocked, isVisible: assetData.isVisible, eventData: {}, socketId: builderSocket?.id, versionId: selectedVersion?.versionId || "", projectId, userId, }; if (assetData.eventData) { data.eventData = assetData.eventData; } if (!builderSocket?.connected) { //REST setAssetsApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: assetData.rotation, scale: assetData.scale, isCollidable: assetData.isCollidable, opacity: assetData.opacity, isLocked: assetData.isLocked, isVisible: assetData.isVisible, eventData: data.eventData, versionId: selectedVersion?.versionId || "", projectId: projectId, }).then((data) => { if (!data.message || !data.data) { echo.error(`Error adding asset`); return; } if (data.message === "Model created successfully" && data.data) { const model: Asset = { modelUuid: data.data.modelUuid, modelName: data.data.modelName, assetId: data.data.assetId, position: data.data.position, rotation: data.data.rotation, scale: data.data.scale, isLocked: data.data.isLocked, isVisible: data.data.isVisible, isCollidable: data.data.isCollidable, opacity: data.data.opacity, ...(data.data.eventData ? { eventData: data.data.eventData } : {}), }; addAssetToScene(model, () => { echo.info(`Added asset: ${model.modelName}`); }); } else { removeAssetFromScene(data.data.modelUuid, () => { echo.error(`Error adding asset: ${data?.data?.modelName}`); }); } }); } else { //SOCKET builderSocket.emit("v1:model-asset:add", data); } } }; const addWallAssetToBackend = (assetData: WallAsset) => {}; const deleteWallAssetToBackend = (assetData: WallAsset) => {}; const updateWallAssetToBackend = (modelUuid: string, updatedData: WallAsset) => {}; const copyWallAssetToBackend = (assetData: WallAsset) => {}; const duplicateWallAssetToBackend = (assetData: WallAsset) => {}; return { handleRedo }; } export default use3DRedoHandler;