From 1eac67bf2577f1a24c87c4762fe83aca29fa7592 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 22 May 2023 10:06:54 +0100 Subject: [PATCH] Refactor search related functionality (#436) Refactor search related functionality This is a prelude to adding the feature of inviting users to a room, getting everything in the right place and reusable. What this does: ## User search refactor Moves the (global) user search logic (dealing with MXIDs, minimum lengths, debounces) into a `UserRepository`. This now sits in a `usersearch` library, which will be used by the create room flow and the new invite flow. ## SearchBar logic pull-up Every place we use SearchBar, we're doing the same things to style placeholders, show back/cancel buttons, etc. We also have a results type that is duplicated for basically every feature that uses the search bar. I've pushed all this common functionality into the SearchBar itself. This makes the component a bit less general purpose, but saves a lot of repetition. ## Remove the userlist feature Almost all the functionality of the userlist feature is now exclusively used by the create room feature. Room details uses its own version because the requirements are different. Components useful elsewhere (SelectedUsers and SelectedUser) have gone to matrixui, everything else has gone to createroom. ## Other bits and pieces I've fixed everywhere that uses Scaffold to correctly consume the WindowInsets if the contentPadding is applied to the contents (which it universally is). This was a change in the last version of Material3 (I guess previously Scaffold handled the consumption for us). This fixes weird gaps above search bars. Added overloads for the MatrixUserRow and CheckedMatrixUserRow that take the name/subtitle/avatar separately, so the invites list can pass arbitrary text like "User has already been invited". The `blockuser` package was for some reason not under `impl` but alongside it, I've bumped it into the right place. --- features/createroom/impl/build.gradle.kts | 5 +- .../createroom/impl/CreateRoomDataStore.kt | 2 +- .../impl/addpeople/AddPeoplePresenter.kt | 17 +- .../AddPeopleUserListStateProvider.kt | 14 +- .../impl/addpeople/AddPeopleView.kt | 16 +- .../SearchMultipleUsersResultItem.kt | 2 +- .../components/SearchSingleUserResultItem.kt | 2 +- .../impl/components/SearchUserBar.kt | 95 +++++++++ .../impl}/components/UserListView.kt | 9 +- .../ConfigureRoomStateProvider.kt | 2 +- .../impl/configureroom/ConfigureRoomView.kt | 10 +- .../impl/root/CreateRoomRootPresenter.kt | 17 +- .../impl/root/CreateRoomRootState.kt | 2 +- .../impl/root/CreateRoomRootStateProvider.kt | 9 +- .../impl/root/CreateRoomRootView.kt | 11 +- .../userlist}/DefaultUserListPresenter.kt | 53 ++--- .../impl/userlist}/UserListDataStore.kt | 2 +- .../impl/userlist}/UserListEvents.kt | 2 +- .../impl/userlist}/UserListPresenter.kt | 5 +- .../impl/userlist}/UserListPresenterArgs.kt | 11 +- .../impl/userlist}/UserListState.kt | 16 +- .../impl/userlist}/UserListStateProvider.kt | 11 +- .../impl/addpeople/AddPeoplePresenterTests.kt | 13 +- .../ConfigureRoomPresenterTests.kt | 2 +- .../impl/root/CreateRoomRootPresenterTests.kt | 16 +- .../DefaultUserListPresenterTests.kt | 143 ++++++++----- .../impl/userlist}/FakeUserListPresenter.kt | 5 +- .../userlist}/FakeUserListPresenterFactory.kt | 9 +- .../invitelist/impl/InviteListView.kt | 8 +- .../impl/changeserver/ChangeServerView.kt | 5 +- .../features/login/impl/root/LoginRootView.kt | 5 +- .../features/messages/impl/MessagesView.kt | 8 +- features/roomdetails/impl/build.gradle.kts | 2 +- .../roomdetails/impl/RoomDetailsFlowNode.kt | 1 - .../roomdetails/impl/RoomDetailsView.kt | 9 +- .../{ => impl}/blockuser/BlockUserSection.kt | 2 +- .../impl/members/RoomMemberListPresenter.kt | 9 +- .../impl/members/RoomMemberListState.kt | 14 +- .../members/RoomMemberListStateProvider.kt | 8 +- .../impl/members/RoomMemberListView.kt | 110 +++------- .../members/details/RoomMemberDetailsView.kt | 9 +- .../members/RoomMemberListPresenterTests.kt | 10 +- .../features/roomlist/impl/RoomListView.kt | 5 +- .../roomlist/impl/search/RoomListSearch.kt | 5 +- .../userlist/api/components/SearchUserBar.kt | 163 --------------- .../preferences/PreferenceScreen.kt | 4 + .../theme/components/SearchBar.kt | 196 +++++++++++++++--- libraries/matrixui/build.gradle.kts | 1 + .../ui/components/CheckableMatrixUserRow.kt | 36 +++- .../matrix/ui/components/MatrixUserRow.kt | 24 ++- .../matrix/ui}/components/SelectedUser.kt | 7 +- .../ui}/components/SelectedUsersList.kt | 6 +- .../src/main/res/values/localazy.xml | 4 +- .../usersearch}/api/build.gradle.kts | 10 +- .../usersearch}/api/UserListDataSource.kt | 2 +- .../usersearch/api/UserRepository.kt | 20 +- .../usersearch}/impl/build.gradle.kts | 25 +-- .../impl/MatrixUserListDataSource.kt | 9 +- .../usersearch/impl/MatrixUserRepository.kt | 64 ++++++ .../impl/MatrixUserListDataSourceTest.kt | 22 +- .../impl/MatrixUserRepositoryTest.kt | 140 +++++++++++++ .../usersearch}/test/build.gradle.kts | 10 +- .../test/FakeUserListDataSource.kt | 4 +- .../usersearch/test/FakeUserRepository.kt | 40 ++++ .../kotlin/extension/DependencyHandleScope.kt | 1 + ...atarDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...tarLightPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...temDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...emLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...temDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...emLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_0,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_1,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_2,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_3,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_4,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_5,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_6,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_7,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_0,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_1,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_2,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_3,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_4,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_5,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_6,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_7,NEXUS_5,1.0,en].png} | 0 ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...ViewDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...iewLightPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...ewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 2 +- ...ewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...wLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...reenDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...eenLightPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ctiveEmptyQuery_0_null,NEXUS_5,1.0,en].png | 3 + ...tiveWithContent_0_null,NEXUS_5,1.0,en].png | 3 + ...veWithNoResults_0_null,NEXUS_5,1.0,en].png | 3 + ...ActiveWithQuery_0_null,NEXUS_5,1.0,en].png | 3 + ...PreviewInactive_0_null,NEXUS_5,1.0,en].png | 3 + ...earchBarPreview_0_null,NEXUS_5,1.0,en].png | 3 - ...owDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...owDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...serDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...erLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...istDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...stLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 137 files changed, 1002 insertions(+), 675 deletions(-) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl}/components/SearchMultipleUsersResultItem.kt (97%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl}/components/SearchSingleUserResultItem.kt (96%) create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl}/components/UserListView.kt (89%) rename features/{userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/DefaultUserListPresenter.kt (57%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListDataStore.kt (95%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListEvents.kt (94%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListPresenter.kt (83%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListPresenterArgs.kt (74%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListState.kt (64%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListStateProvider.kt (83%) rename features/{userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl => createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist}/DefaultUserListPresenterTests.kt (54%) rename features/{userlist/test/src/main/kotlin/io/element/android/features/userlist/test => createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist}/FakeUserListPresenter.kt (79%) rename features/{userlist/test/src/main/kotlin/io/element/android/features/userlist/test => createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist}/FakeUserListPresenterFactory.kt (71%) rename features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/{ => impl}/blockuser/BlockUserSection.kt (98%) delete mode 100644 features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt rename {features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api => libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui}/components/SelectedUser.kt (92%) rename {features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api => libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui}/components/SelectedUsersList.kt (94%) rename {features/userlist => libraries/usersearch}/api/build.gradle.kts (70%) rename {features/userlist/api/src/main/kotlin/io/element/android/features/userlist => libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch}/api/UserListDataSource.kt (94%) rename features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt => libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt (51%) rename {features/userlist => libraries/usersearch}/impl/build.gradle.kts (61%) rename features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt => libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt (79%) create mode 100644 libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt rename features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt => libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt (81%) create mode 100644 libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt rename {features/userlist => libraries/usersearch}/test/build.gradle.kts (78%) rename {features/userlist/test/src/main/kotlin/io/element/android/features/userlist => libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch}/test/FakeUserListDataSource.kt (90%) create mode 100644 libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png} (100%) create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_0_null,NEXUS_5,1.0,en].png delete mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 2026ac5214..feab0f16e7 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -45,10 +45,10 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.elementresources) implementation(projects.libraries.uiStrings) - implementation(projects.features.userlist.api) implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediaupload.api) implementation(libs.coil.compose) + implementation(projects.libraries.usersearch.impl) api(projects.features.createroom.api) testImplementation(libs.test.junit) @@ -59,10 +59,9 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(libs.test.robolectric) testImplementation(projects.libraries.matrix.test) - testImplementation(projects.features.userlist.impl) - testImplementation(projects.features.userlist.test) testImplementation(projects.libraries.mediapickers.test) testImplementation(projects.libraries.mediaupload.test) + testImplementation(projects.libraries.usersearch.test) androidTestImplementation(libs.test.junitext) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt index 2a0dedc3e5..46de8fff91 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt @@ -19,7 +19,7 @@ package io.element.android.features.createroom.impl import android.net.Uri import io.element.android.features.createroom.impl.configureroom.RoomPrivacy import io.element.android.features.createroom.impl.di.CreateRoomScope -import io.element.android.features.userlist.api.UserListDataStore +import io.element.android.features.createroom.impl.userlist.UserListDataStore import io.element.android.libraries.di.SingleIn import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.Flow diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt index 50e84ebec6..0927e193ad 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt @@ -18,18 +18,17 @@ package io.element.android.features.createroom.impl.addpeople import androidx.compose.runtime.Composable import io.element.android.features.createroom.impl.CreateRoomDataStore -import io.element.android.features.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs -import io.element.android.features.userlist.api.UserListState +import io.element.android.features.createroom.impl.userlist.SelectionMode +import io.element.android.features.createroom.impl.userlist.UserListPresenter +import io.element.android.features.createroom.impl.userlist.UserListPresenterArgs +import io.element.android.features.createroom.impl.userlist.UserListState import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.usersearch.api.UserRepository import javax.inject.Inject -import javax.inject.Named class AddPeoplePresenter @Inject constructor( private val userListPresenterFactory: UserListPresenter.Factory, - @Named("AllUsers") private val userListDataSource: UserListDataSource, + private val userRepository: UserRepository, private val dataStore: CreateRoomDataStore, ) : Presenter { @@ -37,10 +36,8 @@ class AddPeoplePresenter @Inject constructor( userListPresenterFactory.create( UserListPresenterArgs( selectionMode = SelectionMode.Multiple, - minimumSearchLength = 3, - searchDebouncePeriodMillis = UserListPresenterArgs.DEFAULT_DEBOUNCE ), - userListDataSource, + userRepository, dataStore.selectedUserListDataStore, ) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt index d005fe8dda..48ad56caf4 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt @@ -17,11 +17,11 @@ package io.element.android.features.createroom.impl.addpeople import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.features.userlist.api.aListOfSelectedUsers -import io.element.android.features.userlist.api.aUserListState +import io.element.android.features.createroom.impl.userlist.SelectionMode +import io.element.android.features.createroom.impl.userlist.UserListState +import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers +import io.element.android.features.createroom.impl.userlist.aUserListState +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUserList import kotlinx.collections.immutable.toImmutableList @@ -30,13 +30,13 @@ open class AddPeopleUserListStateProvider : PreviewParameterProvider Unit = {}, ) { Scaffold( + modifier = modifier, topBar = { if (!state.isSearchActive) { AddPeopleViewTopBar( @@ -60,12 +64,14 @@ fun AddPeopleView( } ) { padding -> Column( - modifier = modifier + modifier = Modifier .fillMaxSize() - .padding(padding), + .padding(padding) + .consumeWindowInsets(padding), ) { UserListView( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .fillMaxWidth(), state = state, ) } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchMultipleUsersResultItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchMultipleUsersResultItem.kt similarity index 97% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchMultipleUsersResultItem.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchMultipleUsersResultItem.kt index f153d3671a..cf13768a82 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchMultipleUsersResultItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchMultipleUsersResultItem.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.features.createroom.impl.components import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchSingleUserResultItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchSingleUserResultItem.kt similarity index 96% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchSingleUserResultItem.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchSingleUserResultItem.kt index 5f42438868..8dcaeb2bdf 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchSingleUserResultItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchSingleUserResultItem.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.features.createroom.impl.components import androidx.compose.foundation.clickable import androidx.compose.runtime.Composable diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt new file mode 100644 index 0000000000..33d308941f --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom.impl.components + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.theme.components.SearchBar +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.components.SelectedUsersList +import io.element.android.libraries.ui.strings.R +import kotlinx.collections.immutable.ImmutableList + +@Composable +fun SearchUserBar( + query: String, + state: SearchBarResultState>, + selectedUsers: ImmutableList, + active: Boolean, + isMultiSelectionEnabled: Boolean, + modifier: Modifier = Modifier, + placeHolderTitle: String = stringResource(R.string.common_search_for_someone), + onActiveChanged: (Boolean) -> Unit = {}, + onTextChanged: (String) -> Unit = {}, + onUserSelected: (MatrixUser) -> Unit = {}, + onUserDeselected: (MatrixUser) -> Unit = {}, +) { + SearchBar( + query = query, + onQueryChange = onTextChanged, + active = active, + onActiveChange = onActiveChanged, + modifier = modifier, + placeHolderTitle = placeHolderTitle, + contentPrefix = { + if (isMultiSelectionEnabled && active && selectedUsers.isNotEmpty()) { + SelectedUsersList( + contentPadding = PaddingValues(16.dp), + selectedUsers = selectedUsers, + autoScroll = true, + onUserRemoved = onUserDeselected, + ) + } + }, + resultState = state, + resultHandler = { users -> + LazyColumn { + if (isMultiSelectionEnabled) { + items(users) { matrixUser -> + SearchMultipleUsersResultItem( + modifier = Modifier.fillMaxWidth(), + matrixUser = matrixUser, + isUserSelected = selectedUsers.find { it.userId == matrixUser.userId } != null, + onCheckedChange = { checked -> + if (checked) { + onUserSelected(matrixUser) + } else { + onUserDeselected(matrixUser) + } + } + ) + } + } else { + items(users) { matrixUser -> + SearchSingleUserResultItem( + modifier = Modifier.fillMaxWidth(), + matrixUser = matrixUser, + onClick = { onUserSelected(matrixUser) } + ) + } + } + } + }, + ) +} diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/UserListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt similarity index 89% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/UserListView.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt index afff072d9f..299dc59abf 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/UserListView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.features.createroom.impl.components import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -24,12 +24,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.userlist.api.UserListEvents -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.UserListStateProvider +import io.element.android.features.createroom.impl.userlist.UserListEvents +import io.element.android.features.createroom.impl.userlist.UserListState +import io.element.android.features.createroom.impl.userlist.UserListStateProvider import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.components.SelectedUsersList @Composable fun UserListView( diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 9cb62d4f28..0e31e9e1c0 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -18,7 +18,7 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.createroom.impl.CreateRoomConfig -import io.element.android.features.userlist.api.aListOfSelectedUsers +import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers import io.element.android.libraries.architecture.Async import kotlinx.collections.immutable.persistentListOf diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 0b1e3d71c0..53d46b03c9 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -20,8 +20,10 @@ import android.net.Uri import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.selection.selectableGroup @@ -48,7 +50,6 @@ import io.element.android.features.createroom.impl.components.Avatar import io.element.android.features.createroom.impl.components.LabelledTextField import io.element.android.features.createroom.impl.components.RoomPrivacyOption import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListView -import io.element.android.features.userlist.api.components.SelectedUsersList import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.button.BackButton @@ -60,10 +61,11 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.ui.components.SelectedUsersList import kotlinx.coroutines.launch import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterialApi::class) @Composable fun ConfigureRoomView( state: ConfigureRoomState, @@ -104,7 +106,9 @@ fun ConfigureRoomView( } ) { padding -> LazyColumn( - modifier = Modifier.padding(padding), + modifier = Modifier + .padding(padding) + .consumeWindowInsets(padding), verticalArrangement = Arrangement.spacedBy(24.dp), ) { item { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt index 0ac9611fc7..602f0a575b 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt @@ -21,25 +21,24 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import io.element.android.features.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs +import io.element.android.features.createroom.impl.userlist.SelectionMode +import io.element.android.features.createroom.impl.userlist.UserListDataStore +import io.element.android.features.createroom.impl.userlist.UserListPresenter +import io.element.android.features.createroom.impl.userlist.UserListPresenterArgs import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.execute import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named class CreateRoomRootPresenter @Inject constructor( private val presenterFactory: UserListPresenter.Factory, - @Named("AllUsers") private val userListDataSource: UserListDataSource, + private val userRepository: UserRepository, private val userListDataStore: UserListDataStore, private val matrixClient: MatrixClient, ) : Presenter { @@ -48,10 +47,8 @@ class CreateRoomRootPresenter @Inject constructor( presenterFactory.create( UserListPresenterArgs( selectionMode = SelectionMode.Single, - minimumSearchLength = 3, - searchDebouncePeriodMillis = UserListPresenterArgs.DEFAULT_DEBOUNCE, ), - userListDataSource, + userRepository, userListDataStore, ) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt index d8e7533b0b..e4e7f821c7 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt @@ -16,7 +16,7 @@ package io.element.android.features.createroom.impl.root -import io.element.android.features.userlist.api.UserListState +import io.element.android.features.createroom.impl.userlist.UserListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt index ccfad47a86..d3e8492240 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt @@ -17,9 +17,10 @@ package io.element.android.features.createroom.impl.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.features.userlist.api.aUserListState +import io.element.android.features.createroom.impl.userlist.aUserListState + import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUser import kotlinx.collections.immutable.persistentListOf @@ -32,7 +33,7 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider Column( - modifier = Modifier.padding(paddingValues), + modifier = Modifier + .padding(paddingValues) + .consumeWindowInsets(paddingValues), verticalArrangement = Arrangement.spacedBy(8.dp), ) { - val context = LocalContext.current UserListView( modifier = Modifier.fillMaxWidth(), state = state.userListState, diff --git a/features/userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt similarity index 57% rename from features/userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenter.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt index 24ee9d4e26..2efbdb7b9a 100644 --- a/features/userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.impl +package io.element.android.features.createroom.impl.userlist import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -28,24 +28,16 @@ import com.squareup.anvil.annotations.ContributesBinding import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListEvents -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.UserSearchResultState +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.core.MatrixPatterns -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser -import kotlinx.collections.immutable.persistentListOf +import io.element.android.libraries.usersearch.api.UserRepository +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.delay class DefaultUserListPresenter @AssistedInject constructor( @Assisted val args: UserListPresenterArgs, - @Assisted val userListDataSource: UserListDataSource, + @Assisted val userRepository: UserRepository, @Assisted val userListDataStore: UserListDataStore, ) : UserListPresenter { @@ -54,7 +46,7 @@ class DefaultUserListPresenter @AssistedInject constructor( interface DefaultUserListFactory : UserListPresenter.Factory { override fun create( args: UserListPresenterArgs, - userListDataSource: UserListDataSource, + userRepository: UserRepository, userListDataStore: UserListDataStore, ): DefaultUserListPresenter } @@ -64,24 +56,18 @@ class DefaultUserListPresenter @AssistedInject constructor( var isSearchActive by rememberSaveable { mutableStateOf(false) } val selectedUsers by userListDataStore.selectedUsers().collectAsState(emptyList()) var searchQuery by rememberSaveable { mutableStateOf("") } - var searchResults: UserSearchResultState by remember { - mutableStateOf(UserSearchResultState.NotSearching) + var searchResults: SearchBarResultState> by remember { + mutableStateOf(SearchBarResultState.NotSearching()) } LaunchedEffect(searchQuery) { - // Clear the search results before performing the search, manually add a fake result with the matrixId, if any - searchResults = if (MatrixPatterns.isUserId(searchQuery)) { - UserSearchResultState.Results(persistentListOf(MatrixUser(UserId(searchQuery)))) - } else { - UserSearchResultState.NotSearching - } + searchResults = SearchBarResultState.NotSearching() - // Debounce - delay(args.searchDebouncePeriodMillis) - - // Perform the search asynchronously - if (searchQuery.length >= args.minimumSearchLength) { - searchResults = performSearch(searchQuery) + userRepository.search(searchQuery).collect { + searchResults = when { + it.isEmpty() -> SearchBarResultState.NoResults() + else -> SearchBarResultState.Results(it.toImmutableList()) + } } } @@ -101,15 +87,4 @@ class DefaultUserListPresenter @AssistedInject constructor( }, ) } - - private suspend fun performSearch(query: String): UserSearchResultState { - val isMatrixId = MatrixPatterns.isUserId(query) - val results = userListDataSource.search(query).toMutableList() - if (isMatrixId && results.none { it.userId.value == query }) { - val getProfileResult: MatrixUser? = userListDataSource.getProfile(UserId(query)) - val profile = getProfileResult ?: MatrixUser(UserId(query)) - results.add(0, profile) - } - return if (results.isEmpty()) UserSearchResultState.NoResults else UserSearchResultState.Results(results.toImmutableList()) - } } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListDataStore.kt similarity index 95% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataStore.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListDataStore.kt index 31750e5350..8de7be3114 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListDataStore.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.coroutines.flow.Flow diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListEvents.kt similarity index 94% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListEvents.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListEvents.kt index fe0d681fe1..6dc817d22c 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListEvents.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import io.element.android.libraries.matrix.api.user.MatrixUser diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenter.kt similarity index 83% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenter.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenter.kt index 90205eab2a..e5d68a2e28 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenter.kt @@ -14,16 +14,17 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.usersearch.api.UserRepository interface UserListPresenter : Presenter { interface Factory { fun create( args: UserListPresenterArgs, - userListDataSource: UserListDataSource, + userRepository: UserRepository, userListDataStore: UserListDataStore, ): UserListPresenter } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenterArgs.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenterArgs.kt similarity index 74% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenterArgs.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenterArgs.kt index e00aa89155..15c2a94a24 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenterArgs.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenterArgs.kt @@ -14,18 +14,11 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist data class UserListPresenterArgs( val selectionMode: SelectionMode, - val minimumSearchLength: Int = 1, - val searchDebouncePeriodMillis: Long = NO_DEBOUNCE, -) { - companion object { - const val NO_DEBOUNCE = 0L - const val DEFAULT_DEBOUNCE = 500L - } -} +) enum class SelectionMode { Single, diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt similarity index 64% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListState.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt index 490a1fdde3..d8ff391163 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt @@ -14,14 +14,15 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList data class UserListState( val searchQuery: String, - val searchResults: UserSearchResultState, + val searchResults: SearchBarResultState>, val selectedUsers: ImmutableList, val isSearchActive: Boolean, val selectionMode: SelectionMode, @@ -29,14 +30,3 @@ data class UserListState( ) { val isMultiSelectionEnabled = selectionMode == SelectionMode.Multiple } - -sealed interface UserSearchResultState { - /** No search results are available yet (e.g. because the user hasn't entered a (long enough) search term). */ - object NotSearching : UserSearchResultState - - /** The search has completed, but no results were found. */ - object NoResults : UserSearchResultState - - /** The search has completed, and some matching users were found. */ - data class Results(val results: ImmutableList) : UserSearchResultState -} diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt similarity index 83% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListStateProvider.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt index d0047e4717..cb8bf284b0 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt @@ -14,9 +14,10 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUserList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -37,19 +38,19 @@ open class UserListStateProvider : PreviewParameterProvider { isSearchActive = true, searchQuery = "@someone:matrix.org", selectedUsers = aListOfSelectedUsers(), - searchResults = UserSearchResultState.Results(aMatrixUserList().toImmutableList()), + searchResults = SearchBarResultState.Results(aMatrixUserList().toImmutableList()), ), aUserListState().copy( isSearchActive = true, searchQuery = "@someone:matrix.org", selectionMode = SelectionMode.Multiple, selectedUsers = aListOfSelectedUsers(), - searchResults = UserSearchResultState.Results(aMatrixUserList().toImmutableList()), + searchResults = SearchBarResultState.Results(aMatrixUserList().toImmutableList()), ), aUserListState().copy( isSearchActive = true, searchQuery = "something-with-no-results", - searchResults = UserSearchResultState.NoResults + searchResults = SearchBarResultState.NoResults() ), ) } @@ -57,7 +58,7 @@ open class UserListStateProvider : PreviewParameterProvider { fun aUserListState() = UserListState( isSearchActive = false, searchQuery = "", - searchResults = UserSearchResultState.NotSearching, + searchResults = SearchBarResultState.NotSearching(), selectedUsers = persistentListOf(), selectionMode = SelectionMode.Single, eventSink = {} diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt index d7ee836453..fe8c7b7462 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt @@ -21,9 +21,9 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.createroom.impl.CreateRoomDataStore -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.test.FakeUserListDataSource -import io.element.android.features.userlist.test.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.UserListDataStore +import io.element.android.libraries.usersearch.test.FakeUserRepository import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -34,7 +34,11 @@ class AddPeoplePresenterTests { @Before fun setup() { - presenter = AddPeoplePresenter(FakeUserListPresenterFactory(), FakeUserListDataSource(), CreateRoomDataStore(UserListDataStore())) + presenter = AddPeoplePresenter( + FakeUserListPresenterFactory(), + FakeUserRepository(), + CreateRoomDataStore(UserListDataStore()) + ) } @Test @@ -42,6 +46,7 @@ class AddPeoplePresenterTests { moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + // TODO This doesn't actually test anything... val initialState = awaitItem() assertThat(initialState) } diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 82a35cf2ee..ed44cc1983 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -24,7 +24,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction -import io.element.android.features.userlist.api.UserListDataStore +import io.element.android.features.createroom.impl.userlist.UserListDataStore import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.test.AN_AVATAR_URL diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt index 2a06278934..517afc9fe9 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt @@ -20,11 +20,10 @@ import app.cash.molecule.RecompositionClock import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.aUserListState -import io.element.android.features.userlist.test.FakeUserListDataSource -import io.element.android.features.userlist.test.FakeUserListPresenter -import io.element.android.features.userlist.test.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.FakeUserListPresenter +import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.UserListDataStore +import io.element.android.features.createroom.impl.userlist.aUserListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId @@ -32,6 +31,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.libraries.usersearch.test.FakeUserRepository import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Before @@ -39,7 +39,7 @@ import org.junit.Test class CreateRoomRootPresenterTests { - private lateinit var userListDataSource: FakeUserListDataSource + private lateinit var userRepository: FakeUserRepository private lateinit var presenter: CreateRoomRootPresenter private lateinit var fakeUserListPresenter: FakeUserListPresenter private lateinit var fakeMatrixClient: FakeMatrixClient @@ -48,8 +48,8 @@ class CreateRoomRootPresenterTests { fun setup() { fakeUserListPresenter = FakeUserListPresenter() fakeMatrixClient = FakeMatrixClient() - userListDataSource = FakeUserListDataSource() - presenter = CreateRoomRootPresenter(FakeUserListPresenterFactory(fakeUserListPresenter), userListDataSource, UserListDataStore(), fakeMatrixClient) + userRepository = FakeUserRepository() + presenter = CreateRoomRootPresenter(FakeUserListPresenterFactory(fakeUserListPresenter), userRepository, UserListDataStore(), fakeMatrixClient) } @Test diff --git a/features/userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt similarity index 54% rename from features/userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenterTests.kt rename to features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index b13881dc5b..40b7e6549b 100644 --- a/features/userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -14,77 +14,78 @@ * limitations under the License. */ -package io.element.android.features.userlist.impl +package io.element.android.features.createroom.impl.userlist import app.cash.molecule.RecompositionClock import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import io.element.android.features.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListEvents -import io.element.android.features.userlist.api.UserListPresenterArgs -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.features.userlist.test.FakeUserListDataSource -import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUser +import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import io.element.android.libraries.usersearch.test.FakeUserRepository import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Test class DefaultUserListPresenterTests { - private val userListDataSource = FakeUserListDataSource() + private val userRepository = FakeUserRepository() @Test fun `present - initial state for single selection`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Single), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() assertThat(initialState.searchQuery).isEmpty() assertThat(initialState.isMultiSelectionEnabled).isFalse() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isEqualTo(UserSearchResultState.NotSearching) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) } } @Test fun `present - initial state for multiple selection`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Multiple), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Multiple), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() assertThat(initialState.searchQuery).isEmpty() assertThat(initialState.isMultiSelectionEnabled).isTrue() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isEqualTo(UserSearchResultState.NotSearching) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) } } @Test fun `present - update search query`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Single), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() initialState.eventSink(UserListEvents.OnSearchActiveChanged(true)) @@ -93,12 +94,14 @@ class DefaultUserListPresenterTests { val matrixIdQuery = "@name:matrix.org" initialState.eventSink(UserListEvents.UpdateSearchQuery(matrixIdQuery)) assertThat(awaitItem().searchQuery).isEqualTo(matrixIdQuery) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.Results(persistentListOf(MatrixUser(UserId(matrixIdQuery))))) + assertThat(userRepository.providedQuery).isEqualTo(matrixIdQuery) + skipItems(1) val notMatrixIdQuery = "name" initialState.eventSink(UserListEvents.UpdateSearchQuery(notMatrixIdQuery)) assertThat(awaitItem().searchQuery).isEqualTo(notMatrixIdQuery) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.NoResults) + assertThat(userRepository.providedQuery).isEqualTo(notMatrixIdQuery) + skipItems(1) initialState.eventSink(UserListEvents.OnSearchActiveChanged(false)) assertThat(awaitItem().isSearchActive).isFalse() @@ -106,39 +109,83 @@ class DefaultUserListPresenterTests { } @Test - fun `present - searches when minimum length exceeded`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single, minimumSearchLength = 3), - userListDataSource, - UserListDataStore(), - ) + fun `present - presents search results`() = runTest { + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs( + selectionMode = SelectionMode.Single, + ), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() - // When the search term is too short, nothing happens - initialState.eventSink(UserListEvents.UpdateSearchQuery("al")) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.NotSearching) - - // When it reaches the minimum length, a search is performed asynchronously - userListDataSource.givenSearchResult(listOf(aMatrixUser())) initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.NotSearching) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.Results(persistentListOf(aMatrixUser()))) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(userRepository.providedQuery).isEqualTo("alice") + skipItems(2) + + // When the user repository emits a result, it's copied to the state + userRepository.emitResult(listOf(aMatrixUser())) + assertThat(awaitItem().searchResults).isEqualTo( + SearchBarResultState.Results( + persistentListOf(aMatrixUser()) + ) + ) + + // When the user repository emits another result, it replaces the previous value + userRepository.emitResult(aMatrixUserList()) + assertThat(awaitItem().searchResults).isEqualTo( + SearchBarResultState.Results( + aMatrixUserList() + ) + ) + } + } + + @Test + fun `present - presents search results when not found`() = runTest { + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs( + selectionMode = SelectionMode.Single, + ), + userRepository, + UserListDataStore(), + ) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + + initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(userRepository.providedQuery).isEqualTo("alice") + skipItems(2) + + // When the results list is empty, the state is set to NoResults + userRepository.emitResult(emptyList()) + assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.NoResults::class.java) } } @Test fun `present - select a user`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Single), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() val userA = aMatrixUser("@userA:domain", "A") diff --git a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenter.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenter.kt similarity index 79% rename from features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenter.kt rename to features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenter.kt index 54aef4a6f7..45eb712dc1 100644 --- a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenter.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenter.kt @@ -14,12 +14,9 @@ * limitations under the License. */ -package io.element.android.features.userlist.test +package io.element.android.features.createroom.impl.userlist import androidx.compose.runtime.Composable -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.aUserListState class FakeUserListPresenter : UserListPresenter { diff --git a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenterFactory.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenterFactory.kt similarity index 71% rename from features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenterFactory.kt rename to features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenterFactory.kt index 00966a5082..07697ce458 100644 --- a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenterFactory.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenterFactory.kt @@ -14,12 +14,9 @@ * limitations under the License. */ -package io.element.android.features.userlist.test +package io.element.android.features.createroom.impl.userlist -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs +import io.element.android.libraries.usersearch.api.UserRepository class FakeUserListPresenterFactory( private val fakeUserListPresenter: FakeUserListPresenter = FakeUserListPresenter() @@ -27,7 +24,7 @@ class FakeUserListPresenterFactory( override fun create( args: UserListPresenterArgs, - userListDataSource: UserListDataSource, + userRepository: UserRepository, userListDataStore: UserListDataStore, ): UserListPresenter = fakeUserListPresenter } diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt index 78c4c140a1..d714eda319 100644 --- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt +++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt @@ -17,7 +17,9 @@ package io.element.android.features.invitelist.impl import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -103,7 +105,7 @@ fun InviteListView( } } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun InviteListContent( state: InviteListState, @@ -124,7 +126,9 @@ fun InviteListContent( }, content = { padding -> Column( - modifier = Modifier.padding(padding) + modifier = Modifier + .padding(padding) + .consumeWindowInsets(padding) ) { if (state.inviteList.isEmpty()) { Spacer(Modifier.size(80.dp)) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt index 2137760085..cbd2bc9308 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt @@ -20,7 +20,9 @@ import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -81,7 +83,7 @@ import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class, ExperimentalLayoutApi::class) @Composable fun ChangeServerView( state: ChangeServerState, @@ -121,6 +123,7 @@ fun ChangeServerView( .fillMaxSize() .imePadding() .padding(padding) + .consumeWindowInsets(padding) ) { Column( modifier = Modifier diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt index b7491f5b3b..b72122c914 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt @@ -21,8 +21,10 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -86,7 +88,7 @@ import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun LoginRootView( state: LoginRootState, @@ -113,6 +115,7 @@ fun LoginRootView( .fillMaxSize() .imePadding() .padding(padding) + .consumeWindowInsets(padding) ) { val scrollState = rememberScrollState() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index f98b19575a..a55ea1021d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -19,9 +19,11 @@ package io.element.android.features.messages.impl import androidx.activity.compose.BackHandler import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding @@ -79,7 +81,7 @@ import io.element.android.libraries.designsystem.utils.LogCompositions import kotlinx.coroutines.launch import timber.log.Timber -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalLayoutApi::class) @Composable fun MessagesView( state: MessagesState, @@ -183,7 +185,9 @@ fun MessagesView( content = { padding -> MessagesViewContent( state = state, - modifier = Modifier.padding(padding), + modifier = Modifier + .padding(padding) + .consumeWindowInsets(padding), onMessageClicked = ::onMessageClicked, onMessageLongClicked = ::onMessageLongClicked ) diff --git a/features/roomdetails/impl/build.gradle.kts b/features/roomdetails/impl/build.gradle.kts index 7b072a5faf..05181c3f67 100644 --- a/features/roomdetails/impl/build.gradle.kts +++ b/features/roomdetails/impl/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { implementation(projects.libraries.uiStrings) implementation(projects.libraries.androidutils) api(projects.features.roomdetails.api) + api(projects.libraries.usersearch.api) implementation(libs.coil.compose) testImplementation(libs.test.junit) @@ -50,7 +51,6 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) - testImplementation(projects.features.userlist.test) testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index f3a0ef9001..8c7d9cd375 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -35,7 +35,6 @@ import io.element.android.libraries.architecture.animation.rememberDefaultTransi import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.room.RoomMember import kotlinx.parcelize.Parcelize @ContributesNode(RoomScope::class) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index f9f6d43720..c09a80cf1b 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -19,8 +19,10 @@ package io.element.android.features.roomdetails.impl import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -43,8 +45,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.roomdetails.blockuser.BlockUserDialogs -import io.element.android.features.roomdetails.blockuser.BlockUserSection +import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs +import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection import io.element.android.features.roomdetails.impl.members.details.RoomMemberHeaderSection import io.element.android.features.roomdetails.impl.members.details.RoomMemberMainActionsSection import io.element.android.libraries.architecture.isLoading @@ -68,7 +70,7 @@ import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun RoomDetailsView( state: RoomDetailsState, @@ -91,6 +93,7 @@ fun RoomDetailsView( ) { padding -> Column(modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) .verticalScroll(rememberScrollState()) ) { when (state.roomType) { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/blockuser/BlockUserSection.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt similarity index 98% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/blockuser/BlockUserSection.kt rename to features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt index 49daa15af3..3effaca4a1 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/blockuser/BlockUserSection.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.roomdetails.blockuser +package io.element.android.features.roomdetails.impl.blockuser import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Block diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 3a719983b6..ddf7864b96 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.setValue import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.room.RoomMembershipState import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.withContext @@ -41,7 +42,7 @@ class RoomMemberListPresenter @Inject constructor( var roomMembers by remember { mutableStateOf>(Async.Loading()) } var searchQuery by rememberSaveable { mutableStateOf("") } var searchResults by remember { - mutableStateOf(RoomMemberSearchResultState.NotSearching) + mutableStateOf>(SearchBarResultState.NotSearching()) } var isSearchActive by rememberSaveable { mutableStateOf(false) } @@ -60,11 +61,11 @@ class RoomMemberListPresenter @Inject constructor( LaunchedEffect(searchQuery) { withContext(coroutineDispatchers.io) { searchResults = if (searchQuery.isEmpty()) { - RoomMemberSearchResultState.NotSearching + SearchBarResultState.NotSearching() } else { val results = roomMemberListDataSource.search(searchQuery).groupBy { it.membership } - if (results.isEmpty()) RoomMemberSearchResultState.NoResults - else RoomMemberSearchResultState.Results( + if (results.isEmpty()) SearchBarResultState.NoResults() + else SearchBarResultState.Results( RoomMembers( invited = results.getOrDefault(RoomMembershipState.INVITE, emptyList()).toImmutableList(), joined = results.getOrDefault(RoomMembershipState.JOIN, emptyList()).toImmutableList(), diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index a689ad1fd2..93e2142a19 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -17,13 +17,14 @@ package io.element.android.features.roomdetails.impl.members import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.room.RoomMember import kotlinx.collections.immutable.ImmutableList data class RoomMemberListState( val roomMembers: Async, val searchQuery: String, - val searchResults: RoomMemberSearchResultState, + val searchResults: SearchBarResultState, val isSearchActive: Boolean, val eventSink: (RoomMemberListEvents) -> Unit, ) @@ -32,14 +33,3 @@ data class RoomMembers( val invited: ImmutableList, val joined: ImmutableList ) - -sealed interface RoomMemberSearchResultState { - /** No search results are available yet (e.g. because the user hasn't entered a (long enough) search term). */ - object NotSearching : RoomMemberSearchResultState - - /** The search has completed, but no results were found. */ - object NoResults : RoomMemberSearchResultState - - /** The search has completed, and some matching users were found. */ - data class Results(val results: RoomMembers) : RoomMemberSearchResultState -} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index 7f91969bcd..9bc8c00a1e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -18,11 +18,11 @@ package io.element.android.features.roomdetails.impl.members import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList internal class RoomMemberListStateProvider : PreviewParameterProvider { override val values: Sequence @@ -42,7 +42,7 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider = Async.Uninitialized, - searchResults: RoomMemberSearchResultState = RoomMemberSearchResultState.NotSearching, + searchResults: SearchBarResultState = SearchBarResultState.NotSearching(), ) = RoomMemberListState( roomMembers = roomMembers, searchQuery = "", diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 3358451784..ff7bb54f9e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -20,27 +20,20 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SearchBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -59,10 +52,9 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator -import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.SearchBar +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember @@ -71,6 +63,7 @@ import io.element.android.libraries.matrix.ui.components.MatrixUserRow import kotlinx.collections.immutable.ImmutableList import io.element.android.libraries.ui.strings.R as StringR +@OptIn(ExperimentalLayoutApi::class) @Composable fun RoomMemberListView( state: RoomMemberListState, @@ -93,21 +86,20 @@ fun RoomMemberListView( Column( modifier = modifier .fillMaxWidth() - .padding(padding), + .padding(padding) + .consumeWindowInsets(padding), verticalArrangement = Arrangement.spacedBy(16.dp), ) { - Column { - RoomMemberSearchBar( - query = state.searchQuery, - state = state.searchResults, - active = state.isSearchActive, - placeHolderTitle = stringResource(StringR.string.common_search_for_someone), - onActiveChanged = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) }, - onTextChanged = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) }, - onUserSelected = ::onUserSelected, - modifier = Modifier.fillMaxWidth() - ) - } + RoomMemberSearchBar( + query = state.searchQuery, + state = state.searchResults, + active = state.isSearchActive, + placeHolderTitle = stringResource(StringR.string.common_search_for_someone), + onActiveChanged = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) }, + onTextChanged = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) }, + onUserSelected = ::onUserSelected, + modifier = Modifier.fillMaxWidth() + ) if (!state.isSearchActive) { if (state.roomMembers is Async.Success) { @@ -216,11 +208,10 @@ private fun RoomMemberListTopBar( ) } -@OptIn(ExperimentalMaterial3Api::class) @Composable private fun RoomMemberSearchBar( query: String, - state: RoomMemberSearchResultState, + state: SearchBarResultState, active: Boolean, placeHolderTitle: String, onActiveChanged: (Boolean) -> Unit, @@ -228,72 +219,21 @@ private fun RoomMemberSearchBar( onUserSelected: (RoomMember) -> Unit, modifier: Modifier = Modifier, ) { - val focusManager = LocalFocusManager.current - - if (!active) { - onTextChanged("") - focusManager.clearFocus() - } - SearchBar( query = query, onQueryChange = onTextChanged, - onSearch = { focusManager.clearFocus() }, active = active, onActiveChange = onActiveChanged, - modifier = modifier - .padding(horizontal = if (!active) 16.dp else 0.dp), - placeholder = { - Text( - text = placeHolderTitle, - modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) + modifier = modifier, + placeHolderTitle = placeHolderTitle, + resultState = state, + resultHandler = { results -> + RoomMemberList( + roomMembers = results, + showMembersCount = false, + onUserSelected = { onUserSelected(it) } ) }, - leadingIcon = if (active) { - { BackButton(onClick = { onActiveChanged(false) }) } - } else { - null - }, - trailingIcon = when { - active && query.isNotEmpty() -> { - { - IconButton(onClick = { onTextChanged("") }) { - Icon(Icons.Default.Close, stringResource(StringR.string.action_clear)) - } - } - } - - !active -> { - { - Icon( - imageVector = Icons.Default.Search, - contentDescription = stringResource(StringR.string.action_search), - modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) - ) - } - } - - else -> null - }, - colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent), - content = { - if (state is RoomMemberSearchResultState.Results) { - RoomMemberList( - roomMembers = state.results, - showMembersCount = false, - onUserSelected = onUserSelected - ) - } else if (state is RoomMemberSearchResultState.NoResults) { - Spacer(Modifier.size(80.dp)) - - Text( - text = stringResource(StringR.string.common_no_results), - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.tertiary, - modifier = Modifier.fillMaxWidth() - ) - } - }, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt index a8ef557289..62b3d07a85 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt @@ -19,8 +19,10 @@ package io.element.android.features.roomdetails.impl.members.details import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -39,8 +41,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.roomdetails.blockuser.BlockUserDialogs -import io.element.android.features.roomdetails.blockuser.BlockUserSection +import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs +import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection import io.element.android.libraries.designsystem.ElementTextStyles import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -57,7 +59,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun RoomMemberDetailsView( state: RoomMemberDetailsState, @@ -74,6 +76,7 @@ fun RoomMemberDetailsView( Column( modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) .verticalScroll(rememberScrollState()) ) { RoomMemberHeaderSection( diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt index 48cf660877..73c873701e 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt @@ -24,12 +24,12 @@ import io.element.android.features.roomdetails.aMatrixRoom import io.element.android.features.roomdetails.impl.members.RoomMemberListDataSource import io.element.android.features.roomdetails.impl.members.RoomMemberListEvents import io.element.android.features.roomdetails.impl.members.RoomMemberListPresenter -import io.element.android.features.roomdetails.impl.members.RoomMemberSearchResultState import io.element.android.features.roomdetails.impl.members.aRoomMemberList import io.element.android.features.roomdetails.impl.members.aVictor import io.element.android.features.roomdetails.impl.members.aWalter import io.element.android.libraries.architecture.Async import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.tests.testutils.testCoroutineDispatchers @@ -49,7 +49,7 @@ class RoomMemberListPresenterTests { val initialState = awaitItem() Truth.assertThat(initialState.roomMembers).isInstanceOf(Async.Loading::class.java) Truth.assertThat(initialState.searchQuery).isEmpty() - Truth.assertThat(initialState.searchResults).isEqualTo(RoomMemberSearchResultState.NotSearching) + Truth.assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) Truth.assertThat(initialState.isSearchActive).isFalse() val loadedState = awaitItem() @@ -89,7 +89,7 @@ class RoomMemberListPresenterTests { val searchQueryUpdatedState = awaitItem() Truth.assertThat((searchQueryUpdatedState.searchQuery)).isEqualTo("something") val searchSearchResultDelivered = awaitItem() - Truth.assertThat((searchSearchResultDelivered.searchResults)).isInstanceOf(RoomMemberSearchResultState.NoResults::class.java) + Truth.assertThat(searchSearchResultDelivered.searchResults).isInstanceOf(SearchBarResultState.NoResults::class.java) } } @@ -107,8 +107,8 @@ class RoomMemberListPresenterTests { val searchQueryUpdatedState = awaitItem() Truth.assertThat((searchQueryUpdatedState.searchQuery)).isEqualTo("Alice") val searchSearchResultDelivered = awaitItem() - Truth.assertThat((searchSearchResultDelivered.searchResults)).isInstanceOf(RoomMemberSearchResultState.Results::class.java) - Truth.assertThat((searchSearchResultDelivered.searchResults as RoomMemberSearchResultState.Results).results.joined.first().displayName) + Truth.assertThat((searchSearchResultDelivered.searchResults)).isInstanceOf(SearchBarResultState.Results::class.java) + Truth.assertThat((searchSearchResultDelivered.searchResults as SearchBarResultState.Results).results.joined.first().displayName) .isEqualTo("Alice") } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index acfc822658..dc3c7bff7a 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -22,9 +22,11 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -116,7 +118,7 @@ fun RoomListView( } } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun RoomListContent( state: RoomListState, @@ -190,6 +192,7 @@ fun RoomListContent( Column( modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) ) { LazyColumn( modifier = Modifier diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt index 021959c3aa..bdd4858ce3 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt @@ -20,6 +20,8 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -89,7 +91,7 @@ internal fun RoomListSearchResultView( } } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable internal fun RoomListSearchResultContent( state: RoomListState, @@ -183,6 +185,7 @@ internal fun RoomListSearchResultContent( Column( modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) ) { LazyColumn( modifier = Modifier diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt b/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt deleted file mode 100644 index 1e82936c92..0000000000 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.userlist.api.components - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SearchBarDefaults -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.IconButton -import io.element.android.libraries.designsystem.theme.components.SearchBar -import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.ui.strings.R -import kotlinx.collections.immutable.ImmutableList - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchUserBar( - query: String, - state: UserSearchResultState, - selectedUsers: ImmutableList, - active: Boolean, - isMultiSelectionEnabled: Boolean, - modifier: Modifier = Modifier, - placeHolderTitle: String = stringResource(R.string.common_search_for_someone), - onActiveChanged: (Boolean) -> Unit = {}, - onTextChanged: (String) -> Unit = {}, - onUserSelected: (MatrixUser) -> Unit = {}, - onUserDeselected: (MatrixUser) -> Unit = {}, -) { - val focusManager = LocalFocusManager.current - - if (!active) { - onTextChanged("") - focusManager.clearFocus() - } - - SearchBar( - query = query, - onQueryChange = onTextChanged, - onSearch = { focusManager.clearFocus() }, - active = active, - onActiveChange = onActiveChanged, - modifier = modifier - .padding(horizontal = if (!active) 16.dp else 0.dp), - placeholder = { - Text( - text = placeHolderTitle, - modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) - ) - }, - leadingIcon = if (active) { - { BackButton(onClick = { onActiveChanged(false) }) } - } else { - null - }, - trailingIcon = when { - active && query.isNotEmpty() -> { - { - IconButton(onClick = { onTextChanged("") }) { - Icon(Icons.Default.Close, stringResource(R.string.action_clear)) - } - } - } - - !active -> { - { - Icon( - imageVector = Icons.Default.Search, - contentDescription = stringResource(R.string.action_search), - modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) - ) - } - } - - else -> null - }, - colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent), - content = { - if (isMultiSelectionEnabled && active && selectedUsers.isNotEmpty()) { - SelectedUsersList( - contentPadding = PaddingValues(16.dp), - selectedUsers = selectedUsers, - autoScroll = true, - onUserRemoved = onUserDeselected, - ) - } - - - if (state is UserSearchResultState.Results) { - LazyColumn { - if (isMultiSelectionEnabled) { - items(state.results) { matrixUser -> - SearchMultipleUsersResultItem( - modifier = Modifier.fillMaxWidth(), - matrixUser = matrixUser, - isUserSelected = selectedUsers.find { it.userId == matrixUser.userId } != null, - onCheckedChange = { checked -> - if (checked) { - onUserSelected(matrixUser) - } else { - onUserDeselected(matrixUser) - } - } - ) - } - } else { - items(state.results) { matrixUser -> - SearchSingleUserResultItem( - modifier = Modifier.fillMaxWidth(), - matrixUser = matrixUser, - onClick = { onUserSelected(matrixUser) } - ) - } - } - } - } else if (state is UserSearchResultState.NoResults) { - Spacer(Modifier.size(80.dp)) - - Text( - text = stringResource(R.string.common_no_results), - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.tertiary, - modifier = Modifier.fillMaxWidth() - ) - } - }, - ) -} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt index 03ba290829..eacdf82fb7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt @@ -18,8 +18,10 @@ package io.element.android.libraries.designsystem.components.preferences import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding @@ -45,6 +47,7 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar +@OptIn(ExperimentalLayoutApi::class) @Composable fun PreferenceView( title: String, @@ -69,6 +72,7 @@ fun PreferenceView( Column( modifier = Modifier .padding(it) + .consumeWindowInsets(it) .verticalScroll( state = scrollState, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index f0e9eaf906..8d91404d29 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -16,74 +16,216 @@ package io.element.android.libraries.designsystem.theme.components +import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Search import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.SearchBarColors +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SearchBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup +import io.element.android.libraries.ui.strings.R @OptIn(ExperimentalMaterial3Api::class) @Composable -fun SearchBar( +fun SearchBar( query: String, onQueryChange: (String) -> Unit, - onSearch: (String) -> Unit, active: Boolean, onActiveChange: (Boolean) -> Unit, + placeHolderTitle: String, modifier: Modifier = Modifier, enabled: Boolean = true, - placeholder: @Composable (() -> Unit)? = null, - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, + resultState: SearchBarResultState = SearchBarResultState.NotSearching(), shape: Shape = SearchBarDefaults.inputFieldShape, - colors: SearchBarColors = SearchBarDefaults.colors(), tonalElevation: Dp = SearchBarDefaults.Elevation, windowInsets: WindowInsets = SearchBarDefaults.windowInsets, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - content: @Composable ColumnScope.() -> Unit, + contentPrefix: @Composable ColumnScope.() -> Unit = {}, + contentSuffix: @Composable ColumnScope.() -> Unit = {}, + resultHandler: @Composable ColumnScope.(T) -> Unit = {}, ) { + val focusManager = LocalFocusManager.current + + if (!active) { + onQueryChange("") + focusManager.clearFocus() + } + androidx.compose.material3.SearchBar( query = query, onQueryChange = onQueryChange, - onSearch = onSearch, + onSearch = { focusManager.clearFocus() }, active = active, onActiveChange = onActiveChange, - modifier = modifier, + modifier = modifier.padding(horizontal = if (!active) 16.dp else 0.dp), enabled = enabled, - placeholder = placeholder, - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, + placeholder = { + Text( + text = placeHolderTitle, + modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) + ) + }, + leadingIcon = if (active) { + { BackButton(onClick = { onActiveChange(false) }) } + } else { + null + }, + trailingIcon = when { + active && query.isNotEmpty() -> { + { + IconButton(onClick = { onQueryChange("") }) { + Icon(Icons.Default.Close, stringResource(R.string.action_clear)) + } + } + } + + !active -> { + { + Icon( + imageVector = Icons.Default.Search, + contentDescription = stringResource(R.string.action_search), + modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) + ) + } + } + + else -> null + }, shape = shape, - colors = colors, + colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent), tonalElevation = tonalElevation, windowInsets = windowInsets, interactionSource = interactionSource, - content = content, + content = { + contentPrefix() + when (resultState) { + is SearchBarResultState.Results -> { + resultHandler(resultState.results) + } + + is SearchBarResultState.NoResults -> { + // No results found, show a message + Spacer(Modifier.size(80.dp)) + + Text( + text = stringResource(R.string.common_no_results), + textAlign = TextAlign.Center, + color = MaterialTheme.colorScheme.tertiary, + modifier = Modifier.fillMaxWidth() + ) + } + + else -> { + // Not searching - nothing to show. + } + } + contentSuffix() + }, + ) +} + +sealed interface SearchBarResultState { + /** No search results are available yet (e.g. because the user hasn't entered a search term). */ + class NotSearching : SearchBarResultState + + /** The search has completed, but no results were found. */ + class NoResults : SearchBarResultState + + /** The search has completed, and some matching users were found. */ + data class Results(val results: T) : SearchBarResultState +} + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewInactive() = ElementThemedPreview { ContentToPreview() } + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewActiveEmptyQuery() = ElementThemedPreview { + ContentToPreview( + query = "", + active = true, ) } @Preview(group = PreviewGroup.Search) @Composable -internal fun SearchBarPreview() = ElementThemedPreview { ContentToPreview() } - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ContentToPreview() { - SearchBar( - query = "Some text", - onQueryChange = {}, - onSearch = {}, - active = false, - onActiveChange = {}, - content = {}, +internal fun SearchBarPreviewActiveWithQuery() = ElementThemedPreview { + ContentToPreview( + query = "search term", + active = true, + ) +} + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewActiveWithNoResults() = ElementThemedPreview { + ContentToPreview( + query = "search term", + active = true, + resultState = SearchBarResultState.NoResults(), + ) +} + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewActiveWithContent() = ElementThemedPreview { + ContentToPreview( + query = "search term", + active = true, + resultState = SearchBarResultState.Results("result!"), + contentPrefix = { + Text(text = "Content that goes before the search results", modifier = Modifier.background(color = Color.Red).fillMaxWidth()) + }, + contentSuffix = { + Text(text = "Content that goes after the search results", modifier = Modifier.background(color = Color.Blue).fillMaxWidth()) + }, + resultHandler = { + Text(text = "Results go here", modifier = Modifier.background(color = Color.Green).fillMaxWidth()) + } + ) +} + +@Composable +private fun ContentToPreview( + query: String = "", + active: Boolean = false, + resultState: SearchBarResultState = SearchBarResultState.NotSearching(), + contentPrefix: @Composable ColumnScope.() -> Unit = {}, + contentSuffix: @Composable ColumnScope.() -> Unit = {}, + resultHandler: @Composable ColumnScope.(String) -> Unit = {}, +) { + SearchBar( + query = query, + active = active, + resultState = resultState, + onQueryChange = {}, + onActiveChange = {}, + placeHolderTitle = "Search for things", + contentPrefix = contentPrefix, + contentSuffix = contentSuffix, + resultHandler = resultHandler, ) } diff --git a/libraries/matrixui/build.gradle.kts b/libraries/matrixui/build.gradle.kts index 17d9522aeb..380f19f792 100644 --- a/libraries/matrixui/build.gradle.kts +++ b/libraries/matrixui/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { implementation(projects.libraries.matrix.api) implementation(projects.libraries.designsystem) implementation(projects.libraries.core) + implementation(projects.libraries.uiStrings) implementation(libs.coil.compose) ksp(libs.showkase.processor) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableMatrixUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableMatrixUserRow.kt index 14ed5ef134..5c7a5eb458 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableMatrixUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableMatrixUserRow.kt @@ -26,11 +26,14 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter +import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.theme.components.Checkbox import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.model.getAvatarData +import io.element.android.libraries.matrix.ui.model.getBestName @Composable fun CheckableMatrixUserRow( @@ -40,18 +43,39 @@ fun CheckableMatrixUserRow( avatarSize: AvatarSize = AvatarSize.MEDIUM, onCheckedChange: (Boolean) -> Unit = {}, enabled: Boolean = true, -) { +) = CheckableUserRow( + checked = checked, + avatarData = matrixUser.getAvatarData(avatarSize), + name = matrixUser.getBestName(), + subtext = if (matrixUser.displayName.isNullOrEmpty()) null else matrixUser.userId.value, + modifier = modifier, + onCheckedChange = onCheckedChange, + enabled = enabled, +) +@Composable +fun CheckableUserRow( + checked: Boolean, + avatarData: AvatarData, + name: String, + subtext: String?, + modifier: Modifier = Modifier, + onCheckedChange: (Boolean) -> Unit = {}, + enabled: Boolean = true, +) { Row( modifier = modifier .fillMaxWidth() - .clickable(role = Role.Checkbox) { onCheckedChange(!checked) }, + .clickable(role = Role.Checkbox, enabled = enabled) { + onCheckedChange(!checked) + }, verticalAlignment = Alignment.CenterVertically, ) { - MatrixUserRow( + UserRow( modifier = Modifier.weight(1f), - matrixUser = matrixUser, - avatarSize = avatarSize, + avatarData = avatarData, + name = name, + subtext = subtext, ) Checkbox( @@ -77,5 +101,7 @@ private fun ContentToPreview(matrixUser: MatrixUser) { Column { CheckableMatrixUserRow(checked = true, matrixUser) CheckableMatrixUserRow(checked = false, matrixUser) + CheckableMatrixUserRow(checked = true, matrixUser, enabled = false) + CheckableMatrixUserRow(checked = false, matrixUser, enabled = false) } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt index 721682f3a3..0ad787b79b 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight @@ -46,6 +47,19 @@ fun MatrixUserRow( matrixUser: MatrixUser, modifier: Modifier = Modifier, avatarSize: AvatarSize = AvatarSize.MEDIUM, +) = UserRow( + avatarData = matrixUser.getAvatarData(avatarSize), + name = matrixUser.getBestName(), + subtext = if (matrixUser.displayName.isNullOrEmpty()) null else matrixUser.userId.value, + modifier = modifier, +) + +@Composable +fun UserRow( + avatarData: AvatarData, + name: String, + subtext: String?, + modifier: Modifier = Modifier, ) { Row( modifier = modifier @@ -54,9 +68,7 @@ fun MatrixUserRow( .height(IntrinsicSize.Min), verticalAlignment = Alignment.CenterVertically ) { - Avatar( - matrixUser.getAvatarData(size = avatarSize), - ) + Avatar(avatarData) Column( modifier = Modifier .padding(start = 12.dp), @@ -65,15 +77,15 @@ fun MatrixUserRow( Text( fontSize = 16.sp, fontWeight = FontWeight.SemiBold, - text = matrixUser.getBestName(), + text = name, maxLines = 1, overflow = TextOverflow.Ellipsis, color = MaterialTheme.colorScheme.primary, ) // Id - if (matrixUser.displayName.isNullOrEmpty().not()) { + subtext?.let { Text( - text = matrixUser.userId.value, + text = subtext, color = MaterialTheme.colorScheme.secondary, fontSize = 14.sp, maxLines = 1, diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUser.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt similarity index 92% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUser.kt rename to libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt index d43281bbb1..6d31666822 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUser.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.libraries.matrix.ui.components import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box @@ -41,10 +41,9 @@ import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.getBestName -import io.element.android.libraries.ui.strings.R +import io.element.android.libraries.ui.strings.R as StringR @Composable fun SelectedUser( @@ -74,7 +73,7 @@ fun SelectedUser( ) { Icon( imageVector = Icons.Default.Close, - contentDescription = stringResource(id = R.string.action_remove), + contentDescription = stringResource(id = StringR.string.action_remove), tint = MaterialTheme.colorScheme.onPrimary, ) } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUsersList.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUsersList.kt similarity index 94% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUsersList.kt rename to libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUsersList.kt index c9279a3389..c9f819a3d5 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUsersList.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUsersList.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.libraries.matrix.ui.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues @@ -30,11 +30,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import io.element.android.features.userlist.api.aListOfSelectedUsers import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList @Composable fun SelectedUsersList( @@ -82,6 +82,6 @@ internal fun SelectedUsersListDarkPreview() = ElementPreviewDark { ContentToPrev @Composable private fun ContentToPreview() { SelectedUsersList( - selectedUsers = aListOfSelectedUsers(), + selectedUsers = aMatrixUserList().take(6).toImmutableList(), ) } diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 849f306133..40468f8a05 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -85,14 +85,14 @@ "Report a bug" "Report submitted" "Search for someone" - "Search results" + "Search results" "Security" "Select your server" "Sending…" "Server not supported" "Server URL" "Settings" - "Starting chat…" + "Starting chat…" "Sticker" "Success" "Suggestions" diff --git a/features/userlist/api/build.gradle.kts b/libraries/usersearch/api/build.gradle.kts similarity index 70% rename from features/userlist/api/build.gradle.kts rename to libraries/usersearch/api/build.gradle.kts index fb994538f6..39b03bfe90 100644 --- a/features/userlist/api/build.gradle.kts +++ b/libraries/usersearch/api/build.gradle.kts @@ -13,20 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + plugins { - id("io.element.android-compose-library") - alias(libs.plugins.ksp) + id("io.element.android-library") } android { - namespace = "io.element.android.features.userlist.api" + namespace = "io.element.android.libraries.usersearch.api" } dependencies { implementation(projects.libraries.architecture) - implementation(projects.libraries.designsystem) - implementation(projects.libraries.uiStrings) implementation(projects.libraries.matrix.api) - implementation(projects.libraries.matrixui) - ksp(libs.showkase.processor) } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataSource.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserListDataSource.kt similarity index 94% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataSource.kt rename to libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserListDataSource.kt index 0f579b48b7..f855e20861 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataSource.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserListDataSource.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.libraries.usersearch.api import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt similarity index 51% rename from features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt rename to libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt index f3b293c602..bbb124c3c5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt @@ -14,22 +14,12 @@ * limitations under the License. */ -package io.element.android.features.createroom.impl.di +package io.element.android.libraries.usersearch.api -import com.squareup.anvil.annotations.ContributesTo -import dagger.Binds -import dagger.Module -import io.element.android.features.createroom.impl.AllMatrixUsersDataSource -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.libraries.di.SessionScope -import javax.inject.Named +import io.element.android.libraries.matrix.api.user.MatrixUser +import kotlinx.coroutines.flow.Flow -@Module -@ContributesTo(SessionScope::class) -interface CreateRoomModule { - - @Binds - @Named("AllUsers") - fun bindAllUserListDataSource(dataSource: AllMatrixUsersDataSource): UserListDataSource +interface UserRepository { + suspend fun search(query: String): Flow> } diff --git a/features/userlist/impl/build.gradle.kts b/libraries/usersearch/impl/build.gradle.kts similarity index 61% rename from features/userlist/impl/build.gradle.kts rename to libraries/usersearch/impl/build.gradle.kts index 28fe788ffe..226860e86f 100644 --- a/features/userlist/impl/build.gradle.kts +++ b/libraries/usersearch/impl/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,12 @@ */ plugins { - id("io.element.android-compose-library") + id("io.element.android-library") alias(libs.plugins.anvil) - alias(libs.plugins.ksp) } android { - namespace = "io.element.android.features.userlist.impl" + namespace = "io.element.android.libraries.usersearch.impl" } anvil { @@ -29,28 +28,18 @@ anvil { } dependencies { - implementation(projects.anvilannotations) - anvil(projects.anvilcodegen) implementation(projects.libraries.core) implementation(projects.libraries.architecture) - implementation(projects.libraries.matrix.api) + implementation(projects.libraries.di) implementation(projects.libraries.matrixui) - implementation(projects.libraries.designsystem) - implementation(projects.libraries.elementresources) - implementation(projects.libraries.testtags) - implementation(projects.libraries.uiStrings) - api(projects.features.userlist.api) - ksp(libs.showkase.processor) + implementation(projects.libraries.matrix.api) + api(projects.libraries.usersearch.api) testImplementation(libs.test.junit) testImplementation(libs.coroutines.test) - testImplementation(libs.coroutines.core) testImplementation(libs.molecule.runtime) testImplementation(libs.test.truth) testImplementation(libs.test.turbine) - testImplementation(libs.test.mockk) testImplementation(projects.libraries.matrix.test) - testImplementation(projects.features.userlist.test) - - androidTestImplementation(libs.test.junitext) + testImplementation(projects.libraries.usersearch.test) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt similarity index 79% rename from features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt rename to libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt index b79ccc1d5b..53985415f1 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt +++ b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt @@ -14,15 +14,18 @@ * limitations under the License. */ -package io.element.android.features.createroom.impl +package io.element.android.libraries.usersearch.impl -import io.element.android.features.userlist.api.UserListDataSource +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserListDataSource import javax.inject.Inject -class AllMatrixUsersDataSource @Inject constructor( +@ContributesBinding(SessionScope::class) +class MatrixUserListDataSource @Inject constructor( private val client: MatrixClient ) : UserListDataSource { override suspend fun search(query: String): List { diff --git a/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt new file mode 100644 index 0000000000..7577e8f6e8 --- /dev/null +++ b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.usersearch.impl + +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.core.MatrixPatterns +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserListDataSource +import io.element.android.libraries.usersearch.api.UserRepository +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import javax.inject.Inject + +@ContributesBinding(SessionScope::class) +class MatrixUserRepository @Inject constructor( + private val dataSource: UserListDataSource +) : UserRepository { + + override suspend fun search(query: String): Flow> = flow { + // Manually add a fake result with the matrixId, if any + val isUserId = MatrixPatterns.isUserId(query) + if (isUserId) { + emit(listOf(MatrixUser(UserId(query)))) + } + + if (query.length >= MINIMUM_SEARCH_LENGTH) { + // Debounce + delay(DEBOUNCE_TIME_MILLIS) + + val results = dataSource.search(query).toMutableList() + + // If the query is a user ID and the result doesn't contain that user ID, query the profile information explicitly + if (isUserId && results.none { it.userId.value == query }) { + val getProfileResult: MatrixUser? = dataSource.getProfile(UserId(query)) + val profile = getProfileResult ?: MatrixUser(UserId(query)) + results.add(0, profile) + } + + emit(results) + } + } + + companion object { + private const val DEBOUNCE_TIME_MILLIS = 500L + private const val MINIMUM_SEARCH_LENGTH = 3 + } +} diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt similarity index 81% rename from features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt rename to libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt index 043ad06361..5dc42773d3 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt +++ b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.createroom.impl +package io.element.android.libraries.usersearch.impl import com.google.common.truth.Truth import io.element.android.libraries.matrix.api.core.UserId @@ -28,7 +28,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import kotlinx.coroutines.test.runTest import org.junit.Test -internal class AllMatrixUsersDataSourceTest { +internal class MatrixUserListDataSourceTest { @Test fun `search - returns users on success`() = runTest { @@ -37,15 +37,21 @@ internal class AllMatrixUsersDataSourceTest { searchTerm = "test", result = Result.success( MatrixSearchUserResults( - results = listOf(aMatrixUserProfile(), aMatrixUserProfile(userId = A_USER_ID_2)), + results = listOf( + aMatrixUserProfile(), + aMatrixUserProfile(userId = A_USER_ID_2) + ), limited = false ) ) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val results = dataSource.search("test") - Truth.assertThat(results).containsExactly(aMatrixUserProfile(), aMatrixUserProfile(userId = A_USER_ID_2)) + Truth.assertThat(results).containsExactly( + aMatrixUserProfile(), + aMatrixUserProfile(userId = A_USER_ID_2) + ) } @Test @@ -55,7 +61,7 @@ internal class AllMatrixUsersDataSourceTest { searchTerm = "test", result = Result.failure(Throwable("Ruhroh")) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val results = dataSource.search("test") Truth.assertThat(results).isEmpty() @@ -68,7 +74,7 @@ internal class AllMatrixUsersDataSourceTest { userId = A_USER_ID, result = Result.success(aMatrixUserProfile()) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val result = dataSource.getProfile(A_USER_ID) Truth.assertThat(result).isEqualTo(aMatrixUserProfile()) @@ -81,7 +87,7 @@ internal class AllMatrixUsersDataSourceTest { userId = A_USER_ID, result = Result.failure(Throwable("Ruhroh")) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val result = dataSource.getProfile(A_USER_ID) Truth.assertThat(result).isNull() diff --git a/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt new file mode 100644 index 0000000000..e2eab067e6 --- /dev/null +++ b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.usersearch.impl + +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.test.A_USER_ID +import io.element.android.libraries.matrix.test.A_USER_NAME +import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import io.element.android.libraries.usersearch.test.FakeUserListDataSource +import kotlinx.coroutines.test.runTest +import org.junit.Test + +internal class MatrixUserRepositoryTest { + + @Test + fun `search - emits nothing if the search query is too short`() = runTest { + val dataSource = FakeUserListDataSource() + val repository = MatrixUserRepository(dataSource) + + val result = repository.search("x") + + result.test { + awaitComplete() + } + } + + @Test + fun `search - returns empty list if no results are found`() = runTest { + val dataSource = FakeUserListDataSource() + val repository = MatrixUserRepository(dataSource) + + val result = repository.search("some query") + + result.test { + assertThat(awaitItem()).isEmpty() + awaitComplete() + } + } + + @Test + fun `search - returns users if results are found`() = runTest { + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(aMatrixUserList()) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search("some query") + + result.test { + assertThat(awaitItem()).isEqualTo(aMatrixUserList()) + awaitComplete() + } + } + + @Test + fun `search - immediately returns placeholder if search is mxid`() = runTest { + val dataSource = FakeUserListDataSource() + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + assertThat(awaitItem()).isEqualTo(listOf(MatrixUser(userId = A_USER_ID))) + skipItems(1) + awaitComplete() + } + } + + @Test + fun `search - does not change results if they contain searched mxid`() = runTest { + val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + MatrixUser(userId = A_USER_ID, displayName = A_USER_NAME) + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + skipItems(1) + assertThat(awaitItem()).isEqualTo(searchResults) + awaitComplete() + } + } + + @Test + fun `search - gets profile results if searched mxid not in results`() = runTest { + val userProfile = MatrixUser(userId = A_USER_ID, displayName = A_USER_NAME) + val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + dataSource.givenUserProfile(userProfile) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + skipItems(1) + assertThat(awaitItem()).isEqualTo(listOf(userProfile) + searchResults) + awaitComplete() + } + } + + @Test + fun `search - just shows id if profile can't be loaded`() = runTest { + val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + dataSource.givenUserProfile(null) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + skipItems(1) + assertThat(awaitItem()).isEqualTo(listOf(MatrixUser(userId = A_USER_ID)) + searchResults) + awaitComplete() + } + } + + private fun aMatrixUserListWithoutUserId(userId: UserId) = aMatrixUserList().filterNot { it.userId == userId } + +} diff --git a/features/userlist/test/build.gradle.kts b/libraries/usersearch/test/build.gradle.kts similarity index 78% rename from features/userlist/test/build.gradle.kts rename to libraries/usersearch/test/build.gradle.kts index a064038665..dc8a0b3d69 100644 --- a/features/userlist/test/build.gradle.kts +++ b/libraries/usersearch/test/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + plugins { - id("io.element.android-compose-library") + id("io.element.android-library") } android { - namespace = "io.element.android.features.userlist.test" + namespace = "io.element.android.libraries.usersearch" } dependencies { implementation(projects.libraries.architecture) implementation(projects.libraries.matrixui) implementation(projects.libraries.matrix.api) - api(projects.features.userlist.api) - api(libs.coroutines.core) + api(projects.libraries.usersearch.api) } diff --git a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListDataSource.kt b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserListDataSource.kt similarity index 90% rename from features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListDataSource.kt rename to libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserListDataSource.kt index 1f656e388f..d5f5183a4f 100644 --- a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListDataSource.kt +++ b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserListDataSource.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.element.android.features.userlist.test +package io.element.android.libraries.usersearch.test -import io.element.android.features.userlist.api.UserListDataSource import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserListDataSource class FakeUserListDataSource : UserListDataSource { diff --git a/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt new file mode 100644 index 0000000000..ea0d93a197 --- /dev/null +++ b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.usersearch.test + +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow + +class FakeUserRepository : UserRepository { + + var providedQuery: String? = null + private set + + private val flow = MutableSharedFlow>() + + override suspend fun search(query: String): Flow> { + providedQuery = query + return flow + } + + suspend fun emitResult(result: List) { + flow.emit(result) + } + +} diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 962cb2c18d..e7023ad88e 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -90,6 +90,7 @@ fun DependencyHandlerScope.allLibrariesImpl() { implementation(project(":libraries:statemachine")) implementation(project(":libraries:mediapickers:impl")) implementation(project(":libraries:mediaupload:impl")) + implementation(project(":libraries:usersearch:impl")) } fun DependencyHandlerScope.allServicesImpl() { diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_0_null,NEXUS_5,1.0,en].png index a7e6d29b5f..efe83873c0 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cbfbfa08085539bbfa4f20bc5d149bf0db0036169a32747c96f956d0d0f4b42d -size 93741 +oid sha256:b7787897d8dda469f17da7151260f26b6dcc5500f93ce44fb317af42ae8d457c +size 93739 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_0_null,NEXUS_5,1.0,en].png index e278779a22..6dae242f3c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e0ba60e784a0dc582826a3f5679a6015531dc9aca22617ec1e0dede38b97f30 -size 93678 +oid sha256:6691512398d2c7e319d15397120054f1c2aae452ffed0be47df72ecb906ac4fa +size 93675 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index ca85a9b25c..964891e6d2 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:766b2d44b51a36d1b15d8a39434ce5237f8427d1150f9b4c1255043fc1e4bb79 -size 492165 +oid sha256:44313efc4d87857b9eb0bb05c8d24330b17353fd95344bcce06c1ad1bba8df81 +size 492167 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index ca85a9b25c..964891e6d2 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:766b2d44b51a36d1b15d8a39434ce5237f8427d1150f9b4c1255043fc1e4bb79 -size 492165 +oid sha256:44313efc4d87857b9eb0bb05c8d24330b17353fd95344bcce06c1ad1bba8df81 +size 492167 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 7d93e5c715..17e1d2852a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3443f60b8ceec7eccfee92c1bca8cad151e25cff8e7845459a5f4c3d50e5e08 -size 3330 +oid sha256:523d6607d70a331d2ec32aeabf033d59c4dc60e0e7373982893df0245ae924ce +size 3332 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 7b025a402e..abfa1dae68 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0b0cdb7e39d5ca5ce874477da4397ebed00ecf9f5d8980f9f3b03ab72259d9f -size 4000 +oid sha256:266490a1bdce29ac65d875543deda072d7f2a9aa2e216efb0d54b93c2a11aa5f +size 4001 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_2,NEXUS_5,1.0,en].png index 7d93e5c715..17e1d2852a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3443f60b8ceec7eccfee92c1bca8cad151e25cff8e7845459a5f4c3d50e5e08 -size 3330 +oid sha256:523d6607d70a331d2ec32aeabf033d59c4dc60e0e7373982893df0245ae924ce +size 3332 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_3,NEXUS_5,1.0,en].png index 7b025a402e..abfa1dae68 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0b0cdb7e39d5ca5ce874477da4397ebed00ecf9f5d8980f9f3b03ab72259d9f -size 4000 +oid sha256:266490a1bdce29ac65d875543deda072d7f2a9aa2e216efb0d54b93c2a11aa5f +size 4001 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_0,NEXUS_5,1.0,en].png index eb0f1bcfde..66a540e8a7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d35eb1aac0d413c216dc77f45f655be97ae9d36c3cade57ee8f70e25c44fafd1 -size 3142 +oid sha256:e94515b43bc4b8427edc60456ec657ec38b33539a034a2c45c92624a6b75d4e8 +size 3138 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_1,NEXUS_5,1.0,en].png index 69b558a480..6a087cd16c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:782a439312e4b616a6dd3020d8c99d04042208b2ebc416fab73c95344adeba67 -size 3834 +oid sha256:a4dc928a04bfc6331673be2fa0bf7f12e384dfd8ff91b07dc57b220c8dbbdd71 +size 3829 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_2,NEXUS_5,1.0,en].png index eb0f1bcfde..66a540e8a7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d35eb1aac0d413c216dc77f45f655be97ae9d36c3cade57ee8f70e25c44fafd1 -size 3142 +oid sha256:e94515b43bc4b8427edc60456ec657ec38b33539a034a2c45c92624a6b75d4e8 +size 3138 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_3,NEXUS_5,1.0,en].png index 69b558a480..6a087cd16c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:782a439312e4b616a6dd3020d8c99d04042208b2ebc416fab73c95344adeba67 -size 3834 +oid sha256:a4dc928a04bfc6331673be2fa0bf7f12e384dfd8ff91b07dc57b220c8dbbdd71 +size 3829 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_0_null,NEXUS_5,1.0,en].png index d6eab0d361..89034f66b9 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cab21ee595c96700e4577554f9c98fdc56a59bf5093aa9d81a54d10381ba122 -size 6065 +oid sha256:25d0334932490997d432115c550c42e74e7226399ef82031430bf86ba33972bd +size 6066 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_0_null,NEXUS_5,1.0,en].png index 70722aa53f..c407012dfd 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9235621126fe90a51d557df616878d53120dada814830fba006b54f1556e69e -size 5895 +oid sha256:a2d15387248308e5234c84b9b2b282e736f05f0495c80807bacfb0acff31eb2b +size 5890 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index b11864d276..3fc91b65e4 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:562e83b7771ff2209c7882180af55a8f3123c12c020b294858b1b46bff8a8a95 -size 30928 +oid sha256:5315b975f8b9def0b0d7575160cb34300511f1b83845ee2d1762188481cf6fe9 +size 30927 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index a55c0f8cdc..7a61ecf737 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79b16cbbbf36e6de4ea6270476371c7097424b26d4066f7156738c084fe061de +oid sha256:099401d03621aca301d3c4590d90ba4e4642d400d7603a8e15140a1bfef0c0ec size 42758 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png index f1bd1303ce..e361e4a2d2 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7534d8379a1ab220833b8c877f9b3021a665cdb97c71ba383695276d83757702 -size 32721 +oid sha256:ca5dbc3aa00d6116de38fc0217b20ab0db4096b1f76bcc18b43ab9fd343f8110 +size 32722 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png index 2fa40047c6..42f22c9a26 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3123fce3d4e4ed0480d2757e4daa70ecd14ddad1e8471523638561cccbab8dc -size 44568 +oid sha256:6211ec07d10d48e4713206e4c1fe24eae890fe2310d5bcc1f4ca54cc57f84ec9 +size 44564 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png index d0b80fcd37..b974aec366 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:32d8032b1b2b3ae2b2795dea60b6395104df24790450f9452bbe82e81d9e62e8 -size 28911 +oid sha256:8ac7985e70782a84fc351cb15536bfd700ca8d6d48d5da0ee9dcaf5c78226479 +size 28909 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png index c14452b104..cf23661de1 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abff6db46d39ec39f3c0d5366f91252b58cbf62e6850bc86a6e81e52c80ba096 -size 45979 +oid sha256:c99138940ed1a8beac7da3c673600016a03b87195e07f205d5d389ef05be0fb0 +size 45978 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index 3123c5dd15..20f62bf8e6 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34469e4b86a441fb6f7cfbdce4b622109c093a234ae5d35d895dce35ef10c20c -size 30327 +oid sha256:2f24112ad89e5ef93917d45e3232043168d5092ce6d62a7d414773dd0afda963 +size 30326 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 6d5c269d4c..534402d370 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11c677ab3124a94f531f1db14eb2b2f19a493470620f7375cf7c1d14056cdbc9 -size 42429 +oid sha256:9c696c464515873a94d28f8909dc47255717fc3b012ce0d80000769714e3cb9c +size 42427 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_2,NEXUS_5,1.0,en].png index 3b8db29b08..88014ea46b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a35878a3d306b1a6d1768669904ee1f9e0a71abd4ab3c04ff6564027732614f -size 32077 +oid sha256:0fe506e4e7adbfe19fd48f0a40c19343471e0bb06e12fac8d5e6d54595e7193a +size 32076 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_3,NEXUS_5,1.0,en].png index 816518f7aa..e70fa9d639 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1b3b0b538dafa85849c6e255bcff6b1a82a52d49be1fe4ded9b7f7c2ec06bff -size 44431 +oid sha256:c9c9374c303c9a71b0526fccfd18903d145c1b3b0059de3ccd41cf80f1541a80 +size 44427 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_4,NEXUS_5,1.0,en].png index 25f8d272a1..4ebc61d047 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef18369400f738e94c5a812dc0ec4c8473659eafb11d7361385647ba6a640d15 -size 28320 +oid sha256:5f18d8b33eace857f78b92eed035621125bbfca1f0d43e5e47fd1c3965324de0 +size 28319 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_5,NEXUS_5,1.0,en].png index 49caf143da..336334e955 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:633210082fc83be3628250fa35768969aad136035924667bd2f3c6c8307fd87c -size 45641 +oid sha256:be0722a804c2fc264f931f8784635bceab7ddcf08e378bed8ea510bd76813fbf +size 45642 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 580da9ceb6..1ba319f8ee 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01f54909964a4ed07d8850ab2bffad8b99ed641d731c1808b04f164ff3e0cbba -size 39632 +oid sha256:b77478183675fd3bb9a7ef34ef808e3ad75b504a0236b4dcb0d96a7faafc29cc +size 39629 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index ff59a95d62..27b4e07cb9 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ea39fdf1cb61657bc1eafb7d353ee15517c26c0e6bb2804b7c8350fa651299e -size 41508 +oid sha256:2645c93a097d35725a7afb83c97dd0ea6b5623990cbae2372aaf66c9011e353c +size 41506 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png index 1d82aaf60b..dee6d7dd1a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7d7470933e27c64182c5f8acec7b4ce3896db1cc3836ff6aa6cf33fe8688f10 +oid sha256:394ffe0b730e7d4010ec0d7f96b5487b2775e70aa7e42b6bf8b2535ad5acc244 size 37524 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png index a943b1245f..4aa436dc8c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ac05963f89ac0d3045700447a40a4a6f38cc155812de7eb9a87fb9a01643033 -size 36300 +oid sha256:b87be006b0125029391e74a09bc2a07a906c33d9ea21ca17f884f2d8862af32a +size 36302 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index a24d98a08c..c3e23147ca 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6c558d2a8e6adb4831b91aff249d16dfc48389adef5ada6e1215df1d597639a -size 38654 +oid sha256:93f8dd057f245d454a6ebf81607c879b6ae4c20287a64d001bee36764e0802a5 +size 38657 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 549011130b..c3d01356c6 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:946802d97d29f9fe41a71f1ee343e298e1b0d9dbbc6561cc82fed712e623f89c +oid sha256:2a4ce62d7f8f27128fd59cd3e7eea068a002d7e2c0a054fef1f555d06cf91ebe size 40708 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png index 3586f9c218..4660650dfb 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97f10ca5290a0b4b1e034e157abb0f069fac2f2c2e88234edb1efc25c6c111f0 -size 36228 +oid sha256:bee8752a24938844cae76aadae9148a19001302a9e4909cf69a192a98d583ba4 +size 36230 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png index 8866feaf6f..6e04daf76b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfc76bb6a8d8b269f53c2cc1c369a5c5ffb0f0fb858ebfa50c613a793bc1b421 -size 35195 +oid sha256:8f89eebcabe514594c53e6e436ae63685e6b693628f2acf796c6306298aff1a8 +size 35199 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png index 9749477ebd..b1f708d57c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c820bd324df729db08710d1a6c17ca34a451a3bb94da2206fc57d6b4efe91e2f -size 60019 +oid sha256:b53d55b5085673ac3a0a7663f7ff68e7d510fe352f3931b49c7e75e4c3767b93 +size 60007 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png index f24edcc4a1..d020b1e521 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da2f9f87d89382b4b18d39a477a8e86f98067e2326adae4def8374b5bf09f316 -size 57588 +oid sha256:a761318f3dfbc2ce6e777cfabc19eeb2f89100ae7631660f4b4d7550cd947c84 +size 57580 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 07451a0330..01ec8ec0fc 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:628f1f00dca9d15faabd8288a3c54b1b8581a380cf14edf364f0dee9ecc187d5 +oid sha256:147786f2cfcf7674147253cca5e41b4af96587a27216076a1c0802c81b0b1b46 size 180117 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 8146c241cb..a49d11835b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:827bccb0fdd3106fb24a95d665b4da2cfc15de48e8f508ae809c9f75d6d1bbf0 -size 178915 +oid sha256:789a979f7207531b4b9ba488ae2de52e6046809e788baf6690e1383a933cf624 +size 178916 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..030fb820b7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbf23d459e0eb3bbe1e368ab481d7f5eed081b509e4e14e609cb39cfcf48be8 +size 7740 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..34fa9c6c48 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cfe71589b04ee2842891d156144c8ba5fdce9cc45e598a29c6fb88a9ba7b0a2 +size 23703 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..8a1696e8d5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b9511f6e2d61f6779c5a7e5de2086ccb6cf262a40892d513432deddf852adf3 +size 9971 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2b3c997070 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36b46cd1c92f38e10d6590d388d5d63f93b1bb594646c4a237912f1a6ca95aee +size 7929 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..7b91e01600 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4844839df09fe09a60136fc284e0d17047e162852c82a00c71a1c799587dd3d8 +size 24687 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png deleted file mode 100644 index d1f5f87768..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0b6a919d51f99281574b6b337614c14e120f0496c4e3616db2e75283ea282cc0 -size 20655 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 3dfe0d733a..9ee0c6f7da 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:30c90c24433d78554597a31fd1219ca3ad5538343b56b6ca32812f66757fa26e -size 53630 +oid sha256:928ca6703262b25b95c5db3e57683d1ca93e52a56919f5b49be2bce2048c7f81 +size 108583 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png index c3461af285..e3a85d6ed2 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da34205fab6387e76410a05efa0ea509d8a6b1b051628847b7420abf6c58d12d -size 52180 +oid sha256:48cd12b8a729b9d05f2fc85eb5eda8f0df3a29e45d3a7d5f64d087e1d48cfbc2 +size 104207 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png index ef64232112..09ab29f73d 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a31c217b10467f987d9fa0c387a32b493ff07eb0891715406f141b5f3dd447bf -size 52045 +oid sha256:8ee67026a3d030a6aeec422866e75dae820853dcb1108b34a060d6020865a35e +size 104725 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png index 9ee1c0e61b..8b550991ad 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56af20b122a1cda4f472b572f71a6f1411d759855f81ed99f24448d43739133c -size 50292 +oid sha256:f33ca29caddd1134e4d94f823ee5a9ac307ac9ec6806fd1910aef96b3d39c39b +size 100419 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png