Merge branch 'main' into rtViz

This commit is contained in:
Gomathi 2025-04-11 17:26:29 +05:30
commit 00933b34c8
3 changed files with 205 additions and 164 deletions

View File

@ -26,9 +26,14 @@ const Templates = () => {
templateData(); templateData();
}, []); }, []);
const handleDeleteTemplate = async (id: string) => { const handleDeleteTemplate = async (
e: React.MouseEvent<HTMLButtonElement>,
id: string
) => {
try { try {
e.stopPropagation();
const email = localStorage.getItem("email") || ""; const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]; const organization = email?.split("@")[1]?.split(".")[0];
let deleteTemplate = { let deleteTemplate = {
organization: organization, organization: organization,
@ -49,7 +54,6 @@ const Templates = () => {
const handleLoadTemplate = async (template: any) => { const handleLoadTemplate = async (template: any) => {
try { try {
if (selectedZone.zoneName === "") return; if (selectedZone.zoneName === "") return;
const email = localStorage.getItem("email") || ""; const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]; const organization = email?.split("@")[1]?.split(".")[0];
@ -108,7 +112,7 @@ const Templates = () => {
<RenameInput value={`Template ${index + 1}`} /> <RenameInput value={`Template ${index + 1}`} />
</div> </div>
<button <button
onClick={() => handleDeleteTemplate(template.id)} onClick={(e) => handleDeleteTemplate(e, template.id)}
className="delete-button" className="delete-button"
aria-label="Delete template" aria-label="Delete template"
> >

View File

@ -33,7 +33,7 @@ const WidgetsFloating = () => {
}; };
return ( return (
<div className="floatingWidgets-wrapper"> <div className="floatingWidgets-wrapper widgets-wrapper">
{/* {widgets.map((widget) => ( {/* {widgets.map((widget) => (
<div <div
key={widget.id} key={widget.id}

View File

@ -10,190 +10,227 @@ import { useNavigate } from "react-router-dom";
import { Html } from "@react-three/drei"; import { Html } from "@react-three/drei";
import CollabUserIcon from "./collabUserIcon"; import CollabUserIcon from "./collabUserIcon";
import { getAvatarColor } from "./users/functions/getAvatarColor"; import { getAvatarColor } from "./users/functions/getAvatarColor";
import useModuleStore from "../../store/useModuleStore";
const CamModelsGroup = () => { const CamModelsGroup = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const groupRef = useRef<THREE.Group>(null); const groupRef = useRef<THREE.Group>(null);
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
const { activeUsers, setActiveUsers } = useActiveUsers(); const { setActiveUsers } = useActiveUsers();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { activeModule } = useModuleStore();
const loader = new GLTFLoader(); const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader(); const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("three/examples/jsm/libs/draco/gltf/"); dracoLoader.setDecoderPath("three/examples/jsm/libs/draco/gltf/");
loader.setDRACOLoader(dracoLoader); loader.setDRACOLoader(dracoLoader);
const [cams, setCams] = useState<any[]>([]); const [cams, setCams] = useState<any[]>([]);
const [models, setModels] = useState<Record<string, { targetPosition: THREE.Vector3; targetRotation: THREE.Euler }>>({}); const [models, setModels] = useState<
Record<
string,
{ targetPosition: THREE.Vector3; targetRotation: THREE.Euler }
>
>({});
const dedupeCams = (cams: any[]) => { const dedupeCams = (cams: any[]) => {
const seen = new Set(); const seen = new Set();
return cams.filter((cam) => { return cams.filter((cam) => {
if (seen.has(cam.uuid)) return false; if (seen.has(cam.uuid)) return false;
seen.add(cam.uuid); seen.add(cam.uuid);
return true; return true;
}); });
}; };
const dedupeUsers = (users: any[]) => { const dedupeUsers = (users: any[]) => {
const seen = new Set(); const seen = new Set();
return users.filter((user) => { return users.filter((user) => {
if (seen.has(user._id)) return false; if (seen.has(user._id)) return false;
seen.add(user._id); seen.add(user._id);
return true; return true;
}); });
}; };
useEffect(() => { useEffect(() => {
if (!email) navigate("/"); if (!email) navigate("/");
if (!socket) return; if (!socket) return;
const organization = email!.split("@")[1].split(".")[0]; const organization = email!.split("@")[1].split(".")[0];
socket.on("userConnectResponse", (data: any) => { socket.on("userConnectResponse", (data: any) => {
if (!groupRef.current) return; if (!groupRef.current) return;
if (data.data.userData.email === email) return; if (data.data.userData.email === email) return;
if (socket.id === data.socketId || organization !== data.organization) return; if (socket.id === data.socketId || organization !== data.organization)
return;
const model = groupRef.current.getObjectByProperty("uuid", data.data.userData._id); const model = groupRef.current.getObjectByProperty(
if (model) { "uuid",
groupRef.current.remove(model); data.data.userData._id
} );
if (model) {
groupRef.current.remove(model);
}
loader.load(camModel, (gltf) => { loader.load(camModel, (gltf) => {
const newModel = gltf.scene.clone(); const newModel = gltf.scene.clone();
newModel.uuid = data.data.userData._id; newModel.uuid = data.data.userData._id;
newModel.position.set( newModel.position.set(
data.data.position.x, data.data.position.x,
data.data.position.y, data.data.position.y,
data.data.position.z data.data.position.z
); );
newModel.rotation.set( newModel.rotation.set(
data.data.rotation.x, data.data.rotation.x,
data.data.rotation.y, data.data.rotation.y,
data.data.rotation.z data.data.rotation.z
); );
newModel.userData = data.data.userData; newModel.userData = data.data.userData;
setCams((prev) => dedupeCams([...prev, newModel])); setCams((prev) => dedupeCams([...prev, newModel]));
setActiveUsers((prev: any) => setActiveUsers((prev: any) =>
dedupeUsers([...prev, data.data.userData]) dedupeUsers([...prev, data.data.userData])
); );
}); });
}); });
socket.on("userDisConnectResponse", (data: any) => { socket.on("userDisConnectResponse", (data: any) => {
if (!groupRef.current) return; if (!groupRef.current) return;
if (socket.id === data.socketId || organization !== data.organization) return; if (socket.id === data.socketId || organization !== data.organization)
return;
setCams((prev) => setCams((prev) =>
prev.filter((cam) => cam.uuid !== data.data.userData._id) prev.filter((cam) => cam.uuid !== data.data.userData._id)
); );
setActiveUsers((prev: any) => setActiveUsers((prev: any) =>
prev.filter((user: any) => user._id !== data.data.userData._id) prev.filter((user: any) => user._id !== data.data.userData._id)
); );
}); });
socket.on("cameraUpdateResponse", (data: any) => { socket.on("cameraUpdateResponse", (data: any) => {
if ( if (
!groupRef.current || !groupRef.current ||
socket.id === data.socketId || socket.id === data.socketId ||
organization !== data.organization organization !== data.organization
) )
return; return;
setModels((prev) => ({ setModels((prev) => ({
...prev, ...prev,
[data.data.userId]: { [data.data.userId]: {
targetPosition: new THREE.Vector3( targetPosition: new THREE.Vector3(
data.data.position.x, data.data.position.x,
data.data.position.y, data.data.position.y,
data.data.position.z data.data.position.z
), ),
targetRotation: new THREE.Euler( targetRotation: new THREE.Euler(
data.data.rotation.x, data.data.rotation.x,
data.data.rotation.y, data.data.rotation.y,
data.data.rotation.z data.data.rotation.z
), ),
}, },
})); }));
}); });
return () => { return () => {
socket.off("userConnectResponse"); socket.off("userConnectResponse");
socket.off("userDisConnectResponse"); socket.off("userDisConnectResponse");
socket.off("cameraUpdateResponse"); socket.off("cameraUpdateResponse");
}; };
}, [socket]); }, [socket]);
useFrame(() => { useFrame(() => {
if (!groupRef.current) return; if (!groupRef.current) return;
Object.keys(models).forEach((uuid) => { Object.keys(models).forEach((uuid) => {
const model = groupRef.current!.getObjectByProperty("uuid", uuid); const model = groupRef.current!.getObjectByProperty("uuid", uuid);
if (!model) return; if (!model) return;
const { targetPosition, targetRotation } = models[uuid]; const { targetPosition, targetRotation } = models[uuid];
model.position.lerp(targetPosition, 0.1); model.position.lerp(targetPosition, 0.1);
model.rotation.x = THREE.MathUtils.lerp(model.rotation.x, targetRotation.x, 0.1); model.rotation.x = THREE.MathUtils.lerp(
model.rotation.y = THREE.MathUtils.lerp(model.rotation.y, targetRotation.y, 0.1); model.rotation.x,
model.rotation.z = THREE.MathUtils.lerp(model.rotation.z, targetRotation.z, 0.1); targetRotation.x,
}); 0.1
}); );
model.rotation.y = THREE.MathUtils.lerp(
model.rotation.y,
targetRotation.y,
0.1
);
model.rotation.z = THREE.MathUtils.lerp(
model.rotation.z,
targetRotation.z,
0.1
);
});
});
useEffect(() => { useEffect(() => {
if (!groupRef.current) return; if (!groupRef.current) return;
const organization = email!.split("@")[1].split(".")[0]; const organization = email!.split("@")[1].split(".")[0];
getActiveUsersData(organization).then((data) => { getActiveUsersData(organization).then((data) => {
const filteredData = data.cameraDatas.filter( const filteredData = data.cameraDatas.filter(
(camera: any) => camera.userData.email !== email (camera: any) => camera.userData.email !== email
); );
if (filteredData.length > 0) { if (filteredData.length > 0) {
loader.load(camModel, (gltf) => { loader.load(camModel, (gltf) => {
const newCams = filteredData.map((cam: any) => { const newCams = filteredData.map((cam: any) => {
const newModel = gltf.scene.clone(); const newModel = gltf.scene.clone();
newModel.uuid = cam.userData._id; newModel.uuid = cam.userData._id;
newModel.position.set(cam.position.x, cam.position.y, cam.position.z); newModel.position.set(
newModel.rotation.set(cam.rotation.x, cam.rotation.y, cam.rotation.z); cam.position.x,
newModel.userData = cam.userData; cam.position.y,
return newModel; cam.position.z
}); );
newModel.rotation.set(
cam.rotation.x,
cam.rotation.y,
cam.rotation.z
);
newModel.userData = cam.userData;
return newModel;
});
const users = filteredData.map((cam: any) => cam.userData); const users = filteredData.map((cam: any) => cam.userData);
setActiveUsers((prev: any) => dedupeUsers([...prev, ...users])); setActiveUsers((prev: any) => dedupeUsers([...prev, ...users]));
setCams((prev) => dedupeCams([...prev, ...newCams])); setCams((prev) => dedupeCams([...prev, ...newCams]));
}); });
} }
}); });
}, []); }, []);
return ( return (
<group ref={groupRef} name="Cam-Model-Group"> <group
{cams.map((cam, index) => ( ref={groupRef}
<primitive key={cam.uuid} object={cam}> name="Cam-Model-Group"
<Html visible={activeModule !== "visualization" ? true : false}
as="div" >
center {cams.map((cam, index) => (
zIndexRange={[1, 0]} <primitive key={cam.uuid} object={cam}>
sprite <Html
style={{ as="div"
color: "white", center
textAlign: "center", zIndexRange={[1, 0]}
fontFamily: "Arial, sans-serif", sprite
}} style={{
position={[-0.015, 0, 0.7]} color: "white",
> textAlign: "center",
<CollabUserIcon fontFamily: "Arial, sans-serif",
userImage={cam.userData.userImage ||""} display: `${activeModule !== "visualization" ? "" : "none"}`,
userName={cam.userData.userName} }}
color={getAvatarColor(index, cam.userData.userName)} position={[-0.015, 0, 0.7]}
/> >
</Html> <CollabUserIcon
</primitive> userImage={cam.userData.userImage || ""}
))} userName={cam.userData.userName}
</group> color={getAvatarColor(index, cam.userData.userName)}
); />
</Html>
</primitive>
))}
</group>
);
}; };
export default CamModelsGroup; export default CamModelsGroup;