|
1 | | -import { z } from "zod"; |
2 | | -import { getCurrentUser } from "@cap/database/auth/session"; |
| 1 | +// Ideally all the Notification-related types would be in @cap/web-domain |
| 2 | +// but @cap/web-api-contract is the closest we have right now |
| 3 | + |
3 | 4 | import { notifications, videos, users } from "@cap/database/schema"; |
4 | 5 | import { db } from "@cap/database"; |
5 | 6 | import { and, eq, sql } from "drizzle-orm"; |
6 | 7 | import { nanoId } from "@cap/database/helpers"; |
7 | 8 | import { UserPreferences } from "@/app/(org)/dashboard/dashboard-data"; |
8 | 9 | import { revalidatePath } from "next/cache"; |
9 | | - |
10 | | -const buildNotification = <TType extends string, TFields extends z.ZodRawShape>( |
11 | | - type: TType, |
12 | | - fields: TFields |
13 | | -) => z.object({ ...fields, type: z.literal(type) }); |
14 | | - |
15 | | -export const Notification = z.union([ |
16 | | - buildNotification("view", { videoId: z.string(), authorId: z.string() }), |
17 | | - buildNotification("comment", { |
18 | | - videoId: z.string(), |
19 | | - authorId: z.string(), |
20 | | - comment: z.object({ |
21 | | - id: z.string(), |
22 | | - content: z.string(), |
23 | | - }), |
24 | | - }), |
25 | | - buildNotification("reaction", { videoId: z.string(), authorId: z.string() }), |
26 | | - // buildNotification("mention", { |
27 | | - // videoId: z.string(), |
28 | | - // authorId: z.string(), |
29 | | - // comment: z.object({ |
30 | | - // id: z.string(), |
31 | | - // content: z.string(), |
32 | | - // }), |
33 | | - // }), |
34 | | - buildNotification("reply", { |
35 | | - videoId: z.string(), |
36 | | - authorId: z.string(), |
37 | | - comment: z.object({ |
38 | | - id: z.string(), |
39 | | - content: z.string(), |
40 | | - }), |
41 | | - }), |
42 | | -]); |
43 | | - |
44 | | -export type RawNotification = z.infer<typeof Notification>; |
45 | | -export type NotificationType = z.infer<typeof Notification>["type"]; |
46 | | - |
47 | | -export type HydratedNotification = |
48 | | - | Extract<RawNotification, { type: "view" }> |
49 | | - | (Extract<RawNotification, { type: "comment" }> & { content: string }); |
50 | | - |
51 | | -export async function createNotification(notification: RawNotification) { |
| 10 | +import { Notification, NotificationBase } from "@cap/web-api-contract"; |
| 11 | + |
| 12 | +// Notification daata without id, readTime, etc |
| 13 | +type NotificationSpecificData = DistributiveOmit< |
| 14 | + Notification, |
| 15 | + keyof NotificationBase |
| 16 | +>; |
| 17 | + |
| 18 | +// Replaces author object with authorId since we query for that info. |
| 19 | +// If we add more notifications this would probably be better done manually |
| 20 | +// Type is weird since we need to operate on each member of the NotificationSpecificData union |
| 21 | +type CreateNotificationInput<D = NotificationSpecificData> = |
| 22 | + D extends NotificationSpecificData |
| 23 | + ? D["author"] extends never |
| 24 | + ? D |
| 25 | + : Omit<D, "author"> & { authorId: string } |
| 26 | + : never; |
| 27 | + |
| 28 | +export async function createNotification( |
| 29 | + notification: CreateNotificationInput |
| 30 | +) { |
52 | 31 | try { |
53 | 32 | // First, get the video and owner data |
54 | 33 | const [videoResult] = await db() |
@@ -79,10 +58,9 @@ export async function createNotification(notification: RawNotification) { |
79 | 58 |
|
80 | 59 | const shouldSkipNotification = |
81 | 60 | (notification.type === "comment" && notificationPrefs.pauseComments) || |
82 | | - (notification.type === "view" && notificationPrefs.pauseViews); |
83 | | - // || |
84 | | - // (variant === "reply" && notificationPrefs.pauseReplies) || |
85 | | - // (variant === "reaction" && notificationPrefs.pauseReactions); |
| 61 | + (notification.type === "view" && notificationPrefs.pauseViews) || |
| 62 | + (notification.type === "reply" && notificationPrefs.pauseReplies) || |
| 63 | + (notification.type === "reaction" && notificationPrefs.pauseReactions); |
86 | 64 |
|
87 | 65 | if (shouldSkipNotification) { |
88 | 66 | return; |
@@ -115,7 +93,7 @@ export async function createNotification(notification: RawNotification) { |
115 | 93 | and( |
116 | 94 | eq(notifications.type, "comment"), |
117 | 95 | eq(notifications.recipientId, videoResult.ownerId), |
118 | | - sql`JSON_EXTRACT(${notifications.data}, '$.commentId') = ${notification.comment.id}` |
| 96 | + sql`JSON_EXTRACT(${notifications.data}, '$.comment.id') = ${notification.comment.id}` |
119 | 97 | ) |
120 | 98 | ) |
121 | 99 | .limit(1); |
|
0 commit comments