Merge pull request #7569 from thunderbird/change-special-folder-success-to-loading
Change special folder success to loading and change navigation
This commit is contained in:
commit
4dad5313e4
9 changed files with 31 additions and 89 deletions
|
@ -129,8 +129,18 @@ fun AccountSetupNavHost(
|
|||
|
||||
composable(route = NESTED_NAVIGATION_SPECIAL_FOLDERS) {
|
||||
SpecialFoldersScreen(
|
||||
onNext = {
|
||||
navController.navigate(NESTED_NAVIGATION_DISPLAY_OPTIONS)
|
||||
onNext = { isManualSetup ->
|
||||
navController.navigate(NESTED_NAVIGATION_DISPLAY_OPTIONS) {
|
||||
if (isManualSetup) {
|
||||
popUpTo(NESTED_NAVIGATION_SPECIAL_FOLDERS)
|
||||
} else {
|
||||
if (isAutomaticConfig) {
|
||||
popUpTo(NESTED_NAVIGATION_AUTO_CONFIG)
|
||||
} else {
|
||||
popUpTo(NESTED_NAVIGATION_OUTGOING_SERVER_CONFIG)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onBack = { navController.popBackStack() },
|
||||
viewModel = koinViewModel<SpecialFoldersViewModel>(),
|
||||
|
|
|
@ -1,29 +1,19 @@
|
|||
package app.k9mail.feature.account.setup.ui.specialfolders
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.Icon
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.ContentLoadingErrorView
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.ErrorView
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.LoadingView
|
||||
import app.k9mail.core.ui.compose.designsystem.template.ResponsiveWidthContainer
|
||||
import app.k9mail.core.ui.compose.theme.Icons
|
||||
import app.k9mail.core.ui.compose.theme.MainTheme
|
||||
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
|
||||
import app.k9mail.feature.account.common.ui.AppTitleTopHeader
|
||||
|
@ -66,9 +56,9 @@ fun SpecialFoldersContent(
|
|||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
if (state.isSuccess) {
|
||||
SuccessView(
|
||||
LoadingView(
|
||||
message = stringResource(id = R.string.account_setup_special_folders_success_message),
|
||||
onEditClick = { onEvent(Event.OnEditClicked) },
|
||||
modifier = Modifier.padding(horizontal = MainTheme.spacings.double),
|
||||
)
|
||||
} else {
|
||||
SpecialFoldersFormContent(
|
||||
|
@ -82,46 +72,6 @@ fun SpecialFoldersContent(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SuccessView(
|
||||
message: String,
|
||||
onEditClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(MainTheme.spacings.double)
|
||||
.then(modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
|
||||
) {
|
||||
TextSubtitle1(
|
||||
text = message,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.height(MainTheme.sizes.larger),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.celebration,
|
||||
tint = MainTheme.colors.secondary,
|
||||
modifier = Modifier.requiredSize(MainTheme.sizes.large),
|
||||
)
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
ButtonText(
|
||||
text = stringResource(id = R.string.account_setup_special_folders_edit_folders_button_label),
|
||||
onClick = onEditClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SpecialFoldersErrorView(
|
||||
failure: SpecialFoldersContract.Failure,
|
||||
|
|
|
@ -15,6 +15,7 @@ interface SpecialFoldersContract {
|
|||
data class State(
|
||||
val formState: FormState = FormState(),
|
||||
|
||||
val isManualSetup: Boolean = false,
|
||||
val isSuccess: Boolean = false,
|
||||
override val error: Failure? = null,
|
||||
override val isLoading: Boolean = true,
|
||||
|
@ -36,7 +37,6 @@ interface SpecialFoldersContract {
|
|||
|
||||
sealed interface Event {
|
||||
data object LoadSpecialFolderOptions : Event
|
||||
data object OnEditClicked : Event
|
||||
data object OnRetryClicked : Event
|
||||
data object OnNextClicked : Event
|
||||
data object OnBackClicked : Event
|
||||
|
@ -51,7 +51,10 @@ interface SpecialFoldersContract {
|
|||
}
|
||||
|
||||
sealed interface Effect {
|
||||
data object NavigateNext : Effect
|
||||
data class NavigateNext(
|
||||
val isManualSetup: Boolean,
|
||||
) : Effect
|
||||
|
||||
data object NavigateBack : Effect
|
||||
}
|
||||
|
||||
|
|
|
@ -17,14 +17,14 @@ import app.k9mail.feature.account.setup.ui.specialfolders.fake.FakeSpecialFolder
|
|||
|
||||
@Composable
|
||||
fun SpecialFoldersScreen(
|
||||
onNext: () -> Unit,
|
||||
onNext: (isManualSetup: Boolean) -> Unit,
|
||||
onBack: () -> Unit,
|
||||
viewModel: ViewModel,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val (state, dispatch) = viewModel.observe { effect ->
|
||||
when (effect) {
|
||||
Effect.NavigateNext -> onNext()
|
||||
is Effect.NavigateNext -> onNext(effect.isManualSetup)
|
||||
Effect.NavigateBack -> onBack()
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ fun SpecialFoldersScreen(
|
|||
onNextClick = { dispatch(Event.OnNextClicked) },
|
||||
onBackClick = { dispatch(Event.OnBackClicked) },
|
||||
state = WizardNavigationBarState(
|
||||
isNextEnabled = state.value.isLoading.not(),
|
||||
showNext = state.value.isManualSetup && state.value.isLoading.not(),
|
||||
),
|
||||
)
|
||||
},
|
||||
|
|
|
@ -37,7 +37,6 @@ class SpecialFoldersViewModel(
|
|||
|
||||
Event.OnNextClicked -> onNextClicked()
|
||||
Event.OnBackClicked -> onBackClicked()
|
||||
Event.OnEditClicked -> onEditClicked()
|
||||
Event.OnRetryClicked -> onRetryClicked()
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +64,7 @@ class SpecialFoldersViewModel(
|
|||
is ValidationResult.Failure -> {
|
||||
updateState {
|
||||
it.copy(
|
||||
isManualSetup = true,
|
||||
isSuccess = false,
|
||||
isLoading = false,
|
||||
)
|
||||
|
@ -129,7 +129,7 @@ class SpecialFoldersViewModel(
|
|||
|
||||
private fun navigateNext() {
|
||||
viewModelScope.coroutineContext.cancelChildren()
|
||||
emitEffect(Effect.NavigateNext)
|
||||
emitEffect(Effect.NavigateNext(isManualSetup = state.value.isManualSetup))
|
||||
}
|
||||
|
||||
private fun onBackClicked() {
|
||||
|
@ -137,15 +137,6 @@ class SpecialFoldersViewModel(
|
|||
emitEffect(Effect.NavigateBack)
|
||||
}
|
||||
|
||||
private fun onEditClicked() {
|
||||
viewModelScope.coroutineContext.cancelChildren()
|
||||
updateState { state ->
|
||||
state.copy(
|
||||
isSuccess = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onRetryClicked() {
|
||||
viewModelScope.coroutineContext.cancelChildren()
|
||||
updateState {
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
<string name="account_setup_special_folders_trash_folder_label">Trash folder</string>
|
||||
<string name="account_setup_special_folders_folder_none">None</string>
|
||||
<string name="account_setup_special_folders_folder_automatic">Automatic (%s)</string>
|
||||
<string name="account_setup_special_folders_edit_folders_button_label">Edit special folders</string>
|
||||
|
||||
<string name="account_setup_options_top_bar_title">Account options</string>
|
||||
<string name="account_setup_options_section_display_options">Display options</string>
|
||||
|
|
|
@ -33,7 +33,7 @@ class SpecialFoldersScreenKtTest : ComposeTest() {
|
|||
assertThat(onNextCounter).isEqualTo(0)
|
||||
assertThat(onBackCounter).isEqualTo(0)
|
||||
|
||||
viewModel.effect(Effect.NavigateNext)
|
||||
viewModel.effect(Effect.NavigateNext(true))
|
||||
|
||||
assertThat(onNextCounter).isEqualTo(1)
|
||||
assertThat(onBackCounter).isEqualTo(0)
|
||||
|
|
|
@ -16,6 +16,7 @@ class SpecialFoldersStateTest {
|
|||
assertThat(state).isEqualTo(
|
||||
State(
|
||||
formState = FormState(),
|
||||
isManualSetup = false,
|
||||
isSuccess = false,
|
||||
error = null,
|
||||
isLoading = true,
|
||||
|
|
|
@ -75,7 +75,7 @@ class SpecialFoldersViewModelTest {
|
|||
}
|
||||
|
||||
turbines.assertThatAndEffectTurbineConsumed {
|
||||
isEqualTo(Effect.NavigateNext)
|
||||
isEqualTo(Effect.NavigateNext(false))
|
||||
}
|
||||
|
||||
assertThat(accountStateRepository.getState()).isEqualTo(
|
||||
|
@ -108,6 +108,7 @@ class SpecialFoldersViewModelTest {
|
|||
testSubject.event(Event.LoadSpecialFolderOptions)
|
||||
|
||||
val unvalidatedState = initialState.copy(
|
||||
isManualSetup = true,
|
||||
isLoading = false,
|
||||
isSuccess = false,
|
||||
formState = FormState(
|
||||
|
@ -187,7 +188,7 @@ class SpecialFoldersViewModelTest {
|
|||
|
||||
@Test
|
||||
fun `should save form data and emit NavigateNext effect when OnNextClicked event received`() = runTest {
|
||||
val initialState = State(isSuccess = true)
|
||||
val initialState = State(isManualSetup = true)
|
||||
val accountStateRepository = InMemoryAccountStateRepository()
|
||||
val testSubject = createTestSubject(
|
||||
initialState = initialState,
|
||||
|
@ -200,7 +201,7 @@ class SpecialFoldersViewModelTest {
|
|||
assertThat(turbines.awaitStateItem()).isEqualTo(initialState.copy(isLoading = false))
|
||||
|
||||
turbines.assertThatAndEffectTurbineConsumed {
|
||||
isEqualTo(Effect.NavigateNext)
|
||||
isEqualTo(Effect.NavigateNext(true))
|
||||
}
|
||||
|
||||
assertThat(accountStateRepository.getState()).isEqualTo(
|
||||
|
@ -228,19 +229,6 @@ class SpecialFoldersViewModelTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should show form when OnEditClicked event received`() = runTest {
|
||||
val initialState = State(isSuccess = true)
|
||||
val testSubject = createTestSubject(initialState = initialState)
|
||||
val turbines = turbinesWithInitialStateCheck(testSubject, initialState)
|
||||
|
||||
testSubject.event(Event.OnEditClicked)
|
||||
|
||||
turbines.assertThatAndStateTurbineConsumed {
|
||||
isEqualTo(initialState.copy(isSuccess = false))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should show form when OnRetryClicked event received`() = runTest {
|
||||
val initialState = State(error = SpecialFoldersContract.Failure.LoadFoldersFailed("irrelevant"))
|
||||
|
@ -281,7 +269,7 @@ class SpecialFoldersViewModelTest {
|
|||
)
|
||||
|
||||
turbines.assertThatAndEffectTurbineConsumed {
|
||||
isEqualTo(Effect.NavigateNext)
|
||||
isEqualTo(Effect.NavigateNext(false))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue