From 2c3ef82f548e55a0da3120872beaff740a8c4ca8 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:36:07 +0300 Subject: [PATCH 1/4] fix avatars in notifications --- .../Notifications/NotificationItem.tsx | 18 ++--- apps/web/app/api/notifications/route.ts | 70 +++++++++++-------- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx index 2eddf25dea..5215423751 100644 --- a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx +++ b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx @@ -5,6 +5,7 @@ import clsx from "clsx"; import moment from "moment"; import Link from "next/link"; import { markAsRead } from "@/actions/notifications/mark-as-read"; +import { SignedImageUrl } from "@/components/SignedImageUrl"; import type { NotificationType } from "@/lib/Notification"; type NotificationItemProps = { @@ -45,17 +46,12 @@ export const NotificationItem = ({ > {/* Avatar */}
- {notification.author.avatar ? ( - {notification.author.name} - ) : ( -
- {notification.author.name.charAt(0)} -
- )} + {notification.readAt === null && (
)} diff --git a/apps/web/app/api/notifications/route.ts b/apps/web/app/api/notifications/route.ts index 0ea8748bee..ca36ba888d 100644 --- a/apps/web/app/api/notifications/route.ts +++ b/apps/web/app/api/notifications/route.ts @@ -2,12 +2,13 @@ import { db } from "@cap/database"; import { getCurrentUser } from "@cap/database/auth/session"; import { notifications, users } from "@cap/database/schema"; import { Notification as APINotification } from "@cap/web-api-contract"; -import { and, ColumnBaseConfig, desc, eq, isNull, sql } from "drizzle-orm"; -import { MySqlColumn } from "drizzle-orm/mysql-core"; +import { ImageUploads } from "@cap/web-backend"; +import { and, desc, eq, isNull, sql } from "drizzle-orm"; +import { Effect } from "effect"; import { NextResponse } from "next/server"; -import { AvcProfileInfo } from "node_modules/@remotion/media-parser/dist/containers/avc/parse-avc"; import { z } from "zod"; import type { NotificationType } from "@/lib/Notification"; +import { runPromise } from "@/lib/server"; import { jsonExtractString } from "@/utils/sql"; const notificationDataSchema = z.object({ @@ -90,32 +91,45 @@ export async function GET() { formattedCountResults[type] = Number(count); }); - const formattedNotifications = notificationsWithAuthors - .map(({ notification, author }) => { - try { - // all notifications currently require an author - if (!author) return; + // Resolve avatar URLs using ImageUploads service + const formattedNotifications = await Effect.gen(function* () { + const imageUploads = yield* ImageUploads; - return APINotification.parse({ - id: notification.id, - type: notification.type, - readAt: notification.readAt, - videoId: notification.data.videoId, - createdAt: notification.createdAt, - data: notification.data, - comment: notification.data.comment, - author: { - id: author.id, - name: author.name ?? "Unknown", - avatar: author.avatar, - }, - }); - } catch (error) { - console.error("Invalid notification data:", error); - return null; - } - }) - .filter(Boolean); + return yield* Effect.all( + notificationsWithAuthors.map(({ notification, author }) => + Effect.fn(function* () { + try { + // all notifications currently require an author + if (!author) return null; + + const resolvedAvatar = author.avatar + ? yield* imageUploads.resolveImageUrl(author.avatar) + : null; + + return APINotification.parse({ + id: notification.id, + type: notification.type, + readAt: notification.readAt, + videoId: notification.data.videoId, + createdAt: notification.createdAt, + data: notification.data, + comment: notification.data.comment, + author: { + id: author.id, + name: author.name ?? "Unknown", + avatar: resolvedAvatar, + }, + }); + } catch (error) { + console.error("Invalid notification data:", error); + return null; + } + })(), + ), + ); + }) + .pipe(runPromise) + .then((results) => results.filter(Boolean)); return NextResponse.json({ notifications: formattedNotifications, From 1c08e7b8ad5a18bb59eb46fe6fda52568974c1c3 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:42:52 +0300 Subject: [PATCH 2/4] Update route.ts --- apps/web/app/api/notifications/route.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/web/app/api/notifications/route.ts b/apps/web/app/api/notifications/route.ts index ca36ba888d..079ba17f41 100644 --- a/apps/web/app/api/notifications/route.ts +++ b/apps/web/app/api/notifications/route.ts @@ -91,7 +91,6 @@ export async function GET() { formattedCountResults[type] = Number(count); }); - // Resolve avatar URLs using ImageUploads service const formattedNotifications = await Effect.gen(function* () { const imageUploads = yield* ImageUploads; From 46dbc3df08345d3514166010015dad3bcadf12f1 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:49:33 +0300 Subject: [PATCH 3/4] Update route.ts --- apps/web/app/api/notifications/route.ts | 50 ++++++++++++------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/apps/web/app/api/notifications/route.ts b/apps/web/app/api/notifications/route.ts index 079ba17f41..ac8ec2bdf7 100644 --- a/apps/web/app/api/notifications/route.ts +++ b/apps/web/app/api/notifications/route.ts @@ -96,34 +96,34 @@ export async function GET() { return yield* Effect.all( notificationsWithAuthors.map(({ notification, author }) => - Effect.fn(function* () { - try { - // all notifications currently require an author - if (!author) return null; + Effect.gen(function* () { + // all notifications currently require an author + if (!author) return null; - const resolvedAvatar = author.avatar - ? yield* imageUploads.resolveImageUrl(author.avatar) - : null; + const resolvedAvatar = author.avatar + ? yield* imageUploads.resolveImageUrl(author.avatar) + : null; - return APINotification.parse({ - id: notification.id, - type: notification.type, - readAt: notification.readAt, - videoId: notification.data.videoId, - createdAt: notification.createdAt, - data: notification.data, - comment: notification.data.comment, - author: { - id: author.id, - name: author.name ?? "Unknown", - avatar: resolvedAvatar, - }, - }); - } catch (error) { + return APINotification.parse({ + id: notification.id, + type: notification.type, + readAt: notification.readAt, + videoId: notification.data.videoId, + createdAt: notification.createdAt, + data: notification.data, + comment: notification.data.comment, + author: { + id: author.id, + name: author.name ?? "Unknown", + avatar: resolvedAvatar, + }, + }); + }).pipe( + Effect.catchAll((error) => { console.error("Invalid notification data:", error); - return null; - } - })(), + return Effect.succeed(null); + }), + ), ), ); }) From 93670a51d022497fcd25060d101afaca746a2c4d Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:56:44 +0300 Subject: [PATCH 4/4] ts --- .../dashboard/_components/Notifications/NotificationItem.tsx | 3 ++- apps/web/app/api/notifications/route.ts | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx index 5215423751..90ad061e96 100644 --- a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx +++ b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx @@ -1,4 +1,5 @@ import type { Notification as APINotification } from "@cap/web-api-contract"; +import type { ImageUpload } from "@cap/web-domain"; import { faComment, faEye, faReply } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import clsx from "clsx"; @@ -47,7 +48,7 @@ export const NotificationItem = ({ {/* Avatar */}
Effect.succeed(null))) : null; return APINotification.parse({