Skip to content

Commit fc2d1d6

Browse files
authored
Merge pull request #42 from techdiary-dev/comment
feat: add comment_id handling in comment actions and schemas for impr…
2 parents 2426348 + 0d6f12c commit fc2d1d6

File tree

5 files changed

+33
-40
lines changed

5 files changed

+33
-40
lines changed

src/backend/persistence/schemas.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,6 @@ export const commentsTable = pgTable("comments", {
148148
user_id: uuid("user_id")
149149
.notNull()
150150
.references(() => usersTable.id, { onDelete: "cascade" }),
151-
parent_id: uuid("parent_id").references((): AnyPgColumn => commentsTable.id, {
152-
onDelete: "cascade",
153-
}),
154151
created_at: timestamp("created_at").defaultNow(),
155152
updated_at: timestamp("updated_at").defaultNow(),
156153
});

src/backend/services/comment.action.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export const createMyComment = async (
6464

6565
const created = await persistenceRepository.comment.insert([
6666
{
67+
id: input.comment_id ?? crypto.randomUUID(),
6768
body,
6869
resource_id,
6970
resource_type,

src/backend/services/inputs/comment.input.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const CommentActionInput = {
66
resource_type: z.enum(["ARTICLE", "COMMENT"]),
77
}),
88
create: z.object({
9+
comment_id: z.string().uuid().optional().nullable(),
910
resource_id: z.string().uuid(),
1011
resource_type: z.enum(["ARTICLE", "COMMENT"]),
1112
body: z.string().min(1).max(5000),

src/components/ResourceReaction.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const ResourceReaction = ({
2727
<button
2828
key={reaction.reaction_type}
2929
onClick={() => toggle(reaction.reaction_type!)}
30-
className={`p-1 flex items-center gap-1 cursor-pointer rounded-sm hover:bg-primary/20 ${
30+
className={`p-1 w-10 h-6 flex items-center gap-1 cursor-pointer rounded-sm hover:bg-primary/20 ${
3131
reaction.is_reacted ? "bg-primary/20" : ""
3232
}`}
3333
>
@@ -40,11 +40,14 @@ const ResourceReaction = ({
4040
</button>
4141
))}
4242
<HoverCard openDelay={0}>
43-
<HoverCardTrigger asChild>
44-
<button className="p-1 border flex-none flex items-center gap-1 cursor-pointer rounded-sm hover:bg-primary/20">
45-
<FaceIcon />
46-
</button>
47-
</HoverCardTrigger>
43+
{reactions.length !== reactions.filter((r) => r.count).length && (
44+
<HoverCardTrigger asChild>
45+
<button className="p-1 border w-10 h-6 flex-none grid place-content-center cursor-pointer rounded-sm hover:bg-primary/20">
46+
<FaceIcon />
47+
</button>
48+
</HoverCardTrigger>
49+
)}
50+
4851
<HoverCardContent>
4952
<div className="flex items-center gap-2 flex-wrap">
5053
{reactions.map((reaction) => (

src/components/comment-section.tsx

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ import { useTranslation } from "@/i18n/use-translation";
66
import { formattedTime } from "@/lib/utils";
77
import { useSession } from "@/store/session.atom";
88
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
9-
import clsx from "clsx";
109
import { ChevronDown, ChevronUp, MessageSquare } from "lucide-react";
1110
import React, { useMemo, useState } from "react";
1211
import { useImmer } from "use-immer";
1312
import { useLoginPopup } from "./app-login-popup";
14-
import { ResourceReactionable } from "./render-props/ResourceReactionable";
15-
import { Textarea } from "./ui/textarea";
1613
import ResourceReaction from "./ResourceReaction";
14+
import { Textarea } from "./ui/textarea";
1715

1816
export const CommentSection = (props: {
1917
resource_id: string;
@@ -24,13 +22,14 @@ export const CommentSection = (props: {
2422
const appLoginPopup = useLoginPopup();
2523
const session = useSession();
2624
const mutation = useMutation({
27-
mutationFn: (newComment: { body: string }) =>
25+
mutationFn: (payload: { body: string; comment_id: string }) =>
2826
commentActions.createMyComment({
2927
resource_id: props.resource_id,
3028
resource_type: props.resource_type,
31-
body: newComment.body,
29+
body: payload.body,
30+
comment_id: payload.comment_id,
3231
}),
33-
onMutate: async (newComment) => {
32+
onMutate: async (payload) => {
3433
if (!session?.user) {
3534
appLoginPopup.show();
3635
return;
@@ -52,8 +51,8 @@ export const CommentSection = (props: {
5251
(old: any) => {
5352
return [
5453
{
55-
id: crypto.randomUUID(), // Generate a temporary ID for optimistic update
56-
body: newComment.body,
54+
id: payload.comment_id || crypto.randomUUID(),
55+
body: payload.body,
5756
level: 0,
5857
author: {
5958
id: session?.user?.id || "temp-user-id",
@@ -83,15 +82,16 @@ export const CommentSection = (props: {
8382
refetchOnReconnect: false,
8483
});
8584

85+
const generated_comment_id = useMemo(() => crypto.randomUUID(), []);
8686
return (
8787
<div className="max-w-4xl mx-auto p-4">
8888
<div className="mb-6">
89-
<h2 className="text-lg font-semibold mb-4">Comments</h2>
89+
<h2 className="text-lg font-semibold mb-4">{_t("Comments")}</h2>
9090

9191
{/* New Comment Box */}
9292
<CommentEditor
9393
onSubmit={(body) => {
94-
mutation.mutate({ body });
94+
mutation.mutate({ body, comment_id: generated_comment_id });
9595
}}
9696
isLoading={mutation.isPending}
9797
placeholder={_t("What are your thoughts?")}
@@ -173,24 +173,25 @@ const CommentItem = (props: { comment: CommentPresentation }) => {
173173
);
174174

175175
const level = useMemo(() => props.comment.level ?? 0, [props.comment]);
176-
176+
const generated_comment_id = useMemo(() => crypto.randomUUID(), []);
177177
const mutation = useMutation({
178-
mutationFn: (body: string) =>
178+
mutationFn: (payload: { body: string; comment_id: string }) =>
179179
commentActions.createMyComment({
180-
body,
180+
comment_id: payload.comment_id,
181+
body: payload.body,
181182
resource_id: props.comment.id,
182183
resource_type: "COMMENT",
183184
}),
184-
onMutate: (body) => {
185+
onMutate: (payload) => {
185186
if (!session?.user) {
186187
appLoginPopup.show();
187188
return;
188189
}
189190

190191
setReplies((draft) => {
191192
draft.unshift({
192-
id: crypto.randomUUID(),
193-
body,
193+
id: payload.comment_id,
194+
body: payload.body,
194195
level: (props.comment.level ?? 0) + 1,
195196
author: {
196197
id: session?.user?.id || "temp-user-id",
@@ -206,7 +207,7 @@ const CommentItem = (props: { comment: CommentPresentation }) => {
206207
});
207208

208209
const levelMargin = useMemo(
209-
() => Math.min(level, 8) * 12,
210+
() => Math.min(level, 8) * 30,
210211
[props.comment.level]
211212
);
212213
return (
@@ -215,13 +216,6 @@ const CommentItem = (props: { comment: CommentPresentation }) => {
215216
className="group"
216217
style={{ marginLeft: `${levelMargin}px` }}
217218
>
218-
{/* <div className="flex items-center gap-2 text-xs text-muted-foreground mb-1">
219-
<button className="flex items-center gap-1 hover:text-foreground">
220-
<span className="font-medium">@{props.comment.author?.username}</span>
221-
</button>
222-
<span>•</span>
223-
<span>{formattedTime(new Date(props.comment.created_at!))}</span>
224-
</div> */}
225219
<div className="flex items-center gap-2 text-xs text-muted-foreground mb-1">
226220
<button
227221
onClick={() => setIsCollapsed(!isCollapsed)}
@@ -247,11 +241,6 @@ const CommentItem = (props: { comment: CommentPresentation }) => {
247241
</div>
248242
</div>
249243

250-
{/* Comment Attachments */}
251-
{/* {comment.attachments && comment.attachments.length > 0 && (
252-
<AttachmentDisplay attachments={comment.attachments} />
253-
)} */}
254-
255244
{/* Comment Actions */}
256245
<div className="flex items-center gap-4 mb-3">
257246
{level < 2 && (
@@ -263,7 +252,6 @@ const CommentItem = (props: { comment: CommentPresentation }) => {
263252
<span>{_t("Reply")}</span>
264253
</button>
265254
)}
266-
267255
<ResourceReaction
268256
resource_type="COMMENT"
269257
resource_id={props.comment.id}
@@ -275,7 +263,10 @@ const CommentItem = (props: { comment: CommentPresentation }) => {
275263
<div className="mb-4 ml-4">
276264
<CommentEditor
277265
onSubmit={(value) => {
278-
mutation.mutate(value);
266+
mutation.mutate({
267+
body: value,
268+
comment_id: generated_comment_id,
269+
});
279270
setShowReplyBox(false);
280271
}}
281272
isLoading={false}

0 commit comments

Comments
 (0)