# MessageListViewModel

Previously, our XML and Compose message list `ViewModel`s used the low level client directly to make API calls and enable user interaction. In order to make our code more reliable and the maintenance of our codebase easier, we introduced a layer of shared code between the two message list `ViewModel`s.
That layer is represented by a class called `MessageListController`.

## Using the `ViewModelFactory`

If you're using our `MessageListViewModelFactory`, you'll notice that we added new parameters allowing for greater control over the `ViewModel`'s behaviour:

```kotlin {8-17}
public class MessageListViewModelFactory @JvmOverloads constructor(
    private val cid: String,
    private val messageId: String? = null,
    private val parentMessageId: String? = null,
    private val chatClient: ChatClient = ChatClient.instance(),
    private val clientState: ClientState = chatClient.clientState,
    private val messageLimit: Int = MessageListController.DEFAULT_MESSAGES_LIMIT,
    private val enforceUniqueReactions: Boolean = true,
    private val maxAttachmentCount: Int = AttachmentConstants.MAX_ATTACHMENTS_COUNT,
    private val maxAttachmentSize: Long = AttachmentConstants.MAX_UPLOAD_FILE_SIZE,
    private val showSystemMessages: Boolean = true,
    private val deletedMessageVisibility: DeletedMessageVisibility = DeletedMessageVisibility.ALWAYS_VISIBLE,
    private val messageFooterVisibility: MessageFooterVisibility = MessageFooterVisibility.WithTimeDifference(),
    private val dateSeparatorHandler: DateSeparatorHandler = DateSeparatorHandler.getDefaultDateSeparatorHandler(),
    private val threadDateSeparatorHandler: DateSeparatorHandler =
        DateSeparatorHandler.getDefaultThreadDateSeparatorHandler(),
    private val messagePositionHandler: MessagePositionHandler = MessagePositionHandler.defaultHandler(),
) : ViewModelProvider.Factory {
```

<admonition type="note">

The highlighted parameters have been added and the parameter `navigateToThreadViaNotification: Boolean` has been removed as navigating to thread messages via push notifications is the default behavior in `v6`.

</admonition>

- `enforceUniqueReactions`: Determines if a single user is able to set multiple reactions to a single message.
- `maxAttachmentCount`: The maximum number of attachments that can be sent in a single message.
- `maxAttachmentSize`: The maximum size of a single attachment, expressed in bytes. Restricted to 100mb by default by Stream's CDN.
- `showSystemMessages`: If system messages should be visible.
- `deletedMessageVisibility`: Sets the visibility of the deleted messages according to user ownership.
- `messageFooterVisibility`: Sets the visibility of message footers.
- `dateSeparatorHandler`: Determines the visibility of date separators inside the message list.
- `threadDateSeparatorHandler`: Determines the visibility of date separators inside the message list when the list is in thread mode.
- `messagePositionHandler`: Determines the position of the message inside the group.

Parameters `showDateSeparators: Boolean` and `dateSeparatorThresholdMillis: Long` have been removed in favor of the new date separator handlers which allow for greater flexibility.

## Instantiating the `ViewModel`

We recommend that you instantiate the model using `MessageListViewModelFactory`, however if you want to instantiate it yourself, then you'll notice its signature has changed.

Previously, the `ViewModel` had the following signature:

```kotlin
public class MessageListViewModel(
    private val cid: String,
    private val messageId: String? = null,
    private val chatClient: ChatClient = ChatClient.instance(),
    private val clientState: ClientState = chatClient.clientState,
    private val messageLimit: Int = DEFAULT_MESSAGES_LIMIT,
    private val navigateToThreadViaNotification: Boolean = false,
) : ViewModel()
```

Currently, the `ViewModel` holds only two parameters:

```kotlin
public class MessageListViewModel(
   private val messageListController: MessageListController,
   private val chatClient: ChatClient = ChatClient.instance(),
) : ViewModel()
```

## `MessageListController`

The controller has now been made the driving part behind `MessageListViewModel`. In turn, this means that the parameters necessary to adjust the functioning of the `ViewModel` have been moved to the controller:

```kotlin
public class MessageListController(
    private val cid: String,
    private val clipboardHandler: ClipboardHandler,
    private val messageId: String? = null,
    private val parentMessageId: String? = null,
    public val messageLimit: Int = DEFAULT_MESSAGES_LIMIT,
    private val chatClient: ChatClient = ChatClient.instance(),
    private val clientState: ClientState = chatClient.clientState,
    private val deletedMessageVisibility: DeletedMessageVisibility = DeletedMessageVisibility.ALWAYS_VISIBLE,
    private val showSystemMessages: Boolean = true,
    private val messageFooterVisibility: MessageFooterVisibility = MessageFooterVisibility.WithTimeDifference(),
    private val enforceUniqueReactions: Boolean = true,
    private val dateSeparatorHandler: DateSeparatorHandler = DateSeparatorHandler.getDefaultDateSeparatorHandler(),
    private val threadDateSeparatorHandler: DateSeparatorHandler =
        DateSeparatorHandler.getDefaultThreadDateSeparatorHandler(),
    private val messagePositionHandler: MessagePositionHandler = MessagePositionHandler.defaultHandler(),
)
```

You'll notice that these parameters seem familiar, this is because all of them are passed down to the controller by `MessageListViewModelFactory` and have been covered in the [section](#using-the-viewmodelfactory) addressing the changes made to the `ViewModel` factory.


---

This page was last updated at 2026-04-17T17:33:32.097Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/android/v6/migration-guides/ui-components/message-list-viewmodel/](https://getstream.io/chat/docs/sdk/android/v6/migration-guides/ui-components/message-list-viewmodel/).