Skip to content

Commit fa22d45

Browse files
committed
implement comment handlers
1 parent e781efc commit fa22d45

File tree

2 files changed

+114
-34
lines changed

2 files changed

+114
-34
lines changed

packages/app/src/components/CommentsCard/index.jsx

Lines changed: 100 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,127 @@ import moment from "moment"
55
import { Icons } from "components/Icons"
66
import { CommentCreator } from "components"
77

8+
import PostModel from "models/post"
9+
810
import "./index.less"
911

12+
const CommentCard = (props) => {
13+
const { data, onClickDelete } = props
14+
15+
const handleClickDelete = () => {
16+
if (typeof onClickDelete !== "function") {
17+
console.warn("onClickDelete is not a function")
18+
return
19+
}
20+
21+
return onClickDelete(data._id)
22+
}
23+
24+
return <div className="comment" id={data._id}>
25+
<div className="header">
26+
<div className="avatar">
27+
<antd.Avatar src={data.user.avatar} />
28+
</div>
29+
<div className="username">
30+
{data.user.username}
31+
</div>
32+
<div className="timeAgo">
33+
{moment(data.created_at).fromNow()}
34+
</div>
35+
<antd.Button
36+
className="deleteBtn"
37+
type="link"
38+
icon={<Icons.Trash />}
39+
onClick={handleClickDelete}
40+
/>
41+
</div>
42+
<div className="content">
43+
{data.message}
44+
</div>
45+
</div>
46+
}
47+
1048
export default (props) => {
11-
const [postData, setPostData] = React.useState(null)
1249
const [comments, setComments] = React.useState(null)
1350

1451
const fetchData = async () => {
15-
setPostData(null)
1652
setComments(null)
1753

18-
// fetch post data
19-
const postDataResult = await window.app.api.request("main", "get", `post`, undefined, {
20-
post_id: props.post_id
54+
// fetch comments
55+
const commentsResult = await window.app.api.customRequest("main", {
56+
method: "get",
57+
url: `/post/${props.post_id}/comments`,
2158
}).catch((err) => {
2259
console.log(err)
2360

24-
antd.message.error("Failed to fetch post data")
61+
antd.message.error("Failed to fetch comments")
2562

2663
return null
2764
})
2865

29-
if (!postDataResult) return
66+
if (!commentsResult) return
3067

31-
setPostData(postDataResult)
68+
setComments(commentsResult.data)
69+
}
3270

33-
// fetch comments
34-
const commentsResult = await window.app.api.customRequest("main", {
35-
method: "get",
36-
url: `/post/${props.post_id}/comments`,
71+
const handleCommentSubmit = async (comment) => {
72+
const result = await PostModel.sendComment({
73+
post_id: props.post_id,
74+
comment
3775
}).catch((err) => {
3876
console.log(err)
3977

40-
antd.message.error("Failed to fetch comments")
78+
antd.message.error("Failed to send comment")
4179

4280
return null
4381
})
4482

45-
console.log(commentsResult)
83+
if (!result) return
84+
}
4685

47-
if (!commentsResult) return
86+
const handleCommentDelete = async (comment_id) => {
87+
antd.Modal.confirm({
88+
title: "Are you sure you want to delete this comment?",
89+
onOk: async () => {
90+
const result = await PostModel.deleteComment({
91+
post_id: props.post_id,
92+
comment_id: comment_id
93+
}).catch((err) => {
94+
console.log(err)
95+
96+
antd.message.error("Failed to delete comment")
97+
})
98+
99+
if (!result) return
100+
},
101+
})
102+
}
48103

49-
setComments(commentsResult.data)
104+
const listenEvents = () => {
105+
window.app.api.namespaces["main"].listenEvent(`post.new.comment.${props.post_id}`, (comment) => {
106+
setComments((comments) => {
107+
return [comment, ...comments]
108+
})
109+
})
110+
window.app.api.namespaces["main"].listenEvent(`post.delete.comment.${props.post_id}`, (comment_id) => {
111+
setComments((comments) => {
112+
return comments.filter((comment) => comment._id !== comment_id)
113+
})
114+
})
115+
}
116+
117+
const unlistenEvents = () => {
118+
window.app.api.namespaces["main"].unlistenEvent(`post.new.comment.${props.post_id}`)
119+
window.app.api.namespaces["main"].unlistenEvent(`post.delete.comment.${props.post_id}`)
50120
}
51121

52122
React.useEffect(() => {
53123
fetchData()
124+
listenEvents()
125+
126+
return () => {
127+
unlistenEvents()
128+
}
54129
}, [])
55130

56131
const renderComments = () => {
@@ -63,22 +138,10 @@ export default (props) => {
63138
}
64139

65140
return comments.map((comment) => {
66-
return <div className="comment" id={comment._id}>
67-
<div className="header">
68-
<div className="avatar">
69-
<antd.Avatar src={comment.user.avatar} />
70-
</div>
71-
<div className="username">
72-
{comment.user.username}
73-
</div>
74-
<div className="timeAgo">
75-
{moment(comment.createdAt).fromNow()}
76-
</div>
77-
</div>
78-
<div className="content">
79-
{comment.message}
80-
</div>
81-
</div>
141+
return <CommentCard
142+
data={comment}
143+
onClickDelete={handleCommentDelete}
144+
/>
82145
})
83146
}
84147

@@ -89,12 +152,15 @@ export default (props) => {
89152
return <div className="comments">
90153
<div className="header">
91154
<h1>
92-
<Icons.MessageSquare /> Comments
155+
<Icons.MessageSquare /> Comments
93156
</h1>
94157
</div>
95158
{renderComments()}
96159
<div className="commentCreatorWrapper">
97-
<CommentCreator />
160+
<CommentCreator
161+
onSubmit={handleCommentSubmit}
162+
maxLength={PostModel.maxCommentLength}
163+
/>
98164
</div>
99165
</div>
100166
}

packages/app/src/components/CommentsCard/index.less

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
}
3131

3232
.comment {
33+
position: relative;
3334
display: flex;
3435
flex-direction: column;
3536

@@ -73,6 +74,19 @@
7374
color: var(--text-color);
7475
margin-left: 20px;
7576
}
77+
78+
.deleteBtn {
79+
position: absolute;
80+
81+
top: 0;
82+
right: 0;
83+
84+
margin: 10px;
85+
86+
svg {
87+
font-size: 0.8rem;
88+
}
89+
}
7690
}
7791

7892
.commentCreatorWrapper {

0 commit comments

Comments
 (0)