From ac5f50d264a8899c52043cb7b45dd7075103ea38 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Mon, 3 Apr 2023 15:02:33 +0200 Subject: [PATCH] WIP create room screen --- features/createroom/impl/build.gradle.kts | 1 + .../configureroom/ConfigureRoomPresenter.kt | 4 +- .../impl/configureroom/ConfigureRoomState.kt | 5 +- .../ConfigureRoomStateProvider.kt | 5 +- .../impl/configureroom/ConfigureRoomView.kt | 195 +++++++++++++++++- .../features/userlist/api/UserListView.kt | 3 + 6 files changed, 207 insertions(+), 6 deletions(-) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 6f2544822c..77a5ed26be 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -49,6 +49,7 @@ dependencies { implementation(projects.libraries.uiStrings) implementation(projects.features.userlist.api) api(projects.features.createroom.api) + implementation(libs.coil.compose) // FIXME temp testImplementation(libs.test.junit) testImplementation(libs.coroutines.test) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 243769e90d..25851e41af 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -21,6 +21,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import io.element.android.libraries.architecture.Presenter +import kotlinx.collections.immutable.toImmutableList class ConfigureRoomPresenter @AssistedInject constructor( @Assisted val args: ConfigureRoomPresenterArgs, @@ -41,7 +42,8 @@ class ConfigureRoomPresenter @AssistedInject constructor( } return ConfigureRoomState( - selectedUsers = args.selectedUsers, + selectedUsers = args.selectedUsers.toImmutableList(), + avatarUri = null, eventSink = ::handleEvents, ) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt index b06f4e29b9..b8eee9e7bf 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt @@ -16,9 +16,12 @@ package io.element.android.features.createroom.impl.configureroom +import android.net.Uri import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.ImmutableList data class ConfigureRoomState( - val selectedUsers: List, + val selectedUsers: ImmutableList, + val avatarUri: Uri?, val eventSink: (ConfigureRoomEvents) -> Unit ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index f9701fdaa6..30100c720b 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -17,6 +17,8 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.matrix.ui.components.aMatrixUser +import kotlinx.collections.immutable.persistentListOf open class ConfigureRoomStateProvider : PreviewParameterProvider { override val values: Sequence @@ -27,6 +29,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider Unit = {}, + onCreatePressed: () -> Unit = {}, ) { - Box(modifier, contentAlignment = Alignment.Center) { + Scaffold( + modifier = modifier, + topBar = { + ConfigureRoomToolbar( + isNextActionEnabled = false, + onBackPressed = onBackPressed, + onNextPressed = onCreatePressed, + ) + } + ) { padding -> + Column( + modifier = Modifier.padding(padding), + verticalArrangement = Arrangement.spacedBy(24.dp), + ) { + RoomNameWithAvatar( + modifier = Modifier.padding(horizontal = 16.dp), + ) + RoomTopic( + modifier = Modifier.padding(horizontal = 16.dp), + ) + SelectedUsersList( + listState = LazyListState(), // FIXME + contentPadding = PaddingValues(horizontal = 24.dp), + selectedUsers = state.selectedUsers, + onUserRemoved = { + // TODO + }, + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ConfigureRoomToolbar( + isNextActionEnabled: Boolean, + modifier: Modifier = Modifier, + onBackPressed: () -> Unit = {}, + onNextPressed: () -> Unit = {}, +) { + CenterAlignedTopAppBar( + modifier = modifier, + title = { + Text( + text = "Create a room", + fontSize = 16.sp, + fontWeight = FontWeight.SemiBold, + ) + }, + navigationIcon = { BackButton(onClick = onBackPressed) }, + actions = { + TextButton( + modifier = Modifier.padding(horizontal = 8.dp), + enabled = isNextActionEnabled, + onClick = onNextPressed, + ) { + Text( + text = "Create", + fontSize = 16.sp, + ) + } + } + ) +} + +@Composable +fun RoomNameWithAvatar( + modifier: Modifier = Modifier, + avatarUri: Uri? = null, + roomName: String = "", + onAvatarClick: () -> Unit = {}, + onRoomNameChanged: (String) -> Unit = {}, +) { + Row( + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Avatar( + avatarUri = avatarUri, + onClick = onAvatarClick, + ) + + Column( + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + Text( + modifier = Modifier.padding(horizontal = 16.dp), + text = "Room name" + ) + + TextField( + modifier = Modifier.fillMaxWidth(), + value = roomName, + placeholder = { Text("e.g. Product Sprint") }, + onValueChange = onRoomNameChanged, + maxLines = 1, + ) + } + } +} + +@Composable +fun Avatar( + modifier: Modifier = Modifier, + avatarUri: Uri? = null, + onClick: () -> Unit = {}, +) { + val commonModifier = modifier + .size(70.dp) + .clip(CircleShape) + .clickable(onClick = onClick) + + if (avatarUri != null) { + val context = LocalContext.current + val model = ImageRequest.Builder(context) + .data(avatarUri) + .build() + AsyncImage( + model = model, + contentDescription = null, + modifier = commonModifier, + ) + } else { + Box( + modifier = commonModifier + .background(LocalColors.current.quinary) + ) { + Icon( + imageVector = Icons.Outlined.AddAPhoto, + contentDescription = "", + modifier = modifier + .align(Alignment.Center) + .size(40.dp), + tint = MaterialTheme.colorScheme.secondary, + ) + } + } +} + +@Composable +fun RoomTopic( + modifier: Modifier = Modifier, + topic: String = "", + onTopicChanged: (String) -> Unit = {}, +) { + Column( + modifier = modifier, + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { Text( - "ConfigureRoom feature view", - color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(horizontal = 16.dp), + text = "Topic (optional)", + ) + TextField( + modifier = Modifier.fillMaxWidth(), + value = topic, + placeholder = { Text("What is this room about?") }, + onValueChange = onTopicChanged, + maxLines = 3, ) } } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListView.kt b/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListView.kt index bc355a0a26..5605ed6028 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListView.kt +++ b/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListView.kt @@ -21,6 +21,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -244,11 +245,13 @@ fun SelectedUsersList( listState: LazyListState, selectedUsers: ImmutableList, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(0.dp), onUserRemoved: (MatrixUser) -> Unit = {}, ) { LazyRow( state = listState, modifier = modifier, + contentPadding = contentPadding, horizontalArrangement = Arrangement.spacedBy(24.dp), ) { items(selectedUsers.toList()) { matrixUser ->