| name | cometchat-flutter-v6-messages |
| description | Use when implementing the messages screen with CometChat Flutter UIKit v6. Covers CometChatMessageList, CometChatMessageComposer, CometChatMessageHeader, MessageListBloc, MessageComposerBloc, SliverSpacing, keyboard-aware spacing, rich text toolbar, CometChatTextBubble, CometChatImageBubble, CometChatVideoBubble, CometChatAudioBubble, CometChatFileBubble, CometChatMessageBubble, bubble factories, message templates, send message, edit message, delete message, reply, thread, reactions, receipts, typing indicators, mentions, markdown formatting, text formatters, scroll to bottom, unread messages, mark as read, goToMessageId, message options, swipe to reply, smart replies, conversation starters, or resizeToAvoidBottomInset. Also use when the user asks about building a chat screen, message input, or message display.
|
| license | MIT |
| compatibility | cometchat_chat_uikit ^6.0.0-beta2; flutter_bloc ^8.1.0 |
| allowed-tools | shell, file-read, file-search, file-list, grep |
| metadata | {"author":"CometChat","version":"3.0.0","tags":"cometchat flutter messages composer header bubbles keyboard rich-text"} |
CometChat Flutter UIKit — Messages
The messages screen is composed of three components: CometChatMessageHeader, CometChatMessageList, and CometChatMessageComposer.
Complete Messages Screen
Scaffold(
resizeToAvoidBottomInset: false, // REQUIRED — composer handles keyboard internally
appBar: CometChatMessageHeader(
user: user,
group: group,
onBack: () => Navigator.pop(context),
),
body: Column(
children: [
Expanded(
child: CometChatMessageList(
user: user,
group: group,
textFormatters: [
CometChatMentionsFormatter(user: user, group: group),
MarkdownTextFormatter(),
CometChatUrlFormatter(),
CometChatPhoneNumberFormatter(),
CometChatEmailFormatter(),
],
),
),
CometChatMessageComposer(
user: user,
group: group,
textFormatters: [
CometChatMentionsFormatter(user: user, group: group),
MarkdownTextFormatter(),
CometChatUrlFormatter(),
],
),
],
),
)
CometChatMessageList
Displays messages with SliverAnimatedList, O(1) lookups, and keyboard-aware spacing.
Key Props
| Prop | Type | Purpose |
|---|
user / group | User? / Group? | Target conversation (one required) |
goToMessageId | int? | Jump to specific message on load |
startFromUnreadMessages | bool | Start from unread position |
hideDeletedMessages | bool | Hide deleted message placeholders |
disableReceipts | bool | Hide read/delivered receipts |
disableReactions | bool | Hide reaction bar |
enableSwipeToReply | bool | Swipe gesture for reply |
hideDateSeparator | bool | Hide date headers |
textFormatters | List<CometChatTextFormatter> | Formatters for message text |
onThreadRepliesClick | Function(BaseMessage, BuildContext, {template}) | Thread navigation callback |
MessageListBloc Events
| Event | Purpose |
|---|
LoadMessages(conversationWith, conversationType) | Initial load |
LoadOlderMessages | Scroll up pagination |
LoadNewerMessages | Scroll down pagination |
MessageReceived(message) | Real-time incoming message |
MessageEdited(message) | Real-time edit |
MessageDeleted(message) | Real-time delete |
JumpToMessage(messageId) | Scroll to specific message |
MarkMessageAsRead(message) | Mark as read |
MarkMessageAsUnread(message) | Mark as unread |
MessageListState
MessageListState(
status: MessageListStatus.loaded, // initial, loading, loaded, empty, error
messages: [...],
isLoadingOlder: false,
isLoadingNewer: false,
hasMoreOlder: true,
hasMoreNewer: false,
unreadCount: 5,
unreadMessageAnchor: message,
)
CometChatMessageComposer
Rich text input with formatting toolbar, attachments, mentions, and audio recording.
Key Props
| Prop | Type | Purpose |
|---|
user / group | User? / Group? | Target conversation |
disableTypingEvents | bool | Stop sending typing indicators |
hideVoiceRecordingButton | bool | Hide audio recorder |
hideSendButton | bool | Hide send button |
hideAttachmentButton | bool | Hide attachment picker |
hideStickersButton | bool | Hide sticker panel |
disableMentions | bool | Disable @mentions |
hideBottomSafeArea | bool | Hide bottom safe area padding |
textFormatters | List<CometChatTextFormatter> | Text formatters |
Rich Text Formatting
The composer uses a WYSIWYG system (not the clean architecture module):
RichTextEditingController — span tracking, markdown rendering, format application
SegmentComposerController — multi-segment (normal text + code blocks)
- Toolbar buttons dispatch through
cometchat_message_composer.dart
buildWhen Optimization
The composer uses buildWhen to prevent rebuilds during keyboard animation:
BlocConsumer<MessageComposerBloc, MessageComposerState>(
buildWhen: (previous, current) =>
previous.isEditMode != current.isEditMode ||
previous.isReplyMode != current.isReplyMode ||
previous.isRecordingMode != current.isRecordingMode,
// ...
)
CometChatMessageHeader
Shows user/group info, typing indicators, and optional call buttons.
CometChatMessageHeader(
user: user,
group: group,
onBack: () => Navigator.pop(context),
hideVideoCallButton: false,
hideVoiceCallButton: false,
usersStatusVisibility: true,
trailingView: (user, group, ctx) => [
IconButton(icon: Icon(Icons.info_outline), onPressed: () { /* ... */ }),
],
messageHeaderStyle: CometChatMessageHeaderStyle(
backgroundColor: colorPalette.background1,
),
)
Keyboard-Aware Spacing
SliverSpacing handles keyboard interaction:
- At bottom: keyboard pushes list up (normal behavior)
- Scrolled up: list stays still, only composer moves
- Safe area: only added when keyboard is closed
This is why resizeToAvoidBottomInset: false is mandatory.
Message Bubbles
| Type | Widget | Key Features |
|---|
| Text | CometChatTextBubble | Rich text, links, markdown |
| Image | CometChatImageBubble | Local/network, GIF, HEIC fallback |
| Video | CometChatVideoBubble | Thumbnail, play overlay |
| Audio | CometChatAudioBubble | Waveform, play/pause, duration |
| File | CometChatFileBubble | Type icon, download, size |
| Deleted | CometChatDeletedBubble | "Message was deleted" |
All bubble widgets accept optional colorPalette, spacing, typography params for the hybrid theme caching pattern.
Sending Messages
// Text message
await CometChatUIKit.sendTextMessage(
TextMessage(
text: 'Hello!',
receiverUid: user.uid,
receiverType: ReceiverTypeConstants.user,
),
);
// Media message
await CometChatUIKit.sendMediaMessage(
MediaMessage(
file: '/path/to/image.jpg',
type: MessageTypeConstants.image,
receiverUid: user.uid,
receiverType: ReceiverTypeConstants.user,
),
);
// Custom message
await CometChatUIKit.sendCustomMessage(
CustomMessage(
type: 'location',
receiverUid: user.uid,
receiverType: ReceiverTypeConstants.user,
customData: {'latitude': 37.7749, 'longitude': -122.4194},
),
);
Thread Replies
CometChatMessageList(
onThreadRepliesClick: (message, ctx, {template}) {
Navigator.push(context, MaterialPageRoute(
builder: (_) => Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: [
CometChatThreadedHeader(
parentMessage: message,
loggedInUser: CometChatUIKit.loggedInUser!,
),
Expanded(child: CometChatMessageList(
user: user, group: group,
parentMessageId: message.id,
)),
CometChatMessageComposer(
user: user, group: group,
parentMessageId: message.id,
),
],
),
),
));
},
)
Gotchas
Anti-Patterns
// ❌ WRONG — missing resizeToAvoidBottomInset
Scaffold(
body: Column(children: [
Expanded(child: CometChatMessageList(user: user)),
CometChatMessageComposer(user: user),
]),
)
// ❌ WRONG — thread screen with resizeToAvoidBottomInset: true
Scaffold(
resizeToAvoidBottomInset: true, // Double compensation!
body: Column(children: [
CometChatThreadedHeader(parentMessage: message, loggedInUser: user),
Expanded(child: CometChatMessageList(user: user, parentMessageId: message.id)),
CometChatMessageComposer(user: user, parentMessageId: message.id),
]),
)
// ✅ CORRECT — both messages and thread screens
Scaffold(
resizeToAvoidBottomInset: false,
body: Column(children: [
Expanded(child: CometChatMessageList(user: user)),
CometChatMessageComposer(user: user),
]),
)
// ❌ WRONG — passing immutable widget params to UIKit components
CometChatMessageList(user: widget.user) // Stale after block/unblock
// ✅ CORRECT — mutable state copy
late User? _user = widget.user;
// Update _user from SDK listeners
CometChatMessageList(user: _user)
// ❌ WRONG — different formatters for list and composer
CometChatMessageList(textFormatters: [MarkdownTextFormatter()])
CometChatMessageComposer(textFormatters: []) // Inconsistent rendering
// ✅ CORRECT — same formatters
final formatters = [CometChatMentionsFormatter(user: user), MarkdownTextFormatter()];
CometChatMessageList(textFormatters: formatters)
CometChatMessageComposer(textFormatters: formatters)
Checklist