426 lines
16 KiB
TypeScript
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;
|