import { useState } from "react"; import { ArrowRight, RefreshCcw, Copy, Check, Trash2, RotateCcw, ListFilter, ChevronLeft, ChevronRight } from "lucide-react"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { format } from "date-fns"; import { Avatar, AvatarFallback } from "../ui/avatar"; import { ChatMessage } from "./ChatMessage"; import { ThinkingAnimation } from "./ThinkingAnimation"; import { toast } from '../ui/sonner'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; interface MessageVariation { id: string; content: string; timestamp: Date; } interface Message { id: string; content: string; sender: "user" | "system"; timestamp: Date; isLoading?: boolean; error?: boolean; result?: any; variations?: MessageVariation[]; activeVariation?: string; } interface ChatBubbleProps { message: Message; onViewSearchResults?: (messageId: string) => void; onRetry?: (messageId: string) => void; onRegenerate?: (messageId: string) => void; onDelete?: (messageId: string) => void; onSelectVariation?: (messageId: string, variationId: string) => void; } export const ChatBubble = ({ message, onViewSearchResults, onRetry, onRegenerate, onDelete, onSelectVariation }: ChatBubbleProps) => { const [copied, setCopied] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const isWelcomeMessage = message.id === "welcomems" const isSystem = message.sender === "system"; const showCopyButton = true; const hasVariations = isSystem && message.variations && message.variations.length > 0; // If the message has variations, display the active one or the first one const displayContent = isSystem && hasVariations && message.activeVariation ? message.variations.find(v => v.id === message.activeVariation)?.content || message.content : message.content; const copyToClipboard = () => { navigator.clipboard.writeText(displayContent); setCopied(true); toast.success('Copied to clipboard!'); setTimeout(() => setCopied(false), 2000); }; const handleDelete = () => { setDeleteDialogOpen(false); if (onDelete) { onDelete(message.id); } }; const handleSelectVariation = (variationId: string) => { if (onSelectVariation) { onSelectVariation(message.id, variationId); } }; // Function to get the current variation index and navigate through variations const navigateVariations = (direction: 'prev' | 'next') => { if (!hasVariations || !message.variations || message.variations.length <= 1) return; const currentIndex = message.activeVariation ? message.variations.findIndex(v => v.id === message.activeVariation) : 0; let newIndex; if (direction === 'prev') { newIndex = (currentIndex - 1 + message.variations.length) % message.variations.length; } else { newIndex = (currentIndex + 1) % message.variations.length; } handleSelectVariation(message.variations[newIndex].id); }; // Get current variation index for display const getCurrentVariationIndex = () => { if (!hasVariations || !message.variations) return 0; return message.activeVariation ? message.variations.findIndex(v => v.id === message.activeVariation) + 1 : 1; }; return ( <>
{isSystem ? "AI" : "You"}
{message.isLoading ? ( ) : ( )}
{/* Chat bubble footer */}
{/* Time */}
{format(message.timestamp, "h:mm a")}
{/* Controls */} {!isWelcomeMessage &&
{/* Variation Navigation */} {hasVariations && message.variations && message.variations.length > 1 && (
{getCurrentVariationIndex()}/{message.variations.length}
)} {/* Retry button for failed messages */} {message.error && onRetry && (
)} {/* Regenerate button for system messages */} {isSystem && !message.isLoading && onRegenerate && (

Generate variation

)} {/* Delete button */} {onDelete && !message.isLoading && (

Delete message

)} {/* Copy */} {showCopyButton && !message.isLoading && (
)}
}
{/* Delete confirmation dialog */} Delete Message Are you sure you want to delete this message? This action cannot be undone. Cancel Delete ); };