Skip to content

Commit

Permalink
Created UserComposables for re-using Composables
Browse files Browse the repository at this point in the history
  • Loading branch information
nbradbury committed Sep 27, 2024
1 parent a307286 commit 1f87535
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 113 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package org.wordpress.android.ui.selfhostedusers

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
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.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import coil.request.ImageRequest
import org.wordpress.android.R
import org.wordpress.android.ui.compose.theme.M3Theme

@Composable
fun UserAvatar(avatarUrl: String?) {
if (avatarUrl.isNullOrEmpty()) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_user_placeholder_primary_24),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.size(48.dp)
)
} else {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(avatarUrl)
.error(R.drawable.ic_user_placeholder_primary_24)
.crossfade(true)
.build(),
contentScale = ContentScale.Fit,
contentDescription = null,
modifier = Modifier
.clip(CircleShape)
.size(48.dp),
)
}
}

@Composable
fun UserEmptyView(emptyText: String) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_people_white_24dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.size(85.dp)
)
Text(
text = emptyText,
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface,
)
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun UserScreen(
title: String,
content: @Composable () -> Unit,
onCloseClick: () -> Unit,
isScrollable: Boolean,
) {
M3Theme {
Scaffold(
topBar = {
TopAppBar(
title = { Text(title) },
navigationIcon = {
IconButton(onClick = onCloseClick) {
Icon(Icons.Filled.Close, stringResource(R.string.close))
}
},
)
},
) { contentPadding ->
Column(
modifier = if (isScrollable) {
Modifier
.fillMaxSize()
.imePadding()
.padding(contentPadding)
.verticalScroll(rememberScrollState())
} else {
Modifier
.fillMaxSize()
.imePadding()
.padding(contentPadding)
}
) {
content()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,49 +1,26 @@
package org.wordpress.android.ui.selfhostedusers

import android.content.res.Configuration
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import coil.request.ImageRequest
import kotlinx.coroutines.flow.MutableStateFlow
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.compose.theme.M3Theme
import uniffi.wp_api.UserWithEditContext

@Composable
Expand All @@ -59,12 +36,13 @@ fun UserListScreen(
if (users.value.isNotEmpty()) {
UserList(users.value)
} else {
EmptyView()
UserEmptyView(stringResource(R.string.no_users))
}
}
}
Screen(
UserScreen(
content = content,
title = stringResource(R.string.users),
onCloseClick = { onCloseClick() },
isScrollable = users.value.isNotEmpty()
)
Expand Down Expand Up @@ -117,94 +95,6 @@ private fun UserLazyRow(user: UserWithEditContext) {
}
}

@Composable
private fun UserAvatar(avatarUrl: String?) {
if (avatarUrl.isNullOrEmpty()) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_user_placeholder_primary_24),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.size(48.dp)
)
} else {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(avatarUrl)
.error(R.drawable.ic_user_placeholder_primary_24)
.crossfade(true)
.build(),
contentScale = ContentScale.Fit,
contentDescription = null,
modifier = Modifier
.clip(CircleShape)
.size(48.dp),
)
}
}

@Composable
private fun EmptyView() {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_people_white_24dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.size(85.dp)
)
Text(
text = stringResource(id = R.string.no_users),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface,
)
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun Screen(
content: @Composable () -> Unit,
onCloseClick: () -> Unit,
isScrollable: Boolean,
) {
M3Theme {
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(id = R.string.users)) },
navigationIcon = {
IconButton(onClick = onCloseClick) {
Icon(Icons.Filled.Close, stringResource(R.string.close))
}
},
)
},
) { contentPadding ->
Column(
modifier = if (isScrollable) {
Modifier
.fillMaxSize()
.imePadding()
.padding(contentPadding)
.verticalScroll(rememberScrollState())
} else {
Modifier
.fillMaxSize()
.imePadding()
.padding(contentPadding)
}
) {
content()
}
}
}
}

@Composable
@Preview(
name = "Light Mode",
Expand Down

0 comments on commit 1f87535

Please sign in to comment.