diff --git a/docs.json b/docs.json
index 416e94087..c4e8310c3 100644
--- a/docs.json
+++ b/docs.json
@@ -1676,6 +1676,119 @@
}
]
},
+ {
+ "version": "v6",
+ "groups": [
+ {
+ "group": " ",
+ "pages": [
+ "ui-kit/android/v6/overview",
+ {
+ "group": "Getting Started",
+ "pages": [
+ "ui-kit/android/v6/getting-started",
+ "ui-kit/android/v6/getting-started-kotlin",
+ "ui-kit/android/v6/getting-started-jetpack",
+ "ui-kit/android/v6/one-to-one-chat",
+ "ui-kit/android/v6/tab-based-chat",
+ "ui-kit/android/v6/calling-integration"
+ ]
+ },
+ {
+ "group": "Features",
+ "pages": [
+ {
+ "group": "Chat",
+ "pages": [
+ "ui-kit/android/v6/core-features",
+ "ui-kit/android/v6/extensions",
+ "ui-kit/android/v6/ai-features"
+ ]
+ },
+ "ui-kit/android/v6/call-features"
+ ]
+ },
+ {
+ "group": "Theming",
+ "pages": [
+ "ui-kit/android/v6/theme-introduction",
+ "ui-kit/android/v6/color-resources",
+ "ui-kit/android/v6/component-styling",
+ "ui-kit/android/v6/message-bubble-styling",
+ "ui-kit/android/v6/localize",
+ "ui-kit/android/v6/sound-manager"
+ ]
+ },
+ {
+ "group": "Customization",
+ "pages": [
+ "ui-kit/android/v6/customization-overview",
+ "ui-kit/android/v6/customization-view-slots",
+ "ui-kit/android/v6/customization-styles",
+ "ui-kit/android/v6/customization-viewmodel-data",
+ "ui-kit/android/v6/customization-events",
+ "ui-kit/android/v6/customization-state-views",
+ "ui-kit/android/v6/customization-text-formatters",
+ "ui-kit/android/v6/customization-menu-options"
+ ]
+ },
+ {
+ "group": "Components",
+ "pages": [
+ "ui-kit/android/v6/components-overview",
+ "ui-kit/android/v6/conversations",
+ "ui-kit/android/v6/conversation-message-view",
+ "ui-kit/android/v6/users",
+ "ui-kit/android/v6/groups",
+ "ui-kit/android/v6/group-members",
+ "ui-kit/android/v6/message-header",
+ "ui-kit/android/v6/message-list",
+ "ui-kit/android/v6/message-composer",
+ "ui-kit/android/v6/message-template",
+ "ui-kit/android/v6/threaded-messages-header",
+ "ui-kit/android/v6/incoming-call",
+ "ui-kit/android/v6/outgoing-call",
+ "ui-kit/android/v6/call-buttons",
+ "ui-kit/android/v6/call-logs"
+ ]
+ },
+ {
+ "group": "Reference",
+ "pages": [
+ "ui-kit/android/v6/methods",
+ "ui-kit/android/v6/events"
+ ]
+ },
+ {
+ "group": "Guides",
+ "pages": [
+ "ui-kit/android/v6/guide-overview",
+ "ui-kit/android/v6/guide-threaded-messages",
+ "ui-kit/android/v6/guide-block-unblock-user",
+ "ui-kit/android/v6/guide-new-chat",
+ "ui-kit/android/v6/guide-message-privately",
+ "ui-kit/android/v6/guide-call-log-details",
+ "ui-kit/android/v6/guide-group-chat",
+ "ui-kit/android/v6/custom-text-formatter-guide",
+ "ui-kit/android/v6/mentions-formatter-guide",
+ "ui-kit/android/v6/shortcut-formatter-guide"
+ ]
+ },
+ "ui-kit/android/v6/architecture-data-flow",
+ {
+ "group": "Migration Guide",
+ "pages": [
+ "ui-kit/android/v6/upgrading-from-v5"
+ ]
+ },
+ "ui-kit/android/v6/troubleshooting",
+ "ui-kit/android/v6/link/sample",
+ "ui-kit/android/v6/link/figma",
+ "ui-kit/android/v6/link/changelog"
+ ]
+ }
+ ]
+ },
{
"version": "v4",
"groups": [
diff --git a/ui-kit/android/overview.mdx b/ui-kit/android/overview.mdx
index 02fcb45af..462c31ccf 100644
--- a/ui-kit/android/overview.mdx
+++ b/ui-kit/android/overview.mdx
@@ -4,6 +4,10 @@ sidebarTitle: "Overview"
description: "Prebuilt Android Views for chat, voice, and video calling. Supports Kotlin and Java with XML and Jetpack Compose compatibility."
---
+
+🚀 **CometChat Android UI Kit v6 is now available!** It features a completely revamped component architecture and improved theming. [Try the v6 →](/ui-kit/android/v6/overview)
+
+
| Field | Value |
diff --git a/ui-kit/android/v2/overview.mdx b/ui-kit/android/v2/overview.mdx
index abc347ed9..2dd6587df 100644
--- a/ui-kit/android/v2/overview.mdx
+++ b/ui-kit/android/v2/overview.mdx
@@ -2,6 +2,10 @@
title: "Overview"
---
+
+🚀 **CometChat Android UI Kit v6 is now available!** It features a completely revamped component architecture and improved theming. [Try the v6 →](/ui-kit/android/v6/overview)
+
+
The CometChat Android Java UI Kit is developed to keep developers in mind and aims to reduce development efforts significantly.
diff --git a/ui-kit/android/v3/overview.mdx b/ui-kit/android/v3/overview.mdx
index 9e97d6ed9..c90cdfba6 100644
--- a/ui-kit/android/v3/overview.mdx
+++ b/ui-kit/android/v3/overview.mdx
@@ -2,6 +2,10 @@
title: "Overview"
---
+
+🚀 **CometChat Android UI Kit v6 is now available!** It features a completely revamped component architecture and improved theming. [Try the v6 →](/ui-kit/android/v6/overview)
+
+
Reference for Kotlin UI Kit.
diff --git a/ui-kit/android/v4/overview.mdx b/ui-kit/android/v4/overview.mdx
index 25c5e7a82..2b07e946b 100644
--- a/ui-kit/android/v4/overview.mdx
+++ b/ui-kit/android/v4/overview.mdx
@@ -2,6 +2,10 @@
title: "Overview"
---
+
+🚀 **CometChat Android UI Kit v6 is now available!** It features a completely revamped component architecture and improved theming. [Try the v6 →](/ui-kit/android/v6/overview)
+
+
With CometChat's UI Kit for Android, you can effortlessly build a chat app equipped with all the essential messaging features, along with customizable options tailored to your application requirements. This UI Kit comprises prebuilt UI components organized into smaller modules and components, each configurable to meet your specific needs.
diff --git a/ui-kit/android/v6/ai-features.mdx b/ui-kit/android/v6/ai-features.mdx
new file mode 100644
index 000000000..9af4bbabf
--- /dev/null
+++ b/ui-kit/android/v6/ai-features.mdx
@@ -0,0 +1,59 @@
+---
+title: "Smart Chat Features"
+description: "Integrate AI-powered conversation starters, smart replies, and conversation summaries into your Android chat app."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Packages | `com.cometchat:chat-uikit-android` (Java), `com.cometchat:chat-uikit-kotlin` (Kotlin XML), `com.cometchat:chat-uikit-compose` (Jetpack Compose) |
+| Required setup | `CometChatUIKit.init()` then `CometChatUIKit.login()` + AI features enabled in [CometChat Dashboard](/fundamentals/ai-user-copilot/overview) |
+| AI features | Conversation Starter, Smart Replies, Conversation Summary |
+| Key components | [Message List](/ui-kit/android/v6/message-list) (Conversation Starter), [Message Composer](/ui-kit/android/v6/message-composer) (Smart Replies, Summary) |
+| Activation | Enable each AI feature from the CometChat Dashboard — UI Kit auto-integrates them, no additional code required |
+| Related | [Core Features](/ui-kit/android/v6/core-features), [Extensions](/ui-kit/android/v6/extensions), [AI Agent Guide](/ui-kit/android/v6/guide-ai-agent) |
+
+
+
+CometChat's AI capabilities greatly enhance user interaction and engagement in your application. Here's how the Android UI Kit integrates these features.
+
+
+
+
+
+## Conversation Starter
+
+When a user initiates a new chat, the UI kit displays a list of suggested opening lines that users can select, making it easier for them to start a conversation. These suggestions are powered by CometChat's AI, which predicts contextually relevant conversation starter options.
+
+For a comprehensive understanding and guide on implementing and using the Conversation Starter, refer to our specific guide on the [Conversation Starter](/fundamentals/ai-user-copilot/conversation-starter).
+
+Once you have successfully activated the [Conversation Starter](/fundamentals/ai-user-copilot/conversation-starter) from your CometChat Dashboard, the feature will automatically be incorporated into the [MessageList](/ui-kit/android/v6/message-list) Component of UI Kits.
+
+
+
+
+
+## Smart Replies
+
+Smart Replies are AI-generated responses to messages. They can predict what a user might want to say next by analyzing the context of the conversation. This allows for quicker and more convenient responses, especially on mobile devices.
+
+For a comprehensive understanding and guide on implementing and using the Smart Replies, refer to our specific guide on the [Smart Replies](/fundamentals/ai-user-copilot/smart-replies).
+
+Once you have successfully activated the [Smart Replies](/fundamentals/ai-user-copilot/smart-replies) from your CometChat Dashboard, the feature will automatically be incorporated into the Action sheet of [MessageComposer](/ui-kit/android/v6/message-composer) Component of UI Kits.
+
+
+
+
+
+## Conversation Summary
+
+The Conversation Summary feature provides concise summaries of long conversations, allowing users to catch up quickly on missed chats. This feature uses natural language processing to determine the main points in a conversation.
+
+For a comprehensive understanding and guide on implementing and using the Conversation Summary, refer to our specific guide on the [Conversation Summary](/fundamentals/ai-user-copilot/conversation-summary).
+
+Once you have successfully activated the [Conversation Summary](/fundamentals/ai-user-copilot/conversation-summary) from your CometChat Dashboard, the feature will automatically be incorporated into the Action sheet of [MessageComposer](/ui-kit/android/v6/message-composer) Component of UI Kits.
+
+
+
+
diff --git a/ui-kit/android/v6/architecture-data-flow.mdx b/ui-kit/android/v6/architecture-data-flow.mdx
new file mode 100644
index 000000000..a40e18bc4
--- /dev/null
+++ b/ui-kit/android/v6/architecture-data-flow.mdx
@@ -0,0 +1,570 @@
+---
+title: "Architecture & Data Flow"
+description: "How chatuikit-core, chatuikit-jetpack, and chatuikit-kotlin modules are structured using Clean Architecture."
+---
+
+The UI Kit is split into three modules that follow Clean Architecture principles. `chatuikit-core` holds all business logic, data access, and state management. The UI modules (`chatuikit-jetpack` and `chatuikit-kotlin`) provide platform-specific rendering on top of the shared core.
+
+## Module Structure
+
+```
+┌─────────────────────────────────────────────────────────┐
+│ chatuikit-jetpack │ chatuikit-kotlin │
+│ (Jetpack Compose UI) │ (XML Views / ViewBinding) │
+│ Composables, Themes │ Custom Views, Adapters │
+└────────────────┬────────────┴──────────┬────────────────┘
+ │ │
+ │ depends on │
+ ▼ ▼
+┌─────────────────────────────────────────────────────────┐
+│ chatuikit-core │
+│ │
+│ domain/ │
+│ ├── usecase/ ← Business logic (single actions) │
+│ ├── repository/ ← Contracts (interfaces) │
+│ └── model/ ← Domain models │
+│ │
+│ data/ │
+│ ├── datasource/ ← SDK call wrappers (interface+impl) │
+│ └── repository/ ← Repository implementations │
+│ │
+│ viewmodel/ ← ViewModels (shared across UI) │
+│ state/ ← Sealed UIState classes │
+│ factory/ ← ViewModel factories (DI) │
+│ events/ ← CometChatEvents (SharedFlow bus) │
+│ constants/ ← Shared constants │
+│ formatter/ ← Rich text / markdown │
+│ mentions/ ← @mention detection │
+│ resources/ ← Localization, sound manager │
+│ utils/ ← Call utils, permissions, helpers │
+└──────────────────────────┬──────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────┐
+│ CometChat SDK │
+│ Chat SDK 4.x • Calls SDK 4.x │
+└─────────────────────────────────────────────────────────┘
+```
+
+## 4-Layer Architecture
+
+Every feature follows the same layered flow: **View → ViewModel → Repository → DataSource**.
+
+```
+View / Composable (chatuikit-kotlin or chatuikit-jetpack)
+ │
+ │ observes StateFlow
+ ▼
+ ViewModel (chatuikit-core)
+ │
+ │ calls UseCase
+ ▼
+ Repository (chatuikit-core)
+ │
+ │ calls DataSource
+ ▼
+ DataSource (chatuikit-core → CometChat SDK)
+```
+
+The ViewModel lives in `chatuikit-core` and is shared by both UI modules. This means the same `CometChatConversationsViewModel` drives both the XML View and the Composable — only the rendering layer differs.
+
+## Clean Architecture Layers (chatuikit-core)
+
+### Data Layer
+
+The data layer wraps the CometChat SDK behind interfaces, making it swappable and testable.
+
+**DataSource** — defines the contract for raw SDK operations:
+
+```kotlin
+// Interface (contract)
+interface ConversationsDataSource {
+ suspend fun fetchConversations(request: ConversationsRequest): List
+ suspend fun deleteConversation(conversationWith: String, conversationType: String): String
+ suspend fun markAsDelivered(message: BaseMessage)
+}
+
+// Implementation (calls CometChat SDK)
+class ConversationsDataSourceImpl : ConversationsDataSource {
+ override suspend fun fetchConversations(request: ConversationsRequest): List {
+ // Wraps CometChat.fetchConversations() in a coroutine
+ }
+}
+```
+
+Every feature has a DataSource pair: `ConversationsDataSource` / `ConversationsDataSourceImpl`, `UsersDataSource` / `UsersDataSourceImpl`, etc.
+
+**Repository Implementation** — coordinates data sources and handles error wrapping:
+
+```kotlin
+class ConversationsRepositoryImpl(
+ private val dataSource: ConversationsDataSource
+) : ConversationsRepository {
+
+ private var hasMore = true
+
+ override suspend fun getConversations(
+ request: ConversationsRequest
+ ): Result> {
+ return try {
+ val conversations = dataSource.fetchConversations(request)
+ hasMore = conversations.isNotEmpty()
+ Result.success(conversations)
+ } catch (e: CometChatException) {
+ Result.failure(e)
+ }
+ }
+}
+```
+
+Repositories wrap raw SDK exceptions into Kotlin `Result` types, track pagination state, and coordinate between data sources.
+
+### Domain Layer
+
+The domain layer defines contracts and single-purpose use cases. It has no dependency on the SDK or Android framework.
+
+**Repository Interfaces** — contracts that the data layer implements:
+
+```kotlin
+interface ConversationsRepository {
+ suspend fun getConversations(request: ConversationsRequest): Result>
+ suspend fun deleteConversation(conversationWith: String, conversationType: String): Result
+ suspend fun markAsDelivered(conversation: Conversation): Result
+ fun hasMoreConversations(): Boolean
+}
+```
+
+**Use Cases** — encapsulate a single business action:
+
+```kotlin
+open class GetConversationsUseCase(
+ private val repository: ConversationsRepository
+) {
+ open suspend operator fun invoke(
+ request: ConversationsRequest
+ ): Result> {
+ return repository.getConversations(request)
+ }
+
+ open fun hasMore(): Boolean = repository.hasMoreConversations()
+}
+```
+
+Use cases are `open` so they can be overridden for testing or custom behavior. Each use case does one thing:
+
+| Use Case | Action |
+|---|---|
+| `GetConversationsUseCase` | Fetch paginated conversations |
+| `DeleteConversationUseCase` | Delete a conversation |
+| `RefreshConversationsUseCase` | Clear and re-fetch |
+| `FetchUsersUseCase` / `SearchUsersUseCase` | Fetch or search users |
+| `FetchGroupsUseCase` | Fetch groups |
+| `FetchGroupMembersUseCase` / `SearchGroupMembersUseCase` | Fetch or search group members |
+| `BanGroupMemberUseCase` / `KickGroupMemberUseCase` | Member moderation |
+| `ChangeMemberScopeUseCase` | Change member role |
+| `SendTextMessageUseCase` / `SendMediaMessageUseCase` / `SendCustomMessageUseCase` | Send messages |
+| `EditMessageUseCase` | Edit a sent message |
+| `FetchCallLogsUseCase` | Fetch call history |
+| `InitiateCallUseCase` / `InitiateUserCallUseCase` / `StartGroupCallUseCase` | Start calls |
+| `FetchReactionsUseCase` / `RemoveReactionUseCase` | Reaction management |
+| `CreatePollUseCase` | Create a poll |
+| `GetStickersUseCase` | Fetch sticker sets |
+| `JoinGroupUseCase` / `GetGroupUseCase` / `GetUserUseCase` | Entity lookups |
+
+### ViewModel Layer
+
+ViewModels receive use cases via constructor injection and expose `StateFlow` / sealed `UIState` classes to the UI:
+
+```kotlin
+class CometChatConversationsViewModel(
+ private val getConversationsUseCase: GetConversationsUseCase,
+ private val deleteConversationUseCase: DeleteConversationUseCase,
+ private val refreshConversationsUseCase: RefreshConversationsUseCase,
+ private val enableListeners: Boolean = true
+) : ViewModel() {
+
+ // UI observes this sealed state
+ private val _uiState = MutableStateFlow(UIState.Loading)
+ val uiState: StateFlow = _uiState
+
+ fun fetchConversations() {
+ viewModelScope.launch {
+ getConversationsUseCase(request)
+ .onSuccess { conversations ->
+ _uiState.value = if (conversations.isEmpty()) UIState.Empty
+ else UIState.Content(conversations)
+ }
+ .onFailure { _uiState.value = UIState.Error(it) }
+ }
+ }
+}
+```
+
+### State Management (StateFlow + Sealed Classes)
+
+Each feature has a dedicated sealed UIState class. All state is exposed via `StateFlow` — not LiveData:
+
+```kotlin
+sealed class UIState {
+ object Loading : UIState()
+ object Empty : UIState()
+ data class Error(val exception: CometChatException) : UIState()
+ data class Content(val conversations: List) : UIState()
+}
+```
+
+Feature-specific states include additional fields:
+
+| State Class | Feature | Extra Fields |
+|---|---|---|
+| `ConversationStarterUIState` | Conversation list | — |
+| `MessageListUIState` | Message list | scroll position, reply state |
+| `MessageComposerUIState` | Composer | attachment state, edit mode |
+| `MessageHeaderUIState` | Header | typing indicator, user status |
+| `GroupsUIState` | Groups | — |
+| `UsersUIState` | Users | — |
+| `GroupMembersUIState` | Group members | scope change state |
+| `CallLogsUIState` | Call logs | — |
+| `CallButtonsUIState` | Call buttons | call initiation state |
+| `IncomingCallUIState` / `OutgoingCallUIState` / `OngoingCallUIState` | Calls | call session state |
+| `ReactionListUIState` | Reactions | — |
+| `CreatePollUIState` | Polls | form validation state |
+| `StickerKeyboardUIState` | Stickers | sticker sets |
+
+### ListOperations Interface
+
+List-based ViewModels implement the `ListOperations` interface, which provides a standard contract for manipulating list data:
+
+```kotlin
+interface ListOperations {
+ fun addAtIndex(index: Int, item: T)
+ fun updateAtIndex(index: Int, item: T)
+ fun removeAtIndex(index: Int)
+ fun moveToTop(item: T)
+}
+```
+
+This ensures consistent list manipulation across Conversations, Users, Groups, Group Members, and Call Logs.
+
+## Dependency Injection via Factories
+
+ViewModels are created through `ViewModelProvider.Factory` classes that wire up the dependency chain:
+
+```kotlin
+class CometChatConversationsViewModelFactory(
+ private val repository: ConversationsRepository = ConversationsRepositoryImpl(
+ ConversationsDataSourceImpl()
+ ),
+ private val enableListeners: Boolean = true
+) : ViewModelProvider.Factory {
+
+ override fun create(modelClass: Class): T {
+ val getUseCase = GetConversationsUseCase(repository)
+ val deleteUseCase = DeleteConversationUseCase(repository)
+ val refreshUseCase = RefreshConversationsUseCase(repository)
+
+ return CometChatConversationsViewModel(
+ getConversationsUseCase = getUseCase,
+ deleteConversationUseCase = deleteUseCase,
+ refreshConversationsUseCase = refreshUseCase,
+ enableListeners = enableListeners
+ ) as T
+ }
+}
+```
+
+Default implementations are provided, but you can inject custom repositories:
+
+```kotlin
+// Custom repository for testing or caching
+val factory = CometChatConversationsViewModelFactory(
+ repository = MyCustomConversationRepository(),
+ enableListeners = false // disable for previews
+)
+```
+
+## Data Flow: End to End
+
+### Fetching Conversations
+
+```
+UI (Composable/View)
+ │ collects uiState
+ ▼
+CometChatConversationsViewModel
+ │ calls getConversationsUseCase(request)
+ ▼
+GetConversationsUseCase
+ │ calls repository.getConversations(request)
+ ▼
+ConversationsRepositoryImpl
+ │ calls dataSource.fetchConversations(request)
+ │ wraps result in Result<>, tracks pagination
+ ▼
+ConversationsDataSourceImpl
+ │ calls CometChat SDK (ConversationsRequest.fetchNext())
+ ▼
+CometChat SDK → REST API → Response
+```
+
+### Real-Time Updates
+
+```
+CometChat SDK (WebSocket)
+ │ onTextMessageReceived / onTypingStarted / etc.
+ ▼
+ViewModel (SDK listener registered in init)
+ │ processes event → updates internal list
+ │ emits new UIState.Content(updatedList)
+ ▼
+UI recomposes / rebinds automatically
+```
+
+### User Action (Delete Conversation)
+
+```
+UI → user swipes to delete
+ │
+ ▼
+ViewModel.deleteConversation(conversation)
+ │ calls deleteConversationUseCase(id, type)
+ ▼
+DeleteConversationUseCase
+ │ calls repository.deleteConversation(id, type)
+ ▼
+ConversationsRepositoryImpl
+ │ calls dataSource.deleteConversation(id, type)
+ ▼
+CometChat SDK → REST API → 200 OK
+ │
+ ▼
+ViewModel removes item from list → emits updated UIState
+```
+
+## Component ↔ Core Mapping
+
+| UI Component | Core ViewModel | Use Cases | Repository | DataSource |
+|---|---|---|---|---|
+| Conversation List | `CometChatConversationsViewModel` | Get, Delete, Refresh | `ConversationsRepository` | `ConversationsDataSource` |
+| Message List | `CometChatMessageListViewModel` | (message fetching) | `MessageListRepository` | `MessageListDataSource` |
+| Message Composer | `CometChatMessageComposerViewModel` | SendText, SendMedia, SendCustom, Edit | `MessageComposerRepository` | `MessageComposerDataSource` |
+| Message Header | `CometChatMessageHeaderViewModel` | — | `MessageHeaderRepository` | `MessageHeaderDataSource` |
+| Users | `CometChatUsersViewModel` | FetchUsers, SearchUsers | `UsersRepository` | `UsersDataSource` |
+| Groups | `CometChatGroupsViewModel` | FetchGroups, JoinGroup | `GroupsRepository` | `GroupsDataSource` |
+| Group Members | `CometChatGroupMembersViewModel` | FetchMembers, Search, Ban, Kick, ChangeScope | `GroupMembersRepository` | `GroupMembersDataSource` |
+| Call Logs | `CometChatCallLogsViewModel` | FetchCallLogs | `CallLogsRepository` | `CallLogsDataSource` |
+| Call Buttons | `CometChatCallButtonsViewModel` | InitiateCall, StartGroupCall | `CallButtonsRepository` | `CallButtonsDataSource` |
+| Reactions | `CometChatReactionListViewModel` | FetchReactions, RemoveReaction | `ReactionListRepository` | `ReactionListDataSource` |
+| Message Info | `CometChatMessageInformationViewModel` | — | `MessageInformationRepository` | `MessageInformationDataSource` |
+
+## Events (Cross-Component Communication)
+
+The `CometChatEvents` singleton in `chatuikit-core` provides a typed event bus using Kotlin `SharedFlow` for communication between components that don't share a ViewModel:
+
+| Event Flow | Emitted When |
+|---|---|
+| `CometChatEvents.messageEvents` | Message sent, edited, deleted, reacted |
+| `CometChatEvents.conversationEvents` | Conversation deleted |
+| `CometChatEvents.groupEvents` | Group created, member added/removed/banned |
+| `CometChatEvents.userEvents` | User blocked/unblocked |
+| `CometChatEvents.callEvents` | Call initiated, accepted, rejected |
+| `CometChatEvents.uiEvents` | UI-level events (show dialog, navigate) |
+
+See the [Events reference](/ui-kit/android/v6/events) for sealed class types and subscription examples.
+
+## Component-Level Overrides
+
+Every layer in the architecture is designed to be replaceable. You can override at the level that makes sense for your use case — from swapping the entire data source to just tweaking a single use case.
+
+### Override Points
+
+```
+┌──────────────────────────────────────────────────────────────┐
+│ UI Component (CometChatUsers, CometChatConversations...) │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ ViewModel ← inject via custom Factory │ │
+│ │ ┌──────────────────────────────────────────────┐ │ │
+│ │ │ UseCase ← subclass (open classes) │ │ │
+│ │ │ ┌──────────────────────────────────────┐ │ │ │
+│ │ │ │ Repository ← implement interface │ │ │ │
+│ │ │ │ ┌──────────────────────────────┐ │ │ │ │
+│ │ │ │ │ DataSource ← implement iface│ │ │ │ │
+│ │ │ │ └──────────────────────────────┘ │ │ │ │
+│ │ │ └──────────────────────────────────────┘ │ │ │
+│ │ └──────────────────────────────────────────────┘ │ │
+│ └──────────────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────────────────┘
+```
+
+### 1. Custom Repository
+
+The most common override. Implement the repository interface and pass it to the factory.
+
+```kotlin
+class OfflineUsersRepository : UsersRepository {
+
+ private val cachedUsers = listOf(/* local data */)
+
+ override suspend fun getUsers(request: UsersRequest): Result> {
+ return Result.success(cachedUsers)
+ }
+
+ override fun hasMoreUsers(): Boolean = false
+}
+```
+
+Wire it in:
+
+
+
+```kotlin
+val factory = CometChatUsersViewModelFactory(
+ repository = OfflineUsersRepository(),
+ enableListeners = false
+)
+val viewModel = ViewModelProvider(this, factory)[CometChatUsersViewModel::class.java]
+
+val usersView = findViewById(R.id.users)
+usersView.setViewModel(viewModel)
+```
+
+
+
+```kotlin
+val factory = CometChatUsersViewModelFactory(
+ repository = OfflineUsersRepository(),
+ enableListeners = false
+)
+val viewModel: CometChatUsersViewModel = viewModel(factory = factory)
+
+CometChatUsers(
+ usersViewModel = viewModel
+)
+```
+
+
+
+### 2. Custom DataSource
+
+Override at the lowest level to change how SDK calls are made — useful for caching, offline support, or wrapping a different backend.
+
+```kotlin
+class CachedUsersDataSource(
+ private val sdkDataSource: UsersDataSourceImpl = UsersDataSourceImpl(),
+ private val cache: UserCache
+) : UsersDataSource {
+
+ override suspend fun fetchUsers(request: UsersRequest): List {
+ val cached = cache.get(request)
+ if (cached != null) return cached
+
+ val users = sdkDataSource.fetchUsers(request)
+ cache.put(request, users)
+ return users
+ }
+}
+```
+
+Then wrap it in the default repository implementation:
+
+```kotlin
+val dataSource = CachedUsersDataSource(cache = myCache)
+val repository = UsersRepositoryImpl(dataSource)
+val factory = CometChatUsersViewModelFactory(repository = repository)
+```
+
+### 3. Custom Use Cases
+
+Use cases are `open` classes, so you can subclass them to add validation, logging, or transformation:
+
+```kotlin
+class LoggingGetConversationsUseCase(
+ repository: ConversationsRepository
+) : GetConversationsUseCase(repository) {
+
+ override suspend operator fun invoke(
+ request: ConversationsRequest
+ ): Result> {
+ Log.d("Conversations", "Fetching conversations...")
+ val result = super.invoke(request)
+ result.onSuccess { Log.d("Conversations", "Fetched ${it.size} items") }
+ result.onFailure { Log.e("Conversations", "Fetch failed", it) }
+ return result
+ }
+}
+```
+
+### 4. Passing a Custom ViewModel to the UI Component
+
+Both `chatuikit-jetpack` (Compose) and `chatuikit-kotlin` (XML Views) accept a pre-built ViewModel. This is the entry point for all overrides.
+
+
+
+```kotlin
+class MyUsersActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_users)
+
+ val factory = CometChatUsersViewModelFactory(
+ repository = MyCustomUsersRepository()
+ )
+ val viewModel = ViewModelProvider(this, factory)[CometChatUsersViewModel::class.java]
+
+ val usersView = findViewById(R.id.users)
+ usersView.setViewModel(viewModel)
+ }
+}
+```
+
+
+
+```kotlin
+@Composable
+fun MyUsersScreen() {
+ val factory = CometChatUsersViewModelFactory(
+ repository = MyCustomUsersRepository(),
+ enableListeners = true
+ )
+ val viewModel: CometChatUsersViewModel = viewModel(factory = factory)
+
+ CometChatUsers(
+ usersViewModel = viewModel,
+ style = CometChatUsersStyle.default(),
+ hideToolbar = false,
+ hideSearchBox = false
+ )
+}
+```
+
+
+
+### 5. Disabling Listeners for Previews and Testing
+
+Every factory accepts `enableListeners = false`. When disabled, the ViewModel won't register SDK listeners or UIKit event subscriptions — useful for Compose previews, unit tests, or showcase screens:
+
+```kotlin
+val factory = CometChatConversationsViewModelFactory(
+ repository = FakeConversationRepository(),
+ enableListeners = false // No WebSocket listeners, no event subscriptions
+)
+```
+
+### Override Summary by Component
+
+| Component | Factory Class | Repository Interface | Key Use Cases |
+|---|---|---|---|
+| Conversation List | `CometChatConversationsViewModelFactory` | `ConversationsRepository` | Get, Delete, Refresh |
+| Users | `CometChatUsersViewModelFactory` | `UsersRepository` | FetchUsers, SearchUsers |
+| Groups | `CometChatGroupsViewModelFactory` | `GroupsRepository` | FetchGroups, JoinGroup |
+| Group Members | `CometChatGroupMembersViewModelFactory` | `GroupMembersRepository` | FetchMembers, Search, Ban, Kick, ChangeScope |
+| Message List | `CometChatMessageListViewModelFactory` | `MessageListRepository` | (message fetching) |
+| Message Composer | `CometChatMessageComposerViewModelFactory` | `MessageComposerRepository` | SendText, SendMedia, SendCustom, Edit |
+| Call Logs | `CometChatCallLogsViewModelFactory` | `CallLogsRepository` | FetchCallLogs |
+| Call Buttons | `CometChatCallButtonsViewModelFactory` | `CallButtonsRepository` | InitiateCall, StartGroupCall |
+| Reactions | `CometChatReactionListViewModelFactory` | `ReactionListRepository` | FetchReactions, RemoveReaction |
+
+## Related
+
+- [Events](/ui-kit/android/v6/events) — Cross-component communication via `CometChatEvents` SharedFlow
+- [Methods](/ui-kit/android/v6/methods) — UI Kit wrapper methods for init, auth, and messaging
diff --git a/ui-kit/android/v6/call-buttons.mdx b/ui-kit/android/v6/call-buttons.mdx
new file mode 100644
index 000000000..93d396843
--- /dev/null
+++ b/ui-kit/android/v6/call-buttons.mdx
@@ -0,0 +1,304 @@
+---
+title: "Call Buttons"
+description: "Voice and video call buttons that initiate calls for a given user or group."
+---
+
+`CometChatCallButtons` renders voice and video call buttons and initiates calls for the bound `User` or `Group`. Place it in a `CometChatMessageHeader` or anywhere a call action is needed.
+
+---
+
+## Where It Fits
+
+`CometChatCallButtons` is a utility component. Wire it into a `CometChatMessageHeader` or place it standalone wherever a call action is needed.
+
+
+
+
+```xml activity_chat.xml lines
+
+```
+
+```kotlin lines
+val callButtons = findViewById(R.id.call_buttons)
+callButtons.setUser(user)
+```
+
+
+
+
+```kotlin lines
+CometChatCallButtons(
+ user = user
+)
+```
+
+
+
+
+---
+
+## Quick Start
+
+
+
+
+Add to your layout XML:
+
+```xml lines
+
+```
+
+Set a `User` or `Group` — required before calls can be initiated:
+
+```kotlin lines
+override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.your_layout)
+
+ val callButtons = findViewById(R.id.call_buttons)
+ callButtons.setUser(user)
+ // or callButtons.setGroup(group)
+}
+```
+
+Or programmatically:
+
+```kotlin lines
+override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val callButtons = CometChatCallButtons(this)
+ callButtons.setUser(user)
+ setContentView(callButtons)
+}
+```
+
+
+
+
+```kotlin lines
+@Composable
+fun CallButtonsScreen() {
+ CometChatCallButtons(
+ user = user
+ // or group = group
+ )
+}
+```
+
+
+
+
+Prerequisites: CometChat SDK initialized with `CometChatUIKit.init()`, a user logged in, and the UI Kit dependency added.
+
+> You must call `setUser(User)` or `setGroup(Group)` before the buttons can initiate a call. Without a target, button clicks have no effect.
+
+---
+
+## Actions and Events
+
+### Callback Methods
+
+#### `onVoiceCallClick`
+
+Fires when the voice call button is tapped. Replaces the default behavior of initiating an audio call.
+
+
+
+
+```kotlin lines
+callButtons.setOnVoiceCallClick { user, group ->
+ // Custom voice call logic
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallButtons(
+ user = user,
+ onVoiceCallClick = { u, g ->
+ // Custom voice call logic
+ }
+)
+```
+
+
+
+
+#### `onVideoCallClick`
+
+Fires when the video call button is tapped. Replaces the default behavior of initiating a video call.
+
+
+
+
+```kotlin lines
+callButtons.setOnVideoCallClick { user, group ->
+ // Custom video call logic
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallButtons(
+ user = user,
+ onVideoCallClick = { u, g ->
+ // Custom video call logic
+ }
+)
+```
+
+
+
+
+#### `onError`
+
+Fires on internal errors (network failure, auth issue, SDK exception).
+
+
+
+
+```kotlin lines
+callButtons.setOnError { exception ->
+ Log.e("CallButtons", "Error: ${exception.message}")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallButtons(
+ user = user,
+ onError = { exception ->
+ Log.e("CallButtons", "Error: ${exception.message}")
+ }
+)
+```
+
+
+
+
+### Global UI Events (CometChatCallEvents)
+
+| Event | Fires when | Payload |
+| --- | --- | --- |
+| `ccOutgoingCall` | An outgoing call is initiated | `Call` |
+| `ccCallAccepted` | A call is accepted by the recipient | `Call` |
+| `ccCallRejected` | A call is rejected by the recipient | `Call` |
+| `ccCallEnded` | A call is ended | `Call` |
+
+---
+
+## Functionality
+
+| Method (Kotlin XML) | Compose Parameter | Description |
+| --- | --- | --- |
+| `setUser(user)` | `user = user` | Set the user to call (required for 1-on-1) |
+| `setGroup(group)` | `group = group` | Set the group to call (required for group calls) |
+| `setOnVoiceCallClick { }` | `onVoiceCallClick = { }` | Override voice call button behavior |
+| `setOnVideoCallClick { }` | `onVideoCallClick = { }` | Override video call button behavior |
+| `setOnError { }` | `onError = { }` | Error callback |
+| `setVoiceCallButtonVisibility(View.GONE)` | `hideVoiceCallButton = true` | Toggle voice call button |
+| `setVideoCallButtonVisibility(View.GONE)` | `hideVideoCallButton = true` | Toggle video call button |
+
+---
+
+## Style
+
+
+
+
+Define a custom style in `themes.xml`:
+
+```xml themes.xml lines
+
+```
+
+```kotlin lines
+callButtons.setStyle(R.style.CustomCallButtonsStyle)
+```
+
+
+
+
+```kotlin lines
+CometChatCallButtons(
+ user = user,
+ style = CometChatCallButtonsStyle.default().copy(
+ voiceCallIconTint = Color(0xFF4CAF50),
+ videoCallIconTint = Color(0xFF2196F3),
+ voiceCallBackgroundColor = Color(0xFFE8F5E9),
+ videoCallBackgroundColor = Color(0xFFE3F2FD)
+ )
+)
+```
+
+
+
+
+See [Component Styling](/ui-kit/android/v6/component-styling) for the full reference.
+
+---
+
+## ViewModel
+
+```kotlin lines
+val viewModel = ViewModelProvider(this)
+ .get(CometChatCallButtonsViewModel::class.java)
+```
+
+
+
+
+```kotlin lines
+callButtons.setViewModel(viewModel)
+```
+
+
+
+
+```kotlin lines
+CometChatCallButtons(
+ user = user,
+ callButtonsViewModel = viewModel
+)
+```
+
+
+
+
+See [ViewModel & Data](/ui-kit/android/v6/customization-viewmodel-data) for state observation and custom repositories.
+
+---
+
+## Next Steps
+
+
+
+ View call history
+
+
+ Incoming call notification with accept/reject
+
+
+ Outgoing call screen with end-call button
+
+
+ Display user/group info in the toolbar
+
+
diff --git a/ui-kit/android/v6/call-features.mdx b/ui-kit/android/v6/call-features.mdx
new file mode 100644
index 000000000..39a5f31ac
--- /dev/null
+++ b/ui-kit/android/v6/call-features.mdx
@@ -0,0 +1,200 @@
+---
+title: "Call"
+description: "Add one-on-one and group audio/video calling to your Android app using the CometChat Calls SDK and UI Kit."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Kotlin (XML Views) | `com.cometchat:chat-uikit-kotlin` + `com.cometchat:calls-sdk-android` |
+| Jetpack Compose | `com.cometchat:chat-uikit-compose` + `com.cometchat:calls-sdk-android` |
+| Required setup | `CometChatUIKit.init()` then `CometChatUIKit.login()` — Calls SDK must also be installed |
+| Call features | Incoming Call, Outgoing Call, Call Logs, Call Buttons, Ongoing Call |
+| Key components | `CometChatCallButtons`, `CometChatIncomingCall`, `CometChatOutgoingCall`, `CometChatCallLogs`, `CometChatOngoingCall` |
+| Auto-detection | UI Kit automatically detects the Calls SDK and enables call UI components |
+| Related | [Getting Started](/ui-kit/android/v6/getting-started), [Core Features](/ui-kit/android/v6/core-features), [Call Log Details Guide](/ui-kit/android/v6/guide-call-log-details) |
+
+
+
+CometChat's Calls feature allows you to seamlessly integrate one-on-one as well as group audio and video calling capabilities into your application. This document provides a technical overview of these features, as implemented in the Android UI Kit.
+
+## Integration
+
+First, make sure that you've correctly integrated the UI Kit library into your project. If you haven't done this yet or are facing difficulties, refer to our [Getting Started](/ui-kit/android/v6/getting-started) guide.
+
+Once you've successfully integrated the UI Kit, the next step is to add the CometChat Calls SDK to your project. This is necessary to enable the calling features in the UI Kit.
+
+### Step 1: Add Calls SDK Dependency
+
+Add the following dependency to your `build.gradle.kts` file:
+
+
+
+```kotlin build.gradle.kts
+dependencies {
+ implementation("com.cometchat:chat-uikit-kotlin:5.2.9")
+ implementation("com.cometchat:calls-sdk-android:4.3.3")
+}
+```
+
+
+
+```kotlin build.gradle.kts
+dependencies {
+ implementation("com.cometchat:chat-uikit-compose:5.2.9")
+ implementation("com.cometchat:calls-sdk-android:4.3.3")
+}
+```
+
+
+
+After adding this dependency, sync your project. The Android UI Kit will automatically detect the Calls SDK and activate the calling features.
+
+### Step 2: Verify Call Buttons Appear
+
+Once the Calls SDK is integrated, you will see the `CometChatCallButtons` component automatically rendered in the [MessageHeader](/ui-kit/android/v6/message-header) component. This provides users with quick access to initiate audio and video calls.
+
+
+
+
+
+### Step 3: Add Call Listener for Incoming Calls
+
+To receive incoming calls globally in your app, you will need to add a `CallListener`. This should be added before you initialize the CometChat UI Kit. We recommend creating a custom Application class and adding the call listener there.
+
+When an incoming call is received, you can display the `CometChatIncomingCall` component using the current activity context.
+
+
+
+```kotlin
+class BaseApplication : Application() {
+
+ companion object {
+ private val LISTENER_ID = "${BaseApplication::class.java.simpleName}${System.currentTimeMillis()}"
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+
+ CometChat.addCallListener(LISTENER_ID, object : CometChat.CallListener {
+ override fun onIncomingCallReceived(call: Call) {
+ // Get the current activity context
+ val currentActivity = getCurrentActivity() // Implement this method
+
+ currentActivity?.let {
+ // Create and display the incoming call component
+ val incomingCallView = CometChatIncomingCall(it)
+ incomingCallView.call = call
+ incomingCallView.fitsSystemWindows = true
+ incomingCallView.onError = OnError { exception ->
+ // Handle errors
+ }
+
+ // Display the component (e.g., as dialog or snackbar)
+ }
+ }
+
+ override fun onOutgoingCallAccepted(call: Call) {
+ // Handle outgoing call acceptance
+ }
+
+ override fun onOutgoingCallRejected(call: Call) {
+ // Handle outgoing call rejection
+ }
+
+ override fun onIncomingCallCancelled(call: Call) {
+ // Handle incoming call cancellation
+ }
+ })
+ }
+}
+```
+
+
+
+```kotlin
+class BaseApplication : Application() {
+
+ companion object {
+ private val LISTENER_ID = "${BaseApplication::class.java.simpleName}${System.currentTimeMillis()}"
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+
+ CometChat.addCallListener(LISTENER_ID, object : CometChat.CallListener {
+ override fun onIncomingCallReceived(call: Call) {
+ CometChatCallActivity.launchIncomingCallScreen(this@BaseApplication, call, null)
+ // Pass null or IncomingCallConfiguration if need to configure CometChatIncomingCall component
+ }
+
+ override fun onOutgoingCallAccepted(call: Call) {
+ // Handle outgoing call acceptance
+ }
+
+ override fun onOutgoingCallRejected(call: Call) {
+ // Handle outgoing call rejection
+ }
+
+ override fun onIncomingCallCancelled(call: Call) {
+ // Handle incoming call cancellation
+ }
+ })
+ }
+}
+```
+
+
+
+## Call Components
+
+The CometChat Android UI Kit provides five main components for implementing calling features in your app. Each component handles a specific part of the calling experience.
+
+### Call Buttons
+
+The `CometChatCallButtons` component provides users with quick access to initiate audio and video calls. This component is automatically rendered in the [MessageHeader](/ui-kit/android/v6/message-header) when the Calls SDK is integrated.
+
+
+
+
+
+[Learn more about Call Buttons →](/ui-kit/android/v6/call-buttons)
+
+### Incoming Call
+
+The `CometChatIncomingCall` component displays when a user receives an incoming call. It provides a full-screen interface showing caller information and call controls.
+
+
+
+
+
+[Learn more about Incoming Call →](/ui-kit/android/v6/incoming-call)
+
+### Outgoing Call
+
+The `CometChatOutgoingCall` component manages the outgoing call experience. It displays while waiting for the recipient to answer and automatically transitions to the active call screen once accepted.
+
+
+
+
+
+[Learn more about Outgoing Call →](/ui-kit/android/v6/outgoing-call)
+
+### Call Logs
+
+The `CometChatCallLogs` component displays a history of all call activities, including missed, received, and dialed calls. Users can view call details and initiate new calls from the log.
+
+
+
+
+
+[Learn more about Call Logs →](/ui-kit/android/v6/call-logs)
+
+### Ongoing Call
+
+The `CometChatOngoingCall` component renders the active call screen with video feeds, mute/unmute controls, camera toggle, and end-call actions.
+
+### Call Log Details
+
+For detailed information about individual calls, including participants, join/leave history, and recordings, see the [Call Log Details](/ui-kit/android/v6/guide-call-log-details) guide.
diff --git a/ui-kit/android/v6/call-logs.mdx b/ui-kit/android/v6/call-logs.mdx
new file mode 100644
index 000000000..c15a0a8b2
--- /dev/null
+++ b/ui-kit/android/v6/call-logs.mdx
@@ -0,0 +1,862 @@
+---
+title: "Call Logs"
+description: "Scrollable list of call logs for the logged-in user with caller names, avatars, call status, and timestamps."
+---
+
+`CometChatCallLogs` renders a scrollable list of call logs for the logged-in user with caller names, avatars, call status indicators, and timestamps.
+
+
+
+
+
+---
+
+## Where It Fits
+
+`CometChatCallLogs` is a list component. It renders the user's call history and emits the selected `CallLog` via `onItemClick`. Use it as a standalone call history screen or as a tab in a tabbed layout alongside conversations and contacts.
+
+
+
+
+```xml activity_call_logs.xml lines
+
+```
+
+```kotlin lines
+val callLogs = findViewById(R.id.call_logs)
+
+callLogs.setOnItemClick { callLog ->
+ // Navigate to call detail or initiate call
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ modifier = Modifier.fillMaxSize(),
+ onItemClick = { callLog ->
+ // Navigate to call detail or initiate call
+ }
+)
+```
+
+
+
+
+---
+
+## Quick Start
+
+
+
+
+Add to your layout XML:
+
+```xml lines
+
+```
+
+Or programmatically:
+
+```kotlin lines
+override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(CometChatCallLogs(this))
+}
+```
+
+
+
+
+```kotlin lines
+@Composable
+fun CallLogsScreen() {
+ CometChatCallLogs(
+ modifier = Modifier.fillMaxSize()
+ )
+}
+```
+
+
+
+
+Prerequisites: CometChat SDK initialized with `CometChatUIKit.init()`, a user logged in, the UI Kit dependency added, and the CometChat Calls SDK configured.
+
+Or in a Fragment:
+
+
+
+
+```kotlin lines
+override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ return CometChatCallLogs(requireContext())
+}
+```
+
+
+
+
+```kotlin lines
+override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ return ComposeView(requireContext()).apply {
+ setContent { CometChatCallLogs() }
+ }
+}
+```
+
+
+
+
+---
+
+## Filtering Call Logs
+
+
+
+
+Pass a `CallLogRequest.CallLogRequestBuilder` to control what loads:
+
+```kotlin lines
+callLogs.setCallLogRequestBuilder(
+ CallLogRequest.CallLogRequestBuilder()
+ .setLimit(20)
+ .setCallCategory(CometChatConstants.CALL_CATEGORY_CALL)
+)
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ callLogRequestBuilder = CallLogRequest.CallLogRequestBuilder()
+ .setLimit(20)
+ .setCallCategory(CometChatConstants.CALL_CATEGORY_CALL)
+)
+```
+
+
+
+
+### Filter Recipes
+
+| Recipe | Builder method |
+| --- | --- |
+| Limit per page | `.setLimit(10)` |
+| Audio calls only | `.setCallType(CometChatConstants.CALL_TYPE_AUDIO)` |
+| Video calls only | `.setCallType(CometChatConstants.CALL_TYPE_VIDEO)` |
+| Call category | `.setCallCategory(CometChatConstants.CALL_CATEGORY_CALL)` |
+
+
+Pass the builder object, not the result of `.build()`. The component calls `.build()` internally. Default page size is 30 with infinite scroll.
+
+
+---
+
+## Actions and Events
+
+### Callback Methods
+
+#### `onItemClick`
+
+Fires when a call log row is tapped. Primary navigation hook.
+
+
+
+
+```kotlin lines
+callLogs.setOnItemClick { callLog ->
+ // Navigate to call detail
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ onItemClick = { callLog ->
+ // Navigate to call detail
+ }
+)
+```
+
+
+
+
+> Replaces the default item-click behavior. Your custom lambda executes instead of the built-in navigation.
+
+#### `onItemLongClick`
+
+Fires when a call log row is long-pressed.
+
+
+
+
+```kotlin lines
+callLogs.setOnItemLongClick { callLog ->
+ // Show context menu
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ onItemLongClick = { callLog ->
+ // Show context menu
+ }
+)
+```
+
+
+
+
+#### `onBackPress`
+
+Fires when the user presses the back button in the toolbar.
+
+
+
+
+```kotlin lines
+callLogs.setOnBackPress {
+ finish()
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ onBackPress = { /* navigate back */ }
+)
+```
+
+
+
+
+#### `onError`
+
+Fires on internal errors (network failure, auth issue, SDK exception).
+
+
+
+
+```kotlin lines
+callLogs.setOnError { exception ->
+ Log.e("CallLogs", "Error: ${exception.message}")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ onError = { exception ->
+ Log.e("CallLogs", "Error: ${exception.message}")
+ }
+)
+```
+
+
+
+
+#### `onLoad`
+
+Fires when the list is successfully fetched and loaded.
+
+
+
+
+```kotlin lines
+callLogs.setOnLoad { callLogList ->
+ Log.d("CallLogs", "Loaded ${callLogList.size}")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ onLoad = { callLogList ->
+ Log.d("CallLogs", "Loaded ${callLogList.size}")
+ }
+)
+```
+
+
+
+
+#### `onEmpty`
+
+Fires when the list is empty after loading.
+
+
+
+
+```kotlin lines
+callLogs.setOnEmpty {
+ Log.d("CallLogs", "No call logs")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ onEmpty = { /* no call logs */ }
+)
+```
+
+
+
+
+---
+
+## Functionality
+
+| Method (Kotlin XML) | Compose Parameter | Description |
+| --- | --- | --- |
+| `setBackIconVisibility(View.VISIBLE)` | `hideBackIcon = false` | Toggle back button |
+| `setToolbarVisibility(View.GONE)` | `hideToolbar = true` | Toggle toolbar |
+| `setSeparatorVisibility(View.GONE)` | `hideSeparator = true` | Toggle list separators |
+| `setTitle("Call History")` | `title = "Call History"` | Custom toolbar title |
+
+---
+
+## Custom View Slots
+
+### Leading View
+
+Replace the avatar / left section.
+
+
+
+
+
+
+
+
+```kotlin lines
+callLogs.setLeadingView(object : CallLogsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
+ return ImageView(context).apply {
+ layoutParams = ViewGroup.LayoutParams(48.dp, 48.dp)
+ }
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, callLog: CallLog,
+ holder: RecyclerView.ViewHolder, callLogList: List, position: Int
+ ) {
+ val imageView = createdView as ImageView
+ // Load caller avatar
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ leadingView = { callLog ->
+ CometChatAvatar(
+ imageUrl = callLog.initiator?.avatar,
+ name = callLog.initiator?.name
+ )
+ }
+)
+```
+
+
+
+
+### Title View
+
+Replace the name / title text.
+
+
+
+
+
+
+
+
+```kotlin lines
+callLogs.setTitleView(object : CallLogsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
+ return TextView(context)
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, callLog: CallLog,
+ holder: RecyclerView.ViewHolder, callLogList: List, position: Int
+ ) {
+ (createdView as TextView).text = callLog.initiator?.name ?: ""
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ titleView = { callLog ->
+ Text(
+ text = callLog.initiator?.name ?: "",
+ style = CometChatTheme.typography.heading4Medium
+ )
+ }
+)
+```
+
+
+
+
+### Subtitle View
+
+Replace the subtitle text below the caller's name.
+
+
+
+
+
+
+
+
+```kotlin lines
+callLogs.setSubtitleView(object : CallLogsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
+ return TextView(context).apply { maxLines = 1; ellipsize = TextUtils.TruncateAt.END }
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, callLog: CallLog,
+ holder: RecyclerView.ViewHolder, callLogList: List, position: Int
+ ) {
+ (createdView as TextView).text = callLog.status ?: "Unknown"
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ subtitleView = { callLog ->
+ Text(
+ text = callLog.status ?: "Unknown",
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis
+ )
+ }
+)
+```
+
+
+
+
+### Trailing View
+
+Replace the right section of each call log item.
+
+
+
+
+
+
+
+
+```kotlin lines
+callLogs.setTrailingView(object : CallLogsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
+ return TextView(context)
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, callLog: CallLog,
+ holder: RecyclerView.ViewHolder, callLogList: List, position: Int
+ ) {
+ (createdView as TextView).text = SimpleDateFormat("h:mm a", Locale.getDefault())
+ .format(Date(callLog.initiatedAt * 1000))
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ trailingView = { callLog ->
+ Text(
+ text = SimpleDateFormat("h:mm a", Locale.getDefault())
+ .format(Date(callLog.initiatedAt * 1000))
+ )
+ }
+)
+```
+
+
+
+
+### Item View
+
+Replace the entire list item row.
+
+
+
+
+
+
+
+
+```kotlin lines
+callLogs.setItemView(object : CallLogsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
+ return LayoutInflater.from(context).inflate(R.layout.custom_call_log_item, null)
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, callLog: CallLog,
+ holder: RecyclerView.ViewHolder, callLogList: List, position: Int
+ ) {
+ val avatar = createdView.findViewById(R.id.custom_avatar)
+ val title = createdView.findViewById(R.id.tvName)
+ title.text = callLog.initiator?.name
+ avatar.setAvatar(callLog.initiator?.name, callLog.initiator?.avatar)
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ itemView = { callLog ->
+ Row(
+ modifier = Modifier.fillMaxWidth().padding(12.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ CometChatAvatar(imageUrl = callLog.initiator?.avatar, name = callLog.initiator?.name)
+ Spacer(Modifier.width(12.dp))
+ Column(modifier = Modifier.weight(1f)) {
+ Text(callLog.initiator?.name ?: "", style = CometChatTheme.typography.heading4Medium)
+ Text(callLog.status ?: "", style = CometChatTheme.typography.body3Regular)
+ }
+ }
+ }
+)
+```
+
+
+
+
+### State Views
+
+
+
+
+```kotlin lines
+callLogs.setEmptyView(R.layout.custom_empty_view)
+callLogs.setErrorView(R.layout.custom_error_view)
+callLogs.setLoadingView(R.layout.custom_loading_view)
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ emptyView = { Text("No call logs") },
+ errorView = { onRetry -> Button(onClick = onRetry) { Text("Retry") } },
+ loadingView = { CircularProgressIndicator() }
+)
+```
+
+
+
+
+### Overflow Menu
+
+
+
+
+```kotlin lines
+callLogs.setOverflowMenu(ImageButton(context).apply {
+ setImageResource(R.drawable.ic_filter)
+ setOnClickListener { /* show filter */ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ overflowMenu = {
+ IconButton(onClick = { /* show filter */ }) {
+ Icon(painterResource(R.drawable.ic_filter), "Filter")
+ }
+ }
+)
+```
+
+
+
+
+---
+
+## Menu Options
+
+
+
+
+```kotlin lines
+// Replace all options
+callLogs.setOptions { context, callLog ->
+ listOf(
+ CometChatPopupMenu.MenuItem(id = "delete", name = "Delete", onClick = { /* ... */ }),
+ CometChatPopupMenu.MenuItem(id = "callback", name = "Call Back", onClick = { /* ... */ })
+ )
+}
+
+// Append to defaults
+callLogs.setAddOptions { context, callLog ->
+ listOf(
+ CometChatPopupMenu.MenuItem(id = "info", name = "Info", onClick = { /* ... */ })
+ )
+}
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ options = { context, callLog ->
+ listOf(
+ MenuItem(id = "delete", name = "Delete", onClick = { /* ... */ }),
+ MenuItem(id = "callback", name = "Call Back", onClick = { /* ... */ })
+ )
+ },
+ addOptions = { context, callLog ->
+ listOf(MenuItem(id = "info", name = "Info", onClick = { /* ... */ }))
+ }
+)
+```
+
+
+
+
+---
+
+## Common Patterns
+
+### Minimal list — hide all chrome
+
+
+
+
+```kotlin lines
+callLogs.setToolbarVisibility(View.GONE)
+callLogs.setSeparatorVisibility(View.GONE)
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ hideToolbar = true,
+ hideSeparator = true
+)
+```
+
+
+
+
+### Audio calls only
+
+
+
+
+```kotlin lines
+callLogs.setCallLogRequestBuilder(
+ CallLogRequest.CallLogRequestBuilder()
+ .setCallType(CometChatConstants.CALL_TYPE_AUDIO)
+)
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ callLogRequestBuilder = CallLogRequest.CallLogRequestBuilder()
+ .setCallType(CometChatConstants.CALL_TYPE_AUDIO)
+)
+```
+
+
+
+
+### Video calls only
+
+
+
+
+```kotlin lines
+callLogs.setCallLogRequestBuilder(
+ CallLogRequest.CallLogRequestBuilder()
+ .setCallType(CometChatConstants.CALL_TYPE_VIDEO)
+)
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ callLogRequestBuilder = CallLogRequest.CallLogRequestBuilder()
+ .setCallType(CometChatConstants.CALL_TYPE_VIDEO)
+)
+```
+
+
+
+
+---
+
+## Advanced Methods
+
+### ViewModel Access
+
+```kotlin lines
+val factory = CometChatCallLogsViewModelFactory()
+val viewModel = ViewModelProvider(this, factory)
+ .get(CometChatCallLogsViewModel::class.java)
+```
+
+
+
+
+```kotlin lines
+callLogs.setViewModel(viewModel)
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ callLogsViewModel = viewModel
+)
+```
+
+
+
+
+See [ViewModel & Data](/ui-kit/android/v6/customization-viewmodel-data) for ListOperations, state observation, and custom repositories.
+
+---
+
+## Style
+
+
+
+
+
+
+
+
+Define a custom style in `themes.xml`:
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ style = CometChatCallLogsStyle.default().copy(
+ backgroundColor = Color(0xFFF5F5F5),
+ titleTextColor = Color(0xFF141414),
+ itemStyle = CometChatCallLogsItemStyle.default().copy(
+ backgroundColor = Color.White,
+ titleTextColor = Color(0xFF141414),
+ subtitleTextColor = Color(0xFF727272),
+ avatarStyle = CometChatAvatarStyle.default().copy(cornerRadius = 12.dp)
+ )
+ )
+)
+```
+
+
+
+
+### Style Properties
+
+| Property | Description |
+| --- | --- |
+| `backgroundColor` | List background color |
+| `titleTextColor` | Toolbar title color |
+| `itemStyle.backgroundColor` | Row background |
+| `itemStyle.titleTextColor` | Caller name color |
+| `itemStyle.subtitleTextColor` | Call status text color |
+| `itemStyle.separatorColor` | Row separator color |
+| `itemStyle.avatarStyle` | Avatar appearance |
+
+See [Component Styling](/ui-kit/android/v6/component-styling) for the full reference.
+
+---
+
+## Next Steps
+
+
+
+ Voice and video calling overview
+
+
+ Browse recent conversations
+
+
+ Detailed styling reference with screenshots
+
+
+ Custom ViewModels, repositories, and ListOperations
+
+
diff --git a/ui-kit/android/v6/calling-integration.mdx b/ui-kit/android/v6/calling-integration.mdx
new file mode 100644
index 000000000..dc4ca591d
--- /dev/null
+++ b/ui-kit/android/v6/calling-integration.mdx
@@ -0,0 +1,123 @@
+---
+title: "Calling Integration"
+description: "Add voice and video calling to your Android UI Kit application using chatuikit-kotlin or chatuikit-jetpack."
+---
+
+## Overview
+
+This guide walks you through adding voice and video calling capabilities to your Android application using the CometChat UI Kit.
+
+
+Make sure you've completed the [Getting Started](/ui-kit/android/v6/getting-started) guide before proceeding.
+
+
+## Add the Calls SDK
+
+Add the CometChat Calls SDK dependency alongside your chosen UI Kit module:
+
+
+
+```kotlin build.gradle.kts
+dependencies {
+ implementation("com.cometchat:chat-uikit-kotlin:5.2.9")
+ implementation("com.cometchat:calls-sdk-android:4.3.3")
+}
+```
+
+
+
+```kotlin build.gradle.kts
+dependencies {
+ implementation("com.cometchat:chat-uikit-compose:5.2.9")
+ implementation("com.cometchat:calls-sdk-android:4.3.3")
+}
+```
+
+
+
+After adding this dependency, the Android UI Kit will automatically detect it and activate the calling features. You will see the `CometChatCallButtons` component rendered in the [MessageHeader](/ui-kit/android/v6/message-header) component.
+
+
+
+
+
+## Set Up Call Listener
+
+To receive incoming calls globally in your app, add a `CallListener` before initializing the CometChat UI Kit. We recommend creating a custom Application class:
+
+
+
+```kotlin
+class BaseApplication : Application() {
+ companion object {
+ private val LISTENER_ID = "${BaseApplication::class.java.simpleName}${System.currentTimeMillis()}"
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ CometChat.addCallListener(LISTENER_ID, object : CometChat.CallListener {
+ override fun onIncomingCallReceived(call: Call) {
+ // Get the current activity context
+ val currentActivity = getCurrentActivity() // Implement this method
+
+ currentActivity?.let {
+ val incomingCallView = CometChatIncomingCall(it)
+ incomingCallView.call = call
+ incomingCallView.fitsSystemWindows = true
+ incomingCallView.onError = OnError { exception ->
+ // Handle errors
+ }
+
+ // Display the component (e.g., as dialog or full-screen overlay)
+ }
+ }
+
+ override fun onOutgoingCallAccepted(call: Call) {
+ // Handle accepted outgoing call
+ }
+
+ override fun onOutgoingCallRejected(call: Call) {
+ // Handle rejected outgoing call
+ }
+
+ override fun onIncomingCallCancelled(call: Call) {
+ // Handle cancelled incoming call
+ }
+ })
+ }
+}
+```
+
+
+
+```kotlin
+class BaseApplication : Application() {
+ companion object {
+ private val LISTENER_ID = "${BaseApplication::class.java.simpleName}${System.currentTimeMillis()}"
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ CometChat.addCallListener(LISTENER_ID, object : CometChat.CallListener {
+ override fun onIncomingCallReceived(call: Call) {
+ CometChatCallActivity.launchIncomingCallScreen(this@BaseApplication, call, null)
+ // Pass null or IncomingCallConfiguration if need to configure CometChatIncomingCall component
+ }
+
+ override fun onOutgoingCallAccepted(call: Call) {
+ // Handle accepted outgoing call
+ }
+
+ override fun onOutgoingCallRejected(call: Call) {
+ // Handle rejected outgoing call
+ }
+
+ override fun onIncomingCallCancelled(call: Call) {
+ // Handle cancelled incoming call
+ }
+ })
+ }
+}
+```
+
+
diff --git a/ui-kit/android/v6/color-resources.mdx b/ui-kit/android/v6/color-resources.mdx
new file mode 100644
index 000000000..89d9e8684
--- /dev/null
+++ b/ui-kit/android/v6/color-resources.mdx
@@ -0,0 +1,219 @@
+---
+title: "Color Resources"
+description: "Review and override the default UI Kit color palette for consistent light and dark mode styling."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Kotlin XML Views | Colors defined in `res/values/color.xml` (light) and `res/values-night/color.xml` (dark), overridable via theme attributes or `CometChatTheme.set*()` |
+| Jetpack Compose | Colors provided via `lightColorScheme()` and `darkColorScheme()` factory functions, customizable via `.copy()` |
+| Key tokens | `primary`, `backgroundColor1–4`, `textColorPrimary/Secondary/Tertiary`, `strokeColorDefault/Light/Dark`, `successColor`, `errorColor`, `warningColor`, `infoColor` |
+| Related | [Theme Introduction](/ui-kit/android/v6/theme-introduction) · [Component Styling](/ui-kit/android/v6/component-styling) |
+
+
+
+The UI Kit ships with a complete color palette for light and dark modes. This page documents the default values and how to override them.
+
+---
+
+## Color Categories
+
+The palette is organized into these groups:
+
+| Category | Tokens | Purpose |
+| --- | --- | --- |
+| Primary | `primary` | Brand color for buttons, highlights, interactive elements |
+| Neutral | `neutral50` – `neutral900` | Grayscale ramp for backgrounds, text, borders |
+| Alert | `success`, `error`, `warning`, `info`, `messageRead` | Status indicators |
+| Background | `backgroundColor1` – `backgroundColor4` | Surface/panel backgrounds (derived from neutrals) |
+| Stroke | `strokeColorDefault`, `strokeColorLight`, `strokeColorDark`, `strokeColorHighlight` | Borders and dividers |
+| Text | `textColorPrimary`, `textColorSecondary`, `textColorTertiary`, `textColorDisabled`, `textColorWhite`, `textColorHighlight` | Typography colors |
+| Icon | `iconTintPrimary`, `iconTintSecondary`, `iconTintTertiary`, `iconTintWhite`, `iconTintHighlight` | Icon tints |
+| Button | `primaryButtonBackground`, `primaryButtonText`, `secondaryButtonBackground`, `secondaryButtonText` | Button colors |
+
+---
+
+## Default Light Mode Palette
+
+
+
+
+Defined in `chatuikit-kotlin/src/main/res/values/color.xml`:
+
+```xml color.xml lines
+
+#6852D6
+
+
+#FFFFFF
+#FAFAFA
+#F5F5F5
+#E8E8E8
+#DCDCDC
+#A1A1A1
+#727272
+#5B5B5B
+#434343
+#141414
+
+
+#0B7BEA
+#09C26F
+#FFAB00
+#F44649
+#56E8A7
+```
+
+
+
+
+Provided by `lightColorScheme()` in `CometChatColorScheme.kt`:
+
+```kotlin lines
+import com.cometchat.uikit.compose.theme.lightColorScheme
+
+// Default light color scheme
+val colors = lightColorScheme()
+
+// Key defaults:
+// primary = Color(0xFF6852D6)
+// neutralColor50 = Color(0xFFFFFFFF)
+// neutralColor900 = Color(0xFF141414)
+// successColor = Color(0xFF09C26F)
+// errorColor = Color(0xFFF44649)
+// warningColor = Color(0xFFFFAB00)
+// infoColor = Color(0xFF0B7BEA)
+```
+
+
+
+
+---
+
+## Default Dark Mode Palette
+
+
+
+
+Defined in `chatuikit-kotlin/src/main/res/values-night/color.xml`. Note how neutral values are inverted:
+
+```xml values-night/color.xml lines
+
+#6852D6
+
+
+#141414
+#1A1A1A
+#272727
+#383838
+#4C4C4C
+#858585
+#989898
+#A8A8A8
+#C8C8C8
+#FFFFFF
+
+
+#0D66BF
+#0B9F5D
+#D08D04
+#C73C3E
+#56E8A7
+```
+
+Android automatically uses `values-night` resources when the system is in dark mode.
+
+
+
+
+Provided by `darkColorScheme()`:
+
+```kotlin lines
+import com.cometchat.uikit.compose.theme.darkColorScheme
+
+// Default dark color scheme
+val colors = darkColorScheme()
+
+// Key defaults (neutrals inverted):
+// primary = Color(0xFF6852D6)
+// neutralColor50 = Color(0xFF141414)
+// neutralColor900 = Color(0xFFFFFFFF)
+// successColor = Color(0xFF0B9F5D)
+// errorColor = Color(0xFFC73C3E)
+```
+
+
+
+
+---
+
+## Override Colors
+
+
+
+
+Override via XML theme attributes in `themes.xml`:
+
+```xml themes.xml lines
+
+```
+
+Or programmatically via `CometChatTheme`:
+
+```kotlin lines
+CometChatTheme.setPrimaryColor(Color.parseColor("#F76808"))
+CometChatTheme.setBackgroundColor1(Color.parseColor("#FFFFFF"))
+CometChatTheme.setTextColorPrimary(Color.parseColor("#000000"))
+CometChatTheme.setStrokeColorDefault(Color.parseColor("#E0E0E0"))
+```
+
+
+
+
+Customize via `.copy()` on the factory functions:
+
+```kotlin lines
+val customColors = lightColorScheme().copy(
+ primary = Color(0xFFF76808),
+ backgroundColor1 = Color(0xFFFFFFFF),
+ textColorPrimary = Color(0xFF000000),
+ strokeColorDefault = Color(0xFFE0E0E0)
+)
+
+CometChatTheme(colorScheme = customColors) {
+ // Your content
+}
+```
+
+
+
+
+
+
+
+
+---
+
+## Derived Colors
+
+Background, stroke, text, and icon colors are derived from the neutral scale by default:
+
+| Token | Light Mode Default | Dark Mode Default |
+| --- | --- | --- |
+| `backgroundColor1` | `neutral50` (#FFFFFF) | `neutral50` (#141414) |
+| `backgroundColor2` | `neutral100` (#FAFAFA) | `neutral100` (#1A1A1A) |
+| `textColorPrimary` | `neutral900` (#141414) | `neutral900` (#FFFFFF) |
+| `textColorSecondary` | `neutral600` (#727272) | `neutral600` (#989898) |
+| `strokeColorDefault` | `neutral200` (#F5F5F5) | `neutral200` (#272727) |
+| `strokeColorLight` | `neutral300` (#E8E8E8) | `neutral300` (#383838) |
+| `iconTintPrimary` | `neutral900` (#141414) | `neutral900` (#FFFFFF) |
+| `iconTintHighlight` | `primary` (#6852D6) | `primary` (#6852D6) |
+
+This means overriding a neutral color automatically updates all tokens that reference it.
diff --git a/ui-kit/android/v6/component-styling.mdx b/ui-kit/android/v6/component-styling.mdx
new file mode 100644
index 000000000..a1a7dd8b5
--- /dev/null
+++ b/ui-kit/android/v6/component-styling.mdx
@@ -0,0 +1,679 @@
+---
+title: "Component Styling"
+description: "Style CometChat UI Kit components using XML theme attributes or Compose style data classes."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Kotlin XML Views | Override XML styles in `themes.xml` extending component parent styles (e.g., `CometChatConversationsStyle`), assign via theme attributes |
+| Jetpack Compose | Pass style data classes as parameters (e.g., `CometChatConversationsStyle`, `CometChatMessageListStyle`) with `.default()` and `.copy()` |
+| Pattern (XML) | Create custom style → extend parent → assign to `AppTheme` via theme attribute |
+| Pattern (Compose) | Call `ComponentStyle.default().copy(property = value)` → pass as `style` parameter |
+| Related | [Theme Introduction](/ui-kit/android/v6/theme-introduction) · [Color Resources](/ui-kit/android/v6/color-resources) · [Message Bubble Styling](/ui-kit/android/v6/message-bubble-styling) |
+
+
+
+This page shows how to style CometChat UI Kit components. Each component supports customization of colors, typography, and icons.
+
+---
+
+## Styling Pattern
+
+
+
+
+Components read styles from XML theme attributes. The pattern is:
+
+1. Create a custom style extending the component's parent style
+2. Override the attributes you want to change
+3. Assign your custom style to `AppTheme` via the component's theme attribute
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+You can also set fonts globally:
+
+```xml themes.xml lines
+
+```
+
+
+
+
+Components accept a `style` parameter — a data class with `.default()` factory and `.copy()` for overrides:
+
+```kotlin lines
+CometChatConversations(
+ style = CometChatConversationsStyle.default().copy(
+ backgroundColor = Color(0xFFFFF9F5),
+ titleTextColor = Color(0xFFF76808)
+ )
+)
+```
+
+Nested styles (e.g., avatar inside conversations) are overridden the same way:
+
+```kotlin lines
+CometChatConversations(
+ style = CometChatConversationsStyle.default().copy(
+ avatarStyle = CometChatAvatarStyle.default().copy(
+ backgroundColor = Color(0xFFFBAA75),
+ cornerRadius = 8.dp
+ )
+ )
+)
+```
+
+
+
+
+---
+
+## Chat Lists & Messaging
+
+### Conversation List
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ style = CometChatConversationsStyle.default().copy(
+ avatarStyle = CometChatAvatarStyle.default().copy(
+ backgroundColor = Color(0xFFFBAA75),
+ cornerRadius = 8.dp
+ ),
+ badgeStyle = CometChatBadgeStyle.default().copy(
+ backgroundColor = Color(0xFFF76808),
+ textColor = Color.White
+ )
+ )
+)
+```
+
+
+
+
+### Users
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatUsers(
+ style = CometChatUsersStyle.default().copy(
+ separatorColor = Color(0xFFF76808),
+ titleTextColor = Color(0xFFF76808)
+ )
+)
+```
+
+
+
+
+### Groups
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatGroups(
+ style = CometChatGroupsStyle.default().copy(
+ separatorColor = Color(0xFFF76808),
+ titleTextColor = Color(0xFFF76808)
+ )
+)
+```
+
+
+
+
+### Message Header
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatMessageHeader(
+ style = CometChatMessageHeaderStyle.default().copy(
+ titleTextColor = Color(0xFFF76808)
+ )
+)
+```
+
+
+
+
+### Message List
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatMessageList(
+ style = CometChatMessageListStyle.default().copy(
+ backgroundColor = Color(0xFFFEEDE1),
+ outgoingMessageBubbleStyle = CometChatOutgoingMessageBubbleStyle.default().copy(
+ backgroundColor = Color(0xFFF76808)
+ )
+ )
+)
+```
+
+
+
+
+### Message Composer
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatMessageComposer(
+ style = CometChatMessageComposerStyle.default().copy(
+ attachmentIconTint = Color(0xFFF76808),
+ voiceRecordingIconTint = Color(0xFFF76808),
+ aiIconTint = Color(0xFFF76808)
+ )
+)
+```
+
+
+
+
+### Group Members
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatGroupMembers(
+ style = CometChatGroupMembersStyle.default().copy(
+ separatorColor = Color(0xFFF76808),
+ titleTextColor = Color(0xFFF76808)
+ )
+)
+```
+
+
+
+
+### Thread Header
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatThreadHeader(
+ style = CometChatThreadHeaderStyle.default().copy(
+ backgroundColor = Color(0xFFFEEDE1),
+ replyCountTextColor = Color(0xFFF76808)
+ )
+)
+```
+
+
+
+
+---
+
+## Calling UI
+
+### Call Logs
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatCallLogs(
+ style = CometChatCallLogsStyle.default().copy(
+ separatorColor = Color(0xFFF76808),
+ titleTextColor = Color(0xFFF76808)
+ )
+)
+```
+
+
+
+
+### Incoming Call
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatIncomingCall(
+ call = call,
+ style = CometChatIncomingCallStyle.default().copy(
+ backgroundColor = Color(0xFFAA9EE8)
+ )
+)
+```
+
+
+
+
+### Outgoing Call
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatOutgoingCall(
+ call = call,
+ style = CometChatOutgoingCallStyle.default().copy(
+ avatarStyle = CometChatAvatarStyle.default().copy(
+ backgroundColor = Color(0xFFFBAA75)
+ )
+ )
+)
+```
+
+
+
+
+---
+
+## Base Components
+
+### Avatar
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+// Globally via CometChatConversations, CometChatUsers, etc.
+style = ComponentStyle.default().copy(
+ avatarStyle = CometChatAvatarStyle.default().copy(
+ backgroundColor = Color(0xFFFBAA75),
+ cornerRadius = 8.dp
+ )
+)
+```
+
+
+
+
+### Badge
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+// Via parent component style
+style = CometChatConversationsStyle.default().copy(
+ badgeStyle = CometChatBadgeStyle.default().copy(
+ backgroundColor = Color(0xFFF44649),
+ textColor = Color.White,
+ cornerRadius = 4.dp
+ )
+)
+```
+
+
+
+
+### Status Indicator
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+// Via parent component style
+style = ComponentStyle.default().copy(
+ statusIndicatorStyle = CometChatStatusIndicatorStyle.default().copy(
+ cornerRadius = 8.dp
+ )
+)
+```
+
+
+
+
+### Reaction List
+
+
+
+
+
+
+
+
+```xml themes.xml lines
+
+
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatReactionList(
+ style = CometChatReactionListStyle.default().copy(
+ tabTextActiveColor = Color(0xFFF76808)
+ )
+)
+```
+
+
+
diff --git a/ui-kit/android/v6/components-overview.mdx b/ui-kit/android/v6/components-overview.mdx
new file mode 100644
index 000000000..ed3f40df8
--- /dev/null
+++ b/ui-kit/android/v6/components-overview.mdx
@@ -0,0 +1,248 @@
+---
+title: "Overview"
+description: "Browse all prebuilt UI components in the CometChat Android UI Kit."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Packages | `com.cometchat:chat-uikit-kotlin` (Kotlin XML Views), `com.cometchat:chat-uikit-compose` (Jetpack Compose) |
+| Required setup | `CometChatUIKit.init()` + `CometChatUIKit.login()` before rendering any component |
+| Shared core | `chatuikit-core` — ViewModels, repositories, use cases, events (shared by both modules) |
+| Calling | Requires separate `com.cometchat:calls-sdk-android` package |
+
+
+
+## Architecture
+
+The UI Kit is a set of independent components that compose into chat layouts. A typical chat layout uses four core components:
+
+- `CometChatConversations` — list of recent conversations
+- `CometChatMessageHeader` — toolbar with avatar, name, status, typing indicator
+- `CometChatMessageList` — scrollable message feed with reactions, receipts, threads
+- `CometChatMessageComposer` — rich input with attachments, mentions, voice notes
+
+Selecting a conversation yields a `User` or `Group` object. Pass it to the message components to load the chat.
+
+Components communicate via `CometChatEvents` — a SharedFlow-based event bus. See [Events](/ui-kit/android/v6/events).
+
+---
+
+## Component Catalog
+
+### Conversations and Lists
+
+| Component | Purpose | Page |
+| --- | --- | --- |
+| `CometChatConversations` | Scrollable list of recent conversations | [Conversations](/ui-kit/android/v6/conversations) |
+| `CometChatUsers` | Scrollable list of users | [Users](/ui-kit/android/v6/users) |
+| `CometChatGroups` | Scrollable list of groups | [Groups](/ui-kit/android/v6/groups) |
+| `CometChatGroupMembers` | Scrollable list of group members | [Group Members](/ui-kit/android/v6/group-members) |
+
+### Messages
+
+| Component | Purpose | Page |
+| --- | --- | --- |
+| `CometChatMessageHeader` | Toolbar with avatar, name, status, typing | [Message Header](/ui-kit/android/v6/message-header) |
+| `CometChatMessageList` | Message feed with reactions, receipts, threads | [Message List](/ui-kit/android/v6/message-list) |
+| `CometChatMessageComposer` | Rich input with attachments, mentions, voice | [Message Composer](/ui-kit/android/v6/message-composer) |
+| `CometChatThreadHeader` | Parent message bubble and reply count | [Thread Header](/ui-kit/android/v6/threaded-messages-header) |
+
+### Calling
+
+| Component | Purpose | Page |
+| --- | --- | --- |
+| `CometChatCallButtons` | Voice and video call buttons | [Call Buttons](/ui-kit/android/v6/call-buttons) |
+| `CometChatIncomingCall` | Incoming call notification | [Incoming Call](/ui-kit/android/v6/incoming-call) |
+| `CometChatOutgoingCall` | Outgoing call screen | [Outgoing Call](/ui-kit/android/v6/outgoing-call) |
+| `CometChatCallLogs` | Call history list | [Call Logs](/ui-kit/android/v6/call-logs) |
+
+---
+
+## Component API Pattern
+
+All components share a consistent API surface across both modules.
+
+### Setting User or Group
+
+
+
+
+
+```kotlin lines
+messageHeader.setUser(user)
+messageList.setUser(user)
+messageComposer.setUser(user)
+
+// Or for group chat
+messageHeader.setGroup(group)
+messageList.setGroup(group)
+messageComposer.setGroup(group)
+```
+
+
+
+
+```kotlin lines
+CometChatMessageHeader(user = user)
+CometChatMessageList(user = user)
+CometChatMessageComposer(user = user)
+
+// Or for group chat
+CometChatMessageHeader(group = group)
+CometChatMessageList(group = group)
+CometChatMessageComposer(group = group)
+```
+
+
+
+
+### Callbacks
+
+
+
+
+```kotlin lines
+conversations.setOnItemClick { conversation -> /* navigate */ }
+conversations.setOnError { exception -> /* handle error */ }
+conversations.setOnLoad { list -> /* data loaded */ }
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onItemClick = { conversation -> /* navigate */ },
+ onError = { exception -> /* handle error */ },
+ onLoad = { list -> /* data loaded */ }
+)
+```
+
+
+
+
+### Data Filtering
+
+
+
+
+```kotlin lines
+conversations.setConversationsRequestBuilder(
+ ConversationsRequest.ConversationsRequestBuilder().setLimit(20)
+)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ conversationsRequestBuilder = ConversationsRequest.ConversationsRequestBuilder().setLimit(20)
+)
+```
+
+
+
+
+### View Slots
+
+Replace specific regions of a component's UI. See [View Slots](/ui-kit/android/v6/customization-view-slots).
+
+
+
+
+```kotlin lines
+conversations.setSubtitleView(object : ConversationsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatConversationsListItemsBinding): View {
+ return CustomSubtitleView(context)
+ }
+ override fun bindView(context: Context, createdView: View, conversation: Conversation, ...) {
+ (createdView as CustomSubtitleView).bind(conversation)
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ subtitleView = { conversation, typingIndicator ->
+ Text(conversation.lastMessage?.text ?: "")
+ }
+)
+```
+
+
+
+
+### Styles
+
+See [Component Styling](/ui-kit/android/v6/component-styling).
+
+
+
+
+XML theme attributes in `themes.xml`:
+
+```xml lines
+
+```
+
+
+
+
+Style data classes via parameters:
+
+```kotlin lines
+CometChatConversations(
+ style = CometChatConversationsStyle.default().copy(
+ backgroundColor = Color(0xFFF5F5F5)
+ )
+)
+```
+
+
+
+
+### Events
+
+Global inter-component communication via `CometChatEvents`:
+
+```kotlin lines
+// Subscribe to message events
+viewModelScope.launch {
+ CometChatEvents.messageEvents.collect { event ->
+ when (event) {
+ is CometChatMessageEvent.MessageSent -> { /* handle */ }
+ is CometChatMessageEvent.MessageDeleted -> { /* handle */ }
+ else -> {}
+ }
+ }
+}
+```
+
+See [Events](/ui-kit/android/v6/events) for the full reference.
+
+---
+
+## Next Steps
+
+
+
+ Chat features included out of the box
+
+
+ Customize colors, fonts, and styles
+
+
+ Deep customization via ViewModels, styles, and view slots
+
+
+ Task-oriented tutorials for common patterns
+
+
diff --git a/ui-kit/android/v6/conversation-message-view.mdx b/ui-kit/android/v6/conversation-message-view.mdx
new file mode 100644
index 000000000..61f3ed5f9
--- /dev/null
+++ b/ui-kit/android/v6/conversation-message-view.mdx
@@ -0,0 +1,446 @@
+---
+title: "Building A Conversation List + Message View"
+sidebarTitle: "Conversation List + Message View"
+description: "Build a conversation list with a full-screen message view using the Kotlin XML Views or Jetpack Compose UI Kit."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Components | `CometChatConversations`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` |
+| Layout | Sequential navigation — conversation list → full-screen message view |
+| Prerequisite | Complete [Kotlin Integration](/ui-kit/android/v6/getting-started-kotlin) or [Jetpack Compose Integration](/ui-kit/android/v6/getting-started-jetpack) Steps 1–3 first |
+| Pattern | WhatsApp, Slack, Telegram |
+
+
+
+This guide builds a sequential navigation chat layout — conversation list as the entry point, tap a conversation to open a full-screen message view.
+
+This assumes you've already completed the integration guide for your chosen UI toolkit (project created, dependencies installed, init + login working).
+
+---
+
+## What You're Building
+
+Three sections working together:
+
+1. **Conversation list** — shows all active conversations (users and groups)
+2. **Message header** — displays user/group name, avatar, and status
+3. **Message list + composer** — chat history with real-time updates and text input
+
+
+
+This implementation uses Android's standard Activity navigation: `ConversationActivity` displays the list, user taps a conversation, `MessageActivity` launches with the selected user/group data via Intent extras.
+
+
+This implementation uses Compose state to manage navigation between the conversation list and message screen — no Activities or Fragments needed beyond your `MainActivity`.
+
+
+
+---
+
+## Step 1: Set Up the Conversation List
+
+
+
+
+Create a new Activity called `ConversationActivity` to display the list of conversations.
+
+**Layout** — `activity_conversation.xml`:
+
+```xml activity_conversation.xml lines
+
+
+
+
+
+```
+
+**Activity** — `ConversationActivity.kt`:
+
+```kotlin ConversationActivity.kt lines
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import com.cometchat.chat.models.Group
+import com.cometchat.chat.models.User
+import com.cometchat.uikit.kotlin.presentation.conversations.ui.CometChatConversations
+
+class ConversationActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_conversation)
+
+ val conversations = findViewById(R.id.conversations)
+
+ conversations.setTitle("Chats")
+ conversations.setOnItemClick { conversation ->
+ val intent = Intent(this, MessageActivity::class.java)
+ when (val entity = conversation.conversationWith) {
+ is User -> intent.putExtra("user", entity)
+ is Group -> intent.putExtra("group", entity)
+ else -> Log.e("ConversationActivity", "Unknown conversation type")
+ }
+ startActivity(intent)
+ }
+ }
+}
+```
+
+
+You must use an activity that supports the **lifecycle** API (`AppCompatActivity`, `ComponentActivity`, or `FragmentActivity`) to properly manage the UI Kit's lifecycle events.
+
+
+
+
+
+Create a `ChatApp.kt` file with the root composable that manages navigation between the conversation list and message screen:
+
+```kotlin ChatApp.kt lines
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import com.cometchat.chat.models.Group
+import com.cometchat.chat.models.User
+
+@Composable
+fun ChatApp() {
+ var selectedUser by remember { mutableStateOf(null) }
+ var selectedGroup by remember { mutableStateOf(null) }
+
+ val inChat = selectedUser != null || selectedGroup != null
+
+ if (!inChat) {
+ ConversationsScreen(
+ onConversationClick = { user, group ->
+ selectedUser = user
+ selectedGroup = group
+ }
+ )
+ } else {
+ MessageScreen(
+ user = selectedUser,
+ group = selectedGroup,
+ onBack = {
+ selectedUser = null
+ selectedGroup = null
+ }
+ )
+ }
+}
+```
+
+Add the `ConversationsScreen` composable:
+
+```kotlin ChatApp.kt lines
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import com.cometchat.uikit.compose.presentation.conversations.ui.CometChatConversations
+
+@Composable
+fun ConversationsScreen(
+ onConversationClick: (User?, Group?) -> Unit
+) {
+ CometChatConversations(
+ modifier = Modifier.fillMaxSize(),
+ title = "Chats",
+ onItemClick = { conversation ->
+ when (val entity = conversation.conversationWith) {
+ is User -> onConversationClick(entity, null)
+ is Group -> onConversationClick(null, entity)
+ }
+ }
+ )
+}
+```
+
+
+
+
+---
+
+## Step 2: Set Up the Message Screen
+
+
+
+
+Create a new Activity — `MessageActivity` to display the chat interface.
+
+**Layout** — `activity_message.xml`:
+
+```xml activity_message.xml lines
+
+
+
+
+
+
+
+
+
+```
+
+**Activity** — `MessageActivity.kt`:
+
+```kotlin MessageActivity.kt lines
+import android.os.Bundle
+import android.widget.Toast
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import com.cometchat.chat.models.Group
+import com.cometchat.chat.models.User
+import com.cometchat.uikit.kotlin.presentation.messagecomposer.ui.CometChatMessageComposer
+import com.cometchat.uikit.kotlin.presentation.messageheader.ui.CometChatMessageHeader
+import com.cometchat.uikit.kotlin.presentation.messagelist.ui.CometChatMessageList
+
+class MessageActivity : AppCompatActivity() {
+
+ private lateinit var messageHeader: CometChatMessageHeader
+ private lateinit var messageList: CometChatMessageList
+ private lateinit var messageComposer: CometChatMessageComposer
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_message)
+
+ messageHeader = findViewById(R.id.message_header)
+ messageList = findViewById(R.id.message_list)
+ messageComposer = findViewById(R.id.message_composer)
+
+ val user = intent.getSerializableExtra("user") as? User
+ val group = intent.getSerializableExtra("group") as? Group
+
+ when {
+ user != null -> {
+ messageHeader.setUser(user)
+ messageList.setUser(user)
+ messageComposer.setUser(user)
+ }
+ group != null -> {
+ messageHeader.setGroup(group)
+ messageList.setGroup(group)
+ messageComposer.setGroup(group)
+ }
+ else -> {
+ Toast.makeText(this, "Missing user or group data", Toast.LENGTH_SHORT).show()
+ finish()
+ }
+ }
+
+ messageHeader.setOnBackPress { finish() }
+ }
+}
+```
+
+
+
+
+Add the `MessageScreen` composable with header, list, and composer stacked vertically:
+
+```kotlin ChatApp.kt lines
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.consumeWindowInsets
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.imePadding
+import androidx.compose.foundation.layout.navigationBarsPadding
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.statusBars
+import androidx.compose.material3.Scaffold
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import com.cometchat.chat.models.Group
+import com.cometchat.chat.models.User
+import com.cometchat.uikit.compose.presentation.messagecomposer.ui.CometChatMessageComposer
+import com.cometchat.uikit.compose.presentation.messageheader.ui.CometChatMessageHeader
+import com.cometchat.uikit.compose.presentation.messagelist.ui.CometChatMessageList
+
+@Composable
+fun MessageScreen(
+ user: User? = null,
+ group: Group? = null,
+ onBack: () -> Unit
+) {
+ Scaffold(
+ contentWindowInsets = WindowInsets.statusBars
+ ) { paddingValues ->
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(paddingValues)
+ .consumeWindowInsets(paddingValues)
+ .navigationBarsPadding()
+ .imePadding()
+ ) {
+ CometChatMessageHeader(
+ modifier = Modifier.fillMaxWidth(),
+ user = user,
+ group = group,
+ hideBackButton = false,
+ onBackPress = onBack
+ )
+
+ CometChatMessageList(
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1f),
+ user = user,
+ group = group
+ )
+
+ CometChatMessageComposer(
+ modifier = Modifier.fillMaxWidth(),
+ user = user,
+ group = group
+ )
+ }
+ }
+}
+```
+
+
+
+
+---
+
+## Step 3: Update MainActivity
+
+
+
+
+Update your `MainActivity` to launch `ConversationActivity` after successful login:
+
+```kotlin MainActivity.kt lines
+private fun loginUser() {
+ CometChatUIKit.login("cometchat-uid-1", object : CometChat.CallbackListener() {
+ override fun onSuccess(user: User) {
+ Log.d(TAG, "Login successful: ${user.uid}")
+
+ // Launch Conversation List + Message View
+ startActivity(Intent(this@MainActivity, ConversationActivity::class.java))
+ }
+
+ override fun onError(e: CometChatException) {
+ Log.e(TAG, "Login failed: ${e.message}")
+ }
+ })
+}
+```
+
+
+
+
+Update your `MainActivity` to render `ChatApp()` after successful login:
+
+```kotlin MainActivity.kt lines
+setContent {
+ when {
+ error != null -> {
+ Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+ Text(error ?: "Unknown error")
+ }
+ }
+ !isReady -> {
+ Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+ CircularProgressIndicator()
+ }
+ }
+ else -> {
+ ChatApp()
+ }
+ }
+}
+```
+
+
+
+
+---
+
+## Step 4: Register Activities & Permissions
+
+
+
+
+Add the new activities to your `AndroidManifest.xml`:
+
+```xml AndroidManifest.xml lines
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+
+No additional activities needed — everything runs inside your existing `MainActivity`.
+
+
+
+
+Ensure you've added the required permissions in your `AndroidManifest.xml`:
+
+```xml AndroidManifest.xml lines
+
+
+```
+
+---
+
+## Next Steps
+
+
+
+ Explore all available UI Kit components and their customization options
+
+
+ Customize colors, fonts, and styles to match your brand
+
+
+ Back to the main integration guide
+
+
+ Add capabilities like threaded messages, blocking, and group management
+
+
diff --git a/ui-kit/android/v6/conversations.mdx b/ui-kit/android/v6/conversations.mdx
new file mode 100644
index 000000000..ffbc2278f
--- /dev/null
+++ b/ui-kit/android/v6/conversations.mdx
@@ -0,0 +1,952 @@
+---
+title: "Conversations"
+description: "Scrollable list of recent one-on-one and group conversations for the logged-in user."
+---
+
+`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 `onItemClick`. Wire it to `CometChatMessageHeader`, `CometChatMessageList`, and `CometChatMessageComposer` to build a standard chat layout.
+
+
+
+
+```xml activity_chat.xml lines
+
+```
+
+```kotlin lines
+val conversations = findViewById(R.id.conversations)
+
+conversations.setOnItemClick { conversation ->
+ when (val entity = conversation.conversationWith) {
+ is User -> navigateToUserChat(entity)
+ is Group -> navigateToGroupChat(entity)
+ }
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ modifier = Modifier.fillMaxSize(),
+ onItemClick = { conversation ->
+ when (val entity = conversation.conversationWith) {
+ is User -> navigateToUserChat(entity)
+ is Group -> navigateToGroupChat(entity)
+ }
+ }
+)
+```
+
+
+
+
+> See the [Conversation List + Message View](/ui-kit/android/v6/conversation-message-view) guide for a complete layout.
+
+---
+
+## Quick Start
+
+
+
+
+Add to your layout XML:
+
+```xml lines
+
+```
+
+Or programmatically:
+
+```kotlin lines
+override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(CometChatConversations(this))
+}
+```
+
+
+
+
+```kotlin lines
+@Composable
+fun ConversationsScreen() {
+ CometChatConversations(
+ modifier = Modifier.fillMaxSize()
+ )
+}
+```
+
+
+
+
+
+Prerequisites: CometChat SDK initialized with `CometChatUIKit.init()`, a user logged in, and the UI Kit dependency added.
+
+Or in a Fragment:
+
+
+
+
+```kotlin lines
+override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ return CometChatConversations(requireContext())
+}
+```
+
+
+
+
+```kotlin lines
+override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ return ComposeView(requireContext()).apply {
+ setContent { CometChatConversations() }
+ }
+}
+```
+
+
+
+
+---
+
+## Filtering Conversations
+
+
+
+
+Pass a `ConversationsRequest.ConversationsRequestBuilder` to control what loads:
+
+```kotlin lines
+conversations.setConversationsRequestBuilder(
+ ConversationsRequest.ConversationsRequestBuilder()
+ .setConversationType(CometChatConstants.CONVERSATION_TYPE_USER)
+ .setLimit(20)
+)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ conversationsRequestBuilder = ConversationsRequest.ConversationsRequestBuilder()
+ .setConversationType(CometChatConstants.CONVERSATION_TYPE_USER)
+ .setLimit(20)
+)
+```
+
+
+
+
+### Filter Recipes
+
+| Recipe | Builder method |
+| --- | --- |
+| Only user conversations | `.setConversationType(CONVERSATION_TYPE_USER)` |
+| Only group conversations | `.setConversationType(CONVERSATION_TYPE_GROUP)` |
+| Limit per page | `.setLimit(10)` |
+| With tags | `.setTags(listOf("vip")).withTags(true)` |
+| Filter by user tags | `.withUserAndGroupTags(true).setUserTags(listOf("premium"))` |
+| Filter by group tags | `.withUserAndGroupTags(true).setGroupTags(listOf("support"))` |
+
+
+Pass the builder object, not the result of `.build()`. The component calls `.build()` internally. Default page size is 30 with infinite scroll.
+
+
+---
+
+## Actions and Events
+
+### Callback Methods
+
+#### `onItemClick`
+
+Fires when a conversation row is tapped. Primary navigation hook.
+
+
+
+
+```kotlin lines
+conversations.setOnItemClick { conversation ->
+ // Navigate to chat screen
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onItemClick = { conversation ->
+ // Navigate to chat screen
+ }
+)
+```
+
+
+
+
+> Replaces the default item-click behavior. Your custom lambda executes instead of the built-in navigation.
+
+#### `onItemLongClick`
+
+Fires when a conversation row is long-pressed. Use for additional actions like delete or select.
+
+
+
+
+```kotlin lines
+conversations.setOnItemLongClick { conversation ->
+ // Show context menu
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onItemLongClick = { conversation ->
+ // Show context menu
+ }
+)
+```
+
+
+
+
+#### `onBackPress`
+
+Fires when the user presses the back button in the toolbar.
+
+
+
+
+```kotlin lines
+conversations.setOnBackPress {
+ finish()
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onBackPress = { /* navigate back */ }
+)
+```
+
+
+
+
+#### `onSearchClick`
+
+Fires when the user taps the search icon in the toolbar.
+
+
+
+
+```kotlin lines
+conversations.setOnSearchClick {
+ // Open search screen
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onSearchClick = { /* open search */ }
+)
+```
+
+
+
+
+#### `onSelection`
+
+Fires when conversations are selected/deselected in multi-select mode.
+
+
+
+
+```kotlin lines
+conversations.setSelectionMode(UIKitConstants.SelectionMode.MULTIPLE)
+conversations.setOnSelection { selectedConversations ->
+ updateToolbar(selectedConversations.size)
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ selectionMode = UIKitConstants.SelectionMode.MULTIPLE,
+ onSelection = { selectedConversations ->
+ updateToolbar(selectedConversations.size)
+ }
+)
+```
+
+
+
+
+#### `onError`
+
+Fires on internal errors (network failure, auth issue, SDK exception).
+
+
+
+
+```kotlin lines
+conversations.setOnError { exception ->
+ Log.e("Conversations", "Error: ${exception.message}")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onError = { exception ->
+ Log.e("Conversations", "Error: ${exception.message}")
+ }
+)
+```
+
+
+
+
+#### `onLoad`
+
+Fires when the list is successfully fetched and loaded.
+
+
+
+
+```kotlin lines
+conversations.setOnLoad { conversations ->
+ Log.d("Conversations", "Loaded ${conversations.size}")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onLoad = { conversations ->
+ Log.d("Conversations", "Loaded ${conversations.size}")
+ }
+)
+```
+
+
+
+
+#### `onEmpty`
+
+Fires when the list is empty after loading.
+
+
+
+
+```kotlin lines
+conversations.setOnEmpty {
+ Log.d("Conversations", "No conversations")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onEmpty = { /* no conversations */ }
+)
+```
+
+
+
+
+### Global Events
+
+The component emits events via `CometChatEvents` that can be subscribed to from anywhere:
+
+```kotlin lines
+viewModelScope.launch {
+ CometChatEvents.conversationEvents.collect { event ->
+ when (event) {
+ is CometChatConversationEvent.ConversationDeleted -> { /* handle */ }
+ is CometChatConversationEvent.ConversationUpdated -> { /* handle */ }
+ }
+ }
+}
+```
+
+### 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 |
+
+---
+
+## Functionality
+
+| Method (Kotlin XML) | Compose Parameter | Description |
+| --- | --- | --- |
+| `setBackIconVisibility(View.VISIBLE)` | `hideBackIcon = false` | Toggle back button |
+| `setToolbarVisibility(View.GONE)` | `hideToolbar = true` | Toggle toolbar |
+| `setSearchBoxVisibility(View.GONE)` | `hideSearchBox = true` | Toggle search box |
+| `setDisableSoundForMessages(true)` | `disableSoundForMessages = true` | Disable message sounds |
+| `setCustomSoundForMessages(R.raw.sound)` | `customSoundForMessages = R.raw.sound` | Custom message sound |
+| `setSelectionMode(MULTIPLE)` | `selectionMode = MULTIPLE` | Enable selection mode |
+| `setTitle("Chats")` | `title = "Chats"` | Custom toolbar title |
+| `setSearchPlaceholderText("Search...")` | `searchPlaceholderText = "Search..."` | Search placeholder |
+
+---
+
+## Custom View Slots
+
+### Leading View
+
+Replace the avatar / left section.
+
+
+
+
+```kotlin lines
+conversations.setLeadingView(object : ConversationsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatConversationsListItemsBinding): View {
+ return ImageView(context).apply {
+ layoutParams = ViewGroup.LayoutParams(48.dp, 48.dp)
+ }
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, conversation: Conversation,
+ typingIndicator: TypingIndicator?, holder: RecyclerView.ViewHolder,
+ conversations: List, position: Int
+ ) {
+ val imageView = createdView as ImageView
+ // Load avatar image
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ leadingView = { conversation, typingIndicator ->
+ CometChatAvatar(
+ imageUrl = conversation.conversationWith?.avatar,
+ name = conversation.conversationWith?.name
+ )
+ }
+)
+```
+
+
+
+
+### Title View
+
+Replace the name / title text.
+
+
+
+
+```kotlin lines
+conversations.setTitleView(object : ConversationsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatConversationsListItemsBinding): View {
+ return TextView(context)
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, conversation: Conversation,
+ typingIndicator: TypingIndicator?, holder: RecyclerView.ViewHolder,
+ conversations: List, position: Int
+ ) {
+ (createdView as TextView).text = conversation.conversationWith?.name ?: ""
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ titleView = { conversation, _ ->
+ Text(
+ text = conversation.conversationWith?.name ?: "",
+ style = CometChatTheme.typography.heading4Medium
+ )
+ }
+)
+```
+
+
+
+
+### Subtitle View
+
+Replace the last message preview.
+
+
+
+
+```kotlin lines
+conversations.setSubtitleView(object : ConversationsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatConversationsListItemsBinding): View {
+ return TextView(context).apply { maxLines = 1; ellipsize = TextUtils.TruncateAt.END }
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, conversation: Conversation,
+ typingIndicator: TypingIndicator?, holder: RecyclerView.ViewHolder,
+ conversations: List, position: Int
+ ) {
+ val textView = createdView as TextView
+ if (typingIndicator != null) {
+ textView.text = "typing..."
+ } else {
+ textView.text = when (val msg = conversation.lastMessage) {
+ is TextMessage -> msg.text
+ is MediaMessage -> "📎 ${msg.attachment?.fileExtension ?: "Media"}"
+ else -> "New conversation"
+ }
+ }
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ subtitleView = { conversation, typingIndicator ->
+ val text = if (typingIndicator != null) "typing..." else {
+ when (val msg = conversation.lastMessage) {
+ is TextMessage -> msg.text ?: ""
+ is MediaMessage -> "📎 ${msg.attachment?.fileExtension ?: "Media"}"
+ else -> "New conversation"
+ }
+ }
+ Text(text, maxLines = 1, overflow = TextOverflow.Ellipsis)
+ }
+)
+```
+
+
+
+
+### Trailing View
+
+Replace the timestamp / badge / right section.
+
+
+
+
+```kotlin lines
+conversations.setTrailingView(object : ConversationsViewHolderListener() {
+ override fun createView(context: Context, binding: CometchatConversationsListItemsBinding): View {
+ return TextView(context)
+ }
+
+ override fun bindView(
+ context: Context, createdView: View, conversation: Conversation,
+ typingIndicator: TypingIndicator?, holder: RecyclerView.ViewHolder,
+ conversations: List, position: Int
+ ) {
+ (createdView as TextView).text = "${conversation.unreadMessageCount} unread"
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ trailingView = { conversation, _ ->
+ if (conversation.unreadMessageCount > 0) {
+ Badge { Text("${conversation.unreadMessageCount}") }
+ }
+ }
+)
+```
+
+
+
+
+### State Views
+
+
+
+
+```kotlin lines
+conversations.setEmptyView(customEmptyView)
+conversations.setErrorView(customErrorView)
+conversations.setLoadingView(customLoadingView)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ emptyView = { Text("No conversations yet") },
+ errorView = { onRetry -> Button(onClick = onRetry) { Text("Retry") } },
+ loadingView = { CircularProgressIndicator() }
+)
+```
+
+
+
+
+### Overflow Menu
+
+
+
+
+```kotlin lines
+conversations.setOverflowMenu(ImageButton(context).apply {
+ setImageResource(R.drawable.ic_filter)
+ setOnClickListener { /* show filter */ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ overflowMenu = {
+ IconButton(onClick = { /* show filter */ }) {
+ Icon(painterResource(R.drawable.ic_filter), "Filter")
+ }
+ }
+)
+```
+
+
+
+
+---
+
+## Menu Options
+
+
+
+
+```kotlin lines
+// Replace all options
+conversations.setOptions { context, conversation ->
+ listOf(
+ CometChatPopupMenu.MenuItem(id = "archive", name = "Archive", onClick = { /* ... */ }),
+ CometChatPopupMenu.MenuItem(id = "mute", name = "Mute", onClick = { /* ... */ })
+ )
+}
+
+// Append to defaults
+conversations.setAddOptions { context, conversation ->
+ listOf(
+ CometChatPopupMenu.MenuItem(id = "pin", name = "Pin", onClick = { /* ... */ })
+ )
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ options = { context, conversation ->
+ listOf(
+ MenuItem(id = "archive", name = "Archive", onClick = { /* ... */ }),
+ MenuItem(id = "mute", name = "Mute", onClick = { /* ... */ })
+ )
+ },
+ addOptions = { context, conversation ->
+ listOf(MenuItem(id = "pin", name = "Pin", onClick = { /* ... */ }))
+ }
+)
+```
+
+
+
+
+---
+
+## Common Patterns
+
+### Minimal list — hide all chrome
+
+
+
+
+```kotlin lines
+conversations.setToolbarVisibility(View.GONE)
+conversations.setSearchBoxVisibility(View.GONE)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ hideToolbar = true,
+ hideSearchBox = true
+)
+```
+
+
+
+
+### Users-only conversations
+
+
+
+
+```kotlin lines
+conversations.setConversationsRequestBuilder(
+ ConversationsRequest.ConversationsRequestBuilder()
+ .setConversationType(CometChatConstants.CONVERSATION_TYPE_USER)
+)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ conversationsRequestBuilder = ConversationsRequest.ConversationsRequestBuilder()
+ .setConversationType(CometChatConstants.CONVERSATION_TYPE_USER)
+)
+```
+
+
+
+
+### Custom date formatting
+
+
+
+
+```kotlin lines
+conversations.setDateTimeFormatter(object : DateTimeFormatterCallback {
+ override fun today(timestamp: Long) = "Today"
+ override fun yesterday(timestamp: Long) = "Yesterday"
+ override fun otherDays(timestamp: Long) = SimpleDateFormat("MMM d", Locale.getDefault()).format(Date(timestamp))
+ override fun time(timestamp: Long) = SimpleDateFormat("h:mm a", Locale.getDefault()).format(Date(timestamp))
+ override fun minutes(diff: Long, timestamp: Long) = "${diff}m ago"
+ override fun hours(diff: Long, timestamp: Long) = "${diff}h ago"
+ override fun lastWeek(timestamp: Long) = "Last week"
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ dateTimeFormatter = object : DateTimeFormatterCallback {
+ override fun today(timestamp: Long) = "Today"
+ override fun yesterday(timestamp: Long) = "Yesterday"
+ override fun otherDays(timestamp: Long) = SimpleDateFormat("MMM d", Locale.getDefault()).format(Date(timestamp))
+ override fun time(timestamp: Long) = SimpleDateFormat("h:mm a", Locale.getDefault()).format(Date(timestamp))
+ override fun minutes(diff: Long, timestamp: Long) = "${diff}m ago"
+ override fun hours(diff: Long, timestamp: Long) = "${diff}h ago"
+ override fun lastWeek(timestamp: Long) = "Last week"
+ }
+)
+```
+
+
+
+
+---
+
+## Advanced Methods
+
+### Programmatic Selection
+
+
+
+
+```kotlin lines
+// Enable selection
+conversations.setSelectionMode(UIKitConstants.SelectionMode.MULTIPLE)
+
+// Select a conversation
+conversations.selectConversation(conversation, UIKitConstants.SelectionMode.MULTIPLE)
+
+// Get selected
+val selected = conversations.getSelectedConversations()
+
+// Clear
+conversations.clearSelection()
+```
+
+
+
+
+Selection is managed via the `selectionMode` and `onSelection` parameters. The component handles selection state internally.
+
+
+
+
+### ViewModel Access
+
+```kotlin lines
+val factory = CometChatConversationsViewModelFactory(
+ repository = MyCustomRepository() // optional
+)
+val viewModel = ViewModelProvider(this, factory)
+ .get(CometChatConversationsViewModel::class.java)
+```
+
+
+
+
+```kotlin lines
+conversations.setViewModel(viewModel)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ conversationsViewModel = viewModel
+)
+```
+
+
+
+
+See [ViewModel & Data](/ui-kit/android/v6/customization-viewmodel-data) for ListOperations, state observation, and custom repositories.
+
+---
+
+## Style
+
+
+
+
+Define a custom style in `themes.xml`:
+
+```xml themes.xml lines
+
+
+
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ style = CometChatConversationsStyle.default().copy(
+ backgroundColor = Color(0xFFF5F5F5),
+ titleTextColor = Color(0xFF141414),
+ searchBoxStyle = CometChatSearchBoxStyle.default().copy(
+ backgroundColor = Color(0xFFFFFFFF)
+ ),
+ itemStyle = CometChatConversationsItemStyle.default().copy(
+ backgroundColor = Color.White,
+ titleTextColor = Color(0xFF141414),
+ subtitleTextColor = Color(0xFF727272),
+ avatarStyle = CometChatAvatarStyle.default().copy(cornerRadius = 12.dp),
+ badgeStyle = CometChatBadgeStyle.default().copy(backgroundColor = Color(0xFFF76808)),
+ dateStyle = CometChatDateStyle.default().copy(textColor = Color(0xFFA1A1A1)),
+ receiptStyle = CometChatReceiptStyle.default().copy(),
+ statusIndicatorStyle = CometChatStatusIndicatorStyle.default().copy(),
+ typingIndicatorStyle = CometChatTypingIndicatorStyle.default().copy()
+ )
+ )
+)
+```
+
+
+
+
+### Style Properties
+
+| Property | Description |
+| --- | --- |
+| `backgroundColor` | List background color |
+| `titleTextColor` | Toolbar title color |
+| `searchBoxStyle` | Search box appearance |
+| `itemStyle.backgroundColor` | Row background |
+| `itemStyle.selectedBackgroundColor` | Selected row background |
+| `itemStyle.titleTextColor` | Conversation name color |
+| `itemStyle.subtitleTextColor` | Last message preview color |
+| `itemStyle.separatorColor` | Row separator color |
+| `itemStyle.avatarStyle` | Avatar appearance |
+| `itemStyle.badgeStyle` | Unread badge appearance |
+| `itemStyle.dateStyle` | Timestamp appearance |
+| `itemStyle.receiptStyle` | Read receipt icons |
+| `itemStyle.statusIndicatorStyle` | Online/offline indicator |
+| `itemStyle.typingIndicatorStyle` | Typing indicator text |
+| `itemStyle.mentionStyle` | Mention highlight style |
+
+See [Component Styling](/ui-kit/android/v6/component-styling) for the full reference.
+
+---
+
+## Next Steps
+
+
+
+ Build a full chat layout with this component
+
+
+ Detailed styling reference with screenshots
+
+
+ Custom ViewModels, repositories, and ListOperations
+
+
+ Replace specific UI regions across all components
+
+
diff --git a/ui-kit/android/v6/core-features.mdx b/ui-kit/android/v6/core-features.mdx
new file mode 100644
index 000000000..11c956d4d
--- /dev/null
+++ b/ui-kit/android/v6/core-features.mdx
@@ -0,0 +1,216 @@
+---
+title: "Core"
+description: "Overview of CometChat's core chat features including instant messaging, media sharing, read receipts, typing indicators, user presence, reactions, mentions, threaded conversations, and moderation."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Packages | `com.cometchat:chat-uikit-kotlin` (Kotlin XML Views), `com.cometchat:chat-uikit-compose` (Jetpack Compose) |
+| Required setup | `CometChatUIKit.init()` then `CometChatUIKit.login()` — must complete before rendering any component |
+| Core features | Instant Messaging, Media Sharing, Read Receipts, Mark as Unread, Typing Indicator, User Presence, Reactions, Mentions, Quoted Reply, Threaded Conversations, Moderation, Report Message, Group Chat |
+| Key components | `CometChatConversations`, `CometChatMessageList`, `CometChatMessageComposer`, `CometChatMessageHeader`, `CometChatUsers`, `CometChatGroups`, `CometChatGroupMembers`, `CometChatMessageInformation`, `CometChatThreadHeader` |
+| Theming | See [Theming](/ui-kit/android/v6/theme-introduction) |
+
+
+
+The UI Kit components work together to deliver a complete chat experience. The sections below map each core feature to the components that power it.
+
+## Instant Messaging
+
+Real-time text messaging — users can send and receive instant messages.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatMessageComposer](/ui-kit/android/v6/message-composer) | Enables users to write and send text messages. |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Renders sent and received messages using text bubbles. |
+
+## Media Sharing
+
+Share images, videos, audio files, and documents within conversations.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatMessageComposer](/ui-kit/android/v6/message-composer) | Provides an action sheet with options for sharing media files. |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Renders media message bubbles — [Image](/ui-kit/android/v6/message-bubble-styling#image-bubble), [File](/ui-kit/android/v6/message-bubble-styling#file-bubble), [Audio](/ui-kit/android/v6/message-bubble-styling#audio-bubble), [Video](/ui-kit/android/v6/message-bubble-styling#video-bubble). |
+
+## Read Receipts
+
+Visibility into message status — delivered and read indicators.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatConversations](/ui-kit/android/v6/conversations) | Displays delivery status of the last message in each conversation item. |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Shows read receipt status on every message bubble. |
+| [CometChatMessageInformation](/ui-kit/android/v6/component-styling#message-information) | Shows detailed delivery and read status for a specific sent message. |
+
+## Mark as Unread
+
+Users can manually mark messages as unread to revisit important conversations later. The message list can start from the first unread message automatically.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Provides the "Mark as unread" option in message actions and supports starting from the first unread message. |
+| [CometChatConversations](/ui-kit/android/v6/conversations) | Reflects updated unread count in real-time. |
+
+## Typing Indicators
+
+Shows when a user is typing a response in real-time.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatConversations](/ui-kit/android/v6/conversations) | Shows real-time typing status in conversation items. |
+| [CometChatMessageHeader](/ui-kit/android/v6/message-header) | Displays a "typing..." indicator when the other user or a group member is typing. |
+
+## User Presence
+
+See whether contacts are online or offline.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatConversations](/ui-kit/android/v6/conversations) | Shows user presence in conversation items. |
+| [CometChatMessageHeader](/ui-kit/android/v6/message-header) | Displays user presence in the chat header. |
+| [CometChatUsers](/ui-kit/android/v6/users) | Shows presence indicators in the user list. |
+| [CometChatGroupMembers](/ui-kit/android/v6/group-members) | Shows presence indicators for group members. |
+
+## Reactions
+
+React to messages with emojis without typing a full response.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Displays reactions on message bubbles and provides the reaction picker. |
+
+## Mentions
+
+Address specific users in a conversation by typing `@` to trigger mention suggestions.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatConversations](/ui-kit/android/v6/conversations) | Shows where users have been mentioned from the conversation list. |
+| [CometChatMessageComposer](/ui-kit/android/v6/message-composer) | Triggers mention suggestions on `@` and inserts formatted mentions. |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Renders mentions with distinct styling in the message flow. |
+
+## Threaded Conversations
+
+Respond directly to a specific message, keeping conversations organized.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatThreadHeader](/ui-kit/android/v6/threaded-messages-header) | Displays all replies made to a particular message. |
+| [CometChatMessageComposer](/ui-kit/android/v6/message-composer) | Allows composing messages within a thread. |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Displays threaded messages in context. |
+
+## Quoted Replies
+
+Reply to specific messages by selecting "Reply" from the message action menu, maintaining context in the conversation.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Provides the "Reply" option in message actions. |
+| [CometChatMessageComposer](/ui-kit/android/v6/message-composer) | Shows the quoted reply above the input field for context. |
+
+## Group Chats
+
+Conversations with multiple participants — team collaborations, group discussions, and communities.
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatGroups](/ui-kit/android/v6/groups) | Lists and manages groups. |
+| [CometChatGroupMembers](/ui-kit/android/v6/group-members) | Displays and manages group members with roles and actions. |
+
+## Moderation
+
+Automatically filter and manage inappropriate content based on predefined rules.
+
+
+
+
+
+
+Learn more about setting up moderation rules in the [Moderation](/moderation/overview) documentation.
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Handles moderated messages, displaying blocked content based on your moderation settings. |
+
+## Report Message
+
+Users can report inappropriate messages by choosing from predefined reasons with optional remarks.
+
+
+Learn more about flagged messages in the [Flagged Messages](/moderation/flagged-messages) documentation.
+
+
+
+
+
+
+| Component | Role |
+| --- | --- |
+| [CometChatMessageList](/ui-kit/android/v6/message-list) | Provides the "Report Message" option in message actions. |
+
+---
+
+## Next Steps
+
+
+
+ Browse all available UI Kit components
+
+
+ Customize the look and feel of your chat UI
+
+
+ Add audio and video calling
+
+
+ Explore AI-powered chat capabilities
+
+
diff --git a/ui-kit/android/v6/custom-text-formatter-guide.mdx b/ui-kit/android/v6/custom-text-formatter-guide.mdx
new file mode 100644
index 000000000..1454c5b05
--- /dev/null
+++ b/ui-kit/android/v6/custom-text-formatter-guide.mdx
@@ -0,0 +1,174 @@
+---
+title: "Custom Text Formatter"
+sidebarTitle: "Custom Text Formatter"
+description: "Extend CometChatTextFormatter to build custom inline text patterns with tracking characters and suggestion lists."
+---
+
+
+
+| Field | Value |
+| --- | --- |
+| Packages | `com.cometchat:chatuikit-kotlin` · `com.cometchat:chatuikit-jetpack` |
+| Key class | `CometChatTextFormatter` (abstract base class for custom formatters) |
+| Required setup | `CometChatUIKit.init()` then `CometChatUIKit.login("UID")` |
+| Purpose | Extend to create custom inline text patterns with tracking characters, suggestion lists, and span formatting |
+| Features | Tracking character activation, suggestion list, span formatting per context (composer, bubbles, conversations), pre-send hooks |
+| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-android/tree/v5/sample-app-kotlin) |
+| Related | [Mentions Formatter](/ui-kit/android/v6/mentions-formatter-guide) \| [ShortCut Formatter](/ui-kit/android/v6/shortcut-formatter-guide) \| [All Guides](/ui-kit/android/v6/guide-overview) |
+
+
+
+`CometChatTextFormatter` is an abstract class for formatting text in the message composer and message bubbles. Extend it to build custom formatters — hashtags, shortcuts, or any pattern triggered by a tracking character.
+
+| Capability | Description |
+| --- | --- |
+| Tracking character | Activates the formatter when the user types a specific character (e.g., `#`, `!`) |
+| Suggestion list | Populates a dropdown of `SuggestionItem` objects as the user types |
+| Span formatting | Applies `SpannableStringBuilder` spans per context: composer, left/right bubbles, conversations |
+| Pre-send hook | `handlePreMessageSend` lets you modify the message before it's sent |
+| Component integration | Plugs into any component via `setTextFormatters()` |
+
+---
+
+## Steps
+
+### 1. Create a class extending CometChatTextFormatter
+
+Pass your tracking character to the superclass constructor.
+
+
+
+```kotlin lines
+class HashTagFormatter : CometChatTextFormatter('#') {
+ private val suggestions: MutableList = ArrayList()
+}
+```
+
+
+```kotlin lines
+// Same class — formatters are shared between both modules
+class HashTagFormatter : CometChatTextFormatter('#') {
+ private val suggestions: MutableList = ArrayList()
+}
+```
+
+
+
+### 2. Override the search method
+
+Called when the user types after the tracking character. Match input against your data and update the suggestion list.
+
+```kotlin lines
+override fun search(context: Context, queryString: String?) {
+ suggestions.clear()
+ val query = "#${queryString ?: ""}"
+ // Match against your hashtag data source
+ val matchingTags = getMatchingTags(query)
+ for (tag in matchingTags) {
+ val item = SuggestionItem("", tag, null, null, tag, null, null)
+ item.isHideLeadingIcon = true
+ suggestions.add(item)
+ }
+ setSuggestionItemList(suggestions)
+}
+```
+
+### 3. Override onScrollToBottom
+
+Required by the base class. Implement pagination logic or leave empty.
+
+```kotlin
+override fun onScrollToBottom() {
+ // Load more suggestions if needed
+}
+```
+
+### 4. Override span formatting methods (optional)
+
+Customize how matched text renders in different contexts using `SpannableStringBuilder`.
+
+```kotlin lines
+override fun prepareLeftMessageBubbleSpan(
+ context: Context, baseMessage: BaseMessage, spannable: SpannableStringBuilder
+): SpannableStringBuilder? {
+ // Apply custom spans for incoming message bubbles
+ return applyHashTagSpans(spannable, Color.parseColor("#5dff05"))
+}
+
+override fun prepareRightMessageBubbleSpan(
+ context: Context, baseMessage: BaseMessage, spannable: SpannableStringBuilder
+): SpannableStringBuilder? {
+ // Apply custom spans for outgoing message bubbles
+ return applyHashTagSpans(spannable, Color.parseColor("#30b3ff"))
+}
+```
+
+### 5. Integrate with a component
+
+
+
+```kotlin lines
+import com.cometchat.uikit.core.CometChatUIKit
+
+val textFormatters = CometChatUIKit.getDataSource().getTextFormatters(this, messageComposer.additionParameter)
+textFormatters.add(HashTagFormatter())
+messageComposer.setTextFormatters(textFormatters)
+```
+
+
+```kotlin lines
+import com.cometchat.uikit.core.CometChatUIKit
+
+// In your composable or ViewModel setup
+val textFormatters = CometChatUIKit.getDataSource().getTextFormatters(context, additionParameter)
+textFormatters.add(HashTagFormatter())
+
+CometChatMessageComposer(
+ user = user,
+ textFormatters = textFormatters
+)
+```
+
+
+
+Pass the same list to `CometChatMessageList` and `CometChatConversations` via their `setTextFormatters()` methods to apply formatting across all contexts.
+
+---
+
+## Methods Reference
+
+| Method | Description |
+| --- | --- |
+| `search(Context, String)` | Abstract — called when user types after the tracking character. Update the suggestion list here. |
+| `onScrollToBottom()` | Abstract — called when the suggestion list scrolls to the bottom. Implement pagination or leave empty. |
+| `onItemClick(Context, SuggestionItem, User, Group)` | Called when a suggestion item is selected. Override to customize insertion behavior. |
+| `handlePreMessageSend(Context, BaseMessage)` | Called before a message is sent. Override to modify the message (e.g., add metadata). |
+| `prepareLeftMessageBubbleSpan(Context, BaseMessage, SpannableStringBuilder)` | Override to format text in incoming message bubbles. |
+| `prepareRightMessageBubbleSpan(Context, BaseMessage, SpannableStringBuilder)` | Override to format text in outgoing message bubbles. |
+| `prepareComposerSpan(Context, BaseMessage, SpannableStringBuilder)` | Override to format text in the message composer. |
+| `prepareConversationSpan(Context, BaseMessage, SpannableStringBuilder)` | Override to format text in the conversations list preview. |
+| `setSuggestionItemList(List)` | Updates the suggestion dropdown with new items. |
+| `setDisableSuggestions(boolean)` | Disables the suggestion dropdown entirely. (`protected` — accessible from subclasses only.) |
+| `setInfoText(String)` | Sets informational text displayed above the suggestion list. |
+| `setInfoVisibility(boolean)` | Toggles visibility of the info text. |
+| `setShowLoadingIndicator(boolean)` | Shows/hides a loading spinner in the suggestion dropdown. |
+| `getTrackingCharacter()` | Returns the tracking character passed to the constructor. |
+
+---
+
+## Next Steps
+
+
+
+ Built-in @mention formatting with styled tokens
+
+
+ Shortcut text expansion via the message-shortcuts extension
+
+
+ Browse all feature and formatter guides
+
+
+ Full working sample application on GitHub
+
+
\ No newline at end of file
diff --git a/ui-kit/android/v6/customization-events.mdx b/ui-kit/android/v6/customization-events.mdx
new file mode 100644
index 000000000..61991429a
--- /dev/null
+++ b/ui-kit/android/v6/customization-events.mdx
@@ -0,0 +1,227 @@
+---
+title: "Events & Callbacks"
+description: "Handle user interaction events, selection mode, and global UI Kit events."
+---
+
+The UI Kit provides two levels of event handling: component-level callbacks set directly on a component, and global events via the `CometChatEvents` singleton using Kotlin `SharedFlow`.
+
+---
+
+## Component-Level Callbacks
+
+### Click Callbacks
+
+
+
+
+```kotlin lines
+conversations.setOnItemClick { conversation ->
+ // Navigate to chat screen
+}
+
+conversations.setOnItemLongClick { conversation ->
+ // Show context menu
+}
+
+conversations.setOnBackPress {
+ // Handle back navigation
+}
+
+conversations.setOnSearchClick {
+ // Open search
+}
+
+conversations.setOnError { exception ->
+ Log.e("Conversations", "Error: ${exception.message}")
+}
+
+conversations.setOnLoad { list ->
+ Log.d("Conversations", "Loaded ${list.size} conversations")
+}
+
+conversations.setOnEmpty {
+ Log.d("Conversations", "No conversations")
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ onItemClick = { conversation ->
+ // Navigate to chat screen
+ },
+ onItemLongClick = { conversation ->
+ // Show context menu
+ },
+ onBackPress = {
+ // Handle back navigation
+ },
+ onSearchClick = {
+ // Open search
+ },
+ onError = { exception ->
+ Log.e("Conversations", "Error: ${exception.message}")
+ },
+ onLoad = { list ->
+ Log.d("Conversations", "Loaded ${list.size} conversations")
+ },
+ onEmpty = {
+ Log.d("Conversations", "No conversations")
+ }
+)
+```
+
+
+
+
+---
+
+## Selection Mode
+
+Enable single or multi-select on list components:
+
+
+
+
+```kotlin lines
+// Enable multi-select mode
+conversations.setSelectionMode(UIKitConstants.SelectionMode.MULTIPLE)
+
+// Listen for selection changes
+conversations.setOnSelection { selectedList ->
+ updateToolbar(selectedList.size)
+}
+
+// Get selected items
+val selected = conversations.getSelectedConversations()
+
+// Clear selection
+conversations.clearSelection()
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ selectionMode = UIKitConstants.SelectionMode.MULTIPLE,
+ onSelection = { selectedList ->
+ updateToolbar(selectedList.size)
+ }
+)
+```
+
+
+
+
+---
+
+## Global Events (CometChatEvents)
+
+Global events are emitted by UI Kit components when actions happen anywhere in the app. They use Kotlin `SharedFlow` for reactive, type-safe event distribution. Subscribe from any coroutine scope.
+
+### Event Flows
+
+| Flow | Sealed Class | Fires When |
+| --- | --- | --- |
+| `CometChatEvents.messageEvents` | `CometChatMessageEvent` | Messages sent, edited, deleted, reactions, typing |
+| `CometChatEvents.callEvents` | `CometChatCallEvent` | Calls initiated, accepted, rejected, ended |
+| `CometChatEvents.conversationEvents` | `CometChatConversationEvent` | Conversations deleted or updated |
+| `CometChatEvents.groupEvents` | `CometChatGroupEvent` | Groups created, updated, members changed |
+| `CometChatEvents.userEvents` | `CometChatUserEvent` | Users blocked/unblocked |
+| `CometChatEvents.uiEvents` | `CometChatUIEvent` | UI-level events (panels, dialogs) |
+
+### Subscribing to Events
+
+```kotlin lines
+import com.cometchat.uikit.core.events.CometChatEvents
+import com.cometchat.uikit.core.events.CometChatMessageEvent
+
+// Subscribe in a ViewModel or lifecycle-aware scope
+viewModelScope.launch {
+ CometChatEvents.messageEvents.collect { event ->
+ when (event) {
+ is CometChatMessageEvent.MessageSent -> {
+ // Handle sent message: event.message, event.status
+ }
+ is CometChatMessageEvent.MessageDeleted -> {
+ // Handle deleted message: event.message
+ }
+ is CometChatMessageEvent.MessageEdited -> {
+ // Handle edited message: event.message
+ }
+ is CometChatMessageEvent.ReactionAdded -> {
+ // Handle reaction: event.event
+ }
+ else -> { /* other message events */ }
+ }
+ }
+}
+```
+
+### Emitting Events
+
+```kotlin lines
+// Emit from anywhere — thread-safe
+CometChatEvents.emitMessageEvent(
+ CometChatMessageEvent.MessageSent(message, MessageStatus.SUCCESS)
+)
+
+CometChatEvents.emitCallEvent(
+ CometChatCallEvent.OutgoingCall(call)
+)
+
+CometChatEvents.emitConversationEvent(
+ CometChatConversationEvent.ConversationDeleted(conversation)
+)
+```
+
+### Key Event Types
+
+**Message Events:**
+
+| Event | Data |
+| --- | --- |
+| `MessageSent` | `message`, `status` |
+| `MessageEdited` | `message`, `status` |
+| `MessageDeleted` | `message` |
+| `MessageRead` | `message` |
+| `ReactionAdded` / `ReactionRemoved` | `event` (ReactionEvent) |
+| `TypingStarted` / `TypingEnded` | `indicator` (TypingIndicator) |
+| `MessagesDelivered` / `MessagesRead` | `receipt` (MessageReceipt) |
+
+**Call Events:**
+
+| Event | Data |
+| --- | --- |
+| `OutgoingCall` | `call` |
+| `CallAccepted` | `call` |
+| `CallRejected` | `call` |
+| `CallEnded` | `call` |
+
+**Conversation Events:**
+
+| Event | Data |
+| --- | --- |
+| `ConversationDeleted` | `conversation` |
+| `ConversationUpdated` | `conversation` |
+
+---
+
+## Component vs Global Events
+
+| Aspect | Component Callbacks | Global Events |
+| --- | --- | --- |
+| Scope | Single component instance | App-wide |
+| Registration | `setOnItemClick {}` or composable parameter | `CometChatEvents.*.collect {}` |
+| Use case | Handle user interaction on a specific screen | Cross-component coordination |
+| Example | Tap a conversation → navigate | Message sent → update conversation list |
+
+---
+
+## Related
+
+- [Events Reference](/ui-kit/android/v6/events) — Full list of all event types.
+- [Customization Overview](/ui-kit/android/v6/customization-overview) — SDK Listeners vs UIKit Events distinction.
diff --git a/ui-kit/android/v6/customization-menu-options.mdx b/ui-kit/android/v6/customization-menu-options.mdx
new file mode 100644
index 000000000..ff8ea7b08
--- /dev/null
+++ b/ui-kit/android/v6/customization-menu-options.mdx
@@ -0,0 +1,182 @@
+---
+title: "Menu & Options"
+description: "Add, replace, or extend context menu actions on components."
+---
+
+Components provide context menus (e.g., long-press on a conversation or message). You can replace all options or append custom ones.
+
+---
+
+## setOptions vs addOptions
+
+| Method | Behavior |
+| --- | --- |
+| `setOptions` | Replaces all default options with your custom list |
+| `addOptions` | Appends your custom options to the existing defaults |
+
+Use `addOptions` to keep defaults (like "Delete") and add your own. Use `setOptions` for full control.
+
+---
+
+## Adding Custom Options
+
+
+
+
+```kotlin lines
+import com.cometchat.uikit.kotlin.presentation.shared.popupmenu.CometChatPopupMenu
+
+conversations.addOptions { context, conversation ->
+ listOf(
+ CometChatPopupMenu.MenuItem(
+ id = "pin",
+ name = "Pin Conversation",
+ startIcon = ContextCompat.getDrawable(context, R.drawable.ic_pin),
+ onClick = { pinConversation(conversation) }
+ )
+ )
+}
+```
+
+
+
+
+```kotlin lines
+import com.cometchat.uikit.compose.shared.views.popupmenu.MenuItem
+
+CometChatConversations(
+ addOptions = { context, conversation ->
+ listOf(
+ MenuItem(
+ id = "pin",
+ name = "Pin Conversation",
+ startIcon = painterResource(R.drawable.ic_pin),
+ onClick = { pinConversation(conversation) }
+ )
+ )
+ }
+)
+```
+
+
+
+
+---
+
+## Replacing All Options
+
+
+
+
+```kotlin lines
+conversations.setOptions { context, conversation ->
+ listOf(
+ CometChatPopupMenu.MenuItem(
+ id = "archive",
+ name = "Archive",
+ startIcon = ContextCompat.getDrawable(context, R.drawable.ic_archive),
+ onClick = { archiveConversation(conversation) }
+ ),
+ CometChatPopupMenu.MenuItem(
+ id = "mute",
+ name = "Mute",
+ startIcon = ContextCompat.getDrawable(context, R.drawable.ic_mute),
+ onClick = { muteConversation(conversation) }
+ )
+ )
+}
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ options = { context, conversation ->
+ listOf(
+ MenuItem(
+ id = "archive",
+ name = "Archive",
+ startIcon = painterResource(R.drawable.ic_archive),
+ onClick = { archiveConversation(conversation) }
+ ),
+ MenuItem(
+ id = "mute",
+ name = "Mute",
+ startIcon = painterResource(R.drawable.ic_mute),
+ onClick = { muteConversation(conversation) }
+ )
+ )
+ }
+)
+```
+
+
+
+
+---
+
+## MenuItem Properties
+
+
+
+
+`CometChatPopupMenu.MenuItem`:
+
+| Property | Type | Description |
+| --- | --- | --- |
+| `id` | `String` | Unique identifier |
+| `name` | `String` | Display text |
+| `startIcon` | `Drawable?` | Icon at the start |
+| `endIcon` | `Drawable?` | Icon at the end |
+| `startIconTint` | `@ColorInt Int` | Start icon tint |
+| `textColor` | `@ColorInt Int` | Text color |
+| `textAppearance` | `@StyleRes Int` | Text appearance |
+| `onClick` | `(() -> Unit)?` | Click callback |
+
+
+
+
+`MenuItem`:
+
+| Property | Type | Description |
+| --- | --- | --- |
+| `id` | `String` | Unique identifier |
+| `name` | `String` | Display text |
+| `startIcon` | `Painter?` | Icon at the start |
+| `endIcon` | `Painter?` | Icon at the end |
+| `startIconTint` | `Color?` | Start icon tint |
+| `textColor` | `Color?` | Text color |
+| `textStyle` | `TextStyle?` | Text style |
+| `onClick` | `(() -> Unit)?` | Click callback |
+
+
+
+
+Both modules provide convenience factory methods:
+
+```kotlin lines
+// Simple menu item (no icons)
+MenuItem.simple(id = "pin", name = "Pin") { /* onClick */ }
+
+// Menu item with icons (Compose)
+MenuItem.withIcons(id = "pin", name = "Pin", startIcon = painterResource(R.drawable.ic_pin)) { /* onClick */ }
+```
+
+---
+
+## Components with Menu Options
+
+| Component | Data passed to callback |
+| --- | --- |
+| `CometChatConversations` | `(Context, Conversation)` |
+| `CometChatUsers` | `(Context, User)` |
+| `CometChatGroups` | `(Context, Group)` |
+| `CometChatGroupMembers` | `(Context, GroupMember)` |
+| `CometChatCallLogs` | `(Context, CallLog)` |
+
+---
+
+## Related
+
+- [Customization Overview](/ui-kit/android/v6/customization-overview) — See all customization categories.
diff --git a/ui-kit/android/v6/customization-overview.mdx b/ui-kit/android/v6/customization-overview.mdx
new file mode 100644
index 000000000..7d30b0697
--- /dev/null
+++ b/ui-kit/android/v6/customization-overview.mdx
@@ -0,0 +1,242 @@
+---
+title: "Customization Overview"
+description: "Understand the layered architecture and discover all customization entry points in the CometChat Android UI Kit."
+---
+
+Every component in the UI Kit follows a layered architecture. Understanding these layers is the key to deep customization without rebuilding components from scratch.
+
+---
+
+## Architecture Layers
+
+Each component is built from four layers, from outermost (UI) to innermost (data):
+
+| Layer | Role | Example |
+| --- | --- | --- |
+| View | Renders UI, handles user interaction, exposes setter methods | `CometChatConversations`, `CometChatMessageList` |
+| ViewModel | Manages state, business logic, list operations, and SDK listeners | `CometChatConversationsViewModel`, `CometChatMessageListViewModel` |
+| Repository | Abstracts data fetching — can be swapped for custom implementations | `ConversationsRepository`, `MessageListRepository` |
+| DataSource | Direct SDK calls — the lowest layer that talks to CometChat servers | `ConversationsDataSourceImpl`, `MessageListDataSourceImpl` |
+
+```
+┌─────────────────────────────────────────┐
+│ View Layer │
+│ (CometChatConversations / Compose) │
+│ UI rendering, styles, callbacks │
+├─────────────────────────────────────────┤
+│ ViewModel Layer │
+│ (CometChatConversationsViewModel) │
+│ State, ListOperations, SDK listeners │
+├─────────────────────────────────────────┤
+│ Repository Layer │
+│ (ConversationsRepository) │
+│ Data abstraction — swappable │
+├─────────────────────────────────────────┤
+│ DataSource Layer │
+│ (ConversationsDataSourceImpl) │
+│ Direct CometChat SDK calls │
+└─────────────────────────────────────────┘
+```
+
+The ViewModel lives in `chatuikit-core` and is shared by both Kotlin XML Views and Jetpack Compose. The View layer is module-specific.
+
+---
+
+## Overriding the ViewModel
+
+Every component accepts an external ViewModel. This lets you subclass the default ViewModel to override behavior, or provide a completely custom one.
+
+
+
+
+```kotlin lines
+// 1. Subclass the ViewModel to override behavior
+class MyConversationsViewModel(
+ getConversationsUseCase: GetConversationsUseCase,
+ deleteConversationUseCase: DeleteConversationUseCase,
+ refreshConversationsUseCase: RefreshConversationsUseCase
+) : CometChatConversationsViewModel(
+ getConversationsUseCase,
+ deleteConversationUseCase,
+ refreshConversationsUseCase
+) {
+ // Override any behavior here
+}
+
+// 2. Create a factory with optional custom repository
+val factory = CometChatConversationsViewModelFactory(
+ repository = MyCustomRepository() // or use default
+)
+
+// 3. Create the ViewModel via ViewModelProvider
+val viewModel = ViewModelProvider(this, factory)
+ .get(MyConversationsViewModel::class.java)
+
+// 4. Inject into the component
+val conversations = findViewById(R.id.conversations)
+conversations.setViewModel(viewModel)
+```
+
+
+
+
+```kotlin lines
+// 1. Subclass the ViewModel to override behavior
+class MyConversationsViewModel(
+ getConversationsUseCase: GetConversationsUseCase,
+ deleteConversationUseCase: DeleteConversationUseCase,
+ refreshConversationsUseCase: RefreshConversationsUseCase
+) : CometChatConversationsViewModel(
+ getConversationsUseCase,
+ deleteConversationUseCase,
+ refreshConversationsUseCase
+) {
+ // Override any behavior here
+}
+
+// 2. Create a factory with optional custom repository
+val factory = CometChatConversationsViewModelFactory(
+ repository = MyCustomRepository() // or use default
+)
+
+// 3. Create and pass to the component
+val viewModel: MyConversationsViewModel = viewModel(factory = factory)
+
+CometChatConversations(
+ conversationsViewModel = viewModel
+)
+```
+
+
+
+
+---
+
+## Overriding the Repository
+
+Each ViewModel is created via a Factory that accepts a custom Repository. Implement the repository interface to change how data is fetched.
+
+```kotlin lines
+// 1. Implement the repository interface
+class MyConversationsRepository : ConversationsRepository {
+ override suspend fun fetchConversations(request: ConversationsRequest): List {
+ // Custom data fetching logic — local DB, filtered API call, etc.
+ }
+ // ... implement other methods
+}
+
+// 2. Create a factory with your custom repository
+val factory = CometChatConversationsViewModelFactory(
+ repository = MyConversationsRepository()
+)
+
+// 3. Create the ViewModel using the factory
+val viewModel = ViewModelProvider(this, factory)
+ .get(CometChatConversationsViewModel::class.java)
+
+// 4. Set it on the component
+conversations.setViewModel(viewModel)
+```
+
+Available repository interfaces in `chatuikit-core`:
+
+| Repository | Used by |
+| --- | --- |
+| `ConversationsRepository` | `CometChatConversationsViewModel` |
+| `MessageListRepository` | `CometChatMessageListViewModel` |
+| `MessageComposerRepository` | `CometChatMessageComposerViewModel` |
+| `MessageHeaderRepository` | `CometChatMessageHeaderViewModel` |
+| `UsersRepository` | `CometChatUsersViewModel` |
+| `GroupsRepository` | `CometChatGroupsViewModel` |
+| `GroupMembersRepository` | `CometChatGroupMembersViewModel` |
+| `CallLogsRepository` | `CometChatCallLogsViewModel` |
+| `CallButtonsRepository` | `CometChatCallButtonsViewModel` |
+| `ReactionListRepository` | `CometChatReactionListViewModel` |
+| `MessageInformationRepository` | `CometChatMessageInformationViewModel` |
+| `StickerRepository` | `CometChatStickerKeyboardViewModel` |
+| `PollRepository` | `CometChatCreatePollViewModel` |
+
+---
+
+## ListOperations API
+
+All list-based ViewModels implement the `ListOperations` interface, giving you a consistent API to manipulate list data programmatically.
+
+### Available Operations
+
+| Method | Description |
+| --- | --- |
+| `addItem(item)` | Appends an item to the list |
+| `addItems(items)` | Appends multiple items |
+| `removeItem(item)` | Removes the first matching item |
+| `removeItemAt(index)` | Removes item at index |
+| `updateItem(item, predicate)` | Replaces the first item matching the predicate |
+| `clearItems()` | Removes all items |
+| `getItems()` | Returns a copy of all items |
+| `getItemAt(index)` | Returns item at index (or null) |
+| `getItemCount()` | Returns the item count |
+| `moveItemToTop(item)` | Moves an item to index 0 (or adds it there) |
+| `batch { }` | Performs multiple operations in a single emission |
+
+### Example
+
+```kotlin lines
+// Batch operations — emits only once for all changes
+viewModel.batch {
+ add(newConversation1)
+ add(newConversation2)
+ remove(oldConversation)
+ moveToTop(pinnedConversation)
+}
+```
+
+Batch operations are critical for performance when handling rapid updates (e.g., multiple messages arriving simultaneously).
+
+---
+
+## SDK Listeners vs UIKit Events
+
+ViewModels use two event systems for real-time updates:
+
+| Aspect | SDK Listeners | UIKit Events |
+| --- | --- | --- |
+| Source | CometChat server | UIKit components |
+| Direction | Server → Client | Component → Component |
+| Registration | `CometChat.add*Listener()` | `CometChatEvents.*Events.collect {}` |
+| Purpose | Incoming messages, calls, presence | UI-initiated actions (message sent, call accepted) |
+
+Both are needed for full functionality. SDK listeners handle server-pushed events, UIKit events handle inter-component communication.
+
+---
+
+## Customization Categories
+
+
+
+ Replace specific regions of a component's UI (leading view, title, subtitle, trailing view).
+
+
+ Customize visual appearance using XML theme attributes or Compose style data classes.
+
+
+ Configure data fetching, observe state flows, and call mutation methods on the ViewModel.
+
+
+ Handle click events, selection mode, and global UI Kit events.
+
+
+ Replace or restyle the default empty, error, and loading state views.
+
+
+ Create custom text processors for hashtags, mentions, links, or any pattern.
+
+
+ Add, replace, or extend context menu actions and composer attachment options.
+
+
+
+---
+
+## What's Next
+
+Start with [Styles](/ui-kit/android/v6/customization-styles) for quick visual changes, or [ViewModel & Data](/ui-kit/android/v6/customization-viewmodel-data) for behavior customization.
diff --git a/ui-kit/android/v6/customization-state-views.mdx b/ui-kit/android/v6/customization-state-views.mdx
new file mode 100644
index 000000000..9296e3703
--- /dev/null
+++ b/ui-kit/android/v6/customization-state-views.mdx
@@ -0,0 +1,189 @@
+---
+title: "State Views"
+description: "Replace the default empty, error, and loading state views with custom layouts."
+---
+
+Components display state views when the list is empty, an error occurs, or data is loading. You can replace these with your own custom views.
+
+---
+
+## State Types
+
+| State | When it shows |
+| --- | --- |
+| Loading | Data is being fetched |
+| Empty | No data to display |
+| Error | An error occurred during data fetching |
+
+---
+
+## Replacing State Views
+
+
+
+
+Each component accepts a `View?` for each state:
+
+```kotlin lines
+// Custom empty view
+val emptyView = LayoutInflater.from(context)
+ .inflate(R.layout.custom_empty_state, null)
+conversations.setEmptyView(emptyView)
+
+// Custom error view
+val errorView = LayoutInflater.from(context)
+ .inflate(R.layout.custom_error_state, null)
+conversations.setErrorView(errorView)
+
+// Custom loading view
+val loadingView = LayoutInflater.from(context)
+ .inflate(R.layout.custom_loading_state, null)
+conversations.setLoadingView(loadingView)
+```
+
+Example custom empty layout:
+
+```xml res/layout/custom_empty_state.xml lines
+
+
+
+
+
+
+```
+
+
+
+
+Each component accepts `@Composable` lambdas for each state:
+
+```kotlin lines
+CometChatConversations(
+ emptyView = {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ Icon(
+ painter = painterResource(R.drawable.ic_empty_conversations),
+ contentDescription = "No conversations",
+ modifier = Modifier.size(120.dp),
+ tint = CometChatTheme.colorScheme.iconTintSecondary
+ )
+ Spacer(modifier = Modifier.height(16.dp))
+ Text(
+ text = "No conversations yet",
+ style = CometChatTheme.typography.heading2Medium,
+ color = CometChatTheme.colorScheme.textColorPrimary
+ )
+ }
+ },
+ errorView = { onRetry ->
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ Text("Something went wrong")
+ Spacer(modifier = Modifier.height(8.dp))
+ Button(onClick = onRetry) {
+ Text("Retry")
+ }
+ }
+ },
+ loadingView = {
+ Box(
+ modifier = Modifier.fillMaxSize(),
+ contentAlignment = Alignment.Center
+ ) {
+ CircularProgressIndicator()
+ }
+ }
+)
+```
+
+Note: the `errorView` lambda receives an `onRetry` callback you can wire to a retry button.
+
+
+
+
+---
+
+## Hiding State Views
+
+
+
+
+Components like `CometChatMessageList` provide explicit hide methods:
+
+```kotlin lines
+messageList.setHideLoadingState(true)
+messageList.setHideEmptyState(true)
+messageList.setHideErrorState(true)
+```
+
+For components that don't have dedicated hide methods (e.g., `CometChatConversations`), pass `null` to remove a custom state view:
+
+```kotlin lines
+conversations.setEmptyView(null)
+conversations.setErrorView(null)
+conversations.setLoadingView(null)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ hideEmptyState = true,
+ hideErrorState = true,
+ hideLoadingState = true
+)
+
+CometChatMessageList(
+ hideEmptyState = true,
+ hideErrorState = true,
+ hideLoadingState = true
+)
+```
+
+
+
+
+---
+
+## Components with State Views
+
+State views are available on all list-based components:
+
+| Component | States supported |
+| --- | --- |
+| `CometChatConversations` | Loading, Empty, Error |
+| `CometChatUsers` | Loading, Empty, Error |
+| `CometChatGroups` | Loading, Empty, Error |
+| `CometChatGroupMembers` | Loading, Empty, Error |
+| `CometChatCallLogs` | Loading, Empty, Error |
+| `CometChatMessageList` | Loading, Empty, Error |
+
+---
+
+## Related
+
+- [Customization Overview](/ui-kit/android/v6/customization-overview) — See all customization categories.
+- [View Slots](/ui-kit/android/v6/customization-view-slots) — Replace specific regions of list items.
diff --git a/ui-kit/android/v6/customization-styles.mdx b/ui-kit/android/v6/customization-styles.mdx
new file mode 100644
index 000000000..afa2a6c40
--- /dev/null
+++ b/ui-kit/android/v6/customization-styles.mdx
@@ -0,0 +1,231 @@
+---
+title: "Styles"
+description: "Customize component appearance using XML theme attributes, programmatic setters, or Compose style data classes."
+---
+
+The UI Kit supports multiple approaches to styling depending on your module.
+
+---
+
+## Styling Approaches
+
+
+
+
+Two ways to style components:
+
+1. **XML theme attributes** — declarative, app-wide theming via `themes.xml`
+2. **Programmatic `CometChatTheme` setters** — runtime color/font overrides
+
+Programmatic setters take precedence over XML theme attributes.
+
+### XML Theme Hierarchy
+
+```xml themes.xml lines
+
+
+
+
+
+
+
+
+```
+
+### Programmatic Overrides
+
+```kotlin lines
+// Override theme colors at runtime
+CometChatTheme.setPrimaryColor(Color.parseColor("#6851D6"))
+CometChatTheme.setBackgroundColor1(Color.parseColor("#FFFFFF"))
+CometChatTheme.setTextColorPrimary(Color.parseColor("#141414"))
+CometChatTheme.setTextColorSecondary(Color.parseColor("#727272"))
+```
+
+
+
+
+Components accept a `style` parameter — a data class with `.default()` factory and `.copy()` for overrides:
+
+```kotlin lines
+CometChatConversations(
+ style = CometChatConversationsStyle.default().copy(
+ backgroundColor = Color(0xFFF5F5F5),
+ titleTextColor = Color(0xFF6851D6),
+ itemStyle = CometChatConversationsItemStyle.default().copy(
+ avatarStyle = CometChatAvatarStyle.default().copy(
+ cornerRadius = 12.dp,
+ backgroundColor = Color(0xFFE8E0FF)
+ ),
+ badgeStyle = CometChatBadgeStyle.default().copy(
+ backgroundColor = Color(0xFFF76808)
+ )
+ )
+ )
+)
+```
+
+Global theme colors are provided via `CometChatTheme`:
+
+```kotlin lines
+CometChatTheme(
+ colorScheme = lightColorScheme().copy(
+ primary = Color(0xFF6851D6),
+ backgroundColor1 = Color(0xFFFFFFFF),
+ textColorPrimary = Color(0xFF141414)
+ )
+) {
+ // All components inside use these colors as defaults
+}
+```
+
+
+
+
+---
+
+## Font Customization
+
+
+
+
+Override fonts at the theme level:
+
+```xml themes.xml lines
+
+```
+
+| Attribute | Usage |
+| --- | --- |
+| `cometchatFontBold` | Headings, titles, emphasized text |
+| `cometchatFontMedium` | Subtitles, secondary headings |
+| `cometchatFontRegular` | Body text, descriptions, input fields |
+
+
+
+
+Provide custom typography via `CometChatTheme`:
+
+```kotlin lines
+CometChatTheme(
+ typography = CometChatTypography(
+ titleBold = TextStyle(fontFamily = myFontFamily, fontWeight = FontWeight.Bold, fontSize = 20.sp),
+ bodyRegular = TextStyle(fontFamily = myFontFamily, fontWeight = FontWeight.Normal, fontSize = 14.sp),
+ caption1Regular = TextStyle(fontFamily = myFontFamily, fontWeight = FontWeight.Normal, fontSize = 12.sp)
+ )
+) {
+ // All components use custom typography
+}
+```
+
+
+
+
+---
+
+## CometChatTheme Color Tokens
+
+These tokens are available for programmatic override (Kotlin XML) or via `CometChatColorScheme` (Compose):
+
+### Colors
+
+| Token | Description |
+| --- | --- |
+| `primaryColor` | Brand color for buttons, links, highlights |
+| `backgroundColor1` – `backgroundColor4` | Background levels |
+| `textColorPrimary` / `Secondary` / `Tertiary` | Text colors |
+| `textColorDisabled` / `White` / `Highlight` | Special text colors |
+| `errorColor` / `successColor` / `warningColor` / `infoColor` | Alert colors |
+| `strokeColorDefault` / `Light` / `Dark` / `Highlight` | Border colors |
+
+### Icon Tints
+
+| Token | Description |
+| --- | --- |
+| `iconTintPrimary` / `Secondary` / `Tertiary` | Icon tints |
+| `iconTintWhite` / `Highlight` | Special icon tints |
+
+### Button Colors
+
+| Token | Description |
+| --- | --- |
+| `primaryButtonBackgroundColor` / `TextColor` / `IconTint` | Primary button |
+| `secondaryButtonBackgroundColor` / `TextColor` / `IconTint` | Secondary button |
+
+---
+
+## Per-Component Style Properties
+
+Each component has its own style data class with nested sub-component styles. Here's the pattern for key components:
+
+### CometChatConversations
+
+| Property | Description |
+| --- | --- |
+| `backgroundColor` | List background |
+| `titleTextColor` | Toolbar title color |
+| `searchBoxStyle` | Search box styling |
+| `itemStyle.avatarStyle` | Avatar in each row |
+| `itemStyle.badgeStyle` | Unread badge |
+| `itemStyle.dateStyle` | Timestamp |
+| `itemStyle.receiptStyle` | Read receipts |
+| `itemStyle.statusIndicatorStyle` | Online/offline indicator |
+| `itemStyle.typingIndicatorStyle` | Typing indicator |
+
+### CometChatMessageList
+
+| Property | Description |
+| --- | --- |
+| `backgroundColor` | List background |
+| `incomingMessageBubbleStyle` | Incoming bubble appearance |
+| `outgoingMessageBubbleStyle` | Outgoing bubble appearance |
+| `actionBubbleStyle` | Group action bubbles |
+| `callActionBubbleStyle` | Call action bubbles |
+
+### CometChatMessageComposer
+
+| Property | Description |
+| --- | --- |
+| `backgroundColor` | Composer background |
+| `attachmentIconTint` | Attachment button tint |
+| `voiceRecordingIconTint` | Voice recording button tint |
+| `aiIconTint` | AI button tint |
+| `sendButtonStyle` | Send button appearance |
+
+### CometChatMessageHeader
+
+| Property | Description |
+| --- | --- |
+| `backgroundColor` | Header background |
+| `titleTextColor` | User/group name color |
+| `subtitleTextColor` | Status/typing text color |
+| `avatarStyle` | Avatar appearance |
+| `callButtonsStyle` | Call button appearance |
+
+---
+
+## Related
+
+- [Theme Introduction](/ui-kit/android/v6/theme-introduction) — Global theming reference.
+- [Component Styling](/ui-kit/android/v6/component-styling) — Detailed per-component style examples with screenshots.
+- [Color Resources](/ui-kit/android/v6/color-resources) — Default color palette reference.
+- [Customization Overview](/ui-kit/android/v6/customization-overview) — All customization categories.
diff --git a/ui-kit/android/v6/customization-text-formatters.mdx b/ui-kit/android/v6/customization-text-formatters.mdx
new file mode 100644
index 000000000..ef9f0e3e0
--- /dev/null
+++ b/ui-kit/android/v6/customization-text-formatters.mdx
@@ -0,0 +1,176 @@
+---
+title: "Text Formatters"
+description: "Create custom text processors for hashtags, mentions, links, or any pattern using the CometChatTextFormatter API."
+---
+
+Text formatters let you process message text with tracking characters, suggestion lists, and spannable transformations. Use them to add hashtag detection, custom mentions, link previews, or any text pattern processing.
+
+Both modules have their own `CometChatTextFormatter` class with the same API pattern:
+- Kotlin XML: `com.cometchat.uikit.kotlin.shared.formatters.CometChatTextFormatter`
+- Jetpack Compose: `com.cometchat.uikit.compose.presentation.shared.formatters.CometChatTextFormatter`
+
+---
+
+## CometChatTextFormatter API
+
+The abstract class takes a `trackingCharacter` that triggers the formatter when typed in the composer (e.g., `@` for mentions, `#` for hashtags).
+
+### Key Override Methods
+
+| Method | Purpose |
+| --- | --- |
+| `search(context, queryString)` | Called when the user types after the tracking character. Fetch and display suggestions. |
+| `onScrollToBottom()` | Called when the user scrolls to the bottom of the suggestion list. Use for pagination. |
+| `prepareLeftMessageBubbleSpan(context, message, spannable)` | Apply spans to text in incoming message bubbles. |
+| `prepareRightMessageBubbleSpan(context, message, spannable)` | Apply spans to text in outgoing message bubbles. |
+| `prepareComposerSpan(context, message, spannable)` | Apply spans to text in the message composer. |
+| `prepareConversationSpan(context, message, spannable)` | Apply spans to the last message preview in the conversation list. |
+| `handlePreMessageSend(context, message)` | Modify a message before it's sent (attach metadata, transform text). |
+| `onItemClick(context, suggestionItem, user, group)` | Called when the user selects a suggestion item. |
+
+### Suggestion System
+
+| Method | Description |
+| --- | --- |
+| `setSuggestionItemList(items)` | Set the list of suggestions to display |
+| `setShowLoadingIndicator(show)` | Show/hide a loading spinner in the suggestion dropdown |
+| `setDisableSuggestions(disable)` | Disable the suggestion dropdown entirely |
+
+---
+
+## Example: Custom Hashtag Formatter
+
+
+
+
+
+```kotlin lines
+import com.cometchat.uikit.kotlin.shared.formatters.CometChatTextFormatter
+import com.cometchat.uikit.kotlin.shared.formatters.SuggestionItem
+
+class HashtagFormatter : CometChatTextFormatter('#') {
+
+ override fun search(context: Context, queryString: String?) {
+ val suggestions = fetchHashtags(queryString)
+ setSuggestionItemList(suggestions)
+ }
+
+ override fun onScrollToBottom() {
+ // Load more suggestions
+ }
+
+ override fun prepareLeftMessageBubbleSpan(
+ context: Context,
+ baseMessage: BaseMessage,
+ spannable: SpannableStringBuilder
+ ): SpannableStringBuilder? {
+ applyHashtagSpans(spannable, context)
+ return spannable
+ }
+
+ override fun prepareRightMessageBubbleSpan(
+ context: Context,
+ baseMessage: BaseMessage,
+ spannable: SpannableStringBuilder
+ ): SpannableStringBuilder? {
+ applyHashtagSpans(spannable, context)
+ return spannable
+ }
+}
+```
+
+
+
+
+```kotlin lines
+import com.cometchat.uikit.compose.presentation.shared.formatters.CometChatTextFormatter
+import com.cometchat.uikit.compose.presentation.shared.formatters.SuggestionItem
+
+class HashtagFormatter : CometChatTextFormatter('#') {
+
+ override fun search(context: Context, queryString: String?) {
+ val suggestions = fetchHashtags(queryString)
+ setSuggestionItemList(suggestions)
+ }
+
+ override fun onScrollToBottom() {
+ // Load more suggestions
+ }
+
+ override fun prepareLeftMessageBubbleSpan(
+ context: Context,
+ baseMessage: BaseMessage,
+ spannable: SpannableStringBuilder
+ ): SpannableStringBuilder? {
+ applyHashtagSpans(spannable, context)
+ return spannable
+ }
+
+ override fun prepareRightMessageBubbleSpan(
+ context: Context,
+ baseMessage: BaseMessage,
+ spannable: SpannableStringBuilder
+ ): SpannableStringBuilder? {
+ applyHashtagSpans(spannable, context)
+ return spannable
+ }
+}
+```
+
+
+
+
+---
+
+## Registering Formatters
+
+
+
+
+```kotlin lines
+val hashtagFormatter = HashtagFormatter()
+conversations.setTextFormatters(listOf(hashtagFormatter))
+
+// Or on message composer / message list
+messageComposer.setTextFormatters(listOf(hashtagFormatter))
+messageList.setTextFormatters(listOf(hashtagFormatter))
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ textFormatters = listOf(HashtagFormatter())
+)
+
+CometChatMessageComposer(
+ textFormatters = listOf(HashtagFormatter())
+)
+
+CometChatMessageList(
+ textFormatters = listOf(HashtagFormatter())
+)
+```
+
+
+
+
+---
+
+## Built-in Formatter: CometChatMentionsFormatter
+
+The UI Kit includes `CometChatMentionsFormatter` as a built-in formatter that handles `@mention` detection, user suggestion lists, and spannable highlighting. It's automatically added to components when mentions are enabled.
+
+Each module has its own implementation:
+- Kotlin XML: `com.cometchat.uikit.kotlin.shared.formatters.CometChatMentionsFormatter`
+- Jetpack Compose: `com.cometchat.uikit.compose.presentation.shared.formatters.CometChatMentionsFormatter`
+
+See the [Mentions Formatter Guide](/ui-kit/android/v6/mentions-formatter-guide) for details.
+
+---
+
+## Related
+
+- [Mentions Formatter Guide](/ui-kit/android/v6/mentions-formatter-guide) — Built-in mentions formatter reference.
+- [Customization Overview](/ui-kit/android/v6/customization-overview) — See all customization categories.
diff --git a/ui-kit/android/v6/customization-view-slots.mdx b/ui-kit/android/v6/customization-view-slots.mdx
new file mode 100644
index 000000000..eb27f7c3d
--- /dev/null
+++ b/ui-kit/android/v6/customization-view-slots.mdx
@@ -0,0 +1,263 @@
+---
+title: "View Slots"
+description: "Replace specific regions of a component's UI without rebuilding the entire component."
+---
+
+View Slots let you swap out specific parts of a component's list item — the avatar area, title, subtitle, trailing section, or the entire row — while keeping the rest of the component's behavior intact.
+
+---
+
+## Available View Slots
+
+| Slot | Region | Description |
+| --- | --- | --- |
+| `leadingView` | Left section | Replaces the avatar / leading area |
+| `titleView` | Title text | Replaces the name / title text |
+| `subtitleView` | Subtitle text | Replaces the last message preview |
+| `trailingView` | Right section | Replaces the timestamp / badge area |
+| `itemView` | Entire row | Replaces the entire list item layout |
+
+
+When you use `itemView`, all other slot setters are ignored since the entire row is replaced.
+
+
+---
+
+## How It Works
+
+
+
+
+Each list-based component defines a `ViewHolderListener` abstract class with two callbacks:
+
+| Callback | Purpose |
+| --- | --- |
+| `createView(context, binding)` | Return a `View` for the slot. Called once when the ViewHolder is created. |
+| `bindView(context, createdView, data, ...)` | Bind data to your custom view. Called every time the item is bound. |
+
+Pass the listener to the component via `setLeadingView()`, `setTitleView()`, `setSubtitleView()`, `setTrailingView()`, or `setItemView()`.
+
+
+
+
+Each component accepts `@Composable` lambda parameters for each slot:
+
+```kotlin lines
+CometChatConversations(
+ leadingView = { conversation, typingIndicator -> /* your composable */ },
+ titleView = { conversation, typingIndicator -> /* your composable */ },
+ subtitleView = { conversation, typingIndicator -> /* your composable */ },
+ trailingView = { conversation, typingIndicator -> /* your composable */ },
+ itemView = { conversation, typingIndicator -> /* your composable */ }
+)
+```
+
+The lambda receives the data model directly — no `createView`/`bindView` split needed.
+
+
+
+
+---
+
+## Example: Custom Leading View
+
+Replace the default avatar with a custom view showing the first letter of the conversation name.
+
+
+
+
+```kotlin lines
+conversations.setLeadingView(object : ConversationsViewHolderListener() {
+ override fun createView(
+ context: Context,
+ binding: CometchatConversationsListItemsBinding
+ ): View {
+ return TextView(context).apply {
+ layoutParams = ViewGroup.LayoutParams(48.dp, 48.dp)
+ gravity = Gravity.CENTER
+ textSize = 18f
+ setTextColor(Color.WHITE)
+ }
+ }
+
+ override fun bindView(
+ context: Context,
+ createdView: View,
+ conversation: Conversation,
+ typingIndicator: TypingIndicator?,
+ holder: RecyclerView.ViewHolder,
+ conversations: List,
+ position: Int
+ ) {
+ val textView = createdView as TextView
+ val name = conversation.conversationWith?.name ?: ""
+ textView.text = name.firstOrNull()?.uppercase() ?: "?"
+ textView.background = GradientDrawable().apply {
+ shape = GradientDrawable.OVAL
+ setColor(Color.parseColor("#6851D6"))
+ }
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ leadingView = { conversation, _ ->
+ val name = conversation.conversationWith?.name ?: ""
+ val initial = name.firstOrNull()?.uppercase() ?: "?"
+
+ Box(
+ modifier = Modifier
+ .size(48.dp)
+ .background(Color(0xFF6851D6), CircleShape),
+ contentAlignment = Alignment.Center
+ ) {
+ Text(
+ text = initial,
+ color = Color.White,
+ fontSize = 18.sp
+ )
+ }
+ }
+)
+```
+
+
+
+
+---
+
+## Example: Custom Subtitle View
+
+Show a custom last message format in the subtitle area.
+
+
+
+
+```kotlin lines
+conversations.setSubtitleView(object : ConversationsViewHolderListener() {
+ override fun createView(
+ context: Context,
+ binding: CometchatConversationsListItemsBinding
+ ): View {
+ return TextView(context).apply {
+ maxLines = 1
+ ellipsize = TextUtils.TruncateAt.END
+ }
+ }
+
+ override fun bindView(
+ context: Context,
+ createdView: View,
+ conversation: Conversation,
+ typingIndicator: TypingIndicator?,
+ holder: RecyclerView.ViewHolder,
+ conversations: List,
+ position: Int
+ ) {
+ val textView = createdView as TextView
+ // Show typing indicator if available
+ if (typingIndicator != null) {
+ textView.text = "typing..."
+ return
+ }
+ textView.text = when (val msg = conversation.lastMessage) {
+ is TextMessage -> msg.text
+ is MediaMessage -> "📎 ${msg.attachment?.fileExtension ?: "Media"}"
+ else -> "New conversation"
+ }
+ }
+})
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ subtitleView = { conversation, typingIndicator ->
+ val text = if (typingIndicator != null) {
+ "typing..."
+ } else {
+ when (val msg = conversation.lastMessage) {
+ is TextMessage -> msg.text
+ is MediaMessage -> "📎 ${msg.attachment?.fileExtension ?: "Media"}"
+ else -> "New conversation"
+ }
+ }
+
+ Text(
+ text = text,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ style = CometChatTheme.typography.bodyRegular,
+ color = CometChatTheme.colorScheme.textColorSecondary
+ )
+ }
+)
+```
+
+
+
+
+---
+
+## Toolbar Overflow Menu
+
+Inject a custom view into the component's toolbar area. This is separate from list item view slots.
+
+
+
+
+```kotlin lines
+val menuButton = ImageButton(context).apply {
+ setImageResource(R.drawable.ic_filter)
+ setOnClickListener { /* show filter dialog */ }
+}
+conversations.setOverflowMenu(menuButton)
+```
+
+
+
+
+```kotlin lines
+CometChatConversations(
+ overflowMenu = {
+ IconButton(onClick = { /* show filter dialog */ }) {
+ Icon(
+ painter = painterResource(R.drawable.ic_filter),
+ contentDescription = "Filter"
+ )
+ }
+ }
+)
+```
+
+
+
+
+---
+
+## Components with View Slots
+
+View slots are available on all list-based components:
+
+| Component | ViewHolderListener (Kotlin XML) | Composable Lambdas (Compose) |
+| --- | --- | --- |
+| `CometChatConversations` | `ConversationsViewHolderListener` | `(Conversation, TypingIndicator?) -> Unit` |
+| `CometChatUsers` | `UsersViewHolderListener` | `(User) -> Unit` |
+| `CometChatGroups` | `GroupsViewHolderListener` | `(Group) -> Unit` |
+| `CometChatGroupMembers` | `GroupMembersViewHolderListener` | `(GroupMember) -> Unit` |
+| `CometChatCallLogs` | `CallLogsViewHolderListener` | `(CallLog) -> Unit` |
+| `CometChatReactionList` | `ReactionListViewHolderListener` | `(Reaction) -> Unit` |
+| `CometChatMessageHeader` | `MessageHeaderViewHolderListener` | `(User?, Group?) -> Unit` |
+
+---
+
+## Related
+
+- [Styles](/ui-kit/android/v6/customization-styles) — Customize visual appearance without replacing views.
+- [Customization Overview](/ui-kit/android/v6/customization-overview) — See all customization categories.
diff --git a/ui-kit/android/v6/customization-viewmodel-data.mdx b/ui-kit/android/v6/customization-viewmodel-data.mdx
new file mode 100644
index 000000000..8c51cde9f
--- /dev/null
+++ b/ui-kit/android/v6/customization-viewmodel-data.mdx
@@ -0,0 +1,339 @@
+---
+title: "ViewModel & Data"
+description: "Access and configure the ViewModel layer to customize data fetching, state management, and list operations."
+---
+
+Each component's ViewModel lives in `chatuikit-core` and manages data fetching, state transitions, real-time listeners, and list operations via `StateFlow`. The same ViewModel is shared by both Kotlin XML Views and Jetpack Compose modules.
+
+---
+
+## Creating and Providing a ViewModel
+
+By default, each component creates its own ViewModel internally. To customize behavior, create the ViewModel externally using the factory and pass it to the component.
+
+
+
+
+```kotlin lines
+// 1. Create the factory (optionally with a custom repository)
+val factory = CometChatConversationsViewModelFactory()
+
+// 2. Create the ViewModel using ViewModelProvider
+val viewModel = ViewModelProvider(this, factory)
+ .get(CometChatConversationsViewModel::class.java)
+
+// 3. Configure the ViewModel before passing it
+viewModel.setConversationsRequestBuilder(
+ ConversationsRequest.ConversationsRequestBuilder()
+ .setLimit(20)
+ .withTags(true)
+)
+
+// 4. Pass it to the component
+val conversations = findViewById(R.id.conversations)
+conversations.setViewModel(viewModel)
+```
+
+
+
+
+```kotlin lines
+// 1. Create the factory (optionally with a custom repository)
+val factory = CometChatConversationsViewModelFactory()
+
+// 2. Create the ViewModel using Compose's viewModel()
+val viewModel: CometChatConversationsViewModel = viewModel(factory = factory)
+
+// 3. Pass it to the component
+CometChatConversations(
+ conversationsViewModel = viewModel
+)
+```
+
+
+
+
+This pattern applies to all components — `CometChatUsers`, `CometChatGroups`, `CometChatMessageList`, `CometChatCallLogs`, etc. Each has a corresponding factory class.
+
+---
+
+## State Observation
+
+ViewModels expose state via Kotlin `StateFlow` (not LiveData). The key state flows are:
+
+| StateFlow | Type | Description |
+| --- | --- | --- |
+| `uiState` | `StateFlow` | Current screen state: `Loading`, `Empty`, `Error(exception)`, `Content(list)` |
+| `conversations` | `StateFlow>` | The current list of conversations |
+| `typingIndicators` | `StateFlow