mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 21:32:34 +00:00
Merge pull request #7266 from element-hq/feature/fga/searchbar-result-state-refactor
Refactor SearchBarResultState.Initial/NoResultsFound to data objects
This commit is contained in:
+4
-4
@@ -88,7 +88,7 @@ class DefaultInvitePeoplePresenter(
|
|||||||
override fun present(): InvitePeopleState {
|
override fun present(): InvitePeopleState {
|
||||||
val roomMembers = remember { mutableStateOf<AsyncData<ImmutableList<RoomMember>>>(AsyncData.Loading()) }
|
val roomMembers = remember { mutableStateOf<AsyncData<ImmutableList<RoomMember>>>(AsyncData.Loading()) }
|
||||||
val selectedUsers = remember { mutableStateOf<ImmutableList<MatrixUser>>(persistentListOf()) }
|
val selectedUsers = remember { mutableStateOf<ImmutableList<MatrixUser>>(persistentListOf()) }
|
||||||
val searchResults = remember { mutableStateOf<SearchBarResultState<ImmutableList<InvitableUser>>>(SearchBarResultState.Initial()) }
|
val searchResults = remember { mutableStateOf<SearchBarResultState<ImmutableList<InvitableUser>>>(SearchBarResultState.Initial) }
|
||||||
val queryState = rememberTextFieldState()
|
val queryState = rememberTextFieldState()
|
||||||
var searchActive by rememberSaveable { mutableStateOf(false) }
|
var searchActive by rememberSaveable { mutableStateOf(false) }
|
||||||
val showSearchLoader = rememberSaveable { mutableStateOf(false) }
|
val showSearchLoader = rememberSaveable { mutableStateOf(false) }
|
||||||
@@ -332,15 +332,15 @@ class DefaultInvitePeoplePresenter(
|
|||||||
showSearchLoader: MutableState<Boolean>,
|
showSearchLoader: MutableState<Boolean>,
|
||||||
searchQuery: String,
|
searchQuery: String,
|
||||||
) = withContext(coroutineDispatchers.io) {
|
) = withContext(coroutineDispatchers.io) {
|
||||||
searchResults.value = SearchBarResultState.Initial()
|
searchResults.value = SearchBarResultState.Initial
|
||||||
showSearchLoader.value = false
|
showSearchLoader.value = false
|
||||||
val joinedMembers = roomMembers.value.dataOrNull().orEmpty()
|
val joinedMembers = roomMembers.value.dataOrNull().orEmpty()
|
||||||
|
|
||||||
userRepository.search(searchQuery).onEach { state ->
|
userRepository.search(searchQuery).onEach { state ->
|
||||||
showSearchLoader.value = state.isSearching
|
showSearchLoader.value = state.isSearching
|
||||||
searchResults.value = when {
|
searchResults.value = when {
|
||||||
state.results.isEmpty() && state.isSearching -> SearchBarResultState.Initial()
|
state.results.isEmpty() && state.isSearching -> SearchBarResultState.Initial
|
||||||
state.results.isEmpty() && !state.isSearching -> SearchBarResultState.NoResultsFound()
|
state.results.isEmpty() && !state.isSearching -> SearchBarResultState.NoResultsFound
|
||||||
else -> SearchBarResultState.Results(state.results.map { result ->
|
else -> SearchBarResultState.Results(state.results.map { result ->
|
||||||
val existingMembership = joinedMembers.firstOrNull { j -> j.userId == result.matrixUser.userId }?.membership
|
val existingMembership = joinedMembers.firstOrNull { j -> j.userId == result.matrixUser.userId }?.membership
|
||||||
val isJoined = existingMembership == RoomMembershipState.JOIN
|
val isJoined = existingMembership == RoomMembershipState.JOIN
|
||||||
|
|||||||
+2
-2
@@ -33,7 +33,7 @@ internal class DefaultInvitePeopleStateProvider : PreviewParameterProvider<Defau
|
|||||||
aDefaultInvitePeopleState(canInvite = true, selectedUsers = aMatrixUserList().toImmutableList()),
|
aDefaultInvitePeopleState(canInvite = true, selectedUsers = aMatrixUserList().toImmutableList()),
|
||||||
aDefaultInvitePeopleState(isSearchActive = true, searchQuery = "some query"),
|
aDefaultInvitePeopleState(isSearchActive = true, searchQuery = "some query"),
|
||||||
aDefaultInvitePeopleState(isSearchActive = true, searchQuery = "some query", selectedUsers = aMatrixUserList().toImmutableList()),
|
aDefaultInvitePeopleState(isSearchActive = true, searchQuery = "some query", selectedUsers = aMatrixUserList().toImmutableList()),
|
||||||
aDefaultInvitePeopleState(isSearchActive = true, searchQuery = "some query", searchResults = SearchBarResultState.NoResultsFound()),
|
aDefaultInvitePeopleState(isSearchActive = true, searchQuery = "some query", searchResults = SearchBarResultState.NoResultsFound),
|
||||||
aDefaultInvitePeopleState(
|
aDefaultInvitePeopleState(
|
||||||
isSearchActive = true,
|
isSearchActive = true,
|
||||||
canInvite = true,
|
canInvite = true,
|
||||||
@@ -115,7 +115,7 @@ private fun aDefaultInvitePeopleState(
|
|||||||
room: AsyncData<Unit> = AsyncData.Success(Unit),
|
room: AsyncData<Unit> = AsyncData.Success(Unit),
|
||||||
canInvite: Boolean = false,
|
canInvite: Boolean = false,
|
||||||
searchQuery: String = "",
|
searchQuery: String = "",
|
||||||
searchResults: SearchBarResultState<ImmutableList<InvitableUser>> = SearchBarResultState.Initial(),
|
searchResults: SearchBarResultState<ImmutableList<InvitableUser>> = SearchBarResultState.Initial,
|
||||||
selectedUsers: ImmutableList<MatrixUser> = persistentListOf(),
|
selectedUsers: ImmutableList<MatrixUser> = persistentListOf(),
|
||||||
isSearchActive: Boolean = false,
|
isSearchActive: Boolean = false,
|
||||||
showSearchLoader: Boolean = false,
|
showSearchLoader: Boolean = false,
|
||||||
|
|||||||
+4
-8
@@ -95,7 +95,7 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
resultState.searchQuery.setTextAndPlaceCursorAtEnd("some query")
|
resultState.searchQuery.setTextAndPlaceCursorAtEnd("some query")
|
||||||
assertThat(awaitItemAsDefault().searchQuery.text.toString()).isEqualTo("some query")
|
assertThat(awaitItemAsDefault().searchQuery.text.toString()).isEqualTo("some query")
|
||||||
resultState.eventSink(InvitePeopleEvents.CloseSearch)
|
resultState.eventSink(InvitePeopleEvents.CloseSearch)
|
||||||
skipItems(2)
|
skipItems(1)
|
||||||
awaitItemAsDefault().also {
|
awaitItemAsDefault().also {
|
||||||
assertThat(it.isSearchActive).isFalse()
|
assertThat(it.isSearchActive).isFalse()
|
||||||
assertThat(it.searchQuery.text.toString()).isEmpty()
|
assertThat(it.searchQuery.text.toString()).isEmpty()
|
||||||
@@ -116,7 +116,7 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
initialState.searchQuery.setTextAndPlaceCursorAtEnd("some query")
|
initialState.searchQuery.setTextAndPlaceCursorAtEnd("some query")
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitState(UserSearchResultState(results = emptyList(), isSearching = true))
|
repository.emitState(UserSearchResultState(results = emptyList(), isSearching = true))
|
||||||
skipItems(3)
|
skipItems(2)
|
||||||
awaitItemAsDefault().also { state ->
|
awaitItemAsDefault().also { state ->
|
||||||
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
||||||
assertThat(state.showSearchLoader).isTrue()
|
assertThat(state.showSearchLoader).isTrue()
|
||||||
@@ -145,7 +145,6 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList())
|
repository.emitStateWithUsers(users = aMatrixUserList())
|
||||||
skipItems(1)
|
|
||||||
|
|
||||||
val resultState = awaitItemAsDefault()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
@@ -198,7 +197,6 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList())
|
repository.emitStateWithUsers(users = aMatrixUserList())
|
||||||
skipItems(1)
|
|
||||||
|
|
||||||
val resultState = awaitItemAsDefault()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
@@ -265,7 +263,6 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
it
|
it
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
skipItems(1)
|
|
||||||
|
|
||||||
val resultState = awaitItemAsDefault()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
@@ -329,7 +326,7 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
||||||
skipItems(2)
|
skipItems(1)
|
||||||
|
|
||||||
val resultState = awaitItemAsDefault()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
@@ -366,7 +363,6 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
||||||
skipItems(1)
|
|
||||||
awaitItemAsDefault().also { state ->
|
awaitItemAsDefault().also { state ->
|
||||||
// selectedUser is not selected
|
// selectedUser is not selected
|
||||||
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
@@ -732,7 +728,7 @@ internal class DefaultInvitePeoplePresenterTest {
|
|||||||
isSearching = true
|
isSearching = true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
skipItems(3)
|
skipItems(2)
|
||||||
|
|
||||||
awaitItemAsDefault().run {
|
awaitItemAsDefault().run {
|
||||||
assertThat(selectedUsers).containsExactly(alice, bob, charlie)
|
assertThat(selectedUsers).containsExactly(alice, bob, charlie)
|
||||||
|
|||||||
+2
-2
@@ -77,7 +77,7 @@ class ChangeRolesPresenter(
|
|||||||
val queryState = rememberTextFieldState()
|
val queryState = rememberTextFieldState()
|
||||||
var searchActive by rememberSaveable { mutableStateOf(false) }
|
var searchActive by rememberSaveable { mutableStateOf(false) }
|
||||||
var searchResults by remember {
|
var searchResults by remember {
|
||||||
mutableStateOf<SearchBarResultState<MembersByRole>>(SearchBarResultState.Initial())
|
mutableStateOf<SearchBarResultState<MembersByRole>>(SearchBarResultState.Initial)
|
||||||
}
|
}
|
||||||
val selectedUsers = remember {
|
val selectedUsers = remember {
|
||||||
mutableStateOf<ImmutableList<MatrixUser>>(persistentListOf())
|
mutableStateOf<ImmutableList<MatrixUser>>(persistentListOf())
|
||||||
@@ -118,7 +118,7 @@ class ChangeRolesPresenter(
|
|||||||
.groupedByRole()
|
.groupedByRole()
|
||||||
|
|
||||||
searchResults = if (results.isEmpty()) {
|
searchResults = if (results.isEmpty()) {
|
||||||
SearchBarResultState.NoResultsFound()
|
SearchBarResultState.NoResultsFound
|
||||||
} else {
|
} else {
|
||||||
SearchBarResultState.Results(results)
|
SearchBarResultState.Results(results)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ internal fun aChangeRolesState(
|
|||||||
role: RoomMember.Role = RoomMember.Role.Admin,
|
role: RoomMember.Role = RoomMember.Role.Admin,
|
||||||
searchQuery: String = "",
|
searchQuery: String = "",
|
||||||
isSearchActive: Boolean = false,
|
isSearchActive: Boolean = false,
|
||||||
searchResults: SearchBarResultState<MembersByRole> = SearchBarResultState.NoResultsFound(),
|
searchResults: SearchBarResultState<MembersByRole> = SearchBarResultState.NoResultsFound,
|
||||||
selectedUsers: ImmutableList<MatrixUser> = persistentListOf(),
|
selectedUsers: ImmutableList<MatrixUser> = persistentListOf(),
|
||||||
hasPendingChanges: Boolean = false,
|
hasPendingChanges: Boolean = false,
|
||||||
savingState: AsyncAction<Boolean> = AsyncAction.Uninitialized,
|
savingState: AsyncAction<Boolean> = AsyncAction.Uninitialized,
|
||||||
|
|||||||
+2
-2
@@ -66,8 +66,8 @@ class AddRoomToSpacePresenter(
|
|||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
when {
|
when {
|
||||||
filteredRooms.isNotEmpty() -> SearchBarResultState.Results(filteredRooms)
|
filteredRooms.isNotEmpty() -> SearchBarResultState.Results(filteredRooms)
|
||||||
isSearchActive && searchQuery.text.isNotEmpty() -> SearchBarResultState.NoResultsFound<ImmutableList<SelectRoomInfo>>()
|
isSearchActive && searchQuery.text.isNotEmpty() -> SearchBarResultState.NoResultsFound
|
||||||
else -> SearchBarResultState.Initial<ImmutableList<SelectRoomInfo>>()
|
else -> SearchBarResultState.Initial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -40,7 +40,7 @@ internal class AddRoomToSpaceStateProvider : PreviewParameterProvider<AddRoomToS
|
|||||||
anAddRoomToSpaceState(
|
anAddRoomToSpaceState(
|
||||||
isSearchActive = true,
|
isSearchActive = true,
|
||||||
searchQuery = "unknown",
|
searchQuery = "unknown",
|
||||||
searchResults = SearchBarResultState.NoResultsFound(),
|
searchResults = SearchBarResultState.NoResultsFound,
|
||||||
),
|
),
|
||||||
// With selected rooms
|
// With selected rooms
|
||||||
anAddRoomToSpaceState(
|
anAddRoomToSpaceState(
|
||||||
@@ -62,7 +62,7 @@ internal class AddRoomToSpaceStateProvider : PreviewParameterProvider<AddRoomToS
|
|||||||
|
|
||||||
internal fun anAddRoomToSpaceState(
|
internal fun anAddRoomToSpaceState(
|
||||||
searchQuery: String = "",
|
searchQuery: String = "",
|
||||||
searchResults: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial(),
|
searchResults: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial,
|
||||||
selectedRooms: ImmutableList<SelectRoomInfo> = persistentListOf(),
|
selectedRooms: ImmutableList<SelectRoomInfo> = persistentListOf(),
|
||||||
isSearchActive: Boolean = false,
|
isSearchActive: Boolean = false,
|
||||||
saveAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
saveAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||||
|
|||||||
+4
-4
@@ -67,19 +67,19 @@ class DefaultUserListPresenter(
|
|||||||
val selectedUsers by userListDataStore.selectedUsers.collectAsState(emptyList())
|
val selectedUsers by userListDataStore.selectedUsers.collectAsState(emptyList())
|
||||||
val queryState = rememberTextFieldState()
|
val queryState = rememberTextFieldState()
|
||||||
var searchResults: SearchBarResultState<ImmutableList<UserSearchResult>> by remember {
|
var searchResults: SearchBarResultState<ImmutableList<UserSearchResult>> by remember {
|
||||||
mutableStateOf(SearchBarResultState.Initial())
|
mutableStateOf(SearchBarResultState.Initial)
|
||||||
}
|
}
|
||||||
var showSearchLoader by remember { mutableStateOf(false) }
|
var showSearchLoader by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val searchQuery = queryState.text.toString()
|
val searchQuery = queryState.text.toString()
|
||||||
LaunchedEffect(searchQuery) {
|
LaunchedEffect(searchQuery) {
|
||||||
searchResults = SearchBarResultState.Initial()
|
searchResults = SearchBarResultState.Initial
|
||||||
showSearchLoader = false
|
showSearchLoader = false
|
||||||
userRepository.search(searchQuery).onEach { state ->
|
userRepository.search(searchQuery).onEach { state ->
|
||||||
showSearchLoader = state.isSearching
|
showSearchLoader = state.isSearching
|
||||||
searchResults = when {
|
searchResults = when {
|
||||||
state.results.isEmpty() && state.isSearching -> SearchBarResultState.Initial()
|
state.results.isEmpty() && state.isSearching -> SearchBarResultState.Initial
|
||||||
state.results.isEmpty() && !state.isSearching -> SearchBarResultState.NoResultsFound()
|
state.results.isEmpty() && !state.isSearching -> SearchBarResultState.NoResultsFound
|
||||||
else -> SearchBarResultState.Results(state.results.toImmutableList())
|
else -> SearchBarResultState.Results(state.results.toImmutableList())
|
||||||
}
|
}
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
|
|||||||
+2
-2
@@ -47,7 +47,7 @@ open class UserListStateProvider : PreviewParameterProvider<UserListState> {
|
|||||||
aUserListState(
|
aUserListState(
|
||||||
isSearchActive = true,
|
isSearchActive = true,
|
||||||
searchQuery = "something-with-no-results",
|
searchQuery = "something-with-no-results",
|
||||||
searchResults = SearchBarResultState.NoResultsFound()
|
searchResults = SearchBarResultState.NoResultsFound
|
||||||
),
|
),
|
||||||
aUserListState(
|
aUserListState(
|
||||||
isSearchActive = true,
|
isSearchActive = true,
|
||||||
@@ -63,7 +63,7 @@ open class UserListStateProvider : PreviewParameterProvider<UserListState> {
|
|||||||
fun aUserListState(
|
fun aUserListState(
|
||||||
searchQuery: String = "",
|
searchQuery: String = "",
|
||||||
isSearchActive: Boolean = false,
|
isSearchActive: Boolean = false,
|
||||||
searchResults: SearchBarResultState<ImmutableList<UserSearchResult>> = SearchBarResultState.Initial(),
|
searchResults: SearchBarResultState<ImmutableList<UserSearchResult>> = SearchBarResultState.Initial,
|
||||||
selectedUsers: List<MatrixUser> = emptyList(),
|
selectedUsers: List<MatrixUser> = emptyList(),
|
||||||
showSearchLoader: Boolean = false,
|
showSearchLoader: Boolean = false,
|
||||||
selectionMode: SelectionMode = SelectionMode.Single,
|
selectionMode: SelectionMode = SelectionMode.Single,
|
||||||
|
|||||||
+2
-10
@@ -40,7 +40,6 @@ class DefaultUserListPresenterTest {
|
|||||||
FakeMatrixClient(),
|
FakeMatrixClient(),
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
skipItems(1)
|
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.searchQuery.text.toString()).isEmpty()
|
assertThat(initialState.searchQuery.text.toString()).isEmpty()
|
||||||
assertThat(initialState.isMultiSelectionEnabled).isFalse()
|
assertThat(initialState.isMultiSelectionEnabled).isFalse()
|
||||||
@@ -60,7 +59,6 @@ class DefaultUserListPresenterTest {
|
|||||||
FakeMatrixClient(),
|
FakeMatrixClient(),
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
skipItems(1)
|
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.searchQuery.text.toString()).isEmpty()
|
assertThat(initialState.searchQuery.text.toString()).isEmpty()
|
||||||
assertThat(initialState.isMultiSelectionEnabled).isTrue()
|
assertThat(initialState.isMultiSelectionEnabled).isTrue()
|
||||||
@@ -80,7 +78,6 @@ class DefaultUserListPresenterTest {
|
|||||||
FakeMatrixClient(),
|
FakeMatrixClient(),
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
skipItems(1)
|
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
|
|
||||||
initialState.eventSink(UserListEvents.OnSearchActiveChanged(true))
|
initialState.eventSink(UserListEvents.OnSearchActiveChanged(true))
|
||||||
@@ -90,13 +87,11 @@ class DefaultUserListPresenterTest {
|
|||||||
initialState.searchQuery.setTextAndPlaceCursorAtEnd(matrixIdQuery)
|
initialState.searchQuery.setTextAndPlaceCursorAtEnd(matrixIdQuery)
|
||||||
assertThat(awaitItem().searchQuery.text.toString()).isEqualTo(matrixIdQuery)
|
assertThat(awaitItem().searchQuery.text.toString()).isEqualTo(matrixIdQuery)
|
||||||
assertThat(userRepository.providedQuery).isEqualTo(matrixIdQuery)
|
assertThat(userRepository.providedQuery).isEqualTo(matrixIdQuery)
|
||||||
skipItems(1)
|
|
||||||
|
|
||||||
val notMatrixIdQuery = "name"
|
val notMatrixIdQuery = "name"
|
||||||
initialState.searchQuery.setTextAndPlaceCursorAtEnd(notMatrixIdQuery)
|
initialState.searchQuery.setTextAndPlaceCursorAtEnd(notMatrixIdQuery)
|
||||||
assertThat(awaitItem().searchQuery.text.toString()).isEqualTo(notMatrixIdQuery)
|
assertThat(awaitItem().searchQuery.text.toString()).isEqualTo(notMatrixIdQuery)
|
||||||
assertThat(userRepository.providedQuery).isEqualTo(notMatrixIdQuery)
|
assertThat(userRepository.providedQuery).isEqualTo(notMatrixIdQuery)
|
||||||
skipItems(1)
|
|
||||||
|
|
||||||
initialState.eventSink(UserListEvents.OnSearchActiveChanged(false))
|
initialState.eventSink(UserListEvents.OnSearchActiveChanged(false))
|
||||||
assertThat(awaitItem().isSearchActive).isFalse()
|
assertThat(awaitItem().isSearchActive).isFalse()
|
||||||
@@ -115,13 +110,12 @@ class DefaultUserListPresenterTest {
|
|||||||
FakeMatrixClient(),
|
FakeMatrixClient(),
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
skipItems(1)
|
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
|
|
||||||
initialState.searchQuery.setTextAndPlaceCursorAtEnd("alice")
|
initialState.searchQuery.setTextAndPlaceCursorAtEnd("alice")
|
||||||
assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
||||||
assertThat(userRepository.providedQuery).isEqualTo("alice")
|
assertThat(userRepository.providedQuery).isEqualTo("alice")
|
||||||
skipItems(2)
|
skipItems(1)
|
||||||
|
|
||||||
// When the user repository emits a result, it's copied to the state
|
// When the user repository emits a result, it's copied to the state
|
||||||
val result = UserSearchResultState(
|
val result = UserSearchResultState(
|
||||||
@@ -166,13 +160,12 @@ class DefaultUserListPresenterTest {
|
|||||||
FakeMatrixClient(),
|
FakeMatrixClient(),
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
skipItems(1)
|
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
|
|
||||||
initialState.searchQuery.setTextAndPlaceCursorAtEnd("alice")
|
initialState.searchQuery.setTextAndPlaceCursorAtEnd("alice")
|
||||||
assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
||||||
assertThat(userRepository.providedQuery).isEqualTo("alice")
|
assertThat(userRepository.providedQuery).isEqualTo("alice")
|
||||||
skipItems(2)
|
skipItems(1)
|
||||||
|
|
||||||
// When the results list is empty, the state is set to NoResults
|
// When the results list is empty, the state is set to NoResults
|
||||||
userRepository.emitState(UserSearchResultState(results = emptyList(), isSearching = false))
|
userRepository.emitState(UserSearchResultState(results = emptyList(), isSearching = false))
|
||||||
@@ -190,7 +183,6 @@ class DefaultUserListPresenterTest {
|
|||||||
FakeMatrixClient(),
|
FakeMatrixClient(),
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
skipItems(1)
|
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
|
|
||||||
val userA = aMatrixUser("@userA:domain", "A")
|
val userA = aMatrixUser("@userA:domain", "A")
|
||||||
|
|||||||
+7
-7
@@ -59,7 +59,7 @@ fun <T> SearchBar(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
showBackButton: Boolean = true,
|
showBackButton: Boolean = true,
|
||||||
resultState: SearchBarResultState<T> = SearchBarResultState.Initial(),
|
resultState: SearchBarResultState<T> = SearchBarResultState.Initial,
|
||||||
shape: Shape = SearchBarDefaults.inputFieldShape,
|
shape: Shape = SearchBarDefaults.inputFieldShape,
|
||||||
tonalElevation: Dp = SearchBarDefaults.TonalElevation,
|
tonalElevation: Dp = SearchBarDefaults.TonalElevation,
|
||||||
windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
|
windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
|
||||||
@@ -134,7 +134,7 @@ fun <T> SearchBar(
|
|||||||
resultHandler(resultState.results)
|
resultHandler(resultState.results)
|
||||||
}
|
}
|
||||||
|
|
||||||
is SearchBarResultState.NoResultsFound<T> -> {
|
is SearchBarResultState.NoResultsFound -> {
|
||||||
// No results found, show a message
|
// No results found, show a message
|
||||||
Spacer(Modifier.size(80.dp))
|
Spacer(Modifier.size(80.dp))
|
||||||
|
|
||||||
@@ -200,12 +200,12 @@ object ElementSearchBarDefaults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
sealed interface SearchBarResultState<in T> {
|
sealed interface SearchBarResultState<out T> {
|
||||||
/** No search results are available yet (e.g. because the user hasn't entered a search term). */
|
/** No search results are available yet (e.g. because the user hasn't entered a search term). */
|
||||||
class Initial<T> : SearchBarResultState<T>
|
data object Initial : SearchBarResultState<Nothing>
|
||||||
|
|
||||||
/** The search has completed, but no results were found. */
|
/** The search has completed, but no results were found. */
|
||||||
class NoResultsFound<T> : SearchBarResultState<T>
|
data object NoResultsFound : SearchBarResultState<Nothing>
|
||||||
|
|
||||||
/** The search has completed, and some matching users were found. */
|
/** The search has completed, and some matching users were found. */
|
||||||
data class Results<T>(val results: T) : SearchBarResultState<T>
|
data class Results<T>(val results: T) : SearchBarResultState<T>
|
||||||
@@ -249,7 +249,7 @@ internal fun SearchBarActiveWithNoResultsPreview() = ElementThemedPreview {
|
|||||||
ContentToPreview(
|
ContentToPreview(
|
||||||
initialQuery = "search term",
|
initialQuery = "search term",
|
||||||
active = true,
|
active = true,
|
||||||
resultState = SearchBarResultState.NoResultsFound<String>(),
|
resultState = SearchBarResultState.NoResultsFound,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +293,7 @@ private fun ContentToPreview(
|
|||||||
initialQuery: String = "",
|
initialQuery: String = "",
|
||||||
active: Boolean = false,
|
active: Boolean = false,
|
||||||
showBackButton: Boolean = true,
|
showBackButton: Boolean = true,
|
||||||
resultState: SearchBarResultState<String> = SearchBarResultState.Initial(),
|
resultState: SearchBarResultState<String> = SearchBarResultState.Initial,
|
||||||
contentPrefix: @Composable ColumnScope.() -> Unit = {},
|
contentPrefix: @Composable ColumnScope.() -> Unit = {},
|
||||||
contentSuffix: @Composable ColumnScope.() -> Unit = {},
|
contentSuffix: @Composable ColumnScope.() -> Unit = {},
|
||||||
resultHandler: @Composable ColumnScope.(String) -> Unit = {},
|
resultHandler: @Composable ColumnScope.(String) -> Unit = {},
|
||||||
|
|||||||
+2
-6
@@ -55,7 +55,7 @@ class DefaultEmojiPickerPresenter(
|
|||||||
override fun present(): EmojiPickerState {
|
override fun present(): EmojiPickerState {
|
||||||
val queryState = rememberTextFieldState()
|
val queryState = rememberTextFieldState()
|
||||||
var isSearchActive by remember { mutableStateOf(false) }
|
var isSearchActive by remember { mutableStateOf(false) }
|
||||||
var emojiResults by remember { mutableStateOf<SearchBarResultState<ImmutableList<Emoji>>>(SearchBarResultState.Initial()) }
|
var emojiResults by remember { mutableStateOf<SearchBarResultState<ImmutableList<Emoji>>>(SearchBarResultState.Initial) }
|
||||||
|
|
||||||
val data by produceState(EmojiPickerData.Empty) {
|
val data by produceState(EmojiPickerData.Empty) {
|
||||||
val storeDeferred = async { emojibaseProvider.getStore() }
|
val storeDeferred = async { emojibaseProvider.getStore() }
|
||||||
@@ -93,11 +93,7 @@ class DefaultEmojiPickerPresenter(
|
|||||||
val searchQuery = queryState.text.toString()
|
val searchQuery = queryState.text.toString()
|
||||||
LaunchedEffect(searchQuery, data) {
|
LaunchedEffect(searchQuery, data) {
|
||||||
if (searchQuery.isEmpty() || data.allEmojis.isEmpty()) {
|
if (searchQuery.isEmpty() || data.allEmojis.isEmpty()) {
|
||||||
// `SearchBarResultState.Initial` has no `equals` override, so reassigning a new instance
|
emojiResults = SearchBarResultState.Initial
|
||||||
// would trigger a redundant emission each time this effect re-runs while the query is empty.
|
|
||||||
if (emojiResults !is SearchBarResultState.Initial) {
|
|
||||||
emojiResults = SearchBarResultState.Initial()
|
|
||||||
}
|
|
||||||
return@LaunchedEffect
|
return@LaunchedEffect
|
||||||
}
|
}
|
||||||
delay(100.milliseconds)
|
delay(100.milliseconds)
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ internal fun aDefaultEmojiPickerState(
|
|||||||
}.toImmutableList(),
|
}.toImmutableList(),
|
||||||
searchQuery: String = "",
|
searchQuery: String = "",
|
||||||
isSearchActive: Boolean = false,
|
isSearchActive: Boolean = false,
|
||||||
searchResults: SearchBarResultState<ImmutableList<Emoji>> = SearchBarResultState.Initial(),
|
searchResults: SearchBarResultState<ImmutableList<Emoji>> = SearchBarResultState.Initial,
|
||||||
eventSink: (EmojiPickerEvent) -> Unit = {},
|
eventSink: (EmojiPickerEvent) -> Unit = {},
|
||||||
) = DefaultEmojiPickerState(
|
) = DefaultEmojiPickerState(
|
||||||
categories = categories,
|
categories = categories,
|
||||||
|
|||||||
+2
-2
@@ -65,8 +65,8 @@ class RoomSelectPresenter(
|
|||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
when {
|
when {
|
||||||
roomSummaryDetailsList.isNotEmpty() -> SearchBarResultState.Results(roomSummaryDetailsList.toImmutableList())
|
roomSummaryDetailsList.isNotEmpty() -> SearchBarResultState.Results(roomSummaryDetailsList.toImmutableList())
|
||||||
isSearchActive -> SearchBarResultState.NoResultsFound()
|
isSearchActive -> SearchBarResultState.NoResultsFound
|
||||||
else -> SearchBarResultState.Initial()
|
else -> SearchBarResultState.Initial
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ open class RoomSelectStateProvider : PreviewParameterProvider<RoomSelectState> {
|
|||||||
internal fun aRoomSelectState(
|
internal fun aRoomSelectState(
|
||||||
mode: RoomSelectMode = RoomSelectMode.Forward,
|
mode: RoomSelectMode = RoomSelectMode.Forward,
|
||||||
maxNumberOfRooms: Int = 10,
|
maxNumberOfRooms: Int = 10,
|
||||||
resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial(),
|
resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial,
|
||||||
searchQuery: String = "",
|
searchQuery: String = "",
|
||||||
isSearchActive: Boolean = false,
|
isSearchActive: Boolean = false,
|
||||||
selectedRooms: ImmutableList<SelectRoomInfo> = persistentListOf(),
|
selectedRooms: ImmutableList<SelectRoomInfo> = persistentListOf(),
|
||||||
|
|||||||
Reference in New Issue
Block a user