feat(comments): add sorting and liking functionality

Support sorting by oldest, latest, most-liked, and most-replied.
Implement like/unlike actions for Life and Entity Discussion comments.
This commit is contained in:
2026-05-04 17:29:09 +08:00
parent 504849c14a
commit 2ff2519647
10 changed files with 993 additions and 65 deletions

View File

@@ -55,7 +55,9 @@ import {
deleteHabitat,
deleteItem,
deleteLanguage,
deleteEntityDiscussionCommentLike,
deleteLifeComment,
deleteLifeCommentLike,
deleteLifePost,
deleteLifePostRating,
deleteLifePostReaction,
@@ -108,6 +110,8 @@ import {
restoreLifeComment,
setLifePostRating,
setLifePostReaction,
setEntityDiscussionCommentLike,
setLifeCommentLike,
updateConfig,
updateAncientArtifact,
updateDailyChecklistItem,
@@ -1470,6 +1474,26 @@ app.post('/api/life-comments/:id/restore', async (request, reply) => {
return comment ? comment : notFound(reply, request);
});
app.put('/api/life-comments/:id/like', async (request, reply) => {
const user = await requirePermissionWithRateLimits(request, reply, 'life.comments.like', 'communityReaction');
if (!user) {
return;
}
const { id } = request.params as { id: string };
const comment = await setLifeCommentLike(Number(id), user.id);
return comment ? comment : notFound(reply, request);
});
app.delete('/api/life-comments/:id/like', async (request, reply) => {
const user = await requirePermissionWithRateLimits(request, reply, 'life.comments.like', 'communityReaction');
if (!user) {
return;
}
const { id } = request.params as { id: string };
const comment = await deleteLifeCommentLike(Number(id), user.id);
return comment ? comment : notFound(reply, request);
});
app.post('/api/life-comments/:id/moderation/retry', async (request, reply) => {
const user = await requireAnyPermissionWithRateLimits(
request,
@@ -1580,6 +1604,28 @@ app.post('/api/discussions/comments/:id/moderation/retry', async (request, reply
return comment ? comment : notFound(reply, request);
});
app.put('/api/discussions/comments/:id/like', async (request, reply) => {
const user = await requirePermissionWithRateLimits(request, reply, 'discussions.comments.like', 'communityReaction');
if (!user) {
return;
}
const { id } = request.params as { id: string };
const comment = await setEntityDiscussionCommentLike(Number(id), user.id);
return comment ? comment : notFound(reply, request);
});
app.delete('/api/discussions/comments/:id/like', async (request, reply) => {
const user = await requirePermissionWithRateLimits(request, reply, 'discussions.comments.like', 'communityReaction');
if (!user) {
return;
}
const { id } = request.params as { id: string };
const comment = await deleteEntityDiscussionCommentLike(Number(id), user.id);
return comment ? comment : notFound(reply, request);
});
app.get('/api/pokemon', async (request) =>
listPokemon(request.query as Record<string, string | string[] | undefined>, requestLocale(request))
);