Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
JcMinarro committed Mar 15, 2024
1 parent 7977445 commit fd349b7
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The easiest way to set up a screen that shows the active user's channels and giv
`ChannelsScreen` sets up the following functionality internally:

* Header with the information of the current user and customizable title and action.
* Search input that can be shown or hidden that allows users to search for channels by name.
* Search input that can be shown or hidden that allows users to search for channels by name or message text.
* List of user's channels with pagination, based on defined filters and sorting.
* Menu with detailed channel information, shown when long clicking on a `Channel` in the list.

Expand Down Expand Up @@ -49,7 +49,8 @@ fun ChannelsScreen(
..., // ViewModel factory and UI customization
onHeaderActionClick: () -> Unit = {},
onHeaderAvatarClick: () -> Unit = {},
onItemClick: (Channel) -> Unit = {},
onChannelClick: (Channel) -> Unit = {},
onSearchMessageItemClick: (Message) -> Unit = {},
onViewChannelInfoAction: (Channel) -> Unit = {},
onBackPressed: () -> Unit = {},
)
Expand All @@ -59,8 +60,9 @@ There are several action handlers you can use with the `ChannelsScreen`:

* `onHeaderActionClick`: Handler for the default header trailing icon click action.
* `onHeaderAvatarClick`: Handler for the clicks on the user avatar in the header.
* `onItemClick`: Handler for a `Channel` being clicked.
* `onViewChannelInfoAction`: Handler for the **View info** action selected in `SelectedChannelMenu`.
* `onChannelClick`: Handler for a `Channel` being clicked.
* `onSearchMessageItemClick`: Handler for a `Message` being clicked.
* `onViewChannelInfoAction`: Handler for the **View info** action selected in `SelectedChannelMenu`.
* `onBackPressed`: Handler for the system back button being clicked.

All of these actions are empty by default, but if you want to customize them, you can do the following:
Expand All @@ -72,9 +74,12 @@ override fun onCreate(savedInstanceState: Bundle?) {
setContent {
ChatTheme {
ChannelsScreen(
onItemClick = {
onChannelClick = {
// Open messages screen
},
onSearchMessageItemClick = {
// Open messages screen and scroll to the message
},
onHeaderActionClick = {
// Handle the header click action
},
Expand Down Expand Up @@ -149,15 +154,19 @@ fun ChannelsScreen(
),
title: String = "Stream Chat",
isShowingHeader: Boolean = true,
isShowingSearch: Boolean = false,
searchMode: SearchMode = SearchMode.None,
... // Action handlers
)
```

* `viewModelFactory`: The factory that you build yourself, if you want access to `ViewModels` for custom behavior. This lets you control not just the way the `ViewModel`s are built, but also their lifecycle, as you can share them between components. You can also customize its parameters to affect the behavior of the screen.
* `title`: The title of the `ChannelListHeader`.
* `isShowingHeader`: Flag that affects if we show the `ChannelListHeader`. `true` by default.
* `isShowingSearch`: Flag that affects if we show the `SearchInput`. `false` by default.
* `searchMode`: SearchMode to be configured for the `SearchInput`. `SearchMode.None` by default. It can take the following values:
* `SearchMode.None`: Hides the search input.
* `SearchMode.Search`: Shows the search input.
* `SearchMode.Filter`: Shows the filter input.
* `SearchMode.SearchAndFilter`: Shows both the search and filter inputs.

:::note
If you want to build a completely custom channel list, follow our [Custom Channel List](../../04-compose-cookbook/02-custom-channel-list.mdx) Cookbook recipe.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ fun ChannelList(
onLastItemReached: () -> Unit = { viewModel.loadMore() },
onChannelClick: (Channel) -> Unit = {},
onChannelLongClick: (Channel) -> Unit = { viewModel.selectChannel(it) },
onSearchResultClick: (Message) -> Unit = {},
... // Content Slots
)
```
Expand All @@ -65,6 +66,7 @@ fun ChannelList(
* `onLastItemReached`: Handler when the user reaches the last item in the list to trigger pagination. You don't need to override this if you're using the default `viewModel`, but if you're using a custom one, you can add custom behavior.
* `onChannelClick`: Handler when the user taps on an item. Useful for starting the `MessagesScreen`.
* `onChannelLongClick`: Handler when the user long taps on an item. By default, this updates state in the `viewModel`, which you can read to show custom UI and `Channel` actions if you're using a custom `ViewModel` instance. Override if you're using the default `viewModel` and you want to change the behavior.
* `onSearchResultClick`: Handler when the user taps on a search result item. Useful for starting the `MessagesScreen` with the selected message.

:::note
<!-- TODO link to guides, which we'll remove. Revisit after re-organizing pages. (Liviu) -->
Expand All @@ -91,6 +93,9 @@ override fun onCreate(savedInstanceState: Bundle?) {
onChannelClick = {
// Start the MessagesScreen
},
onSearchResultClick = {
// Start the MessagesScreen with the selected message
}
)

if (selectedChannel != null) {
Expand All @@ -105,6 +110,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
In the example above, we created a `selectedChannel` state holder, which we use to show some custom UI if the data is not null. We update the state when the user long taps on an item.

We also provide a custom `onChannelClick` handler, to open the `MessagesScreen` with the selected item. This will produce the same UI, but with user-defined actions.
Finally we provide a custom `onSearchResultClick` handler, to open the `MessagesScreen` with the selected message.

Alternatively, you can override the default `ViewModel` and read the internal state:

Expand All @@ -122,7 +128,10 @@ override fun onCreate(savedInstanceState: Bundle?) {
viewModel = listViewModel, // Passing in our ViewModel
onChannelClick = {
// Start the MessagesScreen
}
},
onSearchResultClick = {
// Start the MessagesScreen with the selected message
},
)

if (listViewModel.selectedChannel != null) {
Expand Down Expand Up @@ -180,7 +189,8 @@ fun ChannelList(
emptySearchContent: @Composable (String) -> Unit = { ... },
helperContent: @Composable BoxScope.() -> Unit = { ... },
loadingMoreContent: @Composable () -> Unit = { ... },
itemContent: @Composable (ChannelItemState) -> Unit = { ... },
channelContent: @Composable (ItemState.ChannelItemState) -> Unit = { ... },
searchResultContent: @Composable (ItemState.SearchResultItemState) -> Unit = { ... },
divider: @Composable () -> Unit = { ... },
)
```
Expand All @@ -192,17 +202,18 @@ fun ChannelList(
* `emptySearchContent`: Customizable composable that allows you to override the empty state, when there are no channels matching the search query.
* `helperContent`: Composable that represents helper content for the channel list. Empty by default, but can be used, for example, to display back to top floating action button.
* `loadingMoreContent`: Composable that represents the loading more content, when we're loading the next page.
* `itemContent`: Customizable composable that allows you to fully override the UI and behavior of channel items. This will be applied to each item in the list, and you'll gain access to the `Channel` inside the lambda when building your custom UI.
* `channelContent`: Customizable composable that allows you to fully override the UI and behavior of channel items. This will be applied to each item in the list, and you'll gain access to the `Channel` inside the lambda when building your custom UI.
* `searchResultContent`: Customizable composable that allows you to fully override the UI and behavior of search result items. This will be applied to each item in the list, and you'll gain access to the `Message` inside the lambda when building your custom UI.
* `divider`: Customizable composable that allows you to override the item divider.

Here's a simple example for building your own channel item, by overriding the `itemContent` parameter:
Here's a simple example for building your own channel item, by overriding the `channelContent` parameter:

```kotlin
val user by listViewModel.user.collectAsState() // Fetch user

ChannelList(
..., // Set up state
itemContent = { // Customize the channel items
channelContent = { // Customize the channel items
Row(
modifier = Modifier
.padding(8.dp)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Channel Items

The `ChannelItem` component represents the `ChannelList` items that are shown by default if you don't customize its `itemContent`.
The `ChannelItem` component represents the `ChannelList` items that are shown by default if you don't customize its `channelContent`.

However, you can also use the `ChannelItem` and customize its Slot APIs, in case you want only to replace a specific part of the default UI.

Expand All @@ -12,7 +12,7 @@ Let's see how to use and customize this component.

## Usage

To use the `ChannelItem`, it's best to override the `itemContent` parameter in the `ChannelList` and use it for the channel items:
To use the `ChannelItem`, it's best to override the `channelContent` parameter in the `ChannelList` and use it for the channel items:

```kotlin
val listViewModel: ChannelListViewModel by viewModels { ChannelViewModelFactory() }
Expand All @@ -25,7 +25,7 @@ override fun onCreate(savedInstanceState: Bundle?) {

ChatTheme {
ChannelList(
itemContent = { channelItem -> // Customize the channel items
channelContent = { channelItem -> // Customize the channel items
ChannelItem(
channelItem = channelItem,
currentUser = user,
Expand All @@ -39,7 +39,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
}
```

This is a very basic and crude example of a `ChannelList`, where you override the `itemContent`.
This is a very basic and crude example of a `ChannelList`, where you override the `channelContent`.

The snippet above will generate the following UI.

Expand Down Expand Up @@ -77,7 +77,7 @@ override fun onCreate(savedInstanceState: Bundle?) {

ChatTheme {
ChannelList(
itemContent = { channelItem ->
channelContent = { channelItem ->
ChannelItem(
channelItem = channelItem,
currentUser = user,
Expand Down Expand Up @@ -110,9 +110,9 @@ If you're looking to customize the UI of the `ChannelItem`, there are a few ways
fun ChannelItem(
..., // State and action handlers
modifier: Modifier = Modifier,
leadingContent: @Composable RowScope.(ChannelItemState) -> Unit = { ... },
centerContent: @Composable RowScope.(ChannelItemState) -> Unit = { ... },
trailingContent: @Composable RowScope.(ChannelItemState) -> Unit = { ... },
leadingContent: @Composable RowScope.(ItemState.ChannelItemState) -> Unit = { ... },
centerContent: @Composable RowScope.(ItemState.ChannelItemState) -> Unit = { ... },
trailingContent: @Composable RowScope.(ItemState.ChannelItemState) -> Unit = { ... },
)
```

Expand All @@ -134,7 +134,7 @@ override fun onCreate(savedInstanceState: Bundle?) {

ChatTheme {
ChannelList(
itemContent = { channelItem -> // Customize the channel items
channelContent = { channelItem -> // Customize the channel items
CustomChannelListItem(channelItem = channelItem, user = user)
}
)
Expand All @@ -143,7 +143,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
}

@Composable
fun CustomChannelListItem(channelItem: ChannelItemState, user: User?) {
fun CustomChannelListItem(channelItem: ItemState.ChannelItemState, user: User?) {
ChannelItem(
channelItem = channelItem,
currentUser = user,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fun SearchInput(
* `onValueChange`: Handler when the value changes.
* `onSearchStarted`: Handler when the search starts, by focusing the input field.

You can use the `ChannelListViewModel` to search for named channels by name and distinct channels by member name. To do so, simply pass the search query from `onValueChange` callback to the `ChannelListViewModel`. The results can be displayed using the `ChannelList`.
You can use the `ChannelListViewModel` to search for named channels by name and distinct channels by member name. To do so, simply pass the search query from `onValueChange` callback to the `ChannelListViewModel` using `SearchQuery.Channels` entity. The results can be displayed using the `ChannelList.channelContent`.

```kotlin
var searchQuery by rememberSaveable { mutableStateOf("") }
Expand All @@ -61,8 +61,25 @@ SearchInput(
onValueChange = {
searchQuery = it

// Use ChannelListViewModel to search for channels
channelListViewModel.setSearchQuery(it)
// Use ChannelListViewModel to search for channels
channelListViewModel.setSearchQuery(SearchQuery.Channels(it))
}
)
```

You can also search for text messages in a channel using the `ChannelListViewModel`. To do so, pass the search query from `onValueChange` callback to the `ChannelListViewModel` using `SearchQuery.Messages` entity. The results can be displayed using the `ChannelList.searchResultContent`.

```kotlin
var searchQuery by rememberSaveable { mutableStateOf("") }

SearchInput(
...,
query = searchQuery,
onValueChange = {
searchQuery = it

// Use ChannelListViewModel to search for channels
channelListViewModel.setSearchQuery(SearchQuery.Messages(it))
}
)
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class ChannelsActivity : BaseConnectedActivity() {
title = stringResource(id = R.string.app_name),
isShowingHeader = true,
searchMode = SearchMode.Messages,
onItemClick = ::openMessages,
onChannelClick = ::openMessages,
onSearchMessageItemClick = ::openMessages,
onBackPressed = ::finish,
onHeaderAvatarClick = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ import io.getstream.chat.android.ui.common.state.channels.actions.ViewInfo
* can customize the behavior using its parameters.
* @param title Header title.
* @param isShowingHeader If we show the header or hide it.
* @param isShowingSearch If we show the search input or hide it.
* @param searchMode The search mode for the screen.
* @param onHeaderActionClick Handler for the default header action.
* @param onHeaderAvatarClick Handle for when the user clicks on the header avatar.
* @param onItemClick Handler for Channel item clicks.
* @param onChannelClick Handler for Channel item clicks.
* @param onViewChannelInfoAction Handler for when the user selects the [ViewInfo] option for a [Channel].
* @param onBackPressed Handler for back press action.
*/
Expand All @@ -92,7 +92,7 @@ public fun ChannelsScreen(
searchMode: SearchMode = SearchMode.None,
onHeaderActionClick: () -> Unit = {},
onHeaderAvatarClick: () -> Unit = {},
onItemClick: (Channel) -> Unit = {},
onChannelClick: (Channel) -> Unit = {},
onSearchMessageItemClick: (Message) -> Unit = {},
onViewChannelInfoAction: (Channel) -> Unit = {},
onBackPressed: () -> Unit = {},
Expand Down Expand Up @@ -167,7 +167,7 @@ public fun ChannelsScreen(
ChannelList(
modifier = Modifier.fillMaxSize(),
viewModel = listViewModel,
onChannelClick = onItemClick,
onChannelClick = onChannelClick,
onSearchResultClick = onSearchMessageItemClick,
onChannelLongClick = remember(listViewModel) {
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private object ComponentArchitectureScreenComponentsUsageSnippet {
ChatTheme { // Theme wrapper
ChannelsScreen(
title = "App name",
onItemClick = {
onChannelClick = {
// On item clicked action
},
onHeaderActionClick = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private object ChannelsScreenHandlingActionsSnippet {
setContent {
ChatTheme {
ChannelsScreen(
onItemClick = {
onChannelClick = {
// Open messages screen
},
onHeaderActionClick = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import io.getstream.chat.android.compose.state.channels.list.SearchQuery
import io.getstream.chat.android.compose.ui.components.SearchInput
import io.getstream.chat.android.compose.ui.theme.ChatTheme
import io.getstream.chat.android.compose.viewmodel.channels.ChannelListViewModel
Expand Down Expand Up @@ -60,7 +61,7 @@ private object SearchInputHandlingActionsSnippet {
searchQuery = it

// Use ChannelListViewModel to search for channels
channelListViewModel.setSearchQuery(it)
channelListViewModel.setSearchQuery(SearchQuery.Channels(it))
}
)
}
Expand All @@ -87,7 +88,7 @@ private object SearchInputCustomizationSnippet {
searchQuery = it

// Use ChannelListViewModel to search for channels
channelListViewModel.setSearchQuery(it)
channelListViewModel.setSearchQuery(SearchQuery.Channels(it))
},
leadingIcon = {
// Remove the leading icon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ChannelsActivity : AppCompatActivity() {
setContent {
ChatTheme(attachmentFactories = customFactories + defaultFactories) {
ChannelsScreen(
onItemClick = { channel ->
onChannelClick = { channel ->
startActivity(MessagesActivity.createIntent(this, channel.cid))
},
onBackPressed = { finish() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ChannelsActivity : AppCompatActivity() {
setContent {
ChatTheme {
ChannelsScreen(
onItemClick = { channel ->
onChannelClick = { channel ->
startActivity(MessagesActivity.getIntent(this, channel.cid))
},
onBackPressed = { finish() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ChannelsActivity : AppCompatActivity() {
setContent {
ChatTheme {
ChannelsScreen(
onItemClick = { channel ->
onChannelClick = { channel ->
startActivity(MessagesActivity.createIntent(this, channel.cid))
},
onBackPressed = { finish() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ComposeChannelsActivity : AppCompatActivity() {
ChannelsScreen(
title = stringResource(id = R.string.sdk_name_compose),
searchMode = SearchMode.Channels,
onItemClick = ::openMessages,
onChannelClick = ::openMessages,
onHeaderAvatarClick = ::logout,
onBackPressed = ::finish,
)
Expand Down

0 comments on commit fd349b7

Please sign in to comment.