Adding a view to list the selected users

This commit is contained in:
Maxime NATUREL
2023-03-13 16:17:55 +01:00
committed by Florian Renaud
parent a41b025f5b
commit 341dfb478e
3 changed files with 97 additions and 5 deletions

View File

@@ -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<String> = emptyList(),
val selectedUsers: List<MatrixUser> = emptyList(),
val eventSink: (SelectMembersEvents) -> Unit,
)

View File

@@ -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<SelectMembersState> {
override val values: Sequence<SelectMembersState>
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))
}

View File

@@ -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<MatrixUser>,
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) =