Refactor DashboardEditor to improve block and element handling, including backend updates and drag-and-drop functionality. Adjust minimum block size constraints and enhance asset visibility checks in the asset group store. Update socket initialization to streamline project connections. Modify styles for element dropdown transitions.
This commit is contained in:
@@ -3,6 +3,7 @@ import React, { useState, useRef, useEffect } from "react";
|
||||
import { dataModelManager } from "./data/dataModel";
|
||||
import ControlPanel from "./ControlPanel";
|
||||
import SwapModal from "./SwapModal";
|
||||
import { Block } from "../../types/exportedTypes";
|
||||
import DataModelPanel from "./components/models/DataModelPanel";
|
||||
|
||||
import { useSceneContext } from "../../modules/scene/sceneContext";
|
||||
@@ -77,23 +78,35 @@ const DashboardEditor: React.FC = () => {
|
||||
const currentBlock = blocks.find((b) => b.blockUuid === selectedBlock);
|
||||
const currentElement = currentBlock?.elements.find((el) => el.elementUuid === selectedElement);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("blocks: ", blocks);
|
||||
}, [blocks]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!projectId || !selectedVersion) return;
|
||||
// getDashBoardBlocksApi(projectId, selectedVersion.versionId).then((data) => {
|
||||
// if (data.data && data.data.blocks) {
|
||||
// console.log("data: ", data);
|
||||
// setBlocks(data.data.blocks);
|
||||
// }
|
||||
// });
|
||||
getDashBoardBlocksApi(projectId, selectedVersion.versionId).then((data) => {
|
||||
if (data.data?.blocks) {
|
||||
console.log("data.data.blocks: ", data.data.blocks);
|
||||
setBlocks(data.data.blocks);
|
||||
}
|
||||
});
|
||||
}, [projectId, selectedVersion]);
|
||||
|
||||
const updateBackend = (blocks: Block[]) => {
|
||||
if (!projectId || !selectedVersion) return;
|
||||
|
||||
upsetDashBoardBlocksApi({ projectId, versionId: selectedVersion.versionId, blocks }).then((data) => {
|
||||
if (data.data?.blocks) {
|
||||
console.log("data.data.blocks: ", data.data.blocks);
|
||||
setBlocks(data.data.blocks);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = subscribe(() => {
|
||||
if (!projectId || !selectedVersion) return;
|
||||
|
||||
// upsetDashBoardBlocksApi({ projectId, versionId: selectedVersion.versionId, blocks }).then((data) => {
|
||||
// console.log("data: ", data);
|
||||
// });
|
||||
updateBackend(blocks);
|
||||
});
|
||||
|
||||
return () => {
|
||||
@@ -103,10 +116,11 @@ const DashboardEditor: React.FC = () => {
|
||||
|
||||
useCallBackOnKey(
|
||||
() => {
|
||||
console.log(blocks);
|
||||
if (!projectId || !selectedVersion) return;
|
||||
updateBackend(blocks);
|
||||
},
|
||||
"Ctrl+S",
|
||||
{ dependencies: [blocks], noRepeat: true, allowOnInput: true }
|
||||
{ dependencies: [blocks, projectId, selectedVersion], noRepeat: true, allowOnInput: true }
|
||||
);
|
||||
|
||||
// Subscribe to data model changes
|
||||
@@ -118,27 +132,27 @@ const DashboardEditor: React.FC = () => {
|
||||
const keys = dataModelManager.getAvailableKeys();
|
||||
const subscriptions: Array<[string, () => void]> = [];
|
||||
|
||||
keys.forEach((key) => {
|
||||
for (const key of keys) {
|
||||
const callback = () => handleDataChange();
|
||||
dataModelManager.subscribe(key, callback);
|
||||
subscriptions.push([key, callback]);
|
||||
});
|
||||
}
|
||||
|
||||
const interval = setInterval(() => {
|
||||
const currentKeys = dataModelManager.getAvailableKeys();
|
||||
const newKeys = currentKeys.filter((key) => !keys.includes(key));
|
||||
|
||||
newKeys.forEach((key) => {
|
||||
for (const key of newKeys) {
|
||||
const callback = () => handleDataChange();
|
||||
dataModelManager.subscribe(key, callback);
|
||||
subscriptions.push([key, callback]);
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
return () => {
|
||||
subscriptions.forEach(([key, callback]) => {
|
||||
for (const [key, callback] of subscriptions) {
|
||||
dataModelManager.unsubscribe(key, callback);
|
||||
});
|
||||
}
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, []);
|
||||
@@ -183,144 +197,144 @@ const DashboardEditor: React.FC = () => {
|
||||
}, [selectedBlock, selectedElement]);
|
||||
|
||||
// Drag and drop handler
|
||||
useEffect(() => {
|
||||
const handleMouseMove = (e: MouseEvent): void => {
|
||||
// Element dragging - direct DOM manipulation
|
||||
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
|
||||
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
|
||||
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
|
||||
|
||||
if (blockElement && elementToDrag) {
|
||||
const blockRect = blockElement.getBoundingClientRect();
|
||||
const newX = e.clientX - blockRect.left - elementDragOffset.x;
|
||||
const newY = e.clientY - blockRect.top - elementDragOffset.y;
|
||||
useEffect(() => {
|
||||
const handleMouseMove = (e: MouseEvent): void => {
|
||||
// Element dragging - direct DOM manipulation
|
||||
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
|
||||
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
|
||||
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
|
||||
|
||||
// Direct DOM manipulation
|
||||
elementToDrag.style.left = `${Math.max(0, Math.min(blockRect.width - 50, newX))}px`;
|
||||
elementToDrag.style.top = `${Math.max(0, Math.min(blockRect.height - 30, newY))}px`;
|
||||
if (blockElement && elementToDrag) {
|
||||
const blockRect = blockElement.getBoundingClientRect();
|
||||
const newX = e.clientX - blockRect.left - elementDragOffset.x;
|
||||
const newY = e.clientY - blockRect.top - elementDragOffset.y;
|
||||
|
||||
// Direct DOM manipulation
|
||||
elementToDrag.style.left = `${Math.max(0, Math.min(blockRect.width - 50, newX))}px`;
|
||||
elementToDrag.style.top = `${Math.max(0, Math.min(blockRect.height - 30, newY))}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block dragging - direct DOM manipulation
|
||||
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
|
||||
const editorElement = editorRef.current;
|
||||
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
||||
|
||||
if (editorElement && blockToDrag) {
|
||||
const editorRect = editorElement.getBoundingClientRect();
|
||||
const newX = e.clientX - editorRect.left - blockDragOffset.x;
|
||||
const newY = e.clientY - editorRect.top - blockDragOffset.y;
|
||||
// Block dragging - direct DOM manipulation
|
||||
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
|
||||
const editorElement = editorRef.current;
|
||||
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
||||
|
||||
// Direct DOM manipulation
|
||||
blockToDrag.style.left = `${Math.max(0, Math.min(editorRect.width - (currentBlock.size?.width || 400), newX))}px`;
|
||||
blockToDrag.style.top = `${Math.max(0, Math.min(editorRect.height - (currentBlock.size?.height || 300), newY))}px`;
|
||||
if (editorElement && blockToDrag) {
|
||||
const editorRect = editorElement.getBoundingClientRect();
|
||||
const newX = e.clientX - editorRect.left - blockDragOffset.x;
|
||||
const newY = e.clientY - editorRect.top - blockDragOffset.y;
|
||||
|
||||
// Direct DOM manipulation
|
||||
blockToDrag.style.left = `${Math.max(0, Math.min(editorRect.width - (currentBlock.size?.width || 400), newX))}px`;
|
||||
blockToDrag.style.top = `${Math.max(0, Math.min(editorRect.height - (currentBlock.size?.height || 300), newY))}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resizing - direct DOM manipulation
|
||||
if ((resizingElement || resizingBlock) && resizeStart) {
|
||||
// Resizing - direct DOM manipulation
|
||||
if ((resizingElement || resizingBlock) && resizeStart) {
|
||||
if (resizingElement && selectedBlock) {
|
||||
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
|
||||
if (elementToResize) {
|
||||
const deltaX = e.clientX - resizeStart.x;
|
||||
const deltaY = e.clientY - resizeStart.y;
|
||||
|
||||
const newWidth = Math.max(100, resizeStart.width + deltaX);
|
||||
const newHeight = Math.max(50, resizeStart.height + deltaY);
|
||||
|
||||
// Direct DOM manipulation
|
||||
elementToResize.style.width = `${newWidth}px`;
|
||||
elementToResize.style.height = `${newHeight}px`;
|
||||
}
|
||||
} else if (resizingBlock) {
|
||||
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
|
||||
if (blockToResize) {
|
||||
const deltaX = e.clientX - resizeStart.x;
|
||||
const deltaY = e.clientY - resizeStart.y;
|
||||
|
||||
const currentBlock = blocks.find((b) => b.blockUuid === resizingBlock);
|
||||
const minSize = currentBlock ? calculateMinBlockSize(currentBlock) : { width: 100, height: 50 };
|
||||
|
||||
const newWidth = Math.max(minSize.width, resizeStart.width + deltaX);
|
||||
const newHeight = Math.max(minSize.height, resizeStart.height + deltaY);
|
||||
|
||||
// Direct DOM manipulation
|
||||
blockToResize.style.width = `${newWidth}px`;
|
||||
blockToResize.style.height = `${newHeight}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseUp = (): void => {
|
||||
// Update state only on mouse up for elements
|
||||
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
|
||||
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
|
||||
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
|
||||
|
||||
if (blockElement && elementToDrag) {
|
||||
const computedStyle = window.getComputedStyle(elementToDrag);
|
||||
const x = parseFloat(computedStyle.left);
|
||||
const y = parseFloat(computedStyle.top);
|
||||
|
||||
updateElementPosition(selectedBlock, draggingElement, { x, y });
|
||||
}
|
||||
}
|
||||
|
||||
// Update state only on mouse up for blocks
|
||||
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
|
||||
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
||||
|
||||
if (blockToDrag) {
|
||||
const computedStyle = window.getComputedStyle(blockToDrag);
|
||||
const x = parseFloat(computedStyle.left);
|
||||
const y = parseFloat(computedStyle.top);
|
||||
|
||||
updateBlockPosition(draggingBlock, { x, y });
|
||||
}
|
||||
}
|
||||
|
||||
// Update state only on mouse up for resizing
|
||||
if (resizingElement && selectedBlock) {
|
||||
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
|
||||
if (elementToResize) {
|
||||
const deltaX = e.clientX - resizeStart.x;
|
||||
const deltaY = e.clientY - resizeStart.y;
|
||||
const computedStyle = window.getComputedStyle(elementToResize);
|
||||
const width = parseFloat(computedStyle.width);
|
||||
const height = parseFloat(computedStyle.height);
|
||||
|
||||
const newWidth = Math.max(100, resizeStart.width + deltaX);
|
||||
const newHeight = Math.max(50, resizeStart.height + deltaY);
|
||||
|
||||
// Direct DOM manipulation
|
||||
elementToResize.style.width = `${newWidth}px`;
|
||||
elementToResize.style.height = `${newHeight}px`;
|
||||
updateElementSize(selectedBlock, resizingElement, { width, height });
|
||||
}
|
||||
} else if (resizingBlock) {
|
||||
}
|
||||
|
||||
if (resizingBlock) {
|
||||
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
|
||||
if (blockToResize) {
|
||||
const deltaX = e.clientX - resizeStart.x;
|
||||
const deltaY = e.clientY - resizeStart.y;
|
||||
const computedStyle = window.getComputedStyle(blockToResize);
|
||||
const width = parseFloat(computedStyle.width);
|
||||
const height = parseFloat(computedStyle.height);
|
||||
|
||||
const currentBlock = blocks.find((b) => b.blockUuid === resizingBlock);
|
||||
const minSize = currentBlock ? calculateMinBlockSize(currentBlock) : { width: 300, height: 200 };
|
||||
|
||||
const newWidth = Math.max(minSize.width, resizeStart.width + deltaX);
|
||||
const newHeight = Math.max(minSize.height, resizeStart.height + deltaY);
|
||||
|
||||
// Direct DOM manipulation
|
||||
blockToResize.style.width = `${newWidth}px`;
|
||||
blockToResize.style.height = `${newHeight}px`;
|
||||
updateBlockSize(resizingBlock, { width, height });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseUp = (): void => {
|
||||
// Update state only on mouse up for elements
|
||||
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
|
||||
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
|
||||
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
|
||||
|
||||
if (blockElement && elementToDrag) {
|
||||
const computedStyle = window.getComputedStyle(elementToDrag);
|
||||
const x = parseFloat(computedStyle.left);
|
||||
const y = parseFloat(computedStyle.top);
|
||||
|
||||
updateElementPosition(selectedBlock, draggingElement, { x, y });
|
||||
}
|
||||
// Reset all dragging states
|
||||
setDraggingElement(null);
|
||||
setResizingElement(null);
|
||||
setDraggingBlock(null);
|
||||
setResizingBlock(null);
|
||||
setResizeStart(null);
|
||||
};
|
||||
|
||||
if (draggingElement || draggingBlock || resizingElement || resizingBlock) {
|
||||
document.addEventListener("mousemove", handleMouseMove);
|
||||
document.addEventListener("mouseup", handleMouseUp);
|
||||
}
|
||||
|
||||
// Update state only on mouse up for blocks
|
||||
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
|
||||
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
||||
|
||||
if (blockToDrag) {
|
||||
const computedStyle = window.getComputedStyle(blockToDrag);
|
||||
const x = parseFloat(computedStyle.left);
|
||||
const y = parseFloat(computedStyle.top);
|
||||
|
||||
updateBlockPosition(draggingBlock, { x, y });
|
||||
}
|
||||
}
|
||||
|
||||
// Update state only on mouse up for resizing
|
||||
if (resizingElement && selectedBlock) {
|
||||
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
|
||||
if (elementToResize) {
|
||||
const computedStyle = window.getComputedStyle(elementToResize);
|
||||
const width = parseFloat(computedStyle.width);
|
||||
const height = parseFloat(computedStyle.height);
|
||||
|
||||
updateElementSize(selectedBlock, resizingElement, { width, height });
|
||||
}
|
||||
}
|
||||
|
||||
if (resizingBlock) {
|
||||
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
|
||||
if (blockToResize) {
|
||||
const computedStyle = window.getComputedStyle(blockToResize);
|
||||
const width = parseFloat(computedStyle.width);
|
||||
const height = parseFloat(computedStyle.height);
|
||||
|
||||
updateBlockSize(resizingBlock, { width, height });
|
||||
}
|
||||
}
|
||||
|
||||
// Reset all dragging states
|
||||
setDraggingElement(null);
|
||||
setResizingElement(null);
|
||||
setDraggingBlock(null);
|
||||
setResizingBlock(null);
|
||||
setResizeStart(null);
|
||||
};
|
||||
|
||||
if (draggingElement || draggingBlock || resizingElement || resizingBlock) {
|
||||
document.addEventListener("mousemove", handleMouseMove);
|
||||
document.addEventListener("mouseup", handleMouseUp);
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
document.removeEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
}, [draggingElement, resizingElement, draggingBlock, resizingBlock, elementDragOffset, blockDragOffset, selectedBlock, currentElement, resizeStart, currentBlock, blocks]);
|
||||
return () => {
|
||||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
document.removeEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
}, [draggingElement, resizingElement, draggingBlock, resizingBlock, elementDragOffset, blockDragOffset, selectedBlock, currentElement, resizeStart, currentBlock, blocks]);
|
||||
|
||||
// Update dropdown position when showElementDropdown changes
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { Block } from "../../../../types/exportedTypes";
|
||||
|
||||
export const calculateMinBlockSize = (block: Block): Size => {
|
||||
let minWidth = 300;
|
||||
let minHeight = 200;
|
||||
let minWidth = 100;
|
||||
let minHeight = 50;
|
||||
|
||||
block.elements.forEach((element) => {
|
||||
if (element.positionType === "absolute") {
|
||||
|
||||
@@ -30,7 +30,6 @@ export const handleBlockDragStart = (
|
||||
setDraggingBlock: (blockId: string | null) => void,
|
||||
setBlockDragOffset: (offset: Position) => void // Change to specific offset
|
||||
): void => {
|
||||
console.log("Block drag start:", blockId);
|
||||
setDraggingBlock(blockId);
|
||||
const element = event.currentTarget as HTMLElement;
|
||||
const rect = element.getBoundingClientRect();
|
||||
|
||||
@@ -32,6 +32,7 @@ const TreeNode = ({
|
||||
onDrop,
|
||||
onToggleExpand,
|
||||
onOptionClick,
|
||||
onRename,
|
||||
}: {
|
||||
item: AssetGroupChild;
|
||||
level?: number;
|
||||
@@ -43,6 +44,7 @@ const TreeNode = ({
|
||||
onClick: (e: React.MouseEvent, selectedItem: AssetGroupChild) => void;
|
||||
onToggleExpand: (groupUuid: string, newExpanded: boolean) => void;
|
||||
onOptionClick: (option: string, item: AssetGroupChild) => void;
|
||||
onRename: (item: AssetGroupChild, newName: string) => void;
|
||||
}) => {
|
||||
const { assetGroupStore, assetStore } = useSceneContext();
|
||||
const { hasSelectedAsset, selectedAssets } = assetStore();
|
||||
@@ -136,7 +138,13 @@ const TreeNode = ({
|
||||
|
||||
<div className="node-icon">{isGroupNode ? <FolderIcon isOpen={isExpanded} /> : <CubeIcon />}</div>
|
||||
|
||||
<RenameInput value={itemName} onRename={() => {}} canEdit={true} />
|
||||
<RenameInput
|
||||
value={itemName}
|
||||
onRename={(newName) => {
|
||||
onRename(item, newName);
|
||||
}}
|
||||
canEdit={true}
|
||||
/>
|
||||
|
||||
<div className="node-controls">
|
||||
<button className="control-button" title={isVisible ? "Visible" : "Hidden"} onClick={(e) => handleOptionClick(e, "visibility")}>
|
||||
@@ -171,6 +179,7 @@ const TreeNode = ({
|
||||
onDrop={onDrop}
|
||||
onToggleExpand={onToggleExpand}
|
||||
onOptionClick={onOptionClick}
|
||||
onRename={onRename}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -195,6 +204,7 @@ export const AssetOutline = () => {
|
||||
const {
|
||||
groupHierarchy,
|
||||
isGroup,
|
||||
getItemId,
|
||||
getGroupsContainingAsset,
|
||||
getFlatGroupChildren,
|
||||
setGroupExpanded,
|
||||
@@ -207,6 +217,8 @@ export const AssetOutline = () => {
|
||||
toggleSelectedGroup,
|
||||
clearSelectedGroups,
|
||||
hasSelectedGroup,
|
||||
toggleGroupVisibility,
|
||||
toggleGroupLock,
|
||||
} = assetGroupStore();
|
||||
const { projectId } = useParams();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
@@ -232,6 +244,77 @@ export const AssetOutline = () => {
|
||||
return flattened;
|
||||
}, [groupHierarchy, isGroup]);
|
||||
|
||||
const handleAssetRenameUpdate = async (asset: Asset | null, newName: string) => {
|
||||
if (!asset) return;
|
||||
|
||||
if (!builderSocket?.connected) {
|
||||
setAssetsApi({
|
||||
modelUuid: asset.modelUuid,
|
||||
modelName: newName,
|
||||
assetId: asset.assetId,
|
||||
position: asset.position,
|
||||
rotation: asset.rotation,
|
||||
scale: asset.scale,
|
||||
isCollidable: asset.isCollidable,
|
||||
opacity: asset.opacity,
|
||||
isLocked: asset.isLocked,
|
||||
isVisible: asset.isVisible,
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId || "",
|
||||
})
|
||||
.then((data) => {
|
||||
if (!data.message || !data.data) {
|
||||
echo.error(`Error renaming asset: ${asset.modelName}`);
|
||||
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(`Renamed asset to: ${model.modelName}`);
|
||||
});
|
||||
} else {
|
||||
echo.error(`Error renaming asset: ${asset.modelName}`);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
echo.error(`Error renaming asset: ${asset.modelName}`);
|
||||
});
|
||||
} else {
|
||||
const data = {
|
||||
organization,
|
||||
modelUuid: asset.modelUuid,
|
||||
modelName: newName,
|
||||
assetId: asset.assetId,
|
||||
position: asset.position,
|
||||
rotation: asset.rotation,
|
||||
scale: asset.scale,
|
||||
isCollidable: asset.isCollidable,
|
||||
opacity: asset.opacity,
|
||||
isLocked: asset.isLocked,
|
||||
isVisible: asset.isVisible,
|
||||
socketId: builderSocket?.id,
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId,
|
||||
};
|
||||
|
||||
builderSocket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAssetVisibilityUpdate = async (asset: Asset | null) => {
|
||||
if (!asset) return;
|
||||
|
||||
@@ -556,11 +639,6 @@ export const AssetOutline = () => {
|
||||
|
||||
if (!scene.current) return;
|
||||
|
||||
// Helper to get item ID
|
||||
const getItemId = (i: AssetGroupChild): string => {
|
||||
return isGroup(i) ? i.groupUuid : i.modelUuid;
|
||||
};
|
||||
|
||||
const itemId = getItemId(item);
|
||||
const flattened = getFlattenedHierarchy();
|
||||
const clickedIndex = flattened.findIndex((flatItem) => getItemId(flatItem) === itemId);
|
||||
@@ -674,14 +752,57 @@ export const AssetOutline = () => {
|
||||
]
|
||||
);
|
||||
|
||||
const handleRename = useCallback(
|
||||
(item: AssetGroupChild, newName: string) => {
|
||||
if (isGroup(item)) {
|
||||
console.log("Rename group:", item.groupUuid, "to:", newName);
|
||||
} else {
|
||||
const asset = getAssetById(item.modelUuid);
|
||||
if (!asset) return;
|
||||
const oldName = asset.modelName;
|
||||
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToUpdate: AssetData[] = [];
|
||||
|
||||
assetsToUpdate.push({
|
||||
type: "Asset",
|
||||
assetData: { ...asset, modelName: oldName },
|
||||
newData: { ...asset, modelName: newName },
|
||||
timeStap: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (assetsToUpdate.length > 0) {
|
||||
if (assetsToUpdate.length === 1) {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Asset-Update",
|
||||
asset: assetsToUpdate[0],
|
||||
});
|
||||
} else {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Assets-Update",
|
||||
assets: assetsToUpdate,
|
||||
});
|
||||
}
|
||||
|
||||
push3D({
|
||||
type: "Scene",
|
||||
actions: undoActions,
|
||||
});
|
||||
}
|
||||
|
||||
handleAssetRenameUpdate(asset, newName);
|
||||
}
|
||||
},
|
||||
[selectedVersion, builderSocket, projectId, userId, organization]
|
||||
);
|
||||
|
||||
const handleOptionClick = useCallback(
|
||||
(option: string, item: AssetGroupChild) => {
|
||||
const getItemId = (i: AssetGroupChild): string => {
|
||||
return isGroup(i) ? i.groupUuid : i.modelUuid;
|
||||
};
|
||||
|
||||
if (option === "visibility") {
|
||||
if (isGroup(item)) {
|
||||
toggleGroupVisibility(item.groupUuid);
|
||||
} else {
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToUpdate: AssetData[] = [];
|
||||
@@ -724,6 +845,7 @@ export const AssetOutline = () => {
|
||||
}
|
||||
} else if (option === "lock") {
|
||||
if (isGroup(item)) {
|
||||
toggleGroupLock(item.groupUuid);
|
||||
} else {
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToUpdate: AssetData[] = [];
|
||||
@@ -790,7 +912,7 @@ export const AssetOutline = () => {
|
||||
|
||||
const handleAddGroup = useCallback(() => {}, [assetGroupStore, clearSelectedGroups, addSelectedGroup]);
|
||||
|
||||
const handleExpandAll = useCallback(() => {}, [assetGroupStore, setGroupExpanded]);
|
||||
const handleCollapseAll = useCallback(() => {}, [assetGroupStore, setGroupExpanded]);
|
||||
|
||||
// Selection statistics
|
||||
const selectionStats = useMemo(() => {
|
||||
@@ -824,7 +946,7 @@ export const AssetOutline = () => {
|
||||
<button className="toolbar-button" title="Add Group" onClick={handleAddGroup}>
|
||||
<AddIcon />
|
||||
</button>
|
||||
<button className="toolbar-button" title="Expand All" onClick={handleExpandAll}>
|
||||
<button className="toolbar-button" title="Collapse All" onClick={handleCollapseAll}>
|
||||
<CollapseAllIcon />
|
||||
</button>
|
||||
<button className="close-button" onClick={() => setIsOpen(!isOpen)}>
|
||||
@@ -847,6 +969,7 @@ export const AssetOutline = () => {
|
||||
onClick={handleClick}
|
||||
onToggleExpand={handleToggleExpand}
|
||||
onOptionClick={handleOptionClick}
|
||||
onRename={handleRename}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -27,8 +27,9 @@ export function useModelEventHandlers({ boundingBox, groupRef, asset }: { boundi
|
||||
const { selectedEventData, setSelectedEventData } = useSelectedEventData();
|
||||
const { setSelectedAction, selectedAction } = useSelectedAction();
|
||||
const { builderSocket, simulationSocket } = useSocketStore();
|
||||
const { eventStore, productStore, undoRedo3DStore, versionStore, assetStore } = useSceneContext();
|
||||
const { eventStore, productStore, undoRedo3DStore, versionStore, assetStore, assetGroupStore } = useSceneContext();
|
||||
const { toggleSelectedAsset, selectedAssets, clearSelectedAssets } = assetStore();
|
||||
const { isAssetVisible } = assetGroupStore();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
||||
const { resourceManagementId, setResourceManagementId } = useResourceManagementId();
|
||||
@@ -95,7 +96,9 @@ export function useModelEventHandlers({ boundingBox, groupRef, asset }: { boundi
|
||||
(toolMode === "cursor" || toolMode === "Move-Asset" || toolMode === "Rotate-Asset") &&
|
||||
boundingBox &&
|
||||
groupRef.current &&
|
||||
(activeModule === "builder" || (activeModule === "simulation" && resourceManagementId))
|
||||
(activeModule === "builder" || (activeModule === "simulation" && resourceManagementId)) &&
|
||||
asset.isVisible &&
|
||||
isAssetVisible(asset.modelUuid)
|
||||
) {
|
||||
zoomMeshes([asset.modelUuid]);
|
||||
|
||||
|
||||
@@ -13,17 +13,14 @@ import { getAssetFieldApi } from "../../../../../services/builder/asset/floorAss
|
||||
import { ModelAnimator } from "./animator/modelAnimator";
|
||||
import { useModelEventHandlers } from "./eventHandlers/useModelEventHandlers";
|
||||
|
||||
function Model({
|
||||
asset,
|
||||
isRendered,
|
||||
loader,
|
||||
}: Readonly<{ asset: Asset; isRendered: boolean; loader: GLTFLoader }>) {
|
||||
function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendered: boolean; loader: GLTFLoader }>) {
|
||||
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||
const savedTheme: string = localStorage.getItem("theme") || "light";
|
||||
const { toolMode } = useToolMode();
|
||||
const { toggleView } = useToggleView();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { assetStore, layout } = useSceneContext();
|
||||
const { assetStore, assetGroupStore } = useSceneContext();
|
||||
const { isAssetVisible } = assetGroupStore();
|
||||
const { resetAnimation, hasSelectedAsset, updateSelectedAsset, selectedAssets } = assetStore();
|
||||
const { setDeletableFloorAsset } = useBuilderStore();
|
||||
const [gltfScene, setGltfScene] = useState<GLTF["scene"] | null>(null);
|
||||
@@ -56,12 +53,7 @@ function Model({
|
||||
}, [activeModule, toolMode, selectedAssets]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
groupRef.current &&
|
||||
selectedAssets.length === 1 &&
|
||||
selectedAssets[0].userData.modelUuid === asset.modelUuid &&
|
||||
hasSelectedAsset(asset.modelUuid)
|
||||
) {
|
||||
if (groupRef.current && selectedAssets.length === 1 && selectedAssets[0].userData.modelUuid === asset.modelUuid && hasSelectedAsset(asset.modelUuid)) {
|
||||
updateSelectedAsset(groupRef.current);
|
||||
}
|
||||
}, [isRendered, selectedAssets, asset]);
|
||||
@@ -139,10 +131,7 @@ function Model({
|
||||
logModelStatus(assetId, "backend-loaded");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
`[Backend] Error storing/loading ${asset.modelName}:`,
|
||||
error
|
||||
);
|
||||
console.error(`[Backend] Error storing/loading ${asset.modelName}:`, error);
|
||||
});
|
||||
},
|
||||
undefined,
|
||||
@@ -156,8 +145,7 @@ function Model({
|
||||
});
|
||||
}, []);
|
||||
|
||||
const { handleDblClick, handleClick, handlePointerOver, handlePointerOut, handleContextMenu } =
|
||||
useModelEventHandlers({ boundingBox, groupRef, asset });
|
||||
const { handleDblClick, handleClick, handlePointerOver, handlePointerOut, handleContextMenu } = useModelEventHandlers({ boundingBox, groupRef, asset });
|
||||
|
||||
return (
|
||||
<group
|
||||
@@ -205,30 +193,14 @@ function Model({
|
||||
<>
|
||||
{isRendered ? (
|
||||
<>
|
||||
<primitive visible={asset.isVisible} object={gltfScene} />
|
||||
<primitive visible={asset.isVisible && isAssetVisible(asset.modelUuid)} object={gltfScene} />
|
||||
|
||||
<ModelAnimator asset={asset} gltfScene={gltfScene} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{!hasSelectedAsset(asset.modelUuid) && (
|
||||
<AssetBoundingBox
|
||||
name="Asset Fallback"
|
||||
boundingBox={boundingBox}
|
||||
color="gray"
|
||||
lineWidth={2.5}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{hasSelectedAsset(asset.modelUuid) && (
|
||||
<AssetBoundingBox
|
||||
name="Asset BBox"
|
||||
boundingBox={boundingBox}
|
||||
color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"}
|
||||
lineWidth={2.7}
|
||||
/>
|
||||
<>{!hasSelectedAsset(asset.modelUuid) && <AssetBoundingBox name="Asset Fallback" boundingBox={boundingBox} color="gray" lineWidth={2.5} />}</>
|
||||
)}
|
||||
{hasSelectedAsset(asset.modelUuid) && <AssetBoundingBox name="Asset BBox" boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />}
|
||||
</>
|
||||
)}
|
||||
</group>
|
||||
|
||||
@@ -24,9 +24,10 @@ const SelectionControls3D: React.FC = () => {
|
||||
const { toolMode } = useToolMode();
|
||||
const { builderSocket, simulationSocket } = useSocketStore();
|
||||
const { contextAction, setContextAction } = useContextActionStore();
|
||||
const { assetStore, productStore, undoRedo3DStore, versionStore } = useSceneContext();
|
||||
const { assetStore, productStore, undoRedo3DStore, versionStore, assetGroupStore } = useSceneContext();
|
||||
const { selectedDecal, selectedWall, selectedAisle, selectedFloor, selectedWallAsset } = useBuilderStore();
|
||||
const { push3D, undoStack, redoStack } = undoRedo3DStore();
|
||||
const { isAssetVisible } = assetGroupStore();
|
||||
const { selectedProduct, updateEvent, deleteEvent } = productStore();
|
||||
const {
|
||||
assets,
|
||||
@@ -253,7 +254,13 @@ const SelectionControls3D: React.FC = () => {
|
||||
let currentObject: THREE.Object3D | null = object;
|
||||
while (currentObject) {
|
||||
// if (currentObject.userData.modelUuid && !currentObject.userData.wallAssetType) {
|
||||
if (currentObject.userData.modelUuid && !currentObject.userData.wallAssetType && currentObject.userData.isVisible && currentObject.visible) {
|
||||
if (
|
||||
currentObject.userData.modelUuid &&
|
||||
!currentObject.userData.wallAssetType &&
|
||||
currentObject.userData.isVisible &&
|
||||
currentObject.visible &&
|
||||
isAssetVisible(currentObject.userData.modelUuid)
|
||||
) {
|
||||
Objects.add(currentObject);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -77,13 +77,10 @@ const Project: React.FC = () => {
|
||||
}, [projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (token && refreshToken && projectId) {
|
||||
if (projectId) {
|
||||
echo.warn("Validating token");
|
||||
initializeBuilderSocket(token, refreshToken, projectId);
|
||||
initializeSimulationSocket(token, refreshToken, projectId);
|
||||
initializeBuilderSocket(projectId);
|
||||
initializeSimulationSocket(projectId);
|
||||
echo.success("Builder socket initialized");
|
||||
} else {
|
||||
navigate("/");
|
||||
@@ -100,11 +97,8 @@ const Project: React.FC = () => {
|
||||
}, [projectId, builderSocket]);
|
||||
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (token && refreshToken && projectId) {
|
||||
initializeVisualizationSocket(token, refreshToken, projectId);
|
||||
if (projectId) {
|
||||
initializeVisualizationSocket(projectId);
|
||||
echo.success("Visualization socket initialized");
|
||||
} else {
|
||||
navigate("/");
|
||||
@@ -121,11 +115,8 @@ const Project: React.FC = () => {
|
||||
}, [projectId, visualizationSocket]);
|
||||
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (token && refreshToken && projectId) {
|
||||
initializeThreadSocket(token, refreshToken, projectId);
|
||||
if (projectId) {
|
||||
initializeThreadSocket(projectId);
|
||||
echo.success("Thread socket initialized");
|
||||
} else {
|
||||
navigate("/");
|
||||
@@ -142,11 +133,8 @@ const Project: React.FC = () => {
|
||||
}, [projectId, threadSocket]);
|
||||
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (token && refreshToken && projectId) {
|
||||
initializeSimulationSocket(token, refreshToken, projectId);
|
||||
if (projectId) {
|
||||
initializeSimulationSocket(projectId);
|
||||
echo.success("Simulation socket initialized");
|
||||
} else {
|
||||
navigate("/");
|
||||
|
||||
@@ -27,8 +27,9 @@ interface AssetGroupStore {
|
||||
|
||||
// Group properties
|
||||
setGroupName: (groupUuid: string, newName: string) => void;
|
||||
setGroupVisibility: (groupUuid: string, isVisible: boolean) => void;
|
||||
setGroupLock: (groupUuid: string, isLocked: boolean) => void;
|
||||
setGroupVisibility: (groupUuid: string, isVisible: boolean) => void;
|
||||
toggleGroupLock: (groupUuid: string) => void;
|
||||
toggleGroupVisibility: (groupUuid: string) => void;
|
||||
setGroupExpanded: (groupUuid: string, isExpanded: boolean) => void;
|
||||
|
||||
@@ -46,7 +47,12 @@ interface AssetGroupStore {
|
||||
getParentGroup: (item: AssetGroupChild) => string | null;
|
||||
hasGroup: (groupUuid: string) => boolean;
|
||||
isGroup: (item: AssetGroupChild) => item is AssetGroupHierarchyNode;
|
||||
getItemId: (i: AssetGroupChild) => string;
|
||||
isEmptyGroup: (groupUuid: string) => boolean;
|
||||
isAssetGroupVisible: (groupUuid: string) => boolean;
|
||||
isAssetGroupLocked: (groupUuid: string) => boolean;
|
||||
isAssetVisible: (assetUuid: string) => boolean;
|
||||
isAssetLocked: (assetUuid: string) => boolean;
|
||||
}
|
||||
|
||||
export const createAssetGroupStore = () => {
|
||||
@@ -228,6 +234,15 @@ export const createAssetGroupStore = () => {
|
||||
});
|
||||
},
|
||||
|
||||
setGroupLock: (groupUuid, isLocked) => {
|
||||
set((state) => {
|
||||
const group = state.assetGroups.find((g) => g.groupUuid === groupUuid);
|
||||
if (group) {
|
||||
group.isLocked = isLocked;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setGroupVisibility: (groupUuid, isVisible) => {
|
||||
set((state) => {
|
||||
const group = state.assetGroups.find((g) => g.groupUuid === groupUuid);
|
||||
@@ -237,11 +252,11 @@ export const createAssetGroupStore = () => {
|
||||
});
|
||||
},
|
||||
|
||||
setGroupLock: (groupUuid, isLocked) => {
|
||||
toggleGroupLock: (groupUuid) => {
|
||||
set((state) => {
|
||||
const group = state.assetGroups.find((g) => g.groupUuid === groupUuid);
|
||||
if (group) {
|
||||
group.isLocked = isLocked;
|
||||
group.isLocked = !group.isLocked;
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -455,10 +470,94 @@ export const createAssetGroupStore = () => {
|
||||
return "children" in item;
|
||||
},
|
||||
|
||||
getItemId: (i: AssetGroupChild): string => {
|
||||
return get().isGroup(i) ? i.groupUuid : i.modelUuid;
|
||||
},
|
||||
|
||||
isEmptyGroup: (groupUuid) => {
|
||||
const group = get().assetGroups.find((g) => g.groupUuid === groupUuid);
|
||||
return !group || group.children.length === 0;
|
||||
},
|
||||
|
||||
isAssetGroupVisible: (groupUuid: string) => {
|
||||
const state = get();
|
||||
const group = state.assetGroups.find((g) => g.groupUuid === groupUuid);
|
||||
if (!group) return true; // Default to visible if group not found
|
||||
|
||||
// If this group is not visible, return false regardless of parents
|
||||
if (!group.isVisible) return false;
|
||||
|
||||
// Check parent groups recursively
|
||||
const parentGroups = state.getGroupsContainingGroup(groupUuid);
|
||||
for (const parentGroup of parentGroups) {
|
||||
if (!state.isAssetGroupVisible(parentGroup.groupUuid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
isAssetGroupLocked: (groupUuid: string) => {
|
||||
const state = get();
|
||||
const group = state.assetGroups.find((g) => g.groupUuid === groupUuid);
|
||||
if (!group) return false; // Default to unlocked if group not found
|
||||
|
||||
// If this group is locked, return true regardless of parents
|
||||
if (group.isLocked) return true;
|
||||
|
||||
// Check parent groups recursively
|
||||
const parentGroups = state.getGroupsContainingGroup(groupUuid);
|
||||
for (const parentGroup of parentGroups) {
|
||||
if (state.isAssetGroupLocked(parentGroup.groupUuid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
isAssetVisible: (assetUuid: string) => {
|
||||
const state = get();
|
||||
|
||||
// Check if asset is in any groups
|
||||
const parentGroups = state.getGroupsContainingAsset(assetUuid);
|
||||
|
||||
// If asset is not in any groups, it's always visible
|
||||
if (parentGroups.length === 0) return true;
|
||||
|
||||
// Asset is visible only if ALL parent groups are visible
|
||||
for (const parentGroup of parentGroups) {
|
||||
if (!state.isAssetGroupVisible(parentGroup.groupUuid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
isAssetLocked: (assetUuid: string) => {
|
||||
const state = get();
|
||||
|
||||
// Check if asset is in any groups
|
||||
const parentGroups = state.getGroupsContainingAsset(assetUuid);
|
||||
|
||||
// If asset is not in any groups, check its own locked state
|
||||
if (parentGroups.length === 0) {
|
||||
// You might need access to the assets store to get the asset's own locked state
|
||||
// For now, returning false as default
|
||||
return false;
|
||||
}
|
||||
|
||||
// Asset is locked if ANY parent group is locked
|
||||
for (const parentGroup of parentGroups) {
|
||||
if (state.isAssetGroupLocked(parentGroup.groupUuid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
}))
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,11 +8,11 @@ interface SocketStore {
|
||||
threadSocket: Socket | null;
|
||||
simulationSocket: Socket | null;
|
||||
|
||||
initializeBuilderSocket: (token: string, refreshToken: string, projectId: string) => void;
|
||||
initializeVisualizationSocket: (token: string, refreshToken: string, projectId: string) => void;
|
||||
initializeThreadSocket: (token: string, refreshToken: string, projectId: string) => void;
|
||||
initializeBuilderSocket: (projectId: string) => void;
|
||||
initializeVisualizationSocket: (projectId: string) => void;
|
||||
initializeThreadSocket: (projectId: string) => void;
|
||||
initializeProjectSocket: (token: string, refreshToken: string) => void;
|
||||
initializeSimulationSocket: (token: string, refreshToken: string, projectId: string) => void;
|
||||
initializeSimulationSocket: (projectId: string) => void;
|
||||
|
||||
disconnectBuilderSocket: (projectId: string) => void;
|
||||
disconnectVisualizationSocket: (projectId: string) => void;
|
||||
@@ -56,36 +56,51 @@ export const useSocketStore = create<SocketStore>((set, get) => ({
|
||||
threadSocket: null,
|
||||
simulationSocket: null,
|
||||
|
||||
initializeBuilderSocket: (token, refreshToken, projectId) => {
|
||||
if (get().builderSocket) return;
|
||||
initializeBuilderSocket: (projectId) => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (get().builderSocket || !token || !refreshToken) return;
|
||||
const builderSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`, socketOptions({ token, refreshToken, projectId }));
|
||||
attachLogs("Builder", builderSocket);
|
||||
set({ builderSocket });
|
||||
},
|
||||
|
||||
initializeVisualizationSocket: (token, refreshToken, projectId) => {
|
||||
if (get().visualizationSocket) return;
|
||||
initializeVisualizationSocket: (projectId) => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (get().visualizationSocket || !token || !refreshToken) return;
|
||||
const visualizationSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`, socketOptions({ token, refreshToken, projectId }));
|
||||
attachLogs("Visualization", visualizationSocket);
|
||||
set({ visualizationSocket });
|
||||
},
|
||||
|
||||
initializeThreadSocket: (token, refreshToken, projectId) => {
|
||||
if (get().threadSocket) return;
|
||||
initializeThreadSocket: (projectId) => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (get().threadSocket || !token || !refreshToken) return;
|
||||
const threadSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`, socketOptions({ token, refreshToken, projectId }));
|
||||
attachLogs("Thread", threadSocket);
|
||||
set({ threadSocket });
|
||||
},
|
||||
|
||||
initializeProjectSocket: (token, refreshToken) => {
|
||||
if (get().projectSocket) return;
|
||||
initializeProjectSocket: () => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (get().projectSocket || !token || !refreshToken) return;
|
||||
const projectSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`, socketOptions({ token, refreshToken }));
|
||||
attachLogs("Project", projectSocket);
|
||||
set({ projectSocket });
|
||||
},
|
||||
|
||||
initializeSimulationSocket: (token, refreshToken, projectId) => {
|
||||
if (get().simulationSocket) return;
|
||||
initializeSimulationSocket: (projectId) => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
|
||||
if (get().simulationSocket || !token || !refreshToken) return;
|
||||
const simulationSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Simulation_v1`, socketOptions({ token, refreshToken, projectId }));
|
||||
attachLogs("Simulation", simulationSocket);
|
||||
set({ simulationSocket });
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
margin: 5px;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
transition: all 0.2s ease;
|
||||
// transition: all 0.2s ease;
|
||||
user-select: none;
|
||||
border: 1px solid transparent;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user