# Pinned Message List

`PinnedMessageList` is a composable component which shows a list of pinned messages in a given channel.
It includes pagination logic, which ensures that only the 30 most recently pinned messages are initially loaded, and older pinned messages are loaded only when the user scrolls to the bottom of the list.

## Usage

This component is backed by its `PinnedMessageListViewModel`. To use this component in your screens, you need to:

- Create a `PinnedMessageListViewModelFactory` and pass the ID of the channel.
- Instantiate a `PinnedMessageListViewModel` via the factory.
- Pass the ViewModel as an argument to the component.

```kotlin
private val viewModelFactory by lazy {
    PinnedMessageListViewModelFactory(cid = channelId)
}

private val viewModel by viewModels<PinnedMessageListViewModel> { viewModelFactory }

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContent {
        ChatTheme {
            PinnedMessageList(
                modifier = Modifier.fillMaxSize(),
                viewModel = viewModel
            )
        }
    }
}
```

This snippet will produce a fully working list, together with a loading state, and an empty state for the case without pinned messages in the channel:

| Empty                                                                                       | Loaded                                                                                         |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| ![Empty](@chat-sdk/android/v7-latest/_assets/compose_default_pinned_message_list_empty.png) | ![Loaded](@chat-sdk/android/v7-latest/_assets/compose_default_pinned_message_list_content.png) |

## Handling Actions

The `PinnedMessageList` component exposes the action handler for clicking on a pinned message:

```kotlin
@Composable
public fun PinnedMessageList(
    ..., // ViewModel and UI customization
    onPinnedMessageClick: (Message) -> Unit = {},
)
```

The `onPinnedMessageClick` action is empty by default, but you can override it to provide your own click handler:

```kotlin
PinnedMessageList(
    viewModel = viewModel,
    onPinnedMessageClick = { message ->
        // Custom click action
    },
)
```

## Customization

The `PinnedMessageList` component accepts the following parameters:

```kotlin
@Composable
public fun PinnedMessageList(
    viewModel: PinnedMessageListViewModel,
    modifier: Modifier = Modifier,
    currentUser: User? = ChatClient.instance().getCurrentUser(),
    onPinnedMessageClick: (Message) -> Unit = {},
)
```

- `viewModel` - The `PinnedMessageListViewModel` that provides the pinned messages data and handles pagination.
- `modifier` - The modifier for the root component. Used for general customization such as size and padding.
- `currentUser` - The currently logged-in user. Defaults to `ChatClient.instance().getCurrentUser()`.
- `onPinnedMessageClick` - Action invoked when the user clicks on a pinned message. Empty by default.

All UI rendering is delegated to the component factory (`ChatTheme.componentFactory`). To customize individual elements, override the corresponding factory methods: `PinnedMessageListItem`, `PinnedMessageListItemDivider`, `PinnedMessageListEmptyContent`, `PinnedMessageListLoadingContent`, or `PinnedMessageListLoadingMoreContent`. See the [Component Factory](/chat/docs/sdk/android/compose/general-customization/component-factory/) documentation for more details.

If you want to customize only parts of the item, you can use the `PinnedMessageItem`:

```kotlin
@Composable
public fun PinnedMessageItem(
    message: Message,
    currentUser: User?,
    onPinnedMessageClick: (Message) -> Unit,
    modifier: Modifier = Modifier,
    leadingContent: @Composable RowScope.(Message) -> Unit = { ... },
    centerContent: @Composable RowScope.(Message) -> Unit = { ... },
    trailingContent: @Composable RowScope.(Message) -> Unit = { ... },
)
```

- `modifier` - The modifier for the root component. You can apply a background, elevation, padding...
- `leadingContent` - Composable that represents the leading content of the item. By default, it shows an Avatar of the user who wrote the message. Override this to replace the Avatar and show a custom component instead of it.
- `centerContent` - Composable that represents the central content of the item. By default, it shows a preview of the pinned message: Title holding the name of the user who sent the message, and a body holding a preview of the message text.
- `trailingContent` - Composable that represents the trailing content of the item. By default, it shows the time when the message was created.

For example, if you would like to override the time content from the pinned message, you can override the `PinnedMessageListItem` method in your custom `ChatComponentFactory`:

```kotlin
object MyComponentFactory : ChatComponentFactory {
    @Composable
    override fun PinnedMessageListItem(params: PinnedMessageListItemParams) {
        PinnedMessageItem(
            message = params.message,
            currentUser = params.currentUser,
            onPinnedMessageClick = params.onClick,
            trailingContent = {
                // Custom implementation
            }
        )
    }
}
```

If you would like to keep the same layout as the default item, but you want to show a custom preview text for the message, you can do that by passing a custom `MessagePreviewFormatter` to the `ChatTheme`:

```kotlin
class CustomMessagePreviewFormatter: MessagePreviewFormatter {

    override fun formatMessageTitle(message: Message, currentUser: User?): AnnotatedString {
        // Your implementation for customized message title
    }

    override fun formatMessagePreview(message: Message, currentUser: User?, isDirectMessaging: Boolean): AnnotatedString {
        // Your implementation for customized message text
    }
}

// Usage
@Composable
public fun YourScreen() {
    ChatTheme(
        messagePreviewFormatter = CustomMessagePreviewFormatter() // override the default formatter
    ) {
        PinnedMessageList(viewModel = viewModel)
    }
}
```


---

This page was last updated at 2026-04-22T16:42:47.447Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/android/compose/guides/pinned-messages/](https://getstream.io/chat/docs/sdk/android/compose/guides/pinned-messages/).