Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement final screen UI #18305

Merged
merged 9 commits into from
Apr 25, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ import org.wordpress.android.databinding.SiteCreationPreviewScreenDefaultBinding
import org.wordpress.android.ui.sitecreation.SiteCreationActivity.Companion.ARG_STATE
import org.wordpress.android.ui.sitecreation.SiteCreationBaseFormFragment
import org.wordpress.android.ui.sitecreation.SiteCreationState
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewData
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewContentUiState
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewLoadingShimmerState
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewWebErrorUiState
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.UrlData
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.ErrorManagedWebViewClient.ErrorManagedWebViewClientListener
import org.wordpress.android.util.URLFilteredWebViewClient
Expand Down Expand Up @@ -85,11 +83,9 @@ class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(),
private fun SiteCreationPreviewScreenDefaultBinding.observeState() {
viewModel.uiState.observe(this@SiteCreationPreviewFragment) {
it?.let { ui ->
when (ui) {
is SitePreviewContentUiState -> updateContentLayout(ui.data)
is SitePreviewWebErrorUiState -> updateContentLayout(ui.data)
is SitePreviewLoadingShimmerState -> updateContentLayout(ui.data, isFirstContent = true)
}
uiHelpers.setTextOrHide(siteCreationPreviewHeaderItem.sitePreviewSubtitle, ui.subtitle)
uiHelpers.setTextOrHide(sitePreviewCaption, ui.caption)
updateContentLayout(ui.urlData, isFirstContent = ui is SitePreviewLoadingShimmerState)
siteCreationPreviewWebViewContainer.apply {
uiHelpers.updateVisibility(sitePreviewWebView, ui.webViewVisibility)
uiHelpers.updateVisibility(sitePreviewWebError, ui.webViewErrorVisibility)
Expand All @@ -110,10 +106,10 @@ class SiteCreationPreviewFragment : SiteCreationBaseFormFragment(),
}

private fun SiteCreationPreviewScreenDefaultBinding.updateContentLayout(
sitePreviewData: SitePreviewData,
urlData: UrlData,
isFirstContent: Boolean = false,
) {
sitePreviewData.apply {
urlData.apply {
siteCreationPreviewWebViewContainer.sitePreviewWebUrlTitle.text = createSpannableUrl(
requireNotNull(activity),
shortUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.wordpress.android.R
import org.wordpress.android.fluxc.Dispatcher
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.store.SiteStore
Expand All @@ -22,8 +23,12 @@ import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewContentUiState
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewLoadingShimmerState
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.SitePreviewWebErrorUiState
import org.wordpress.android.ui.sitecreation.previews.SitePreviewViewModel.SitePreviewUiState.UrlData
import org.wordpress.android.ui.sitecreation.services.FetchWpComSiteUseCase
import org.wordpress.android.ui.sitecreation.usecases.isWordPressComSubDomain
import org.wordpress.android.ui.utils.UiString
import org.wordpress.android.ui.utils.UiString.UiStringRes
import org.wordpress.android.ui.utils.UiString.UiStringResWithParams
import org.wordpress.android.util.AppLog
import org.wordpress.android.util.AppLog.T
import org.wordpress.android.util.UrlUtilsWrapper
Expand Down Expand Up @@ -59,9 +64,10 @@ class SitePreviewViewModel @Inject constructor(
private var webviewFullyLoadedTracked = false

private var siteDesign: String? = null
private var urlWithoutScheme: String? = null
private var isFree: Boolean = true

private lateinit var result: Created
private lateinit var domainName: String

private val _uiState: MutableLiveData<SitePreviewUiState> = MutableLiveData()
val uiState: LiveData<SitePreviewUiState> = _uiState
Expand All @@ -77,7 +83,8 @@ class SitePreviewViewModel @Inject constructor(
require(siteCreationState.result is Created)
siteDesign = siteCreationState.siteDesign
result = siteCreationState.result
urlWithoutScheme = result.site.url
isFree = requireNotNull(siteCreationState.domain).isFree
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess based on the require here that this isn't ever expected to be null here?

Copy link
Contributor Author

@ovitrif ovitrif Apr 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, the only reason it's nullable is because of how we modelled the SiteCreationState 😄 . Ideally we'd have found a better, immutable way to do it instead of simply storing the value in a nullable field when advancing to the next step of the flow, imho 😄
But in real world scenarios it should be impossible to get to this screen with the domain null. If we can get here, it's better to crash 😄

domainName = requireNotNull(siteCreationState.domain).domainName
startPreLoadingWebView()
if (result is CreatedButNotFetched) {
launch {
Expand All @@ -103,12 +110,12 @@ class SitePreviewViewModel @Inject constructor(
withContext(mainDispatcher) {
if (uiState.value !is SitePreviewContentUiState) {
tracker.trackPreviewWebviewShown(siteDesign)
updateUiState(SitePreviewLoadingShimmerState(createSitePreviewData()))
updateUiState(SitePreviewLoadingShimmerState(isFree, createSitePreviewData()))
}
}
}
// Load the newly created site in the webview
urlWithoutScheme?.let { url ->
result.site.url?.let { url ->
val urlToLoad = urlUtils.addUrlSchemeIfNeeded(
url = url,
addHttps = isWordPressComSubDomain(url)
Expand Down Expand Up @@ -142,23 +149,23 @@ class SitePreviewViewModel @Inject constructor(
* In other words don't update it after a configuration change.
*/
if (uiState.value !is SitePreviewContentUiState) {
updateUiState(SitePreviewContentUiState(createSitePreviewData()))
updateUiState(SitePreviewContentUiState(isFree, createSitePreviewData()))
}
}

fun onWebViewError() {
if (uiState.value !is SitePreviewWebErrorUiState) {
updateUiState(SitePreviewWebErrorUiState(createSitePreviewData()))
updateUiState(SitePreviewWebErrorUiState(isFree, createSitePreviewData()))
}
}

private fun createSitePreviewData(): SitePreviewData {
val url = urlWithoutScheme ?: ""
private fun createSitePreviewData(): UrlData {
val url = domainName
val subDomain = urlUtils.extractSubDomain(url)
val fullUrl = urlUtils.addUrlSchemeIfNeeded(url, true)
val subDomainIndices = 0 to subDomain.length
val domainIndices = subDomainIndices.second.coerceAtMost(url.length) to url.length
return SitePreviewData(
return UrlData(
fullUrl,
url,
subDomainIndices,
Expand All @@ -171,29 +178,67 @@ class SitePreviewViewModel @Inject constructor(
}

sealed class SitePreviewUiState(
open val urlData: UrlData,
val webViewVisibility: Boolean = false,
val webViewErrorVisibility: Boolean = false,
val shimmerVisibility: Boolean = false,
val subtitle: UiString,
val caption: UiString?,
) {
data class SitePreviewContentUiState(val data: SitePreviewData) : SitePreviewUiState(
data class SitePreviewContentUiState(
val isFree: Boolean,
override val urlData: UrlData,
) : SitePreviewUiState(
urlData = urlData,
webViewVisibility = true,
webViewErrorVisibility = false
webViewErrorVisibility = false,
subtitle = getSubtitle(isFree),
caption = getCaption(isFree),
)

data class SitePreviewWebErrorUiState(val data: SitePreviewData) : SitePreviewUiState(
data class SitePreviewWebErrorUiState(
val isFree: Boolean,
override val urlData: UrlData,
) : SitePreviewUiState(
urlData = urlData,
webViewVisibility = false,
webViewErrorVisibility = true
webViewErrorVisibility = true,
subtitle = getSubtitle(isFree),
caption = getCaption(isFree),
)

data class SitePreviewLoadingShimmerState(val data: SitePreviewData) : SitePreviewUiState(
shimmerVisibility = true
data class SitePreviewLoadingShimmerState(
val isFree: Boolean,
override val urlData: UrlData,
) : SitePreviewUiState(
urlData = urlData,
shimmerVisibility = true,
subtitle = getSubtitle(isFree),
caption = getCaption(isFree),
)
}

data class SitePreviewData(
val fullUrl: String,
val shortUrl: String,
val domainIndices: Pair<Int, Int>,
val subDomainIndices: Pair<Int, Int>
)
companion object {
private fun getSubtitle(isFree: Boolean): UiString {
return if (isFree) {
UiStringRes(R.string.new_site_creation_preview_subtitle)
} else {
UiStringResWithParams(
R.string.new_site_creation_preview_subtitle_paid,
UiStringRes(R.string.new_site_creation_preview_subtitle),
)
}
}

private fun getCaption(isFree: Boolean): UiStringRes? {
return UiStringRes(R.string.new_site_creation_preview_caption_paid).takeIf { !isFree }
}
}

data class UrlData(
val fullUrl: String,
val shortUrl: String,
val domainIndices: Pair<Int, Int>,
val subDomainIndices: Pair<Int, Int>
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ class UiHelpers @Inject constructor() {
view.visibility = if (visible) View.VISIBLE else View.GONE
}

fun setTextOrHide(view: TextView, uiString: UiString?) {
val text = uiString?.let { getTextOfUiString(view.context, uiString) }
setTextOrHide(view, text)
fun setTextOrHide(view: TextView?, uiString: UiString?) {
view?.let {
val text = uiString?.let { getTextOfUiString(view.context, uiString) }
setTextOrHide(view, text)
}
}

fun setTextOrHide(view: TextView, @StringRes resId: Int?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
android:id="@+id/site_creation_preview_header_item"
layout="@layout/site_creation_preview_header_item" />

<TextView
android:id="@+id/sitePreviewCaption"
style="@style/SiteCreationHeaderV2Subtitle"
android:lineSpacingExtra="@null"
android:paddingBottom="@null"
android:text="@string/new_site_creation_preview_caption_paid" />

<com.google.android.material.button.MaterialButton
android:id="@+id/okButton"
style="@style/WordPress.Button.Primary"
Expand All @@ -38,9 +45,10 @@
layout="@layout/site_creation_preview_web_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_extra_medium_large"
android:layout_marginBottom="@dimen/margin_large"
android:layout_marginEnd="@dimen/margin_large"
android:layout_marginStart="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_large"
android:layout_toStartOf="@+id/sitePreviewTitleAndButtonContainer" />
</RelativeLayout>

4 changes: 0 additions & 4 deletions WordPress/src/main/res/layout/site_creation_header_v2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
<org.wordpress.android.widgets.WPTextView
android:id="@+id/title"
style="@style/SiteCreationHeaderV2Title"
android:lineSpacingExtra="-4sp"
android:letterSpacing="0.01"
android:paddingBottom="@dimen/margin_large"
app:fixWidowWords="true"
app:autoSizeTextType="uniform"
Expand All @@ -20,8 +18,6 @@
android:id="@+id/subtitle"
style="@style/SiteCreationHeaderV2Subtitle"
android:paddingBottom="@dimen/margin_extra_medium_large"
android:lineSpacingExtra="5sp"
android:letterSpacing="0.01"
app:fixWidowWords="true"
tools:text="@string/new_site_creation_intents_header_subtitle" />
</LinearLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@

<org.wordpress.android.widgets.WPTextView
android:id="@+id/sitePreviewTitle"
style="@style/SiteCreationPreviewHeaderTitle"
app:fixWidowWords="true" />
style="@style/SiteCreationHeaderV2Title"
android:paddingBottom="@dimen/margin_large"
android:text="@string/new_site_creation_preview_title"
app:fixWidowWords="true"
app:autoSizeTextType="uniform" />

<org.wordpress.android.widgets.WPTextView
android:id="@+id/sitePreviewSubtitle"
style="@style/SiteCreationPreviewHeaderSubtitle"
style="@style/SiteCreationHeaderV2Subtitle"
android:lineSpacingExtra="@null"
android:paddingBottom="@null"
android:text="@string/new_site_creation_preview_subtitle"
app:fixWidowWords="true" />
</LinearLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,35 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/margin_extra_medium_large"
android:layout_marginEnd="@dimen/margin_large"
android:layout_marginStart="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_extra_medium_large" />
android:layout_marginHorizontal="@dimen/margin_extra_large"
android:layout_marginVertical="@dimen/margin_large" />

<include
android:id="@+id/site_creation_preview_web_view_container"
layout="@layout/site_creation_preview_web_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/sitePreviewOkButtonContainer"
android:layout_above="@+id/sitePreviewCaption"
android:layout_below="@id/site_creation_preview_header_item"
android:layout_marginBottom="@dimen/negative_margin_medium"
android:layout_marginLeft="@dimen/site_creation_preview_web_view_side_margin"
android:layout_marginRight="@dimen/site_creation_preview_web_view_side_margin" />
android:layout_marginHorizontal="@dimen/margin_extra_large" />

<TextView
android:id="@+id/sitePreviewCaption"
style="@style/SiteCreationHeaderV2Subtitle"
android:layout_above="@+id/sitePreviewOkButtonContainer"
android:lineSpacingExtra="@null"
android:layout_marginHorizontal="@dimen/margin_extra_large"
android:layout_marginTop="@dimen/margin_large"
android:paddingBottom="@null"
android:text="@string/new_site_creation_preview_caption_paid" />

<com.google.android.material.card.MaterialCardView
android:id="@+id/sitePreviewOkButtonContainer"
style="@style/Widget.MaterialComponents.CardView"
android:layout_width="match_parent"
android:layout_height="@dimen/site_creation_preview_ok_button_container_height"
android:layout_alignParentBottom="true"
android:layout_marginTop="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_large"
app:cardElevation="@dimen/site_creation_container_elevation"
tools:ignore="InconsistentLayout">

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
style="@style/Widget.MaterialComponents.CardView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="0dp"
app:cardElevation="@dimen/card_elevation">
app:cardCornerRadius="@dimen/margin_large"
app:cardElevation="@dimen/card_elevation"
app:strokeColor="@color/site_creation_preview_card_border"
app:strokeWidth="@dimen/margin_extra_extra_small">

<LinearLayout
android:layout_width="match_parent"
Expand Down
7 changes: 7 additions & 0 deletions WordPress/src/main/res/values-land/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="SiteCreationHeaderV2Title" parent="SiteCreationHeaderV2Title.Base">
<item name="android:textSize">@dimen/text_sz_double_extra_large</item>
<item name="android:lineSpacingExtra">@null</item>
</style>
</resources>
1 change: 1 addition & 0 deletions WordPress/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@

<!-- Site creation -->
<color name="site_creation_intent_item_emoji_bg">#3d3d3d</color>
<color name="site_creation_preview_card_border">@color/white_translucent_20</color>

<!-- Jetpack Migration -->
<color name="bg_jp_migration_buttons_panel">#E6121212</color>
Expand Down
1 change: 1 addition & 0 deletions WordPress/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
<!-- Site creation -->
<color name="site_creation_skip_button_text">@color/blue_50</color>
<color name="site_creation_intent_item_emoji_bg">@color/grey_lighten_30</color>
<color name="site_creation_preview_card_border">@color/black_translucent_20</color>

<!-- Jetpack Migration -->
<color name="bg_jp_migration_buttons_panel">@color/white_translucent_80</color>
Expand Down
1 change: 0 additions & 1 deletion WordPress/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,6 @@
<dimen name="site_creation_verticals_clear_search_icon_size">24dp</dimen>
<dimen name="site_creation_verticals_clear_search_clickable_area_width">48dp</dimen>

<dimen name="site_creation_preview_web_view_side_margin">40dp</dimen>
<dimen name="site_creation_preview_ok_button_container_height">68dp</dimen>
<dimen name="site_creation_container_elevation">6dp</dimen>

Expand Down
2 changes: 2 additions & 0 deletions WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3331,6 +3331,8 @@
<string name="new_site_creation_screen_title_step_count">%1$d of %2$d</string>
<string name="new_site_creation_preview_title">Your site has been created!</string>
<string name="new_site_creation_preview_subtitle">You\'ll be able to customize the look and feel of your site later</string>
<string name="new_site_creation_preview_subtitle_paid">We’ve emailed your receipt. %s</string>
<string name="new_site_creation_preview_caption_paid">It may take up to 30 minutes for your custom domain to start working.</string>
<string name="site_creation_fetch_suggestions_error_unknown">There was a problem</string>
<string name="site_creation_error_generic_title">There was a problem</string>
<string name="site_creation_error_generic_subtitle">Error communicating with the server, please try again</string>
Expand Down
Loading