import { useState } from 'react'; import { MessageSquare, UserCircle, Bot, Star, User, Image as ImageIcon } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Persona } from '@/types/persona'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { getPersonaAvatarSrc } from '@/utils/avatarUtils'; import { parseMentions, formatMentionsForDisplay } from '@/utils/mentionUtils'; import { focusGroupsApi } from '@/lib/api'; interface Message { id: string; senderId: string; // 'moderator' = AI Moderator, 'facilitator' = Human Facilitator, or participant ID text: string; timestamp: Date; type: 'question' | 'response' | 'system' | 'highlight'; highlighted?: boolean; } interface ChatMessageProps { message: Message; persona: Persona | null; toggleHighlight: () => void; participants?: Persona[]; // For parsing @mentions in message text focusGroupId?: string; // For loading creative assets } const ChatMessage = ({ message, persona, toggleHighlight, participants = [], focusGroupId }: ChatMessageProps) => { const [isHovered, setIsHovered] = useState(false); const isModerator = message.senderId === 'moderator'; const isFacilitator = message.senderId === 'facilitator'; // Parse and format mentions in the message text const parsedMentions = parseMentions(message.text, participants); const formattedText = formatMentionsForDisplay(message.text, parsedMentions.mentions); // Extract creative asset filename from message text if this is a creative review const extractAssetFilename = (text: string): string | null => { // Look for patterns like "asset: filename.jpg" or similar const patterns = [ // Match quoted filenames (most specific pattern first) /titled\s+['"]([^'"]+\.(jpg|jpeg|png))['\"]/i, // "titled 'filename.jpg'" /asset\s+['"]([^'"]+\.(jpg|jpeg|png))['\"]/i, // "asset 'filename.jpg'" /image\s+['"]([^'"]+\.(jpg|jpeg|png))['\"]/i, // "image 'filename.jpg'" /['"]([a-zA-Z0-9_\-]+\.(jpg|jpeg|png))['\"]/i, // Any quoted filename // Match focus group asset pattern without quotes /(fg-[a-f0-9]+-[a-f0-9]{32}\.(jpg|jpeg|png))/i, // fg-{id}-{uuid}.{ext} ]; for (const pattern of patterns) { const match = text.match(pattern); if (match) { return match[1]; } } return null; }; const assetFilename = extractAssetFilename(message.text); const hasCreativeAsset = (isModerator || isFacilitator) && assetFilename && focusGroupId; const handleToggleHighlight = () => { toggleHighlight(); }; return (
{formattedText}
{/* Display creative asset if this is a moderator message with an asset */} {hasCreativeAsset && (