From 54425584a84d09729bcdff31d8e9c492e39f49d3 Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 15:58:47 +1100 Subject: [PATCH 01/26] Update SiteCreationStep.kt Add Plans step in the flow --- .../wordpress/android/ui/sitecreation/SiteCreationStep.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt index 6a2e52a4fead..86afa3549d90 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationStep.kt @@ -2,6 +2,7 @@ package org.wordpress.android.ui.sitecreation import org.wordpress.android.ui.sitecreation.SiteCreationStep.DOMAINS import org.wordpress.android.ui.sitecreation.SiteCreationStep.INTENTS +import org.wordpress.android.ui.sitecreation.SiteCreationStep.PLANS import org.wordpress.android.ui.sitecreation.SiteCreationStep.PROGRESS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_DESIGNS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_NAME @@ -13,7 +14,7 @@ import javax.inject.Inject import javax.inject.Singleton enum class SiteCreationStep : WizardStep { - SITE_DESIGNS, DOMAINS, PROGRESS, SITE_PREVIEW, INTENTS, SITE_NAME; + SITE_DESIGNS, DOMAINS, PLANS, PROGRESS, SITE_PREVIEW, INTENTS, SITE_NAME; } @Singleton @@ -26,7 +27,7 @@ class SiteCreationStepsProvider @Inject constructor( fun getSteps(): List = when { isSiteNameEnabled -> listOf(INTENTS, SITE_NAME, SITE_DESIGNS, PROGRESS, SITE_PREVIEW) - isIntentsEnabled -> listOf(INTENTS, SITE_DESIGNS, DOMAINS, PROGRESS, SITE_PREVIEW) - else -> listOf(SITE_DESIGNS, DOMAINS, PROGRESS, SITE_PREVIEW) + isIntentsEnabled -> listOf(INTENTS, SITE_DESIGNS, DOMAINS, PLANS, PROGRESS, SITE_PREVIEW) + else -> listOf(SITE_DESIGNS, DOMAINS, PLANS, PROGRESS, SITE_PREVIEW) } } From ad2692a0e060431193cd1daee0dce2b2b78bbd8f Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 16:06:50 +1100 Subject: [PATCH 02/26] Create SiteCreationPlansUiState.kt --- .../plans/SiteCreationPlansUiState.kt | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansUiState.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansUiState.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansUiState.kt new file mode 100644 index 000000000000..281e8cf24fa5 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansUiState.kt @@ -0,0 +1,52 @@ +package org.wordpress.android.ui.sitecreation.plans + +import org.wordpress.android.R +import org.wordpress.android.ui.utils.UiString + +sealed class SiteCreationPlansUiState { + object Preparing : SiteCreationPlansUiState() + + data class Prepared( + val model: SiteCreationPlansModel + ) : SiteCreationPlansUiState() + + object Loaded : SiteCreationPlansUiState() + + open class Error( + val title: UiString, + val description: UiString, + val button: ErrorButton? = null + ) : SiteCreationPlansUiState() { + data class ErrorButton( + val text: UiString, + val click: () -> Unit + ) + } + + data class NoNetworkError(val buttonClick: () -> Unit): Error( + title = UiString.UiStringRes(R.string.no_network_title), + description = UiString.UiStringRes(R.string.request_failed_message), + button = ErrorButton( + text = UiString.UiStringRes(R.string.retry), + click = buttonClick + ) + ) + + data class GenericError(val buttonClick: () -> Unit): Error( + title = UiString.UiStringRes(R.string.jp_migration_generic_error_title), + description = UiString.UiStringRes(R.string.request_failed_message), + button = ErrorButton( + text = UiString.UiStringRes(R.string.retry), + click = buttonClick + ) + ) +} + +data class SiteCreationPlansModel( + val enableJavascript: Boolean = true, + val enableDomStorage: Boolean = true, + val enableChromeClient: Boolean = true, + val userAgent: String = "", + val url: String = "", + val addressToLoad: String = "" +) From 012d53238e5070a1eb17f4285002f85d2dcb4fb6 Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 16:07:10 +1100 Subject: [PATCH 03/26] Create SiteCreationPlansWebViewClient.kt --- .../plans/SiteCreationPlansWebViewClient.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt new file mode 100644 index 000000000000..1b2be0b5e3b2 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt @@ -0,0 +1,39 @@ +package org.wordpress.android.ui.sitecreation.plans + +import android.net.Uri +import android.os.Parcelable +import android.webkit.WebResourceRequest +import android.webkit.WebView +import kotlinx.parcelize.Parcelize +import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewNavigationDelegate +import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewNavigationDelegate.toUrl +import org.wordpress.android.util.ErrorManagedWebViewClient + +class SiteCreationPlansWebViewClient( + private val listener: SiteCreationPlansWebViewClientListener +) : ErrorManagedWebViewClient(listener) { + private val navigationDelegate = DomainRegistrationCheckoutWebViewNavigationDelegate + + interface SiteCreationPlansWebViewClientListener : ErrorManagedWebViewClientListener { + fun onPlanSelected(url: String) + } + + override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) : Boolean { + if (canNavigateTo(request.url)) return false + if (request.isRedirect) { + listener.onPlanSelected(request.url.toString()) + } + return true + } + + private fun canNavigateTo(uri: Uri) = navigationDelegate.canNavigateTo(uri.toUrl()) +} + +@Parcelize +data class PlanModel( + val productId: Int?, + val productSlug: String?, + val productName: String?, + val isCurrentPlan: Boolean, + val hasDomainCredit: Boolean +) : Parcelable From 363aa9a73f59f0dd1092418a074be4741851bbff Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 16:07:37 +1100 Subject: [PATCH 04/26] Update strings.xml --- WordPress/src/main/res/values/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index b3489d641e29..7bd4a8362cfe 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -3418,6 +3418,7 @@ Create Site There was a problem We\'re creating your new site + Select a plan Search for a short and memorable domain to help people find and visit your site. From 7ca8666d9fb82a79db8e604a8390247cc17c749c Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 16:08:06 +1100 Subject: [PATCH 05/26] Update SiteCreationMainVM.kt --- .../org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt index 8b2249636750..5a7ba736ed43 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt @@ -32,6 +32,7 @@ import org.wordpress.android.ui.sitecreation.SiteCreationResult.NotCreated import org.wordpress.android.ui.sitecreation.domains.DomainModel import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker +import org.wordpress.android.ui.sitecreation.plans.PlanModel import org.wordpress.android.ui.sitecreation.usecases.FetchHomePageLayoutsUseCase import org.wordpress.android.ui.utils.UiString.UiStringRes import org.wordpress.android.util.AppLog @@ -59,6 +60,7 @@ data class SiteCreationState( val segmentId: Long? = null, val siteDesign: String? = null, val domain: DomainModel? = null, + val plan: PlanModel? = null, val result: SiteCreationResult = NotCreated, ) : WizardState, Parcelable From 71969f044d7858e1957d2adc04b4967a2d1a604c Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 16:08:23 +1100 Subject: [PATCH 06/26] Create SiteCreationPlansFragment.kt --- .../plans/SiteCreationPlansFragment.kt | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt new file mode 100644 index 000000000000..531125334661 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt @@ -0,0 +1,210 @@ +package org.wordpress.android.ui.sitecreation.plans + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.webkit.WebView +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Button +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.viewmodel.compose.viewModel +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import org.wordpress.android.R +import org.wordpress.android.ui.ActivityLauncher +import org.wordpress.android.ui.WPWebViewActivity +import org.wordpress.android.ui.compose.components.MainTopAppBar +import org.wordpress.android.ui.compose.components.NavigationIcons +import org.wordpress.android.ui.compose.theme.AppTheme +import org.wordpress.android.ui.compose.utils.uiStringText +import org.wordpress.android.ui.main.jetpack.migration.compose.state.LoadingState +import org.wordpress.android.ui.sitecreation.SiteCreationBaseFormFragment.Companion.EXTRA_SCREEN_TITLE +import org.wordpress.android.ui.sitecreation.plans.SiteCreationPlansWebViewClient.SiteCreationPlansWebViewClientListener + +@AndroidEntryPoint +class SiteCreationPlansFragment : Fragment(), SiteCreationPlansWebViewClientListener { + private val viewModel: SiteCreationPlansViewModel by viewModels() + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View = ComposeView(requireContext()).apply { + setContent { + AppTheme { + SiteCreationPlansPage( + navigationUp = requireActivity().onBackPressedDispatcher::onBackPressed + ) + } + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.start() + viewModel.actionEvents.onEach(this::handleActionEvents).launchIn(viewLifecycleOwner.lifecycleScope) + } + + private fun handleActionEvents(actionEvent: SiteCreationPlansActionEvent) { + when (actionEvent) { + is SiteCreationPlansActionEvent.FinishActivity -> requireActivity().finish() + is SiteCreationPlansActionEvent.LaunchExternalBrowser -> { + ActivityLauncher.openUrlExternal( + requireContext(), + actionEvent.url + ) + } + } + } + + // SiteCreationWebViewClient + override fun onPlanSelected(url: String) { + viewModel.onPlanSelected(url) + } + + override fun onWebViewPageLoaded() { + viewModel.onUrlLoaded() + } + + override fun onWebViewReceivedError() { + viewModel.onWebViewError() + } + + @Composable + @SuppressLint("UnusedMaterialScaffoldPaddingParameter") + fun SiteCreationPlansPage( + navigationUp: () -> Unit = { }, + viewModel: SiteCreationPlansViewModel = viewModel(), + ) { + val uiState by viewModel.uiState.collectAsState() + Scaffold( + topBar = { + MainTopAppBar( + title = stringResource(R.string.site_creation_plans_selection_title), + navigationIcon = NavigationIcons.BackIcon, + onNavigationIconClick = navigationUp + ) + }, + content = { SiteCreationPlansContent(uiState) } + ) + } + + @SuppressLint("SetJavaScriptEnabled") + @Composable + private fun SiteCreationPlansContent(uiState: SiteCreationPlansUiState) { + when (uiState) { + is SiteCreationPlansUiState.Preparing -> LoadingState() + is SiteCreationPlansUiState.Prepared, + is SiteCreationPlansUiState.Loaded -> SiteCreationPlansWebView(uiState) + is SiteCreationPlansUiState.Error -> SiteCreationPlansError(uiState) + } + } + + @Composable + fun SiteCreationPlansError(error: SiteCreationPlansUiState.Error) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .padding(20.dp) + .fillMaxWidth() + .fillMaxHeight(), + ) { + Text( + text = uiStringText(uiString = error.title), + style = MaterialTheme.typography.h5, + textAlign = TextAlign.Center + ) + Text( + text = uiStringText(uiString = error.description), + style = MaterialTheme.typography.body1, + textAlign = TextAlign.Center, + modifier = Modifier.padding(top = 8.dp) + ) + if (error.button != null) { + Button( + modifier = Modifier.padding(top = 8.dp), + onClick = error.button.click + ) { + Text(text = uiStringText(uiString = error.button.text)) + } + } + } + } + + @SuppressLint("SetJavaScriptEnabled") + @Composable + private fun SiteCreationPlansWebView(uiState: SiteCreationPlansUiState) { + var webView: WebView? by remember { mutableStateOf(null) } + + if (uiState is SiteCreationPlansUiState.Prepared) { + val model = uiState.model + LaunchedEffect(true) { + webView = WebView(requireContext()).apply { + layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY + settings.userAgentString = model.userAgent + settings.javaScriptEnabled = model.enableJavascript + settings.domStorageEnabled = model.enableDomStorage + webViewClient = SiteCreationPlansWebViewClient(this@SiteCreationPlansFragment) + postUrl(WPWebViewActivity.WPCOM_LOGIN_URL, model.addressToLoad.toByteArray()) + } + } + } + + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + if (uiState is SiteCreationPlansUiState.Prepared) { + LoadingState() + } else { + webView?.let { theWebView -> + AndroidView( + factory = { theWebView }, + modifier = Modifier.fillMaxSize() + ) + } + } + } + } + + companion object { + const val TAG = "site_creation_plans_fragment_tag" + fun newInstance(screenTitle: String) = SiteCreationPlansFragment().apply { + arguments = Bundle().apply { + putString(EXTRA_SCREEN_TITLE, screenTitle) + } + } + } +} From 8e68b0314470bb19d41220e139a911add66d9cf5 Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 16:08:27 +1100 Subject: [PATCH 07/26] Create SiteCreationPlansViewModel.kt --- .../plans/SiteCreationPlansViewModel.kt | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt new file mode 100644 index 000000000000..9e024a987c7d --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt @@ -0,0 +1,182 @@ +package org.wordpress.android.ui.sitecreation.plans + +import android.net.Uri +import android.text.TextUtils +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch +import org.wordpress.android.WordPress +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.store.AccountStore +import org.wordpress.android.fluxc.store.SiteStore +import org.wordpress.android.ui.WPWebViewActivity +import org.wordpress.android.ui.mysite.SelectedSiteRepository +import org.wordpress.android.util.AppLog +import org.wordpress.android.util.NetworkUtilsWrapper +import javax.inject.Inject + +@HiltViewModel +class SiteCreationPlansViewModel @Inject constructor( + private val accountStore: AccountStore, + private val siteStore: SiteStore, + private val selectedSiteRepository: SelectedSiteRepository, + private val networkUtilsWrapper: NetworkUtilsWrapper +) : ViewModel() { + private val _uiState = MutableStateFlow(SiteCreationPlansUiState.Preparing) + val uiState = _uiState as StateFlow + + private val _actionEvents = Channel(Channel.BUFFERED) + val actionEvents = _actionEvents.receiveAsFlow() + + fun start() { + showPlans() + } + + fun onPlanSelected(url: String) { + AppLog.d(AppLog.T.PLANS, url) + } + + fun onCheckoutSuccess() { + // + } + fun onRedirectToExternalBrowser(url: String) { + postActionEvent(SiteCreationPlansActionEvent.LaunchExternalBrowser(url)) + } + + fun onUrlLoaded() { + postUiState(SiteCreationPlansUiState.Loaded) + } + + fun onWebViewError() { + postUiState(SiteCreationPlansUiState.GenericError(this@SiteCreationPlansViewModel::launchPlans)) + } + + private fun showPlans() { + postUiState(SiteCreationPlansUiState.Preparing) + if (!checkForInternetConnectivityAndPostErrorIfNeeded()) return + if (!validateAndPostErrorIfNeeded()) return + launchPlans() + } + + private fun launchPlans() { + val url = createURL() + AppLog.d(AppLog.T.PLANS, url) + + val addressToLoad = prepareAddressToLoad(url) + postUiState(SiteCreationPlansUiState.Prepared( + SiteCreationPlansModel( + enableJavascript = true, + enableDomStorage = true, + userAgent = WordPress.getUserAgent(), + enableChromeClient = true, + url = url, + addressToLoad = addressToLoad + ) + )) + } + + private fun createURL(): String { + // Temporarily using freed domain with annual plan url, till Calypso PR is merged + return Uri.Builder().apply { + scheme("https") + authority("wordpress.com") + appendPath(PLANS_PATH) + appendPath(PLANS_FREQUENCY_PATH) + appendPath(extractAndSanitizeSiteUrl()) + appendQueryParameter(PLANS_PACKAGE, "true") + appendQueryParameter(PLANS_JETPACK_APP, "true") + appendQueryParameter("redirect_to", REDIRECT_TO ) + build() + }.toString() + + + // https://container-focused-fermi.calypso.live/plans/domainspurchases.wordpress.com +// return Uri.Builder().apply { +// scheme("https") +// authority("container-amazing-stonebraker.calypso.live") +// appendPath("jetpack-app-plans") +// build() +// }.toString() + } + + private fun extractAndSanitizeSiteUrl(): String { + return selectedSiteRepository.getSelectedSite()?.url?.replace(Regex(HTTP_PATTERN), "") ?: "" + } + private fun prepareAddressToLoad(url: String): String { + val username = accountStore.account.userName + val accessToken = accountStore.accessToken + + var addressToLoad = url + + // Custom domains are not properly authenticated due to a server side(?) issue, so this gets around that + if (!addressToLoad.contains(WPCOM_DOMAIN)) { + val wpComSites: List = siteStore.wPComSites + for (siteModel in wpComSites) { + // Only replace the url if we know the unmapped url and if it's a custom domain + if (!TextUtils.isEmpty(siteModel.unmappedUrl) + && !siteModel.url.contains(WPCOM_DOMAIN) + ) { + addressToLoad = addressToLoad.replace(siteModel.url, siteModel.unmappedUrl) + } + } + } + return WPWebViewActivity.getAuthenticationPostData( + WPCOM_LOGIN_URL, +// "https://container-amazing-stonebraker.calypso.live/jetpack-app-plans", + addressToLoad, + username, + "", + accessToken?:"" + ) + } + + private fun validateAndPostErrorIfNeeded(): Boolean { + if (accountStore.account.userName.isNullOrEmpty() || accountStore.accessToken.isNullOrEmpty()) { + postUiState(SiteCreationPlansUiState.GenericError(this@SiteCreationPlansViewModel::showPlans)) + return false + } + return true + } + + private fun checkForInternetConnectivityAndPostErrorIfNeeded(): Boolean { + if (networkUtilsWrapper.isNetworkAvailable()) return true + postUiState(SiteCreationPlansUiState.NoNetworkError(this@SiteCreationPlansViewModel::showPlans)) + return false + } + + private fun postUiState(state: SiteCreationPlansUiState) { + viewModelScope.launch { + _uiState.value = state + } + } + + private fun postActionEvent(actionEvent: SiteCreationPlansActionEvent) { + viewModelScope.launch { + _actionEvents.send(actionEvent) + } + } + + companion object { + const val HTTP_PATTERN = "(https?://)" + const val WPCOM_LOGIN_URL = "https://wordpress.com/wp-login.php" + const val WPCOM_DOMAIN = ".wordpress.com" + + const val WP_HOST = "https://wordpress.com" + const val PLANS_PATH = "plans" // "jetpack-app-plans" + const val REDIRECT_TO = "jetpackapp://" + const val PAID_DOMAIN_NAME = "paid_domain_name" + const val PLANS_FREQUENCY_PATH = "yearly" // not required + const val PLANS_JETPACK_APP = "jetpackAppPlans" // not required + const val PLANS_PACKAGE = "domainAndPlanPackage" // not required + } +} + +sealed class SiteCreationPlansActionEvent { + object FinishActivity : SiteCreationPlansActionEvent() + data class LaunchExternalBrowser(val url: String) : SiteCreationPlansActionEvent() +} From 3f62e7631fef5281744c26238ef1818aed2a838c Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 5 Oct 2023 16:08:31 +1100 Subject: [PATCH 08/26] Update SiteCreationActivity.kt --- .../wordpress/android/ui/sitecreation/SiteCreationActivity.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt index f1c742345b34..5c61895225e5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt @@ -34,6 +34,7 @@ import org.wordpress.android.ui.sitecreation.SiteCreationResult.Created import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched import org.wordpress.android.ui.sitecreation.SiteCreationStep.DOMAINS import org.wordpress.android.ui.sitecreation.SiteCreationStep.INTENTS +import org.wordpress.android.ui.sitecreation.SiteCreationStep.PLANS import org.wordpress.android.ui.sitecreation.SiteCreationStep.PROGRESS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_DESIGNS import org.wordpress.android.ui.sitecreation.SiteCreationStep.SITE_NAME @@ -43,6 +44,7 @@ import org.wordpress.android.ui.sitecreation.domains.DomainsScreenListener import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsFragment import org.wordpress.android.ui.sitecreation.misc.OnHelpClickedListener import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource +import org.wordpress.android.ui.sitecreation.plans.SiteCreationPlansFragment import org.wordpress.android.ui.sitecreation.previews.SiteCreationPreviewFragment import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressFragment @@ -235,6 +237,7 @@ class SiteCreationActivity : LocaleAwareActivity(), HomePagePickerFragment.newInstance(target.wizardState.siteIntent) } DOMAINS -> SiteCreationDomainsFragment.newInstance(screenTitle) + PLANS -> SiteCreationPlansFragment.newInstance(screenTitle) PROGRESS -> SiteCreationProgressFragment.newInstance(target.wizardState) SITE_PREVIEW -> SiteCreationPreviewFragment.newInstance(screenTitle, target.wizardState) } From 62c0f59972bf5e297663ff4cfc1d8dd4fb663d59 Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 6 Oct 2023 16:09:13 +1100 Subject: [PATCH 09/26] Add params to request Add paid_domain_name and redirect_to params --- .../ui/sitecreation/SiteCreationActivity.kt | 2 +- .../plans/SiteCreationPlansFragment.kt | 12 ++++++++---- .../plans/SiteCreationPlansViewModel.kt | 17 +++++++++++------ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt index 5c61895225e5..86c92b0f7dc1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt @@ -237,7 +237,7 @@ class SiteCreationActivity : LocaleAwareActivity(), HomePagePickerFragment.newInstance(target.wizardState.siteIntent) } DOMAINS -> SiteCreationDomainsFragment.newInstance(screenTitle) - PLANS -> SiteCreationPlansFragment.newInstance(screenTitle) + PLANS -> SiteCreationPlansFragment.newInstance(target.wizardState) PROGRESS -> SiteCreationProgressFragment.newInstance(target.wizardState) SITE_PREVIEW -> SiteCreationPreviewFragment.newInstance(screenTitle, target.wizardState) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt index 531125334661..af22ca2fb6a0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt @@ -46,8 +46,10 @@ import org.wordpress.android.ui.compose.components.NavigationIcons import org.wordpress.android.ui.compose.theme.AppTheme import org.wordpress.android.ui.compose.utils.uiStringText import org.wordpress.android.ui.main.jetpack.migration.compose.state.LoadingState -import org.wordpress.android.ui.sitecreation.SiteCreationBaseFormFragment.Companion.EXTRA_SCREEN_TITLE +import org.wordpress.android.ui.sitecreation.SiteCreationActivity.Companion.ARG_STATE +import org.wordpress.android.ui.sitecreation.SiteCreationState import org.wordpress.android.ui.sitecreation.plans.SiteCreationPlansWebViewClient.SiteCreationPlansWebViewClientListener +import org.wordpress.android.util.extensions.getParcelableCompat @AndroidEntryPoint class SiteCreationPlansFragment : Fragment(), SiteCreationPlansWebViewClientListener { @@ -68,7 +70,8 @@ class SiteCreationPlansFragment : Fragment(), SiteCreationPlansWebViewClientList override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel.start() + + viewModel.start(requireNotNull(requireArguments().getParcelableCompat(ARG_STATE))) viewModel.actionEvents.onEach(this::handleActionEvents).launchIn(viewLifecycleOwner.lifecycleScope) } @@ -201,9 +204,10 @@ class SiteCreationPlansFragment : Fragment(), SiteCreationPlansWebViewClientList companion object { const val TAG = "site_creation_plans_fragment_tag" - fun newInstance(screenTitle: String) = SiteCreationPlansFragment().apply { + + fun newInstance(siteCreationState: SiteCreationState) = SiteCreationPlansFragment().apply { arguments = Bundle().apply { - putString(EXTRA_SCREEN_TITLE, screenTitle) + putParcelable(ARG_STATE, siteCreationState) } } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt index 9e024a987c7d..be347291fca8 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt @@ -16,6 +16,7 @@ import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.ui.WPWebViewActivity import org.wordpress.android.ui.mysite.SelectedSiteRepository +import org.wordpress.android.ui.sitecreation.SiteCreationState import org.wordpress.android.util.AppLog import org.wordpress.android.util.NetworkUtilsWrapper import javax.inject.Inject @@ -33,7 +34,10 @@ class SiteCreationPlansViewModel @Inject constructor( private val _actionEvents = Channel(Channel.BUFFERED) val actionEvents = _actionEvents.receiveAsFlow() - fun start() { + private lateinit var domainName: String + + fun start(siteCreationState: SiteCreationState) { + domainName = requireNotNull(siteCreationState.domain).domainName showPlans() } @@ -95,11 +99,12 @@ class SiteCreationPlansViewModel @Inject constructor( }.toString() - // https://container-focused-fermi.calypso.live/plans/domainspurchases.wordpress.com // return Uri.Builder().apply { // scheme("https") -// authority("container-amazing-stonebraker.calypso.live") +// authority("container-jolly-cerf.calypso.live") // appendPath("jetpack-app-plans") +// appendQueryParameter(PAID_DOMAIN_NAME, domainName) +// appendQueryParameter(REDIRECT_TO, REDIRECT_SCHEME) // build() // }.toString() } @@ -127,8 +132,7 @@ class SiteCreationPlansViewModel @Inject constructor( } return WPWebViewActivity.getAuthenticationPostData( WPCOM_LOGIN_URL, -// "https://container-amazing-stonebraker.calypso.live/jetpack-app-plans", - addressToLoad, + url, // addressToLoad, username, "", accessToken?:"" @@ -168,7 +172,8 @@ class SiteCreationPlansViewModel @Inject constructor( const val WP_HOST = "https://wordpress.com" const val PLANS_PATH = "plans" // "jetpack-app-plans" - const val REDIRECT_TO = "jetpackapp://" + const val REDIRECT_TO = "redirect_to" + const val REDIRECT_SCHEME = "jetpackapp://" const val PAID_DOMAIN_NAME = "paid_domain_name" const val PLANS_FREQUENCY_PATH = "yearly" // not required const val PLANS_JETPACK_APP = "jetpackAppPlans" // not required From fb4dbd7293f4baf14ac0a4c5a523e4a2843d1be6 Mon Sep 17 00:00:00 2001 From: Irfan Omur Date: Thu, 12 Oct 2023 18:36:29 +0300 Subject: [PATCH 10/26] Detect plan selection in site creation flow --- .../plans/SiteCreationPlansWebViewClient.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt index 1b2be0b5e3b2..a69005614bf6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt @@ -18,15 +18,20 @@ class SiteCreationPlansWebViewClient( fun onPlanSelected(url: String) } - override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) : Boolean { + override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { if (canNavigateTo(request.url)) return false - if (request.isRedirect) { - listener.onPlanSelected(request.url.toString()) + val urlString = request.url.toString() + if (urlString.contains(PLAN_SLUG)) { + listener.onPlanSelected(urlString) } return true } private fun canNavigateTo(uri: Uri) = navigationDelegate.canNavigateTo(uri.toUrl()) + + companion object { + private const val PLAN_SLUG = "plan_slug" + } } @Parcelize From 68559c3b73f7ca6f96f7848645d9a53009320f05 Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 15:14:00 +1100 Subject: [PATCH 11/26] Update SiteCreationPlansViewModel.kt Update to the new Calypso url --- .../plans/SiteCreationPlansViewModel.kt | 67 +++++++------------ 1 file changed, 23 insertions(+), 44 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt index be347291fca8..93892d86c84d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt @@ -15,8 +15,8 @@ import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.ui.WPWebViewActivity -import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.sitecreation.SiteCreationState +import org.wordpress.android.ui.sitecreation.domains.DomainModel import org.wordpress.android.util.AppLog import org.wordpress.android.util.NetworkUtilsWrapper import javax.inject.Inject @@ -25,7 +25,6 @@ import javax.inject.Inject class SiteCreationPlansViewModel @Inject constructor( private val accountStore: AccountStore, private val siteStore: SiteStore, - private val selectedSiteRepository: SelectedSiteRepository, private val networkUtilsWrapper: NetworkUtilsWrapper ) : ViewModel() { private val _uiState = MutableStateFlow(SiteCreationPlansUiState.Preparing) @@ -34,10 +33,10 @@ class SiteCreationPlansViewModel @Inject constructor( private val _actionEvents = Channel(Channel.BUFFERED) val actionEvents = _actionEvents.receiveAsFlow() - private lateinit var domainName: String + private lateinit var domainName: DomainModel fun start(siteCreationState: SiteCreationState) { - domainName = requireNotNull(siteCreationState.domain).domainName + domainName = requireNotNull(siteCreationState.domain) showPlans() } @@ -45,13 +44,6 @@ class SiteCreationPlansViewModel @Inject constructor( AppLog.d(AppLog.T.PLANS, url) } - fun onCheckoutSuccess() { - // - } - fun onRedirectToExternalBrowser(url: String) { - postActionEvent(SiteCreationPlansActionEvent.LaunchExternalBrowser(url)) - } - fun onUrlLoaded() { postUiState(SiteCreationPlansUiState.Loaded) } @@ -85,33 +77,22 @@ class SiteCreationPlansViewModel @Inject constructor( } private fun createURL(): String { - // Temporarily using freed domain with annual plan url, till Calypso PR is merged - return Uri.Builder().apply { - scheme("https") - authority("wordpress.com") + val uriBuilder = Uri.Builder().apply { + scheme(SCHEME) + authority(AUTHORITY) + appendPath(JETPACK_APP_PATH) appendPath(PLANS_PATH) - appendPath(PLANS_FREQUENCY_PATH) - appendPath(extractAndSanitizeSiteUrl()) - appendQueryParameter(PLANS_PACKAGE, "true") - appendQueryParameter(PLANS_JETPACK_APP, "true") - appendQueryParameter("redirect_to", REDIRECT_TO ) - build() - }.toString() - - -// return Uri.Builder().apply { -// scheme("https") -// authority("container-jolly-cerf.calypso.live") -// appendPath("jetpack-app-plans") -// appendQueryParameter(PAID_DOMAIN_NAME, domainName) -// appendQueryParameter(REDIRECT_TO, REDIRECT_SCHEME) -// build() -// }.toString() - } + appendQueryParameter(PLAN_ID_PARAM, "") + appendQueryParameter(PLAN_SLUG_PARAM, "") + } + + if (!domainName.isFree) uriBuilder.apply { + appendQueryParameter(PAID_DOMAIN_NAME, domainName.domainName) + } - private fun extractAndSanitizeSiteUrl(): String { - return selectedSiteRepository.getSelectedSite()?.url?.replace(Regex(HTTP_PATTERN), "") ?: "" + return uriBuilder.build().toString() } + private fun prepareAddressToLoad(url: String): String { val username = accountStore.account.userName val accessToken = accountStore.accessToken @@ -132,7 +113,7 @@ class SiteCreationPlansViewModel @Inject constructor( } return WPWebViewActivity.getAuthenticationPostData( WPCOM_LOGIN_URL, - url, // addressToLoad, + addressToLoad, username, "", accessToken?:"" @@ -166,18 +147,16 @@ class SiteCreationPlansViewModel @Inject constructor( } companion object { - const val HTTP_PATTERN = "(https?://)" const val WPCOM_LOGIN_URL = "https://wordpress.com/wp-login.php" const val WPCOM_DOMAIN = ".wordpress.com" - const val WP_HOST = "https://wordpress.com" - const val PLANS_PATH = "plans" // "jetpack-app-plans" - const val REDIRECT_TO = "redirect_to" - const val REDIRECT_SCHEME = "jetpackapp://" + const val SCHEME = "https" + const val AUTHORITY = "wordpress.com" + const val JETPACK_APP_PATH = "jetpack-app" + const val PLANS_PATH = "plans" + const val PLAN_ID_PARAM = "plan_id" + const val PLAN_SLUG_PARAM = "plan_slug" const val PAID_DOMAIN_NAME = "paid_domain_name" - const val PLANS_FREQUENCY_PATH = "yearly" // not required - const val PLANS_JETPACK_APP = "jetpackAppPlans" // not required - const val PLANS_PACKAGE = "domainAndPlanPackage" // not required } } From 44c8e2bf3b9f23e652c879a485148b867ff2169a Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 15:14:23 +1100 Subject: [PATCH 12/26] Update SiteCreationPlansWebViewClient.kt --- .../plans/SiteCreationPlansWebViewClient.kt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt index a69005614bf6..2faaaa1f3a45 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt @@ -1,25 +1,21 @@ package org.wordpress.android.ui.sitecreation.plans -import android.net.Uri import android.os.Parcelable import android.webkit.WebResourceRequest import android.webkit.WebView import kotlinx.parcelize.Parcelize -import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewNavigationDelegate -import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewNavigationDelegate.toUrl import org.wordpress.android.util.ErrorManagedWebViewClient class SiteCreationPlansWebViewClient( private val listener: SiteCreationPlansWebViewClientListener ) : ErrorManagedWebViewClient(listener) { - private val navigationDelegate = DomainRegistrationCheckoutWebViewNavigationDelegate - interface SiteCreationPlansWebViewClientListener : ErrorManagedWebViewClientListener { fun onPlanSelected(url: String) } override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { - if (canNavigateTo(request.url)) return false + if (request.url.toString().startsWith(JETPACK_APP_PLANS_PATH)) return false + val urlString = request.url.toString() if (urlString.contains(PLAN_SLUG)) { listener.onPlanSelected(urlString) @@ -27,10 +23,9 @@ class SiteCreationPlansWebViewClient( return true } - private fun canNavigateTo(uri: Uri) = navigationDelegate.canNavigateTo(uri.toUrl()) - companion object { private const val PLAN_SLUG = "plan_slug" + private const val JETPACK_APP_PLANS_PATH = "https://wordpress.com/jetpack-app/plans" } } From 3cf439685193f7c038046530a21b73d725dfdd4a Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 15:14:40 +1100 Subject: [PATCH 13/26] Update DomainRegistrationCheckoutWebViewNavigationDelegate.kt Add jetpack-app path --- .../DomainRegistrationCheckoutWebViewNavigationDelegate.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationCheckoutWebViewNavigationDelegate.kt b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationCheckoutWebViewNavigationDelegate.kt index cac0b26ebdc7..131276e76175 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationCheckoutWebViewNavigationDelegate.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationCheckoutWebViewNavigationDelegate.kt @@ -8,6 +8,7 @@ object DomainRegistrationCheckoutWebViewNavigationDelegate { UrlMatcher( ".*wordpress.com".toRegex(), listOf( + "/jetpack-app".toRegex(), "/plans.*?.*".toRegex(), "/automattic-domain-name-registration-agreement.*".toRegex(), "/checkout.*".toRegex(), From fc30b402c4c2eeeb44643ea5c33b15b746dc24cb Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 15:17:26 +1100 Subject: [PATCH 14/26] Update SiteCreationProgressViewModel.kt pass in plan productId --- .../ui/sitecreation/progress/SiteCreationProgressViewModel.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt index 14211f62bfe5..6b30471a3ae4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt @@ -21,6 +21,7 @@ import org.wordpress.android.ui.sitecreation.domains.DomainModel import org.wordpress.android.ui.sitecreation.misc.SiteCreationErrorType.INTERNET_UNAVAILABLE_ERROR import org.wordpress.android.ui.sitecreation.misc.SiteCreationErrorType.UNKNOWN import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker +import org.wordpress.android.ui.sitecreation.plans.PlanModel import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error.CartError import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error.ConnectionError import org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModel.SiteProgressUiState.Error.GenericError @@ -63,6 +64,7 @@ class SiteCreationProgressViewModel @Inject constructor( private lateinit var siteCreationState: SiteCreationState private lateinit var domain: DomainModel + private lateinit var plan: PlanModel private lateinit var site: SiteModel private var lastReceivedServiceState: SiteCreationServiceState? = null @@ -106,6 +108,7 @@ class SiteCreationProgressViewModel @Inject constructor( } this.siteCreationState = siteCreationState domain = requireNotNull(siteCreationState.domain) { "domain required to create a site" } + plan = requireNotNull(siteCreationState.plan) { "plan purchased to create a site" } runLoadingAnimationUi() startCreateSiteService() @@ -207,6 +210,7 @@ class SiteCreationProgressViewModel @Inject constructor( domain.domainName, domain.supportsPrivacy, false, + planProductId = plan.productId ) if (event.isError) { From b91069b8fb2703199ef47b659ca72e939c2f67ac Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 15:32:22 +1100 Subject: [PATCH 15/26] Remove unused --- .../plans/SiteCreationPlansFragment.kt | 17 ----------------- .../plans/SiteCreationPlansViewModel.kt | 11 ----------- 2 files changed, 28 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt index af22ca2fb6a0..2cd6703220a9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt @@ -33,13 +33,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import androidx.lifecycle.lifecycleScope import androidx.lifecycle.viewmodel.compose.viewModel import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import org.wordpress.android.R -import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.WPWebViewActivity import org.wordpress.android.ui.compose.components.MainTopAppBar import org.wordpress.android.ui.compose.components.NavigationIcons @@ -72,19 +68,6 @@ class SiteCreationPlansFragment : Fragment(), SiteCreationPlansWebViewClientList super.onViewCreated(view, savedInstanceState) viewModel.start(requireNotNull(requireArguments().getParcelableCompat(ARG_STATE))) - viewModel.actionEvents.onEach(this::handleActionEvents).launchIn(viewLifecycleOwner.lifecycleScope) - } - - private fun handleActionEvents(actionEvent: SiteCreationPlansActionEvent) { - when (actionEvent) { - is SiteCreationPlansActionEvent.FinishActivity -> requireActivity().finish() - is SiteCreationPlansActionEvent.LaunchExternalBrowser -> { - ActivityLauncher.openUrlExternal( - requireContext(), - actionEvent.url - ) - } - } } // SiteCreationWebViewClient diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt index 93892d86c84d..42b76446c181 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt @@ -5,10 +5,8 @@ import android.text.TextUtils import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch import org.wordpress.android.WordPress import org.wordpress.android.fluxc.model.SiteModel @@ -30,9 +28,6 @@ class SiteCreationPlansViewModel @Inject constructor( private val _uiState = MutableStateFlow(SiteCreationPlansUiState.Preparing) val uiState = _uiState as StateFlow - private val _actionEvents = Channel(Channel.BUFFERED) - val actionEvents = _actionEvents.receiveAsFlow() - private lateinit var domainName: DomainModel fun start(siteCreationState: SiteCreationState) { @@ -140,12 +135,6 @@ class SiteCreationPlansViewModel @Inject constructor( } } - private fun postActionEvent(actionEvent: SiteCreationPlansActionEvent) { - viewModelScope.launch { - _actionEvents.send(actionEvent) - } - } - companion object { const val WPCOM_LOGIN_URL = "https://wordpress.com/wp-login.php" const val WPCOM_DOMAIN = ".wordpress.com" From 7b80db6e473084394cace16bf0a92ae9edf5be85 Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 16:50:14 +1100 Subject: [PATCH 16/26] Update SiteCreationFixtures.kt --- .../wordpress/android/ui/sitecreation/SiteCreationFixtures.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationFixtures.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationFixtures.kt index f8efb2efdccd..0f9e67d2fa2e 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationFixtures.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/SiteCreationFixtures.kt @@ -14,6 +14,7 @@ import org.wordpress.android.ui.sitecreation.SiteCreationResult.Completed import org.wordpress.android.ui.sitecreation.SiteCreationResult.Created import org.wordpress.android.ui.sitecreation.SiteCreationResult.CreatedButNotFetched import org.wordpress.android.ui.sitecreation.domains.DomainModel +import org.wordpress.android.ui.sitecreation.plans.PlanModel import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.CREATE_SITE import org.wordpress.android.ui.sitecreation.services.SiteCreationServiceState.SiteCreationStep.FAILURE @@ -26,6 +27,7 @@ const val URL_CUSTOM = "$SUB_DOMAIN.host.com" const val SITE_SLUG = "${SUB_DOMAIN}host0.wordpress.com" val FREE_DOMAIN = DomainModel(URL, true, "", 1, false) val PAID_DOMAIN = DomainModel(URL_CUSTOM, false, "$1", 2, true) +val PLAN_MODEL = PlanModel(1009, "paid_plan", "Personal", isCurrentPlan = false, hasDomainCredit = false) const val SITE_REMOTE_ID = 1L @@ -33,6 +35,7 @@ val SITE_CREATION_STATE = SiteCreationState( segmentId = 1, siteDesign = defaultTemplateSlug, domain = FREE_DOMAIN, + plan = PLAN_MODEL ) val SITE_MODEL = SiteModel().apply { siteId = SITE_REMOTE_ID; url = SITE_SLUG } From 69fb18bddef19a96602651c68283c2fa3277f56c Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 19:06:08 +1100 Subject: [PATCH 17/26] Create PlansScreenListener.kt --- .../sitecreation/plans/PlansScreenListener.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/PlansScreenListener.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/PlansScreenListener.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/PlansScreenListener.kt new file mode 100644 index 000000000000..7e3ed9f1eee2 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/PlansScreenListener.kt @@ -0,0 +1,17 @@ +package org.wordpress.android.ui.sitecreation.plans + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +interface PlansScreenListener { + fun onPlanSelected(plan: PlanModel) +} + +@Parcelize +data class PlanModel( + val productId: Int?, + val productSlug: String?, + val productName: String?, + val isCurrentPlan: Boolean, + val hasDomainCredit: Boolean +) : Parcelable From fac06f3c8dbefae5796c85945cf265a7b677e12d Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 19:06:33 +1100 Subject: [PATCH 18/26] Update SiteCreationPlansWebViewClient.kt --- .../plans/SiteCreationPlansWebViewClient.kt | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt index 2faaaa1f3a45..daa780c1b176 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt @@ -1,16 +1,15 @@ package org.wordpress.android.ui.sitecreation.plans -import android.os.Parcelable +import android.net.Uri import android.webkit.WebResourceRequest import android.webkit.WebView -import kotlinx.parcelize.Parcelize import org.wordpress.android.util.ErrorManagedWebViewClient class SiteCreationPlansWebViewClient( private val listener: SiteCreationPlansWebViewClientListener ) : ErrorManagedWebViewClient(listener) { interface SiteCreationPlansWebViewClientListener : ErrorManagedWebViewClientListener { - fun onPlanSelected(url: String) + fun onPlanSelected(uri: Uri) } override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { @@ -18,7 +17,7 @@ class SiteCreationPlansWebViewClient( val urlString = request.url.toString() if (urlString.contains(PLAN_SLUG)) { - listener.onPlanSelected(urlString) + listener.onPlanSelected(request.url) } return true } @@ -28,12 +27,3 @@ class SiteCreationPlansWebViewClient( private const val JETPACK_APP_PLANS_PATH = "https://wordpress.com/jetpack-app/plans" } } - -@Parcelize -data class PlanModel( - val productId: Int?, - val productSlug: String?, - val productName: String?, - val isCurrentPlan: Boolean, - val hasDomainCredit: Boolean -) : Parcelable From f336392eb3e0a6cbd2bf2bbde603c7454c5028cb Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 19:06:49 +1100 Subject: [PATCH 19/26] Update SiteCreationPlansViewModel.kt --- .../plans/SiteCreationPlansViewModel.kt | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt index 42b76446c181..4a8d90cd804e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt @@ -5,8 +5,10 @@ import android.text.TextUtils import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch import org.wordpress.android.WordPress import org.wordpress.android.fluxc.model.SiteModel @@ -28,6 +30,9 @@ class SiteCreationPlansViewModel @Inject constructor( private val _uiState = MutableStateFlow(SiteCreationPlansUiState.Preparing) val uiState = _uiState as StateFlow + private val _actionEvents = Channel(Channel.BUFFERED) + val actionEvents = _actionEvents.receiveAsFlow() + private lateinit var domainName: DomainModel fun start(siteCreationState: SiteCreationState) { @@ -35,8 +40,17 @@ class SiteCreationPlansViewModel @Inject constructor( showPlans() } - fun onPlanSelected(url: String) { - AppLog.d(AppLog.T.PLANS, url) + fun onPlanSelected(uri: Uri) { + AppLog.d(AppLog.T.PLANS, uri.toString()) + + val planModel = PlanModel( + productId = uri.getQueryParameter(PLAN_ID_PARAM)?.toInt(), + productSlug = uri.getQueryParameter(PLAN_SLUG_PARAM), + productName = "", + isCurrentPlan = false, + hasDomainCredit = false + ) + postActionEvent(SiteCreationPlansActionEvent.CreateSite(planModel)) } fun onUrlLoaded() { @@ -135,6 +149,12 @@ class SiteCreationPlansViewModel @Inject constructor( } } + private fun postActionEvent(actionEvent: SiteCreationPlansActionEvent) { + viewModelScope.launch { + _actionEvents.send(actionEvent) + } + } + companion object { const val WPCOM_LOGIN_URL = "https://wordpress.com/wp-login.php" const val WPCOM_DOMAIN = ".wordpress.com" @@ -150,6 +170,5 @@ class SiteCreationPlansViewModel @Inject constructor( } sealed class SiteCreationPlansActionEvent { - object FinishActivity : SiteCreationPlansActionEvent() - data class LaunchExternalBrowser(val url: String) : SiteCreationPlansActionEvent() + data class CreateSite(val planModel: PlanModel) : SiteCreationPlansActionEvent() } From 8356847fcf928d19a5c02515b3a3941d48f110f6 Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 19:07:01 +1100 Subject: [PATCH 20/26] Update SiteCreationPlansFragment.kt --- .../plans/SiteCreationPlansFragment.kt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt index 2cd6703220a9..e60918086813 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansFragment.kt @@ -1,6 +1,7 @@ package org.wordpress.android.ui.sitecreation.plans import android.annotation.SuppressLint +import android.net.Uri import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -33,8 +34,11 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.lifecycle.viewmodel.compose.viewModel import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.wordpress.android.R import org.wordpress.android.ui.WPWebViewActivity import org.wordpress.android.ui.compose.components.MainTopAppBar @@ -68,11 +72,20 @@ class SiteCreationPlansFragment : Fragment(), SiteCreationPlansWebViewClientList super.onViewCreated(view, savedInstanceState) viewModel.start(requireNotNull(requireArguments().getParcelableCompat(ARG_STATE))) + viewModel.actionEvents.onEach(this::handleActionEvents).launchIn(viewLifecycleOwner.lifecycleScope) + } + + private fun handleActionEvents(actionEvent: SiteCreationPlansActionEvent) { + when (actionEvent) { + is SiteCreationPlansActionEvent.CreateSite -> { + (requireActivity() as PlansScreenListener).onPlanSelected(actionEvent.planModel) + } + } } // SiteCreationWebViewClient - override fun onPlanSelected(url: String) { - viewModel.onPlanSelected(url) + override fun onPlanSelected(uri: Uri) { + viewModel.onPlanSelected(uri) } override fun onWebViewPageLoaded() { From b92f5a8840eae81fe5410087e1c205a3fd84c663 Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 19:07:06 +1100 Subject: [PATCH 21/26] Update SiteCreationActivity.kt --- .../android/ui/sitecreation/SiteCreationActivity.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt index 86c92b0f7dc1..a892881e0f7b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationActivity.kt @@ -44,6 +44,8 @@ import org.wordpress.android.ui.sitecreation.domains.DomainsScreenListener import org.wordpress.android.ui.sitecreation.domains.SiteCreationDomainsFragment import org.wordpress.android.ui.sitecreation.misc.OnHelpClickedListener import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource +import org.wordpress.android.ui.sitecreation.plans.PlanModel +import org.wordpress.android.ui.sitecreation.plans.PlansScreenListener import org.wordpress.android.ui.sitecreation.plans.SiteCreationPlansFragment import org.wordpress.android.ui.sitecreation.previews.SiteCreationPreviewFragment import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel @@ -72,6 +74,7 @@ class SiteCreationActivity : LocaleAwareActivity(), IntentsScreenListener, SiteNameScreenListener, DomainsScreenListener, + PlansScreenListener, OnHelpClickedListener, BasicDialogPositiveClickInterface, BasicDialogNegativeClickInterface { @@ -222,6 +225,10 @@ class SiteCreationActivity : LocaleAwareActivity(), mainViewModel.onDomainsScreenFinished(domain) } + override fun onPlanSelected(plan: PlanModel) { + mainViewModel.onPlanSelection(plan) + } + override fun onHelpClicked(origin: Origin) { ActivityLauncher.viewHelp(this, origin, null, null) } From a5ac6925e736d96643827421be814be965bf9bbe Mon Sep 17 00:00:00 2001 From: Ravi Date: Fri, 13 Oct 2023 19:07:11 +1100 Subject: [PATCH 22/26] Update SiteCreationMainVM.kt --- .../wordpress/android/ui/sitecreation/SiteCreationMainVM.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt index 5a7ba736ed43..211917370f6b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt @@ -269,6 +269,11 @@ class SiteCreationMainVM @Inject constructor( wizardManager.showNextStep() } + fun onPlanSelection(plan: PlanModel) { + siteCreationState = siteCreationState.copy(plan = plan) + wizardManager.showNextStep() + } + fun screenTitleForWizardStep(step: SiteCreationStep): SiteCreationScreenTitle { val stepPosition = wizardManager.stepPosition(step) val stepCount = wizardManager.stepsCount From 63015e75e130913b8a7bb781c921e506a5b9112c Mon Sep 17 00:00:00 2001 From: Ravi Date: Sat, 14 Oct 2023 17:35:56 +1100 Subject: [PATCH 23/26] Update SiteCreationPlansWebViewClient.kt handle plan selection --- .../plans/SiteCreationPlansWebViewClient.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt index daa780c1b176..6bc1dc72942d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansWebViewClient.kt @@ -13,12 +13,14 @@ class SiteCreationPlansWebViewClient( } override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { - if (request.url.toString().startsWith(JETPACK_APP_PLANS_PATH)) return false - - val urlString = request.url.toString() - if (urlString.contains(PLAN_SLUG)) { - listener.onPlanSelected(request.url) + if (request.url.toString().startsWith(JETPACK_APP_PLANS_PATH)) { + val planSlug = request.url.getQueryParameter(PLAN_SLUG).orEmpty() + if (planSlug.isNotBlank()) { + listener.onPlanSelected(request.url) + } + return false } + return true } From b094d590fde52e070623339b7e35f05d89f0c887 Mon Sep 17 00:00:00 2001 From: Ravi Date: Sat, 14 Oct 2023 17:36:19 +1100 Subject: [PATCH 24/26] Update SiteCreationPlansViewModel.kt update PlanId and PlanSlug --- .../ui/sitecreation/plans/SiteCreationPlansViewModel.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt index 4a8d90cd804e..7aa33d76a3db 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt @@ -43,9 +43,12 @@ class SiteCreationPlansViewModel @Inject constructor( fun onPlanSelected(uri: Uri) { AppLog.d(AppLog.T.PLANS, uri.toString()) + val planId = uri.getQueryParameter(PLAN_ID_PARAM)?.toInt() ?: 0 + val planSlug = uri.getQueryParameter(PLAN_SLUG_PARAM).orEmpty() + val planModel = PlanModel( - productId = uri.getQueryParameter(PLAN_ID_PARAM)?.toInt(), - productSlug = uri.getQueryParameter(PLAN_SLUG_PARAM), + productId = planId, + productSlug = planSlug, productName = "", isCurrentPlan = false, hasDomainCredit = false From 782b7b4ce089e9d0b635de84a7c924ad9df7cea0 Mon Sep 17 00:00:00 2001 From: Ravi Date: Sat, 14 Oct 2023 17:37:03 +1100 Subject: [PATCH 25/26] Update SiteCreationProgressViewModel.kt check for plan and product id before cart creation --- .../ui/sitecreation/progress/SiteCreationProgressViewModel.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt index 6b30471a3ae4..8d5196536066 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt @@ -98,7 +98,7 @@ class SiteCreationProgressViewModel @Inject constructor( if (siteCreationState.result is Created) { check(siteCreationState.result !is Completed) { "Unexpected state on progress screen." } // reuse the previously blog when returning with the same domain - if (siteCreationState.domain == domain) { + if (siteCreationState.domain == domain && siteCreationState.plan == plan) { site = siteCreationState.result.site if (siteCreationState.result is InCart) { createCart() @@ -176,7 +176,7 @@ class SiteCreationProgressViewModel @Inject constructor( SUCCESS -> { site = mapPayloadToSiteModel(event.payload) _onFreeSiteCreated.postValue(site) // MainVM will navigate forward if the domain is free - if (!domain.isFree) { + if (!domain.isFree && plan.productId != 0) { createCart() } } From 05d968249aa941a08ee6b3d8d88a609c28871221 Mon Sep 17 00:00:00 2001 From: Ravi Date: Sun, 15 Oct 2023 11:43:47 +1100 Subject: [PATCH 26/26] handle free plan selection handle free plan with free domain selection after first selecting paid domain --- .../ui/sitecreation/SiteCreationMainVM.kt | 17 +++++++++++++++++ .../plans/SiteCreationPlansViewModel.kt | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt index 211917370f6b..3c52ce378bf6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/SiteCreationMainVM.kt @@ -262,6 +262,11 @@ class SiteCreationMainVM @Inject constructor( siteCreationState = siteCreationState.copy(domain = null) } } + if (wizardStep == SiteCreationStep.PLANS) { + siteCreationState.plan?.let { + siteCreationState = siteCreationState.copy(plan = null) + } + } } fun onDomainsScreenFinished(domain: DomainModel) { @@ -271,6 +276,18 @@ class SiteCreationMainVM @Inject constructor( fun onPlanSelection(plan: PlanModel) { siteCreationState = siteCreationState.copy(plan = plan) + if (plan.productSlug == "free_plan") { + // if they select a paid domain, then choose a free plan, with free domain on plan selection screen + siteCreationState = siteCreationState.copy( + domain = DomainModel( + domainName = plan.productName.orEmpty(), + isFree = true, + cost = "", + productId = 0, + supportsPrivacy = false + ) + ) + } wizardManager.showNextStep() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt index 7aa33d76a3db..2bd322fea5c8 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/plans/SiteCreationPlansViewModel.kt @@ -45,11 +45,12 @@ class SiteCreationPlansViewModel @Inject constructor( val planId = uri.getQueryParameter(PLAN_ID_PARAM)?.toInt() ?: 0 val planSlug = uri.getQueryParameter(PLAN_SLUG_PARAM).orEmpty() + val domainName = uri.getQueryParameter(PAID_DOMAIN_NAME).orEmpty() val planModel = PlanModel( productId = planId, productSlug = planSlug, - productName = "", + productName = domainName, // using domainName here isCurrentPlan = false, hasDomainCredit = false )