import { useParams } from "react-router-dom"; import { getUserData } from "../../../../../functions/getUserData"; import { useSceneContext } from "../../../sceneContext"; import { useProductContext } from "../../../../simulation/products/productContext"; import { useSocketStore } from "../../../../../store/builder/store"; import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi"; import { setAssetsApi } from "../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; import { deleteFloorAssetApi } from "../../../../../services/factoryBuilder/asset/floorAsset/deleteFloorAssetApi"; function use3DUndoHandler() { const { undoRedo3DStore, assetStore, productStore, eventStore, versionStore } = useSceneContext(); const { deleteEvent } = productStore(); const { addEvent, removeEvent } = eventStore(); const { updateAsset, removeAsset, addAsset } = assetStore(); const { undo3D, peekUndo3D } = undoRedo3DStore(); const { selectedVersion } = versionStore(); const { selectedProductStore } = useProductContext(); const { selectedProduct } = selectedProductStore(); const { userId, organization } = getUserData(); const { projectId } = useParams(); const { socket } = useSocketStore(); const updateBackend = ( productName: string, productUuid: string, projectId: string, eventData: EventsSchema ) => { upsertProductOrEventApi({ productName: productName, productUuid: productUuid, projectId: projectId, eventDatas: eventData, versionId: selectedVersion?.versionId || '', }); }; const handleUndo = () => { const unDoData = peekUndo3D(); if (!unDoData) return; if (unDoData.type === 'Scene') { const { actions } = unDoData; actions.forEach(action => { const { actionType } = action; if ('asset' in action) { const asset = action.asset; if (actionType === 'Asset-Add') { handleDelete(asset); } else if (actionType === 'Asset-Delete') { handleAdd(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(handleDelete); } else if (actionType === 'Assets-Delete') { assets.forEach(handleAdd); } 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 (unDoData.type === 'UI') { // Handle UI actions if needed } undo3D(); }; 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) => { switch (asset.type) { case 'Asset': updateAssetToBackend(asset.assetData.modelUuid, asset.assetData); break; case 'WallAsset': updateWallAssetToBackend(asset.assetData.modelUuid, asset.assetData); 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) => { addAsset(assetData); if (projectId) { const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: { x: assetData.rotation[0], y: assetData.rotation[1], z: assetData.rotation[2] }, isLocked: false, isVisible: true, eventData: {}, socketId: socket?.id, versionId: selectedVersion?.versionId || '', projectId, userId }; if (assetData.eventData) { data.eventData = assetData.eventData; addEvent(assetData.eventData as EventsSchema); } if (!socket?.connected) { // REST setAssetsApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, assetId: assetData.assetId, position: assetData.position, rotation: { x: assetData.rotation[0], y: assetData.rotation[1], z: assetData.rotation[2] }, isLocked: false, isVisible: true, eventData: data.eventData, versionId: selectedVersion?.versionId || '', projectId: projectId, }); } else { // SOCKET socket.emit("v1:model-asset:add", data); } } } const deleteAssetToBackend = (assetData: Asset) => { if (!socket?.connected) { // REST deleteFloorAssetApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, versionId: selectedVersion?.versionId || '', projectId: projectId || '' }); } else { // SOCKET const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, socketId: socket.id, userId, versionId: selectedVersion?.versionId || '', projectId } socket.emit('v1:model-asset:delete', data) } removeEvent(assetData.modelUuid); const updatedEvents = deleteEvent(assetData.modelUuid); updatedEvents.forEach((event) => { updateBackend( selectedProduct.productName, selectedProduct.productUuid, projectId || '', event ); }) removeAsset(assetData.modelUuid); } const updateAssetToBackend = (modelUuid: string, updatedData: Asset) => { updateAsset(modelUuid, updatedData); if (projectId) { const data = { organization, modelUuid: updatedData.modelUuid, modelName: updatedData.modelName, assetId: updatedData.assetId, position: updatedData.position, rotation: { x: updatedData.rotation[0], y: updatedData.rotation[1], z: updatedData.rotation[2] }, isLocked: false, isVisible: true, socketId: socket?.id, versionId: selectedVersion?.versionId || '', projectId, userId }; if (!socket?.connected) { // REST setAssetsApi({ modelUuid: updatedData.modelUuid, modelName: updatedData.modelName, assetId: updatedData.assetId, position: updatedData.position, rotation: { x: updatedData.rotation[0], y: updatedData.rotation[1], z: updatedData.rotation[2] }, isLocked: false, isVisible: true, versionId: selectedVersion?.versionId || '', projectId: projectId, }); } else { // SOCKET socket.emit("v1:model-asset:add", data); } } } const copyAssetToBackend = (assetData: Asset) => { if (!socket?.connected) { // REST deleteFloorAssetApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, versionId: selectedVersion?.versionId || '', projectId: projectId || '' }); } else { // SOCKET const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, socketId: socket.id, userId, versionId: selectedVersion?.versionId || '', projectId } socket.emit('v1:model-asset:delete', data) } removeEvent(assetData.modelUuid); const updatedEvents = deleteEvent(assetData.modelUuid); updatedEvents.forEach((event) => { updateBackend( selectedProduct.productName, selectedProduct.productUuid, projectId || '', event ); }) removeAsset(assetData.modelUuid); } const duplicateAssetToBackend = (assetData: Asset) => { if (!socket?.connected) { // REST deleteFloorAssetApi({ modelUuid: assetData.modelUuid, modelName: assetData.modelName, versionId: selectedVersion?.versionId || '', projectId: projectId || '' }); } else { // SOCKET const data = { organization, modelUuid: assetData.modelUuid, modelName: assetData.modelName, socketId: socket.id, userId, versionId: selectedVersion?.versionId || '', projectId } socket.emit('v1:model-asset:delete', data) } removeEvent(assetData.modelUuid); const updatedEvents = deleteEvent(assetData.modelUuid); updatedEvents.forEach((event) => { updateBackend( selectedProduct.productName, selectedProduct.productUuid, projectId || '', event ); }) removeAsset(assetData.modelUuid); } const addWallAssetToBackend = (assetData: WallAsset) => { } const deleteWallAssetToBackend = (assetData: WallAsset) => { } const updateWallAssetToBackend = (modelUuid: string, updatedData: WallAsset) => { } const copyWallAssetToBackend = (assetData: WallAsset) => { } const duplicateWallAssetToBackend = (assetData: WallAsset) => { } return { handleUndo }; } export default use3DUndoHandler;