Skip to content

Message Components

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)

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
/>

Location: src/screens/chat-screen/components/message-components/

Renders plain text with markdown support and link detection.

<TextMessage content={message.content} />

Displays image attachments with lightbox viewer.

<ImageMessage
imageUrl={attachment.dataUrl}
thumbnailUrl={attachment.thumbUrl}
onPress={() => openLightbox(attachment)}
/>

Shows video thumbnail with play button.

<VideoMessage
videoUrl={attachment.dataUrl}
thumbnailUrl={attachment.thumbUrl}
onPress={() => playVideo(attachment)}
/>

Renders audio player with playback controls.

<AudioMessage
audioUrl={attachment.dataUrl}
duration={attachment.duration}
/>

Displays file attachment with download action.

<FileMessage
fileName={attachment.fileName}
fileSize={attachment.fileSize}
fileUrl={attachment.dataUrl}
onDownload={() => downloadFile(attachment)}
/>

Props:

interface MessageBubbleProps {
isOutgoing: boolean;
isPrivate: boolean;
children: React.ReactNode;
}

Usage:

<MessageBubble isOutgoing={message.messageType === 1} isPrivate={message.private}>
<TextMessage content={message.content} />
</MessageBubble>

Shows when other users are typing in the conversation.

interface TypingIndicatorProps {
users: User[];
}
<TypingIndicator users={typingUsers} />

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

Text messages automatically detect and highlight:

  • URLs (https://, http://)
  • Email addresses
  • Phone numbers

Markdown rendering supports:

  • Bold text
  • Italic text
  • Code blocks
  • Lists (ordered and unordered)
  • Blockquotes
  • Images lazy-loaded with placeholders
  • Videos show thumbnails, load on tap
  • Large messages truncated with “Read more” option
  • Virtualized list for smooth scrolling
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();
});
});