This is beta documentation for Stream Chat Android SDK v7. For the latest stable version, see the latest version (v6) .

Message Status Indicators

For messages sent by the current user, the status indicators represent the state of the message. It is shown below the message bubble, by default.

Status indicators states

The possible states of the status indicators are:

  • pending: The message is pending to be sent to the server.
  • sent: The message has been sent to the server successfully. It is shown as a gray checkmark.
  • delivered: The message has been delivered to at least one of the channel members devices. It is shown as double gray checkmark.
  • read: The message has been read by at least one of the channel members. It is shown as double blue checkmark.

The delivered state needs to be enabled in the Dashboard for each channel type.

PendingSentDeliveredReadRead by many
Message Status Pending
Message Status Sent
Message Status Delivered
Message Status Read
Message Status Read Group

If read_events are turned OFF for the channel, read indicators are hidden.

If delivery_events are turned OFF for the channel, delivery indicators are hidden.

Basic Customization

Hide status indicators

In case your app does not need to show the status indicators, you can hide them by overriding the MessageFooterStatusIndicator component factory method.

class CustomChatComponentFactory : ChatComponentFactory {

    @Composable
    override fun ChannelItemReadStatusIndicator(
        params: ChannelItemReadStatusIndicatorParams,
    ) {
        // Do not show any status indicator
    }

    @Composable
    override fun MessageFooterStatusIndicator(
        params: MessageFooterStatusIndicatorParams,
    ) {
        // Do not show any status indicator
    }
}

When hidden, no status icons appear next to your messages.

Advanced Customization

Show all read and delivered members

To show all the read and delivered members, you can create a custom screen that shows the members that have read the message and the ones that were delivered but not read yet.

For this, we can extend the message menu to add a message info option to show a screen with the read and delivered members.

class CustomChatComponentFactory(
    private val delegate: ChatComponentFactory = object : ChatComponentFactory {},
) : ChatComponentFactory by delegate {
    /**
     * Creates a message menu with an additional option for message info.
     */
    @Composable
    override fun MessageMenu(params: MessageMenuParams) {
        var showMessageInfoDialog by remember { mutableStateOf(false) }

        val allOptions = listOf(
            MessageOptionItemState(
                title = R.string.message_option_message_info,
                titleColor = ChatTheme.colors.textPrimary,
                iconPainter = rememberVectorPainter(Icons.Outlined.Info),
                iconColor = ChatTheme.colors.textSecondary,
                action = CustomAction(params.message, mapOf("message_info" to true)),
            ),
        ) + params.messageOptions

        val extendedOnMessageAction: (MessageAction) -> Unit = { action ->
            when {
                action is CustomAction && action.extraProperties.contains("message_info") ->
                    showMessageInfoDialog = true

                else -> params.onMessageAction(action)
            }
        }

        var dismissed by remember { mutableStateOf(false) }

        if (showMessageInfoDialog) {
            ModalBottomSheet(
                onDismissRequest = {
                    showMessageInfoDialog = false
                    params.onDismiss()
                    dismissed = true
                },
                containerColor = ChatTheme.colors.backgroundCoreApp,
            ) {
                // Show read/delivered members for the message
                // Use your own implementation to fetch and display read receipts
            }
        } else if (!dismissed) {
            delegate.MessageMenu(
                params = params.copy(
                    messageOptions = allOptions,
                    onMessageAction = extendedOnMessageAction,
                ),
            )
        }
    }
}

At the moment, showing the timestamps of the read and delivered members is not recommended since the timestamp is always related to the latest message in the channel, and not for each message individually.