diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationScreen.kt index 2621ceb5457f..c4e2340e840f 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Text +import androidx.compose.material.TextButton import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons.Filled import androidx.compose.material.icons.filled.ArrowBack @@ -28,8 +29,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.woocommerce.android.R.string import com.woocommerce.android.ui.common.wpcomwebview.WPComWebViewAuthenticator +import com.woocommerce.android.ui.compose.component.AlertDialog import com.woocommerce.android.ui.compose.component.WCColoredButton import com.woocommerce.android.ui.compose.component.WCWebView +import com.woocommerce.android.ui.login.storecreation.webview.WebViewStoreCreationViewModel.DialogState import com.woocommerce.android.ui.login.storecreation.webview.WebViewStoreCreationViewModel.ViewState.ErrorState import com.woocommerce.android.ui.login.storecreation.webview.WebViewStoreCreationViewModel.ViewState.StoreCreationState import com.woocommerce.android.ui.login.storecreation.webview.WebViewStoreCreationViewModel.ViewState.StoreLoadingState @@ -47,9 +50,7 @@ fun WebViewStoreCreationScreen(viewModel: WebViewStoreCreationViewModel) { backgroundColor = MaterialTheme.colors.surface, title = { Text(stringResource(id = string.store_creation_create_new_store_label)) }, navigationIcon = { - IconButton(onClick = { - viewModel.onBackPressed() - }) { + IconButton(onClick = viewModel::onBackPressed) { Icon(Filled.ArrowBack, contentDescription = "Back") } }, @@ -73,6 +74,12 @@ fun WebViewStoreCreationScreen(viewModel: WebViewStoreCreationViewModel) { } } } + + viewModel.dialogViewState.observeAsState().value?.let { + if (it.isDialogVisible) { + ConfirmExitDialog(it) + } + } } @SuppressLint("SetJavaScriptEnabled") @@ -102,9 +109,11 @@ private fun StoreCreationWebView( viewState.onSiteAddressFound(it) } - if (url.contains(viewState.exitTriggerKeyword, ignoreCase = true) && !storeCreationTriggered) { + if (url.contains(viewState.successTriggerKeyword, ignoreCase = true) && !storeCreationTriggered) { storeCreationTriggered = true viewState.onStoreCreated() + } else if (url == viewState.exitTriggerKeyword) { + viewState.onExitTriggered() } }, modifier = modifier.fillMaxSize() @@ -152,6 +161,30 @@ private fun StoreCreationInProgress() { } } +@Composable +private fun ConfirmExitDialog(viewState: DialogState) { + AlertDialog( + onDismissRequest = { viewState.onDialogDismissed() }, + title = { + Text(text = stringResource(id = string.store_creation_exit_dialog_title)) + }, + text = { + Text(text = stringResource(id = string.store_creation_exit_dialog_message)) + }, + confirmButton = { + TextButton(onClick = { viewState.onExitConfirmed() }) { + Text(stringResource(id = string.store_creation_confirm_and_leave)) + } + }, + dismissButton = { + TextButton(onClick = { viewState.onDialogDismissed() }) { + Text(stringResource(id = string.cancel)) + } + }, + neutralButton = {} + ) +} + @Preview @Composable private fun PreviewStoreCreationInProgress() { diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationViewModel.kt index 06076f95dac1..781f17c2cb81 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/login/storecreation/webview/WebViewStoreCreationViewModel.kt @@ -17,6 +17,7 @@ import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit import com.woocommerce.android.viewmodel.ScopedViewModel import com.woocommerce.android.viewmodel.getStateFlow import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize @@ -33,10 +34,14 @@ class WebViewStoreCreationViewModel @Inject constructor( companion object { private const val STORE_CREATION_URL = "https://woocommerce.com/start" private const val SITE_URL_KEYWORD = "checkout/thank-you/" - private const val WEBVIEW_EXIT_TRIGGER_KEYWORD = "calypso/images/wpcom-ecommerce" + private const val WEBVIEW_SUCCESS_TRIGGER_KEYWORD = "calypso/images/wpcom-ecommerce" + private const val WEBVIEW_EXIT_TRIGGER_KEYWORD = "https://woocommerce.com/" private const val STORE_LOAD_RETRIES_LIMIT = 10 } + private val _dialogViewState = savedStateHandle.getStateFlow(viewModelScope, setDialogState(isVisible = false)) + val dialogViewState = _dialogViewState.asStateFlow().asLiveData() + private val step = savedStateHandle.getStateFlow(viewModelScope, Step.StoreCreation) val viewState: LiveData = step.map { step -> when (step) { @@ -51,17 +56,27 @@ class WebViewStoreCreationViewModel @Inject constructor( private fun prepareStoreCreationState() = StoreCreationState( storeCreationUrl = STORE_CREATION_URL, siteUrlKeyword = SITE_URL_KEYWORD, + successTriggerKeyword = WEBVIEW_SUCCESS_TRIGGER_KEYWORD, exitTriggerKeyword = WEBVIEW_EXIT_TRIGGER_KEYWORD, onStoreCreated = ::onStoreCreated, - onSiteAddressFound = ::onSiteAddressFound + onSiteAddressFound = ::onSiteAddressFound, + onExitTriggered = ::exitStoreCreation ) private fun prepareErrorState() = ErrorState( - onRetryButtonClick = { - onStoreCreated() - } + onRetryButtonClick = ::onStoreCreated + ) + + private fun setDialogState(isVisible: Boolean) = DialogState( + isDialogVisible = isVisible, + onExitConfirmed = ::exitStoreCreation, + onDialogDismissed = ::onDialogDismissed ) + private fun onDialogDismissed() { + _dialogViewState.value = setDialogState(isVisible = false) + } + private fun onStoreCreated() { step.value = Step.StoreLoading launch { @@ -92,16 +107,23 @@ class WebViewStoreCreationViewModel @Inject constructor( possibleStoreUrls.add(url) } - fun onBackPressed() { + private fun exitStoreCreation() { + _dialogViewState.value = setDialogState(isVisible = false) triggerEvent(Exit) } + fun onBackPressed() { + _dialogViewState.value = setDialogState(isVisible = true) + } + sealed interface ViewState { data class StoreCreationState( val storeCreationUrl: String, val siteUrlKeyword: String, + val successTriggerKeyword: String, val exitTriggerKeyword: String, val onStoreCreated: () -> Unit, + val onExitTriggered: () -> Unit, val onSiteAddressFound: (url: String) -> Unit ) : ViewState @@ -112,6 +134,13 @@ class WebViewStoreCreationViewModel @Inject constructor( ) : ViewState } + @Parcelize + data class DialogState( + val isDialogVisible: Boolean, + val onExitConfirmed: () -> Unit, + val onDialogDismissed: () -> Unit + ) : Parcelable + object NavigateToNewStore : MultiLiveEvent.Event() private sealed interface Step : Parcelable { diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 5aaff3d75f14..daa337ade379 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -2686,4 +2686,7 @@ Create a new store Couldn\'t load your store.\nPlease try again… Creating your store… + Do you want to leave? + You will lose all your store information. + Confirm and leave