WIP create room screen

This commit is contained in:
Florian Renaud
2023-04-03 15:02:33 +02:00
parent 0a926bd05a
commit ac5f50d264
6 changed files with 207 additions and 6 deletions

View File

@@ -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)

View File

@@ -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,
)
}

View File

@@ -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<MatrixUser>,
val selectedUsers: ImmutableList<MatrixUser>,
val avatarUri: Uri?,
val eventSink: (ConfigureRoomEvents) -> Unit
)

View File

@@ -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<ConfigureRoomState> {
override val values: Sequence<ConfigureRoomState>
@@ -27,6 +29,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
}
fun aConfigureRoomState() = ConfigureRoomState(
selectedUsers = emptyList(),
selectedUsers = persistentListOf(aMatrixUser(), aMatrixUser(), aMatrixUser(), aMatrixUser(), aMatrixUser(), aMatrixUser()),
avatarUri = null,
eventSink = {}
)

View File

@@ -16,26 +16,215 @@
package io.element.android.features.createroom.impl.configureroom
import android.net.Uri
import androidx.compose.foundation.background
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.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AddAPhoto
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.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
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 coil.compose.AsyncImage
import coil.request.ImageRequest
import io.element.android.features.selectusers.api.SelectedUsersList
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.LocalColors
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.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
import io.element.android.libraries.designsystem.theme.components.TextField
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ConfigureRoomView(
state: ConfigureRoomState,
modifier: Modifier = Modifier,
onBackPressed: () -> 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,
)
}
}

View File

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