> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-skills-v5-temp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Message List

> Scrollable list of messages for a conversation with real-time updates, reactions, threaded replies, and message actions.

<Accordion title="AI Integration Quick Reference">
  | Field                | Value                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
  | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | Component            | `CometChatMessageList`                                                                                                                                                                                                                                                                                                                                                                                                                                       |
  | Package              | `cometchat_chat_uikit`                                                                                                                                                                                                                                                                                                                                                                                                                                       |
  | Import               | `import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';`                                                                                                                                                                                                                                                                                                                                                                                           |
  | Purpose              | Scrollable list of messages for a conversation with real-time updates, reactions, threaded replies, and message actions.                                                                                                                                                                                                                                                                                                                                     |
  | Data props           | `user` · `group` · `messagesRequestBuilder` · `templates` · `addTemplate` · `parentMessageId` · `reactionsRequestBuilder`                                                                                                                                                                                                                                                                                                                                    |
  | Actions              | `onError` · `onLoad` · `onEmpty` · `onThreadRepliesClick` · `addMoreReactionTap` · `onReactionClick` · `onReactionLongPress` · `onReactionListItemClick` — [details](#actions-and-events)                                                                                                                                                                                                                                                                    |
  | View slots           | `headerView` · `footerView` · `loadingStateView` · `emptyStateView` · `errorStateView` · `emptyChatGreetingView` — [details](#custom-view-slots)                                                                                                                                                                                                                                                                                                             |
  | Styling              | `style` — the app `ThemeData` does not reach inside a kit widget, so scope colours here.                                                                                                                                                                                                                                                                                                                                                                     |
  | Layout               | Fills its parent — place it in an `Expanded` (or a sized box) inside a `Column`, or layout throws an unbounded-height error at render.                                                                                                                                                                                                                                                                                                                       |
  | Custom message types | Use `addTemplate:` — **never** `templates:`. `addTemplate` merges your `CometChatMessageTemplate` with the defaults **and** folds its type/category into the list's fetch + realtime filter; `templates` replaces the default set and only registers the bubble, so a custom type sends fine and **never appears**, with no error. A hand-rolled `MessagesRequestBuilder` does not help — the list always overrides `uid`/`guid`/`types`/`categories` on it. |
  | Stitching            | Pair with `CometChatMessageHeader` and `CometChatMessageComposer`, passing the same `user` or `group` to all three.                                                                                                                                                                                                                                                                                                                                          |
  | Prerequisites        | `CometChatUIKit` initialised and a user logged in.                                                                                                                                                                                                                                                                                                                                                                                                           |
  | Full props           | [88 props](#functionality)                                                                                                                                                                                                                                                                                                                                                                                                                                   |
</Accordion>

`CometChatMessageList` renders a scrollable list of messages for a conversation with real-time updates for new messages, edits, deletions, reactions, and threaded replies.

***

## Where It Fits

`CometChatMessageList` is a message display component. It requires either a `User` or `Group` object to fetch and render messages. Wire it with `CometChatMessageHeader` and `CometChatMessageComposer` to build a complete messaging layout.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
    )
    ```
  </Tab>
</Tabs>

***

## Quick Start

Using Navigator:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    Navigator.push(context, MaterialPageRoute(builder: (context) => CometChatMessageList(user: user)));
    ```
  </Tab>
</Tabs>

Embedding as a widget:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        body: SafeArea(
          child: CometChatMessageList(
            user: user, // or group: group
          ),
        ),
      );
    }
    ```
  </Tab>
</Tabs>

Prerequisites: CometChat SDK initialized with `CometChatUIKit.init()`, a user logged in, and the UI Kit dependency added.

<Warning>
  Simply adding the `MessageList` component to the layout will only display the loading indicator. You must supply a `User` or `Group` object to fetch messages.
</Warning>

***

## Filtering

Pass a `MessagesRequestBuilder` to control what loads:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      messagesRequestBuilder: MessagesRequestBuilder()
        ..uid = user.uid
        ..searchKeyword = "hello"
        ..limit = 30,
    )
    ```
  </Tab>
</Tabs>

<Note>
  The following parameters in `MessagesRequestBuilder` will always be altered inside the message list: UID, GUID, types, categories.
</Note>

***

## Actions and Events

### Callback Methods

#### `onThreadRepliesClick`

Fires when a user taps a threaded message bubble.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      onThreadRepliesClick: (message, context, {template}) {
        // Navigate to thread view
      },
    )
    ```
  </Tab>
</Tabs>

#### `onError`

Fires on internal errors.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      onError: (e) {
        debugPrint("Error: $e");
      },
    )
    ```
  </Tab>
</Tabs>

#### `onLoad`

Fires when the list is successfully fetched and loaded.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      onLoad: (messages) {
        debugPrint("Loaded ${messages.length}");
      },
    )
    ```
  </Tab>
</Tabs>

#### `onEmpty`

Fires when the list is empty after loading.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      onEmpty: () {
        debugPrint("No messages");
      },
    )
    ```
  </Tab>
</Tabs>

#### `onReactionClick`

Fires when a reaction pill is tapped.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      onReactionClick: (emoji, message) {
        // Handle reaction click
      },
    )
    ```
  </Tab>
</Tabs>

#### `onReactionLongPress`

Fires when a reaction pill is long-pressed.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      onReactionLongPress: (emoji, message) {
        // Handle reaction long press
      },
    )
    ```
  </Tab>
</Tabs>

### SDK Events (Real-Time, Automatic)

The component listens to SDK message events internally. No manual setup needed.

| SDK Listener                                                                   | Internal behavior                             |
| ------------------------------------------------------------------------------ | --------------------------------------------- |
| `onTextMessageReceived` / `onMediaMessageReceived` / `onCustomMessageReceived` | Inserts new message with animation            |
| `onMessageEdited`                                                              | Updates message in-place                      |
| `onMessageDeleted`                                                             | Removes or marks message as deleted           |
| `onMessagesDelivered` / `onMessagesRead`                                       | Updates receipt status via ValueNotifier      |
| `onTypingStarted` / `onTypingEnded`                                            | Updates typing indicator                      |
| `onMessageReactionAdded` / `onMessageReactionRemoved`                          | Updates reaction counts                       |
| Connection reconnected                                                         | Triggers silent sync to fetch missed messages |

***

## Functionality

| Property                       | Type                                                           | Default                                    | Description                                                                                                                                                                                                                          |
| ------------------------------ | -------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `user`                         | `User?`                                                        | `null`                                     | User for 1-on-1 conversation                                                                                                                                                                                                         |
| `group`                        | `Group?`                                                       | `null`                                     | Group for group conversation                                                                                                                                                                                                         |
| `messageListBloc`              | `MessageListBloc?`                                             | `null`                                     | Optional external `MessageListBloc` instance.                                                                                                                                                                                        |
| `messagesRequestBuilder`       | `MessagesRequestBuilder?`                                      | `null`                                     | Request builder used to fetch the message list. Note the widget always overrides `uid`, `guid`, `types` and `categories` on whatever builder you pass.                                                                               |
| `templates`                    | `List<CometChatMessageTemplate>?`                              | `null`                                     | REPLACES the default message templates. For a message type of your own use `addTemplate` instead — `templates` only registers the bubble and does not widen the fetch filter, so a custom type sends successfully and never appears. |
| `addTemplate`                  | `List<CometChatMessageTemplate>?`                              | `null`                                     | Merges templates with the defaults. Each template's type and category are also folded into the list's fetch and realtime filter, which is what makes a custom message type actually render.                                          |
| `parentMessageId`              | `int?`                                                         | `null`                                     | Parent message ID for thread replies                                                                                                                                                                                                 |
| `withParent`                   | `bool`                                                         | `true`                                     | Whether to include the parent message in thread results (default: false). Set to true for AI chat history where the parent message should appear in the list.                                                                        |
| `hideDeletedMessages`          | `bool`                                                         | `false`                                    | Hide deleted messages entirely                                                                                                                                                                                                       |
| `disableSoundForMessages`      | `bool`                                                         | `false`                                    | Disable message sounds                                                                                                                                                                                                               |
| `disableReceipts`              | `bool`                                                         | `false`                                    | Disable read/delivery receipts                                                                                                                                                                                                       |
| `hideReplies`                  | `bool`                                                         | `true`                                     | Hide thread replies in main conversation                                                                                                                                                                                             |
| `headerView`                   | `HeaderFooterBuilder?`                                         | `null`                                     | Custom header view displayed above the message list. **Validates: Requirements 13.2**                                                                                                                                                |
| `footerView`                   | `HeaderFooterBuilder?`                                         | `null`                                     | Custom footer view displayed below the message list. **Validates: Requirements 13.2**                                                                                                                                                |
| `loadingStateView`             | `WidgetBuilder?`                                               | `null`                                     | `loadingStateView` is a parameter used to show the loading state view in case of loading                                                                                                                                             |
| `emptyStateView`               | `WidgetBuilder?`                                               | `null`                                     | `emptyStateView` returns view fow empty state                                                                                                                                                                                        |
| `errorStateView`               | `WidgetBuilder?`                                               | `null`                                     | `errorStateView` is a parameter used to show the error state view in case of any error                                                                                                                                               |
| `emptyChatGreetingView`        | `WidgetBuilder?`                                               | `null`                                     | View shown in an empty conversation, in place of the generic empty state.                                                                                                                                                            |
| `style`                        | `CometChatMessageListStyle?`                                   | `null`                                     | Style configuration for the message list.                                                                                                                                                                                            |
| `scrollController`             | `ScrollController?`                                            | `null`                                     | Optional scroll controller                                                                                                                                                                                                           |
| `alignment`                    | `ChatAlignment`                                                | `ChatAlignment.standard`                   | Chat alignment setting                                                                                                                                                                                                               |
| `onError`                      | `OnError?`                                                     | `null`                                     | `onError` callback triggered in case any error happens when fetching data                                                                                                                                                            |
| `onLoad`                       | `OnLoad<BaseMessage>?`                                         | `null`                                     | Called once the first page of messages has loaded.                                                                                                                                                                                   |
| `onEmpty`                      | `OnEmpty?`                                                     | `null`                                     | `onEmpty` callback triggered when the list is empty                                                                                                                                                                                  |
| `stateCallBack`                | `Function(CometChatMessageListControllerProtocol controller)?` | `null`                                     | Exposes the widget's state so a host can drive it imperatively.                                                                                                                                                                      |
| `customSoundForMessages`       | `String?`                                                      | `null`                                     | `customSoundForMessages` set custom sound for messages                                                                                                                                                                               |
| `customSoundForMessagePackage` | `String?`                                                      | `null`                                     | `customSoundForMessagePackage` package name to show icon from                                                                                                                                                                        |
| `readIcon`                     | `Widget?`                                                      | `null`                                     | `readIcon` widget visible when readAt != null in `BaseMessage`. If blank will load default readIcon                                                                                                                                  |
| `deliveredIcon`                | `Widget?`                                                      | `null`                                     | `deliveredIcon` widget visible while deliveredAt != null in `BaseMessage`. If blank will load default deliveredIcon                                                                                                                  |
| `sentIcon`                     | `Widget?`                                                      | `null`                                     | `sentIcon` widget visible while sentAt != null and deliveredAt is null in `BaseMessage`. If blank will load default sentIcon                                                                                                         |
| `waitIcon`                     | `Widget?`                                                      | `null`                                     | `waitIcon` widget visible while sentAt and deliveredAt is null in `BaseMessage`. If blank will load default waitIcon                                                                                                                 |
| `avatarVisibility`             | `bool?`                                                        | `true`                                     | Toggle avatar visibility                                                                                                                                                                                                             |
| `enableMultipleAttachments`    | `bool`                                                         | `true`                                     | Render multi-attachment media messages as grouped per-type bubbles. See [Multiple Attachments](#multiple-attachments)                                                                                                                |
| `hideTimestamp`                | `bool?`                                                        | `null`                                     | Toggle timestamp visibility                                                                                                                                                                                                          |
| `datePattern`                  | `String Function(BaseMessage message)?`                        | `null`                                     | Builds the timestamp string shown on a bubble.                                                                                                                                                                                       |
| `dateSeparatorPattern`         | `String Function(DateTime dateTime)?`                          | `null`                                     | Builds the date string shown on the separator between days.                                                                                                                                                                          |
| `dateSeparatorStyle`           | `CometChatDateStyle?`                                          | `null`                                     | Style for the date separator shown between days.                                                                                                                                                                                     |
| `hideDateSeparator`            | `bool?`                                                        | `false`                                    | Hide date separators                                                                                                                                                                                                                 |
| `hideStickyDate`               | `bool?`                                                        | `false`                                    | Hide floating sticky date header                                                                                                                                                                                                     |
| `onThreadRepliesClick`         | `ThreadRepliesClick?`                                          | `null`                                     | Called when the thread-replies indicator on a bubble is tapped. Wire this to push your thread screen.                                                                                                                                |
| `hideThreadView`               | `bool?`                                                        | `null`                                     | When true, hides the thread-replies indicator on bubbles.                                                                                                                                                                            |
| `receiptsVisibility`           | `bool?`                                                        | `true`                                     | Toggle read receipts                                                                                                                                                                                                                 |
| `disableReactions`             | `bool?`                                                        | `false`                                    | Toggle reactions                                                                                                                                                                                                                     |
| `addReactionIcon`              | `Widget?`                                                      | `null`                                     | `addReactionIcon` sets custom icon for adding reaction                                                                                                                                                                               |
| `addMoreReactionTap`           | `Function(BaseMessage message)?`                               | `null`                                     | Called when the 'add reaction' affordance is tapped.                                                                                                                                                                                 |
| `favoriteReactions`            | `List<String>?`                                                | `null`                                     | `favoriteReactions` is a list of frequently used reactions                                                                                                                                                                           |
| `onReactionClick`              | `Function(String? emoji, BaseMessage message)?`                | `null`                                     | Called when an existing reaction chip is tapped.                                                                                                                                                                                     |
| `onReactionLongPress`          | `Function(String? emoji, BaseMessage message)?`                | `null`                                     | Called when an existing reaction chip is long-pressed.                                                                                                                                                                               |
| `onReactionListItemClick`      | `Function(String? reaction, BaseMessage? message)?`            | `null`                                     | Called when a row in the reaction list sheet is tapped.                                                                                                                                                                              |
| `reactionsRequestBuilder`      | `ReactionsRequestBuilder?`                                     | `null`                                     | Request builder used to fetch the reaction list for a message.                                                                                                                                                                       |
| `textFormatters`               | `List<CometChatTextFormatter>?`                                | `null`                                     | `textFormatters` is a list of `CometChatTextFormatter` that can be used to format text                                                                                                                                               |
| `additionalConfigurations`     | `AdditionalConfigurations?`                                    | `null`                                     | Configuration passed down to the bubble views this list renders.                                                                                                                                                                     |
| `disableMentions`              | `bool?`                                                        | `null`                                     | `disableMentions` disables mentions in the composer                                                                                                                                                                                  |
| `mentionAllLabel`              | `String?`                                                      | `null`                                     | `mentionAllLabel` is the label to display for @all mention (default: localized "Notify All")                                                                                                                                         |
| `mentionAllLabelId`            | `String?`                                                      | `null`                                     | `mentionAllLabelId` is the ID for @all mention (default: "all")                                                                                                                                                                      |
| `padding`                      | `EdgeInsetsGeometry?`                                          | `null`                                     | `padding` sets the padding for snackBar                                                                                                                                                                                              |
| `margin`                       | `EdgeInsetsGeometry?`                                          | `null`                                     | `margin` sets the margin for snackBar                                                                                                                                                                                                |
| `width`                        | `double?`                                                      | `null`                                     | `width` provides width to the widget                                                                                                                                                                                                 |
| `height`                       | `double?`                                                      | `null`                                     | `height` provides height to the widget                                                                                                                                                                                               |
| `hideCopyMessageOption`        | `bool?`                                                        | `false`                                    | `hideCopyMessageOption` This prop defines whether a user can copy message or not.                                                                                                                                                    |
| `hideDeleteMessageOption`      | `bool?`                                                        | `false`                                    | `hideDeleteMessageOption` This prop defines whether Delete Message option should be visible or not.                                                                                                                                  |
| `hideEditMessageOption`        | `bool?`                                                        | `false`                                    | `hideEditMessageOption` This prop defines whether Edit Message option should be visible or not.                                                                                                                                      |
| `hideGroupActionMessages`      | `bool?`                                                        | `false`                                    | Hide group action messages                                                                                                                                                                                                           |
| `hideMessageInfoOption`        | `bool?`                                                        | `false`                                    | `hideMessageInfoOption` This prop defines whether a user can fetch information about the message whether it's received or not.                                                                                                       |
| `hideMessagePrivatelyOption`   | `bool?`                                                        | `false`                                    | `hideMessagePrivatelyOption` This prop defines whether a user can privately message other member of the group or not.                                                                                                                |
| `hideReactionOption`           | `bool?`                                                        | `false`                                    | `hideReactionOption` This prop defines whether Reaction option should be visible or not.                                                                                                                                             |
| `hideReplyInThreadOption`      | `bool?`                                                        | `false`                                    | `hideReplyInThreadOption` This prop defines whether Reply In Thread option should be visible or not.                                                                                                                                 |
| `hideReplyOption`              | `bool?`                                                        | `false`                                    | `hideReplyOption` This prop defines whether the inline Reply option should be visible or not.                                                                                                                                        |
| `hideTranslateMessageOption`   | `bool?`                                                        | `false`                                    | `hideTranslateMessageOption` This prop defines whether Reply In Thread option should be visible or not.                                                                                                                              |
| `hideShareMessageOption`       | `bool?`                                                        | `false`                                    | `hideShareMessageOption` This prop defines whether share option should be visible or not.                                                                                                                                            |
| `hideModerationView`           | `bool?`                                                        | `null`                                     | When true, hides the moderation affordance on bubbles.                                                                                                                                                                               |
| `enableConversationStarters`   | `bool?`                                                        | `false`                                    | When true, shows AI conversation starters in an empty conversation.                                                                                                                                                                  |
| `enableSmartReplies`           | `bool?`                                                        | `false`                                    | When true, shows AI smart replies beneath the list.                                                                                                                                                                                  |
| `smartRepliesDelayDuration`    | `int?`                                                         | `10000`                                    | Milliseconds to wait after the last message before smart replies appear.                                                                                                                                                             |
| `smartRepliesKeywords`         | `List<String>?`                                                | `const [ 'what', 'when', 'why', 'who', '…` | Keywords in the last message that trigger smart replies.                                                                                                                                                                             |
| `suggestedMessages`            | `List<String>?`                                                | `null`                                     | Suggested messages offered in an empty conversation.                                                                                                                                                                                 |
| `hideSuggestedMessages`        | `bool?`                                                        | `false`                                    | When true, suppresses the suggested messages.                                                                                                                                                                                        |
| `emptyStateText`               | `String?`                                                      | `null`                                     | `emptyStateText` text to be displayed when the list is empty                                                                                                                                                                         |
| `errorStateText`               | `String?`                                                      | `null`                                     | `errorStateText` is a parameter used to show the error state text in case of any error                                                                                                                                               |
| `dateTimeFormatterCallback`    | `DateTimeFormatterCallback?`                                   | `null`                                     | `dateTimeFormatterCallback` is a callback that can be used to format the date and time                                                                                                                                               |
| `enableSwipeToReply`           | `bool`                                                         | `true`                                     | Enable swipe-to-reply gesture                                                                                                                                                                                                        |
| `goToMessageId`                | `int?`                                                         | `null`                                     | Scroll to a specific message after load                                                                                                                                                                                              |
| `showMarkAsUnreadOption`       | `bool`                                                         | `false`                                    | Show "Mark as Unread" in long-press options                                                                                                                                                                                          |
| `startFromUnreadMessages`      | `bool`                                                         | `false`                                    | Scroll to first unread on open                                                                                                                                                                                                       |
| `hideFlagOption`               | `bool`                                                         | `false`                                    | Hide the Flag/Report option from message long-press actions                                                                                                                                                                          |
| `flagReasonLocalizer`          | `String Function(String reasonId)?`                            | `null`                                     | Custom localizer that converts a flag-reason ID into a display string                                                                                                                                                                |
| `hideFlagRemarkField`          | `bool`                                                         | `false`                                    | Hide the optional remark/context text field in the flag dialog                                                                                                                                                                       |
| `loadLastAgentConversation`    | `bool`                                                         | `false`                                    | Loads the most recent existing agent conversation on start                                                                                                                                                                           |

\* One of `user` or `group` is required.

***

## Custom View Slots

### Header View

Custom view displayed at the top of the message list.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      headerView: (context, {user, group, parentMessageId}) {
        return Container(
          padding: EdgeInsets.all(8),
          child: Text("Pinned Messages"),
        );
      },
    )
    ```
  </Tab>
</Tabs>

### Footer View

Custom view displayed at the bottom of the message list.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      footerView: (context, {user, group, parentMessageId}) {
        return Container(
          padding: EdgeInsets.all(8),
          child: Text("End of messages"),
        );
      },
    )
    ```
  </Tab>
</Tabs>

### State Views

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      emptyStateView: (context) => Center(child: Text("No messages yet")),
      errorStateView: (context) => Center(child: Text("Something went wrong")),
      loadingStateView: (context) => Center(child: CircularProgressIndicator()),
      emptyChatGreetingView: (context) => Center(child: Text("Say hello!")),
    )
    ```
  </Tab>
</Tabs>

### Text Formatters (Mentions)

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      textFormatters: [
        CometChatMentionsFormatter(),
      ],
    )
    ```
  </Tab>
</Tabs>

### Message Templates

Override or extend message bubble rendering:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    // Replace all templates
    CometChatMessageList(
      user: user,
      templates: getCustomTemplates(),
    )

    // Add/override specific templates (merged with defaults)
    CometChatMessageList(
      user: user,
      addTemplate: [
        CometChatMessageTemplate(
          type: MessageTypeConstants.text,
          category: MessageCategoryConstants.message,
          contentView: (message, context, alignment, {additionalConfigurations}) {
            return Text((message as TextMessage).text,
              style: TextStyle(color: Colors.red));
          },
        ),
      ],
    )
    ```
  </Tab>
</Tabs>

See [Message Template](/ui-kit/flutter/message-template) for the full template structure.

***

## Multiple Attachments

A media message carrying several attachments renders with a dedicated per-type bubble: a **media grid** for images and videos, **inline player rows** for audio files, and a **connected card stack** for documents.

| Message type         | Bubble                  | Rendering                                                |
| -------------------- | ----------------------- | -------------------------------------------------------- |
| `image`              | `CometChatImagesBubble` | Grid — 1, 2, 3 or 2×2, with a `+N` tile past 4           |
| `video`              | `CometChatVideosBubble` | Grid with poster frames, a play badge and an `m:ss` chip |
| `audio` (files)      | `CometChatAudiosBubble` | Stacked player rows; collapses past 4                    |
| `audio` (voice note) | `CometChatAudioBubble`  | The classic waveform player                              |
| `file`               | `CometChatFilesBubble`  | Connected card stack with a "+N more" toggle             |

Tapping any image/video cell opens the full-screen media viewer, paged across the message's image, video and audio attachments.

<Note>
  A **voice note** always renders as the classic single audio bubble, whatever the flag below — it is single by nature. Only picked audio *files* use the multi-attachment bubble.
</Note>

A message always carries attachments of a single kind, so each one renders with the bubble for that kind. Picking a mix — say three photos and a PDF — sends an `image` message and a `file` message: the photos render as a grid, the PDF as a card. They share a `batchId` and group as described below.

### Grouping

Messages produced by one send share `batchId`, `batchIndex` and `batchSize` metadata, and the list presents them as one block:

* the avatar and sender name appear on the **first** message only
* the timestamp and receipt appear on the **last** message only
* reactions stay attached to their individual message
* the caption rides on the **last** message of the batch

Deleting one message of a batch takes it out of the group: it renders as a standalone delete bubble, and its neighbours treat it as a batch boundary.

### Enable or disable

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      enableMultipleAttachments: true, // default
    )
    ```
  </Tab>
</Tabs>

Set it to `false` to render the classic single-attachment bubbles (`CometChatImageBubble`, `CometChatVideoBubble`, `CometChatAudioBubble`, `CometChatFileBubble`) instead. Those bubbles are **deprecated** and remain only for that path.

You can also drive it per-template through `AdditionalConfigurations`:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    AdditionalConfigurations(enableMultipleAttachments: false)
    ```
  </Tab>
</Tabs>

### Styling

Each bubble has its own style class:

| Bubble                  | Style                        |
| ----------------------- | ---------------------------- |
| `CometChatImagesBubble` | `CometChatImagesBubbleStyle` |
| `CometChatVideosBubble` | `CometChatVideosBubbleStyle` |
| `CometChatAudiosBubble` | `CometChatAudiosBubbleStyle` |
| `CometChatFilesBubble`  | `CometChatFilesBubbleStyle`  |

Where a property has an equivalent on the old singular bubble it keeps the same name (`playIconColor`, `titleTextStyle`, `backgroundColor`…), so migrating is a rename of the class, not of every field. Grid-only knobs — `tileBorderRadius`, `gridSpacing`, `overflowScrimColor`, `captionTextStyle`, the duration chip and the "+N more" toggle — have no old counterpart.

<Warning>
  These bubbles are styled **only** through theme extensions. The per-message-list slots — `AdditionalConfigurations.imageBubbleStyle` and `CometChatIncoming/OutgoingMessageBubbleStyle.imageBubbleStyle` — still target the **deprecated** singular bubbles and are ignored while `enableMultipleAttachments` is `true`. Move that styling into the theme.
</Warning>

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    MaterialApp(
      theme: ThemeData(
        extensions: const [
          CometChatImagesBubbleStyle(gridSpacing: 3, tileBorderRadius: 8),
          CometChatVideosBubbleStyle(showVideoDuration: true),
          CometChatFilesBubbleStyle(titleTextStyle: TextStyle(fontSize: 15)),
        ],
      ),
    )
    ```
  </Tab>
</Tabs>

To stage and send multiple attachments, see [Message Composer](/ui-kit/flutter/message-composer#multiple-attachments).

***

## Message Option Visibility

| Property                     | Default | Description              |
| ---------------------------- | ------- | ------------------------ |
| `hideCopyMessageOption`      | `false` | Hide "Copy Message"      |
| `hideDeleteMessageOption`    | `false` | Hide "Delete Message"    |
| `hideEditMessageOption`      | `false` | Hide "Edit Message"      |
| `hideMessageInfoOption`      | `false` | Hide "Message Info"      |
| `hideMessagePrivatelyOption` | `false` | Hide "Message Privately" |
| `hideReactionOption`         | `false` | Hide "Reaction"          |
| `hideReplyInThreadOption`    | `false` | Hide "Reply in Thread"   |
| `hideTranslateMessageOption` | `false` | Hide "Translate Message" |
| `hideShareMessageOption`     | `false` | Hide "Share Message"     |
| `hideModerationView`         | `null`  | Hide moderation view     |

***

## Common Patterns

### Thread replies view

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      parentMessageId: parentMessage.id,
    )
    ```
  </Tab>
</Tabs>

### Jump to a specific message

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      goToMessageId: 12345,
    )
    ```
  </Tab>
</Tabs>

### Start from unread messages

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      startFromUnreadMessages: true,
    )
    ```
  </Tab>
</Tabs>

### Load last agent conversation

Resume the most recent AI agent conversation on start:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      loadLastAgentConversation: true,
    )
    ```
  </Tab>
</Tabs>

### Flag / Report a message

Flag/report is available by default from the message long-press menu. Toggle its visibility and customize the dialog:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      // hide the Flag option entirely
      hideFlagOption: false,
      // hide the optional "Remark" text field in the flag dialog
      hideFlagRemarkField: false,
      // localize reason IDs to your own display strings
      flagReasonLocalizer: (reasonId) {
        switch (reasonId) {
          case 'spam':
            return 'Spam or unsolicited';
          case 'inappropriate':
            return 'Inappropriate content';
          default:
            return reasonId;
        }
      },
    )
    ```
  </Tab>
</Tabs>

### Mark a message as unread

Expose the "Mark as Unread" option in the long-press menu:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      showMarkAsUnreadOption: true,
    )
    ```
  </Tab>
</Tabs>

***

## Advanced

### BLoC Access

Provide a custom `MessageListBloc` to override behavior:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      messageListBloc: CustomMessageListBloc(user: user),
    )
    ```
  </Tab>
</Tabs>

### Extending MessageListBloc

`MessageListBloc` uses the `ListBase<BaseMessage>` mixin with override hooks:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    class CustomMessageListBloc extends MessageListBloc {
      CustomMessageListBloc({required User user}) : super(user: user);

      @override
      void onItemAdded(BaseMessage item, List<BaseMessage> updatedList) {
        // Custom logic when a message is added
        super.onItemAdded(item, updatedList);
      }
    }
    ```
  </Tab>
</Tabs>

For `ListBase` override hooks (`onItemAdded`, `onItemRemoved`, `onItemUpdated`, `onListCleared`, `onListReplaced`), see [BLoC & Data — ListBase Hooks](/ui-kit/flutter/customization-bloc-data#listbase-hooks).

### Public BLoC Events

| Event                                                | Description                       |
| ---------------------------------------------------- | --------------------------------- |
| `LoadMessages(conversationWith, conversationType)`   | Load initial messages             |
| `LoadOlderMessages()`                                | Load older messages (scroll up)   |
| `LoadNewerMessages()`                                | Load newer messages (scroll down) |
| `RefreshMessages()`                                  | Refresh from the latest           |
| `SyncMessages()`                                     | Silently sync missed messages     |
| `JumpToMessage(messageId)`                           | Jump to a specific message        |
| `AddReaction(message, reaction)`                     | Add a reaction                    |
| `RemoveReaction(message, reaction)`                  | Remove a reaction                 |
| `MarkMessageAsRead(message)`                         | Mark a message as read            |
| `MarkMessageAsUnread(...)`                           | Mark a message as unread          |
| `LoadFromUnread(conversationWith, conversationType)` | Load from first unread message    |

### Public BLoC Methods

#### O(1) Lookup Methods

| Method                         | Returns        | Description                                   |
| ------------------------------ | -------------- | --------------------------------------------- |
| `findMessageIndex(messageId)`  | `int?`         | Find message index by ID                      |
| `findMessageIndexByMuid(muid)` | `int?`         | Find message index by muid (pending messages) |
| `findMessage(messageId)`       | `BaseMessage?` | Get message by ID                             |
| `findMessageByMuid(muid)`      | `BaseMessage?` | Get message by muid                           |

#### ValueNotifier Accessors (Isolated Rebuilds)

| Method                                         | Returns                                | Description                                |
| ---------------------------------------------- | -------------------------------------- | ------------------------------------------ |
| `getReceiptNotifier(messageId)`                | `ValueNotifier<MessageReceiptStatus>`  | Per-message receipt status notifier        |
| `getReceiptNotifierForMessage(message)`        | `ValueNotifier<MessageReceiptStatus>`  | Receipt notifier handling both ID and muid |
| `getTypingNotifier(conversationId)`            | `ValueNotifier<List<TypingIndicator>>` | Per-conversation typing notifier           |
| `getThreadReplyCountNotifier(parentMessageId)` | `ValueNotifier<int>`                   | Per-message thread reply count notifier    |

#### MessageReceiptStatus Enum

| Value       | Description                             |
| ----------- | --------------------------------------- |
| `sending`   | Message is being sent (id = 0)          |
| `sent`      | Message has been sent to server         |
| `delivered` | Message has been delivered to recipient |
| `read`      | Message has been read by recipient      |
| `error`     | Message failed to send                  |

### Operations Stream

The BLoC exposes an `operationsStream` consumed by `CometChatAnimatedMessageList` for smooth animations:

| Operation                                                | Description                |
| -------------------------------------------------------- | -------------------------- |
| `MessageOperation.insert(message, index)`                | Insert a single message    |
| `MessageOperation.insertAll(messages, index)`            | Insert a batch of messages |
| `MessageOperation.update(oldMessage, newMessage, index)` | Replace a message in-place |
| `MessageOperation.remove(message, index)`                | Remove a message           |
| `MessageOperation.set(messages)`                         | Replace the entire list    |

***

## Style

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatMessageList(
      user: user,
      style: CometChatMessageListStyle(
        backgroundColor: Color(0xFFFEEDE1),
        outgoingMessageBubbleStyle: CometChatOutgoingMessageBubbleStyle(
          backgroundColor: Color(0xFFF76808),
        ),
        incomingMessageBubbleStyle: CometChatIncomingMessageBubbleStyle(
          backgroundColor: Colors.white,
        ),
      ),
    )
    ```
  </Tab>
</Tabs>

See [Component Styling](/ui-kit/flutter/component-styling) and [Message Bubble Styling](/ui-kit/flutter/message-bubble-styling) for the full reference.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Message Header" icon="heading" href="/ui-kit/flutter/message-header">
    Display user/group info in the app bar
  </Card>

  <Card title="Message Composer" icon="pen-to-square" href="/ui-kit/flutter/message-composer">
    Rich input for sending messages
  </Card>

  <Card title="Message Template" icon="puzzle-piece" href="/ui-kit/flutter/message-template">
    Customize message bubble structure
  </Card>

  <Card title="Component Styling" icon="paintbrush" href="/ui-kit/flutter/component-styling">
    Detailed styling reference
  </Card>
</CardGroup>
