Merge branch 'main-dev' into dev-refactor

This commit is contained in:
2025-06-24 15:41:18 +05:30
114 changed files with 591 additions and 273 deletions

View File

@@ -16,7 +16,7 @@ async function loadInitialWallItems(
const { organization, email } = getUserData();
if (!email) {
throw new Error("No email found in localStorage");
console.error("No email found in localStorage");
}
const items = await getWallItems(organization, projectId, versionId);

View File

@@ -48,14 +48,11 @@ function AisleInstances() {
{toggleView &&
<Html
// data
key={`${aisle.points[0].pointUuid}_${aisle.points[1].pointUuid}`}
userData={aisle}
position={[textPosition.x, 1, textPosition.z]}
// class
wrapperClass="distance-text-wrapper"
className="distance-text"
// other
zIndexRange={[1, 0]}
prepend
sprite
@@ -68,7 +65,6 @@ function AisleInstances() {
</div>
</Html>
}
</React.Fragment>
)
})}

View File

@@ -104,7 +104,7 @@ export default function Builder() {
const { setWalls } = useWalls();
const { refTextupdate, setRefTextUpdate } = useRefTextUpdate();
const { projectId } = useParams();
const { setHoveredPoint } = useBuilderStore();
const { setHoveredPoint, setHoveredLine } = useBuilderStore();
const { userId, organization } = getUserData();
// const loader = new GLTFLoader();
@@ -127,7 +127,9 @@ export default function Builder() {
dragPointControls
);
} else {
setHoveredLine(null);
setHoveredPoint(null);
state.gl.domElement.style.cursor = 'default';
setToolMode('cursor');
loadWalls(lines, setWalls);
setUpdateScene(true);

View File

@@ -123,7 +123,7 @@ function loadOnlyFloors(
const originalPoint = originalLines.flat().find(([point]) => point.x === x && point.z === z);
if (!originalPoint) {
throw new Error(`Original point for coordinate [${x}, ${z}] not found.`);
console.error(`Original point for coordinate [${x}, ${z}] not found.`);
}
return originalPoint;

View File

@@ -39,7 +39,7 @@ const ZoneGroup: React.FC = () => {
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
const { userId, organization, email } = getUserData();
const { userId, organization } = getUserData();
const groupsRef = useRef<any>();
@@ -384,13 +384,7 @@ const ZoneGroup: React.FC = () => {
drag = true;
}
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
if (intersects.length > 0 && intersects[0].object.name.includes("point")) {
gl.domElement.style.cursor = toolMode === "move" ? "pointer" : "default";
} else {
gl.domElement.style.cursor = "default";
}
if (isDragging && draggedSphere) {
raycaster.setFromCamera(pointer, camera);
const intersectionPoint = new THREE.Vector3();

View File

@@ -1,13 +1,26 @@
import * as THREE from 'three';
import { useMemo } from "react";
import { useEffect, useMemo, useState } from "react";
import * as Constants from '../../../types/world/worldConstants';
import { Tube } from '@react-three/drei';
import { DragControls, Tube } from '@react-three/drei';
import { useToolMode } from '../../../store/builder/store';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
import { useWallStore } from '../../../store/builder/useWallStore';
import { useThree } from '@react-three/fiber';
interface LineProps {
points: [Point, Point];
}
function Line({ points }: Readonly<LineProps>) {
const [isHovered, setIsHovered] = useState(false);
const { raycaster, camera, pointer, gl } = useThree();
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
const [isDeletable, setIsDeletable] = useState(false);
const { toolMode } = useToolMode();
const { removeWallByPoints, setPosition } = useWallStore();
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
const { hoveredLine, setHoveredLine, hoveredPoint } = useBuilderStore();
const path = useMemo(() => {
const [start, end] = points.map(p => new THREE.Vector3(...p.position));
return new THREE.LineCurve3(start, end);
@@ -44,16 +57,119 @@ function Line({ points }: Readonly<LineProps>) {
}
}
useEffect(() => {
if (toolMode === '2D-Delete') {
if (isHovered && !hoveredPoint) {
setIsDeletable(true);
} else {
setIsDeletable(false);
}
} else {
setIsDeletable(false);
}
}, [isHovered, colors.defaultLineColor, colors.defaultDeleteColor, toolMode, hoveredPoint]);
useEffect(() => {
if (hoveredLine && (hoveredLine[0].pointUuid !== points[0].pointUuid || hoveredLine[1].pointUuid !== points[1].pointUuid)) {
setIsHovered(false);
}
}, [hoveredLine])
const handlePointClick = (points: [Point, Point]) => {
if (toolMode === '2D-Delete') {
if (points[0].pointType === 'Wall' && points[1].pointType === 'Wall') {
removeWallByPoints(points);
}
gl.domElement.style.cursor = 'default';
}
}
const handleDrag = (points: [Point, Point]) => {
if (toolMode === 'move' && isHovered && dragOffset) {
raycaster.setFromCamera(pointer, camera);
const intersectionPoint = new THREE.Vector3();
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (hit) {
gl.domElement.style.cursor = 'move';
const positionWithOffset = new THREE.Vector3().addVectors(hit, dragOffset);
const start = new THREE.Vector3(...points[0].position);
const end = new THREE.Vector3(...points[1].position);
const midPoint = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
const delta = new THREE.Vector3().subVectors(positionWithOffset, midPoint);
const newStart = new THREE.Vector3().addVectors(start, delta);
const newEnd = new THREE.Vector3().addVectors(end, delta);
setPosition(points[0].pointUuid, [newStart.x, newStart.y, newStart.z]);
setPosition(points[1].pointUuid, [newEnd.x, newEnd.y, newEnd.z]);
}
}
};
const handleDragStart = (points: [Point, Point]) => {
raycaster.setFromCamera(pointer, camera);
const intersectionPoint = new THREE.Vector3();
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (hit && !hoveredPoint) {
const start = new THREE.Vector3(...points[0].position);
const end = new THREE.Vector3(...points[1].position);
const midPoint = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
const offset = new THREE.Vector3().subVectors(midPoint, hit);
setDragOffset(offset);
}
};
const handleDragEnd = (points: [Point, Point]) => {
gl.domElement.style.cursor = 'default';
setDragOffset(null);
if (toolMode !== 'move') return;
if (points[0].pointType === 'Wall' && points[1].pointType === 'Wall') {
// console.log('Wall after drag: ', points);
}
}
return (
<Tube
name={`${points[0].pointType}-Line`}
key={`${points[0].pointUuid}-${points[1].pointUuid}`}
uuid={`${points[0].pointUuid}-${points[1].pointUuid}`}
userData={{ points, path }}
args={[path, Constants.lineConfig.tubularSegments, Constants.lineConfig.radius, Constants.lineConfig.radialSegments, false]}
<DragControls
axisLock="y"
autoTransform={false}
onDragStart={() => handleDragStart(points)}
onDrag={() => handleDrag(points)}
onDragEnd={() => handleDragEnd(points)}
>
<meshStandardMaterial color={colors.defaultLineColor} />
</Tube>
<Tube
name={`${points[0].pointType}-Line`}
key={`${points[0].pointUuid}-${points[1].pointUuid}`}
uuid={`${points[0].pointUuid}-${points[1].pointUuid}`}
userData={{ points, path }}
args={[path, Constants.lineConfig.tubularSegments, Constants.lineConfig.radius, Constants.lineConfig.radialSegments, false]}
onClick={() => {
handlePointClick(points);
}}
onPointerOver={() => {
if (!hoveredLine) {
setHoveredLine(points);
setIsHovered(true)
if (toolMode === 'move' && !hoveredPoint) {
gl.domElement.style.cursor = 'pointer';
}
}
}}
onPointerOut={() => {
if (hoveredLine) {
setHoveredLine(null);
gl.domElement.style.cursor = 'default';
}
setIsHovered(false)
}}
>
<meshStandardMaterial color={isDeletable ? colors.defaultDeleteColor : colors.defaultLineColor} />
</Tube>
</DragControls >
);
}

View File

@@ -15,9 +15,10 @@ import { useSceneContext } from '../../scene/sceneContext';
function Point({ point }: { readonly point: Point }) {
const materialRef = useRef<THREE.ShaderMaterial>(null);
const { raycaster, camera, pointer } = useThree();
const { raycaster, camera, pointer, gl } = useThree();
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
const [isHovered, setIsHovered] = useState(false);
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
const { toolMode } = useToolMode();
const { aisleStore } = useSceneContext();
const { setPosition: setAislePosition, removePoint: removeAislePoint, getAislesByPointId } = aisleStore();
@@ -91,33 +92,45 @@ function Point({ point }: { readonly point: Point }) {
}), [colors.defaultInnerColor, colors.defaultOuterColor]);
const handleDrag = (point: Point) => {
if (toolMode === 'move' && isHovered) {
if (toolMode === 'move' && isHovered && dragOffset) {
raycaster.setFromCamera(pointer, camera);
const intersectionPoint = new THREE.Vector3();
const position = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (point.pointType === 'Aisle') {
if (position) {
const newPosition: [number, number, number] = [position.x, position.y, position.z];
const aisleSnappedPosition = snapAisleAngle(newPosition);
const finalSnappedPosition = snapAislePoint(aisleSnappedPosition.position);
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
setAislePosition(point.pointUuid, finalSnappedPosition.position);
if (hit) {
gl.domElement.style.cursor = 'move';
const positionWithOffset = new THREE.Vector3().addVectors(hit, dragOffset);
const newPosition: [number, number, number] = [positionWithOffset.x, positionWithOffset.y, positionWithOffset.z];
}
} else if (point.pointType === 'Wall') {
if (position) {
const newPosition: [number, number, number] = [position.x, position.y, position.z];
const wallSnappedPosition = snapWallAngle(newPosition);
const finalSnappedPosition = snapWallPoint(wallSnappedPosition.position);
setWallPosition(point.pointUuid, finalSnappedPosition.position);
if (point.pointType === 'Aisle') {
const aisleSnapped = snapAisleAngle(newPosition);
const finalSnapped = snapAislePoint(aisleSnapped.position);
setAislePosition(point.pointUuid, finalSnapped.position);
} else if (point.pointType === 'Wall') {
const wallSnapped = snapWallAngle(newPosition);
const finalSnapped = snapWallPoint(wallSnapped.position);
setWallPosition(point.pointUuid, finalSnapped.position);
}
}
}
}
};
const handleDragStart = (point: Point) => {
raycaster.setFromCamera(pointer, camera);
const intersectionPoint = new THREE.Vector3();
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (hit) {
const currentPosition = new THREE.Vector3(...point.position);
const offset = new THREE.Vector3().subVectors(currentPosition, hit);
setDragOffset(offset);
}
};
const handleDragEnd = (point: Point) => {
if (toolMode === '2D-Delete') return;
gl.domElement.style.cursor = 'default';
setDragOffset(null);
if (toolMode !== 'move') return;
if (point.pointType === 'Aisle') {
const updatedAisles = getAislesByPointId(point.pointUuid);
if (updatedAisles.length > 0 && projectId) {
@@ -148,6 +161,7 @@ function Point({ point }: { readonly point: Point }) {
setHoveredPoint(null);
}
}
gl.domElement.style.cursor = 'default';
}
}
@@ -165,8 +179,9 @@ function Point({ point }: { readonly point: Point }) {
<DragControls
axisLock='y'
autoTransform={false}
onDrag={() => { handleDrag(point) }}
onDragEnd={() => { handleDragEnd(point) }}
onDragStart={() => handleDragStart(point)}
onDrag={() => handleDrag(point)}
onDragEnd={() => handleDragEnd(point)}
>
<mesh
key={point.pointUuid}
@@ -179,12 +194,16 @@ function Point({ point }: { readonly point: Point }) {
onPointerOver={() => {
if (!hoveredPoint) {
setHoveredPoint(point);
setIsHovered(true)
setIsHovered(true);
if (toolMode === 'move') {
gl.domElement.style.cursor = 'pointer';
}
}
}}
onPointerOut={() => {
if (hoveredPoint) {
setHoveredPoint(null);
gl.domElement.style.cursor = 'default';
}
setIsHovered(false)
}}

View File

@@ -120,7 +120,6 @@ export function useWallClassification(walls: Walls) {
}
});
console.log('rooms: ', rooms);
return rooms;
};

View File

@@ -8,17 +8,17 @@ import { useWallStore } from '../../../../../store/builder/useWallStore';
import { useWallClassification } from './helpers/useWallClassification';
import { useFrame, useThree } from '@react-three/fiber';
import { useWallVisibility } from '../../../../../store/builder/store';
import { Decal, PivotControls } from '@react-three/drei';
import { Base, Geometry, Subtraction } from '@react-three/csg';
import { Decal } from '@react-three/drei';
import { Base } from '@react-three/csg';
function Wall({ wall }: { readonly wall: Wall }) {
const { walls } = useWallStore();
const { getWallType, isWallFlipped } = useWallClassification(walls);
const wallType = getWallType(wall);
const [visible, setVisible] = useState(true);
const { wallVisibility } = useWallVisibility();
const meshRef = useRef<any>();
const { camera } = useThree();
const { wallVisibility } = useWallVisibility();
const { getWallType, isWallFlipped } = useWallClassification(walls);
const [visible, setVisible] = useState(true);
const meshRef = useRef<any>();
const wallType = getWallType(wall);
const wallFlipped = isWallFlipped(wall);
@@ -84,7 +84,6 @@ function Wall({ wall }: { readonly wall: Wall }) {
camera.getWorldDirection(u);
if (!u || !v) return;
setVisible((2 * v.dot(u)) <= 0.1);
} else {
setVisible(true);
}

View File

@@ -1,13 +1,22 @@
import React, { useEffect, useMemo, useRef } from 'react';
import React, { useEffect, useMemo } from 'react';
import { DoubleSide, RepeatWrapping, Shape, SRGBColorSpace, TextureLoader, Vector2, Vector3 } from 'three';
import { Geometry } from '@react-three/csg';
import { Html, Extrude } from '@react-three/drei';
import { useWallStore } from '../../../../store/builder/useWallStore'
import WallInstance from './instance/wallInstance';
import { useWallClassification } from './instance/helpers/useWallClassification';
import { useToggleView } from '../../../../store/builder/store';
import Line from '../../line/line';
import Point from '../../point/point';
import { useToggleView } from '../../../../store/builder/store';
import { Geometry } from '@react-three/csg';
import WallInstance from './instance/wallInstance';
import * as Constants from '../../../../types/world/worldConstants';
import texturePath from "../../../../assets/textures/floor/white.png";
import texturePathDark from "../../../../assets/textures/floor/black.png";
import { useLoader } from '@react-three/fiber';
function WallInstances() {
const { walls } = useWallStore();
const { rooms } = useWallClassification(walls)
const { toggleView } = useToggleView();
useEffect(() => {
@@ -32,24 +41,22 @@ function WallInstances() {
return (
<>
{!toggleView && (
<mesh name='Walls-Group'>
{/* <Base name="base" geometry={box} scale={[3, 3, 3]} /> */}
<Geometry useGroups>
{walls.map((wall) => (
<WallInstance key={wall.wallUuid} wall={wall} />
))}
</Geometry>
{/* <Subtraction rotation={[0, Math.PI / 2, 0]} position={[-1.425, -0.45, 0]} scale={[1, 3, 1]}>
<Geometry>
<Base geometry={box} />
<>
<mesh name='Walls-Group'>
<Geometry useGroups>
{walls.map((wall) => (
<WallInstance key={wall.wallUuid} wall={wall} />
))}
</Geometry>
</Subtraction> */}
</mesh>
</mesh>
<group name='Wall-Floors-Group'>
{rooms.map((room, index) => (
<Floor key={index} room={room} />
))}
</group>
</>
)}
{toggleView && (
@@ -61,11 +68,42 @@ function WallInstances() {
</group>
<group name='Wall-Lines-Group'>
{walls.map((wall) => (
<React.Fragment key={wall.wallUuid}>
<Line points={wall.points} />
</React.Fragment>
))}
{walls.map((wall) => {
const textPosition = new Vector3().addVectors(new Vector3(...wall.points[0].position), new Vector3(...wall.points[1].position)).divideScalar(2);
const distance = new Vector3(...wall.points[0].position).distanceTo(new Vector3(...wall.points[1].position));
return (
< React.Fragment key={wall.wallUuid}>
{toggleView &&
<Html
key={`${wall.points[0].pointUuid}_${wall.points[1].pointUuid}`}
userData={wall}
position={[textPosition.x, 1, textPosition.z]}
wrapperClass="distance-text-wrapper"
className="distance-text"
zIndexRange={[1, 0]}
prepend
sprite
>
<div
key={wall.wallUuid}
className={`distance ${wall.wallUuid}`}
>
{distance.toFixed(2)} m
</div>
</Html>
}
</React.Fragment>
)
})}
</group>
</>
)}
@@ -73,4 +111,36 @@ function WallInstances() {
)
}
export default WallInstances
export default WallInstances;
function Floor({ room }: { room: Point[] }) {
const savedTheme: string | null = localStorage.getItem('theme');
const textureScale = Constants.floorConfig.textureScale;
const floorTexture = useLoader(TextureLoader, savedTheme === "dark" ? texturePathDark : texturePath);
floorTexture.wrapS = floorTexture.wrapT = RepeatWrapping;
floorTexture.repeat.set(textureScale, textureScale);
floorTexture.colorSpace = SRGBColorSpace;
const shape = useMemo(() => {
const shape = new Shape();
const points = room.map(p => new Vector2(p.position[0], p.position[2]));
if (points.length < 3) return null;
shape.moveTo(points[0].x, points[0].y);
points.forEach((pt) => { shape.lineTo(pt.x, pt.y); });
return shape;
}, [room]);
if (!shape) return null;
return (
<group name="Wall-Floor" rotation={[Math.PI / 2, 0, 0]}>
<Extrude
args={[shape, { depth: Constants.floorConfig.height, bevelEnabled: false }]}
position={[0, 0, 0]}
receiveShadow
>
<meshStandardMaterial color={Constants.floorConfig.defaultColor} map={floorTexture} side={DoubleSide} />
</Extrude>
</group>
);
}

View File

@@ -243,7 +243,7 @@ function WallCreator() {
canvasElement.removeEventListener("click", onMouseClick);
canvasElement.removeEventListener("contextmenu", onContext);
};
}, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addWall, getWallPointById, snappedPosition, snappedPoint]);
}, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addWall, getWallPointById, wallThickness, wallHeight, insideMaterial, outsideMaterial, snappedPosition, snappedPoint]);
return (
<>

View File

@@ -1,18 +1,16 @@
import { useEffect, useState } from "react";
import { useThree } from "@react-three/fiber";
import { MathUtils, Vector3 } from "three";
import { Vector3 } from "three";
import CommentInstances from "./instances/commentInstances";
import { Sphere } from "@react-three/drei";
import { useActiveTool, useSelectedComment } from "../../../store/builder/store";
function CommentsGroup() {
const { gl, raycaster, camera, scene, pointer, size } = useThree();
const { activeTool } = useActiveTool();
const [hoverPos, setHoverPos] = useState<Vector3 | null>(null);
const { setSelectedComment, setCommentPositionState, setPosition2Dstate } = useSelectedComment();
useEffect(() => {
const canvasElement = gl.domElement;

View File

@@ -5,17 +5,19 @@ import { getAllThreads } from '../../../../services/factoryBuilder/comments/getA
import { useParams } from 'react-router-dom';
import { getUserData } from '../../../../functions/getUserData';
import { getRelativeTime } from '../../../../components/ui/collaboration/function/getRelativeTime';
import { useVersionContext } from '../../../builder/version/versionContext';
function CommentInstances() {
const { comments, setComments } = useCommentStore();
const { projectId } = useParams();
const { userId } = getUserData()
const getThreads = async () => {
if (!projectId) return;
try {
const getComments = await getAllThreads(projectId);
const { userId } = getUserData();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const getThreads = async () => {
if (!projectId || !selectedVersion) return;
try {
const getComments = await getAllThreads(projectId, selectedVersion?.versionId);
const formattedThreads = Array.isArray(getComments.data)
? getComments.data.map((thread: any) => ({
@@ -32,14 +34,12 @@ function CommentInstances() {
: [],
}))
: [];
// console.log('formattedThreads: ', formattedThreads);
setComments(formattedThreads);
} catch (err) {
// console.error("Failed to fetch threads:", err);
}
}
useEffect(() => {
getThreads();
}, []);

View File

@@ -14,12 +14,13 @@ interface ThreadSocketProps {
const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSocketProps) => {
const { threadSocket } = useSocketStore();
const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState } = useSelectedComment();
const { comments, addComment, addReply, updateComment, updateReply } = useCommentStore();
const { comments, removeReply, addComment, addReply, updateComment, updateReply } = useCommentStore();
const { userId } = getUserData();
useEffect(() => {
if (!threadSocket) return;
// --- Add Comment Handler ---
// const handleAddComment = (data: any) => {
//
@@ -55,23 +56,21 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
// };
// threadSocket.on('v1-Comment:response:add', handleAddComment);
const handleAddComment = (data: any) => {
// console.log('Add: ', data);
const commentData = {
replyId: data.data?._id,
creatorId: data.data?.userId,
createdAt: getRelativeTime(data.data?.createdAt),
lastUpdatedAt: "2 hrs ago",
comment: data.data.comment,
comment: data.data?.comment,
};
if (modeRef.current === "create") {
addReply(selectedComment?.threadId, commentData);
setMessages((prevMessages) => [...prevMessages, commentData]);
} else if (modeRef.current === "edit") {
updateReply(selectedComment?.threadId, data.data?._id, commentData);
setMessages((prev) =>
prev.map((message) => {
@@ -81,26 +80,22 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
: message;
})
);
// console.log('data.data?.comment: ', data.data?.comment);
} else {
}
threadSocket.off("v1-Comment:response:add", handleAddComment);
};
threadSocket.on('v1-Comment:response:add', handleAddComment);
// --- Delete Comment Handler ---
const handleDeleteComment = (data: any) => {
// console.log('delete: ', data);
threadSocket.off('v1-Comment:response:delete', handleDeleteComment);
};
threadSocket.on('v1-Comment:response:delete', handleDeleteComment);
// --- Create Thread Handler ---
const handleCreateThread = (data: any) => {
// console.log('createThread: ', data);
const comment: CommentSchema = {
state: 'active',
@@ -117,20 +112,26 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
addComment(comment);
setCommentPositionState(null);
// setSelectedComment(null);
threadSocket.off('v1-thread:response:create', handleCreateThread);
};
threadSocket.on('v1-thread:response:create', handleCreateThread);
// --- Delete Thread Handler ---
// const handleDeleteThread = (data: any) => {
//
// };
// threadSocket.on("v1-thread:response:delete", handleDeleteThread);
const handleDeleteThread = (data: any) => {
threadSocket.off('v1-thread:response:delete', handleDeleteThread);
};
threadSocket.on('v1-thread:response:delete', handleDeleteThread);
threadSocket.on("v1-thread:response:delete", handleDeleteThread);
const handleEditThread = (data: any) => {
const editedThread: CommentSchema = {
state: 'active',
threadId: data.data?._id,
@@ -138,17 +139,16 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
createdAt: data.data?.createdAt,
threadTitle: data.data?.threadTitle,
lastUpdatedAt: new Date().toISOString(),
position: data.data.position,
position: data.data?.position,
rotation: [0, 0, 0],
comments: data.data.comments,
comments: data.data?.comments,
};
// console.log('data.data?._id: ', data.data?._id);
//
updateComment(data.data?._id, editedThread);
setSelectedComment(editedThread)
// setSelectedComment(null);
};
threadSocket.on('v1-thread:response:updateTitle', handleEditThread);

View File

@@ -34,6 +34,7 @@ export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Co
if (!projectId && loadingProgress > 1) return;
getAllProjects(userId, organization)
.then((projects) => {
if (!projects || !projects.Projects) return;
let project = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
const canvas = document.getElementById("sceneCanvas")?.getElementsByTagName('canvas')[0];
if (!canvas) return;

View File

@@ -28,6 +28,8 @@ type SceneContextValue = {
vehicleStore: VehicleStoreType;
storageUnitStore: StorageUnitStoreType;
clearStores: () => void;
layout: 'Main Layout' | 'Comparison Layout';
};
@@ -55,8 +57,17 @@ export function SceneProvider({
const storageUnitStore = useMemo(() => createStorageUnitStore(), []);
const clearStores = useMemo(() => () => {
assetStore().clearAssets();
}, [assetStore]);
assetStore.getState().clearAssets();
aisleStore.getState().clearAisles();
eventStore.getState().clearEvents();
productStore.getState().clearProducts();
materialStore.getState().clearMaterials();
armBotStore.getState().clearArmBots();
machineStore.getState().clearMachines();
conveyorStore.getState().clearConveyors();
vehicleStore.getState().clearVehicles();
storageUnitStore.getState().clearStorageUnits();
}, [assetStore, aisleStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore]);
const contextValue = useMemo(() => (
{

View File

@@ -33,7 +33,7 @@ export const createHandleDrop = ({
const droppedData = JSON.parse(data);
const canvasElement = document.getElementById("work-space-three-d-canvas");
if (!canvasElement) throw new Error("Canvas element not found");
if (!canvasElement) return;
const rect = canvasElement.getBoundingClientRect();
const relativeX = event.clientX - rect.left;

View File

@@ -683,7 +683,7 @@ export default function Dropped3dWidgets() {
event.preventDefault();
const canvasElement = document.getElementById("work-space-three-d-canvas");
if (!canvasElement) throw new Error("Canvas element not found");
if (!canvasElement) return;
const canvasRect = canvasElement.getBoundingClientRect();
const relativeX = event.clientX - canvasRect.left;
@@ -747,7 +747,7 @@ export default function Dropped3dWidgets() {
const canvasElement = document.getElementById(
"work-space-three-d-canvas"
);
if (!canvasElement) throw new Error("Canvas element not found");
if (!canvasElement) return;
const canvasRect = canvasElement.getBoundingClientRect();
const relativeX = event.clientX - canvasRect.left;
const relativeY = event.clientY - canvasRect.top;