feat: enhance chat comment notifications with author details

- Added author_avatar_url and author_email to comment creation and reply functions for improved metadata.
- Updated MentionNotificationHandler to include author details in notifications.
- Enhanced NotificationPopup to display author's avatar with initials fallback for mentions.
- Updated notification types to accommodate new author fields.
This commit is contained in:
Anish Sarkar 2026-01-20 20:05:37 +05:30
parent 3fb83e4c3a
commit 96701a9f01
4 changed files with 58 additions and 2 deletions

View file

@ -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,
)

View file

@ -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],
}

View file

@ -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 (
<Avatar className="h-6 w-6">
{avatarUrl && <AvatarImage src={avatarUrl} alt={authorName || "User"} />}
<AvatarFallback className="text-[10px] bg-primary/10 text-primary">
{getInitials(authorName, authorEmail)}
</AvatarFallback>
</Avatar>
);
}
// 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"
)}
>
<div className="flex items-start gap-3 overflow-hidden">
<div className="flex-shrink-0 mt-0.5">{getStatusIcon(notification)}</div>
<div className="flex items-center gap-3 overflow-hidden">
<div className="flex-shrink-0">{getStatusIcon(notification)}</div>
<div className="flex-1 min-w-0 overflow-hidden">
<div className="flex items-start justify-between gap-2 mb-1">
<p

View file

@ -83,6 +83,8 @@ export const newMentionMetadata = z.object({
thread_title: z.string(),
author_id: z.string(),
author_name: z.string(),
author_avatar_url: z.string().nullable().optional(),
author_email: z.string().optional(),
content_preview: z.string(),
});