Message Components
Message Components
Section titled “Message Components”Purpose
Section titled “Purpose”Message Components provide specialized rendering for different message types in the chat interface, including text, images, videos, files, and activity messages.
When to Use:
- Displaying conversation messages
- Rendering message attachments
- Showing message metadata (sender, timestamp, status)
Public API
Section titled “Public API”MessageItem Component
Section titled “MessageItem Component”Location: src/screens/chat-screen/components/message-item/
Props:
interface MessageItemProps { message: Message; showAvatar?: boolean; showTimestamp?: boolean;}
interface Message { id: number; content: string; messageType: 0 | 1 | 2; // 0=incoming, 1=outgoing, 2=activity createdAt: number; sender: { name: string; thumbnail?: string; }; attachments?: Attachment[]; private: boolean;}Usage:
import { MessageItem } from '@/screens/chat-screen/components/message-item';
<MessageItem message={message} showAvatar showTimestamp/>Message Content Components
Section titled “Message Content Components”Location: src/screens/chat-screen/components/message-components/
TextMessage
Section titled “TextMessage”Renders plain text with markdown support and link detection.
<TextMessage content={message.content} />ImageMessage
Section titled “ImageMessage”Displays image attachments with lightbox viewer.
<ImageMessage imageUrl={attachment.dataUrl} thumbnailUrl={attachment.thumbUrl} onPress={() => openLightbox(attachment)}/>VideoMessage
Section titled “VideoMessage”Shows video thumbnail with play button.
<VideoMessage videoUrl={attachment.dataUrl} thumbnailUrl={attachment.thumbUrl} onPress={() => playVideo(attachment)}/>AudioMessage
Section titled “AudioMessage”Renders audio player with playback controls.
<AudioMessage audioUrl={attachment.dataUrl} duration={attachment.duration}/>FileMessage
Section titled “FileMessage”Displays file attachment with download action.
<FileMessage fileName={attachment.fileName} fileSize={attachment.fileSize} fileUrl={attachment.dataUrl} onDownload={() => downloadFile(attachment)}/>MessageBubble Component
Section titled “MessageBubble Component”Props:
interface MessageBubbleProps { isOutgoing: boolean; isPrivate: boolean; children: React.ReactNode;}Usage:
<MessageBubble isOutgoing={message.messageType === 1} isPrivate={message.private}> <TextMessage content={message.content} /></MessageBubble>TypingIndicator Component
Section titled “TypingIndicator Component”Shows when other users are typing in the conversation.
interface TypingIndicatorProps { users: User[];}
<TypingIndicator users={typingUsers} />Behavior and Constraints
Section titled “Behavior and Constraints”Message Grouping
Section titled “Message Grouping”Messages from the same sender within 1 minute are grouped together:
- First message shows avatar and sender name
- Subsequent messages in group show compact layout
- Timestamp only on last message in group
Link Detection
Section titled “Link Detection”Text messages automatically detect and highlight:
- URLs (https://, http://)
- Email addresses
- Phone numbers
Rich Content
Section titled “Rich Content”Markdown rendering supports:
- Bold text
- Italic text
Codeblocks- Lists (ordered and unordered)
- Blockquotes
Performance
Section titled “Performance”- Images lazy-loaded with placeholders
- Videos show thumbnails, load on tap
- Large messages truncated with “Read more” option
- Virtualized list for smooth scrolling
Testing
Section titled “Testing”Message Rendering Tests
Section titled “Message Rendering Tests”import { render } from '@testing-library/react-native';import { MessageItem } from './MessageItem';
describe('MessageItem', () => { it('should render text message', () => { const message = { id: 1, content: 'Hello world', messageType: 1, createdAt: Date.now(), sender: { name: 'Agent' }, };
const { getByText } = render(<MessageItem message={message} />); expect(getByText('Hello world')).toBeTruthy(); });
it('should render image attachment', () => { const message = { id: 1, content: '', messageType: 1, createdAt: Date.now(), sender: { name: 'Agent' }, attachments: [ { id: 1, fileType: 'image', dataUrl: 'https://example.com/image.jpg', }, ], };
const { getByTestId } = render(<MessageItem message={message} />); expect(getByTestId('image-attachment')).toBeTruthy(); });});Further Reading
Section titled “Further Reading”- Messaging Feature - Message handling
- Media Handling - Attachment processing
- UI Components - Base components