refactor: Simplify message and thread handling by removing unused props and improving state management

This commit is contained in:
2025-06-19 17:55:45 +05:30
parent 7da2137117
commit 1a0609d4db
8 changed files with 151 additions and 195 deletions

View File

@@ -17,17 +17,15 @@ interface MessageProps {
i: number;
setMessages?: React.Dispatch<React.SetStateAction<Reply[]>>
setIsEditable?: React.Dispatch<React.SetStateAction<boolean>>
setCreateComments?: React.Dispatch<React.SetStateAction<boolean>>
setEditedThread?: React.Dispatch<React.SetStateAction<boolean>>
setMode?: React.Dispatch<React.SetStateAction<'create' | 'edit' | null>>
isEditable?: boolean;
isEditableThread?: boolean
createComments?: boolean
editedThread?: boolean;
mode?: 'create' | 'edit' | null
}
const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEditable, setEditedThread, editedThread, isEditableThread, setCreateComments, setMode }) => {
const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEditable, setEditedThread, editedThread, isEditableThread, setMode }) => {
const { comments, updateComment, updateReply, removeReply } = useCommentStore();
const [openOptions, setOpenOptions] = useState(false);
@@ -68,7 +66,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
// if (editThreadTitle.message == "ThreadTitle updated Successfully") {
// const editedThread: CommentSchema = {
// state: 'active',
// threadId: editThreadTitle.data._id,
// threadId: editThreadTitle.data.replyId,
// creatorId: userId,
// createdAt: getRelativeTime(editThreadTitle.data.createdAt),
// threadTitle: value,
@@ -98,7 +96,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
// const editComments = await addCommentsApi(projectId, value, selectedComment?.threadId, (val as Reply).replyId)
//
// const commentData = {
// replyId: `${editComments.data?._id}`,
// replyId: `${editComments.data?.replyId}`,
// creatorId: `${userId}`,
// createdAt: getRelativeTime(editComments.data?.createdAt),
// lastUpdatedAt: "2 hrs ago",
@@ -115,14 +113,13 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
comment: value,
organization,
threadId: selectedComment?.threadId,
commentId: (val as Reply)._id ?? ""
commentId: (val as Reply).replyId ?? ""
}
threadSocket.emit("v1-Comment:add", editComment);
setIsEditable && setIsEditable(true);
setEditedThread && setEditedThread(false)
setCreateComments && setCreateComments(false)
}
} catch {
@@ -130,7 +127,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
}
}
setValue("");
// setValue("");
setIsEditComment(false);
}
@@ -138,7 +135,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
if (!projectId) return
setOpenOptions(false);
try {
// const deletedComment = await deleteCommentApi(projectId, selectedComment?.threadId, (val as Reply)._id)
// 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));
@@ -151,15 +148,15 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
const deleteComment = {
projectId,
userId,
commentId: (val as Reply)._id,
commentId: (val as Reply).replyId,
organization,
threadId: selectedComment?.threadId
}
setMessages(prev => prev.filter(message => message.replyId !== (val as Reply).replyId))
console.log('(val as Reply).replyId): ', (val as Reply).replyId);
removeReply(selectedComment?.threadId, (val as Reply).replyId || ((val as Reply)._id ?? "")) // Remove listener after response
removeReply(selectedComment?.threadId, (val as Reply).replyId); // Remove listener after response
threadSocket.emit("v1-Comment:delete", deleteComment);
}
} catch {
@@ -167,7 +164,6 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
}
}
return (
<>
{isEditComment ? (
@@ -215,9 +211,8 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
<div className="content">
<div className="user-details">
<div className="user-name">{userName}</div>
<div className="time">{getRelativeTime(val.createdAt)}</div>
<div className="time">{isEditableThread ? getRelativeTime(val.createdAt) : val.createdAt}</div>
</div>
{/* {(val as Reply).comment && ( */}
{(val as Reply).creatorId === userId && (
<div className="more-options">
<button
@@ -238,7 +233,6 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
setOpenOptions(false);
setEditedThread && setEditedThread(true);
setIsEditComment(true)
setCreateComments && setCreateComments(false)
}}
>
Edit
@@ -246,8 +240,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
{!(isEditableThread) && <button
className="option"
onClick={() => {
handleDeleteAction((val as Reply)._id);
// handleDeleteAction((val as Reply).replyId);
handleDeleteAction((val as Reply).replyId);
}}
>
Delete

View File

@@ -3,42 +3,27 @@ import { CloseIcon, KebabIcon } from "../../icons/ExportCommonIcons";
import Messages from "./Messages";
import { ExpandIcon } from "../../icons/SimulationIcons";
import { adjustHeight } from "./function/textAreaHeightAdjust";
import { Html } from "@react-three/drei";
import { addCommentsApi } from "../../../services/factoryBuilder/comments/addCommentsApi";
import { useParams } from "react-router-dom";
import { useCommentStore } from "../../../store/collaboration/useCommentStore";
import { useSelectedComment, useSocketStore } from "../../../store/builder/store";
import { useCommentStore } from "../../../store/collaboration/useCommentStore";
import { getUserData } from "../../../functions/getUserData";
import ThreadSocketResponsesDev from "../../../modules/collaboration/socket/threadSocketResponses.dev";
import { addCommentsApi } from "../../../services/factoryBuilder/comments/addCommentsApi";
import { deleteThreadApi } from "../../../services/factoryBuilder/comments/deleteThreadApi";
import { createThreadApi } from "../../../services/factoryBuilder/comments/createThreadApi";
import { getUserData } from "../../../functions/getUserData";
import { getRelativeTime } from "./function/getRelativeTime";
import { threadId } from "worker_threads";
import ThreadSocketResponsesDev from "../../../modules/collaboration/socket/threadSocketResponses.dev";
type MessageType = {
replyId: string,
creatorId: string,
createdAt: string,
lastUpdatedAt: string,
comment: string
}
interface ThreadChatProps {
selectedComment: CommentSchema
}
const ThreadChat: React.FC = () => {
// const ThreadChat: React.FC<ThreadChatProps> = (selectedComment) => {
const { userId, organization } = getUserData();
const [openThreadOptions, setOpenThreadOptions] = useState(false);
//
const [inputActive, setInputActive] = useState(false);
const [value, setValue] = useState<string>("");
const { addComment, removeReply, removeComment, addReply, comments } = useCommentStore();
const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState, position2Dstate } = useSelectedComment()
const [mode, setMode] = useState<'create' | 'edit' | null>(null);
const [mode, setMode] = useState<'create' | 'edit' | null>('create');
const [isEditable, setIsEditable] = useState(false);
const [editedThread, setEditedThread] = useState(false);
const [editedComment, setEditedComment] = useState(false);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const wrapperRef = useRef<HTMLDivElement>(null);
const [messages, setMessages] = useState<Reply[]>([])
@@ -47,7 +32,6 @@ const ThreadChat: React.FC = () => {
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
const [position, setPosition] = useState({ x: position2Dstate.x, y: position2Dstate.y });
const { threadSocket } = useSocketStore();
const [createComments, setCreateComments] = useState(true);
const modeRef = useRef<'create' | 'edit' | null>(null);
@@ -57,55 +41,28 @@ const ThreadChat: React.FC = () => {
useEffect(() => {
if (comments.length > 0 && selectedComment) {
console.log('comments: ', comments);
const allMessages = comments
.flatMap((val: any) =>
val?.threadId === selectedComment?.threadId ? val.comments : []
)
.map((c) => ({
replyId: c._id, // or generate a fallback ID if _id is missing
creatorId: c.userId,
createdAt: getRelativeTime(c.createdAt), // optional: format as ISO string
lastUpdatedAt: " 1 hr ago", // defaulting to createdAt
.map((c) => {
return {
replyId: c._id ?? "",
creatorId: c.creatorId || c.userId,
createdAt: c.createdAt,
lastUpdatedAt: "1 hr ago",
comment: c.comment,
_id: c._id ?? "",
}));
};
});
setMessages(allMessages);
console.log('allMessages: ', allMessages);
}
}, [selectedComment]);
// const messages = [
// {
// replyId: "user 1",
// creatorId: "1",
// createdAt: "2 hrs ago",
// lastUpdatedAt: "2 hrs ago",
// comment:
// "comment testing comment content 1, comment testing comment content 1reply testing comment content 1",
// },
// {
// replyId: "user 2",
// creatorId: "2",
// createdAt: "2 hrs ago",
// lastUpdatedAt: "2 hrs ago",
// comment: "comment 2",
// },
// {
// replyId: "user 3",
// creatorId: "2",
// createdAt: "2 hrs ago",
// lastUpdatedAt: "2 hrs ago",
// comment: "comment 2",
// },
// {
// replyId: "user 4",
// creatorId: "2",
// createdAt: "2 hrs ago",
// lastUpdatedAt: "2 hrs ago",
// comment: "comment 2",
// },
// ];
}, [selectedComment])
useEffect(() => {
if (textareaRef.current) adjustHeight(textareaRef.current);
@@ -274,8 +231,6 @@ const ThreadChat: React.FC = () => {
// setSelectedComment([])
// }
const createThread = {
projectId,
userId,
@@ -345,69 +300,56 @@ const ThreadChat: React.FC = () => {
</div>
</div>
{selectedComment && <div className="messages-wrapper">
<Messages val={selectedComment} i={1} key={selectedComment.creatorId} isEditableThread={true} setEditedThread={setEditedThread} editedThread={editedThread} />
</div>}
<div className="messages-wrapper">
{selectedComment &&
<Messages val={selectedComment} i={1} key={selectedComment.creatorId} isEditableThread={true} setEditedThread={setEditedThread} editedThread={editedThread} />
}
{messages && messages.map((val, i) => (
<Messages val={val as any} i={i} key={val._id} setMessages={setMessages} setIsEditable={setIsEditable} isEditable={isEditable} setCreateComments={setCreateComments} createComments={createComments} isEditableThread={false} setMode={setMode} mode={mode} />
<Messages val={val as any} i={i} key={val.replyId} setMessages={setMessages} setIsEditable={setIsEditable} isEditable={isEditable} isEditableThread={false} setMode={setMode} mode={mode} />
))}
</div>
{(commentPositionState && selectedComment === null) ? (< div className="send-message-wrapper">
<div className="send-message-wrapper">
<div className={`input-container ${inputActive ? "active" : ""}`}>
<textarea
placeholder="Type Thread Title"
placeholder={commentPositionState && selectedComment === null ? "Type Thread Title" : "type something"}
ref={textareaRef}
value={value}
onChange={(e) => setValue(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
handleCreateThread(e);
}
}}
onFocus={() => setInputActive(true)}
onBlur={() => setInputActive(false)}
style={{ resize: "none" }}
/>
<div className={`sent-button ${value === "" ? "disable-send-btn" : ""}`} onClick={(e) => handleCreateThread(e)}>
<ExpandIcon />
</div>
</div>
</div>) : (< div className="send-message-wrapper">
<div className={`input-container ${inputActive ? "active" : ""}`}>
<textarea
placeholder="type something"
ref={textareaRef}
value={value}
onChange={(e) => setValue(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
setCreateComments(true)
setEditedComment(false)
setMode("create")
handleCreateComments(e);
}
}}
onClick={(e) => {
e.preventDefault();
if (commentPositionState && selectedComment === null) {
handleCreateThread(e);
} else {
setMode("create");
handleCreateComments(e);
textareaRef.current?.blur();
}
}
}}
onFocus={() => setInputActive(true)}
onBlur={() => setInputActive(false)}
style={{ resize: "none" }}
/>
<div className={`sent-button ${value === "" ? "disable-send-btn" : ""}`} onClick={(e) => handleCreateComments(e)}>
<div
className={`sent-button ${value === "" ? "disable-send-btn" : ""}`}
onClick={(e) => {
if (commentPositionState && selectedComment === null) {
handleCreateThread(e);
} else {
setMode("create");
handleCreateComments(e);
}
}}
>
<ExpandIcon />
</div>
</div>
</div>)}
</div>
<ThreadSocketResponsesDev setMessages={setMessages} createComments={createComments} setCreateComments={setCreateComments} modeRef={modeRef} messages={messages} />
</div>
<ThreadSocketResponsesDev setMessages={setMessages} modeRef={modeRef} messages={messages} />
</div >
);
};

View File

@@ -61,7 +61,7 @@ function CommentInstance({ comment }: { comment: CommentSchema }) {
<CommentThreads commentClicked={commentClicked} comment={comment} />
</Html>
</group>
{selectedObject && transformMode && (
{/* {selectedObject && transformMode && (
<TransformControls
object={selectedObject}
mode={transformMode}
@@ -70,7 +70,7 @@ function CommentInstance({ comment }: { comment: CommentSchema }) {
}}
/>
)}
)} */}
</>
)
}

View File

@@ -10,46 +10,46 @@ function CommentInstances() {
const { comments, setComments } = useCommentStore();
const { projectId } = useParams();
const { userId } = getUserData()
// const getThreads = async () => {
// if (!projectId) return;
// try {
// const getComments = await getAllThreads(projectId);
// console.log("API raw data:", getComments.data);
// const formattedThreads = Array.isArray(getComments.data)
// ? getComments.data.map((thread: any) => ({
// ...thread,
// comments: Array.isArray(thread.comments)
// ? thread.comments.map((val: any) => ({
// replyId: val._id ?? "",
// creatorId: userId,
// createdAt: getRelativeTime(val.createdAt),
// lastUpdatedAt: "1 hr ago",
// comment: val.comment,
// _id: val._id ?? "",
// }))
// : [],
// }))
// : [];
// console.log('formattedThreads: ', formattedThreads);
// setComments(formattedThreads);
// } catch (err) {
// console.error("Failed to fetch threads:", err);
// }
// }
const getThreads = async () => {
if (!projectId) return;
try {
const getComments = await getAllThreads(projectId);
console.log("API raw data:", getComments.data);
setComments(getComments.data);
const formattedThreads = Array.isArray(getComments.data)
? getComments.data.map((thread: any) => ({
...thread,
comments: Array.isArray(thread.comments)
? thread.comments.map((val: any) => ({
replyId: val._id ?? "",
creatorId: userId,
createdAt: getRelativeTime(val.createdAt),
lastUpdatedAt: "1 hr ago",
comment: val.comment,
_id: val._id ?? "",
}))
: [],
}))
: [];
console.log('formattedThreads: ', formattedThreads);
setComments(formattedThreads);
} catch (err) {
console.error("Failed to fetch threads:", err);
}
}
// const getThreads = async () => {
// if (!projectId) return;
// try {
// const getComments = await getAllThreads(projectId);
// console.log('getComments.data: ', getComments.data);
// setComments(getComments.data);
// } catch (err) {
// console.error("Failed to fetch threads:", err);
// }
// }
useEffect(() => {
getThreads();
}, []);

View File

@@ -6,14 +6,12 @@ import { getRelativeTime } from '../../../components/ui/collaboration/function/g
interface ThreadSocketProps {
setMessages: React.Dispatch<React.SetStateAction<Reply[]>>;
setCreateComments: React.Dispatch<React.SetStateAction<boolean>>;
createComments: boolean
// mode: 'create' | 'edit' | null
modeRef: React.RefObject<'create' | 'edit' | null>;
messages: Reply[]
}
const ThreadSocketResponsesDev = ({ setMessages, createComments, modeRef, setCreateComments, messages }: ThreadSocketProps) => {
const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSocketProps) => {
const { threadSocket } = useSocketStore();
const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState } = useSelectedComment();
const { comments, addComment, addReply, updateComment, updateReply } = useCommentStore();
@@ -24,8 +22,8 @@ const ThreadSocketResponsesDev = ({ setMessages, createComments, modeRef, setCre
// --- Add Comment Handler ---
// const handleAddComment = (data: any) => {
// console.log('Thread add response received:', data);
// console.log('Added ', data.data?._id);
//
//
// const commentData = {
// replyId: data.data?._id,
// creatorId: data.data?.userId,
@@ -33,31 +31,31 @@ const ThreadSocketResponsesDev = ({ setMessages, createComments, modeRef, setCre
// lastUpdatedAt: '2 hrs ago',
// comment: data.data.comment,
// };
// // console.log('createComments:res ', createComments);
// console.log('mode:socket ', mode);
// //
//
// if (mode == "create") {
// addReply(selectedComment?.threadId, commentData);
// console.log('commentData: ', commentData);
//
// setMessages(prevMessages => [...prevMessages, commentData]);
// } else if (mode == "edit") {
// updateReply(selectedComment?.threadId, data.data?._id, commentData);
// setMessages((prev) =>
// prev.map((message) => {
// console.log('message:fsadf', message, data.data?.comment, data.data?._id); // 👈 log each message
// // 👈 log each message
// return (message.replyId || message._id) === data.data?._id
// ? { ...message, comment: data.data?.comment }
// : message;
// })
// );
// console.log('data.data?._id: ', data.data?._id);
//
// } else {
// console.log("sfdajhgsak");
//
// }
// threadSocket.off('v1-Comment:response:add', handleAddComment);
// };
// threadSocket.on('v1-Comment:response:add', handleAddComment);
const handleAddComment = (data: any) => {
console.log("mode:socket (from ref):", modeRef.current);
console.log('Add: ', data);
const commentData = {
replyId: data.data?._id,
@@ -68,39 +66,42 @@ const ThreadSocketResponsesDev = ({ setMessages, createComments, modeRef, setCre
};
if (modeRef.current === "create") {
console.log("create");
console.log("Thread add response received:", data);
addReply(selectedComment?.threadId, commentData);
setMessages((prevMessages) => [...prevMessages, commentData]);
} else if (modeRef.current === "edit") {
// console.log("Thread edit response received:", data);
// console.log('selectedComment?.threadId, data.data?._id: ', selectedComment);
updateReply(selectedComment?.threadId, data.data?._id, commentData);
setMessages((prev) =>
prev.map((message) => {
console.log('message:fsadf', message._id, message.replyId, data.data?._id, (message.replyId || message._id) === data.data?._id); // 👈 log each message
// 👈 log each message
return message.replyId === data.data?._id
? { ...message, comment: data.data?.comment }
: message;
})
);
console.log('data.data?.comment: ', data.data?.comment);
} else {
console.log("Unknown mode in socket handler");
}
threadSocket.off("v1-Comment:response:add", handleAddComment);
};
threadSocket.on('v1-Comment:response:add', handleAddComment);
// --- Delete Comment Handler ---
const handleDeleteComment = (data: any) => {
console.log('Thread delete response received:', data);
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('Thread creation response received:', data);
console.log('createThread: ', data);
const comment: CommentSchema = {
state: 'active',
threadId: data.data?._id,
@@ -121,14 +122,14 @@ const ThreadSocketResponsesDev = ({ setMessages, createComments, modeRef, setCre
// --- Delete Thread Handler ---
const handleDeleteThread = (data: any) => {
console.log('Thread delete response received:', data);
threadSocket.off('v1-thread:response:delete', handleDeleteThread);
};
threadSocket.on('v1-thread:response:delete', handleDeleteThread);
const handleEditThread = (data: any) => {
console.log('Thread dfjghdi response received:', data);
const editedThread: CommentSchema = {
state: 'active',
threadId: data.data?._id,
@@ -140,13 +141,16 @@ const ThreadSocketResponsesDev = ({ setMessages, createComments, modeRef, setCre
rotation: [0, 0, 0],
comments: data.data.comments,
};
console.log('data.data.threadId: ', data.data._id);
console.log('data.data?._id: ', data.data?._id);
updateComment(data.data?._id, editedThread);
setSelectedComment(null);
setSelectedComment(editedThread)
// setSelectedComment(null);
};
threadSocket.on('v1-thread:response:updateTitle', handleEditThread);
console.log('messages: ', messages);
// Cleanup on unmount
return () => {
threadSocket.off('v1-Comment:response:add', handleAddComment);

View File

@@ -16,7 +16,6 @@ export const getAllThreads = async (projectId: string) => {
}
);
console.log('response: ', response);
if (!response.ok) {
throw new Error("Failed to get assets");
}

View File

@@ -14,7 +14,7 @@ interface CommentStore {
addReply: (threadId: string, reply: Reply) => void;
updateReply: (
threadId: string,
_id: string,
replyId: string,
updates: Partial<Reply>
) => void;
removeReply: (threadId: string, _id: string) => void;
@@ -43,6 +43,7 @@ export const useCommentStore = create<CommentStore>()(
},
updateComment: (threadId, updates) => {
console.log("threadId:updater ", threadId);
set((state) => {
const comment = state.comments.find((c) => c.threadId === threadId);
if (comment) {
@@ -67,11 +68,11 @@ export const useCommentStore = create<CommentStore>()(
});
},
updateReply: (threadId, _id, updates) => {
updateReply: (threadId, replyId, updates) => {
set((state) => {
const reply = state.comments.find((c) => c.threadId === threadId);
if (reply) {
const comment = reply.comments.find((r) => r._id === _id);
const comment = reply.comments.find((r) => r.replyId === replyId);
if (comment) {
Object.assign(comment, updates);
}
@@ -83,7 +84,7 @@ export const useCommentStore = create<CommentStore>()(
set((state) => {
const comment = state.comments.find((c) => c.threadId === threadId);
if (comment) {
comment.comments = comment.comments.filter((r) => r._id !== _id);
comment.comments = comment.comments.filter((r) => r.replyId !== _id);
}
});
},

View File

@@ -56,16 +56,23 @@
.message {
margin-top: 10px;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
text-align: start;
}
.replies {
.replies,
.comments {
margin-top: 4px;
font-size: var(--font-size-small);
color: var(--input-text-color);
}
.header,
.message,
.replies {
.replies,
.comments {
display: none;
opacity: 0;
}
@@ -84,9 +91,15 @@
.users-commented {
padding: 12px;
}
.message {
display: -webkit-box !important;
opacity: 1 !important;
margin-bottom: 4px;
padding: 0;
}
.header,
.message,
.replies {
.replies,
.comments {
display: flex !important;
opacity: 1 !important;
}
@@ -158,11 +171,13 @@
.messages-wrapper {
padding: 12px;
padding-top: 0;
max-height: 50vh;
overflow-y: auto;
.edit-container {
.input-container {
textarea{
textarea {
background: var(--background-color);
&:focus{
&:focus {
outline-color: var(--border-color-accent);
}
}
@@ -195,7 +210,7 @@
align-items: flex-start;
gap: 12px;
margin-top: 8px;
&:first-child{
&:first-child {
margin: 0;
}
.profile {
@@ -231,7 +246,7 @@
height: 18px;
width: 18px;
border-radius: #{$border-radius-small};
&:hover{
&:hover {
background: var(--background-color-solid);
}
}
@@ -249,14 +264,14 @@
border-radius: #{$border-radius-medium};
padding: 2px 6px;
text-align: start;
&:hover{
&:hover {
background: var(--background-color-accent);
color: var(--text-button-color);
}
}
}
}
.message{
.message {
margin-top: 6px;
}
}
@@ -284,7 +299,9 @@
bottom: 2px;
@include flex-center;
padding: 2px;
cursor: pointer;
svg {
pointer-events: none;
rotate: 45deg;
}
}