From 5a0affdf3b188736ee372b57cd9820cae794d87d Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Mon, 19 Feb 2024 22:43:53 +0100 Subject: [PATCH] Improve the use of BaseDialog --- .../selection/AccountSelectionDialog.kt | 79 ++----- .../readrops/app/compose/feeds/FeedState.kt | 2 + .../compose/feeds/dialogs/AddFeedDialog.kt | 181 ++++++--------- .../app/compose/feeds/dialogs/FolderDialog.kt | 13 +- .../compose/feeds/dialogs/UpdateFeedDialog.kt | 207 +++++++----------- .../app/compose/util/components/BaseDialog.kt | 11 - 6 files changed, 189 insertions(+), 304 deletions(-) diff --git a/appcompose/src/main/java/com/readrops/app/compose/account/selection/AccountSelectionDialog.kt b/appcompose/src/main/java/com/readrops/app/compose/account/selection/AccountSelectionDialog.kt index 044851cf..e75c66a5 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/account/selection/AccountSelectionDialog.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/account/selection/AccountSelectionDialog.kt @@ -1,26 +1,13 @@ package com.readrops.app.compose.account.selection -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Card -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -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.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog import com.readrops.app.compose.R +import com.readrops.app.compose.util.components.BaseDialog import com.readrops.app.compose.util.components.SelectableImageText -import com.readrops.app.compose.util.theme.MediumSpacer import com.readrops.app.compose.util.theme.spacing import com.readrops.db.entities.account.AccountType @@ -29,52 +16,26 @@ fun AccountSelectionDialog( onDismiss: () -> Unit, onValidate: (AccountType) -> Unit, ) { - Dialog( - onDismissRequest = onDismiss + BaseDialog( + title = stringResource(R.string.new_account), + icon = painterResource(id = R.drawable.ic_add_account), + onDismiss = onDismiss ) { - Card( - shape = RoundedCornerShape(24.dp) - ) { - Column( - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.background) - .padding(MaterialTheme.spacing.largeSpacing) - ) { - Icon( - painter = painterResource(id = R.drawable.ic_add_account), - contentDescription = null, - modifier = Modifier.size(MaterialTheme.spacing.largeSpacing) - ) - - MediumSpacer() - - Text( - text = stringResource(R.string.new_account), - style = MaterialTheme.typography.headlineSmall - ) - - MediumSpacer() - - AccountType.values().forEach { type -> - SelectableImageText( - image = painterResource( - id = if (type != AccountType.LOCAL) - type.iconRes - else - R.drawable.ic_rss_feed_grey - ), - text = stringResource(id = type.typeName), - style = MaterialTheme.typography.titleMedium, - spacing = MaterialTheme.spacing.mediumSpacing, - padding = MaterialTheme.spacing.shortSpacing, - imageSize = 36.dp, - onClick = { onValidate(type) } - ) - } - } + AccountType.values().forEach { type -> + SelectableImageText( + image = painterResource( + id = if (type != AccountType.LOCAL) + type.iconRes + else + R.drawable.ic_rss_feed_grey + ), + text = stringResource(id = type.typeName), + style = MaterialTheme.typography.titleMedium, + spacing = MaterialTheme.spacing.mediumSpacing, + padding = MaterialTheme.spacing.shortSpacing, + imageSize = 36.dp, + onClick = { onValidate(type) } + ) } } } \ No newline at end of file diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedState.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedState.kt index f969d32c..5488dfa9 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedState.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedState.kt @@ -56,6 +56,8 @@ data class UpdateFeedDialogState( val isFeedUrlReadOnly: Boolean get() = accountType != null && !accountType.accountConfig!!.isFeedUrlEditable + + val hasFolders = folders.isNotEmpty() } data class FolderState( diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/AddFeedDialog.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/AddFeedDialog.kt index 08fb00cf..c8e3ee79 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/AddFeedDialog.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/AddFeedDialog.kt @@ -1,22 +1,13 @@ package com.readrops.app.compose.feeds.dialogs -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Clear -import androidx.compose.material3.Card import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -25,19 +16,15 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -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 androidx.compose.ui.window.Dialog import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.readrops.app.compose.R import com.readrops.app.compose.feeds.FeedViewModel +import com.readrops.app.compose.util.components.BaseDialog import com.readrops.app.compose.util.theme.LargeSpacer -import com.readrops.app.compose.util.theme.MediumSpacer import com.readrops.app.compose.util.theme.ShortSpacer -import com.readrops.app.compose.util.theme.spacing @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -49,96 +36,50 @@ fun AddFeedDialog( var isExpanded by remember { mutableStateOf(false) } - Dialog( - onDismissRequest = onDismiss + BaseDialog( + title = stringResource(R.string.add_feed_item), + icon = painterResource(id = R.drawable.ic_rss_feed_grey), + onDismiss = onDismiss ) { - Card( - shape = RoundedCornerShape(24.dp), - ) { - Column( - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.background) - .padding(MaterialTheme.spacing.largeSpacing) - ) { - Icon( - painter = painterResource(id = R.drawable.ic_rss_feed_grey), - contentDescription = null, - modifier = Modifier.size(MaterialTheme.spacing.largeSpacing) - ) - - MediumSpacer() - - Text( - text = stringResource(R.string.add_feed_item), - style = MaterialTheme.typography.headlineSmall - ) - - MediumSpacer() - - OutlinedTextField( - value = state.url, - label = { - Text(text = "URL") - }, - onValueChange = { viewModel.setAddFeedDialogURL(it) }, - singleLine = true, - trailingIcon = { - if (state.url.isNotEmpty()) { - IconButton( - onClick = { viewModel.setAddFeedDialogURL("") } - ) { - Icon( - imageVector = Icons.Default.Clear, - contentDescription = null - ) - } - } - }, - isError = state.isError, - supportingText = { Text(state.error?.errorText().orEmpty()) } - ) - - ShortSpacer() - - ExposedDropdownMenuBox( - expanded = isExpanded, - onExpandedChange = { isExpanded = isExpanded.not() } - ) { - ExposedDropdownMenu( - expanded = isExpanded, - onDismissRequest = { isExpanded = false } + OutlinedTextField( + value = state.url, + label = { + Text(text = "URL") + }, + onValueChange = { viewModel.setAddFeedDialogURL(it) }, + singleLine = true, + trailingIcon = { + if (state.url.isNotEmpty()) { + IconButton( + onClick = { viewModel.setAddFeedDialogURL("") } ) { - for (account in state.accounts) { - DropdownMenuItem( - text = { Text(text = account.accountName!!) }, - onClick = { - isExpanded = false - viewModel.setAddFeedDialogSelectedAccount(account) - }, - leadingIcon = { - Icon( - painter = painterResource( - id = if (state.selectedAccount.isLocal) { - R.drawable.ic_rss_feed_grey - } else - state.selectedAccount.accountType!!.iconRes - ), - contentDescription = null - ) - } - ) - } + Icon( + imageVector = Icons.Default.Clear, + contentDescription = null + ) } + } + }, + isError = state.isError, + supportingText = { Text(state.error?.errorText().orEmpty()) } + ) - OutlinedTextField( - value = state.selectedAccount.accountName!!, - readOnly = true, - onValueChange = {}, - trailingIcon = { - ExposedDropdownMenuDefaults.TrailingIcon(expanded = isExpanded) + ShortSpacer() + + ExposedDropdownMenuBox( + expanded = isExpanded, + onExpandedChange = { isExpanded = isExpanded.not() } + ) { + ExposedDropdownMenu( + expanded = isExpanded, + onDismissRequest = { isExpanded = false } + ) { + for (account in state.accounts) { + DropdownMenuItem( + text = { Text(text = account.accountName!!) }, + onClick = { + isExpanded = false + viewModel.setAddFeedDialogSelectedAccount(account) }, leadingIcon = { Icon( @@ -150,19 +91,39 @@ fun AddFeedDialog( ), contentDescription = null ) - }, - modifier = Modifier.menuAnchor() + } ) } - - LargeSpacer() - - TextButton( - onClick = { viewModel.addFeedDialogValidate() }, - ) { - Text(text = stringResource(R.string.validate)) - } } + + OutlinedTextField( + value = state.selectedAccount.accountName!!, + readOnly = true, + onValueChange = {}, + trailingIcon = { + ExposedDropdownMenuDefaults.TrailingIcon(expanded = isExpanded) + }, + leadingIcon = { + Icon( + painter = painterResource( + id = if (state.selectedAccount.isLocal) { + R.drawable.ic_rss_feed_grey + } else + state.selectedAccount.accountType!!.iconRes + ), + contentDescription = null + ) + }, + modifier = Modifier.menuAnchor() + ) + } + + LargeSpacer() + + TextButton( + onClick = { viewModel.addFeedDialogValidate() }, + ) { + Text(text = stringResource(R.string.validate)) } } } diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/FolderDialog.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/FolderDialog.kt index c8d1bdcf..c8c23382 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/FolderDialog.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/FolderDialog.kt @@ -6,6 +6,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.res.painterResource @@ -14,6 +15,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.readrops.app.compose.R import com.readrops.app.compose.feeds.FeedViewModel import com.readrops.app.compose.util.components.BaseDialog +import com.readrops.app.compose.util.theme.LargeSpacer @Composable fun FolderDialog( @@ -27,8 +29,7 @@ fun FolderDialog( BaseDialog( title = stringResource(id = if (updateFolder) R.string.edit_folder else R.string.add_folder), icon = painterResource(id = if (updateFolder) R.drawable.ic_folder_grey else R.drawable.ic_new_folder), - onDismiss = onDismiss, - onValidate = onValidate + onDismiss = onDismiss ) { OutlinedTextField( value = state.name.orEmpty(), @@ -52,5 +53,13 @@ fun FolderDialog( isError = state.isError, supportingText = { Text(text = state.nameError?.errorText().orEmpty()) } ) + + LargeSpacer() + + TextButton( + onClick = { onValidate() }, + ) { + Text(text = stringResource(R.string.validate)) + } } } \ No newline at end of file diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/UpdateFeedDialog.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/UpdateFeedDialog.kt index d24b5015..e1465442 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/UpdateFeedDialog.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/dialogs/UpdateFeedDialog.kt @@ -1,36 +1,24 @@ package com.readrops.app.compose.feeds.dialogs -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Card import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable 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 androidx.compose.ui.window.Dialog import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.readrops.app.compose.R import com.readrops.app.compose.feeds.FeedViewModel +import com.readrops.app.compose.util.components.BaseDialog import com.readrops.app.compose.util.theme.LargeSpacer import com.readrops.app.compose.util.theme.MediumSpacer -import com.readrops.app.compose.util.theme.spacing @OptIn(ExperimentalMaterial3Api::class) @@ -41,122 +29,97 @@ fun UpdateFeedDialog( ) { val state by viewModel.updateFeedDialogState.collectAsStateWithLifecycle() - Dialog( - onDismissRequest = onDismissRequest + BaseDialog( + title = stringResource(R.string.edit_feed), + icon = painterResource(id = R.drawable.ic_rss_feed_grey), + onDismiss = onDismissRequest ) { - Card( - shape = RoundedCornerShape(24.dp) - ) { - Column( - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.background) - .padding(MaterialTheme.spacing.largeSpacing) - ) { - Icon( - painter = painterResource(id = R.drawable.ic_rss_feed_grey), - contentDescription = null, - modifier = Modifier.size(MaterialTheme.spacing.largeSpacing) - ) - - MediumSpacer() - - Text( - text = stringResource(R.string.edit_feed), - style = MaterialTheme.typography.headlineSmall - ) - - MediumSpacer() - - OutlinedTextField( - value = state.feedName, - onValueChange = { viewModel.setUpdateFeedDialogStateFeedName(it) }, - label = { Text(text = stringResource(R.string.feed_name)) }, - singleLine = true, - isError = state.isFeedNameError, - supportingText = { - if (state.isFeedNameError) { - Text( - text = state.feedNameError?.errorText().orEmpty() - ) - } - } - ) - - MediumSpacer() - - OutlinedTextField( - value = state.feedUrl, - onValueChange = { viewModel.setUpdateFeedDialogFeedUrl(it) }, - label = { Text(text = stringResource(R.string.feed_url)) }, - singleLine = true, - readOnly = state.isFeedUrlReadOnly, - isError = state.isFeedUrlError, - supportingText = { - if (state.isFeedUrlError) { - Text( - text = state.feedUrlError?.errorText().orEmpty() - ) - } - } - ) - - MediumSpacer() - - ExposedDropdownMenuBox( - expanded = state.isAccountDropDownExpanded, - onExpandedChange = { viewModel.setAccountDropDownState(state.isAccountDropDownExpanded.not()) } - ) { - ExposedDropdownMenu( - expanded = state.isAccountDropDownExpanded, - onDismissRequest = { viewModel.setAccountDropDownState(false) } - ) { - for (folder in state.folders) { - DropdownMenuItem( - text = { Text(text = folder.name!!) }, - onClick = { - viewModel.setSelectedFolder(folder) - viewModel.setAccountDropDownState(false) - }, - leadingIcon = { - Icon( - painterResource(id = R.drawable.ic_folder_grey), - contentDescription = null, - ) - } - ) - } - } - - OutlinedTextField( - value = state.selectedFolder?.name.orEmpty(), - readOnly = true, - onValueChange = {}, - trailingIcon = { - ExposedDropdownMenuDefaults.TrailingIcon(expanded = state.isAccountDropDownExpanded) - }, - leadingIcon = { - if (state.selectedFolder != null) { - Icon( - painterResource(id = R.drawable.ic_folder_grey), - contentDescription = null, - ) - } - }, - modifier = Modifier.menuAnchor() + OutlinedTextField( + value = state.feedName, + onValueChange = { viewModel.setUpdateFeedDialogStateFeedName(it) }, + label = { Text(text = stringResource(R.string.feed_name)) }, + singleLine = true, + isError = state.isFeedNameError, + supportingText = { + if (state.isFeedNameError) { + Text( + text = state.feedNameError?.errorText().orEmpty() ) } + } + ) - LargeSpacer() + MediumSpacer() - TextButton( - onClick = { viewModel.updateFeedDialogValidate() }, - ) { - Text(text = stringResource(R.string.validate)) + OutlinedTextField( + value = state.feedUrl, + onValueChange = { viewModel.setUpdateFeedDialogFeedUrl(it) }, + label = { Text(text = stringResource(R.string.feed_url)) }, + singleLine = true, + readOnly = state.isFeedUrlReadOnly, + isError = state.isFeedUrlError, + supportingText = { + if (state.isFeedUrlError) { + Text( + text = state.feedUrlError?.errorText().orEmpty() + ) } } + ) + + MediumSpacer() + + ExposedDropdownMenuBox( + expanded = state.isAccountDropDownExpanded && state.hasFolders, + onExpandedChange = { viewModel.setAccountDropDownState(state.isAccountDropDownExpanded.not()) } + ) { + ExposedDropdownMenu( + expanded = state.isAccountDropDownExpanded && state.hasFolders, + onDismissRequest = { viewModel.setAccountDropDownState(false) } + ) { + for (folder in state.folders) { + DropdownMenuItem( + text = { Text(text = folder.name!!) }, + onClick = { + viewModel.setSelectedFolder(folder) + viewModel.setAccountDropDownState(false) + }, + leadingIcon = { + Icon( + painterResource(id = R.drawable.ic_folder_grey), + contentDescription = null, + ) + } + ) + } + } + + OutlinedTextField( + value = state.selectedFolder?.name.orEmpty(), + readOnly = true, + enabled = state.hasFolders, + onValueChange = {}, + trailingIcon = { + ExposedDropdownMenuDefaults.TrailingIcon(expanded = state.isAccountDropDownExpanded) + }, + leadingIcon = { + if (state.selectedFolder != null) { + Icon( + painterResource(id = R.drawable.ic_folder_grey), + contentDescription = null, + ) + } + }, + modifier = Modifier.menuAnchor() + ) + } + + LargeSpacer() + + TextButton( + onClick = { viewModel.updateFeedDialogValidate() }, + ) { + Text(text = stringResource(R.string.validate)) } } } diff --git a/appcompose/src/main/java/com/readrops/app/compose/util/components/BaseDialog.kt b/appcompose/src/main/java/com/readrops/app/compose/util/components/BaseDialog.kt index 29018ef4..29132676 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/util/components/BaseDialog.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/util/components/BaseDialog.kt @@ -11,14 +11,12 @@ import androidx.compose.material3.Card import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text -import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog -import com.readrops.app.compose.util.theme.LargeSpacer import com.readrops.app.compose.util.theme.MediumSpacer import com.readrops.app.compose.util.theme.spacing @@ -27,7 +25,6 @@ fun BaseDialog( title: String, icon: Painter, onDismiss: () -> Unit, - onValidate: () -> Unit, content: @Composable () -> Unit ) { Dialog( @@ -60,14 +57,6 @@ fun BaseDialog( MediumSpacer() content() - - LargeSpacer() - - TextButton( - onClick = { onValidate() }, - ) { - Text(text = "Validate") - } } } }