feat: Implement wall asset management APIs and socket integration for create, update, and delete operations

This commit is contained in:
2025-07-02 10:49:07 +05:30
parent d6f6c4c901
commit 64d086f808
9 changed files with 257 additions and 21 deletions

View File

@@ -1,4 +1,4 @@
import * as THREE from "three"
import * as THREE from "three"
import { useEffect } from 'react'
import { getFloorAssets } from '../../../services/factoryBuilder/asset/floorAsset/getFloorItemsApi';
import { useLoadingProgress, useRenameModeStore, useSelectedFloorItem, useSelectedItem, useSocketStore } from '../../../store/builder/store';

View File

@@ -1,18 +1,25 @@
import * as THREE from 'three';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useThree } from '@react-three/fiber';
import { Base, Geometry, Subtraction } from '@react-three/csg';
import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils';
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import { Base, Geometry, Subtraction } from '@react-three/csg';
import useModuleStore from '../../../../../store/useModuleStore';
import { useSceneContext } from '../../../../scene/sceneContext';
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
import { useActiveTool, useToggleView } from '../../../../../store/builder/store';
import { useActiveTool, useSocketStore, useToggleView } from '../../../../../store/builder/store';
import { useParams } from 'react-router-dom';
import { useVersionContext } from '../../../version/versionContext';
import { getUserData } from '../../../../../functions/getUserData';
import closestPointOnLineSegment from '../../../line/helpers/getClosestPointOnLineSegment';
import { useThree } from '@react-three/fiber';
import { upsertWallAssetApi } from '../../../../../services/factoryBuilder/asset/wallAsset/upsertWallAssetApi';
import { deleteWallAssetApi } from '../../../../../services/factoryBuilder/asset/wallAsset/deleteWallAssetApi';
function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
const { socket } = useSocketStore();
const { raycaster, pointer, camera, scene, controls, gl } = useThree();
const { wallStore, wallAssetStore } = useSceneContext();
const { walls, getWallById } = wallStore();
@@ -26,6 +33,10 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
const groupRef = useRef<THREE.Group>(null);
const wall = useMemo(() => getWallById(wallAsset.wallUuid), [getWallById, wallAsset.wallUuid, walls]);
const draggingRef = useRef(false);
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { userId, organization } = getUserData();
const { projectId } = useParams();
useEffect(() => {
const loader = new GLTFLoader();
@@ -131,11 +142,31 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
const wallRotation = intersect.object.rotation.clone();
updateWallAsset(wallAsset.modelUuid, {
const updatedWallAsset = updateWallAsset(wallAsset.modelUuid, {
wallUuid: intersect.object.userData.wallUuid,
position: [newPoint.x, wallAsset.wallAssetType === 'fixed-move' ? 0 : intersect.point.y, newPoint.z],
rotation: [wallRotation.x, wallRotation.y, wallRotation.z],
});
if (projectId && updatedWallAsset) {
// API
// upsertWallAssetApi(projectId, selectedVersion?.versionId || '', updatedWallAsset);
// SOCKET
const data = {
wallAssetData: updatedWallAsset,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:wall-asset:add', data);
}
}
};
@@ -149,13 +180,34 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) {
canvasElement.removeEventListener('pointerup', onPointerUp);
};
}, [gl, camera, toggleView, activeModule, selectedWallAsset])
}, [gl, camera, toggleView, activeModule, selectedWallAsset, socket])
const handlePointerClick = useCallback((wallAsset: WallAsset) => {
if (activeTool === 'delete' && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) {
removeWallAsset(wallAsset.modelUuid);
const removedWallAsset = removeWallAsset(wallAsset.modelUuid);
if (projectId && removedWallAsset) {
// API
// deleteWallAssetApi(projectId, selectedVersion?.versionId || '', removedWallAsset.modelUuid, removedWallAsset.wallUuid);
// SOCKET
const data = {
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization,
modelUuid: removedWallAsset.modelUuid,
wallUuid: removedWallAsset.wallUuid
}
socket.emit('v1:wall-asset:delete', data);
}
}
}, [activeTool, activeModule, deletableWallAsset])
}, [activeTool, activeModule, deletableWallAsset, socket])
const handlePointerOver = useCallback((wallAsset: WallAsset, currentObject: THREE.Object3D) => {
if (activeTool === "delete" && activeModule === 'builder') {

View File

@@ -1,11 +1,16 @@
import { useThree } from '@react-three/fiber';
import { useEffect } from 'react'
import { useSelectedItem, useSocketStore, useToggleView } from '../../../store/builder/store';
import useModuleStore from '../../../store/useModuleStore';
import { useSelectedItem, useSocketStore, useToggleView } from '../../../store/builder/store';
import { MathUtils, Vector3 } from 'three';
import { useSceneContext } from '../../scene/sceneContext';
import { useParams } from 'react-router-dom';
import { useVersionContext } from '../version/versionContext';
import { getUserData } from '../../../functions/getUserData';
import closestPointOnLineSegment from '../line/helpers/getClosestPointOnLineSegment';
import { upsertWallAssetApi } from '../../../services/factoryBuilder/asset/wallAsset/upsertWallAssetApi';
function WallAssetCreator() {
const { socket } = useSocketStore();
const { pointer, camera, raycaster, scene, gl } = useThree();
@@ -14,6 +19,10 @@ function WallAssetCreator() {
const { wallAssetStore } = useSceneContext();
const { addWallAsset } = wallAssetStore();
const { selectedItem, setSelectedItem } = useSelectedItem();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { userId, organization } = getUserData();
const { projectId } = useParams();
useEffect(() => {
const canvasElement = gl.domElement;
@@ -52,6 +61,25 @@ function WallAssetCreator() {
};
addWallAsset(newWallAsset);
if (projectId) {
// API
// upsertWallAssetApi(projectId, selectedVersion?.versionId || '', newWallAsset);
// SOCKET
const data = {
wallAssetData: newWallAsset,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:wall-asset:add', data);
}
}
}
};

View File

@@ -7,6 +7,7 @@ import { useParams } from 'react-router-dom';
import useModuleStore from '../../../store/useModuleStore';
import WallAssetCreator from './wallAssetCreator'
import WallAssetInstances from './Instances/wallAssetInstances'
import { getWallAssetsApi } from '../../../services/factoryBuilder/asset/wallAsset/getWallAssetsApi';
function WallAssetGroup() {
const { togglView } = useToggleView();
@@ -26,6 +27,21 @@ function WallAssetGroup() {
setDeletableWallAsset(null);
}, [togglView, activeModule, activeTool])
useEffect(() => {
if (projectId && selectedVersion) {
getWallAssetsApi(projectId, selectedVersion?.versionId || '').then((wallAssets) => {
console.log('wallAssets: ', wallAssets);
if (wallAssets && wallAssets.length > 0) {
setWallAssets(wallAssets);
} else {
setWallAssets([]);
}
}).catch((err) => {
console.log(err);
})
}
}, [projectId, selectedVersion?.versionId])
return (
<>

View File

@@ -1,6 +1,17 @@
import React from 'react';
import { useEffect } from 'react';
import { useSocketStore } from '../../../store/builder/store';
export default function SocketResponses() {
const { socket } = useSocketStore();
useEffect(() => {
socket.on("v1:wall-asset:response:delete", (data: any) => {
});
return () => {
socket.off("v1:wall-asset:response:delete");
}
}, [socket])
return (
<>