Add progress indicator in some FeedTab dialogs

This commit is contained in:
Shinokuni 2024-07-11 14:26:23 +02:00
parent d14ea9109b
commit 85b830b82b
5 changed files with 60 additions and 32 deletions

View File

@ -144,13 +144,14 @@ class FeedScreenModel(
it.copy( it.copy(
value = "", value = "",
textFieldError = null, textFieldError = null,
exception = null exception = null,
isLoading = false
) )
} }
} }
is DialogState.UpdateFeed -> { is DialogState.UpdateFeed -> {
_updateFeedDialogState.update { it.copy(exception = null) } _updateFeedDialogState.update { it.copy(exception = null, isLoading = false) }
} }
else -> {} else -> {}
@ -337,7 +338,7 @@ class FeedScreenModel(
} }
else -> { else -> {
_updateFeedDialogState.update { it.copy(exception = null) } _updateFeedDialogState.update { it.copy(exception = null, isLoading = true) }
screenModelScope.launch(dispatcher) { screenModelScope.launch(dispatcher) {
with(_updateFeedDialogState.value) { with(_updateFeedDialogState.value) {
@ -355,12 +356,12 @@ class FeedScreenModel(
) )
) )
} catch (e: Exception) { } catch (e: Exception) {
_updateFeedDialogState.update { it.copy(exception = e) } _updateFeedDialogState.update { it.copy(exception = e, isLoading = false) }
return@launch return@launch
} }
} }
closeDialog() closeDialog(_feedState.value.dialog)
} }
} }
} }
@ -378,10 +379,16 @@ class FeedScreenModel(
} }
fun folderValidate(updateFolder: Boolean = false) { fun folderValidate(updateFolder: Boolean = false) {
_folderState.update { it.copy(isLoading = true) }
val name = _folderState.value.value val name = _folderState.value.value
if (name.isEmpty()) { if (name.isEmpty()) {
_folderState.update { it.copy(textFieldError = TextFieldError.EmptyField) } _folderState.update {
it.copy(
textFieldError = TextFieldError.EmptyField,
isLoading = false
)
}
return return
} }
@ -394,11 +401,11 @@ class FeedScreenModel(
repository?.addFolder(Folder(name = name, accountId = currentAccount!!.id)) repository?.addFolder(Folder(name = name, accountId = currentAccount!!.id))
} }
} catch (e: Exception) { } catch (e: Exception) {
_folderState.update { it.copy(exception = e) } _folderState.update { it.copy(exception = e, isLoading = false) }
return@launch return@launch
} }
closeDialog(DialogState.AddFolder) closeDialog(_feedState.value.dialog)
} }
} }

View File

@ -50,7 +50,8 @@ data class UpdateFeedDialogState(
val folders: List<Folder> = listOf(), val folders: List<Folder> = listOf(),
val isAccountDropDownExpanded: Boolean = false, val isAccountDropDownExpanded: Boolean = false,
val isFeedUrlReadOnly: Boolean = true, val isFeedUrlReadOnly: Boolean = true,
val exception: Exception? = null val exception: Exception? = null,
val isLoading: Boolean = false
) { ) {
val isFeedNameError val isFeedNameError
get() = feedNameError != null get() = feedNameError != null
@ -60,13 +61,3 @@ data class UpdateFeedDialogState(
val hasFolders = folders.isNotEmpty() val hasFolders = folders.isNotEmpty()
} }
data class FolderState(
val folder: Folder = Folder(),
val nameError: TextFieldError? = null,
val exception: Exception? = null
) {
val name = folder.name
val isTextFieldError = nameError != null
}

View File

@ -8,7 +8,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme 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.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -19,6 +18,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.readrops.app.R import com.readrops.app.R
import com.readrops.app.feeds.FeedScreenModel import com.readrops.app.feeds.FeedScreenModel
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.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
@ -133,10 +133,10 @@ fun UpdateFeedDialog(
LargeSpacer() LargeSpacer()
TextButton( LoadingTextButton(
text = stringResource(R.string.validate),
isLoading = state.isLoading,
onClick = { viewModel.updateFeedDialogValidate() }, onClick = { viewModel.updateFeedDialogValidate() },
) { )
Text(text = stringResource(R.string.validate))
}
} }
} }

View File

@ -0,0 +1,29 @@
package com.readrops.app.util.components
import androidx.compose.foundation.layout.size
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun LoadingTextButton(
text: String,
isLoading: Boolean,
onClick: () -> Unit
) {
TextButton(
onClick = onClick
) {
if (isLoading) {
CircularProgressIndicator(
strokeWidth = 2.dp,
modifier = Modifier.size(16.dp)
)
} else {
Text(text = text)
}
}
}

View File

@ -7,7 +7,6 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme 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.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
@ -15,13 +14,15 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.readrops.app.R import com.readrops.app.R
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.TextFieldError import com.readrops.app.util.components.TextFieldError
import com.readrops.app.util.theme.LargeSpacer import com.readrops.app.util.theme.LargeSpacer
data class TextFieldDialogState( data class TextFieldDialogState(
val value: String = "", val value: String = "",
val textFieldError: TextFieldError? = null, val textFieldError: TextFieldError? = null,
val exception: Exception? = null val exception: Exception? = null,
val isLoading: Boolean = false
) { ) {
val isTextFieldError val isTextFieldError
get() = textFieldError != null get() = textFieldError != null
@ -36,12 +37,12 @@ fun TextFieldDialog(
onValueChange: (String) -> Unit, onValueChange: (String) -> Unit,
onValidate: () -> Unit, onValidate: () -> Unit,
onDismiss: () -> Unit, onDismiss: () -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier,
) { ) {
BaseDialog( BaseDialog(
title = title, title = title,
icon = icon, icon = icon,
onDismiss = onDismiss, onDismiss = { if (!state.isLoading) onDismiss() },
modifier = modifier modifier = modifier
) { ) {
OutlinedTextField( OutlinedTextField(
@ -74,10 +75,10 @@ fun TextFieldDialog(
LargeSpacer() LargeSpacer()
TextButton( LoadingTextButton(
text = stringResource(R.string.validate),
isLoading = state.isLoading,
onClick = { onValidate() }, onClick = { onValidate() },
) { )
Text(text = stringResource(R.string.validate))
}
} }
} }