Files
Dwinzo_Demo/app/src/modules/scene/controls/undoRedoControls/handlers/use3DUndoHandler.ts

426 lines
16 KiB
TypeScript

import { useParams } from "react-router-dom";
import { getUserData } from "../../../../../functions/getUserData";
import { useSceneContext } from "../../../sceneContext";
import { useSocketStore } from "../../../../../store/socket/useSocketStore";
import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler";
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, productStore, eventStore, versionStore } = useSceneContext();
const { deleteEvent, selectedProduct } = productStore();
const { addEvent, removeEvent } = eventStore();
const { addAssetToScene, removeAssetFromScene, updateAssetInScene } = useAssetResponseHandler();
const { undo3D, peekUndo3D } = undoRedo3DStore();
const { selectedVersion } = versionStore();
const { userId, organization } = getUserData();
const { projectId } = useParams();
const { builderSocket } = 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) => {
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: builderSocket?.id,
versionId: selectedVersion?.versionId || "",
projectId,
userId,
};
if (assetData.eventData) {
data.eventData = assetData.eventData;
addEvent(assetData.eventData as EventsSchema);
}
if (!builderSocket?.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,
}).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.x, data.data.rotation.y, data.data.rotation.z],
isLocked: data.data.isLocked,
isCollidable: true,
isVisible: data.data.isVisible,
opacity: 1,
...(data.data.eventData ? { eventData: data.data.eventData } : {}),
};
addAssetToScene(model, () => {
echo.log(`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.log(`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);
}
removeEvent(assetData.modelUuid);
const updatedEvents = deleteEvent(assetData.modelUuid);
updatedEvents.forEach((event) => {
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
});
};
const updateAssetToBackend = (modelUuid: string, updatedData: Asset) => {
if (projectId) {
const data = {
organization,
modelUuid: 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: builderSocket?.id,
versionId: selectedVersion?.versionId || "",
projectId,
userId,
};
if (!builderSocket?.connected) {
// REST
setAssetsApi({
modelUuid: 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,
}).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.x, data.data.rotation.y, data.data.rotation.z],
isLocked: data.data.isLocked,
isCollidable: true,
isVisible: data.data.isVisible,
opacity: 1,
...(data.data.eventData ? { eventData: data.data.eventData } : {}),
};
updateAssetInScene(model, () => {
echo.log(`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);
}
}
};
const copyAssetToBackend = (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.log(`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);
}
removeEvent(assetData.modelUuid);
const updatedEvents = deleteEvent(assetData.modelUuid);
updatedEvents.forEach((event) => {
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
});
};
const duplicateAssetToBackend = (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.log(`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);
}
removeEvent(assetData.modelUuid);
const updatedEvents = deleteEvent(assetData.modelUuid);
updatedEvents.forEach((event) => {
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
});
};
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;