From 040f74cda5ffbe74374c97b57fbb67c6670960ee Mon Sep 17 00:00:00 2001 From: John Oberhauser Date: Thu, 2 Nov 2023 11:21:38 -0500 Subject: [PATCH] adding loading and error states --- .../social/feature/account/AccountModule.kt | 1 + .../account/edit/EditAccountInteractions.kt | 1 + .../feature/account/edit/EditAccountScreen.kt | 84 ++++++++++--------- .../account/edit/EditAccountViewModel.kt | 10 ++- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/feature/account/src/main/java/org/mozilla/social/feature/account/AccountModule.kt b/feature/account/src/main/java/org/mozilla/social/feature/account/AccountModule.kt index 83714e62a..2eadf8cd7 100644 --- a/feature/account/src/main/java/org/mozilla/social/feature/account/AccountModule.kt +++ b/feature/account/src/main/java/org/mozilla/social/feature/account/AccountModule.kt @@ -32,6 +32,7 @@ val accountModule = module { EditAccountViewModel( get(), get(), + get(), ) } } \ No newline at end of file diff --git a/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountInteractions.kt b/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountInteractions.kt index 826289db9..167ec34f2 100644 --- a/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountInteractions.kt +++ b/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountInteractions.kt @@ -11,4 +11,5 @@ interface EditAccountInteractions { fun onNewHeaderSelected(uri: Uri, file: File) = Unit fun onLockClicked() = Unit fun onBotClicked() = Unit + fun onRetryClicked() = Unit } \ No newline at end of file diff --git a/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountScreen.kt b/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountScreen.kt index 607816d4e..ac39814ee 100644 --- a/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountScreen.kt +++ b/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountScreen.kt @@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -42,6 +41,8 @@ import org.mozilla.social.core.designsystem.icon.MoSoIcons import org.mozilla.social.core.designsystem.theme.MoSoTheme import org.mozilla.social.core.ui.TransparentNoTouchOverlay import org.mozilla.social.core.ui.appbar.MoSoCloseableTopAppBar +import org.mozilla.social.core.ui.error.GenericError +import org.mozilla.social.core.ui.loading.MaxSizeLoading import org.mozilla.social.feature.account.Header import org.mozilla.social.feature.account.R @@ -51,7 +52,7 @@ internal fun EditAccountScreen( ) { EditAccountScreen( editAccountInteractions = viewModel, - editAccountUiState = viewModel.editAccountUiState.collectAsState().value, + uiState = viewModel.editAccountUiState.collectAsState().value, isUploading = viewModel.isUploading.collectAsState().value, ) @@ -61,39 +62,59 @@ internal fun EditAccountScreen( @Composable fun EditAccountScreen( editAccountInteractions: EditAccountInteractions, - editAccountUiState: Resource, + uiState: Resource, isUploading: Boolean, ) { MoSoSurface( modifier = Modifier .fillMaxSize(), ) { - Box(modifier = Modifier.fillMaxSize()) { - Box( - modifier = Modifier - .systemBarsPadding() - .imePadding(), - ) { - when (editAccountUiState) { - is Resource.Loading -> {} - is Resource.Loaded -> { - LoadedState( - editAccountInteractions = editAccountInteractions, - uiState = editAccountUiState.data, - ) + Column( + modifier = Modifier + .systemBarsPadding() + .imePadding(), + ) { + MoSoCloseableTopAppBar( + title = (uiState as? Resource.Loaded)?.data?.topBarTitle ?: "", + actions = { + if (uiState is Resource.Loaded) { + MoSoButton( + modifier = Modifier + .padding(8.dp) + .height(38.dp), + onClick = { editAccountInteractions.onSaveClicked() } + ) { + Text(text = stringResource(id = R.string.edit_account_save_button)) + } } + }, + showDivider = false, + ) + - is Resource.Error -> {} + when (uiState) { + is Resource.Loading -> { + MaxSizeLoading() + } + is Resource.Loaded -> { + LoadedState( + editAccountInteractions = editAccountInteractions, + uiState = uiState.data, + ) } - } - if (isUploading) { - TransparentNoTouchOverlay() - CircularProgressIndicator( - modifier = Modifier.align(Alignment.Center), - ) + is Resource.Error -> { + GenericError( + onRetryClicked = editAccountInteractions::onRetryClicked + ) + } } } + + if (isUploading) { + TransparentNoTouchOverlay() + MaxSizeLoading() + } } } @@ -105,21 +126,6 @@ private fun LoadedState( val context = LocalContext.current Column { - MoSoCloseableTopAppBar( - title = uiState.topBarTitle, - actions = { - MoSoButton( - modifier = Modifier - .padding(8.dp) - .height(38.dp), - onClick = { editAccountInteractions.onSaveClicked() } - ) { - Text(text = stringResource(id = R.string.edit_account_save_button)) - } - }, - showDivider = false, - ) - val avatarSelectionLauncher = rememberLauncherForActivityResult( ActivityResultContracts.PickVisualMedia() ) { uri -> @@ -270,7 +276,7 @@ private fun BotAndLock( private fun PreviewEditAccountScreen() { MoSoTheme { EditAccountScreen( - editAccountUiState = Resource.Loaded( + uiState = Resource.Loaded( data = EditAccountUiState( topBarTitle = "John", headerUrl = "", diff --git a/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountViewModel.kt b/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountViewModel.kt index 5691709e9..c1265096f 100644 --- a/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountViewModel.kt +++ b/feature/account/src/main/java/org/mozilla/social/feature/account/edit/EditAccountViewModel.kt @@ -14,6 +14,7 @@ import org.mozilla.social.common.Resource import org.mozilla.social.common.utils.StringFactory import org.mozilla.social.core.data.repository.AccountRepository import org.mozilla.social.core.domain.AccountIdBlocking +import org.mozilla.social.core.navigation.usecases.PopNavBackstack import org.mozilla.social.feature.account.R import timber.log.Timber import java.io.File @@ -21,6 +22,7 @@ import java.io.File class EditAccountViewModel( private val accountRepository: AccountRepository, accountIdBlocking: AccountIdBlocking, + private val popNavBackstack: PopNavBackstack, ) : ViewModel(), EditAccountInteractions { private val accountId = accountIdBlocking() @@ -42,6 +44,7 @@ class EditAccountViewModel( } private fun loadAccount() { + _editAccountUiState.update { Resource.Loading() } viewModelScope.launch { try { val account = accountRepository.getAccountFromDatabase(accountId)!! @@ -63,6 +66,7 @@ class EditAccountViewModel( } } catch (e: Exception) { Timber.e(e) + _editAccountUiState.update { Resource.Error(e) } } } } @@ -106,7 +110,7 @@ class EditAccountViewModel( locked = data.lockChecked, bot = data.botChecked, ) - //TODO navigate back + popNavBackstack() } catch (e: Exception) { _errorToastMessage.emit(StringFactory.resource(R.string.edit_account_save_failed)) Timber.e(e) @@ -166,6 +170,10 @@ class EditAccountViewModel( } } + override fun onRetryClicked() { + loadAccount() + } + companion object { const val MAX_BIO_LENGTH = 500 }