From 583d223ed9aba8ba83a2677d4d84c4041ff24c99 Mon Sep 17 00:00:00 2001 From: trafficlunar Date: Sun, 19 Apr 2026 18:16:10 +0100 Subject: [PATCH] fix: better like count --- .../20260416234406_pr_28/migration.sql | 2 ++ .../migration.sql | 5 +++++ backend/prisma/schema.prisma | 7 +++++-- backend/src/app/api/mii/[id]/like/route.ts | 18 ++++++++++-------- backend/src/app/api/mii/list/route.ts | 7 ++----- frontend/src/components/like-button.tsx | 5 +---- 6 files changed, 25 insertions(+), 19 deletions(-) create mode 100644 backend/prisma/migrations/20260416234406_pr_28/migration.sql create mode 100644 backend/prisma/migrations/20260419170916_use_like_count/migration.sql diff --git a/backend/prisma/migrations/20260416234406_pr_28/migration.sql b/backend/prisma/migrations/20260416234406_pr_28/migration.sql new file mode 100644 index 0000000..da78f81 --- /dev/null +++ b/backend/prisma/migrations/20260416234406_pr_28/migration.sql @@ -0,0 +1,2 @@ +-- CreateIndex +CREATE INDEX "miis_in_queue_quarantined_createdAt_idx" ON "miis"("in_queue", "quarantined", "createdAt" DESC); diff --git a/backend/prisma/migrations/20260419170916_use_like_count/migration.sql b/backend/prisma/migrations/20260419170916_use_like_count/migration.sql new file mode 100644 index 0000000..cfd9eac --- /dev/null +++ b/backend/prisma/migrations/20260419170916_use_like_count/migration.sql @@ -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); diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index cfc142b..dca9d42 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -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") } diff --git a/backend/src/app/api/mii/[id]/like/route.ts b/backend/src/app/api/mii/[id]/like/route.ts index 332f5bb..e4e5658 100644 --- a/backend/src/app/api/mii/[id]/like/route.ts +++ b/backend/src/app/api/mii/[id]/like/route.ts @@ -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 }); } diff --git a/backend/src/app/api/mii/list/route.ts b/backend/src/app/api/mii/list/route.ts index 7a4caef..923e735 100644 --- a/backend/src/app/api/mii/list/route.ts +++ b/backend/src/app/api/mii/list/route.ts @@ -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 { diff --git a/frontend/src/components/like-button.tsx b/frontend/src/components/like-button.tsx index 410d100..a1f2716 100644 --- a/frontend/src/components/like-button.tsx +++ b/frontend/src/components/like-button.tsx @@ -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); } };