diff --git a/surfsense_backend/app/services/chat_comments_service.py b/surfsense_backend/app/services/chat_comments_service.py index fa26bf6d5..6f81c0158 100644 --- a/surfsense_backend/app/services/chat_comments_service.py +++ b/surfsense_backend/app/services/chat_comments_service.py @@ -315,6 +315,8 @@ async def create_comment( thread_title=thread.title or "Untitled thread", author_id=str(user.id), author_name=author_name, + author_avatar_url=user.avatar_url, + author_email=user.email, content_preview=content_preview[:200], search_space_id=search_space_id, ) @@ -426,6 +428,8 @@ async def create_reply( thread_title=thread.title or "Untitled thread", author_id=str(user.id), author_name=author_name, + author_avatar_url=user.avatar_url, + author_email=user.email, content_preview=content_preview[:200], search_space_id=search_space_id, ) @@ -565,6 +569,8 @@ async def update_comment( thread_title=thread.title or "Untitled thread", author_id=str(user.id), author_name=author_name, + author_avatar_url=user.avatar_url, + author_email=user.email, content_preview=content_preview[:200], search_space_id=search_space_id, ) diff --git a/surfsense_backend/app/services/notification_service.py b/surfsense_backend/app/services/notification_service.py index 97e0f9457..5f7f568f6 100644 --- a/surfsense_backend/app/services/notification_service.py +++ b/surfsense_backend/app/services/notification_service.py @@ -634,6 +634,8 @@ class MentionNotificationHandler(BaseNotificationHandler): thread_title: str, author_id: str, author_name: str, + author_avatar_url: str | None, + author_email: str, content_preview: str, search_space_id: int, ) -> Notification: @@ -650,6 +652,8 @@ class MentionNotificationHandler(BaseNotificationHandler): thread_title: Title of the chat thread author_id: ID of the comment author author_name: Display name of the comment author + author_avatar_url: Avatar URL of the comment author + author_email: Email of the comment author (for fallback initials) content_preview: First ~100 chars of the comment search_space_id: Search space ID @@ -667,6 +671,8 @@ class MentionNotificationHandler(BaseNotificationHandler): "thread_title": thread_title, "author_id": author_id, "author_name": author_name, + "author_avatar_url": author_avatar_url, + "author_email": author_email, "content_preview": content_preview[:200], } diff --git a/surfsense_web/components/notifications/NotificationPopup.tsx b/surfsense_web/components/notifications/NotificationPopup.tsx index 50deadf03..dff89ff6a 100644 --- a/surfsense_web/components/notifications/NotificationPopup.tsx +++ b/surfsense_web/components/notifications/NotificationPopup.tsx @@ -4,12 +4,32 @@ import { formatDistanceToNow } from "date-fns"; import { AlertCircle, Bell, CheckCheck, CheckCircle2, Loader2 } from "lucide-react"; import { useRouter } from "next/navigation"; import { convertRenderedToDisplay } from "@/components/chat-comments/comment-item/comment-item"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Separator } from "@/components/ui/separator"; import type { Notification } from "@/hooks/use-notifications"; import { cn } from "@/lib/utils"; +/** + * Get initials from name or email for avatar fallback + */ +function getInitials(name: string | null | undefined, email: string | null | undefined): string { + if (name) { + return name + .split(" ") + .map((n) => n[0]) + .join("") + .toUpperCase() + .slice(0, 2); + } + if (email) { + const localPart = email.split("@")[0]; + return localPart.slice(0, 2).toUpperCase(); + } + return "U"; +} + interface NotificationPopupProps { notifications: Notification[]; unreadCount: number; @@ -66,6 +86,28 @@ export function NotificationPopup({ }; const getStatusIcon = (notification: Notification) => { + // For mentions, show the author's avatar with initials fallback + if (notification.type === "new_mention") { + const metadata = notification.metadata as { + author_name?: string; + author_avatar_url?: string | null; + author_email?: string; + }; + const authorName = metadata?.author_name; + const avatarUrl = metadata?.author_avatar_url; + const authorEmail = metadata?.author_email; + + return ( + + {avatarUrl && } + + {getInitials(authorName, authorEmail)} + + + ); + } + + // For other notification types, show status icons const status = notification.metadata?.status as string | undefined; switch (status) { @@ -118,8 +160,8 @@ export function NotificationPopup({ !notification.read && "bg-accent/50" )} > -
-
{getStatusIcon(notification)}
+
+
{getStatusIcon(notification)}