WIP create room screen
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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 = {}
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
Reference in New Issue
Block a user