fix: better like count

This commit is contained in:
trafficlunar 2026-04-19 18:16:10 +01:00
parent c951c7d755
commit 583d223ed9
6 changed files with 25 additions and 19 deletions

View file

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX "miis_in_queue_quarantined_createdAt_idx" ON "miis"("in_queue", "quarantined", "createdAt" DESC);

View file

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "miis" ADD COLUMN "likeCount" INTEGER NOT NULL DEFAULT 0;
-- CreateIndex
CREATE INDEX "miis_likeCount_idx" ON "miis"("likeCount" DESC);

View file

@ -90,20 +90,23 @@ model Mii {
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
likedBy Like[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
likeCount Int @default(0)
punishmentId Int?
punishments MiiPunishment[]
likedBy Like[]
@@index([tags], type: Gin)
@@index([createdAt])
@@index([likeCount(sort: Desc)])
@@index([quarantined, createdAt(sort: Desc)])
@@index([platform, createdAt(sort: Desc)])
@@index([userId, createdAt(sort: Desc)])
@@index([gender])
@@index([makeup])
@@index([quarantined, id])
@@index([in_queue, quarantined, createdAt(sort: Desc)])
@@map("miis")
}

View file

@ -29,7 +29,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
});
if (existingLike) {
// Remove the like if it exists
await tx.like.delete({
where: {
userId_miiId: {
@ -38,22 +37,25 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
},
},
});
await tx.mii.update({
where: { id: miiId },
data: { likeCount: { decrement: 1 } },
});
} else {
// Add a like if it doesn't exist
await tx.like.create({
data: {
userId: Number(session.user?.id),
miiId,
},
});
await tx.mii.update({
where: { id: miiId },
data: { likeCount: { increment: 1 } },
});
}
const likeCount = await tx.like.count({
where: { miiId },
});
return { liked: !existingLike, count: likeCount };
return { liked: !existingLike };
});
return rateLimit.sendResponse({ success: true, liked: result.liked, count: result.count });
return rateLimit.sendResponse({ success: true, liked: result.liked });
}

View file

@ -78,6 +78,7 @@ export async function GET(request: NextRequest) {
allowedCopying: true,
quarantined: true,
in_queue: true,
likeCount: true,
// Mii liked check
...(session?.user?.id && {
likedBy: {
@ -85,10 +86,6 @@ export async function GET(request: NextRequest) {
select: { userId: true },
},
}),
// Like count
_count: {
select: { likedBy: true },
},
// Admin
...(parentPage === "admin" && {
description: true,
@ -102,7 +99,7 @@ export async function GET(request: NextRequest) {
let orderBy: Prisma.MiiOrderByWithRelationInput[];
if (sort === "likes") {
orderBy = [{ likedBy: { _count: "desc" } }, { name: "asc" }];
orderBy = [{ likeCount: "desc" }, { name: "asc" }];
} else if (sort === "oldest") {
orderBy = [{ createdAt: "asc" }, { name: "asc" }];
} else {

View file

@ -30,7 +30,6 @@ export default function LikeButton({ likes, miiId, isLiked, disabled, abbreviate
}
const prevLiked = isLikedState;
const prevLikes = likesState;
setIsLikedState(!prevLiked);
setLikesState(prevLiked ? likesState - 1 : likesState + 1);
@ -42,12 +41,10 @@ export default function LikeButton({ likes, miiId, isLiked, disabled, abbreviate
const response = await fetch(`${import.meta.env.VITE_API_URL}/api/mii/${miiId}/like`, { method: "POST", credentials: "include" });
if (response.ok) {
const { liked, count } = await response.json();
const { liked } = await response.json();
setIsLikedState(liked);
setLikesState(count);
} else {
setIsLikedState(prevLiked);
setLikesState(prevLikes);
}
};