Skillquality 0.46

cometchat-flutter-v6-messages

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, CometChat

Price
free
Protocol
skill
Verified
no

What it does

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

PropTypePurpose
user / groupUser? / Group?Target conversation (one required)
goToMessageIdint?Jump to specific message on load
startFromUnreadMessagesboolStart from unread position
hideDeletedMessagesboolHide deleted message placeholders
disableReceiptsboolHide read/delivered receipts
disableReactionsboolHide reaction bar
enableSwipeToReplyboolSwipe gesture for reply
hideDateSeparatorboolHide date headers
textFormattersList<CometChatTextFormatter>Formatters for message text
onThreadRepliesClickFunction(BaseMessage, BuildContext, {template})Thread navigation callback

MessageListBloc Events

EventPurpose
LoadMessages(conversationWith, conversationType)Initial load
LoadOlderMessagesScroll up pagination
LoadNewerMessagesScroll 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

PropTypePurpose
user / groupUser? / Group?Target conversation
disableTypingEventsboolStop sending typing indicators
hideVoiceRecordingButtonboolHide audio recorder
hideSendButtonboolHide send button
hideAttachmentButtonboolHide attachment picker
hideStickersButtonboolHide sticker panel
disableMentionsboolDisable @mentions
hideBottomSafeAreaboolHide bottom safe area padding
textFormattersList<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

TypeWidgetKey Features
TextCometChatTextBubbleRich text, links, markdown
ImageCometChatImageBubbleLocal/network, GIF, HEIC fallback
VideoCometChatVideoBubbleThumbnail, play overlay
AudioCometChatAudioBubbleWaveform, play/pause, duration
FileCometChatFileBubbleType icon, download, size
DeletedCometChatDeletedBubble"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

  • Forgetting resizeToAvoidBottomInset: false causes double keyboard compensation — the most common bug when integrating the messages screen. This applies to thread screens too — any Scaffold containing a CometChatMessageComposer must set it to false.
  • textFormatters should be the same list for both CometChatMessageList and CometChatMessageComposer to ensure consistent rendering.
  • The rich text system has 3 implementations but only WYSIWYG is active at runtime. Bug fixes go in rich_text_editing_controller.dart, not the clean architecture module.
  • goToMessageId loads messages around that ID, not from the beginning. The list may not have older messages loaded.
  • Keep mutable _user/_group copies in your State class and update them from SDK listeners. Passing widget.user/widget.group directly means stale data after block/kick events.
  • The CometChat SDK has an Action class (a BaseMessage subclass used in group events like kick/ban/scope-change). It conflicts with Flutter's built-in Action widget. If your messages screen uses SDK listener mixins that reference Action, use an import alias:
    import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart' as cc;
    // Then use: cc.Action instead of Action
    
    This is especially common when mixing GroupListener into a messages screen State class.

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

  • Scaffold has resizeToAvoidBottomInset: false
  • Both list and composer have matching textFormatters
  • Mutable _user/_group state copies, not widget.user/widget.group
  • onThreadRepliesClick navigates to thread screen with parentMessageId
  • Thread screen Scaffold also has resizeToAvoidBottomInset: false (same rule as messages screen)
  • SDK listeners update _user/_group for block/kick/scope changes
  • Colors from CometChatThemeHelper, cached in didChangeDependencies()
  • If using SDK listener mixins with Action, import UIKit as cc to avoid Flutter name conflict

Capabilities

skillsource-cometchatskill-cometchat-flutter-v6-messagestopic-agent-skillstopic-ai-agenttopic-chattopic-claude-codetopic-cometchattopic-cursortopic-messagingtopic-nextjstopic-reacttopic-react-nativetopic-ui-kit

Install

Quality

0.46/ 1.00

deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 27 github stars · SKILL.md body (10,672 chars)

Provenance

Indexed fromgithub
Enriched2026-05-18 19:04:51Z · deterministic:skill-github:v1 · v1
First seen2026-05-07
Last seen2026-05-18

Agent access