use list instead of set

This commit is contained in:
Florian Renaud 2023-03-23 11:10:24 +01:00
parent d8c6a5b52d
commit 8c63d1fcb6
6 changed files with 32 additions and 36 deletions

View file

@ -18,8 +18,8 @@ package io.element.android.features.createroom.impl.addpeople
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.selectusers.api.SelectionMode import io.element.android.features.selectusers.api.SelectionMode
import io.element.android.features.selectusers.api.aListOfSelectedUsers
import io.element.android.features.selectusers.api.aSelectUsersState import io.element.android.features.selectusers.api.aSelectUsersState
import io.element.android.features.selectusers.api.aSetOfSelectedUsers
open class AddPeopleStateProvider : PreviewParameterProvider<AddPeopleState> { open class AddPeopleStateProvider : PreviewParameterProvider<AddPeopleState> {
override val values: Sequence<AddPeopleState> override val values: Sequence<AddPeopleState>
@ -27,13 +27,13 @@ open class AddPeopleStateProvider : PreviewParameterProvider<AddPeopleState> {
aAddPeopleState(), aAddPeopleState(),
aAddPeopleState().copy( aAddPeopleState().copy(
selectUsersState = aSelectUsersState().copy( selectUsersState = aSelectUsersState().copy(
selectedUsers = aSetOfSelectedUsers(), selectedUsers = aListOfSelectedUsers(),
selectionMode = SelectionMode.Multiple, selectionMode = SelectionMode.Multiple,
) )
), ),
aAddPeopleState().copy( aAddPeopleState().copy(
selectUsersState = aSelectUsersState().copy( selectUsersState = aSelectUsersState().copy(
selectedUsers = aSetOfSelectedUsers(), selectedUsers = aListOfSelectedUsers(),
isSearchActive = true, isSearchActive = true,
selectionMode = SelectionMode.Multiple, selectionMode = SelectionMode.Multiple,
) )

View file

@ -19,12 +19,11 @@ package io.element.android.features.selectusers.api
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.matrix.ui.model.MatrixUser
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
data class SelectUsersState( data class SelectUsersState(
val searchQuery: String, val searchQuery: String,
val searchResults: ImmutableList<MatrixUser>, val searchResults: ImmutableList<MatrixUser>,
val selectedUsers: ImmutableSet<MatrixUser>, val selectedUsers: ImmutableList<MatrixUser>,
val selectedUsersListState: LazyListState, val selectedUsersListState: LazyListState,
val isSearchActive: Boolean, val isSearchActive: Boolean,
val selectionMode: SelectionMode, val selectionMode: SelectionMode,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.matrix.ui.model.MatrixUser
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
open class SelectUsersStateProvider : PreviewParameterProvider<SelectUsersState> { open class SelectUsersStateProvider : PreviewParameterProvider<SelectUsersState> {
override val values: Sequence<SelectUsersState> override val values: Sequence<SelectUsersState>
@ -29,7 +28,7 @@ open class SelectUsersStateProvider : PreviewParameterProvider<SelectUsersState>
aSelectUsersState(), aSelectUsersState(),
aSelectUsersState().copy( aSelectUsersState().copy(
isSearchActive = false, isSearchActive = false,
selectedUsers = aSetOfSelectedUsers(), selectedUsers = aListOfSelectedUsers(),
selectionMode = SelectionMode.Multiple, selectionMode = SelectionMode.Multiple,
), ),
aSelectUsersState().copy(isSearchActive = true), aSelectUsersState().copy(isSearchActive = true),
@ -38,14 +37,14 @@ open class SelectUsersStateProvider : PreviewParameterProvider<SelectUsersState>
aSelectUsersState().copy( aSelectUsersState().copy(
isSearchActive = true, isSearchActive = true,
searchQuery = "@someone:matrix.org", searchQuery = "@someone:matrix.org",
selectedUsers = aSetOfSelectedUsers(), selectedUsers = aListOfSelectedUsers(),
searchResults = aListOfResults(), searchResults = aListOfResults(),
), ),
aSelectUsersState().copy( aSelectUsersState().copy(
isSearchActive = true, isSearchActive = true,
searchQuery = "@someone:matrix.org", searchQuery = "@someone:matrix.org",
selectionMode = SelectionMode.Multiple, selectionMode = SelectionMode.Multiple,
selectedUsers = aSetOfSelectedUsers(), selectedUsers = aListOfSelectedUsers(),
searchResults = aListOfResults(), searchResults = aListOfResults(),
) )
) )
@ -55,7 +54,7 @@ fun aSelectUsersState() = SelectUsersState(
isSearchActive = false, isSearchActive = false,
searchQuery = "", searchQuery = "",
searchResults = persistentListOf(), searchResults = persistentListOf(),
selectedUsers = persistentSetOf(), selectedUsers = persistentListOf(),
selectedUsersListState = LazyListState( selectedUsersListState = LazyListState(
firstVisibleItemIndex = 0, firstVisibleItemIndex = 0,
firstVisibleItemScrollOffset = 0, firstVisibleItemScrollOffset = 0,
@ -64,7 +63,7 @@ fun aSelectUsersState() = SelectUsersState(
eventSink = {} eventSink = {}
) )
fun aSetOfSelectedUsers() = persistentSetOf( fun aListOfSelectedUsers() = persistentListOf(
MatrixUser(id = UserId("@someone:matrix.org")), MatrixUser(id = UserId("@someone:matrix.org")),
MatrixUser(id = UserId("@other:matrix.org"), username = "other"), MatrixUser(id = UserId("@other:matrix.org"), username = "other"),
) )

View file

@ -61,7 +61,6 @@ import io.element.android.libraries.matrix.ui.components.MatrixUserRow
import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.matrix.ui.model.MatrixUser
import io.element.android.libraries.matrix.ui.model.getBestName import io.element.android.libraries.matrix.ui.model.getBestName
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
import io.element.android.libraries.ui.strings.R as StringR import io.element.android.libraries.ui.strings.R as StringR
@Composable @Composable
@ -113,7 +112,7 @@ fun SelectUsersView(
fun SearchUserBar( fun SearchUserBar(
query: String, query: String,
results: ImmutableList<MatrixUser>, results: ImmutableList<MatrixUser>,
selectedUsers: ImmutableSet<MatrixUser>, selectedUsers: ImmutableList<MatrixUser>,
selectedUsersListState: LazyListState, selectedUsersListState: LazyListState,
active: Boolean, active: Boolean,
isMultiSelectionEnabled: Boolean, isMultiSelectionEnabled: Boolean,
@ -243,7 +242,7 @@ fun SearchSingleUserResultItem(
@Composable @Composable
fun SelectedUsersList( fun SelectedUsersList(
listState: LazyListState, listState: LazyListState,
selectedUsers: ImmutableSet<MatrixUser>, selectedUsers: ImmutableList<MatrixUser>,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onUserRemoved: (MatrixUser) -> Unit = {}, onUserRemoved: (MatrixUser) -> Unit = {},
) { ) {

View file

@ -40,11 +40,8 @@ import io.element.android.libraries.matrix.api.core.MatrixPatterns
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.matrix.ui.model.MatrixUser
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -62,8 +59,8 @@ class DefaultSelectUsersPresenter @AssistedInject constructor(
override fun present(): SelectUsersState { override fun present(): SelectUsersState {
val localCoroutineScope = rememberCoroutineScope() val localCoroutineScope = rememberCoroutineScope()
var isSearchActive by rememberSaveable { mutableStateOf(false) } var isSearchActive by rememberSaveable { mutableStateOf(false) }
val selectedUsers: MutableState<ImmutableSet<MatrixUser>> = remember { val selectedUsers: MutableState<ImmutableList<MatrixUser>> = remember {
mutableStateOf(persistentSetOf()) mutableStateOf(persistentListOf())
} }
val selectedUsersListState = rememberLazyListState() val selectedUsersListState = rememberLazyListState()
var searchQuery by rememberSaveable { mutableStateOf("") } var searchQuery by rememberSaveable { mutableStateOf("") }
@ -76,10 +73,12 @@ class DefaultSelectUsersPresenter @AssistedInject constructor(
is SelectUsersEvents.OnSearchActiveChanged -> isSearchActive = event.active is SelectUsersEvents.OnSearchActiveChanged -> isSearchActive = event.active
is SelectUsersEvents.UpdateSearchQuery -> searchQuery = event.query is SelectUsersEvents.UpdateSearchQuery -> searchQuery = event.query
is SelectUsersEvents.AddToSelection -> { is SelectUsersEvents.AddToSelection -> {
selectedUsers.value = selectedUsers.value.plus(event.matrixUser).toImmutableSet() if (event.matrixUser !in selectedUsers.value) {
selectedUsers.value = selectedUsers.value.plus(event.matrixUser).toImmutableList()
}
localCoroutineScope.scrollToFirstSelectedUser(selectedUsersListState) localCoroutineScope.scrollToFirstSelectedUser(selectedUsersListState)
} }
is SelectUsersEvents.RemoveFromSelection -> selectedUsers.value = selectedUsers.value.minus(event.matrixUser).toImmutableSet() is SelectUsersEvents.RemoveFromSelection -> selectedUsers.value = selectedUsers.value.minus(event.matrixUser).toImmutableList()
} }
} }
@ -99,7 +98,7 @@ class DefaultSelectUsersPresenter @AssistedInject constructor(
return SelectUsersState( return SelectUsersState(
searchQuery = searchQuery, searchQuery = searchQuery,
searchResults = searchResults.value, searchResults = searchResults.value,
selectedUsers = selectedUsers.value.reversed().toImmutableSet(), selectedUsers = selectedUsers.value.reversed().toImmutableList(),
selectedUsersListState = selectedUsersListState, selectedUsersListState = selectedUsersListState,
isSearchActive = isSearchActive, isSearchActive = isSearchActive,
selectionMode = args.selectionMode, selectionMode = args.selectionMode,

View file

@ -105,27 +105,27 @@ class DefaultSelectUsersPresenterTests {
val userA = aMatrixUser("userA", "A") val userA = aMatrixUser("userA", "A")
val userB = aMatrixUser("userB", "B") val userB = aMatrixUser("userB", "B")
val userABis = aMatrixUser("userA", "A")
val userC = aMatrixUser("userC", "C")
initialState.eventSink(SelectUsersEvents.AddToSelection(userA)) initialState.eventSink(SelectUsersEvents.AddToSelection(userA))
val selectionAfterAddingA = awaitItem().selectedUsers assertThat(awaitItem().selectedUsers).containsExactly(userA)
assertThat(selectionAfterAddingA).hasSize(1)
assertThat(selectionAfterAddingA).contains(userA)
initialState.eventSink(SelectUsersEvents.AddToSelection(userB)) initialState.eventSink(SelectUsersEvents.AddToSelection(userB))
val selectionAfterAddingB = awaitItem().selectedUsers
assertThat(selectionAfterAddingB).hasSize(2)
assertThat(selectionAfterAddingB).contains(userA)
assertThat(selectionAfterAddingB).contains(userB)
// the last added user should be presented first // the last added user should be presented first
assertThat(selectionAfterAddingB.first()).isEqualTo(userB) assertThat(awaitItem().selectedUsers).containsExactly(userB, userA)
initialState.eventSink(SelectUsersEvents.AddToSelection(userABis))
initialState.eventSink(SelectUsersEvents.AddToSelection(userC))
// duplicated users should be ignored
assertThat(awaitItem().selectedUsers).containsExactly(userC, userB, userA)
initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userB)) initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userB))
val selectionAfterRemovingB = awaitItem().selectedUsers assertThat(awaitItem().selectedUsers).containsExactly(userC, userA)
assertThat(selectionAfterRemovingB).hasSize(1)
assertThat(selectionAfterRemovingB).contains(userA)
initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userA)) initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userA))
val selectionAfterRemovingA = awaitItem().selectedUsers assertThat(awaitItem().selectedUsers).containsExactly(userC)
assertThat(selectionAfterRemovingA).isEmpty() initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userC))
assertThat(awaitItem().selectedUsers).isEmpty()
} }
} }
} }