Skip to content

Commit

Permalink
[AND-253] Message stateless component factories (#5593)
Browse files Browse the repository at this point in the history
* MessageList factories

* MessageItem factories

* MessageFooter factories

* Refactor to a single factory

* apiDump

* CHANGELOG

* Fix supporting the deprecated MessageContentFactory

* Fix MessageContentFactory.Deprecated condition

* Add breaking change warning
andremion authored Jan 28, 2025

Verified

This commit was signed with the committer’s verified signature.
sparrc Cameron Sparr
1 parent 97da8f4 commit 70a40af
Showing 16 changed files with 1,325 additions and 607 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -72,10 +72,12 @@
- Create snapshot tests for channels stateless components. [#5570](https://github.com/GetStream/stream-chat-android/pull/5570)
- Introduce `ChatComponentFactory` for easier channel components customization. Initially supporting channel stateless components. [#5571](https://github.com/GetStream/stream-chat-android/pull/5571)
- Create snapshot tests for messages stateless components. [#5578](https://github.com/GetStream/stream-chat-android/pull/5578)
- Create message stateless component factories and refactor to have a single component factory object. [#5593](https://github.com/GetStream/stream-chat-android/pull/5593)

### ✅ Added

### ⚠️ Changed
- 🚨 Breaking change: Change `@Composable public fun MessageContainer` function to `@Composable public fun LazyItemScope.MessageContainer` so we can use functions scoped to a list item. [#5593](https://github.com/GetStream/stream-chat-android/pull/5593)

### ❌ Removed

Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@

package io.getstream.chat.android.compose.sample.ui.component

import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyItemScope
@@ -31,95 +31,113 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import io.getstream.chat.android.compose.state.channels.list.ItemState
import io.getstream.chat.android.compose.state.mediagallerypreview.MediaGalleryPreviewResult
import io.getstream.chat.android.compose.ui.theme.ChatComponentFactory
import io.getstream.chat.android.compose.ui.theme.ChatTheme
import io.getstream.chat.android.models.Channel
import io.getstream.chat.android.models.ConnectionState
import io.getstream.chat.android.models.Message
import io.getstream.chat.android.models.Option
import io.getstream.chat.android.models.Poll
import io.getstream.chat.android.models.ReactionSorting
import io.getstream.chat.android.models.User
import io.getstream.chat.android.models.Vote
import io.getstream.chat.android.ui.common.state.messages.list.GiphyAction
import io.getstream.chat.android.ui.common.state.messages.list.MessageItemState
import io.getstream.chat.android.ui.common.state.messages.poll.PollSelectionType

class CustomChatComponentFactory : ChatComponentFactory(
channelListHeader = object : ChannelListHeader() {
@Composable
override fun RowScope.LeadingContent(
currentUser: User?,
onAvatarClick: (User?) -> Unit,
) {
Icon(
imageVector = Icons.Rounded.Face,
contentDescription = null,
)
}
class CustomChatComponentFactory : ChatComponentFactory {
@Composable
override fun RowScope.ChannelListHeaderLeadingContent(
currentUser: User?,
onAvatarClick: (User?) -> Unit,
) {
Icon(
imageVector = Icons.Rounded.Face,
contentDescription = null,
)
}

@Composable
override fun RowScope.CenterContent(
connectionState: ConnectionState,
title: String,
) {
Text(
modifier = Modifier
.padding(horizontal = 16.dp)
.weight(1f),
text = title,
textAlign = TextAlign.Center,
color = ChatTheme.colors.primaryAccent,
)
}
@Composable
override fun RowScope.ChannelListHeaderCenterContent(
connectionState: ConnectionState,
title: String,
) {
Text(
modifier = Modifier
.padding(horizontal = 16.dp)
.weight(1f),
text = title,
textAlign = TextAlign.Center,
color = ChatTheme.colors.primaryAccent,
)
}

@Composable
override fun RowScope.TrailingContent(
onHeaderActionClick: () -> Unit,
) {
Icon(
imageVector = Icons.Rounded.ThumbUp,
contentDescription = null,
)
}
},
searchInput = object : SearchInput() {
@Composable
override fun RowScope.LeadingIcon() {
Icon(
imageVector = Icons.Rounded.Build,
contentDescription = null,
)
}
@Composable
override fun RowScope.ChannelListHeaderTrailingContent(
onHeaderActionClick: () -> Unit,
) {
Icon(
imageVector = Icons.Rounded.ThumbUp,
contentDescription = null,
)
}

@Composable
override fun Label() {
Text(
text = "Search",
color = ChatTheme.colors.textHighEmphasis,
)
}
},
channelList = object : ChannelList() {
@Composable
override fun LazyItemScope.ChannelItemContent(
channelItem: ItemState.ChannelItemState,
currentUser: User?,
onChannelClick: (Channel) -> Unit,
onChannelLongClick: (Channel) -> Unit,
) {
Text(
text = channelItem.channel.name,
color = ChatTheme.colors.textHighEmphasis,
)
}
@Composable
override fun RowScope.SearchInputLeadingIcon() {
Icon(
imageVector = Icons.Rounded.Build,
contentDescription = null,
)
}

@Composable
override fun LoadingIndicator(modifier: Modifier) {
Text(
text = "Loading...",
color = ChatTheme.colors.textHighEmphasis,
)
}
@Composable
override fun SearchInputLabel() {
Text(
text = "Search",
color = ChatTheme.colors.textHighEmphasis,
)
}

@Composable
override fun BoxScope.HelperContent() {
Text(
text = "Helper content",
color = ChatTheme.colors.textLowEmphasis,
)
}
},
)
@Composable
override fun ChannelListLoadingIndicator(modifier: Modifier) {
Text(
text = "Loading...",
color = ChatTheme.colors.textHighEmphasis,
)
}

@Composable
override fun RowScope.ChannelItemLeadingContent(
channelItem: ItemState.ChannelItemState,
currentUser: User?,
) {
Image(
imageVector = Icons.Rounded.Face,
contentDescription = null,
)
}

@Composable
override fun LazyItemScope.MessageListItemContent(
messageItem: MessageItemState,
reactionSorting: ReactionSorting,
onPollUpdated: (Message, Poll) -> Unit,
onCastVote: (Message, Poll, Option) -> Unit,
onRemoveVote: (Message, Poll, Vote) -> Unit,
selectPoll: (Message, Poll, PollSelectionType) -> Unit,
onClosePoll: (String) -> Unit,
onAddPollOption: (Poll, String) -> Unit,
onLongItemClick: (Message) -> Unit,
onThreadClick: (Message) -> Unit,
onReactionsClick: (Message) -> Unit,
onGiphyActionClick: (GiphyAction) -> Unit,
onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit,
onQuotedMessageClick: (Message) -> Unit,
onUserAvatarClick: ((User) -> Unit)?,
onMessageLinkClick: ((Message, String) -> Unit)?,
onUserMentionClick: (User) -> Unit,
onAddAnswer: (Message, Poll, String) -> Unit,
) {
Text(text = messageItem.message.text)
}
}
Loading

0 comments on commit 70a40af

Please sign in to comment.