Skip to content

Commit 740a1b9

Browse files
committed
feat: topping comments
1 parent 8e5e942 commit 740a1b9

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

src/apis/comment.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,13 @@ export const requestRateComment = (
117117
},
118118
})
119119
}
120+
121+
export const requestTopComment = (commentId: string, topping: boolean) => {
122+
return jsonRequest<Response<string>>('/comments/topping', {
123+
method: 'POST',
124+
json: {
125+
comment_id: commentId,
126+
topping,
127+
},
128+
})
129+
}

src/components/viewer/comment/CommentArea.tsx

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import {
1616
requestDeleteComment,
1717
requestRateComment,
18+
requestTopComment,
1819
useComments,
1920
} from '../../../apis/comment'
2021
import {
@@ -142,7 +143,12 @@ const MainComment = ({
142143
children?: ReactNode
143144
}) => {
144145
return (
145-
<Card className={clsx(className)}>
146+
<Card
147+
className={clsx(
148+
className,
149+
comment.topping && 'shadow-[0_0_0_1px_#2d72d2]',
150+
)}
151+
>
146152
<div>
147153
<CommentHeader comment={comment} />
148154
<CommentContent comment={comment} />
@@ -189,21 +195,34 @@ const SubComment = ({
189195

190196
const CommentHeader = ({
191197
className,
192-
comment: { uploader, uploaderId, uploadTime },
198+
comment,
193199
}: {
194200
className?: string
195201
comment: CommentInfo
196202
}) => {
203+
const { uploader, uploaderId, uploadTime } = comment
204+
const topping = isMainComment(comment) ? comment.topping : false
197205
const [{ userId }] = useAtom(authAtom)
198206

199207
return (
200-
<div className={clsx(className, 'mb-2 flex items-center text-xs')}>
208+
<div
209+
className={clsx(
210+
className,
211+
'mb-2 flex items-center text-xs',
212+
'leading-[20px]', // 在无 <Tag> 时保持高度一致
213+
)}
214+
>
201215
<div className={clsx('mr-2', userId === uploaderId && 'font-bold')}>
202216
{uploader}
203217
</div>
204218
<div className="text-slate-500" title={formatDateTime(uploadTime)}>
205219
{formatRelativeTime(uploadTime)}
206220
</div>
221+
{topping && (
222+
<Tag minimal className="ml-2" intent="primary" icon="pin">
223+
置顶
224+
</Tag>
225+
)}
207226
</div>
208227
)
209228
}
@@ -268,6 +287,9 @@ const CommentActions = ({
268287
>
269288
回复
270289
</Button>
290+
{userId === comment.uploaderId && isMainComment(comment) && (
291+
<CommentTopButton comment={comment} />
292+
)}
271293
{userId === comment.uploaderId && (
272294
<Button
273295
minimal
@@ -347,3 +369,35 @@ const CommentRatingButtons = ({ comment }: { comment: CommentInfo }) => {
347369
</>
348370
)
349371
}
372+
373+
const CommentTopButton = ({ comment }: { comment: MainCommentInfo }) => {
374+
const { commentId, topping } = comment
375+
const { reload } = useContext(CommentAreaContext)
376+
377+
const [pending, setPending] = useState(false)
378+
379+
const top = async () => {
380+
if (pending) {
381+
return
382+
}
383+
384+
setPending(true)
385+
386+
try {
387+
await wrapErrorMessage(
388+
(e) => '置顶失败:' + formatError(e),
389+
requestTopComment(commentId, !topping),
390+
)
391+
392+
reload()
393+
} finally {
394+
setPending(false)
395+
}
396+
}
397+
398+
return (
399+
<Button minimal small className="!font-normal !text-[13px]" onClick={top}>
400+
{topping ? '取消置顶' : '置顶'}
401+
</Button>
402+
)
403+
}

src/models/comment.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface MainCommentInfo {
77
message: string
88
uploadTime: string
99
like: number
10+
topping: boolean
1011
subCommentsInfos: SubCommentInfo[]
1112
}
1213

0 commit comments

Comments
 (0)