From 7f51ce1d58a592e14b46d82c462435290cfc606f Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Tue, 8 Jul 2025 10:12:16 +0530 Subject: [PATCH] feat: Enhance arrow and trigger connection handling with backend updates and improved event management --- .../simulation/events/arrows/arrows.tsx | 117 +++++++++++------- .../triggerConnections/triggerConnector.tsx | 18 +-- 2 files changed, 81 insertions(+), 54 deletions(-) diff --git a/app/src/modules/simulation/events/arrows/arrows.tsx b/app/src/modules/simulation/events/arrows/arrows.tsx index 59e56e2..5b9d6fd 100644 --- a/app/src/modules/simulation/events/arrows/arrows.tsx +++ b/app/src/modules/simulation/events/arrows/arrows.tsx @@ -2,6 +2,11 @@ import * as THREE from "three"; import { useMemo, useRef, useState } from "react"; import { useThree } from "@react-three/fiber"; import { useToolMode } from "../../../../store/builder/store"; +import { useSceneContext } from "../../../scene/sceneContext"; +import { useVersionContext } from "../../../builder/version/versionContext"; +import { useProductContext } from "../../products/productContext"; +import { useParams } from "react-router-dom"; +import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; interface ConnectionLine { id: string; @@ -15,6 +20,28 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[] const groupRef = useRef(null); const { scene } = useThree(); const { toolMode } = useToolMode(); + const { eventStore, productStore } = useSceneContext(); + const { removeTrigger } = productStore(); + const { selectedVersionStore } = useVersionContext(); + const { selectedVersion } = selectedVersionStore(); + const { selectedProductStore } = useProductContext(); + const { selectedProduct } = selectedProductStore(); + const { projectId } = useParams(); + + const updateBackend = ( + productName: string, + productUuid: string, + projectId: string, + eventData: EventsSchema + ) => { + upsertProductOrEventApi({ + productName: productName, + productUuid: productUuid, + projectId: projectId, + eventDatas: eventData, + versionId: selectedVersion?.versionId || '', + }) + } const getWorldPositionFromScene = (uuid: string): THREE.Vector3 | null => { const obj = scene.getObjectByProperty("uuid", uuid); @@ -24,14 +51,20 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[] return pos; }; + const processedArrows = new Set(); + const createArrow = ( key: string, fullCurve: THREE.QuadraticBezierCurve3, centerT: number, segmentSize: number, scale: number, - reverse = false + reverse: boolean, + trigger: TriggerSchema ) => { + if (processedArrows.has(trigger.triggerUuid)) return []; + processedArrows.add(trigger.triggerUuid); + const t1 = Math.max(0, centerT - segmentSize / 2); const t2 = Math.min(1, centerT + segmentSize / 2); const subCurve = getSubCurve(fullCurve, t1, t2, reverse); @@ -53,26 +86,41 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[] tangent ); + const removeConnection = (trigger: TriggerSchema) => { + if (trigger.triggerUuid) { + const event = removeTrigger(selectedProduct.productUuid, trigger.triggerUuid); + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productUuid, + projectId || '', + event + ); + } + } + }; + return ( - + setHoveredLineKey(trigger.triggerUuid)} + onPointerOut={() => setHoveredLineKey(null)} + onClick={() => { removeConnection(trigger) }} + > setHoveredLineKey(key)} - onPointerOut={() => setHoveredLineKey(null)} > setHoveredLineKey(key)} - onPointerOut={() => setHoveredLineKey(null)} > @@ -97,50 +145,29 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[] }; const arrowGroups = connections.flatMap((connection) => { - const start = getWorldPositionFromScene(connection.startPointUuid); - const end = getWorldPositionFromScene(connection.endPointUuid); + const { startPointUuid, endPointUuid } = connection; + const start = getWorldPositionFromScene(startPointUuid); + const end = getWorldPositionFromScene(endPointUuid); if (!start || !end) return []; - const isBidirectional = connections.some( - (other) => - other.startPointUuid === connection.endPointUuid && - other.endPointUuid === connection.startPointUuid - ); + const isBidirectional = connections.some((other) => other.startPointUuid === endPointUuid && other.endPointUuid === startPointUuid); - if (isBidirectional && connection.startPointUuid < connection.endPointUuid) { - const distance = start.distanceTo(end); - const heightFactor = Math.max(0.5, distance * 0.2); - const control = new THREE.Vector3( - (start.x + end.x) / 2, - Math.max(start.y, end.y) + heightFactor, - (start.z + end.z) / 2 - ); - const curve = new THREE.QuadraticBezierCurve3(start, control, end); - const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 3); + const distance = start.distanceTo(end); + const heightFactor = Math.max(0.5, distance * 0.2); + const control = new THREE.Vector3((start.x + end.x) / 2, Math.max(start.y, end.y) + heightFactor, (start.z + end.z) / 2); + const curve = new THREE.QuadraticBezierCurve3(start, control, end); + const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 5); + if (isBidirectional) { return [ - createArrow(connection.id + "-fwd", curve, 0.33, 0.25, scale, true), - createArrow(connection.id + "-bwd", curve, 0.66, 0.25, scale, false), + createArrow(connection.id + "-fwd", curve, 0.33, 0.25, scale, true, connection.trigger), + createArrow(connection.id + "-bwd", curve, 0.66, 0.25, scale, false, connection.trigger), + ]; + } else { + return [ + createArrow(connection.id, curve, 0.5, 0.3, scale, false, connection.trigger) ]; } - - if (!isBidirectional) { - const distance = start.distanceTo(end); - const heightFactor = Math.max(0.5, distance * 0.2); - const control = new THREE.Vector3( - (start.x + end.x) / 2, - Math.max(start.y, end.y) + heightFactor, - (start.z + end.z) / 2 - ); - const curve = new THREE.QuadraticBezierCurve3(start, control, end); - const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 5); - - return [ - createArrow(connection.id, curve, 0.5, 0.3, scale) - ]; - } - - return []; }); return {arrowGroups}; diff --git a/app/src/modules/simulation/events/triggerConnections/triggerConnector.tsx b/app/src/modules/simulation/events/triggerConnections/triggerConnector.tsx index ec7406c..fa035cc 100644 --- a/app/src/modules/simulation/events/triggerConnections/triggerConnector.tsx +++ b/app/src/modules/simulation/events/triggerConnections/triggerConnector.tsx @@ -503,15 +503,15 @@ function TriggerConnector() { dashed={toolMode === '3D-Delete' && hoveredLineKey === connection.id ? false : true} dashSize={0.75} dashScale={20} - onPointerOver={() => setHoveredLineKey(connection.id)} - onPointerOut={() => setHoveredLineKey(null)} - onClick={() => { - if (toolMode === '3D-Delete') { - setHoveredLineKey(null); - setCurrentLine(null); - removeConnection(connection); - } - }} + // onPointerOver={() => setHoveredLineKey(connection.id)} + // onPointerOut={() => setHoveredLineKey(null)} + // onClick={() => { + // if (toolMode === '3D-Delete') { + // setHoveredLineKey(null); + // setCurrentLine(null); + // removeConnection(connection); + // } + // }} userData={connection.trigger} /> );