From c6b3387b62b08c7f5750f39ac478aae5521ae512 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 4 Jan 2024 21:27:44 +0100 Subject: [PATCH 01/10] User search : show a loader when fetching results --- .../impl/components/SearchUserBar.kt | 7 +++ .../impl/components/UserListView.kt | 1 + .../impl/userlist/DefaultUserListPresenter.kt | 20 ++++--- .../createroom/impl/userlist/UserListState.kt | 1 + .../impl/userlist/UserListStateProvider.kt | 6 +- .../userlist/DefaultUserListPresenterTests.kt | 10 ++-- .../impl/invite/RoomInviteMembersPresenter.kt | 30 +++++++--- .../impl/invite/RoomInviteMembersState.kt | 1 + .../invite/RoomInviteMembersStateProvider.kt | 6 +- .../impl/invite/RoomInviteMembersView.kt | 8 +++ .../impl/members/RoomMemberListPresenter.kt | 6 +- .../members/RoomMemberListStateProvider.kt | 4 +- .../invite/RoomInviteMembersPresenterTest.kt | 4 +- .../members/RoomMemberListPresenterTests.kt | 4 +- .../theme/components/SearchBar.kt | 31 +++++----- .../roomselect/impl/RoomSelectPresenter.kt | 4 +- .../impl/RoomSelectStateProvider.kt | 2 +- .../impl/RoomSelectPresenterTests.kt | 6 +- .../usersearch/api/UserRepository.kt | 2 +- .../usersearch/api/UserSearchResult.kt | 5 ++ .../usersearch/impl/MatrixUserRepository.kt | 56 +++++++++++-------- 21 files changed, 134 insertions(+), 80 deletions(-) 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 index bc562627cc..a9292e5a24 100644 --- 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 @@ -35,6 +35,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.async.AsyncLoading import io.element.android.libraries.designsystem.theme.components.HorizontalDivider import io.element.android.libraries.designsystem.theme.components.SearchBar import io.element.android.libraries.designsystem.theme.components.SearchBarResultState @@ -49,6 +50,7 @@ import kotlinx.collections.immutable.ImmutableList fun SearchUserBar( query: String, state: SearchBarResultState>, + isSearching: Boolean, selectedUsers: ImmutableList, active: Boolean, isMultiSelectionEnabled: Boolean, @@ -99,6 +101,11 @@ fun SearchUserBar( ) } }, + contentSuffix = { + if (isSearching) { + AsyncLoading() + } + }, resultState = state, resultHandler = { users -> LazyColumn(state = columnState) { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt index 45d898577f..8d5a3690db 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt @@ -48,6 +48,7 @@ fun UserListView( state = state.searchResults, selectedUsers = state.selectedUsers, active = state.isSearchActive, + isSearching = state.isFetchingSearchResults, isMultiSelectionEnabled = state.isMultiSelectionEnabled, showBackButton = showBackButton, onActiveChanged = { state.eventSink(UserListEvents.OnSearchActiveChanged(it)) }, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt index 867fdc9a60..19a858dd78 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt @@ -34,6 +34,8 @@ import io.element.android.libraries.usersearch.api.UserRepository import io.element.android.libraries.usersearch.api.UserSearchResult import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach class DefaultUserListPresenter @AssistedInject constructor( @Assisted val args: UserListPresenterArgs, @@ -57,18 +59,21 @@ class DefaultUserListPresenter @AssistedInject constructor( val selectedUsers by userListDataStore.selectedUsers().collectAsState(emptyList()) var searchQuery by rememberSaveable { mutableStateOf("") } var searchResults: SearchBarResultState> by remember { - mutableStateOf(SearchBarResultState.NotSearching()) + mutableStateOf(SearchBarResultState.Empty()) } + var isFetchingSearchResults by remember { mutableStateOf(false) } LaunchedEffect(searchQuery) { - searchResults = SearchBarResultState.NotSearching() - - userRepository.search(searchQuery).collect { + searchResults = SearchBarResultState.Empty() + isFetchingSearchResults = false + userRepository.search(searchQuery).onEach { state -> + isFetchingSearchResults = state.isFetchingSearchResults searchResults = when { - it.isEmpty() -> SearchBarResultState.NoResults() - else -> SearchBarResultState.Results(it.toImmutableList()) + state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Empty() + state.results.isEmpty() && !state.isFetchingSearchResults -> SearchBarResultState.NoResultsFound() + else -> SearchBarResultState.Results(state.results.toImmutableList()) } - } + }.launchIn(this) } return UserListState( @@ -76,6 +81,7 @@ class DefaultUserListPresenter @AssistedInject constructor( searchResults = searchResults, selectedUsers = selectedUsers.toImmutableList(), isSearchActive = isSearchActive, + isFetchingSearchResults = isFetchingSearchResults, selectionMode = args.selectionMode, eventSink = { event -> when (event) { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt index 60a5bea506..5d59735e46 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt @@ -24,6 +24,7 @@ import kotlinx.collections.immutable.ImmutableList data class UserListState( val searchQuery: String, val searchResults: SearchBarResultState>, + val isFetchingSearchResults: Boolean, val selectedUsers: ImmutableList, val isSearchActive: Boolean, val selectionMode: SelectionMode, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt index 31d1f6953a..ec7fba57b5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt @@ -51,17 +51,19 @@ open class UserListStateProvider : PreviewParameterProvider { aUserListState().copy( isSearchActive = true, searchQuery = "something-with-no-results", - searchResults = SearchBarResultState.NoResults() + searchResults = SearchBarResultState.NoResultsFound() ), + aUserListState().copy(isSearchActive = true, searchQuery = "someone", selectionMode = SelectionMode.Single), ) } fun aUserListState() = UserListState( isSearchActive = false, searchQuery = "", - searchResults = SearchBarResultState.NotSearching(), + searchResults = SearchBarResultState.Empty(), selectedUsers = persistentListOf(), selectionMode = SelectionMode.Single, + isFetchingSearchResults = false, eventSink = {} ) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index a591a7a8e9..7f5eff5c30 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -55,7 +55,7 @@ class DefaultUserListPresenterTests { assertThat(initialState.isMultiSelectionEnabled).isFalse() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) } } @@ -76,7 +76,7 @@ class DefaultUserListPresenterTests { assertThat(initialState.isMultiSelectionEnabled).isTrue() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) } } @@ -131,7 +131,7 @@ class DefaultUserListPresenterTests { val initialState = awaitItem() initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) assertThat(userRepository.providedQuery).isEqualTo("alice") skipItems(2) @@ -170,13 +170,13 @@ class DefaultUserListPresenterTests { val initialState = awaitItem() initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::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) + assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt index cc0886c3af..4cd540bd35 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt @@ -37,6 +37,8 @@ import io.element.android.libraries.usersearch.api.UserRepository import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.withContext import javax.inject.Inject @@ -50,16 +52,22 @@ class RoomInviteMembersPresenter @Inject constructor( override fun present(): RoomInviteMembersState { val roomMembers = remember { mutableStateOf>>(Async.Loading()) } val selectedUsers = remember { mutableStateOf>(persistentListOf()) } - val searchResults = remember { mutableStateOf>>(SearchBarResultState.NotSearching()) } + val searchResults = remember { mutableStateOf>>(SearchBarResultState.Empty()) } var searchQuery by rememberSaveable { mutableStateOf("") } var searchActive by rememberSaveable { mutableStateOf(false) } + var isFetchingSearchResults = rememberSaveable { mutableStateOf(false) } LaunchedEffect(Unit) { fetchMembers(roomMembers) } - LaunchedEffect(searchQuery, roomMembers) { - performSearch(searchResults, roomMembers, selectedUsers, searchQuery) + performSearch( + searchResults = searchResults, + roomMembers = roomMembers, + selectedUsers = selectedUsers, + isFetchingSearchResults = isFetchingSearchResults, + searchQuery = searchQuery + ) } return RoomInviteMembersState( @@ -68,6 +76,7 @@ class RoomInviteMembersPresenter @Inject constructor( searchQuery = searchQuery, isSearchActive = searchActive, searchResults = searchResults.value, + isFetchingSearchResults = isFetchingSearchResults.value, eventSink = { when (it) { is RoomInviteMembersEvents.OnSearchActiveChanged -> { @@ -117,16 +126,19 @@ class RoomInviteMembersPresenter @Inject constructor( searchResults: MutableState>>, roomMembers: MutableState>>, selectedUsers: MutableState>, + isFetchingSearchResults: MutableState, searchQuery: String, ) = withContext(coroutineDispatchers.io) { - searchResults.value = SearchBarResultState.NotSearching() - + searchResults.value = SearchBarResultState.Empty() + isFetchingSearchResults.value = false val joinedMembers = roomMembers.value.dataOrNull().orEmpty() - userRepository.search(searchQuery).collect { + userRepository.search(searchQuery).onEach { state -> + isFetchingSearchResults.value = state.isFetchingSearchResults searchResults.value = when { - it.isEmpty() -> SearchBarResultState.NoResults() - else -> SearchBarResultState.Results(it.map { result -> + state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Empty() + state.results.isEmpty() && !state.isFetchingSearchResults -> SearchBarResultState.NoResultsFound() + else -> SearchBarResultState.Results(state.results.map { result -> val existingMembership = joinedMembers.firstOrNull { j -> j.userId == result.matrixUser.userId }?.membership val isJoined = existingMembership == RoomMembershipState.JOIN val isInvited = existingMembership == RoomMembershipState.INVITE @@ -139,7 +151,7 @@ class RoomInviteMembersPresenter @Inject constructor( ) }.toImmutableList()) } - } + }.launchIn(this) } private suspend fun fetchMembers(roomMembers: MutableState>>) { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt index 16436debf0..1fb2dc1e78 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt @@ -23,6 +23,7 @@ import kotlinx.collections.immutable.ImmutableList data class RoomInviteMembersState( val canInvite: Boolean, val searchQuery: String, + val isFetchingSearchResults: Boolean, val searchResults: SearchBarResultState>, val selectedUsers: ImmutableList, val isSearchActive: Boolean, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt index f44d518fb5..c9ae8a606a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt @@ -32,7 +32,7 @@ internal class RoomInviteMembersStateProvider : PreviewParameterProvider> = SearchBarResultState.NotSearching(), + searchResults: SearchBarResultState> = SearchBarResultState.Empty(), selectedUsers: ImmutableList = persistentListOf(), isSearchActive: Boolean = false, + isFetchingSearchResults: Boolean = false, ): RoomInviteMembersState { return RoomInviteMembersState( canInvite = canInvite, @@ -80,6 +81,7 @@ private fun aRoomInviteMembersState( searchResults = searchResults, selectedUsers = selectedUsers, isSearchActive = isSearchActive, + isFetchingSearchResults = isFetchingSearchResults, eventSink = {}, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt index 6c19b45686..73f6de54a8 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt @@ -50,6 +50,7 @@ import io.element.android.libraries.matrix.ui.components.SelectedUsersList import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.getBestName import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.components.async.AsyncLoading import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList @@ -86,6 +87,7 @@ fun RoomInviteMembersView( RoomInviteMembersSearchBar( modifier = Modifier.fillMaxWidth(), query = state.searchQuery, + isSearching = state.isFetchingSearchResults, selectedUsers = state.selectedUsers, state = state.searchResults, active = state.isSearchActive, @@ -139,6 +141,7 @@ private fun RoomInviteMembersTopBar( private fun RoomInviteMembersSearchBar( query: String, state: SearchBarResultState>, + isSearching: Boolean, selectedUsers: ImmutableList, active: Boolean, onActiveChanged: (Boolean) -> Unit, @@ -167,6 +170,11 @@ private fun RoomInviteMembersSearchBar( }, showBackButton = false, resultState = state, + contentSuffix = { + if (isSearching) { + AsyncLoading() + } + }, resultHandler = { results -> Text( text = stringResource(id = CommonStrings.common_search_results), 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 49ae479d40..e779af5f61 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 @@ -47,7 +47,7 @@ class RoomMemberListPresenter @Inject constructor( var roomMembers by remember { mutableStateOf>(Async.Loading()) } var searchQuery by rememberSaveable { mutableStateOf("") } var searchResults by remember { - mutableStateOf>(SearchBarResultState.NotSearching()) + mutableStateOf>(SearchBarResultState.Empty()) } var isSearchActive by rememberSaveable { mutableStateOf(false) } @@ -71,10 +71,10 @@ class RoomMemberListPresenter @Inject constructor( LaunchedEffect(searchQuery) { withContext(coroutineDispatchers.io) { searchResults = if (searchQuery.isEmpty()) { - SearchBarResultState.NotSearching() + SearchBarResultState.Empty() } else { val results = roomMemberListDataSource.search(searchQuery).groupBy { it.membership } - if (results.isEmpty()) SearchBarResultState.NoResults() + if (results.isEmpty()) SearchBarResultState.NoResultsFound() else SearchBarResultState.Results( RoomMembers( invited = results.getOrDefault(RoomMembershipState.INVITE, emptyList()).toImmutableList(), 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 4954af8efc..f6eefa4385 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 @@ -53,14 +53,14 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider = Async.Uninitialized, - searchResults: SearchBarResultState = SearchBarResultState.NotSearching(), + searchResults: SearchBarResultState = SearchBarResultState.Empty(), ) = RoomMemberListState( roomMembers = roomMembers, searchQuery = "", diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt index 9763ed280b..7ecdccf7f1 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt @@ -63,7 +63,7 @@ internal class RoomInviteMembersPresenterTest { }.test { val initialState = awaitItem() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.canInvite).isFalse() assertThat(initialState.searchQuery).isEmpty() @@ -115,7 +115,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) val resultState = awaitItem() - assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.NoResults::class.java) + assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } 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 097919a5e1..3a2620cad0 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 @@ -55,7 +55,7 @@ class RoomMemberListPresenterTests { val initialState = awaitItem() assertThat(initialState.roomMembers).isInstanceOf(Async.Loading::class.java) assertThat(initialState.searchQuery).isEmpty() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) assertThat(initialState.isSearchActive).isFalse() val loadedState = awaitItem() assertThat(loadedState.roomMembers).isInstanceOf(Async.Success::class.java) @@ -92,7 +92,7 @@ class RoomMemberListPresenterTests { val searchQueryUpdatedState = awaitItem() assertThat(searchQueryUpdatedState.searchQuery).isEqualTo("something") val searchSearchResultDelivered = awaitItem() - assertThat(searchSearchResultDelivered.searchResults).isInstanceOf(SearchBarResultState.NoResults::class.java) + assertThat(searchSearchResultDelivered.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } 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 7e208b88d9..c53fbb6cb6 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 @@ -59,7 +59,7 @@ fun SearchBar( modifier: Modifier = Modifier, enabled: Boolean = true, showBackButton: Boolean = true, - resultState: SearchBarResultState = SearchBarResultState.NotSearching(), + resultState: SearchBarResultState = SearchBarResultState.Empty(), shape: Shape = SearchBarDefaults.inputFieldShape, tonalElevation: Dp = SearchBarDefaults.TonalElevation, windowInsets: WindowInsets = SearchBarDefaults.windowInsets, @@ -129,7 +129,7 @@ fun SearchBar( resultHandler(resultState.results) } - is SearchBarResultState.NoResults -> { + is SearchBarResultState.NoResultsFound -> { // No results found, show a message Spacer(Modifier.size(80.dp)) @@ -184,10 +184,10 @@ object ElementSearchBarDefaults { @Immutable sealed interface SearchBarResultState { /** No search results are available yet (e.g. because the user hasn't entered a search term). */ - class NotSearching : SearchBarResultState + class Empty : SearchBarResultState /** The search has completed, but no results were found. */ - class NoResults : SearchBarResultState + class NoResultsFound : SearchBarResultState /** The search has completed, and some matching users were found. */ data class Results(val results: T) : SearchBarResultState @@ -199,7 +199,7 @@ internal fun SearchBarInactivePreview() = ElementThemedPreview { ContentToPrevie @Preview(group = PreviewGroup.Search) @Composable -internal fun SearchBarActiveEmptyQueryPreview() = ElementThemedPreview { +internal fun SearchBarActiveNoneQueryPreview() = ElementThemedPreview { ContentToPreview( query = "", active = true, @@ -231,7 +231,7 @@ internal fun SearchBarActiveWithNoResultsPreview() = ElementThemedPreview { ContentToPreview( query = "search term", active = true, - resultState = SearchBarResultState.NoResults(), + resultState = SearchBarResultState.NoResultsFound(), ) } @@ -257,16 +257,15 @@ internal fun SearchBarActiveWithContentPreview() = ElementThemedPreview { .background(color = Color.Blue) .fillMaxWidth() ) - }, - resultHandler = { - Text( - text = "Results go here", - modifier = Modifier - .background(color = Color.Green) - .fillMaxWidth() - ) } - ) + ) { + Text( + text = "Results go here", + modifier = Modifier + .background(color = Color.Green) + .fillMaxWidth() + ) + } } @OptIn(ExperimentalMaterial3Api::class) @@ -275,7 +274,7 @@ private fun ContentToPreview( query: String = "", active: Boolean = false, showBackButton: Boolean = true, - resultState: SearchBarResultState = SearchBarResultState.NotSearching(), + resultState: SearchBarResultState = SearchBarResultState.Empty(), contentPrefix: @Composable ColumnScope.() -> Unit = {}, contentSuffix: @Composable ColumnScope.() -> Unit = {}, resultHandler: @Composable ColumnScope.(String) -> Unit = {}, diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt index 16cd7b813d..1bc1e8a4b5 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt @@ -51,7 +51,7 @@ class RoomSelectPresenter @AssistedInject constructor( var selectedRooms by remember { mutableStateOf(persistentListOf()) } var query by remember { mutableStateOf("") } var isSearchActive by remember { mutableStateOf(false) } - var results: SearchBarResultState> by remember { mutableStateOf(SearchBarResultState.NotSearching()) } + var results: SearchBarResultState> by remember { mutableStateOf(SearchBarResultState.Empty()) } val summaries by client.roomListService.allRooms.summaries.collectAsState() @@ -64,7 +64,7 @@ class RoomSelectPresenter @AssistedInject constructor( results = if (filteredSummaries.isNotEmpty()) { SearchBarResultState.Results(filteredSummaries) } else { - SearchBarResultState.NoResults() + SearchBarResultState.NoResultsFound() } } diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt index d06e0be6d6..8cc082d702 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt @@ -48,7 +48,7 @@ open class RoomSelectStateProvider : PreviewParameterProvider { } private fun aRoomSelectState( - resultState: SearchBarResultState> = SearchBarResultState.NotSearching(), + resultState: SearchBarResultState> = SearchBarResultState.Empty(), query: String = "", isSearchActive: Boolean = false, selectedRooms: ImmutableList = persistentListOf(), diff --git a/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt b/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt index 88ae560bb2..9c6e7a0adb 100644 --- a/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt +++ b/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt @@ -45,11 +45,11 @@ class RoomSelectPresenterTests { }.test { val initialState = awaitItem() assertThat(initialState.selectedRooms).isEmpty() - assertThat(initialState.resultState).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(initialState.resultState).isInstanceOf(SearchBarResultState.Empty::class.java) assertThat(initialState.isSearchActive).isFalse() // Search is run automatically val searchState = awaitItem() - assertThat(searchState.resultState).isInstanceOf(SearchBarResultState.NoResults::class.java) + assertThat(searchState.resultState).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } @@ -85,7 +85,7 @@ class RoomSelectPresenterTests { initialState.eventSink(RoomSelectEvents.UpdateQuery("string not contained")) assertThat(awaitItem().query).isEqualTo("string not contained") - assertThat(awaitItem().resultState).isInstanceOf(SearchBarResultState.NoResults::class.java) + assertThat(awaitItem().resultState).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } diff --git a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt index 03e9952c92..9b0af6d2b0 100644 --- a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt @@ -20,5 +20,5 @@ import kotlinx.coroutines.flow.Flow interface UserRepository { - suspend fun search(query: String): Flow> + fun search(query: String): Flow } diff --git a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt index e67a7af46f..c3f7b7b966 100644 --- a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt @@ -22,3 +22,8 @@ data class UserSearchResult( val matrixUser: MatrixUser, val isUnresolved: Boolean = false, ) + +data class UserSearchResultsState( + val results: List, + val isFetchingSearchResults: Boolean +) 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 index 0714528836..ca06a6e83a 100644 --- 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 @@ -25,6 +25,7 @@ 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 io.element.android.libraries.usersearch.api.UserSearchResult +import io.element.android.libraries.usersearch.api.UserSearchResultsState import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow @@ -36,34 +37,43 @@ class MatrixUserRepository @Inject constructor( private val dataSource: UserListDataSource ) : UserRepository { - override suspend fun search(query: String): Flow> = flow { - // If the search term is a MXID that's not ours, we'll show a 'fake' result for that user, then update it when we get search results. + override fun search(query: String): Flow = flow { val shouldQueryProfile = MatrixPatterns.isUserId(query) && !client.isMe(UserId(query)) - if (shouldQueryProfile) { - emit(listOf(UserSearchResult(MatrixUser(UserId(query))))) + val shouldFetchSearchResults = query.length >= MINIMUM_SEARCH_LENGTH + // If the search term is a MXID that's not ours, we'll show a 'fake' result for that user, then update it when we get search results. + val fakeSearchResult = if (shouldQueryProfile) { + UserSearchResult(MatrixUser(UserId(query)), isUnresolved = true) + } else { + null } + if (shouldQueryProfile || shouldFetchSearchResults) { + emit(UserSearchResultsState(isFetchingSearchResults = shouldFetchSearchResults, results = listOfNotNull(fakeSearchResult))) + } + if (shouldFetchSearchResults) { + val results = fetchSearchResults(query, shouldQueryProfile) + emit(results) + } + } - if (query.length >= MINIMUM_SEARCH_LENGTH) { - // Debounce - delay(DEBOUNCE_TIME_MILLIS) - - val results = dataSource - .search(query, MAXIMUM_SEARCH_RESULTS) - .filter { !client.isMe(it.userId) } - .map { UserSearchResult(it) } - .toMutableList() - - // If the query is another user's MXID and the result doesn't contain that user ID, query the profile information explicitly - if (shouldQueryProfile && results.none { it.matrixUser.userId.value == query }) { - results.add( - 0, - dataSource.getProfile(UserId(query)) - ?.let { UserSearchResult(it) } - ?: UserSearchResult(MatrixUser(UserId(query)), isUnresolved = true)) - } + private suspend fun fetchSearchResults(query: String, shouldQueryProfile: Boolean): UserSearchResultsState { + // Debounce + delay(DEBOUNCE_TIME_MILLIS) + val results = dataSource + .search(query, MAXIMUM_SEARCH_RESULTS) + .filter { !client.isMe(it.userId) } + .map { UserSearchResult(it) } + .toMutableList() - emit(results) + // If the query is another user's MXID and the result doesn't contain that user ID, query the profile information explicitly + if (shouldQueryProfile && results.none { it.matrixUser.userId.value == query }) { + results.add( + 0, + dataSource.getProfile(UserId(query)) + ?.let { UserSearchResult(it) } + ?: UserSearchResult(MatrixUser(UserId(query)), isUnresolved = true)) } + + return UserSearchResultsState(results = results, isFetchingSearchResults = false) } companion object { From 109aea5edec273fae2adbac84e0110049b722a15 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 13:44:59 +0100 Subject: [PATCH 02/10] MatrixUserRepo : fix tests --- .../userlist/DefaultUserListPresenterTests.kt | 38 +++++++++++++------ .../invite/RoomInviteMembersPresenterTest.kt | 13 ++++--- .../usersearch/api/UserRepository.kt | 2 +- .../usersearch/api/UserSearchResult.kt | 4 +- .../usersearch/impl/MatrixUserRepository.kt | 10 ++--- .../usersearch/test/FakeUserRepository.kt | 8 ++-- 6 files changed, 45 insertions(+), 30 deletions(-) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index 7f5eff5c30..8b0caf7d66 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -24,6 +24,7 @@ import io.element.android.libraries.designsystem.theme.components.SearchBarResul import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.usersearch.api.UserSearchResult +import io.element.android.libraries.usersearch.api.UserSearchResults import io.element.android.libraries.usersearch.test.FakeUserRepository import io.element.android.tests.testutils.WarmUpRule import kotlinx.collections.immutable.persistentListOf @@ -136,20 +137,33 @@ class DefaultUserListPresenterTests { skipItems(2) // When the user repository emits a result, it's copied to the state - userRepository.emitResult(listOf(UserSearchResult(aMatrixUser()))) - assertThat(awaitItem().searchResults).isEqualTo( - SearchBarResultState.Results( - persistentListOf(UserSearchResult(aMatrixUser())) - ) + val result = UserSearchResults( + results = listOf(UserSearchResult(aMatrixUser())), + isFetchingSearchResults = false, ) - - // When the user repository emits another result, it replaces the previous value - userRepository.emitResult(aMatrixUserList().map { UserSearchResult(it) }) - assertThat(awaitItem().searchResults).isEqualTo( - SearchBarResultState.Results( - aMatrixUserList().map { UserSearchResult(it) } + userRepository.emitResult(result) + awaitItem().also { state -> + assertThat(state.searchResults).isEqualTo( + SearchBarResultState.Results( + persistentListOf(UserSearchResult(aMatrixUser())) + ) ) + assertThat(state.isFetchingSearchResults).isFalse() + } + // When the user repository emits another result, it replaces the previous value + val newResult = UserSearchResults( + results = aMatrixUserList().map { UserSearchResult(it) }, + isFetchingSearchResults = false, ) + userRepository.emitResult(newResult) + awaitItem().also { state -> + assertThat(state.searchResults).isEqualTo( + SearchBarResultState.Results( + aMatrixUserList().map { UserSearchResult(it) } + ) + ) + assertThat(state.isFetchingSearchResults).isFalse() + } } } @@ -175,7 +189,7 @@ class DefaultUserListPresenterTests { skipItems(2) // When the results list is empty, the state is set to NoResults - userRepository.emitResult(emptyList()) + userRepository.emitResult(UserSearchResults(results = emptyList(), isFetchingSearchResults = false)) assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt index 7ecdccf7f1..3c801d9581 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt @@ -35,6 +35,7 @@ import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.usersearch.api.UserSearchResult +import io.element.android.libraries.usersearch.api.UserSearchResults import io.element.android.libraries.usersearch.test.FakeUserRepository import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.testCoroutineDispatchers @@ -111,7 +112,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(emptyList()) + repository.emitResult(UserSearchResults(results = emptyList())) skipItems(1) val resultState = awaitItem() @@ -137,7 +138,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(aMatrixUserList().map { UserSearchResult(it) }) + repository.emitResult(UserSearchResults(results =aMatrixUserList().map { UserSearchResult(it) })) skipItems(1) val resultState = awaitItem() @@ -189,7 +190,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(aMatrixUserList().map { UserSearchResult(it) }) + repository.emitResult(UserSearchResults(results =aMatrixUserList().map { UserSearchResult(it) })) skipItems(1) val resultState = awaitItem() @@ -250,7 +251,7 @@ internal class RoomInviteMembersPresenterTest { assertThat(repository.providedQuery).isEqualTo("some query") val unresolvedUser = UserSearchResult(aMatrixUser(id = A_USER_ID.value), isUnresolved = true) - repository.emitResult(listOf(unresolvedUser) + aMatrixUserList().map { UserSearchResult(it) }) + repository.emitResult(UserSearchResults(results = listOf(unresolvedUser) + aMatrixUserList().map { UserSearchResult(it) })) skipItems(1) val resultState = awaitItem() @@ -318,7 +319,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult((aMatrixUserList() + selectedUser).map { UserSearchResult(it) }) + repository.emitResult(UserSearchResults(results = (aMatrixUserList() + selectedUser).map { UserSearchResult(it) })) skipItems(2) val resultState = awaitItem() @@ -358,7 +359,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult((aMatrixUserList() + selectedUser).map { UserSearchResult(it) }) + repository.emitResult(UserSearchResults(results =(aMatrixUserList() + selectedUser).map { UserSearchResult(it) })) skipItems(2) // And then a user is toggled diff --git a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt index 9b0af6d2b0..4108788cff 100644 --- a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt @@ -20,5 +20,5 @@ import kotlinx.coroutines.flow.Flow interface UserRepository { - fun search(query: String): Flow + fun search(query: String): Flow } diff --git a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt index c3f7b7b966..95ede55f0c 100644 --- a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt @@ -23,7 +23,7 @@ data class UserSearchResult( val isUnresolved: Boolean = false, ) -data class UserSearchResultsState( +data class UserSearchResults( val results: List, - val isFetchingSearchResults: Boolean + val isFetchingSearchResults: Boolean = false, ) 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 index ca06a6e83a..431f452cd9 100644 --- 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 @@ -25,7 +25,7 @@ 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 io.element.android.libraries.usersearch.api.UserSearchResult -import io.element.android.libraries.usersearch.api.UserSearchResultsState +import io.element.android.libraries.usersearch.api.UserSearchResults import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow @@ -37,7 +37,7 @@ class MatrixUserRepository @Inject constructor( private val dataSource: UserListDataSource ) : UserRepository { - override fun search(query: String): Flow = flow { + override fun search(query: String): Flow = flow { val shouldQueryProfile = MatrixPatterns.isUserId(query) && !client.isMe(UserId(query)) val shouldFetchSearchResults = query.length >= MINIMUM_SEARCH_LENGTH // If the search term is a MXID that's not ours, we'll show a 'fake' result for that user, then update it when we get search results. @@ -47,7 +47,7 @@ class MatrixUserRepository @Inject constructor( null } if (shouldQueryProfile || shouldFetchSearchResults) { - emit(UserSearchResultsState(isFetchingSearchResults = shouldFetchSearchResults, results = listOfNotNull(fakeSearchResult))) + emit(UserSearchResults(isFetchingSearchResults = shouldFetchSearchResults, results = listOfNotNull(fakeSearchResult))) } if (shouldFetchSearchResults) { val results = fetchSearchResults(query, shouldQueryProfile) @@ -55,7 +55,7 @@ class MatrixUserRepository @Inject constructor( } } - private suspend fun fetchSearchResults(query: String, shouldQueryProfile: Boolean): UserSearchResultsState { + private suspend fun fetchSearchResults(query: String, shouldQueryProfile: Boolean): UserSearchResults { // Debounce delay(DEBOUNCE_TIME_MILLIS) val results = dataSource @@ -73,7 +73,7 @@ class MatrixUserRepository @Inject constructor( ?: UserSearchResult(MatrixUser(UserId(query)), isUnresolved = true)) } - return UserSearchResultsState(results = results, isFetchingSearchResults = false) + return UserSearchResults(results = results, isFetchingSearchResults = false) } companion object { 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 index 0911d86b36..e21c48a48b 100644 --- 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 @@ -17,7 +17,7 @@ package io.element.android.libraries.usersearch.test import io.element.android.libraries.usersearch.api.UserRepository -import io.element.android.libraries.usersearch.api.UserSearchResult +import io.element.android.libraries.usersearch.api.UserSearchResults import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow @@ -26,14 +26,14 @@ class FakeUserRepository : UserRepository { var providedQuery: String? = null private set - private val flow = MutableSharedFlow>() + private val flow = MutableSharedFlow() - override suspend fun search(query: String): Flow> { + override fun search(query: String): Flow { providedQuery = query return flow } - suspend fun emitResult(result: List) { + suspend fun emitResult(result: UserSearchResults) { flow.emit(result) } From 8842d53038c9a8ec38aeb5ac616a901709b5410e Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 13:53:02 +0100 Subject: [PATCH 03/10] RoomInviteMembers : add small tests --- .../invite/RoomInviteMembersStateProvider.kt | 11 +++++++++ .../invite/RoomInviteMembersPresenterTest.kt | 23 +++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt index c9ae8a606a..e7b0ba3397 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt @@ -64,6 +64,17 @@ internal class RoomInviteMembersStateProvider : PreviewParameterProvider + assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(state.isFetchingSearchResults).isTrue() + } + repository.emitResult(UserSearchResults(results = emptyList(), isFetchingSearchResults = false)) + consumeItemsUntilPredicate { !it.isFetchingSearchResults }.last().also { state -> + assertThat(state.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) + assertThat(state.isFetchingSearchResults).isFalse() + } } } From 96d02a19a9d322cd5b3517bf06acd61155d8efb2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 13:56:59 +0100 Subject: [PATCH 04/10] Fix detekt --- .../roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt index f2a875b956..fb36722f59 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt @@ -38,7 +38,6 @@ import io.element.android.libraries.usersearch.api.UserSearchResult import io.element.android.libraries.usersearch.api.UserSearchResults import io.element.android.libraries.usersearch.test.FakeUserRepository import io.element.android.tests.testutils.WarmUpRule -import io.element.android.tests.testutils.awaitLastSequentialItem import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.collections.immutable.ImmutableList From 00a96e34441402b2d2769b6115999abc29d830e6 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 14:00:25 +0100 Subject: [PATCH 05/10] Add changelog --- changelog.d/2172.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/2172.bugfix diff --git a/changelog.d/2172.bugfix b/changelog.d/2172.bugfix new file mode 100644 index 0000000000..14f34666b9 --- /dev/null +++ b/changelog.d/2172.bugfix @@ -0,0 +1 @@ +Fix no indication that user list is loading when inviting to room. From fae247d38d9f13e69e0e042e03eb5912d6cddd0f Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 5 Jan 2024 13:10:32 +0000 Subject: [PATCH 06/10] Update screenshots --- ...stView_null_UserListView-Day-2_3_null_8,NEXUS_5,1.0,en].png | 3 +++ ...View_null_UserListView-Night-2_4_null_8,NEXUS_5,1.0,en].png | 3 +++ ...s_null_RoomInviteMembers-Day-1_2_null_7,NEXUS_5,1.0,en].png | 3 +++ ...null_RoomInviteMembers-Night-1_3_null_7,NEXUS_5,1.0,en].png | 3 +++ ...hviews_SearchBarActiveNoneQuery_0_null,NEXUS_5,1.0,en].png} | 0 5 files changed, 12 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Day-2_3_null_8,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Night-2_4_null_8,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Day-1_2_null_7,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Night-1_3_null_7,NEXUS_5,1.0,en].png rename tests/uitests/src/test/snapshots/images/{ui_S_t[l.designsystem.theme.components_SearchBarActiveEmptyQuery_null_Searchviews_SearchBarActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png => ui_S_t[l.designsystem.theme.components_SearchBarActiveNoneQuery_null_Searchviews_SearchBarActiveNoneQuery_0_null,NEXUS_5,1.0,en].png} (100%) diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Day-2_3_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Day-2_3_null_8,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..d81d496d15 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Day-2_3_null_8,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4731f36d3ee1331c0767ad27d4286feca266deabfd55960a89b0e823925b30f2 +size 7646 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Night-2_4_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Night-2_4_null_8,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..573ab912c2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.createroom.impl.components_UserListView_null_UserListView-Night-2_4_null_8,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae2119fa8d67dc6787a3cf86ada1259a4ff941d1d9a55936d5ee84e71e42ac72 +size 7217 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Day-1_2_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Day-1_2_null_7,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..d7964f155e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Day-1_2_null_7,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62baff22557bc9b130c87b64b45a53b0209390ecfe11d16e1b31868a5a264cf3 +size 31956 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Night-1_3_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Night-1_3_null_7,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..ee60e0fc83 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.invite_RoomInviteMembers_null_RoomInviteMembers-Night-1_3_null_7,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b5645d81ef1ed73241ec2183f8d5b4cf4cd7510fc8804a26719842e8ed4bc7f +size 29891 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_SearchBarActiveEmptyQuery_null_Searchviews_SearchBarActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_SearchBarActiveNoneQuery_null_Searchviews_SearchBarActiveNoneQuery_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_SearchBarActiveEmptyQuery_null_Searchviews_SearchBarActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_SearchBarActiveNoneQuery_null_Searchviews_SearchBarActiveNoneQuery_0_null,NEXUS_5,1.0,en].png From 96302da97c22e18e7848237886452e86857bdce7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 15:12:31 +0100 Subject: [PATCH 07/10] Fix MatrixUserRepositoryTest --- .../usersearch/impl/MatrixUserRepository.kt | 2 +- .../impl/MatrixUserRepositoryTest.kt | 45 ++++++++++++++----- 2 files changed, 34 insertions(+), 13 deletions(-) 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 index 431f452cd9..02a03f8be4 100644 --- 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 @@ -42,7 +42,7 @@ class MatrixUserRepository @Inject constructor( val shouldFetchSearchResults = query.length >= MINIMUM_SEARCH_LENGTH // If the search term is a MXID that's not ours, we'll show a 'fake' result for that user, then update it when we get search results. val fakeSearchResult = if (shouldQueryProfile) { - UserSearchResult(MatrixUser(UserId(query)), isUnresolved = true) + UserSearchResult(MatrixUser(UserId(query))) } else { null } 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 index 621274bef5..0ddf58e8aa 100644 --- 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 @@ -54,7 +54,14 @@ internal class MatrixUserRepositoryTest { val result = repository.search("some query") result.test { - assertThat(awaitItem()).isEmpty() + awaitItem().also { + assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.results).isEmpty() + } + awaitItem().also { + assertThat(it.isFetchingSearchResults).isFalse() + assertThat(it.results).isEmpty() + } awaitComplete() } } @@ -68,7 +75,14 @@ internal class MatrixUserRepositoryTest { val result = repository.search("some query") result.test { - assertThat(awaitItem()).isEqualTo(aMatrixUserList().toUserSearchResults()) + awaitItem().also { + assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.results).isEmpty() + } + awaitItem().also { + assertThat(it.isFetchingSearchResults).isFalse() + assertThat(it.results).isEqualTo(aMatrixUserList().toUserSearchResults()) + } awaitComplete() } } @@ -81,9 +95,11 @@ internal class MatrixUserRepositoryTest { val result = repository.search(A_USER_ID.value) result.test { - assertThat(awaitItem()).isEqualTo(listOf(placeholderResult())) - skipItems(1) - awaitComplete() + awaitItem().also { + assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.results).isEqualTo(listOf(placeholderResult())) + } + cancelAndConsumeRemainingEvents() } } @@ -95,8 +111,11 @@ internal class MatrixUserRepositoryTest { val result = repository.search(SESSION_ID.value) result.test { - assertThat(awaitItem()).isEmpty() - awaitComplete() + awaitItem().also { + assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.results).isEmpty() + } + cancelAndConsumeRemainingEvents() } } @@ -110,7 +129,8 @@ internal class MatrixUserRepositoryTest { val result = repository.search("some text") result.test { - assertThat(awaitItem()).isEqualTo(aMatrixUserList().toUserSearchResults()) + skipItems(1) + assertThat(awaitItem().results).isEqualTo(aMatrixUserList().toUserSearchResults()) awaitComplete() } } @@ -126,7 +146,7 @@ internal class MatrixUserRepositoryTest { result.test { skipItems(1) - assertThat(awaitItem()).isEqualTo(searchResults.toUserSearchResults()) + assertThat(awaitItem().results).isEqualTo(searchResults.toUserSearchResults()) awaitComplete() } } @@ -145,7 +165,7 @@ internal class MatrixUserRepositoryTest { result.test { skipItems(1) - assertThat(awaitItem()).isEqualTo((listOf(userProfile) + searchResults).toUserSearchResults()) + assertThat(awaitItem().results).isEqualTo((listOf(userProfile) + searchResults).toUserSearchResults()) awaitComplete() } } @@ -163,7 +183,8 @@ internal class MatrixUserRepositoryTest { val result = repository.search(SESSION_ID.value) result.test { - assertThat(awaitItem()).isEqualTo(searchResults.toUserSearchResults()) + skipItems(1) + assertThat(awaitItem().results).isEqualTo(searchResults.toUserSearchResults()) awaitComplete() } } @@ -181,7 +202,7 @@ internal class MatrixUserRepositoryTest { result.test { skipItems(1) - assertThat(awaitItem()).isEqualTo(listOf(placeholderResult(isUnresolved = true)) + searchResults.toUserSearchResults()) + assertThat(awaitItem().results).isEqualTo(listOf(placeholderResult(isUnresolved = true)) + searchResults.toUserSearchResults()) awaitComplete() } } From 9fcc50e08ab68d042e1696c656f366ea8e780d33 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 15:28:18 +0100 Subject: [PATCH 08/10] Rename UserSearchResults as UserSearchResultState --- .../userlist/DefaultUserListPresenterTests.kt | 12 +++--- .../invite/RoomInviteMembersPresenterTest.kt | 38 +++++++++++++++---- .../usersearch/api/UserRepository.kt | 2 +- .../usersearch/api/UserSearchResult.kt | 4 +- .../usersearch/impl/MatrixUserRepository.kt | 10 ++--- .../usersearch/test/FakeUserRepository.kt | 10 ++--- 6 files changed, 49 insertions(+), 27 deletions(-) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index 8b0caf7d66..219a252b7b 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -24,7 +24,7 @@ import io.element.android.libraries.designsystem.theme.components.SearchBarResul import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.usersearch.api.UserSearchResult -import io.element.android.libraries.usersearch.api.UserSearchResults +import io.element.android.libraries.usersearch.api.UserSearchResultState import io.element.android.libraries.usersearch.test.FakeUserRepository import io.element.android.tests.testutils.WarmUpRule import kotlinx.collections.immutable.persistentListOf @@ -137,11 +137,11 @@ class DefaultUserListPresenterTests { skipItems(2) // When the user repository emits a result, it's copied to the state - val result = UserSearchResults( + val result = UserSearchResultState( results = listOf(UserSearchResult(aMatrixUser())), isFetchingSearchResults = false, ) - userRepository.emitResult(result) + userRepository.emitState(result) awaitItem().also { state -> assertThat(state.searchResults).isEqualTo( SearchBarResultState.Results( @@ -151,11 +151,11 @@ class DefaultUserListPresenterTests { assertThat(state.isFetchingSearchResults).isFalse() } // When the user repository emits another result, it replaces the previous value - val newResult = UserSearchResults( + val newResult = UserSearchResultState( results = aMatrixUserList().map { UserSearchResult(it) }, isFetchingSearchResults = false, ) - userRepository.emitResult(newResult) + userRepository.emitState(newResult) awaitItem().also { state -> assertThat(state.searchResults).isEqualTo( SearchBarResultState.Results( @@ -189,7 +189,7 @@ class DefaultUserListPresenterTests { skipItems(2) // When the results list is empty, the state is set to NoResults - userRepository.emitResult(UserSearchResults(results = emptyList(), isFetchingSearchResults = false)) + userRepository.emitState(UserSearchResultState(results = emptyList(), isFetchingSearchResults = false)) assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt index fb36722f59..60ba78c725 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt @@ -29,13 +29,14 @@ import io.element.android.libraries.designsystem.theme.components.SearchBarResul import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState +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_ID_2 import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.usersearch.api.UserSearchResult -import io.element.android.libraries.usersearch.api.UserSearchResults +import io.element.android.libraries.usersearch.api.UserSearchResultState import io.element.android.libraries.usersearch.test.FakeUserRepository import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate @@ -109,12 +110,12 @@ internal class RoomInviteMembersPresenterTest { val initialState = awaitItem() initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query")) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(UserSearchResults(results = emptyList(), isFetchingSearchResults = true)) + repository.emitState(UserSearchResultState(results = emptyList(), isFetchingSearchResults = true)) consumeItemsUntilPredicate { it.isFetchingSearchResults }.last().also { state -> assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) assertThat(state.isFetchingSearchResults).isTrue() } - repository.emitResult(UserSearchResults(results = emptyList(), isFetchingSearchResults = false)) + repository.emitState(results = emptyList(), isFetchingSearchResults = false) consumeItemsUntilPredicate { !it.isFetchingSearchResults }.last().also { state -> assertThat(state.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) assertThat(state.isFetchingSearchResults).isFalse() @@ -140,7 +141,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(UserSearchResults(results =aMatrixUserList().map { UserSearchResult(it) })) + repository.emitStateWithUsers(users = aMatrixUserList()) skipItems(1) val resultState = awaitItem() @@ -192,7 +193,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(UserSearchResults(results =aMatrixUserList().map { UserSearchResult(it) })) + repository.emitStateWithUsers(users = aMatrixUserList()) skipItems(1) val resultState = awaitItem() @@ -253,7 +254,7 @@ internal class RoomInviteMembersPresenterTest { assertThat(repository.providedQuery).isEqualTo("some query") val unresolvedUser = UserSearchResult(aMatrixUser(id = A_USER_ID.value), isUnresolved = true) - repository.emitResult(UserSearchResults(results = listOf(unresolvedUser) + aMatrixUserList().map { UserSearchResult(it) })) + repository.emitState(listOf(unresolvedUser) + aMatrixUserList().map { UserSearchResult(it) }) skipItems(1) val resultState = awaitItem() @@ -321,7 +322,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(UserSearchResults(results = (aMatrixUserList() + selectedUser).map { UserSearchResult(it) })) + repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser) skipItems(2) val resultState = awaitItem() @@ -361,7 +362,7 @@ internal class RoomInviteMembersPresenterTest { skipItems(1) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitResult(UserSearchResults(results =(aMatrixUserList() + selectedUser).map { UserSearchResult(it) })) + repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser) skipItems(2) // And then a user is toggled @@ -384,6 +385,27 @@ internal class RoomInviteMembersPresenterTest { } } + private suspend fun FakeUserRepository.emitStateWithUsers( + users: List, + isFetchingSearchResults: Boolean = false + ) { + emitState( + results = users.map { UserSearchResult(it) }, + isFetchingSearchResults = isFetchingSearchResults, + ) + } + + private suspend fun FakeUserRepository.emitState( + results: List, + isFetchingSearchResults: Boolean = false + ) { + val state = UserSearchResultState( + results = results, + isFetchingSearchResults = isFetchingSearchResults + ) + emitState(state) + } + private fun TestScope.createDataSource( matrixRoom: MatrixRoom = aMatrixRoom().apply { givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList())) diff --git a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt index 4108788cff..ed019fc5a5 100644 --- a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt @@ -20,5 +20,5 @@ import kotlinx.coroutines.flow.Flow interface UserRepository { - fun search(query: String): Flow + fun search(query: String): Flow } diff --git a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt index 95ede55f0c..ebdfb7fedb 100644 --- a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt @@ -23,7 +23,7 @@ data class UserSearchResult( val isUnresolved: Boolean = false, ) -data class UserSearchResults( +data class UserSearchResultState( val results: List, - val isFetchingSearchResults: Boolean = false, + val isFetchingSearchResults: Boolean, ) 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 index 02a03f8be4..7ac3ec8380 100644 --- 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 @@ -25,7 +25,7 @@ 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 io.element.android.libraries.usersearch.api.UserSearchResult -import io.element.android.libraries.usersearch.api.UserSearchResults +import io.element.android.libraries.usersearch.api.UserSearchResultState import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow @@ -37,7 +37,7 @@ class MatrixUserRepository @Inject constructor( private val dataSource: UserListDataSource ) : UserRepository { - override fun search(query: String): Flow = flow { + override fun search(query: String): Flow = flow { val shouldQueryProfile = MatrixPatterns.isUserId(query) && !client.isMe(UserId(query)) val shouldFetchSearchResults = query.length >= MINIMUM_SEARCH_LENGTH // If the search term is a MXID that's not ours, we'll show a 'fake' result for that user, then update it when we get search results. @@ -47,7 +47,7 @@ class MatrixUserRepository @Inject constructor( null } if (shouldQueryProfile || shouldFetchSearchResults) { - emit(UserSearchResults(isFetchingSearchResults = shouldFetchSearchResults, results = listOfNotNull(fakeSearchResult))) + emit(UserSearchResultState(isFetchingSearchResults = shouldFetchSearchResults, results = listOfNotNull(fakeSearchResult))) } if (shouldFetchSearchResults) { val results = fetchSearchResults(query, shouldQueryProfile) @@ -55,7 +55,7 @@ class MatrixUserRepository @Inject constructor( } } - private suspend fun fetchSearchResults(query: String, shouldQueryProfile: Boolean): UserSearchResults { + private suspend fun fetchSearchResults(query: String, shouldQueryProfile: Boolean): UserSearchResultState { // Debounce delay(DEBOUNCE_TIME_MILLIS) val results = dataSource @@ -73,7 +73,7 @@ class MatrixUserRepository @Inject constructor( ?: UserSearchResult(MatrixUser(UserId(query)), isUnresolved = true)) } - return UserSearchResults(results = results, isFetchingSearchResults = false) + return UserSearchResultState(results = results, isFetchingSearchResults = false) } companion object { 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 index e21c48a48b..3ca2320a26 100644 --- 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 @@ -17,7 +17,7 @@ package io.element.android.libraries.usersearch.test import io.element.android.libraries.usersearch.api.UserRepository -import io.element.android.libraries.usersearch.api.UserSearchResults +import io.element.android.libraries.usersearch.api.UserSearchResultState import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow @@ -26,15 +26,15 @@ class FakeUserRepository : UserRepository { var providedQuery: String? = null private set - private val flow = MutableSharedFlow() + private val flow = MutableSharedFlow() - override fun search(query: String): Flow { + override fun search(query: String): Flow { providedQuery = query return flow } - suspend fun emitResult(result: UserSearchResults) { - flow.emit(result) + suspend fun emitState(state: UserSearchResultState) { + flow.emit(state) } } From a0ba83c863c5260f1b2fe52c52e1a38615afb94f Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 15:40:02 +0100 Subject: [PATCH 09/10] Rename SearchBarResultState.Empty to SearchBarResultState.Initial --- .../createroom/impl/userlist/DefaultUserListPresenter.kt | 6 +++--- .../createroom/impl/userlist/UserListStateProvider.kt | 2 +- .../impl/userlist/DefaultUserListPresenterTests.kt | 8 ++++---- .../roomdetails/impl/invite/RoomInviteMembersPresenter.kt | 6 +++--- .../impl/invite/RoomInviteMembersStateProvider.kt | 2 +- .../roomdetails/impl/members/RoomMemberListPresenter.kt | 4 ++-- .../impl/members/RoomMemberListStateProvider.kt | 2 +- .../impl/invite/RoomInviteMembersPresenterTest.kt | 4 ++-- .../roomdetails/members/RoomMemberListPresenterTests.kt | 2 +- .../libraries/designsystem/theme/components/SearchBar.kt | 6 +++--- .../libraries/roomselect/impl/RoomSelectPresenter.kt | 2 +- .../libraries/roomselect/impl/RoomSelectStateProvider.kt | 2 +- .../libraries/roomselect/impl/RoomSelectPresenterTests.kt | 2 +- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt index 19a858dd78..2157f0ce80 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt @@ -59,17 +59,17 @@ class DefaultUserListPresenter @AssistedInject constructor( val selectedUsers by userListDataStore.selectedUsers().collectAsState(emptyList()) var searchQuery by rememberSaveable { mutableStateOf("") } var searchResults: SearchBarResultState> by remember { - mutableStateOf(SearchBarResultState.Empty()) + mutableStateOf(SearchBarResultState.Initial()) } var isFetchingSearchResults by remember { mutableStateOf(false) } LaunchedEffect(searchQuery) { - searchResults = SearchBarResultState.Empty() + searchResults = SearchBarResultState.Initial() isFetchingSearchResults = false userRepository.search(searchQuery).onEach { state -> isFetchingSearchResults = state.isFetchingSearchResults searchResults = when { - state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Empty() + state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Initial() state.results.isEmpty() && !state.isFetchingSearchResults -> SearchBarResultState.NoResultsFound() else -> SearchBarResultState.Results(state.results.toImmutableList()) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt index ec7fba57b5..f50ed6c5ab 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt @@ -60,7 +60,7 @@ open class UserListStateProvider : PreviewParameterProvider { fun aUserListState() = UserListState( isSearchActive = false, searchQuery = "", - searchResults = SearchBarResultState.Empty(), + searchResults = SearchBarResultState.Initial(), selectedUsers = persistentListOf(), selectionMode = SelectionMode.Single, isFetchingSearchResults = false, diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index 219a252b7b..3c1e5c44b5 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -56,7 +56,7 @@ class DefaultUserListPresenterTests { assertThat(initialState.isMultiSelectionEnabled).isFalse() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) } } @@ -77,7 +77,7 @@ class DefaultUserListPresenterTests { assertThat(initialState.isMultiSelectionEnabled).isTrue() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) } } @@ -132,7 +132,7 @@ class DefaultUserListPresenterTests { val initialState = awaitItem() initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) assertThat(userRepository.providedQuery).isEqualTo("alice") skipItems(2) @@ -184,7 +184,7 @@ class DefaultUserListPresenterTests { val initialState = awaitItem() initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) assertThat(userRepository.providedQuery).isEqualTo("alice") skipItems(2) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt index a880afe306..0065f1c5e2 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt @@ -52,7 +52,7 @@ class RoomInviteMembersPresenter @Inject constructor( override fun present(): RoomInviteMembersState { val roomMembers = remember { mutableStateOf>>(AsyncData.Loading()) } val selectedUsers = remember { mutableStateOf>(persistentListOf()) } - val searchResults = remember { mutableStateOf>>(SearchBarResultState.Empty()) } + val searchResults = remember { mutableStateOf>>(SearchBarResultState.Initial()) } var searchQuery by rememberSaveable { mutableStateOf("") } var searchActive by rememberSaveable { mutableStateOf(false) } var isFetchingSearchResults = rememberSaveable { mutableStateOf(false) } @@ -129,14 +129,14 @@ class RoomInviteMembersPresenter @Inject constructor( isFetchingSearchResults: MutableState, searchQuery: String, ) = withContext(coroutineDispatchers.io) { - searchResults.value = SearchBarResultState.Empty() + searchResults.value = SearchBarResultState.Initial() isFetchingSearchResults.value = false val joinedMembers = roomMembers.value.dataOrNull().orEmpty() userRepository.search(searchQuery).onEach { state -> isFetchingSearchResults.value = state.isFetchingSearchResults searchResults.value = when { - state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Empty() + state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Initial() state.results.isEmpty() && !state.isFetchingSearchResults -> SearchBarResultState.NoResultsFound() else -> SearchBarResultState.Results(state.results.map { result -> val existingMembership = joinedMembers.firstOrNull { j -> j.userId == result.matrixUser.userId }?.membership diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt index e7b0ba3397..5e43492a17 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt @@ -81,7 +81,7 @@ internal class RoomInviteMembersStateProvider : PreviewParameterProvider> = SearchBarResultState.Empty(), + searchResults: SearchBarResultState> = SearchBarResultState.Initial(), selectedUsers: ImmutableList = persistentListOf(), isSearchActive: Boolean = false, isFetchingSearchResults: Boolean = false, 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 92a029c8f3..0f66f7db4c 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 @@ -47,7 +47,7 @@ class RoomMemberListPresenter @Inject constructor( var roomMembers by remember { mutableStateOf>(AsyncData.Loading()) } var searchQuery by rememberSaveable { mutableStateOf("") } var searchResults by remember { - mutableStateOf>(SearchBarResultState.Empty()) + mutableStateOf>(SearchBarResultState.Initial()) } var isSearchActive by rememberSaveable { mutableStateOf(false) } @@ -71,7 +71,7 @@ class RoomMemberListPresenter @Inject constructor( LaunchedEffect(searchQuery) { withContext(coroutineDispatchers.io) { searchResults = if (searchQuery.isEmpty()) { - SearchBarResultState.Empty() + SearchBarResultState.Initial() } else { val results = roomMemberListDataSource.search(searchQuery).groupBy { it.membership } if (results.isEmpty()) SearchBarResultState.NoResultsFound() 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 01e29832eb..5d9549808c 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 @@ -60,7 +60,7 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider = AsyncData.Uninitialized, - searchResults: SearchBarResultState = SearchBarResultState.Empty(), + searchResults: SearchBarResultState = SearchBarResultState.Initial(), ) = RoomMemberListState( roomMembers = roomMembers, searchQuery = "", diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt index 60ba78c725..fbd34ad408 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt @@ -66,7 +66,7 @@ internal class RoomInviteMembersPresenterTest { }.test { val initialState = awaitItem() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.canInvite).isFalse() assertThat(initialState.searchQuery).isEmpty() @@ -112,7 +112,7 @@ internal class RoomInviteMembersPresenterTest { assertThat(repository.providedQuery).isEqualTo("some query") repository.emitState(UserSearchResultState(results = emptyList(), isFetchingSearchResults = true)) consumeItemsUntilPredicate { it.isFetchingSearchResults }.last().also { state -> - assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) assertThat(state.isFetchingSearchResults).isTrue() } repository.emitState(results = emptyList(), isFetchingSearchResults = false) 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 982c9f83f0..f08976a8cb 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 @@ -55,7 +55,7 @@ class RoomMemberListPresenterTests { val initialState = awaitItem() assertThat(initialState.roomMembers).isInstanceOf(AsyncData.Loading::class.java) assertThat(initialState.searchQuery).isEmpty() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) assertThat(initialState.isSearchActive).isFalse() val loadedState = awaitItem() assertThat(loadedState.roomMembers).isInstanceOf(AsyncData.Success::class.java) 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 c53fbb6cb6..d32d7de685 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 @@ -59,7 +59,7 @@ fun SearchBar( modifier: Modifier = Modifier, enabled: Boolean = true, showBackButton: Boolean = true, - resultState: SearchBarResultState = SearchBarResultState.Empty(), + resultState: SearchBarResultState = SearchBarResultState.Initial(), shape: Shape = SearchBarDefaults.inputFieldShape, tonalElevation: Dp = SearchBarDefaults.TonalElevation, windowInsets: WindowInsets = SearchBarDefaults.windowInsets, @@ -184,7 +184,7 @@ object ElementSearchBarDefaults { @Immutable sealed interface SearchBarResultState { /** No search results are available yet (e.g. because the user hasn't entered a search term). */ - class Empty : SearchBarResultState + class Initial : SearchBarResultState /** The search has completed, but no results were found. */ class NoResultsFound : SearchBarResultState @@ -274,7 +274,7 @@ private fun ContentToPreview( query: String = "", active: Boolean = false, showBackButton: Boolean = true, - resultState: SearchBarResultState = SearchBarResultState.Empty(), + resultState: SearchBarResultState = SearchBarResultState.Initial(), contentPrefix: @Composable ColumnScope.() -> Unit = {}, contentSuffix: @Composable ColumnScope.() -> Unit = {}, resultHandler: @Composable ColumnScope.(String) -> Unit = {}, diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt index 1bc1e8a4b5..8535031c16 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenter.kt @@ -51,7 +51,7 @@ class RoomSelectPresenter @AssistedInject constructor( var selectedRooms by remember { mutableStateOf(persistentListOf()) } var query by remember { mutableStateOf("") } var isSearchActive by remember { mutableStateOf(false) } - var results: SearchBarResultState> by remember { mutableStateOf(SearchBarResultState.Empty()) } + var results: SearchBarResultState> by remember { mutableStateOf(SearchBarResultState.Initial()) } val summaries by client.roomListService.allRooms.summaries.collectAsState() diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt index 8cc082d702..032dc4a8d0 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectStateProvider.kt @@ -48,7 +48,7 @@ open class RoomSelectStateProvider : PreviewParameterProvider { } private fun aRoomSelectState( - resultState: SearchBarResultState> = SearchBarResultState.Empty(), + resultState: SearchBarResultState> = SearchBarResultState.Initial(), query: String = "", isSearchActive: Boolean = false, selectedRooms: ImmutableList = persistentListOf(), diff --git a/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt b/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt index 9c6e7a0adb..ec85358ebd 100644 --- a/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt +++ b/libraries/roomselect/impl/src/test/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectPresenterTests.kt @@ -45,7 +45,7 @@ class RoomSelectPresenterTests { }.test { val initialState = awaitItem() assertThat(initialState.selectedRooms).isEmpty() - assertThat(initialState.resultState).isInstanceOf(SearchBarResultState.Empty::class.java) + assertThat(initialState.resultState).isInstanceOf(SearchBarResultState.Initial::class.java) assertThat(initialState.isSearchActive).isFalse() // Search is run automatically val searchState = awaitItem() From 44b6a97c9027d840224e825aa0c73a070a67df11 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Jan 2024 15:54:50 +0100 Subject: [PATCH 10/10] Rename isFetchingSearchResults to showSearchLoader --- .../impl/components/SearchUserBar.kt | 4 ++-- .../impl/components/UserListView.kt | 2 +- .../impl/userlist/DefaultUserListPresenter.kt | 12 +++++------ .../createroom/impl/userlist/UserListState.kt | 2 +- .../impl/userlist/UserListStateProvider.kt | 2 +- .../userlist/DefaultUserListPresenterTests.kt | 10 +++++----- .../impl/invite/RoomInviteMembersPresenter.kt | 16 +++++++-------- .../impl/invite/RoomInviteMembersState.kt | 2 +- .../invite/RoomInviteMembersStateProvider.kt | 6 +++--- .../impl/invite/RoomInviteMembersView.kt | 6 +++--- .../invite/RoomInviteMembersPresenterTest.kt | 20 +++++++++---------- .../usersearch/api/UserSearchResult.kt | 2 +- .../usersearch/impl/MatrixUserRepository.kt | 4 ++-- .../impl/MatrixUserRepositoryTest.kt | 12 +++++------ 14 files changed, 50 insertions(+), 50 deletions(-) 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 index a9292e5a24..c047a60018 100644 --- 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 @@ -50,7 +50,7 @@ import kotlinx.collections.immutable.ImmutableList fun SearchUserBar( query: String, state: SearchBarResultState>, - isSearching: Boolean, + showLoader: Boolean, selectedUsers: ImmutableList, active: Boolean, isMultiSelectionEnabled: Boolean, @@ -102,7 +102,7 @@ fun SearchUserBar( } }, contentSuffix = { - if (isSearching) { + if (showLoader) { AsyncLoading() } }, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt index 8d5a3690db..b13d682250 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt @@ -48,7 +48,7 @@ fun UserListView( state = state.searchResults, selectedUsers = state.selectedUsers, active = state.isSearchActive, - isSearching = state.isFetchingSearchResults, + showLoader = state.showSearchLoader, isMultiSelectionEnabled = state.isMultiSelectionEnabled, showBackButton = showBackButton, onActiveChanged = { state.eventSink(UserListEvents.OnSearchActiveChanged(it)) }, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt index 2157f0ce80..a843570fe5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt @@ -61,16 +61,16 @@ class DefaultUserListPresenter @AssistedInject constructor( var searchResults: SearchBarResultState> by remember { mutableStateOf(SearchBarResultState.Initial()) } - var isFetchingSearchResults by remember { mutableStateOf(false) } + var showSearchLoader by remember { mutableStateOf(false) } LaunchedEffect(searchQuery) { searchResults = SearchBarResultState.Initial() - isFetchingSearchResults = false + showSearchLoader = false userRepository.search(searchQuery).onEach { state -> - isFetchingSearchResults = state.isFetchingSearchResults + showSearchLoader = state.isSearching searchResults = when { - state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Initial() - state.results.isEmpty() && !state.isFetchingSearchResults -> SearchBarResultState.NoResultsFound() + state.results.isEmpty() && state.isSearching -> SearchBarResultState.Initial() + state.results.isEmpty() && !state.isSearching -> SearchBarResultState.NoResultsFound() else -> SearchBarResultState.Results(state.results.toImmutableList()) } }.launchIn(this) @@ -81,7 +81,7 @@ class DefaultUserListPresenter @AssistedInject constructor( searchResults = searchResults, selectedUsers = selectedUsers.toImmutableList(), isSearchActive = isSearchActive, - isFetchingSearchResults = isFetchingSearchResults, + showSearchLoader = showSearchLoader, selectionMode = args.selectionMode, eventSink = { event -> when (event) { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt index 5d59735e46..a27191881e 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt @@ -24,7 +24,7 @@ import kotlinx.collections.immutable.ImmutableList data class UserListState( val searchQuery: String, val searchResults: SearchBarResultState>, - val isFetchingSearchResults: Boolean, + val showSearchLoader: Boolean, val selectedUsers: ImmutableList, val isSearchActive: Boolean, val selectionMode: SelectionMode, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt index f50ed6c5ab..4685bb47e3 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt @@ -63,7 +63,7 @@ fun aUserListState() = UserListState( searchResults = SearchBarResultState.Initial(), selectedUsers = persistentListOf(), selectionMode = SelectionMode.Single, - isFetchingSearchResults = false, + showSearchLoader = false, eventSink = {} ) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index 3c1e5c44b5..d1c82120b9 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -139,7 +139,7 @@ class DefaultUserListPresenterTests { // When the user repository emits a result, it's copied to the state val result = UserSearchResultState( results = listOf(UserSearchResult(aMatrixUser())), - isFetchingSearchResults = false, + isSearching = false, ) userRepository.emitState(result) awaitItem().also { state -> @@ -148,12 +148,12 @@ class DefaultUserListPresenterTests { persistentListOf(UserSearchResult(aMatrixUser())) ) ) - assertThat(state.isFetchingSearchResults).isFalse() + assertThat(state.showSearchLoader).isFalse() } // When the user repository emits another result, it replaces the previous value val newResult = UserSearchResultState( results = aMatrixUserList().map { UserSearchResult(it) }, - isFetchingSearchResults = false, + isSearching = false, ) userRepository.emitState(newResult) awaitItem().also { state -> @@ -162,7 +162,7 @@ class DefaultUserListPresenterTests { aMatrixUserList().map { UserSearchResult(it) } ) ) - assertThat(state.isFetchingSearchResults).isFalse() + assertThat(state.showSearchLoader).isFalse() } } } @@ -189,7 +189,7 @@ class DefaultUserListPresenterTests { skipItems(2) // When the results list is empty, the state is set to NoResults - userRepository.emitState(UserSearchResultState(results = emptyList(), isFetchingSearchResults = false)) + userRepository.emitState(UserSearchResultState(results = emptyList(), isSearching = false)) assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt index 0065f1c5e2..f7c4363613 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt @@ -55,7 +55,7 @@ class RoomInviteMembersPresenter @Inject constructor( val searchResults = remember { mutableStateOf>>(SearchBarResultState.Initial()) } var searchQuery by rememberSaveable { mutableStateOf("") } var searchActive by rememberSaveable { mutableStateOf(false) } - var isFetchingSearchResults = rememberSaveable { mutableStateOf(false) } + var showSearchLoader = rememberSaveable { mutableStateOf(false) } LaunchedEffect(Unit) { fetchMembers(roomMembers) @@ -65,7 +65,7 @@ class RoomInviteMembersPresenter @Inject constructor( searchResults = searchResults, roomMembers = roomMembers, selectedUsers = selectedUsers, - isFetchingSearchResults = isFetchingSearchResults, + showSearchLoader = showSearchLoader, searchQuery = searchQuery ) } @@ -76,7 +76,7 @@ class RoomInviteMembersPresenter @Inject constructor( searchQuery = searchQuery, isSearchActive = searchActive, searchResults = searchResults.value, - isFetchingSearchResults = isFetchingSearchResults.value, + showSearchLoader = showSearchLoader.value, eventSink = { when (it) { is RoomInviteMembersEvents.OnSearchActiveChanged -> { @@ -126,18 +126,18 @@ class RoomInviteMembersPresenter @Inject constructor( searchResults: MutableState>>, roomMembers: MutableState>>, selectedUsers: MutableState>, - isFetchingSearchResults: MutableState, + showSearchLoader: MutableState, searchQuery: String, ) = withContext(coroutineDispatchers.io) { searchResults.value = SearchBarResultState.Initial() - isFetchingSearchResults.value = false + showSearchLoader.value = false val joinedMembers = roomMembers.value.dataOrNull().orEmpty() userRepository.search(searchQuery).onEach { state -> - isFetchingSearchResults.value = state.isFetchingSearchResults + showSearchLoader.value = state.isSearching searchResults.value = when { - state.results.isEmpty() && state.isFetchingSearchResults -> SearchBarResultState.Initial() - state.results.isEmpty() && !state.isFetchingSearchResults -> SearchBarResultState.NoResultsFound() + state.results.isEmpty() && state.isSearching -> SearchBarResultState.Initial() + state.results.isEmpty() && !state.isSearching -> SearchBarResultState.NoResultsFound() else -> SearchBarResultState.Results(state.results.map { result -> val existingMembership = joinedMembers.firstOrNull { j -> j.userId == result.matrixUser.userId }?.membership val isJoined = existingMembership == RoomMembershipState.JOIN diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt index 1fb2dc1e78..84fb1b0986 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersState.kt @@ -23,7 +23,7 @@ import kotlinx.collections.immutable.ImmutableList data class RoomInviteMembersState( val canInvite: Boolean, val searchQuery: String, - val isFetchingSearchResults: Boolean, + val showSearchLoader: Boolean, val searchResults: SearchBarResultState>, val selectedUsers: ImmutableList, val isSearchActive: Boolean, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt index 5e43492a17..ca4e4ac7d2 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersStateProvider.kt @@ -73,7 +73,7 @@ internal class RoomInviteMembersStateProvider : PreviewParameterProvider> = SearchBarResultState.Initial(), selectedUsers: ImmutableList = persistentListOf(), isSearchActive: Boolean = false, - isFetchingSearchResults: Boolean = false, + showSearchLoader: Boolean = false, ): RoomInviteMembersState { return RoomInviteMembersState( canInvite = canInvite, @@ -92,7 +92,7 @@ private fun aRoomInviteMembersState( searchResults = searchResults, selectedUsers = selectedUsers, isSearchActive = isSearchActive, - isFetchingSearchResults = isFetchingSearchResults, + showSearchLoader = showSearchLoader, eventSink = {}, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt index 73f6de54a8..e40e624afc 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt @@ -87,7 +87,7 @@ fun RoomInviteMembersView( RoomInviteMembersSearchBar( modifier = Modifier.fillMaxWidth(), query = state.searchQuery, - isSearching = state.isFetchingSearchResults, + showLoader = state.showSearchLoader, selectedUsers = state.selectedUsers, state = state.searchResults, active = state.isSearchActive, @@ -141,7 +141,7 @@ private fun RoomInviteMembersTopBar( private fun RoomInviteMembersSearchBar( query: String, state: SearchBarResultState>, - isSearching: Boolean, + showLoader: Boolean, selectedUsers: ImmutableList, active: Boolean, onActiveChanged: (Boolean) -> Unit, @@ -171,7 +171,7 @@ private fun RoomInviteMembersSearchBar( showBackButton = false, resultState = state, contentSuffix = { - if (isSearching) { + if (showLoader) { AsyncLoading() } }, diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt index fbd34ad408..0d2201342f 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenterTest.kt @@ -110,15 +110,15 @@ internal class RoomInviteMembersPresenterTest { val initialState = awaitItem() initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query")) assertThat(repository.providedQuery).isEqualTo("some query") - repository.emitState(UserSearchResultState(results = emptyList(), isFetchingSearchResults = true)) - consumeItemsUntilPredicate { it.isFetchingSearchResults }.last().also { state -> + repository.emitState(UserSearchResultState(results = emptyList(), isSearching = true)) + consumeItemsUntilPredicate { it.showSearchLoader }.last().also { state -> assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) - assertThat(state.isFetchingSearchResults).isTrue() + assertThat(state.showSearchLoader).isTrue() } - repository.emitState(results = emptyList(), isFetchingSearchResults = false) - consumeItemsUntilPredicate { !it.isFetchingSearchResults }.last().also { state -> + repository.emitState(results = emptyList(), isSearching = false) + consumeItemsUntilPredicate { !it.showSearchLoader }.last().also { state -> assertThat(state.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) - assertThat(state.isFetchingSearchResults).isFalse() + assertThat(state.showSearchLoader).isFalse() } } } @@ -387,21 +387,21 @@ internal class RoomInviteMembersPresenterTest { private suspend fun FakeUserRepository.emitStateWithUsers( users: List, - isFetchingSearchResults: Boolean = false + isSearching: Boolean = false ) { emitState( results = users.map { UserSearchResult(it) }, - isFetchingSearchResults = isFetchingSearchResults, + isSearching = isSearching, ) } private suspend fun FakeUserRepository.emitState( results: List, - isFetchingSearchResults: Boolean = false + isSearching: Boolean = false ) { val state = UserSearchResultState( results = results, - isFetchingSearchResults = isFetchingSearchResults + isSearching = isSearching ) emitState(state) } diff --git a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt index ebdfb7fedb..2410b58d05 100644 --- a/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserSearchResult.kt @@ -25,5 +25,5 @@ data class UserSearchResult( data class UserSearchResultState( val results: List, - val isFetchingSearchResults: Boolean, + val isSearching: Boolean, ) 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 index 7ac3ec8380..fa09a5ce9a 100644 --- 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 @@ -47,7 +47,7 @@ class MatrixUserRepository @Inject constructor( null } if (shouldQueryProfile || shouldFetchSearchResults) { - emit(UserSearchResultState(isFetchingSearchResults = shouldFetchSearchResults, results = listOfNotNull(fakeSearchResult))) + emit(UserSearchResultState(isSearching = shouldFetchSearchResults, results = listOfNotNull(fakeSearchResult))) } if (shouldFetchSearchResults) { val results = fetchSearchResults(query, shouldQueryProfile) @@ -73,7 +73,7 @@ class MatrixUserRepository @Inject constructor( ?: UserSearchResult(MatrixUser(UserId(query)), isUnresolved = true)) } - return UserSearchResultState(results = results, isFetchingSearchResults = false) + return UserSearchResultState(results = results, isSearching = false) } companion object { 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 index 0ddf58e8aa..e775547efc 100644 --- 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 @@ -55,11 +55,11 @@ internal class MatrixUserRepositoryTest { result.test { awaitItem().also { - assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.isSearching).isTrue() assertThat(it.results).isEmpty() } awaitItem().also { - assertThat(it.isFetchingSearchResults).isFalse() + assertThat(it.isSearching).isFalse() assertThat(it.results).isEmpty() } awaitComplete() @@ -76,11 +76,11 @@ internal class MatrixUserRepositoryTest { result.test { awaitItem().also { - assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.isSearching).isTrue() assertThat(it.results).isEmpty() } awaitItem().also { - assertThat(it.isFetchingSearchResults).isFalse() + assertThat(it.isSearching).isFalse() assertThat(it.results).isEqualTo(aMatrixUserList().toUserSearchResults()) } awaitComplete() @@ -96,7 +96,7 @@ internal class MatrixUserRepositoryTest { result.test { awaitItem().also { - assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.isSearching).isTrue() assertThat(it.results).isEqualTo(listOf(placeholderResult())) } cancelAndConsumeRemainingEvents() @@ -112,7 +112,7 @@ internal class MatrixUserRepositoryTest { result.test { awaitItem().also { - assertThat(it.isFetchingSearchResults).isTrue() + assertThat(it.isSearching).isTrue() assertThat(it.results).isEmpty() } cancelAndConsumeRemainingEvents()