Skip to content

Add AddMembersBottomSheet component to the GroupChannelInfoScreen#6276

Open
VelikovPetar wants to merge 6 commits intov7from
feature/add_members
Open

Add AddMembersBottomSheet component to the GroupChannelInfoScreen#6276
VelikovPetar wants to merge 6 commits intov7from
feature/add_members

Conversation

@VelikovPetar
Copy link
Contributor

@VelikovPetar VelikovPetar commented Mar 20, 2026

Goal

Adds the new AddMembersBottomSheet composable to the Compose UI SDK.

Implementation

  • Add new AddMembersBottomSheet composable (+ VM / Controller)
  • Table customisation via ChatComponentFactory

🎨 UI Changes

See snapshots.

Testing

  1. Open a group channel (that you are owner of)
  2. Open channel info
  3. Tap Add members
  4. The new bottom sheet should appear

Summary by CodeRabbit

Release Notes

  • New Features
    • Added "Add Members" bottom sheet for group channels with search functionality, multi-select capabilities, and real-time member status indicators. Users can search for members, select or deselect multiple users, and confirm additions. The interface includes loading states, empty result messaging, and indicators for existing members.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled.

🎉 Great job! This PR is ready for review.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.68 MB 0.43 MB 🟡
stream-chat-android-ui-components 10.60 MB 10.99 MB 0.39 MB 🟡
stream-chat-android-compose 12.81 MB 12.15 MB -0.66 MB 🚀

currentUser: User? = ChatClient.instance().getCurrentUser(),
onNavigationIconClick: () -> Unit = {},
@Suppress("UNUSED_PARAMETER")
onAddMembersClick: () -> Unit = {},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Point to discuss: Do we remove this completely, or allow customers to override it?
They can now override the whole add members, so I am not sure if it makes sense to keep it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove it given that we don't call it anymore, it seems misleading.

/**
* @see [ChannelInfoViewController.addMembers]
*/
public fun addMembers(userIds: Set<String>) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delegated the addMembers call from the AddMembersViewModel to here: The idea is to keep the AddMembers simpler, and if customised, the integrators don't need to worry about calling the addMembers operation manually, they can just call params.onConfirm.
This is also aligned with the SwiftUI API, but I am open for discussion.

(it is also NOT defined as a ChannelInfoViewAction because I believe it is a separate type of action).

@VelikovPetar VelikovPetar added the pr:new-feature New feature label Mar 20, 2026
@VelikovPetar VelikovPetar marked this pull request as ready for review March 20, 2026 13:06
@VelikovPetar VelikovPetar requested a review from a team as a code owner March 20, 2026 13:06
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
74.7% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

Walkthrough

This pull request relocates the "Add Members" feature from the sample app into the main Compose library, converting the dialog-based UI to a bottom sheet, and establishing a layered architecture with a shared business logic controller in the ui-common module.

Changes

Cohort / File(s) Summary
Sample App Removal
stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/AddMembersDialog.kt, stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/AddMembersViewModel.kt
Deleted entire dialog-based Add Members UI implementation and its view model (283 + 185 lines).
Sample App Integration Updates
stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/GroupChannelInfoActivity.kt, stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/chats/ChatsActivity.kt
Removed local state management and dialog rendering for Add Members feature.
Compose Library - Bottom Sheet UI
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/AddMembersBottomSheet.kt
Added new 500-line bottom sheet implementation with header, search input, loading/empty states, user list, selection controls, and pagination support.
Compose Library - View Model & Factory
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/AddMembersViewModel.kt, stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/ChannelInfoViewModel.kt, stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/ChannelInfoViewModelFactory.kt
Added new AddMembersViewModel wrapping a controller, extended ChannelInfoViewModel with addMembers() method, and updated factory to support instantiation.
Compose Library - Theme & Components
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt, stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt
Added new factory method AddMembersBottomSheet() and AddMembersBottomSheetParams data class for customizable UI rendering.
Compose Library - Screen Integration
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/GroupChannelInfoScreen.kt
Deprecated callback parameter, added internal bottom sheet state management, and conditional rendering of Add Members bottom sheet.
UI-Common Library - Business Logic
stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewAction.kt, stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewController.kt, stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channel/info/AddMembersViewState.kt, stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/ChannelInfoViewController.kt
Introduced sealed interface for UI actions, new 169-line controller managing async user search/pagination/selection, state holder with computed properties, and addMembers() delegation method.
API Declarations
stream-chat-android-compose/api/stream-chat-android-compose.api, stream-chat-android-ui-common/api/stream-chat-android-ui-common.api
Updated public API declarations reflecting new bottom sheet params, view model, and controller classes.
Tests
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channel/info/AddMembersBottomSheetTest.kt, stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channel/AddMembersViewModelTest.kt, stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channel/ChannelInfoViewModelFactoryTest.kt, stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewControllerTest.kt
Added Paparazzi snapshot tests for UI variants, view model unit tests with mocked controller, factory creation test, and comprehensive 328-line controller test suite covering search/pagination/selection.
Resources & Preview Data
stream-chat-android-compose/src/main/res/values/strings.xml, stream-chat-android-previewdata/src/main/kotlin/io/getstream/chat/android/previewdata/PreviewUserData.kt
Added three new string resources for bottom sheet titles/messages and exposed user6 from preview data as public.

Sequence Diagram

sequenceDiagram
    participant User
    participant BottomSheet as Bottom Sheet UI
    participant ViewModel as AddMembersViewModel
    participant Controller as AddMembersViewController
    participant ChatClient
    participant ChannelState

    User->>BottomSheet: Type search query
    BottomSheet->>ViewModel: QueryChanged(query)
    ViewModel->>Controller: onViewAction(QueryChanged)
    activate Controller
    Controller->>ChatClient: queryUsers(request)
    ChatClient-->>Controller: searchResult
    Controller->>Controller: Update state (isLoading=false)
    deactivate Controller
    Controller-->>ViewModel: state updated
    ViewModel-->>BottomSheet: state emitted
    BottomSheet->>User: Show search results

    User->>BottomSheet: Click user to select
    BottomSheet->>ViewModel: UserClick(user)
    ViewModel->>Controller: onViewAction(UserClick)
    activate Controller
    Controller->>Controller: Toggle selectedUserIds
    deactivate Controller
    Controller-->>ViewModel: state updated
    ViewModel-->>BottomSheet: state emitted
    BottomSheet->>User: Show selection indicator

    User->>BottomSheet: Scroll to bottom
    BottomSheet->>ViewModel: LoadMore
    ViewModel->>Controller: onViewAction(LoadMore)
    activate Controller
    Controller->>ChatClient: queryUsers(offset=current size)
    ChatClient-->>Controller: nextPage results
    Controller->>Controller: Append to searchResult
    deactivate Controller
    Controller-->>ViewModel: state updated
    ViewModel-->>BottomSheet: state emitted
    BottomSheet->>User: Show appended results

    User->>BottomSheet: Confirm selection
    BottomSheet->>ViewModel: Confirm button clicked
    ViewModel->>ChannelState: infoViewModel.addMembers(selectedUserIds)
    activate ChannelState
    ChannelState->>ChatClient: addMembers(AddMembersParams)
    ChatClient-->>ChannelState: Success
    deactivate ChannelState
    ChannelState-->>BottomSheet: onConfirm callback
    BottomSheet->>User: Dismiss & show updated member list
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 From samples to libraries, the members feature hops,
A bottom sheet replaces dialogs—the refactoring never stops!
Controllers, view models, and tests all neatly stacked,
Layered architecture keeps the code on track.
Search, select, and confirm—pagination's in the pack! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description includes Goal, Implementation, and Testing sections but lacks UI Changes with before/after images and the Contributor Checklist required by the template. Add before/after screenshots/videos demonstrating the bottom sheet UI, and include the Contributor and Reviewer checklists to meet full template requirements.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main change: adding the AddMembersBottomSheet component to GroupChannelInfoScreen.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/add_members
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channel/AddMembersViewModelTest.kt (1)

65-74: Missing mock setup for state flow in action delegation tests.

The action delegation tests (lines 65-95) call fixture.get() without first calling givenControllerStateFlow(). This could cause issues if accessing mockController.state is needed during ViewModel initialization or if the mock returns null by default.

Consider adding a default state flow setup in the Fixture or ensuring all tests that create the ViewModel also set up the state flow:

♻️ Proposed fix
     private class Fixture {
         private val mockController: AddMembersViewController = mock()

+        init {
+            // Provide a default state flow to avoid null issues
+            whenever(mockController.state) doReturn MutableStateFlow(AddMembersViewState())
+        }
+
         fun givenControllerStateFlow(stateFlow: MutableStateFlow<AddMembersViewState>) = apply {
             whenever(mockController.state) doReturn stateFlow
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channel/AddMembersViewModelTest.kt`
around lines 65 - 74, The test creates the ViewModel via Fixture.get() without
initializing the mocked controller's state Flow, which can return null or cause
initialization failures; update the Fixture to provide a default state Flow by
calling or invoking givenControllerStateFlow() inside Fixture.get() (or ensure
every test calls fixture.givenControllerStateFlow() before fixture.get()), so
mockController.state returns a non-null Flow during AddMembersViewModel
construction and methods like onViewAction/verifyControllerOnViewAction work
reliably.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/ChannelInfoViewController.kt`:
- Around line 238-240: The addMembers onError currently only logs the error;
update the addMembers error handler to emit a
ChannelInfoViewEvent.AddMembersError (using the same event emission mechanism
used elsewhere in this controller, e.g., the existing emit/postEvent/eventSink
calls) and include the error details so the UI can react; also add the
AddMembersError variant to the ChannelInfoViewEvent sealed class/interface to
match other operations like renameChannel, setChannelMute, and banMember.

---

Nitpick comments:
In
`@stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channel/AddMembersViewModelTest.kt`:
- Around line 65-74: The test creates the ViewModel via Fixture.get() without
initializing the mocked controller's state Flow, which can return null or cause
initialization failures; update the Fixture to provide a default state Flow by
calling or invoking givenControllerStateFlow() inside Fixture.get() (or ensure
every test calls fixture.givenControllerStateFlow() before fixture.get()), so
mockController.state returns a non-null Flow during AddMembersViewModel
construction and methods like onViewAction/verifyControllerOnViewAction work
reliably.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e1b60bb5-86a5-4a25-a0d7-890f600bfaad

📥 Commits

Reviewing files that changed from the base of the PR and between 9cb3f89 and 12164ac.

⛔ Files ignored due to path filters (14)
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_empty.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_empty_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_loading.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_loading_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_loading_more.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_loading_more_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results_with_existing_member.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results_with_existing_member_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results_with_query.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results_with_query_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results_with_selection.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_AddMembersBottomSheetTest_results_with_selection_in_dark_mode.png is excluded by !**/*.png
📒 Files selected for processing (23)
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/AddMembersDialog.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/AddMembersViewModel.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/GroupChannelInfoActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/chats/ChatsActivity.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/AddMembersBottomSheet.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/GroupChannelInfoScreen.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/AddMembersViewModel.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/ChannelInfoViewModel.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/ChannelInfoViewModelFactory.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/channel/info/AddMembersBottomSheetTest.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channel/AddMembersViewModelTest.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/viewmodel/channel/ChannelInfoViewModelFactoryTest.kt
  • stream-chat-android-previewdata/src/main/kotlin/io/getstream/chat/android/previewdata/PreviewUserData.kt
  • stream-chat-android-ui-common/api/stream-chat-android-ui-common.api
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewAction.kt
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewController.kt
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/ChannelInfoViewController.kt
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channel/info/AddMembersViewState.kt
  • stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewControllerTest.kt
💤 Files with no reviewable changes (4)
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/chats/ChatsActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/AddMembersDialog.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/GroupChannelInfoActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/AddMembersViewModel.kt
👮 Files not reviewed due to content moderation or server errors (5)
  • stream-chat-android-ui-common/api/stream-chat-android-ui-common.api
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/state/channel/info/AddMembersViewState.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/info/AddMembersBottomSheet.kt
  • stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewControllerTest.kt
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/AddMembersViewController.kt

Comment on lines +238 to +240
.onError { error ->
logger.e { "[addMembers] error: ${error.message}" }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Consider emitting an error event on failure.

Unlike other operations in this controller (e.g., renameChannel, setChannelMute, banMember), addMembers only logs the error without emitting a ChannelInfoViewEvent. This means the UI cannot inform the user when adding members fails.

For consistency and better UX, consider adding an AddMembersError event:

Proposed fix
             .onError { error ->
                 logger.e { "[addMembers] error: ${error.message}" }
+                _events.tryEmit(ChannelInfoViewEvent.AddMembersError)
             }

You'll also need to add the corresponding event to ChannelInfoViewEvent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/channel/info/ChannelInfoViewController.kt`
around lines 238 - 240, The addMembers onError currently only logs the error;
update the addMembers error handler to emit a
ChannelInfoViewEvent.AddMembersError (using the same event emission mechanism
used elsewhere in this controller, e.g., the existing emit/postEvent/eventSink
calls) and include the error details so the UI can react; also add the
AddMembersError variant to the ChannelInfoViewEvent sealed class/interface to
match other operations like renameChannel, setChannelMute, and banMember.

Copy link
Contributor

@gpunto gpunto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, just left a few comments

/**
* The list of users selected to be added as members, derived from [searchResult] and [selectedUserIds].
*/
public val selectedUsers: List<User> get() = searchResult.filter { it.id in selectedUserIds }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we're dropping all selected users that are not in the current search results. This can happen for example if I do query1 -> select users -> query2 -> select more users. Is that intended?

If not, I see a couple of options: store users instead of ids (maybe a map from ID to User), or just propagate the set of IDs instead of a list of users.


private fun searchUsers(query: String) {
scope.launch {
_state.update { it.copy(isLoading = true) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we cancel ongoing calls here? I think atm we are exposed to a race condition where it could happen something like this:

  1. we start loading some page (or some search)
  2. the user perform another search
  3. we get first results from 2 and then from 1

We could store a reference to the current operation and cancel it before doing any other?

}

private fun loadMore() {
if (_state.value.isLoadingMore) return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also check isLoading or is that an invalid scenario?

init {
// Keep loadedMemberIds in sync with the live channel member list.
channelMembers
.map { members -> members.map(Member::getUserId).toSet() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: just to avoid an allocation

Suggested change
.map { members -> members.map(Member::getUserId).toSet() }
.map { members -> members.mapTo(mutableSetOf(), Member::getUserId) }

public fun onViewAction(action: AddMembersViewAction) {
when (action) {
is AddMembersViewAction.QueryChanged -> {
_state.update { it.copy(query = action.query.trim()) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this trim elsewhere? Given that this is observed by the ui, if I type a space, it will be immediately removed. Maybe we could put it above, in the listener in the init block, like .map { it.query.trim() }

bottom = StreamTokens.spacing3xl,
),
) {
itemsIndexed(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be items? It seems we're not using the index 🤔

verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacingSm),
) {
UserAvatar(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we pass through ChatComponentFactory?

currentUser: User? = ChatClient.instance().getCurrentUser(),
onNavigationIconClick: () -> Unit = {},
@Suppress("UNUSED_PARAMETER")
onAddMembersClick: () -> Unit = {},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove it given that we don't call it anymore, it seems misleading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:new-feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants