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

# Conversations

> Display CometChat Flutter UI Kit conversations with real-time updates for messages, typing indicators, read receipts, and presence.

<Accordion title="AI Integration Quick Reference">
  | Field | Value |
  | - | - |
  | Component | `CometChatConversations` |
  | Package | `cometchat_chat_uikit` |
  | Import | `import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';` |
  | Purpose | Display CometChat Flutter UI Kit conversations with real-time updates for messages, typing indicators, read receipts, and presence. |
  | Data props | `conversationsRequestBuilder` |
  | Actions | `onSelection` · `onBack` · `onItemTap` · `onItemLongPress` · `onLoad` · `onEmpty` · `onError` · `onSearchTap` — [details](#actions-and-events) |
  | View slots | `subtitleView` · `listItemView` · `emptyStateView` · `errorStateView` · `trailingView` · `loadingStateView` · `leadingView` · `titleView` — [details](#custom-view-slots) |
  | Styling | `conversationsStyle` — 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. |
  | Stitching | Tap a conversation to open a message view built from `CometChatMessageHeader` + `CometChatMessageList` + `CometChatMessageComposer`. |
  | Prerequisites | `CometChatUIKit` initialised and a user logged in. |
  | Full props | [71 props](#functionality) |
</Accordion>

`CometChatConversations` renders a scrollable list of recent conversations with real-time updates for new messages, typing indicators, read receipts, and user presence.

***

## Where It Fits

`CometChatConversations` is a list component. It renders recent conversations and emits the selected `Conversation` via `onItemTap`. Wire it to `CometChatMessageHeader`, `CometChatMessageList`, and `CometChatMessageComposer` to build a standard chat layout.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      onItemTap: (conversation) {
        final entity = conversation.conversationWith;
        if (entity is User) {
          navigateToUserChat(entity);
        } else if (entity is Group) {
          navigateToGroupChat(entity);
        }
      },
    )
    ```
  </Tab>
</Tabs>

***

## Quick Start

Using Navigator:

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

Embedding as a widget:

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

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

***

## Filtering Conversations

Pass a `ConversationsRequestBuilder` to control what loads:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      conversationsRequestBuilder: ConversationsRequestBuilder()
        ..conversationType = "user"
        ..limit = 10,
    )
    ```
  </Tab>
</Tabs>

### Filter Recipes

| Recipe | Builder property |
| - | - |
| Only user conversations | `..conversationType = "user"` |
| Only group conversations | `..conversationType = "group"` |
| Limit per page | `..limit = 10` |
| With tags | `..tags = ["vip"]` and `..withTags = true` |
| With user and group tags | `..withUserAndGroupTags = true` |

***

## Actions and Events

### Callback Methods

#### `onItemTap`

Fires when a conversation row is tapped. Primary navigation hook.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      onItemTap: (conversation) {
        // Navigate to chat screen
      },
    )
    ```
  </Tab>
</Tabs>

#### `onItemLongPress`

Fires when a conversation row is long-pressed. By default shows a delete overlay (when `deleteConversationOptionVisibility` is true).

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      onItemLongPress: (conversation) {
        // Custom long press behavior
      },
    )
    ```
  </Tab>
</Tabs>

#### `onBack`

Fires when the user presses the back button in the app bar.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      onBack: () {
        Navigator.pop(context);
      },
    )
    ```
  </Tab>
</Tabs>

#### `onSelection`

Fires when conversations are selected/deselected in multi-select mode.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      selectionMode: SelectionMode.multiple,
      onSelection: (selectedConversations) {
        // Handle selected conversations
      },
    )
    ```
  </Tab>
</Tabs>

#### `onError`

Fires on internal errors (network failure, auth issue, SDK exception).

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

#### `onLoad`

Fires when the list is successfully fetched and loaded.

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

#### `onEmpty`

Fires when the list is empty after loading.

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

### Global Events

The component emits events via `CometChatConversationEvents` that can be subscribed to from anywhere:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    class _YourScreenState extends State<YourScreen> with CometChatConversationEventListener {

      @override
      void initState() {
        super.initState();
        CometChatConversationEvents.addConversationListListener("listenerId", this);
      }

      @override
      void dispose() {
        CometChatConversationEvents.removeConversationListListener("listenerId");
        super.dispose();
      }

      @override
      void ccConversationDeleted(Conversation conversation) {
        // Handle conversation deleted
      }
    }
    ```
  </Tab>
</Tabs>

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

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

| SDK Listener | Internal behavior |
| - | - |
| `onTextMessageReceived` / `onMediaMessageReceived` / `onCustomMessageReceived` | Moves conversation to top, updates last message and unread count |
| `onTypingStarted` / `onTypingEnded` | Shows/hides typing indicator in subtitle |
| `onMessagesDelivered` / `onMessagesRead` | Updates receipt indicators |
| `onUserOnline` / `onUserOffline` | Updates presence status dot |
| `onGroupMemberJoined` / `onGroupMemberLeft` / `onGroupMemberKicked` / `onGroupMemberBanned` | Updates group conversation metadata |
| Connection reconnected | Triggers silent refresh to sync missed messages |

***

## Functionality

| Property | Type | Default | Description |
| - | - | - | - |
| `conversationsProtocol` | `ConversationsBuilderProtocol?` | `null` | `conversationsProtocol` Request builder protocol to fetch conversations. |
| `subtitleView` | `Widget? Function(BuildContext context, Conversation conversation)?` | `null` | `subtitleView` to set subtitle for each conversation |
| `listItemView` | `Widget Function(Conversation conversation)?` | `null` | `listItemView` set custom view for each conversation |
| `conversationsStyle` | `CometChatConversationsStyle` | `const CometChatConversationsStyle()` | `conversationsStyle` sets style |
| `scrollController` | `ScrollController?` | `null` | `scrollController` to handle scrolling behavior. |
| `backButton` | `Widget?` | `null` | `backButton` back button |
| `showBackButton` | `bool` | `false` | Toggle back button |
| `selectionMode` | `SelectionMode?` | `null` | Enable selection mode (`single` or `multiple`) |
| `onSelection` | `Function(List<Conversation>? list)?` | `null` | `onSelection` function will be performed |
| `title` | `String?` | `null` | Custom app bar title |
| `conversationsRequestBuilder` | `ConversationsRequestBuilder?` | `null` | `conversationsRequestBuilder` Request builder to fetch conversations. |
| `hideError` | `bool?` | `null` | `hideError` toggle visibility of error dialog |
| `emptyStateView` | `WidgetBuilder?` | `null` | `emptyStateView` returns view fow empty state |
| `errorStateView` | `WidgetBuilder?` | `null` | `errorStateView` returns view fow error state |
| `listItemStyle` | `ListItemStyle?` | `null` | `listItemStyle` style for every list item |
| `trailingView` | `Widget? Function(Conversation conversation)?` | `null` | `trailingView` to set tailView for each conversation |
| `appBarOptions` | `List<Widget>?` | `null` | `appBarOptions` list of options to be visible in app bar |
| `usersStatusVisibility` | `bool?` | `true` | Show online/offline status indicator |
| `receiptsVisibility` | `bool?` | `true` | Show message receipts |
| `protectedGroupIcon` | `Widget?` | `null` | `protectedGroupIcon` provides icon in status indicator for protected group |
| `privateGroupIcon` | `Widget?` | `null` | `privateGroupIcon` provides icon in status indicator for private group |
| `readIcon` | `Widget?` | `null` | `readIcon` provides icon in read receipts if a message is read |
| `deliveredIcon` | `Widget?` | `null` | `deliveredIcon` provides icon in read receipts if a message is delivered |
| `sentIcon` | `Widget?` | `null` | `sentIcon` provides icon in read receipts if a message is sent |
| `activateSelection` | `ActivateSelection?` | `null` | `activateSelection` lets the widget know if conversations are allowed to be selected |
| `datePattern` | `String Function(Conversation conversation)?` | `null` | `datePattern` is used to generate customDateString for CometChatDate |
| `typingIndicatorText` | `String?` | `null` | `typingIndicatorText` if not null is visible instead of default text shown when another user is typing |
| `onBack` | `VoidCallback?` | `null` | `onBack` callback triggered on closing this screen |
| `onItemTap` | `Function(Conversation conversation)?` | `null` | `onItemTap` callback triggered on tapping a conversation item |
| `onItemLongPress` | `Function(Conversation conversation)?` | `null` | `onItemLongPress` callback triggered on pressing for long on a conversation item |
| `hideAppbar` | `bool?` | `false` | Toggle app bar visibility |
| `textFormatters` | `List<CometChatTextFormatter>?` | `null` | `textFormatters` is a list of text formatters for message bubbles with type text |
| `mentionAllLabel` | `String?` | `null` | `mentionAllLabel` is a String which is used to set a custom label for @all mentions |
| `mentionAllLabelId` | `String?` | `null` | `mentionAllLabelId` is a String which is used to set a custom label ID for @all mentions |
| `datePadding` | `EdgeInsets?` | `null` | `datePadding` provides padding for `CometChatDate` |
| `dateHeight` | `double?` | `null` | `dateHeight` provides height for `CometChatDate` |
| `dateBackgroundIsTransparent` | `bool?` | `null` | `dateBackgroundIsTransparent` controls the background of `CometChatDate` |
| `dateWidth` | `double?` | `null` | `dateWidth` provides width for `CometChatDate` |
| `badgeWidth` | `double?` | `null` | `badgeWidth` provides width for `CometChatBadge` |
| `badgeHeight` | `double?` | `null` | `badgeHeight` provides height for `CometChatBadge` |
| `badgePadding` | `EdgeInsetsGeometry?` | `null` | `badgePadding` provides padding to the widget |
| `statusIndicatorWidth` | `double?` | `null` | `statusIndicatorWidth` provides width to the status indicator |
| `statusIndicatorHeight` | `double?` | `null` | `statusIndicatorHeight` provides height to the status indicator |
| `statusIndicatorBorderRadius` | `BorderRadiusGeometry?` | `null` | `statusIndicatorBorderRadius` provides borderRadius to the status indicator |
| `avatarMargin` | `EdgeInsetsGeometry?` | `null` | `avatarMargin` provides margin to the widget |
| `avatarPadding` | `EdgeInsetsGeometry?` | `null` | `avatarPadding` provides padding to the widget |
| `avatarWidth` | `double?` | `null` | `avatarWidth` provides width to the widget |
| `avatarHeight` | `double?` | `null` | `avatarHeight` provides height to the widget |
| `deleteConversationOptionVisibility` | `bool?` | `true` | Show delete option on long press |
| `groupTypeVisibility` | `bool?` | `true` | Show group type icon on avatar |
| `setOptions` | `List<CometChatOption>? Function( Conversation conversation, ConversationsBloc bloc, BuildContext context, )?` | `null` | `setOptions` sets List of actions available on the long press of list item |
| `addOptions` | `List<CometChatOption>? Function( Conversation conversation, ConversationsBloc bloc, BuildContext context, )?` | `null` | `addOptions` adds into the current List of actions available on the long press of list item |
| `loadingStateView` | `WidgetBuilder?` | `null` | `loadingStateView` returns view fow loading state |
| `leadingView` | `Widget? Function(BuildContext context, Conversation conversation)?` | `null` | `leadingView` to set leading view for each conversation |
| `titleView` | `Widget? Function(BuildContext context, Conversation conversation)?` | `null` | `titleView` to set title view for each conversation |
| `controllerTag` | `String?` | `null` | `controllerTag` tag to create from , if this is passed its parent responsibility to close this |
| `onLoad` | `OnLoad<Conversation>?` | `null` | `onLoad` callback triggered when conversations are loaded successfully |
| `onEmpty` | `OnEmpty?` | `null` | `onEmpty` callback triggered when the conversations list is empty |
| `onError` | `OnError?` | `null` | `onError` callback triggered when the component encounters an error |
| `customSoundForMessages` | `String?` | `null` | Custom notification sound asset path |
| `disableSoundForMessages` | `bool?` | `false` | Disable message sounds |
| `submitIcon` | `Widget?` | `null` | `submitIcon` will override the default submit icon |
| `dateTimeFormatterCallback` | `DateTimeFormatterCallback?` | `null` | `dateTimeFormatterCallback` is a callback that can be used to format the date and time |
| `conversationsBloc` | `ConversationsBloc?` | `null` | `conversationsBloc` Optional external ConversationsBloc instance. |
| `routeObserver` | `RouteObserver<ModalRoute<void>>?` | `null` | `routeObserver` Optional RouteObserver to detect when this widget is not visible. |
| `hideSearch` | `bool?` | `null` | Toggle search bar |
| `searchReadOnly` | `bool` | `false` | Make search bar read-only (tap opens custom search) |
| `onSearchTap` | `GestureTapCallback?` | `null` | `onSearchTap` callback triggered on search box tap |
| `searchBoxIcon` | `Widget?` | `null` | `searchBoxIcon` search box prefix icon |
| `searchPadding` | `EdgeInsetsGeometry?` | `null` | `searchPadding` provides padding to the search |
| `searchContentPadding` | `EdgeInsetsGeometry?` | `null` | `searchContentPadding` provides padding to the search content |

***

## Custom View Slots

### Leading View

Replace the avatar / left section.

<Note>
  `Conversation.conversationWith` is an `AppEntity` (a `User` **or** a `Group`), so it has no `.name`.
  Narrow the type before reading a display name. The snippets below use this helper:

  ```dart theme={null}
  String _displayName(Conversation conversation) {
    final entity = conversation.conversationWith;
    return entity is User ? entity.name : (entity is Group ? entity.name : "");
  }
  ```
</Note>

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      leadingView: (context, conversation) {
        return CircleAvatar(
          child: Text(_displayName(conversation).isNotEmpty ? _displayName(conversation)[0] : ""),
        );
      },
    )
    ```
  </Tab>
</Tabs>

### Title View

Replace the name / title text.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      titleView: (context, conversation) {
        return Text(
          _displayName(conversation),
          style: TextStyle(fontWeight: FontWeight.bold),
        );
      },
    )
    ```
  </Tab>
</Tabs>

### Subtitle View

Replace the last message preview.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      subtitleView: (context, conversation) {
        final msg = conversation.lastMessage;
        if (msg is TextMessage) {
          return Text(msg.text, maxLines: 1, overflow: TextOverflow.ellipsis);
        }
        return Text("New conversation");
      },
    )
    ```
  </Tab>
</Tabs>

### Trailing View

Replace the timestamp / badge / right section.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      trailingView: (conversation) {
        if (conversation.unreadMessageCount > 0) {
          return Badge(label: Text("${conversation.unreadMessageCount}"));
        }
        return null;
      },
    )
    ```
  </Tab>
</Tabs>

### List Item View

Replace the entire list item row.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      listItemView: (conversation) {
        return ListTile(
          leading: CircleAvatar(
            child: Text(_displayName(conversation).isNotEmpty ? _displayName(conversation)[0] : ""),
          ),
          title: Text(_displayName(conversation)),
          subtitle: Text("Custom item"),
        );
      },
    )
    ```
  </Tab>
</Tabs>

### State Views

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      emptyStateView: (context) => Center(child: Text("No conversations yet")),
      errorStateView: (context) => Center(child: Text("Something went wrong")),
      loadingStateView: (context) => Center(child: CircularProgressIndicator()),
    )
    ```
  </Tab>
</Tabs>

***

## Menu Options

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    // Replace all options
    CometChatConversations(
      setOptions: (conversation, bloc, context) {
        return [
          CometChatOption(
            id: "delete",
            icon: AssetConstants.delete,
            title: "Delete",
            onClick: () {
              bloc.add(DeleteConversation(conversation.conversationId!));
            },
          ),
        ];
      },
    )

    // Append to defaults
    CometChatConversations(
      addOptions: (conversation, bloc, context) {
        return [
          CometChatOption(
            id: "archive",
            iconWidget: Icon(Icons.archive_outlined),
            title: "Archive",
            onClick: () {
              // Archive conversation
            },
          ),
        ];
      },
    )
    ```
  </Tab>
</Tabs>

***

## Common Patterns

### Minimal list — hide all chrome

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      hideAppbar: true,
      hideSearch: true,
    )
    ```
  </Tab>
</Tabs>

### Users-only conversations

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      conversationsRequestBuilder: ConversationsRequestBuilder()
        ..conversationType = "user",
    )
    ```
  </Tab>
</Tabs>

### Custom date formatting

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      datePattern: (conversation) {
        final timestamp = conversation.updatedAt;
        return DateFormat('MMM d').format(DateTime.fromMillisecondsSinceEpoch(timestamp! * 1000));
      },
    )
    ```
  </Tab>
</Tabs>

***

## Advanced

### BLoC Access

Provide a custom `ConversationsBloc` to override behavior:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      conversationsBloc: CustomConversationsBloc(),
    )
    ```
  </Tab>
</Tabs>

### Extending ConversationsBloc

`ConversationsBloc` uses the `ListBase<Conversation>` mixin with override hooks for custom list behavior:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    class CustomConversationsBloc extends ConversationsBloc {
      @override
      void onItemAdded(Conversation item, List<Conversation> updatedList) {
        // Custom sorting — pinned conversations first
        final sorted = _sortWithPinnedFirst(updatedList);
        super.onItemAdded(item, sorted);
      }

      @override
      void onListReplaced(List<Conversation> previousList, List<Conversation> newList) {
        // Filter out blocked users on every list refresh
        final filtered = newList.where((c) => !isBlocked(c)).toList();
        super.onListReplaced(previousList, filtered);
      }
    }
    ```
  </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 |
| - | - |
| `LoadConversations({silent})` | Load initial conversations. `silent: true` keeps existing list visible during refresh. |
| `LoadMoreConversations()` | Load next page (pagination) |
| `RefreshConversations()` | Refresh the list |
| `DeleteConversation(conversationId)` | Delete via SDK and remove from list |
| `RemoveConversation(conversationId)` | Remove from list without SDK call |
| `SetActiveConversation(conversationId)` | Mark as active (suppresses unread count) |
| `UpdateConversation(conversationId, updatedConversation)` | Update with modified data |
| `ResetUnreadCount(conversationId)` | Reset unread count to 0 |

### Public BLoC Methods

| Method | Returns | Description |
| - | - | - |
| `getTypingNotifier(conversationId)` | `ValueNotifier<List<TypingIndicator>>` | Per-conversation typing notifier for isolated rebuilds |
| `getTypingIndicators(conversationId)` | `List<TypingIndicator>` | Current typing indicators for a conversation |

### Route Observer

Pass a `RouteObserver` to freeze rebuilds when another screen is pushed on top (prevents expensive rebuilds during keyboard animation):

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    // In your app
    final RouteObserver<ModalRoute<void>> routeObserver = RouteObserver<ModalRoute<void>>();

    MaterialApp(
      navigatorObservers: [routeObserver],
    )

    // Pass to conversations
    CometChatConversations(
      routeObserver: routeObserver,
    )
    ```
  </Tab>
</Tabs>

***

## Style

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    CometChatConversations(
      conversationsStyle: CometChatConversationsStyle(
        backgroundColor: Colors.white,
        avatarStyle: CometChatAvatarStyle(
          borderRadius: BorderRadius.circular(8),
          backgroundColor: Color(0xFFFBAA75),
        ),
        badgeStyle: CometChatBadgeStyle(
          backgroundColor: Color(0xFFF76808),
        ),
        receiptStyle: CometChatMessageReceiptStyle(),
        typingIndicatorStyle: CometChatTypingIndicatorStyle(),
        dateStyle: CometChatDateStyle(),
        mentionsStyle: CometChatMentionsStyle(),
        deleteConversationDialogStyle: CometChatConfirmDialogStyle(),
      ),
    )
    ```
  </Tab>
</Tabs>

### Style Properties

| Property | Description |
| - | - |
| `backgroundColor` | List background color |
| `avatarStyle` | Avatar appearance |
| `badgeStyle` | Unread badge appearance |
| `receiptStyle` | Read receipt icons |
| `typingIndicatorStyle` | Typing indicator text |
| `dateStyle` | Timestamp appearance |
| `mentionsStyle` | Mention highlight style |
| `deleteConversationDialogStyle` | Delete confirmation dialog |

See [Component Styling](/ui-kit/flutter/component-styling) for the full reference.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Users" icon="user" href="/ui-kit/flutter/users">
    Browse and search available users
  </Card>

  <Card title="Message List" icon="comments" href="/ui-kit/flutter/message-list">
    Display messages for a conversation
  </Card>

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

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.