Package-level declarations

Types

Link copied to clipboard
data class MessagesLazyListState(val lazyListState: LazyListState, messageOffsetHandler: MessagesLazyListState.MessageOffsetHandler = defaultOffsetHandler)

Provides a wrapper around lazy list state to be used with Messages composable. It is used to keep track of the focused message offset needed to center the focused message in the scroll list.

Link copied to clipboard

Represents where the thread messages start.

Properties

Link copied to clipboard

Represents the time the highlight fade out transition will take.

Functions

Link copied to clipboard
fun DefaultMessageItemCenterContent(modifier: Modifier = Modifier, messageItem: MessageItemState, messageContentFactory: MessageContentFactory = ChatTheme.messageContentFactory, onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onLinkClick: (Message, String) -> Unit? = null, onUserMentionClick: (User) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, onPollUpdated: (Message, Poll) -> Unit, onCastVote: (Message, Poll, Option) -> Unit, onRemoveVote: (Message, Poll, Vote) -> Unit, selectPoll: (Message, Poll, PollSelectionType) -> Unit, onAddAnswer: (message: Message, poll: Poll, answer: String) -> Unit, onClosePoll: (String) -> Unit, onAddPollOption: (poll: Poll, option: String) -> Unit)

Represents the default content shown at the center of the message list item.

Link copied to clipboard
fun EmojiMessageContent(messageItem: MessageItemState, modifier: Modifier = Modifier, onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {})

Message content when the message consists only of emoji.

Link copied to clipboard
fun MessageContainer(messageListItemState: MessageListItemState, reactionSorting: ReactionSorting, messageContentFactory: MessageContentFactory = ChatTheme.messageContentFactory, onLongItemClick: (Message) -> Unit = {}, onReactionsClick: (Message) -> Unit = {}, onThreadClick: (Message) -> Unit = {}, onPollUpdated: (Message, Poll) -> Unit = { _, _ -> }, onCastVote: (Message, Poll, Option) -> Unit = { _, _, _ -> }, onRemoveVote: (Message, Poll, Vote) -> Unit = { _, _, _ -> }, selectPoll: (Message, Poll, PollSelectionType) -> Unit = { _, _, _ -> }, onAddAnswer: (message: Message, poll: Poll, answer: String) -> Unit = { _, _, _ -> }, onClosePoll: (String) -> Unit = {}, onAddPollOption: (poll: Poll, option: String) -> Unit = { _, _ -> }, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onUserAvatarClick: (User) -> Unit? = null, onLinkClick: (Message, String) -> Unit? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, onUserMentionClick: (User) -> Unit = {}, dateSeparatorContent: @Composable (DateSeparatorItemState) -> Unit = { DefaultMessageDateSeparatorContent(dateSeparator = it) }, unreadSeparatorContent: @Composable (UnreadSeparatorItemState) -> Unit = { DefaultMessageUnreadSeparatorContent(unreadSeparatorItemState = it) }, threadSeparatorContent: @Composable (ThreadDateSeparatorItemState) -> Unit = { DefaultMessageThreadSeparatorContent(threadSeparator = it) }, systemMessageContent: @Composable (SystemMessageItemState) -> Unit = { DefaultSystemMessageContent(systemMessageState = it) }, moderatedMessageContent: @Composable (ModeratedMessageItemState) -> Unit = { DefaultMessageModeratedContent(moderatedMessageItemState = it) }, messageItemContent: @Composable (MessageItemState) -> Unit = { DefaultMessageItem( messageItem = it, messageContentFactory = messageContentFactory, reactionSorting = reactionSorting, onLongItemClick = onLongItemClick, onReactionsClick = onReactionsClick, onThreadClick = onThreadClick, onPollUpdated = onPollUpdated, onCastVote = onCastVote, onRemoveVote = onRemoveVote, selectPoll = selectPoll, onClosePoll = onClosePoll, onAddPollOption = onAddPollOption, onGiphyActionClick = onGiphyActionClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, onUserAvatarClick = { onUserAvatarClick?.invoke(it.message.user) }, onLinkClick = onLinkClick, onUserMentionClick = onUserMentionClick, onAddAnswer = onAddAnswer, ) }, typingIndicatorContent: @Composable (TypingItemState) -> Unit = { }, emptyThreadPlaceholderItemContent: @Composable (EmptyThreadPlaceholderItemState) -> Unit = { }, startOfTheChannelItemState: @Composable (StartOfTheChannelItemState) -> Unit = { })

Represents the message item container that allows us to customize each type of item in the MessageList.

Link copied to clipboard
fun MessageItem(messageItem: MessageItemState, reactionSorting: ReactionSorting, onLongItemClick: (Message) -> Unit, modifier: Modifier = Modifier, messageContentFactory: MessageContentFactory = ChatTheme.messageContentFactory, onReactionsClick: (Message) -> Unit = {}, onThreadClick: (Message) -> Unit = {}, onPollUpdated: (Message, Poll) -> Unit = { _, _ -> }, onCastVote: (Message, Poll, Option) -> Unit = { _, _, _ -> }, onRemoveVote: (Message, Poll, Vote) -> Unit = { _, _, _ -> }, selectPoll: (Message, Poll, PollSelectionType) -> Unit = { _, _, _ -> }, onAddAnswer: (message: Message, poll: Poll, answer: String) -> Unit = { _, _, _ -> }, onClosePoll: (String) -> Unit = {}, onAddPollOption: (poll: Poll, option: String) -> Unit = { _, _ -> }, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onUserAvatarClick: () -> Unit? = null, onLinkClick: (Message, String) -> Unit? = null, onUserMentionClick: (User) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, leadingContent: @Composable RowScope.(MessageItemState) -> Unit = { DefaultMessageItemLeadingContent( messageItem = it, onUserAvatarClick = onUserAvatarClick, ) }, headerContent: @Composable ColumnScope.(MessageItemState) -> Unit = { DefaultMessageItemHeaderContent( messageItem = it, reactionSorting = reactionSorting, onReactionsClick = onReactionsClick, ) }, centerContent: @Composable ColumnScope.(MessageItemState) -> Unit = { DefaultMessageItemCenterContent( messageItem = it, onLongItemClick = onLongItemClick, messageContentFactory = messageContentFactory, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onGiphyActionClick = onGiphyActionClick, onQuotedMessageClick = onQuotedMessageClick, onLinkClick = onLinkClick, onUserMentionClick = onUserMentionClick, onPollUpdated = onPollUpdated, onCastVote = onCastVote, onRemoveVote = onRemoveVote, selectPoll = selectPoll, onAddAnswer = onAddAnswer, onClosePoll = onClosePoll, onAddPollOption = onAddPollOption, ) }, footerContent: @Composable ColumnScope.(MessageItemState) -> Unit = { DefaultMessageItemFooterContent(messageItem = it, messageContentFactory = messageContentFactory) }, trailingContent: @Composable RowScope.(MessageItemState) -> Unit = { DefaultMessageItemTrailingContent(messageItem = it) })

The default message container for all messages in the Conversation/Messages screen.

Link copied to clipboard
fun MessageList(viewModel: MessageListViewModel, reactionSorting: ReactionSorting = ReactionSortingByFirstReactionAt, modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(vertical = 16.dp), messageContentFactory: MessageContentFactory = ChatTheme.messageContentFactory, messagesLazyListState: MessagesLazyListState = rememberMessageListState(parentMessageId = viewModel.currentMessagesState.parentMessageId), threadMessagesStart: ThreadMessagesStart = ThreadMessagesStart.BOTTOM, onThreadClick: (Message) -> Unit = { viewModel.openMessageThread(it) }, onLongItemClick: (Message) -> Unit = { viewModel.selectMessage(it) }, onReactionsClick: (Message) -> Unit = { viewModel.selectReactions(it) }, onMessagesPageStartReached: () -> Unit = { viewModel.loadOlderMessages() }, onLastVisibleMessageChanged: (Message) -> Unit = { viewModel.updateLastSeenMessage(it) }, onScrollToBottom: () -> Unit = { viewModel.clearNewMessageState() }, onGiphyActionClick: (GiphyAction) -> Unit = { viewModel.performGiphyAction(it) }, onPollUpdated: (Message, Poll) -> Unit = { message, poll -> val selectedPoll = viewModel.pollState.selectedPoll if (viewModel.isShowingPollOptionDetails && selectedPoll != null && selectedPoll.poll.id == poll.id ) { viewModel.updatePollState(poll, message, selectedPoll.pollSelectionType) } }, onCastVote: (Message, Poll, Option) -> Unit = { message, poll, option -> viewModel.castVote( message = message, poll = poll, option = option, ) }, onRemoveVote: (Message, Poll, Vote) -> Unit = { message, poll, vote -> viewModel.removeVote( message = message, poll = poll, vote = vote, ) }, selectPoll: (Message, Poll, PollSelectionType) -> Unit = { message, poll, selectionType -> viewModel.displayPollMoreOptions(selectedPoll = SelectedPoll(poll, message, selectionType)) }, onAddAnswer: (message: Message, poll: Poll, answer: String) -> Unit = { message, poll, answer -> viewModel.castAnswer(message, poll, answer) }, onClosePoll: (String) -> Unit = { pollId -> viewModel.closePoll(pollId = pollId) }, onAddPollOption: (poll: Poll, option: String) -> Unit = { poll, option -> viewModel.addPollOption(poll, option) }, onQuotedMessageClick: (Message) -> Unit = { message -> viewModel.scrollToMessage( messageId = message.id, parentMessageId = message.parentId, ) }, onUserAvatarClick: (User) -> Unit? = null, onMessageLinkClick: (Message, String) -> Unit? = null, onUserMentionClick: (User) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = { if (it?.resultType == MediaGalleryPreviewResultType.SHOW_IN_CHAT) { viewModel.scrollToMessage( messageId = it.messageId, parentMessageId = it.parentMessageId, ) } }, onMessagesPageEndReached: (String) -> Unit = { viewModel.onBottomEndRegionReached(it) }, onScrollToBottomClicked: (() -> Unit) -> Unit = { viewModel.scrollToBottom(scrollToBottom = it) }, loadingContent: @Composable () -> Unit = { DefaultMessageListLoadingIndicator(modifier) }, emptyContent: @Composable () -> Unit = { DefaultMessageListEmptyContent(modifier) }, helperContent: @Composable BoxScope.() -> Unit = { DefaultMessagesHelperContent( messagesState = viewModel.currentMessagesState, messagesLazyListState = messagesLazyListState, scrollToBottom = onScrollToBottomClicked, ) }, loadingMoreContent: @Composable () -> Unit = { DefaultMessagesLoadingMoreIndicator() }, itemContent: @Composable (MessageListItemState) -> Unit = { messageListItem -> DefaultMessageContainer( messageListItemState = messageListItem, reactionSorting = reactionSorting, messageContentFactory = messageContentFactory, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onCastVote = onCastVote, onRemoveVote = onRemoveVote, selectPoll = selectPoll, onPollUpdated = onPollUpdated, onClosePoll = onClosePoll, onAddPollOption = onAddPollOption, onThreadClick = onThreadClick, onLongItemClick = onLongItemClick, onReactionsClick = onReactionsClick, onGiphyActionClick = onGiphyActionClick, onQuotedMessageClick = onQuotedMessageClick, onUserAvatarClick = onUserAvatarClick, onLinkClick = onMessageLinkClick, onUserMentionClick = onUserMentionClick, onAddAnswer = onAddAnswer, ) })

Default MessageList component, that relies on MessageListViewModel to connect all the data handling operations. It also delegates events to the ViewModel to handle, like long item clicks and pagination.

fun MessageList(currentState: MessageListState, threadMessagesStart: ThreadMessagesStart = ThreadMessagesStart.BOTTOM, reactionSorting: ReactionSorting, modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(vertical = 16.dp), messageContentFactory: MessageContentFactory = ChatTheme.messageContentFactory, messagesLazyListState: MessagesLazyListState = rememberMessageListState(parentMessageId = currentState.parentMessageId), onMessagesPageStartReached: () -> Unit = {}, onLastVisibleMessageChanged: (Message) -> Unit = {}, onScrolledToBottom: () -> Unit = {}, onPollUpdated: (Message, Poll) -> Unit = { _, _ -> }, onCastVote: (Message, Poll, Option) -> Unit = { _, _, _ -> }, onRemoveVote: (Message, Poll, Vote) -> Unit = { _, _, _ -> }, selectPoll: (Message, Poll, PollSelectionType) -> Unit = { _, _, _ -> }, onAddAnswer: (message: Message, poll: Poll, answer: String) -> Unit = { _, _, _ -> }, onClosePoll: (String) -> Unit = { _ -> }, onAddPollOption: (poll: Poll, option: String) -> Unit = { _, _ -> }, onThreadClick: (Message) -> Unit = {}, onLongItemClick: (Message) -> Unit = {}, onReactionsClick: (Message) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onMessagesPageEndReached: (String) -> Unit = {}, onScrollToBottom: (() -> Unit) -> Unit = {}, onUserAvatarClick: (User) -> Unit? = null, onMessageLinkClick: (Message, String) -> Unit? = null, onUserMentionClick: (User) -> Unit = { _ -> }, loadingContent: @Composable () -> Unit = { DefaultMessageListLoadingIndicator(modifier) }, emptyContent: @Composable () -> Unit = { DefaultMessageListEmptyContent(modifier) }, helperContent: @Composable BoxScope.() -> Unit = { DefaultMessagesHelperContent( messagesState = currentState, messagesLazyListState = messagesLazyListState, scrollToBottom = onScrollToBottom, ) }, loadingMoreContent: @Composable () -> Unit = { DefaultMessagesLoadingMoreIndicator() }, itemModifier: (index: Int, item: MessageListItemState) -> Modifier = { _, _ -> Modifier }, itemContent: @Composable (MessageListItemState) -> Unit = { DefaultMessageContainer( messageListItemState = it, reactionSorting = reactionSorting, messageContentFactory = messageContentFactory, onPollUpdated = onPollUpdated, onCastVote = onCastVote, onRemoveVote = onRemoveVote, selectPoll = selectPoll, onClosePoll = onClosePoll, onAddPollOption = onAddPollOption, onLongItemClick = onLongItemClick, onThreadClick = onThreadClick, onReactionsClick = onReactionsClick, onGiphyActionClick = onGiphyActionClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, onUserAvatarClick = onUserAvatarClick, onLinkClick = onMessageLinkClick, onUserMentionClick = onUserMentionClick, onAddAnswer = onAddAnswer, ) })

Clean representation of the MessageList that is decoupled from ViewModels. This components allows users to connect the UI to their own data providers, as it relies on pure state.

Link copied to clipboard
fun Messages(messagesState: MessageListState, messagesLazyListState: MessagesLazyListState, threadMessagesStart: ThreadMessagesStart = ThreadMessagesStart.BOTTOM, onMessagesStartReached: () -> Unit, onLastVisibleMessageChanged: (Message) -> Unit, onScrolledToBottom: () -> Unit, onMessagesEndReached: (String) -> Unit, onScrollToBottom: (() -> Unit) -> Unit, modifier: Modifier = Modifier, contentPadding: PaddingValues = PaddingValues(vertical = 16.dp), helperContent: @Composable BoxScope.() -> Unit = { DefaultMessagesHelperContent( messagesState = messagesState, messagesLazyListState = messagesLazyListState, scrollToBottom = onScrollToBottom, ) }, loadingMoreContent: @Composable () -> Unit = { DefaultMessagesLoadingMoreIndicator() }, itemModifier: (index: Int, item: MessageListItemState) -> Modifier = { _, _ -> Modifier }, itemContent: @Composable (MessageListItemState) -> Unit)

Builds a list of message items, based on the itemContent parameter and the state provided within messagesState. Also handles the pagination events, by propagating the event to the call site.

Link copied to clipboard
fun RegularMessageContent(messageItem: MessageItemState, modifier: Modifier = Modifier, messageContentFactory: MessageContentFactory = ChatTheme.messageContentFactory, onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onLinkClick: (Message, String) -> Unit? = null, onUserMentionClick: (User) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {})

Message content for messages which consist of more than just emojis.