diff --git a/app/src/components/ui/collaboration/CommentThreads.tsx b/app/src/components/ui/collaboration/CommentThreads.tsx index 0ce9fad..c06248c 100644 --- a/app/src/components/ui/collaboration/CommentThreads.tsx +++ b/app/src/components/ui/collaboration/CommentThreads.tsx @@ -1,13 +1,21 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor"; +import { getUserData } from "../../../functions/getUserData"; +import { getAllThreads } from "../../../services/factoryBuilder/comments/getAllThreads"; +import { useParams } from "react-router-dom"; +import { useCommentStore } from "../../../store/collaboration/useCommentStore"; +import { getRelativeTime } from "./function/getRelativeTime"; +import { useSelectedComment } from "../../../store/builder/store"; interface CommentThreadsProps { commentClicked: () => void; + comment?: CommentSchema } -const CommentThreads: React.FC = ({ commentClicked }) => { +const CommentThreads: React.FC = ({ commentClicked, comment }) => { const [expand, setExpand] = useState(false); const commentsedUsers = [{ creatorId: "1" }]; + const { userName } = getUserData(); const CommentDetails = { state: "active", @@ -16,26 +24,26 @@ const CommentThreads: React.FC = ({ commentClicked }) => { createdAt: "2 hours ago", comment: "Thread check", lastUpdatedAt: "string", - replies: [ + comments: [ { replyId: "string", creatorId: "string", createdAt: "string", lastUpdatedAt: "string", - reply: "string", + comment: "string", }, { replyId: "string", creatorId: "string", createdAt: "string", lastUpdatedAt: "string", - reply: "string", + comment: "string", }, ], }; function getUsername(userId: string) { - const UserName = "username"; + const UserName = userName?.charAt(0).toUpperCase() || "user"; return UserName; } @@ -48,15 +56,15 @@ const CommentThreads: React.FC = ({ commentClicked }) => { } } + return (
- {getUsername(CommentDetails.creatorId)} + {userName} + {/* {getUsername(CommentDetails.creatorId)} */}
-
{CommentDetails.createdAt}
+
{comment?.createdAt && getRelativeTime(comment.createdAt)}
-
{CommentDetails.comment}
- {CommentDetails.replies.length > 0 && ( -
- {CommentDetails.replies.length}{" "} - {CommentDetails.replies.length === 1 ? "reply" : "replies"} +
{comment?.threadTitle}
+ {comment && comment?.comments.length > 0 && ( +
+ {comment && comment?.comments.length}{" "} + {comment && comment?.comments.length === 1 ? "comment" : "replies"}
)}
+ ); }; diff --git a/app/src/components/ui/collaboration/Messages.tsx b/app/src/components/ui/collaboration/Messages.tsx index 0544b1c..86c3d69 100644 --- a/app/src/components/ui/collaboration/Messages.tsx +++ b/app/src/components/ui/collaboration/Messages.tsx @@ -2,44 +2,181 @@ import React, { useEffect, useRef, useState } from "react"; import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor"; import { KebabIcon } from "../../icons/ExportCommonIcons"; import { adjustHeight } from "./function/textAreaHeightAdjust"; +import { getUserData } from "../../../functions/getUserData"; +import { useParams } from "react-router-dom"; +import { deleteCommentApi } from "../../../services/factoryBuilder/comments/deleteCommentApi"; +import { addCommentsApi } from "../../../services/factoryBuilder/comments/addCommentsApi"; +import { useCommentStore } from "../../../store/collaboration/useCommentStore"; +import { useSelectedComment, useSocketStore } from "../../../store/builder/store"; +import { getRelativeTime } from "./function/getRelativeTime"; +import { editThreadTitleApi } from "../../../services/factoryBuilder/comments/editThreadTitleApi"; + interface MessageProps { val: Reply | CommentSchema; + // val: Reply | CommentSchema; i: number; + setMessages?: React.Dispatch> + setIsEditable?: React.Dispatch> + setEditedThread?: React.Dispatch> + setMode?: React.Dispatch> + isEditable?: boolean; + isEditableThread?: boolean + editedThread?: boolean; + mode?: 'create' | 'edit' | null } -const Messages: React.FC = ({ val, i }) => { - const [isEditing, setIsEditing] = useState(false); +const Messages: React.FC = ({ val, i, setMessages, mode, setIsEditable, setEditedThread, editedThread, isEditableThread, setMode }) => { + + const { comments, updateComment, updateReply, removeReply } = useCommentStore(); const [openOptions, setOpenOptions] = useState(false); + const { projectId } = useParams(); + const { threadSocket } = useSocketStore(); + const { userName, userId, organization } = getUserData(); + const [isEditComment, setIsEditComment] = useState(false) + + const { selectedComment, setCommentPositionState } = useSelectedComment(); // input const [value, setValue] = useState( - "reply" in val ? val.reply : val.comment + "comment" in val ? val.comment : val.threadTitle ); + const textareaRef = useRef(null); const currentUser = "1"; - const UserName = "username"; + // const UserName = "username"; useEffect(() => { if (textareaRef.current) adjustHeight(textareaRef.current); }, [value]); function handleCancelAction() { - setIsEditing(false); + setCommentPositionState(null) + setIsEditable && setIsEditable(true); + setIsEditComment(false) } - function handleSaveAction() { - setIsEditing(false); + const handleSaveAction = async () => { + + if (!projectId) return + + if (isEditableThread && editedThread) { + try { + // const editThreadTitle = await editThreadTitleApi(projectId, (val as CommentSchema).threadId, value) + // if (editThreadTitle.message == "ThreadTitle updated Successfully") { + // const editedThread: CommentSchema = { + // state: 'active', + // threadId: editThreadTitle.data.replyId, + // creatorId: userId, + // createdAt: getRelativeTime(editThreadTitle.data.createdAt), + // threadTitle: value, + // lastUpdatedAt: new Date().toISOString(), + // position: editThreadTitle.data.position, + // rotation: [0, 0, 0], + // comments: [] + // } + // updateComment((val as CommentSchema).threadId, editedThread) + // } + // projectId, userId, threadTitle, organization, threadId + const threadEdit = { + projectId, + userId, + threadTitle: value, + organization, + threadId: (val as CommentSchema).threadId + } + + threadSocket.emit('v1:thread:updateTitle', threadEdit) + } catch { + } + } else { + + if (mode === "edit") { + try { + // const editComments = await addCommentsApi(projectId, value, selectedComment?.threadId, (val as Reply).replyId) + // + // const commentData = { + // replyId: `${editComments.data?.replyId}`, + // creatorId: `${userId}`, + // createdAt: getRelativeTime(editComments.data?.createdAt), + // lastUpdatedAt: "2 hrs ago", + // comment: value, + // } + + // updateReply((val as CommentSchema).threadId, (val as Reply)?.replyId, commentData); + + if (threadSocket) { + // projectId, userId, comment, organization, threadId + const editComment = { + projectId, + userId, + comment: value, + organization, + threadId: selectedComment?.threadId, + commentId: (val as Reply).replyId ?? "" + } + + + threadSocket.emit("v1-Comment:add", editComment); + setIsEditable && setIsEditable(true); + setEditedThread && setEditedThread(false) + } + + } catch { + } + } + + } + // setValue(""); + setIsEditComment(false); } - function handleDeleteAction() { + const handleDeleteAction = async (replyID: any) => { + if (!projectId) return setOpenOptions(false); + try { + // const deletedComment = await deleteCommentApi(projectId, selectedComment?.threadId, (val as Reply).replyId) + // + // if (deletedComment === "'Thread comment deleted Successfully'") { + // setMessages && setMessages(prev => prev.filter(message => message.replyId !== replyID)); + // removeReply(val.creatorId, replyID) + // } + if (threadSocket && setMessages) { + + + // projectId, userId, commentId, organization, threadId + const deleteComment = { + projectId, + userId, + commentId: (val as Reply).replyId, + organization, + threadId: selectedComment?.threadId + } + + + setMessages(prev => prev.filter(message => message.replyId !== (val as Reply).replyId)) + + removeReply(selectedComment?.threadId, (val as Reply).replyId); // Remove listener after response + threadSocket.emit("v1-Comment:delete", deleteComment); + } + } catch { + + } } + const handleFocus = (e: React.FocusEvent) => { + requestAnimationFrame(() => { + if (textareaRef.current) { + const length = textareaRef.current.value.length; + textareaRef.current.setSelectionRange(length, length); + } + }); + }; + return ( <> - {isEditing ? ( + {isEditComment ? (