api's and threads refactor

This commit is contained in:
2025-09-10 11:44:15 +05:30
parent 060d7a7d82
commit f0fdad9dff
28 changed files with 209 additions and 221 deletions

View File

@@ -7,9 +7,9 @@ import { access } from "fs";
import MultiEmailInvite from "../ui/inputs/MultiEmailInvite"; import MultiEmailInvite from "../ui/inputs/MultiEmailInvite";
import { useActiveUsers } from "../../store/builder/store"; import { useActiveUsers } from "../../store/builder/store";
import { getUserData } from "../../functions/getUserData"; import { getUserData } from "../../functions/getUserData";
import { getProjectSharedList } from "../../services/factoryBuilder/collab/getProjectSharedList"; import { getProjectSharedList } from "../../services/factoryBuilder/collab/project/getProjectSharedList";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { shareAccess } from "../../services/factoryBuilder/collab/shareAccess"; import { shareAccess } from "../../services/factoryBuilder/collab/project/shareAccess";
import { getAvatarColor } from "../../modules/collaboration/functions/getAvatarColor"; import { getAvatarColor } from "../../modules/collaboration/functions/getAvatarColor";
interface UserListTemplateProps { interface UserListTemplateProps {

View File

@@ -5,10 +5,10 @@ import { getRelativeTime } from "../function/getRelativeTime";
interface CommentThreadsProps { interface CommentThreadsProps {
commentClicked: () => void; commentClicked: () => void;
comment?: CommentSchema; thread?: ThreadSchema;
} }
const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked, comment }) => { const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked, thread }) => {
const [expand, setExpand] = useState(false); const [expand, setExpand] = useState(false);
const commentsedUsers = [{ creatorId: "1" }]; const commentsedUsers = [{ creatorId: "1" }];
const { userName } = getUserData(); const { userName } = getUserData();
@@ -51,12 +51,12 @@ const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked, comment
<div className={`last-comment-details ${expand ? "expand" : ""}`}> <div className={`last-comment-details ${expand ? "expand" : ""}`}>
<div className="header"> <div className="header">
<div className="user-name">{userName}</div> <div className="user-name">{userName}</div>
<div className="time">{comment?.createdAt && getRelativeTime(comment.createdAt)}</div> <div className="time">{thread?.createdAt && getRelativeTime(thread.createdAt)}</div>
</div> </div>
<div className="message">{comment?.threadTitle}</div> <div className="message">{thread?.threadTitle}</div>
{comment && comment?.comments.length > 0 && ( {thread && thread?.comments.length > 0 && (
<div className="comments"> <div className="comments">
{comment?.comments.length} {comment?.comments.length === 1 ? "comment" : "replies"} {thread?.comments.length} {thread?.comments.length === 1 ? "comment" : "replies"}
</div> </div>
)} )}
</div> </div>

View File

@@ -6,15 +6,14 @@ import { getUserData } from "../../../../functions/getUserData";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { useSelectedComment, useSocketStore } from "../../../../store/builder/store"; import { useSelectedComment, useSocketStore } from "../../../../store/builder/store";
import { getRelativeTime } from "../function/getRelativeTime"; import { getRelativeTime } from "../function/getRelativeTime";
import { editThreadTitleApi } from "../../../../services/factoryBuilder/comments/editThreadTitleApi"; import { editThreadTitleApi } from "../../../../services/factoryBuilder/collab/comments/editThreadTitleApi";
import { useSceneContext } from "../../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { deleteCommentApi } from "../../../../services/factoryBuilder/comments/deleteCommentApi"; import { deleteCommentApi } from "../../../../services/factoryBuilder/collab/comments/deleteCommentApi";
import { addCommentsApi } from "../../../../services/factoryBuilder/comments/addCommentApi"; import { editCommentsApi } from "../../../../services/factoryBuilder/collab/comments/editCommentApi";
import { editCommentsApi } from "../../../../services/factoryBuilder/comments/editCommentApi";
interface MessageProps { interface MessageProps {
val: Reply | CommentSchema; val: Reply | ThreadSchema;
i: number; i: number;
setMessages?: React.Dispatch<React.SetStateAction<Reply[]>>; setMessages?: React.Dispatch<React.SetStateAction<Reply[]>>;
setIsEditable?: React.Dispatch<React.SetStateAction<boolean>>; setIsEditable?: React.Dispatch<React.SetStateAction<boolean>>;
@@ -33,8 +32,8 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
const { userName, userId, organization } = getUserData(); const { userName, userId, organization } = getUserData();
const [isEditComment, setIsEditComment] = useState(false); const [isEditComment, setIsEditComment] = useState(false);
const { selectedComment, setCommentPositionState } = useSelectedComment(); const { selectedComment, setCommentPositionState } = useSelectedComment();
const { versionStore, commentStore } = useSceneContext(); const { versionStore, threadStore } = useSceneContext();
const { updateComment, removeReply, updateReply } = commentStore(); const { updateComment, removeReply, updateReply } = threadStore();
const { selectedVersion } = versionStore(); const { selectedVersion } = versionStore();
const [value, setValue] = useState<string>("comment" in val ? val.comment : val.threadTitle); const [value, setValue] = useState<string>("comment" in val ? val.comment : val.threadTitle);
@@ -52,15 +51,15 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
} }
const handleSaveAction = async () => { const handleSaveAction = async () => {
if (!projectId || !selectedVersion || !setIsEditable || !setEditedThread) return; if (!projectId || !selectedVersion) return;
if (isEditableThread && editedThread) { if (isEditableThread && editedThread) {
if (!threadSocket?.active) { if (!threadSocket?.active) {
// API // API
editThreadTitleApi(projectId, (val as CommentSchema).threadId, value, selectedVersion?.versionId || "").then((editThreadTitle) => { editThreadTitleApi(projectId, (val as ThreadSchema).threadId, value, selectedVersion?.versionId || "").then((editThreadTitle) => {
if (editThreadTitle.message == "ThreadTitle updated Successfully") { if (editThreadTitle.message == "ThreadTitle updated Successfully") {
const editedThread: CommentSchema = { const editedThread: ThreadSchema = {
state: "active", state: "active",
threadId: editThreadTitle.data.replyId, threadId: editThreadTitle.data.replyId,
creatorId: userId, creatorId: userId,
@@ -71,7 +70,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
rotation: [0, 0, 0], rotation: [0, 0, 0],
comments: [], comments: [],
}; };
updateComment((val as CommentSchema).threadId, editedThread); updateComment((val as ThreadSchema).threadId, editedThread);
} }
}); });
} else { } else {
@@ -82,7 +81,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
userId, userId,
threadTitle: value, threadTitle: value,
organization, organization,
threadId: (val as CommentSchema).threadId || selectedComment.threadId, threadId: (val as ThreadSchema).threadId || selectedComment.threadId,
versionId: selectedVersion?.versionId || "", versionId: selectedVersion?.versionId || "",
}; };
@@ -101,9 +100,10 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
comment: value, comment: value,
}; };
updateReply((val as CommentSchema).threadId, (val as Reply)?.replyId, commentData); updateReply((val as ThreadSchema).threadId, (val as Reply)?.replyId, commentData);
setIsEditable(true);
setEditedThread(false); if (setIsEditable) setIsEditable(true);
if (setEditedThread) setEditedThread(false);
}); });
} else { } else {
// SOCKET // SOCKET
@@ -119,8 +119,8 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
}; };
threadSocket.emit("v1-Comment:add", editComment); threadSocket.emit("v1-Comment:add", editComment);
setIsEditable(true); if (setIsEditable) setIsEditable(true);
setEditedThread(false); if (setEditedThread) setEditedThread(false);
} }
} }
setIsEditComment(false); setIsEditComment(false);

View File

@@ -9,9 +9,9 @@ import { getUserData } from "../../../../functions/getUserData";
import ThreadSocketResponsesDev from "../../../../modules/collaboration/socket/threadSocketResponses.dev"; import ThreadSocketResponsesDev from "../../../../modules/collaboration/socket/threadSocketResponses.dev";
import { useSceneContext } from "../../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { addCommentsApi } from "../../../../services/factoryBuilder/comments/addCommentApi"; import { addCommentsApi } from "../../../../services/factoryBuilder/collab/comments/addCommentApi";
import { deleteThreadApi } from "../../../../services/factoryBuilder/comments/deleteThreadApi"; import { deleteThreadApi } from "../../../../services/factoryBuilder/collab/comments/deleteThreadApi";
import { createThreadApi } from "../../../../services/factoryBuilder/comments/createThreadApi"; import { createThreadApi } from "../../../../services/factoryBuilder/collab/comments/createThreadApi";
import { getRelativeTime } from "../function/getRelativeTime"; import { getRelativeTime } from "../function/getRelativeTime";
const ThreadChat: React.FC = () => { const ThreadChat: React.FC = () => {
@@ -33,17 +33,17 @@ const ThreadChat: React.FC = () => {
const { threadSocket } = useSocketStore(); const { threadSocket } = useSocketStore();
const modeRef = useRef<"create" | "edit" | null>(null); const modeRef = useRef<"create" | "edit" | null>(null);
const messagesRef = useRef<HTMLDivElement>(null); const messagesRef = useRef<HTMLDivElement>(null);
const { versionStore, commentStore } = useSceneContext(); const { versionStore, threadStore } = useSceneContext();
const { selectedVersion } = versionStore(); const { selectedVersion } = versionStore();
const { addComment, removeComment, addReply, comments } = commentStore(); const { addComment, removeComment, addReply, threads } = threadStore();
useEffect(() => { useEffect(() => {
modeRef.current = mode; modeRef.current = mode;
}, [mode]); }, [mode]);
useEffect(() => { useEffect(() => {
if (comments.length > 0 && selectedComment) { if (threads.length > 0 && selectedComment) {
const allMessages = comments const allMessages = threads
.flatMap((val: any) => (val?.threadId === selectedComment?.threadId ? val.comments : [])) .flatMap((val: any) => (val?.threadId === selectedComment?.threadId ? val.comments : []))
.map((c) => { .map((c) => {
return { return {
@@ -58,7 +58,7 @@ const ThreadChat: React.FC = () => {
setMessages(allMessages); setMessages(allMessages);
} }
}, []); }, [selectedComment]);
useEffect(() => { useEffect(() => {
if (textareaRef.current) adjustHeight(textareaRef.current); if (textareaRef.current) adjustHeight(textareaRef.current);
@@ -207,7 +207,7 @@ const ThreadChat: React.FC = () => {
createThreadApi(projectId, "active", commentPositionState.position, [0, 0, 0], value, selectedVersion?.versionId || "").then((thread) => { createThreadApi(projectId, "active", commentPositionState.position, [0, 0, 0], value, selectedVersion?.versionId || "").then((thread) => {
if (thread.message === "Thread created Successfully" && thread?.threadData) { if (thread.message === "Thread created Successfully" && thread?.threadData) {
const comment: CommentSchema = { const comment: ThreadSchema = {
state: "active", state: "active",
threadId: thread?.threadData?._id, threadId: thread?.threadData?._id,
creatorId: userId, creatorId: userId,

View File

@@ -1,8 +1,8 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { getSearchUsers } from "../../../services/factoryBuilder/collab/getSearchUsers"; import { getSearchUsers } from "../../../services/factoryBuilder/collab/project/getSearchUsers";
import { shareProject } from "../../../services/factoryBuilder/collab/shareProject"; import { shareProject } from "../../../services/factoryBuilder/collab/project/shareProject";
import { getUserData } from "../../../functions/getUserData"; import { getUserData } from "../../../functions/getUserData";
interface UserData { interface UserData {

View File

@@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from "react";
import { useFrame, useThree } from "@react-three/fiber"; import { useFrame, useThree } from "@react-three/fiber";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import camModel from "../../../assets/gltf-glb/camera face 2.gltf"; import camModel from "../../../assets/gltf-glb/camera face 2.gltf";
import getActiveUsersData from "../../../services/factoryBuilder/collab/getActiveUsers"; import getActiveUsersData from "../../../services/factoryBuilder/collab/users/getActiveUsers";
import { useActiveUsers, useCamMode, useSocketStore } from "../../../store/builder/store"; import { useActiveUsers, useCamMode, useSocketStore } from "../../../store/builder/store";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";

View File

@@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import CamModelsGroup from "./camera/collabCams"; import CamModelsGroup from "./camera/collabCams";
import CommentsGroup from "./comments/commentsGroup"; import ThreadsGroup from "./threads/threadsGroup";
const Collaboration: React.FC = () => { const Collaboration: React.FC = () => {
@@ -9,7 +9,7 @@ const Collaboration: React.FC = () => {
<CamModelsGroup /> <CamModelsGroup />
<CommentsGroup /> <ThreadsGroup />
</> </>
); );

View File

@@ -14,8 +14,8 @@ interface ThreadSocketProps {
const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSocketProps) => { const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSocketProps) => {
const { threadSocket } = useSocketStore(); const { threadSocket } = useSocketStore();
const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState } = useSelectedComment(); const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState } = useSelectedComment();
const { commentStore } = useSceneContext(); const { threadStore } = useSceneContext();
const { comments, removeReply, addComment, addReply, updateComment, updateReply } = commentStore(); const { threads, removeReply, addComment, addReply, updateComment, updateReply } = threadStore();
const { userId } = getUserData(); const { userId } = getUserData();
useEffect(() => { useEffect(() => {
@@ -85,7 +85,7 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
// --- Create Thread Handler --- // --- Create Thread Handler ---
const handleCreateThread = (data: any) => { const handleCreateThread = (data: any) => {
const comment: CommentSchema = { const comment: ThreadSchema = {
state: "active", state: "active",
threadId: data.data?._id, threadId: data.data?._id,
creatorId: userId || data.data?.userId, creatorId: userId || data.data?.userId,
@@ -114,7 +114,7 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
threadSocket.on("v1-thread:response:delete", handleDeleteThread); threadSocket.on("v1-thread:response:delete", handleDeleteThread);
const handleEditThread = (data: any) => { const handleEditThread = (data: any) => {
const editedThread: CommentSchema = { const editedThread: ThreadSchema = {
state: "active", state: "active",
threadId: data.data?._id, threadId: data.data?._id,
creatorId: userId, creatorId: userId,
@@ -142,21 +142,7 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
threadSocket.off("v1-thread:response:delete", handleDeleteThread); threadSocket.off("v1-thread:response:delete", handleDeleteThread);
threadSocket.off("v1-thread:response:updateTitle", handleEditThread); threadSocket.off("v1-thread:response:updateTitle", handleEditThread);
}; };
}, [ }, [threadSocket, selectedComment, commentPositionState, userId, setSelectedComment, setCommentPositionState, threads, modeRef.current, messages]);
threadSocket,
selectedComment,
commentPositionState,
userId,
setMessages,
addReply,
addComment,
setSelectedComment,
setCommentPositionState,
updateComment,
comments,
modeRef.current,
messages,
]);
return null; return null;
}; };

View File

@@ -1,13 +1,14 @@
import { Html, TransformControls } from "@react-three/drei";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
import CommentThreads from "../../../../../components/ui/collaboration/threads/CommentThreads";
import { useSelectedComment } from "../../../../../store/builder/store";
import { Group, Object3D, Vector3 } from "three";
import { useThree } from "@react-three/fiber"; import { useThree } from "@react-three/fiber";
import { Html, TransformControls } from "@react-three/drei";
import { Group, Object3D, Vector3 } from "three";
import { usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
import { useSelectedComment } from "../../../../../store/builder/store";
import CommentThreads from "../../../../../components/ui/collaboration/threads/CommentThreads";
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
function ThreadInstance({ comment }: { readonly comment: CommentSchema }) { function ThreadInstance({ thread }: { readonly thread: ThreadSchema }) {
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const CommentRef = useRef(null); const CommentRef = useRef(null);
const [selectedObject, setSelectedObject] = useState<Object3D | null>(null); const [selectedObject, setSelectedObject] = useState<Object3D | null>(null);
@@ -33,8 +34,8 @@ function ThreadInstance({ comment }: { readonly comment: CommentSchema }) {
// }, [selectedComment]); // }, [selectedComment]);
const commentClicked = () => { const commentClicked = () => {
setSelectedComment(comment); setSelectedComment(thread);
const position = new Vector3(comment.position[0], comment.position[1], comment.position[2]); const position = new Vector3(thread.position[0], thread.position[1], thread.position[2]);
position.project(camera); position.project(camera);
const x = (position.x * 0.5 + 0.5) * size.width; const x = (position.x * 0.5 + 0.5) * size.width;
@@ -47,15 +48,16 @@ function ThreadInstance({ comment }: { readonly comment: CommentSchema }) {
}; };
useEffect(() => { useEffect(() => {
if (!selectedComment || selectedComment.threadId !== comment.threadId) { if (!selectedComment || selectedComment.threadId !== thread.threadId) {
setSelectedObject(null); setSelectedObject(null);
} }
}, [selectedComment]); }, [selectedComment]);
if (comment.state === "inactive" || isPlaying) return null; if (thread.state === "inactive" || isPlaying) return null;
return ( return (
<> <>
<group ref={groupRef} position={comment.position} rotation={comment.rotation}> <group ref={groupRef} position={thread.position} rotation={thread.rotation}>
<Html <Html
ref={CommentRef} ref={CommentRef}
zIndexRange={[1, 0]} zIndexRange={[1, 0]}
@@ -66,7 +68,7 @@ function ThreadInstance({ comment }: { readonly comment: CommentSchema }) {
// rotation={comment.rotation} // rotation={comment.rotation}
className="comments-main-wrapper" className="comments-main-wrapper"
> >
<CommentThreads commentClicked={commentClicked} comment={comment} /> <CommentThreads commentClicked={commentClicked} thread={thread} />
</Html> </Html>
</group> </group>
{/* {selectedObject && transformMode && ( {/* {selectedObject && transformMode && (

View File

@@ -1,21 +1,21 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import CommentInstance from "./commentInstance/commentInstance"; import ThreadInstance from "./threadInstance/threadInstance";
import { getAllThreads } from "../../../../services/factoryBuilder/comments/getAllThreads"; import { getAllThreads } from "../../../../services/factoryBuilder/collab/comments/getAllThreads";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { getUserData } from "../../../../functions/getUserData"; import { getUserData } from "../../../../functions/getUserData";
import { getRelativeTime } from "../../../../components/ui/collaboration/function/getRelativeTime"; import { getRelativeTime } from "../../../../components/ui/collaboration/function/getRelativeTime";
import { useSceneContext } from "../../../scene/sceneContext"; import { useSceneContext } from "../../../scene/sceneContext";
function CommentInstances() { function ThreadInstances() {
const { projectId } = useParams(); const { projectId } = useParams();
const { userId } = getUserData(); const { userId } = getUserData();
const { versionStore, commentStore } = useSceneContext(); const { versionStore, threadStore } = useSceneContext();
const { comments, setComments } = commentStore(); const { threads, setComments } = threadStore();
const { selectedVersion } = versionStore(); const { selectedVersion } = versionStore();
useEffect(() => { useEffect(() => {
// console.log("comments", comments); // console.log("threads", threads);
}, [comments]); }, [threads]);
useEffect(() => { useEffect(() => {
if (!projectId || !selectedVersion) return; if (!projectId || !selectedVersion) return;
@@ -45,13 +45,13 @@ function CommentInstances() {
return ( return (
<> <>
{comments?.map((comment: CommentSchema) => ( {threads?.map((thread: ThreadSchema) => (
<React.Fragment key={comment.threadId}> <React.Fragment key={thread.threadId}>
<CommentInstance comment={comment} /> <ThreadInstance thread={thread} />
</React.Fragment> </React.Fragment>
))} ))}
</> </>
); );
} }
export default CommentInstances; export default ThreadInstances;

View File

@@ -1,11 +1,11 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useThree } from "@react-three/fiber"; import { useThree } from "@react-three/fiber";
import { Vector3 } from "three"; import { Vector3 } from "three";
import CommentInstances from "./instances/commentInstances"; import ThreadInstances from "./threadInstances/threadInstances";
import { Sphere } from "@react-three/drei"; import { Sphere } from "@react-three/drei";
import { useActiveTool, useSelectedComment } from "../../../store/builder/store"; import { useActiveTool, useSelectedComment } from "../../../store/builder/store";
function CommentsGroup() { function ThreadsGroup() {
const { gl, raycaster, camera, scene, pointer, size } = useThree(); const { gl, raycaster, camera, scene, pointer, size } = useThree();
const { activeTool } = useActiveTool(); const { activeTool } = useActiveTool();
const [hoverPos, setHoverPos] = useState<Vector3 | null>(null); const [hoverPos, setHoverPos] = useState<Vector3 | null>(null);
@@ -112,7 +112,7 @@ function CommentsGroup() {
return ( return (
<> <>
<CommentInstances /> <ThreadInstances />
{hoverPos && ( {hoverPos && (
<Sphere name={"commentHolder"} args={[0.1, 16, 16]} position={hoverPos}> <Sphere name={"commentHolder"} args={[0.1, 16, 16]} position={hoverPos}>
<meshStandardMaterial color="orange" /> <meshStandardMaterial color="orange" />
@@ -122,4 +122,4 @@ function CommentsGroup() {
); );
} }
export default CommentsGroup; export default ThreadsGroup;

View File

@@ -24,7 +24,7 @@ import { createStorageUnitStore, StorageUnitStoreType } from "../../store/simula
import { createHumanStore, HumanStoreType } from "../../store/simulation/useHumanStore"; import { createHumanStore, HumanStoreType } from "../../store/simulation/useHumanStore";
import { createCraneStore, CraneStoreType } from "../../store/simulation/useCraneStore"; import { createCraneStore, CraneStoreType } from "../../store/simulation/useCraneStore";
import { createCommentsStore, CommentStoreType } from "../../store/collaboration/useCommentStore"; import { createThreadsStore, ThreadStoreType } from "../../store/collaboration/useCommentStore";
type SceneContextValue = { type SceneContextValue = {
versionStore: VersionStoreType; versionStore: VersionStoreType;
@@ -51,7 +51,7 @@ type SceneContextValue = {
humanStore: HumanStoreType; humanStore: HumanStoreType;
craneStore: CraneStoreType; craneStore: CraneStoreType;
commentStore: CommentStoreType; threadStore: ThreadStoreType;
humanEventManagerRef: React.RefObject<HumanEventManagerState>; humanEventManagerRef: React.RefObject<HumanEventManagerState>;
craneEventManagerRef: React.RefObject<CraneEventManagerState>; craneEventManagerRef: React.RefObject<CraneEventManagerState>;
@@ -88,7 +88,7 @@ export function SceneProvider({ children, layout }: { readonly children: React.R
const humanStore = useMemo(() => createHumanStore(), []); const humanStore = useMemo(() => createHumanStore(), []);
const craneStore = useMemo(() => createCraneStore(), []); const craneStore = useMemo(() => createCraneStore(), []);
const commentStore = useMemo(() => createCommentsStore(), []); const threadStore = useMemo(() => createThreadsStore(), []);
const humanEventManagerRef = useRef<HumanEventManagerState>({ humanStates: [] }); const humanEventManagerRef = useRef<HumanEventManagerState>({ humanStates: [] });
const craneEventManagerRef = useRef<CraneEventManagerState>({ craneStates: [] }); const craneEventManagerRef = useRef<CraneEventManagerState>({ craneStates: [] });
@@ -114,7 +114,7 @@ export function SceneProvider({ children, layout }: { readonly children: React.R
storageUnitStore.getState().clearStorageUnits(); storageUnitStore.getState().clearStorageUnits();
humanStore.getState().clearHumans(); humanStore.getState().clearHumans();
craneStore.getState().clearCranes(); craneStore.getState().clearCranes();
commentStore.getState().clearComments(); threadStore.getState().clearComments();
humanEventManagerRef.current.humanStates = []; humanEventManagerRef.current.humanStates = [];
craneEventManagerRef.current.craneStates = []; craneEventManagerRef.current.craneStates = [];
}, },
@@ -138,7 +138,7 @@ export function SceneProvider({ children, layout }: { readonly children: React.R
storageUnitStore, storageUnitStore,
humanStore, humanStore,
craneStore, craneStore,
commentStore, threadStore,
] ]
); );
@@ -163,7 +163,7 @@ export function SceneProvider({ children, layout }: { readonly children: React.R
storageUnitStore, storageUnitStore,
humanStore, humanStore,
craneStore, craneStore,
commentStore, threadStore,
humanEventManagerRef, humanEventManagerRef,
craneEventManagerRef, craneEventManagerRef,
clearStores, clearStores,
@@ -189,7 +189,7 @@ export function SceneProvider({ children, layout }: { readonly children: React.R
storageUnitStore, storageUnitStore,
humanStore, humanStore,
craneStore, craneStore,
commentStore, threadStore,
clearStores, clearStores,
layout, layout,
] ]

View File

@@ -1,12 +1,12 @@
import { create } from "zustand"; import { create } from "zustand";
import { immer } from "zustand/middleware/immer"; import { immer } from "zustand/middleware/immer";
interface CommentStore { interface ThreadStore {
comments: CommentsSchema; threads: ThreadsSchema;
addComment: (comment: CommentSchema) => void; addComment: (thread: ThreadSchema) => void;
setComments: (comments: CommentsSchema) => void; setComments: (threads: ThreadsSchema) => void;
updateComment: (threadId: string, updates: Partial<CommentSchema>) => void; updateComment: (threadId: string, updates: Partial<ThreadSchema>) => void;
removeComment: (threadId: string) => void; removeComment: (threadId: string) => void;
clearComments: () => void; clearComments: () => void;
@@ -14,65 +14,65 @@ interface CommentStore {
updateReply: (threadId: string, replyId: string, updates: Partial<Reply>) => void; updateReply: (threadId: string, replyId: string, updates: Partial<Reply>) => void;
removeReply: (threadId: string, _id: string) => void; removeReply: (threadId: string, _id: string) => void;
getCommentById: (threadId: string) => CommentSchema | undefined; getCommentById: (threadId: string) => ThreadSchema | undefined;
} }
export const createCommentsStore = () => { export const createThreadsStore = () => {
return create<CommentStore>()( return create<ThreadStore>()(
immer((set, get) => ({ immer((set, get) => ({
comments: [], threads: [],
addComment: (comment) => { addComment: (thread) => {
set((state) => { set((state) => {
if (!state.comments.find((c) => c.threadId === comment.threadId)) { if (!state.threads.find((c) => c.threadId === thread.threadId)) {
state.comments.push(JSON.parse(JSON.stringify(comment))); state.threads.push(JSON.parse(JSON.stringify(thread)));
} }
}); });
}, },
setComments: (comments) => { setComments: (threads) => {
set((state) => { set((state) => {
state.comments = comments; state.threads = threads;
}); });
}, },
updateComment: (threadId, updates) => { updateComment: (threadId, updates) => {
set((state) => { set((state) => {
const comment = state.comments.find((c) => c.threadId === threadId); const thread = state.threads.find((c) => c.threadId === threadId);
if (comment) { if (thread) {
Object.assign(comment, updates); Object.assign(thread, updates);
} }
}); });
}, },
removeComment: (threadId) => { removeComment: (threadId) => {
set((state) => { set((state) => {
state.comments = state.comments.filter((c) => c.threadId !== threadId); state.threads = state.threads.filter((c) => c.threadId !== threadId);
}); });
}, },
clearComments: () => { clearComments: () => {
set((state) => { set((state) => {
state.comments = []; state.threads = [];
}); });
}, },
addReply: (threadId, comment) => { addReply: (threadId, thread) => {
set((state) => { set((state) => {
const reply = state.comments.find((c) => c.threadId === threadId); const reply = state.threads.find((c) => c.threadId === threadId);
if (reply) { if (reply) {
reply.comments.push(comment); reply.comments.push(thread);
} }
}); });
}, },
updateReply: (threadId, replyId, updates) => { updateReply: (threadId, replyId, updates) => {
set((state) => { set((state) => {
const reply = state.comments.find((c) => c.threadId === threadId); const reply = state.threads.find((c) => c.threadId === threadId);
if (reply) { if (reply) {
const comment = reply.comments.find((r) => r.replyId === replyId); const thread = reply.comments.find((r) => r.replyId === replyId);
if (comment) { if (thread) {
Object.assign(comment, updates); Object.assign(thread, updates);
} }
} }
}); });
@@ -80,18 +80,18 @@ export const createCommentsStore = () => {
removeReply: (threadId, _id) => { removeReply: (threadId, _id) => {
set((state) => { set((state) => {
const comment = state.comments.find((c) => c.threadId === threadId); const thread = state.threads.find((c) => c.threadId === threadId);
if (comment) { if (thread) {
comment.comments = comment.comments.filter((r) => r.replyId !== _id); thread.comments = thread.comments.filter((r) => r.replyId !== _id);
} }
}); });
}, },
getCommentById: (threadId) => { getCommentById: (threadId) => {
return get().comments.find((c) => c.threadId === threadId); return get().threads.find((c) => c.threadId === threadId);
}, },
})) }))
); );
}; };
export type CommentStoreType = ReturnType<typeof createCommentsStore>; export type ThreadStoreType = ReturnType<typeof createThreadsStore>;

View File

@@ -1,4 +1,4 @@
interface CommentSchema { interface ThreadSchema {
state: "active" | "inactive"; state: "active" | "inactive";
threadId: string; threadId: string;
creatorId: string; creatorId: string;
@@ -18,4 +18,4 @@ interface Reply {
comment: string; comment: string;
} }
type CommentsSchema = CommentSchema[]; type ThreadsSchema = ThreadSchema[];