From 341dfb478ed39e134fca9e0e4aeb8be5e26813dd Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Mon, 13 Mar 2023 16:17:55 +0100 Subject: [PATCH] Adding a view to list the selected users --- .../impl/selectmembers/SelectMembersState.kt | 4 +- .../SelectMembersStateProvider.kt | 15 +++- .../impl/selectmembers/SelectMembersView.kt | 83 ++++++++++++++++++- 3 files changed, 97 insertions(+), 5 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersState.kt index 58bbd033a3..bbcb205f9b 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersState.kt @@ -16,7 +16,9 @@ package io.element.android.features.createroom.impl.selectmembers +import io.element.android.libraries.matrix.ui.model.MatrixUser + data class SelectMembersState( - val selectedUserIds: List = emptyList(), + val selectedUsers: List = emptyList(), val eventSink: (SelectMembersEvents) -> Unit, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersStateProvider.kt index 6acff4d979..36da523160 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersStateProvider.kt @@ -17,15 +17,28 @@ package io.element.android.features.createroom.impl.selectmembers import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.model.MatrixUser open class SelectMembersStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aSelectMembersState(), - aSelectMembersState().copy(selectedUserIds = listOf("someUserId")) + aSelectMembersState().copy( + selectedUsers = listOf( + aMatrixUser(userName = "User"), + aMatrixUser(userName = "User with long name"), + ) + ) ) } fun aSelectMembersState() = SelectMembersState( eventSink = {} ) + +fun aMatrixUser(userName: String): MatrixUser { + return MatrixUser(id = UserId("@id"), username = userName, avatarData = AvatarData("@id", "U", size = AvatarSize.BIG)) +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersView.kt index 2443405251..a0a313b727 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/selectmembers/SelectMembersView.kt @@ -16,25 +16,43 @@ package io.element.android.features.createroom.impl.selectmembers +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton +import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.ui.strings.R as StringR @OptIn(ExperimentalMaterial3Api::class) @@ -50,18 +68,23 @@ fun SelectMembersView( Scaffold( topBar = { SelectMembersViewTopBar( - hasSelectedUsers = state.selectedUserIds.isNotEmpty(), + hasSelectedUsers = state.selectedUsers.isNotEmpty(), onBackPressed = onBackPressed, onNextPressed = onNextPressed, ) } ) { padding -> - Box( + Column( modifier = modifier .fillMaxSize() .padding(padding) ) { - + SelectedMembersList( + modifier = Modifier.padding(horizontal = 16.dp), + selectedUsers = state.selectedUsers, + ) + // TODO create ViewEvent to add/remove selected user + // TODO create a SearchUserView with multi selection option + callbacks } } } @@ -99,6 +122,60 @@ fun SelectMembersViewTopBar( ) } +@Composable +fun SelectedMembersList( + selectedUsers: List, + modifier: Modifier = Modifier, + onUserRemoved: (MatrixUser) -> Unit = {}, +) { + LazyRow( + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(24.dp), + ) { + items(selectedUsers) { matrixUser -> + SelectedMember( + matrixUser = matrixUser, + onUserRemoved = onUserRemoved, + ) + } + } +} + +@Composable +fun SelectedMember( + matrixUser: MatrixUser, + modifier: Modifier = Modifier, + onUserRemoved: (MatrixUser) -> Unit, +) { + Box(modifier = modifier.width(56.dp)) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Avatar(matrixUser.avatarData) + Text( + text = matrixUser.username.orEmpty(), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = MaterialTheme.typography.bodyLarge, + ) + } + IconButton( + modifier = Modifier + .clip(CircleShape) + .background(MaterialTheme.colorScheme.primary) + .size(20.dp) + .align(Alignment.TopEnd), + onClick = { onUserRemoved(matrixUser) } + ) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = stringResource(id = StringR.string.action_remove), + tint = MaterialTheme.colorScheme.onPrimary, + ) + } + } +} + @Preview @Composable internal fun ChangeServerViewLightPreview(@PreviewParameter(SelectMembersStateProvider::class) state: SelectMembersState) =