"use client"; /** * One row of the chat inbox: avatar, title, the last message (truncated, with * its sender), the time, and an unread badge. * * `highlighted` is driven by realtime `chat_activity` — a new message flashes * its row here rather than raising a notification, which is what keeps chat out * of the notification tray. */ import Link from "next/link"; import { BellOff } from "lucide-react"; import { UserAvatar } from "@/components/ui/user-avatar"; import { KautilyaIcon } from "@/components/selection-toolbar/shared"; import { timeAgo } from "@/lib/time"; import { cn } from "@/lib/utils"; import { conversationTitle, groupAvatarUrl, isMuted, type InboxItem, } from "@/lib/chat"; /** "You: ..." for your own messages, "Name: ..." in groups, bare in a DM. */ function previewText(item: InboxItem, selfId: string): string { const m = item.last_message; if (!m) return "No messages yet"; if (m.deleted_at) return "This message was deleted"; const body = m.body || "Attachment"; if (m.sender_id === selfId) return `You: ${body}`; // A DM's peer is already named by the row title, so repeating it wastes the // line. Groups need the name to tell speakers apart. if (item.kind === "group" && m.sender_name) return `${m.sender_name}: ${body}`; return body; } export function ChatListItem({ item, selfId, highlighted = false, }: { item: InboxItem; selfId: string; highlighted?: boolean; }) { const muted = isMuted(item); const unread = item.unread > 0; return (
  • {item.kind === "ai" ? ( ) : ( )}
    {conversationTitle(item)} {muted && ( )}

    {previewText(item, selfId)}

    {item.last_message_at && ( {timeAgo(item.last_message_at)} )} {unread && ( {item.unread > 99 ? "99+" : item.unread} )}
  • ); }