Extract state from AddFeedDialog

This commit is contained in:
Shinokuni 2024-07-11 17:53:01 +02:00
parent 6cb8c2853d
commit f57d39ec3b
5 changed files with 41 additions and 38 deletions

View File

@ -222,7 +222,11 @@ class FeedScreenModel(
} }
fun setAddFeedDialogSelectedAccount(account: Account) { fun setAddFeedDialogSelectedAccount(account: Account) {
_addFeedDialogState.update { it.copy(selectedAccount = account) } _addFeedDialogState.update { it.copy(selectedAccount = account, isAccountDropDownExpanded = false) }
}
fun setAccountDropDownExpanded(isExpanded: Boolean) {
_addFeedDialogState.update { it.copy(isAccountDropDownExpanded = isExpanded) }
} }
fun addFeedDialogValidate() { fun addFeedDialogValidate() {
@ -319,9 +323,9 @@ class FeedScreenModel(
//region Update feed //region Update feed
fun setAccountDropDownState(isExpanded: Boolean) { fun setFolderDropDownState(isExpanded: Boolean) {
_updateFeedDialogState.update { _updateFeedDialogState.update {
it.copy(isAccountDropDownExpanded = isExpanded) it.copy(isFolderDropDownExpanded = isExpanded)
} }
} }

View File

@ -35,7 +35,8 @@ data class AddFeedDialogState(
val accounts: List<Account> = listOf(), val accounts: List<Account> = listOf(),
val error: TextFieldError? = null, val error: TextFieldError? = null,
val exception: Exception? = null, val exception: Exception? = null,
val isLoading: Boolean = false val isLoading: Boolean = false,
val isAccountDropDownExpanded: Boolean = false
) { ) {
val isError: Boolean get() = error != null val isError: Boolean get() = error != null
} }
@ -49,7 +50,7 @@ data class UpdateFeedDialogState(
val feedUrlError: TextFieldError? = null, val feedUrlError: TextFieldError? = null,
val selectedFolder: Folder? = null, val selectedFolder: Folder? = null,
val folders: List<Folder> = listOf(), val folders: List<Folder> = listOf(),
val isAccountDropDownExpanded: Boolean = false, val isFolderDropDownExpanded: Boolean = false,
val isFeedUrlReadOnly: Boolean = true, val isFeedUrlReadOnly: Boolean = true,
val exception: Exception? = null, val exception: Exception? = null,
val isLoading: Boolean = false val isLoading: Boolean = false

View File

@ -231,15 +231,18 @@ object FeedTab : Tab {
private fun FeedDialogs(state: FeedState, screenModel: FeedScreenModel) { private fun FeedDialogs(state: FeedState, screenModel: FeedScreenModel) {
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
val addFeedDialogState by screenModel.addFeedDialogState.collectAsStateWithLifecycle()
val folderState by screenModel.folderState.collectAsStateWithLifecycle() val folderState by screenModel.folderState.collectAsStateWithLifecycle()
when (val dialog = state.dialog) { when (val dialog = state.dialog) {
is DialogState.AddFeed -> { is DialogState.AddFeed -> {
AddFeedDialog( AddFeedDialog(
screenModel = screenModel, state = addFeedDialogState,
onDismiss = { onValueChange = { screenModel.setAddFeedDialogURL(it) },
screenModel.closeDialog(DialogState.AddFeed) onExpandChange = { screenModel.setAccountDropDownExpanded(it) },
}, onAccountClick = { screenModel.setAddFeedDialogSelectedAccount(it) },
onValidate = { screenModel.addFeedDialogValidate() },
onDismiss = { screenModel.closeDialog(DialogState.AddFeed) },
) )
} }

View File

@ -14,37 +14,33 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.readrops.app.R import com.readrops.app.R
import com.readrops.app.account.selection.adaptiveIconPainterResource import com.readrops.app.account.selection.adaptiveIconPainterResource
import com.readrops.app.feeds.FeedScreenModel import com.readrops.app.feeds.AddFeedDialogState
import com.readrops.app.util.ErrorMessage import com.readrops.app.util.ErrorMessage
import com.readrops.app.util.components.LoadingTextButton import com.readrops.app.util.components.LoadingTextButton
import com.readrops.app.util.components.dialog.BaseDialog import com.readrops.app.util.components.dialog.BaseDialog
import com.readrops.app.util.theme.LargeSpacer import com.readrops.app.util.theme.LargeSpacer
import com.readrops.app.util.theme.MediumSpacer import com.readrops.app.util.theme.MediumSpacer
import com.readrops.app.util.theme.ShortSpacer import com.readrops.app.util.theme.ShortSpacer
import com.readrops.db.entities.account.Account
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun AddFeedDialog( fun AddFeedDialog(
screenModel: FeedScreenModel, state: AddFeedDialogState,
onDismiss: () -> Unit, onValueChange: (String) -> Unit,
onExpandChange: (Boolean) -> Unit,
onAccountClick: (Account) -> Unit,
onValidate: () -> Unit,
onDismiss: () -> Unit
) { ) {
val state by screenModel.addFeedDialogState.collectAsStateWithLifecycle()
var isExpanded by remember { mutableStateOf(false) }
BaseDialog( BaseDialog(
title = stringResource(R.string.add_feed_item), title = stringResource(R.string.add_feed_item),
icon = painterResource(id = R.drawable.ic_rss_feed_grey), icon = painterResource(id = R.drawable.ic_rss_feed_grey),
@ -53,12 +49,12 @@ fun AddFeedDialog(
OutlinedTextField( OutlinedTextField(
value = state.url, value = state.url,
label = { Text(text = stringResource(id = R.string.url)) }, label = { Text(text = stringResource(id = R.string.url)) },
onValueChange = { screenModel.setAddFeedDialogURL(it) }, onValueChange = { onValueChange(it) },
singleLine = true, singleLine = true,
trailingIcon = { trailingIcon = {
if (state.url.isNotEmpty()) { if (state.url.isNotEmpty()) {
IconButton( IconButton(
onClick = { screenModel.setAddFeedDialogURL("") } onClick = { onValueChange("") }
) { ) {
Icon( Icon(
imageVector = Icons.Default.Clear, imageVector = Icons.Default.Clear,
@ -74,19 +70,18 @@ fun AddFeedDialog(
ShortSpacer() ShortSpacer()
ExposedDropdownMenuBox( ExposedDropdownMenuBox(
expanded = isExpanded, expanded = state.isAccountDropDownExpanded,
onExpandedChange = { isExpanded = !isExpanded } onExpandedChange = { onExpandChange(!state.isAccountDropDownExpanded) }
) { ) {
ExposedDropdownMenu( ExposedDropdownMenu(
expanded = isExpanded, expanded = state.isAccountDropDownExpanded,
onDismissRequest = { isExpanded = false } onDismissRequest = { onExpandChange(false) }
) { ) {
for (account in state.accounts) { for (account in state.accounts) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = account.accountName!!) }, text = { Text(text = account.accountName!!) },
onClick = { onClick = {
isExpanded = false onAccountClick(account)
screenModel.setAddFeedDialogSelectedAccount(account)
}, },
leadingIcon = { leadingIcon = {
Image( Image(
@ -106,7 +101,7 @@ fun AddFeedDialog(
readOnly = true, readOnly = true,
onValueChange = {}, onValueChange = {},
trailingIcon = { trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = isExpanded) ExposedDropdownMenuDefaults.TrailingIcon(expanded = state.isAccountDropDownExpanded)
}, },
leadingIcon = { leadingIcon = {
Image( Image(
@ -125,7 +120,7 @@ fun AddFeedDialog(
MediumSpacer() MediumSpacer()
Text( Text(
text = ErrorMessage.get(state.exception!!, LocalContext.current), text = ErrorMessage.get(state.exception, LocalContext.current),
color = MaterialTheme.colorScheme.error, color = MaterialTheme.colorScheme.error,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
@ -136,7 +131,7 @@ fun AddFeedDialog(
LoadingTextButton( LoadingTextButton(
text = stringResource(id = R.string.validate), text = stringResource(id = R.string.validate),
isLoading = state.isLoading, isLoading = state.isLoading,
onClick = { screenModel.addFeedDialogValidate() }, onClick = onValidate,
) )
} }
} }

View File

@ -78,19 +78,19 @@ fun UpdateFeedDialog(
MediumSpacer() MediumSpacer()
ExposedDropdownMenuBox( ExposedDropdownMenuBox(
expanded = state.isAccountDropDownExpanded && state.hasFolders, expanded = state.isFolderDropDownExpanded && state.hasFolders,
onExpandedChange = { viewModel.setAccountDropDownState(state.isAccountDropDownExpanded.not()) } onExpandedChange = { viewModel.setFolderDropDownState(state.isFolderDropDownExpanded.not()) }
) { ) {
ExposedDropdownMenu( ExposedDropdownMenu(
expanded = state.isAccountDropDownExpanded && state.hasFolders, expanded = state.isFolderDropDownExpanded && state.hasFolders,
onDismissRequest = { viewModel.setAccountDropDownState(false) } onDismissRequest = { viewModel.setFolderDropDownState(false) }
) { ) {
for (folder in state.folders) { for (folder in state.folders) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(text = folder.name!!) }, text = { Text(text = folder.name!!) },
onClick = { onClick = {
viewModel.setSelectedFolder(folder) viewModel.setSelectedFolder(folder)
viewModel.setAccountDropDownState(false) viewModel.setFolderDropDownState(false)
}, },
leadingIcon = { leadingIcon = {
Icon( Icon(
@ -108,7 +108,7 @@ fun UpdateFeedDialog(
enabled = state.hasFolders, enabled = state.hasFolders,
onValueChange = {}, onValueChange = {},
trailingIcon = { trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = state.isAccountDropDownExpanded) ExposedDropdownMenuDefaults.TrailingIcon(expanded = state.isFolderDropDownExpanded)
}, },
leadingIcon = { leadingIcon = {
if (state.selectedFolder != null) { if (state.selectedFolder != null) {