import { z } from 'astro:content' import { defineProtectedAction } from '../lib/defineProtectedAction' import { prisma } from '../lib/prisma' export const notificationActions = { updateReadStatus: defineProtectedAction({ accept: 'form', permissions: 'user', input: z.object({ notificationId: z.literal('all').or(z.coerce.number().int().positive()), read: z.coerce.boolean(), }), handler: async (input, context) => { await prisma.notification.updateMany({ where: input.notificationId === 'all' ? { userId: context.locals.user.id, read: !input.read } : { userId: context.locals.user.id, id: input.notificationId }, data: { read: input.read, }, }) }, }), webPush: { subscribe: defineProtectedAction({ accept: 'json', permissions: 'user', input: z.object({ endpoint: z.string(), p256dhKey: z.string(), authKey: z.string(), userAgent: z.string().optional(), }), handler: async (input, context) => { await prisma.pushSubscription.upsert({ where: { userId: context.locals.user.id, endpoint: input.endpoint, }, update: { p256dh: input.p256dhKey, auth: input.authKey, userAgent: input.userAgent, }, create: { userId: context.locals.user.id, endpoint: input.endpoint, p256dh: input.p256dhKey, auth: input.authKey, userAgent: input.userAgent, }, }) }, }), unsubscribe: defineProtectedAction({ accept: 'json', permissions: 'user', input: z.object({ endpoint: z.string().optional(), }), handler: async (input, context) => { if (input.endpoint) { await prisma.pushSubscription.deleteMany({ where: { userId: context.locals.user.id, endpoint: input.endpoint, }, }) } else { await prisma.pushSubscription.deleteMany({ where: { userId: context.locals.user.id, }, }) } }, }), }, preferences: { update: defineProtectedAction({ accept: 'form', permissions: 'user', input: z.object({ enableOnMyCommentStatusChange: z.coerce.boolean().optional(), enableAutowatchMyComments: z.coerce.boolean().optional(), enableNotifyPendingRepliesOnWatch: z.coerce.boolean().optional(), karmaNotificationThreshold: z.coerce.number().int().min(1).max(1_000_000).optional(), }), handler: async (input, context) => { await prisma.notificationPreferences.upsert({ where: { userId: context.locals.user.id }, update: { enableOnMyCommentStatusChange: input.enableOnMyCommentStatusChange, enableAutowatchMyComments: input.enableAutowatchMyComments, enableNotifyPendingRepliesOnWatch: input.enableNotifyPendingRepliesOnWatch, karmaNotificationThreshold: input.karmaNotificationThreshold, }, create: { userId: context.locals.user.id, enableOnMyCommentStatusChange: input.enableOnMyCommentStatusChange, enableAutowatchMyComments: input.enableAutowatchMyComments, enableNotifyPendingRepliesOnWatch: input.enableNotifyPendingRepliesOnWatch, karmaNotificationThreshold: input.karmaNotificationThreshold, }, }) }, }), watchComment: defineProtectedAction({ accept: 'form', permissions: 'user', input: z.object({ commentId: z.coerce.number().int().positive(), watch: z.coerce.boolean(), }), handler: async (input, context) => { await prisma.notificationPreferences.upsert({ where: { userId: context.locals.user.id }, update: { watchedComments: input.watch ? { connect: { id: input.commentId } } : { disconnect: { id: input.commentId } }, }, create: { userId: context.locals.user.id, watchedComments: input.watch ? { connect: { id: input.commentId } } : undefined, }, }) }, }), watchService: defineProtectedAction({ accept: 'form', permissions: 'user', input: z.object({ serviceId: z.coerce.number().int().positive(), watchType: z.enum(['all', 'comments', 'events', 'verification']), value: z.coerce.boolean(), }), handler: async (input, context) => { await prisma.notificationPreferences.upsert({ where: { userId: context.locals.user.id }, update: { onEventCreatedForServices: input.watchType === 'events' || input.watchType === 'all' ? input.value ? { connect: { id: input.serviceId } } : { disconnect: { id: input.serviceId } } : undefined, onRootCommentCreatedForServices: input.watchType === 'comments' || input.watchType === 'all' ? input.value ? { connect: { id: input.serviceId } } : { disconnect: { id: input.serviceId } } : undefined, onVerificationChangeForServices: input.watchType === 'verification' || input.watchType === 'all' ? input.value ? { connect: { id: input.serviceId } } : { disconnect: { id: input.serviceId } } : undefined, }, create: { userId: context.locals.user.id, onEventCreatedForServices: input.watchType === 'events' || input.watchType === 'all' ? input.value ? { connect: { id: input.serviceId } } : undefined : undefined, onRootCommentCreatedForServices: input.watchType === 'comments' || input.watchType === 'all' ? input.value ? { connect: { id: input.serviceId } } : undefined : undefined, onVerificationChangeForServices: input.watchType === 'verification' || input.watchType === 'all' ? input.value ? { connect: { id: input.serviceId } } : undefined : undefined, }, }) }, }), }, }