"use client"; import { X } from "lucide-react"; import { cn } from "@/lib/utils"; import type { Message } from "@/types"; interface ReplyQuoteProps { /** Sender label of the quoted message: "You" for our own messages, * contact name for customer-sent messages. Caller resolves this — the * quote component doesn't see the parent Message. */ authorLabel: string; /** Compact text preview. Falls back to a placeholder for media types. */ preview: string; /** Present → renders the composer-chip variant with an X button. Absent → * renders the embedded-in-bubble variant. */ onDismiss?: () => void; /** True when embedded inside an outbound (primary-filled) bubble, so the * quote must read against the primary surface rather than the neutral * foreground — otherwise it goes low-contrast in light mode. */ onPrimary?: boolean; } export function ReplyQuote({ authorLabel, preview, onDismiss, onPrimary = false, }: ReplyQuoteProps) { const isChip = !!onDismiss; return (
{authorLabel}
{/* Wrap the preview instead of truncating to a single line. * `truncate` (white-space: nowrap) forced the quote onto one * impossibly-wide line and — because the parent flex chain * lacked `min-w-0` at every step — pushed the entire inbox * layout wider, shoving the contact sidebar off-screen. * `break-words` also wraps long URLs that have no whitespace * to break on. Issue #165. */}
{preview}
{onDismiss && ( )}
); } /** Build the one-line preview text shown inside a reply quote. */ export function buildReplyPreview(message: Message): string { if (message.content_text) return message.content_text; switch (message.content_type) { case "image": return "[Image]"; case "video": return "[Video]"; case "audio": return "[Audio]"; case "document": return "[Document]"; case "location": return "[Location]"; case "template": return "[Template]"; default: return "[Message]"; } }