From f13286782a9c5555de4ffa7202ae742b97b87e67 Mon Sep 17 00:00:00 2001 From: migulyaev Date: Fri, 22 Sep 2023 15:59:56 +0200 Subject: [PATCH] extract bottom sheet to separate class for reusage --- .../letro/contacts/ui/ContactsScreen.kt | 131 +++--------------- .../ui/common/LetroActionsBottomSheet.kt | 126 +++++++++++++++++ 2 files changed, 148 insertions(+), 109 deletions(-) create mode 100644 app/src/main/java/tech/relaycorp/letro/ui/common/LetroActionsBottomSheet.kt diff --git a/app/src/main/java/tech/relaycorp/letro/contacts/ui/ContactsScreen.kt b/app/src/main/java/tech/relaycorp/letro/contacts/ui/ContactsScreen.kt index 3275fbd4..8ce68049 100644 --- a/app/src/main/java/tech/relaycorp/letro/contacts/ui/ContactsScreen.kt +++ b/app/src/main/java/tech/relaycorp/letro/contacts/ui/ContactsScreen.kt @@ -1,24 +1,10 @@ package tech.relaycorp.letro.contacts.ui -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.compose.foundation.clickable 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.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Divider -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -26,22 +12,18 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import tech.relaycorp.letro.R import tech.relaycorp.letro.contacts.ContactsViewModel import tech.relaycorp.letro.contacts.model.Contact +import tech.relaycorp.letro.ui.common.BottomSheetAction +import tech.relaycorp.letro.ui.common.LetroActionsBottomSheet import tech.relaycorp.letro.ui.common.text.BoldText import tech.relaycorp.letro.ui.theme.LabelLargeProminent -import tech.relaycorp.letro.ui.theme.LetroColor -import tech.relaycorp.letro.ui.theme.TitleSmallProminent import tech.relaycorp.letro.ui.utils.SnackbarStringsProvider import tech.relaycorp.letro.utils.ext.showSnackbar -@OptIn(ExperimentalMaterial3Api::class) @Composable fun ContactsScreen( viewModel: ContactsViewModel, @@ -63,21 +45,27 @@ fun ContactsScreen( val deleteContactDialog = deleteContactDialogState Box { if (editBottomSheet.isShown && editBottomSheet.contact != null) { - ModalBottomSheet( - containerColor = MaterialTheme.colorScheme.surface, + LetroActionsBottomSheet( + title = editBottomSheet.contact.alias ?: editBottomSheet.contact.contactVeraId, onDismissRequest = { viewModel.onEditBottomSheetDismissed() }, - ) { - EditContactBottomSheet( - title = editBottomSheet.contact.alias ?: editBottomSheet.contact.contactVeraId, - onEditClick = { - viewModel.onEditContactClick() - onEditContactClick(editBottomSheet.contact) - }, - onDeleteClick = { - viewModel.onDeleteContactClick(editBottomSheet.contact) - }, - ) - } + actions = listOf( + BottomSheetAction( + icon = R.drawable.edit, + title = R.string.edit, + action = { + viewModel.onEditContactClick() + onEditContactClick(editBottomSheet.contact) + }, + ), + BottomSheetAction( + icon = R.drawable.ic_delete, + title = R.string.delete, + action = { + viewModel.onDeleteContactClick(editBottomSheet.contact) + }, + ), + ), + ) } else if (deleteContactDialog.isShown && deleteContactDialog.contact != null) { AlertDialog( onDismissRequest = { @@ -139,78 +127,3 @@ fun ContactsScreen( } } } - -@Composable -private fun EditContactBottomSheet( - title: String, - onEditClick: () -> Unit, - onDeleteClick: () -> Unit, -) { - Column( - modifier = Modifier - .padding( - PaddingValues( - bottom = 44.dp, - ), - ), - ) { - Text( - text = title, - style = MaterialTheme.typography.TitleSmallProminent, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier - .fillMaxWidth() - .padding( - start = 16.dp, - ), - ) - Spacer( - modifier = Modifier.height(14.dp), - ) - Divider( - color = MaterialTheme.colorScheme.outlineVariant, - ) - EditContactAction( - icon = R.drawable.edit, - title = R.string.edit, - onClick = onEditClick, - ) - EditContactAction( - icon = R.drawable.ic_delete, - title = R.string.delete, - onClick = onDeleteClick, - ) - } -} - -@Composable -private fun EditContactAction( - @DrawableRes icon: Int, - @StringRes title: Int, - onClick: () -> Unit, -) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .clickable { onClick() } - .padding( - vertical = 14.dp, - horizontal = 16.dp, - ), - ) { - Icon( - painter = painterResource(id = icon), - contentDescription = null, - tint = LetroColor.OnSurfaceContainer, - ) - Spacer( - modifier = Modifier.width(16.dp), - ) - Text( - text = stringResource(id = title), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurface, - ) - } -} diff --git a/app/src/main/java/tech/relaycorp/letro/ui/common/LetroActionsBottomSheet.kt b/app/src/main/java/tech/relaycorp/letro/ui/common/LetroActionsBottomSheet.kt new file mode 100644 index 00000000..7ae42a07 --- /dev/null +++ b/app/src/main/java/tech/relaycorp/letro/ui/common/LetroActionsBottomSheet.kt @@ -0,0 +1,126 @@ +package tech.relaycorp.letro.ui.common + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +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.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import tech.relaycorp.letro.ui.theme.LetroColor +import tech.relaycorp.letro.ui.theme.TitleSmallProminent +import androidx.compose.ui.res.painterResource as painterResource1 + +data class BottomSheetAction( + @DrawableRes val icon: Int, + @StringRes val title: Int, + val action: () -> Unit, +) + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun LetroActionsBottomSheet( + title: String, + actions: List, + onDismissRequest: () -> Unit, +) { + ModalBottomSheet( + containerColor = MaterialTheme.colorScheme.surface, + onDismissRequest = { + onDismissRequest() + }, + ) { + BottomSheetContent( + actions = actions, + title = title, + ) + } +} + +@Composable +private fun BottomSheetContent( + actions: List, + title: String? = null, +) { + Column( + modifier = Modifier + .padding( + PaddingValues( + bottom = 44.dp, + ), + ), + ) { + if (title != null) { + Text( + text = title, + style = MaterialTheme.typography.TitleSmallProminent, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier + .fillMaxWidth() + .padding( + start = 16.dp, + ), + ) + Spacer( + modifier = Modifier.height(14.dp), + ) + Divider( + color = MaterialTheme.colorScheme.outlineVariant, + ) + } + LazyColumn { + items(actions) { + BottomSheetActionView(it.icon, it.title, it.action) + } + } + } +} + +@Composable +private fun BottomSheetActionView( + @DrawableRes icon: Int, + @StringRes title: Int, + onClick: () -> Unit, +) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .clickable { onClick() } + .padding( + vertical = 14.dp, + horizontal = 16.dp, + ), + ) { + Icon( + painter = painterResource1(id = icon), + contentDescription = null, + tint = LetroColor.OnSurfaceContainer, + ) + Spacer( + modifier = Modifier.width(16.dp), + ) + Text( + text = stringResource(id = title), + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.onSurface, + ) + } +}