Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import org.wordpress.android.ui.pages.SnackbarMessageHolder
import org.wordpress.android.ui.prefs.EmptyViewRecyclerView
import org.wordpress.android.ui.prefs.experimentalfeatures.ExperimentalFeatures
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.ColorUtils
import org.wordpress.android.util.extensions.getSerializableCompat
import org.wordpress.android.util.extensions.getSerializableExtraCompat
import org.wordpress.android.util.image.ImageManager
Expand Down Expand Up @@ -94,28 +93,27 @@ class ScanFragment : Fragment(R.layout.scan_fragment) {

private fun ScanFragmentBinding.setupObservers() {
viewModel.uiState.observe(
viewLifecycleOwner,
{ uiState ->
uiHelpers.updateVisibility(progressBar, uiState.loadingVisible)
uiHelpers.updateVisibility(recyclerView, uiState.contentVisible)
uiHelpers.updateVisibility(actionableEmptyView, uiState.errorVisible)

when (uiState) {
is ContentUiState -> updateContentLayout(uiState)

is FullScreenLoadingUiState -> { // Do Nothing
}

is ErrorUiState.NoConnection,
is ErrorUiState.GenericRequestFailed,
is ErrorUiState.ScanRequestFailed,
is ErrorUiState.MultisiteNotSupported,
is ErrorUiState.VaultPressActiveOnSite -> updateErrorLayout(uiState as ErrorUiState)
viewLifecycleOwner
) { uiState ->
uiHelpers.updateVisibility(progressBar, uiState.loadingVisible)
uiHelpers.updateVisibility(recyclerView, uiState.contentVisible)
uiHelpers.updateVisibility(actionableEmptyView, uiState.errorVisible)

when (uiState) {
is ContentUiState -> updateContentLayout(uiState)

is FullScreenLoadingUiState -> { // Do Nothing
}

is ErrorUiState.NoConnection,
is ErrorUiState.GenericRequestFailed,
is ErrorUiState.ScanRequestFailed,
is ErrorUiState.MultisiteNotSupported,
is ErrorUiState.VaultPressActiveOnSite -> updateErrorLayout(uiState)
}
)
}

viewModel.snackbarEvents.observeEvent(viewLifecycleOwner, { it.showSnackbar() })
viewModel.snackbarEvents.observeEvent(viewLifecycleOwner) { it.showSnackbar() }

viewModel.navigationEvents.observeEvent(
viewLifecycleOwner
Expand Down Expand Up @@ -147,10 +145,6 @@ class ScanFragment : Fragment(R.layout.scan_fragment) {
private fun ScanFragmentBinding.updateErrorLayout(state: ErrorUiState) {
uiHelpers.setTextOrHide(actionableEmptyView.title, state.title)
uiHelpers.setTextOrHide(actionableEmptyView.subtitle, state.subtitle)
actionableEmptyView.image.setImageResource(state.image)
state.imageColorResId?.let {
ColorUtils.setImageResourceWithTint(actionableEmptyView.image, state.image, it)
} ?: actionableEmptyView.image.setImageResource(state.image)
state.buttonText?.let { uiHelpers.setTextOrHide(actionableEmptyView.button, state.buttonText) }
state.action?.let { action -> actionableEmptyView.button.setOnClickListener { action.invoke() } }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.wordpress.android.ui.jetpack.scan

import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
Expand Down Expand Up @@ -366,53 +364,35 @@ class ScanViewModel @Inject constructor(
data class ContentUiState(val items: List<JetpackListItemState>) : UiState(contentVisible = true)

sealed class ErrorUiState : UiState(errorVisible = true) {
abstract val image: Int
open val imageColorResId: Int? = null
abstract val title: UiString
abstract val subtitle: UiString
open val buttonText: UiString? = null
open val action: (() -> Unit)? = null

data class NoConnection(override val action: () -> Unit) : ErrorUiState() {
@DrawableRes
override val image = R.drawable.img_illustration_cloud_off_152dp
override val title = UiStringRes(R.string.scan_no_network_title)
override val subtitle = UiStringRes(R.string.scan_no_network_subtitle)
override val buttonText = UiStringRes(R.string.retry)
}

data class GenericRequestFailed(override val action: () -> Unit) : ErrorUiState() {
@DrawableRes
override val image = R.drawable.img_illustration_cloud_off_152dp
override val title = UiStringRes(R.string.scan_request_failed_title)
override val subtitle = UiStringRes(R.string.scan_request_failed_subtitle)
override val buttonText = UiStringRes(R.string.contact_support)
}

data class ScanRequestFailed(override val action: () -> Unit) : ErrorUiState() {
@DrawableRes
override val image = R.drawable.img_illustration_empty_results_216dp
override val title = UiStringRes(R.string.scan_start_request_failed_title)
override val subtitle = UiStringRes(R.string.scan_start_request_failed_subtitle)
override val buttonText = UiStringRes(R.string.contact_support)
}

object MultisiteNotSupported : ErrorUiState() {
@DrawableRes
override val image = R.drawable.ic_baseline_security_white_24dp

@ColorRes
override val imageColorResId = R.color.gray
override val title = UiStringRes(R.string.scan_multisite_not_supported_title)
override val subtitle = UiStringRes(R.string.scan_multisite_not_supported_subtitle)
}

data class VaultPressActiveOnSite(override val action: () -> Unit) : ErrorUiState() {
@DrawableRes
override val image = R.drawable.ic_shield_warning_white

@ColorRes
override val imageColorResId = R.color.error_60
override val title = UiStringRes(R.string.scan_vault_press_active_on_site_title)
override val subtitle = UiStringRes(R.string.scan_vault_press_active_on_site_subtitle)
override val buttonText = UiStringRes(R.string.scan_vault_press_active_on_site_button_text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ class ScanHistoryFragment : Fragment(R.layout.scan_history_fragment), MenuProvid

private fun FullscreenErrorWithRetryBinding.updateErrorLayout(uiState: ErrorUiState) {
uiHelpers.setTextOrHide(errorTitle, uiState.title)
uiHelpers.updateVisibility(errorImage, true)
errorImage.setImageResource(uiState.img)
uiHelpers.updateVisibility(errorImage, false)
errorRetry.setOnClickListener { uiState.retry.invoke() }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.wordpress.android.ui.jetpack.scan.history

import android.annotation.SuppressLint
import android.os.Parcelable
import androidx.annotation.DrawableRes
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import dagger.hilt.android.lifecycle.HiltViewModel
Expand Down Expand Up @@ -90,21 +89,14 @@ class ScanHistoryViewModel @Inject constructor(

sealed class ErrorUiState : UiState(errorVisible = true) {
abstract val title: UiString
abstract val img: Int
abstract val retry: () -> Unit

data class NoConnection(override val retry: () -> Unit) : ErrorUiState() {
override val title: UiString = UiStringRes(R.string.scan_history_no_connection)

@DrawableRes
override val img: Int = R.drawable.img_illustration_cloud_off_152dp
}

data class RequestFailed(override val retry: () -> Unit) : ErrorUiState() {
override val title: UiString = UiStringRes(R.string.scan_history_request_failed)

@DrawableRes
override val img: Int = R.drawable.img_illustration_cloud_off_152dp
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ class SiteItemsViewModelSlice @Inject constructor(
private suspend fun rebuildSiteItemsForJetpackCapabilities(site: SiteModel) {
jetpackCapabilitiesUseCase.getJetpackPurchasedProducts(site.siteId).collect { purchasedProducts ->
// if the site has scan or backup enabled, then only rebuild the site items
if(purchasedProducts.scan || purchasedProducts.backup) {
if (purchasedProducts.scan || purchasedProducts.backup) {
val items = siteItemsBuilder.build(
getParams(
shouldEnableFocusPoints = false,
site = site,
backupAvailable = purchasedProducts.backup,
scanAvailable = purchasedProducts.scan && !site.isWPCom && !site.isWPComAtomic
scanAvailable = purchasedProducts.scan
)
)
_uiModel.postValue(items)
}
} // end collect
}
}

fun getParams(
Expand Down
1 change: 0 additions & 1 deletion WordPress/src/main/res/layout/scan_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:aevImage="@drawable/img_illustration_empty_results_216dp"
app:aevTitle="@string/loading"
tools:visibility="visible" />

Expand Down
1 change: 0 additions & 1 deletion WordPress/src/main/res/values/colors_semantic.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

<color name="error">@color/red_50</color>
<color name="error_50">@color/red_50</color>
<color name="error_60">@color/red_60</color>

<color name="neutral">@color/gray_50</color>
<color name="neutral_0">@color/gray_0</color>
Expand Down
6 changes: 3 additions & 3 deletions WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1263,11 +1263,11 @@
<string name="scan_no_network_title" translatable="false">@string/no_network_title</string>
<string name="scan_no_network_subtitle" translatable="false">@string/no_network_message</string>
<string name="scan_request_failed_title">Something went wrong</string>
<string name="scan_request_failed_subtitle" translatable="false">@string/request_failed_message</string>
<string name="scan_request_failed_subtitle" translatable="false">Failed to start the scan</string>
<string name="scan_start_request_failed_title" translatable="false">@string/scan_request_failed_title</string>
<string name="scan_start_request_failed_subtitle">Jetpack Scan couldn\'t complete a scan of your site. Please check to see if your site is down – if it\'s not, try again. If it is, or if Jetpack Scan is still having problems, contact our support team.</string>
<string name="scan_start_request_failed_subtitle">Jetpack Scan couldn\'t complete a scan of your site. Please check to see if your site is down.</string>
<string name="scan_multisite_not_supported_title">WordPress multisites are not supported</string>
<string name="scan_multisite_not_supported_subtitle">We\'re sorry, Jetpack Scan is not compatible with multisite WordPress installations at this time.</string>
<string name="scan_multisite_not_supported_subtitle">We\'re sorry, Jetpack Scan is not compatible with multisite WordPress installations</string>
<string name="scan_vault_press_active_on_site_title">Your site has VaultPress</string>
<string name="scan_vault_press_active_on_site_subtitle">Your site already is protected by VaultPress. You can find a link to your VaultPress dashboard below.</string>
<string name="scan_vault_press_active_on_site_button_text">Visit Dashboard</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ class ScanViewModelTest : BaseUnitTest() {

val error = observers.uiStates.last() as ErrorUiState
with(error) {
assertThat(image).isEqualTo(R.drawable.img_illustration_cloud_off_152dp)
assertThat(title).isEqualTo(UiStringRes(R.string.scan_no_network_title))
assertThat(subtitle).isEqualTo(UiStringRes(R.string.scan_no_network_subtitle))
assertThat(buttonText).isEqualTo(UiStringRes(R.string.retry))
Expand Down Expand Up @@ -220,7 +219,6 @@ class ScanViewModelTest : BaseUnitTest() {

val state = observers.uiStates.last() as ErrorUiState
with(state) {
assertThat(image).isEqualTo(R.drawable.img_illustration_cloud_off_152dp)
assertThat(title).isEqualTo(UiStringRes(R.string.scan_request_failed_title))
assertThat(subtitle).isEqualTo(UiStringRes(R.string.scan_request_failed_subtitle))
assertThat(buttonText).isEqualTo(UiStringRes(R.string.contact_support))
Expand Down Expand Up @@ -326,8 +324,6 @@ class ScanViewModelTest : BaseUnitTest() {

val state = observers.uiStates.last() as ErrorUiState
with(state) {
assertThat(image).isEqualTo(R.drawable.ic_baseline_security_white_24dp)
assertThat(imageColorResId).isEqualTo(R.color.gray)
assertThat(title).isEqualTo(UiStringRes(R.string.scan_multisite_not_supported_title))
assertThat(subtitle).isEqualTo(UiStringRes(R.string.scan_multisite_not_supported_subtitle))
}
Expand All @@ -352,8 +348,6 @@ class ScanViewModelTest : BaseUnitTest() {

val state = observers.uiStates.last() as ErrorUiState
with(state) {
assertThat(image).isEqualTo(R.drawable.ic_shield_warning_white)
assertThat(imageColorResId).isEqualTo(R.color.error_60)
assertThat(title).isEqualTo(UiStringRes(R.string.scan_vault_press_active_on_site_title))
assertThat(subtitle).isEqualTo(UiStringRes(R.string.scan_vault_press_active_on_site_subtitle))
}
Expand Down Expand Up @@ -446,7 +440,6 @@ class ScanViewModelTest : BaseUnitTest() {

val errorState = observers.uiStates.last() as ErrorUiState
with(errorState) {
assertThat(image).isEqualTo(R.drawable.img_illustration_empty_results_216dp)
assertThat(title).isEqualTo(UiStringRes(R.string.scan_start_request_failed_title))
assertThat(subtitle).isEqualTo(UiStringRes(R.string.scan_start_request_failed_subtitle))
assertThat(buttonText).isEqualTo(UiStringRes(R.string.contact_support))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() {
whenever(blazeFeatureUtils.isSiteBlazeEligible(site)).thenReturn(true)
val captor = argumentCaptor<MySiteCardAndItemBuilderParams.SiteItemsBuilderParams>()


// When
siteItemsViewModelSlice.buildSiteItems(site = site)
advanceUntilIdle()
Expand All @@ -131,6 +130,7 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() {

// When
siteItemsViewModelSlice.buildSiteItems(site = site)
advanceUntilIdle()

// Then
verify(siteItemsBuilder).build(captor.capture())
Expand Down