import { and, eq, sql } from 'drizzle-orm' import { z } from 'zod' import { commentReactions, comments } from '../../../db/schema' const bodySchema = z.object({ emoji: z.string().min(1).max(32), }) export default defineEventHandler(async (event) => { const user = await requireUser(event) const id = Number(getRouterParam(event, 'id')) if (!Number.isInteger(id) || id <= 0) { throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' }) } const { emoji } = await readValidatedBody(event, bodySchema.parse) const db = useDb() const [comment] = await db .select({ id: comments.id, uploadId: comments.uploadId }) .from(comments) .where(eq(comments.id, id)) .limit(1) if (!comment) { throw createError({ statusCode: 404, statusMessage: 'Kommentar nicht gefunden' }) } const existing = await db .select({ userId: commentReactions.userId }) .from(commentReactions) .where(and( eq(commentReactions.commentId, id), eq(commentReactions.userId, user.id), eq(commentReactions.emoji, emoji), )) .limit(1) let active: boolean if (existing.length) { await db.delete(commentReactions).where(and( eq(commentReactions.commentId, id), eq(commentReactions.userId, user.id), eq(commentReactions.emoji, emoji), )) active = false } else { await db.insert(commentReactions).values({ commentId: id, userId: user.id, emoji }) active = true } const [{ total }] = await db .select({ total: sql`count(*)` }) .from(commentReactions) .where(and(eq(commentReactions.commentId, id), eq(commentReactions.emoji, emoji))) const count = Number(total) broadcastToAll({ type: 'reaction', commentId: id, uploadId: comment.uploadId, emoji, actorId: user.id, actorName: user.name, active, count, }) return { active, count } })