From cdd6b64d8805f5c8bf3e194103138283b796b29f Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Fri, 11 Oct 2024 10:08:36 -0400 Subject: [PATCH 1/2] First pass at lazy --- .../selfhostedusers/SelfHostedUsersScreen.kt | 94 +++++++++---------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt b/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt index 27a13e40d350..fc7bb5ab52a0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt @@ -10,6 +10,8 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close @@ -55,12 +57,6 @@ fun SelfHostedUsersScreen( else -> Icons.AutoMirrored.Filled.ArrowBack } - val isScrollable = when (state) { - is SelfHostedUserState.UserList -> true - is SelfHostedUserState.UserDetail -> true - else -> false - } - Crossfade( targetState = state, animationSpec = tween( @@ -71,7 +67,7 @@ fun SelfHostedUsersScreen( ScreenWithTopBar( title = title, onCloseClick = { onCloseClick() }, - isScrollable = isScrollable, + isScrollable = false, closeIcon = closeIcon, ) { when (targetState) { @@ -122,9 +118,11 @@ private fun UserList( users: List, onUserClick: (UserWithEditContext) -> Unit ) { - for (user in users) { - UserListItem(user, onUserClick) - HorizontalDivider(thickness = 1.dp) + LazyColumn { + items(users) { user -> + UserListItem(user, onUserClick) + HorizontalDivider(thickness = 1.dp) + } } } @@ -181,50 +179,48 @@ private fun UserDetail( user: UserWithEditContext, onAvatarClick: (String?) -> Unit = {}, ) { - Row( + LazyColumn( modifier = Modifier .padding(all = userScreenPaddingDp) .fillMaxWidth() ) { - Column { - val avatarUrl = user.avatarUrls?.values?.firstOrNull() - SmallAvatar( - avatarUrl = avatarUrl, - contentDescription = stringResource(R.string.user_avatar_content_description, user.name), - onAvatarClick = if (avatarUrl.isNullOrEmpty()) { - null - } else { - onAvatarClick - } - ) - } - - Column( - modifier = Modifier - .padding(start = userScreenPaddingDp) - ) { - UserDetailSection(title = stringResource(R.string.name)) { - UserDetailItem( - label = stringResource(R.string.username), - text = user.username, + item { + Column { + val avatarUrl = user.avatarUrls?.values?.firstOrNull() + SmallAvatar( + avatarUrl = avatarUrl, + contentDescription = stringResource(R.string.user_avatar_content_description, user.name), + onAvatarClick = if (avatarUrl.isNullOrEmpty()) { + null + } else { + onAvatarClick + } ) - UserDetailItem( - label = stringResource(R.string.role), - text = user.roles.joinToString(), - ) - UserDetailItem( - label = stringResource(R.string.first_name), - text = user.firstName, - ) - UserDetailItem( - label = stringResource(R.string.last_name), - text = user.lastName, - ) - UserDetailItem( - label = stringResource(R.string.nickname), - text = user.nickname, - ) - // TODO display name is missing from the model + } + Column { + UserDetailSection(title = stringResource(R.string.name)) { + UserDetailItem( + label = stringResource(R.string.username), + text = user.username, + ) + UserDetailItem( + label = stringResource(R.string.role), + text = user.roles.joinToString(), + ) + UserDetailItem( + label = stringResource(R.string.first_name), + text = user.firstName, + ) + UserDetailItem( + label = stringResource(R.string.last_name), + text = user.lastName, + ) + UserDetailItem( + label = stringResource(R.string.nickname), + text = user.nickname, + ) + // TODO display name is missing from the model + } } UserDetailSection(title = stringResource(R.string.contact_info)) { From 65004ffde4a6e478083521fe1966f8f1f3ec783f Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Fri, 11 Oct 2024 11:29:58 -0400 Subject: [PATCH 2/2] Use LazyColumn for user list, changed user detail view to be scrollable --- .../SelfHostedUserComposables.kt | 13 +-- .../selfhostedusers/SelfHostedUsersScreen.kt | 83 ++++++++++--------- 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUserComposables.kt b/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUserComposables.kt index 9f848dd94368..4204493f7d7f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUserComposables.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUserComposables.kt @@ -11,10 +11,8 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Button @@ -177,7 +175,6 @@ fun MessageView( fun ScreenWithTopBar( title: String, onCloseClick: () -> Unit, - isScrollable: Boolean = false, closeIcon: ImageVector = Icons.Default.Close, content: @Composable () -> Unit, ) { @@ -194,18 +191,11 @@ fun ScreenWithTopBar( ) }, ) { contentPadding -> - val extraModifier = if (isScrollable) { - Modifier - .padding(contentPadding) - .verticalScroll(rememberScrollState()) - } else { - Modifier - } Column( modifier = Modifier .fillMaxSize() .imePadding() - .then(extraModifier) + .padding(contentPadding) ) { content() } @@ -233,6 +223,5 @@ private fun OfflineScreenPreview() { title = "Title", content = content, onCloseClick = {}, - isScrollable = false, ) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt b/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt index fc7bb5ab52a0..3b58e2ac8426 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/selfhostedusers/SelfHostedUsersScreen.kt @@ -12,6 +12,8 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close @@ -34,6 +36,7 @@ import org.wordpress.android.R import org.wordpress.android.ui.compose.components.ProgressDialog import org.wordpress.android.ui.compose.components.ProgressDialogState import org.wordpress.android.ui.selfhostedusers.SelfHostedUsersViewModel.SelfHostedUserState +import org.wordpress.android.util.AppLog import uniffi.wp_api.UserWithEditContext @Composable @@ -67,7 +70,6 @@ fun SelfHostedUsersScreen( ScreenWithTopBar( title = title, onCloseClick = { onCloseClick() }, - isScrollable = false, closeIcon = closeIcon, ) { when (targetState) { @@ -122,6 +124,8 @@ private fun UserList( items(users) { user -> UserListItem(user, onUserClick) HorizontalDivider(thickness = 1.dp) + // TODO remove logging + AppLog.d(AppLog.T.MAIN, "user: ${user.id}") } } } @@ -179,48 +183,51 @@ private fun UserDetail( user: UserWithEditContext, onAvatarClick: (String?) -> Unit = {}, ) { - LazyColumn( + Row( modifier = Modifier .padding(all = userScreenPaddingDp) .fillMaxWidth() + .verticalScroll(rememberScrollState()) ) { - item { - Column { - val avatarUrl = user.avatarUrls?.values?.firstOrNull() - SmallAvatar( - avatarUrl = avatarUrl, - contentDescription = stringResource(R.string.user_avatar_content_description, user.name), - onAvatarClick = if (avatarUrl.isNullOrEmpty()) { - null - } else { - onAvatarClick - } - ) - } - Column { - UserDetailSection(title = stringResource(R.string.name)) { - UserDetailItem( - label = stringResource(R.string.username), - text = user.username, - ) - UserDetailItem( - label = stringResource(R.string.role), - text = user.roles.joinToString(), - ) - UserDetailItem( - label = stringResource(R.string.first_name), - text = user.firstName, - ) - UserDetailItem( - label = stringResource(R.string.last_name), - text = user.lastName, - ) - UserDetailItem( - label = stringResource(R.string.nickname), - text = user.nickname, - ) - // TODO display name is missing from the model + Column { + val avatarUrl = user.avatarUrls?.values?.firstOrNull() + SmallAvatar( + avatarUrl = avatarUrl, + contentDescription = stringResource(R.string.user_avatar_content_description, user.name), + onAvatarClick = if (avatarUrl.isNullOrEmpty()) { + null + } else { + onAvatarClick } + ) + } + + Column( + modifier = Modifier + .padding(start = userScreenPaddingDp) + ) { + UserDetailSection(title = stringResource(R.string.name)) { + UserDetailItem( + label = stringResource(R.string.username), + text = user.username, + ) + UserDetailItem( + label = stringResource(R.string.role), + text = user.roles.joinToString(), + ) + UserDetailItem( + label = stringResource(R.string.first_name), + text = user.firstName, + ) + UserDetailItem( + label = stringResource(R.string.last_name), + text = user.lastName, + ) + UserDetailItem( + label = stringResource(R.string.nickname), + text = user.nickname, + ) + // TODO display name is missing from the model } UserDetailSection(title = stringResource(R.string.contact_info)) {