Skip to content

Commit

Permalink
Merge pull request #19910 from wordpress-mobile/feature/update-site-d…
Browse files Browse the repository at this point in the history
…omains-screen

Add tapping functionality to domain cards on the Site Domain screen
  • Loading branch information
ravishanker authored Jan 12, 2024
2 parents a2810c5 + e98bb86 commit 54d9f46
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import org.wordpress.android.ui.domains.DomainRegistrationActivity.DomainRegistr
import org.wordpress.android.ui.domains.DomainsDashboardNavigationAction.ClaimDomain
import org.wordpress.android.ui.domains.DomainsDashboardNavigationAction.GetDomain
import org.wordpress.android.ui.domains.DomainsDashboardNavigationAction.GetPlan
import org.wordpress.android.ui.domains.management.details.DomainManagementDetailsActivity
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.config.DomainManagementFeatureConfig
import org.wordpress.android.util.extensions.getSerializableExtraCompat
Expand Down Expand Up @@ -100,16 +101,22 @@ class DomainsDashboardFragment : Fragment(R.layout.domains_dashboard_fragment),
action.site,
DOMAIN_PURCHASE
)

is ClaimDomain -> ActivityLauncher.viewDomainRegistrationActivityForResult(
this,
action.site,
CTA_DOMAIN_CREDIT_REDEMPTION
)

is GetPlan -> ActivityLauncher.viewDomainRegistrationActivityForResult(
this,
action.site,
FREE_DOMAIN_WITH_ANNUAL_PLAN
)

is DomainsDashboardNavigationAction.OpenDomainManagement -> startActivity(
DomainManagementDetailsActivity.createIntent(requireContext(), action.domain, action.detailUrl)
)
}

@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.wordpress.android.ui.domains

import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import org.wordpress.android.ui.domains.DomainsDashboardItem.Type.ADD_DOMAIN
import org.wordpress.android.ui.domains.DomainsDashboardItem.Type.PURCHASE_DOMAIN
Expand All @@ -22,8 +23,11 @@ sealed class DomainsDashboardItem(val type: Type) {

data class SiteDomains(
val domain: UiString,
val expiry: UiString,
val isPrimary: Boolean,
val domainStatus: UiString,
@ColorRes val domainStatusColor: Int,
val expiry: UiString?,
val onDomainClick: ListItemInteraction? = null
) : DomainsDashboardItem(SITE_DOMAINS)

data class AddDomain(val onClick: ListItemInteraction) : DomainsDashboardItem(ADD_DOMAIN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.wordpress.android.ui.domains
import org.wordpress.android.fluxc.model.SiteModel

sealed class DomainsDashboardNavigationAction {
data class OpenDomainManagement(val domain: String, val detailUrl: String) : DomainsDashboardNavigationAction()
data class GetDomain(val site: SiteModel) : DomainsDashboardNavigationAction()
data class ClaimDomain(val site: SiteModel) : DomainsDashboardNavigationAction()
data class GetPlan(val site: SiteModel) : DomainsDashboardNavigationAction()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ sealed class DomainsDashboardViewHolder<T : ViewBinding>(
uiHelpers.setTextOrHide(siteDomain, item.domain)
uiHelpers.setTextOrHide(siteDomainExpiryDate, item.expiry)
primarySiteDomainChip.isVisible = item.isPrimary
uiHelpers.setTextOrHide(siteDomainStatus, item.domainStatus)
siteDomainStatus.compoundDrawablesRelative.first().setTint(
siteDomainStatus.context.getColor(item.domainStatusColor)
)
item.onDomainClick?.let { interaction -> root.setOnClickListener { interaction.click() } }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import org.wordpress.android.analytics.AnalyticsTracker.Stat.DOMAINS_DASHBOARD_V
import org.wordpress.android.analytics.AnalyticsTracker.Stat.DOMAIN_CREDIT_REDEMPTION_TAPPED
import org.wordpress.android.fluxc.model.PlanModel
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpcom.site.AllDomainsDomain
import org.wordpress.android.fluxc.network.rest.wpcom.site.Domain
import org.wordpress.android.fluxc.network.rest.wpcom.site.StatusType
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.ui.domains.DomainsDashboardItem.AddDomain
Expand All @@ -23,6 +25,10 @@ import org.wordpress.android.ui.domains.DomainsDashboardItem.SiteDomainsHeader
import org.wordpress.android.ui.domains.DomainsDashboardNavigationAction.ClaimDomain
import org.wordpress.android.ui.domains.DomainsDashboardNavigationAction.GetDomain
import org.wordpress.android.ui.domains.DomainsDashboardNavigationAction.GetPlan
import org.wordpress.android.ui.domains.DomainsDashboardNavigationAction.OpenDomainManagement
import org.wordpress.android.ui.domains.management.getDomainDetailsUrl
import org.wordpress.android.ui.domains.usecases.AllDomains
import org.wordpress.android.ui.domains.usecases.FetchAllDomainsUseCase
import org.wordpress.android.ui.domains.usecases.FetchPlansUseCase
import org.wordpress.android.ui.plans.isDomainCreditAvailable
import org.wordpress.android.ui.utils.HtmlMessageUtils
Expand All @@ -46,6 +52,7 @@ class DomainsDashboardViewModel @Inject constructor(
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper,
private val htmlMessageUtils: HtmlMessageUtils,
private val fetchPlansUseCase: FetchPlansUseCase,
private val fetchAllDomainsUseCase: FetchAllDomainsUseCase,
@Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher
) : ScopedViewModel(bgDispatcher) {
lateinit var site: SiteModel
Expand Down Expand Up @@ -80,9 +87,11 @@ class DomainsDashboardViewModel @Inject constructor(

val deferredPlansResult = async { fetchPlansUseCase.execute(site) }
val deferredDomainsResult = async { siteStore.fetchSiteDomains(site) }
val deferredAllDomainsResult = async { fetchAllDomainsUseCase.execute() }

val plansResult = deferredPlansResult.await()
val domainsResult = deferredDomainsResult.await()
val allDomainsResult = deferredAllDomainsResult.await()

if (plansResult.isError) {
AppLog.e(DOMAIN_REGISTRATION, "An error occurred while fetching plans: ${plansResult.error.message}")
Expand All @@ -92,10 +101,17 @@ class DomainsDashboardViewModel @Inject constructor(
AppLog.e(DOMAIN_REGISTRATION, "An error occurred while fetching domains: ${domainsResult.error.message}")
}

buildDashboardItems(site, plansResult.plans.orEmpty(), domainsResult.domains.orEmpty())
val allDomains = if (allDomainsResult is AllDomains.Success) allDomainsResult.domains else emptyList()

buildDashboardItems(site, plansResult.plans.orEmpty(), domainsResult.domains.orEmpty(), allDomains)
}

private fun buildDashboardItems(site: SiteModel, plans: List<PlanModel>, domains: List<Domain>) {
private fun buildDashboardItems(
site: SiteModel,
plans: List<PlanModel>,
domains: List<Domain>,
allDomains: List<AllDomainsDomain>
) {
val listItems = mutableListOf<DomainsDashboardItem>()

listItems += SiteDomainsHeader(UiStringRes(R.string.domains_free_domain))
Expand All @@ -106,8 +122,10 @@ class DomainsDashboardViewModel @Inject constructor(

listItems += SiteDomains(
UiStringText(freeDomainUrl),
UiStringRes(R.string.domains_site_domain_never_expires),
freeDomainIsPrimary
freeDomainIsPrimary,
UiStringRes(R.string.active),
getStatusColor(StatusType.SUCCESS),
UiStringRes(R.string.domains_site_domain_never_expires)
)

val customDomains = domains.filter { !it.wpcomDomain }
Expand All @@ -116,7 +134,7 @@ class DomainsDashboardViewModel @Inject constructor(
val hasPaidPlan = !SiteUtils.onFreePlan(site)

if (hasCustomDomains) {
listItems += buildCustomDomainItems(site, customDomains)
listItems += buildCustomDomainItems(site, customDomains, allDomains)
}

listItems += buildCtaItems(hasCustomDomains, hasDomainCredit, hasPaidPlan)
Expand All @@ -125,6 +143,13 @@ class DomainsDashboardViewModel @Inject constructor(
_uiModel.postValue(listItems)
}

private fun getStatusColor(statusType: StatusType?) = when (statusType) {
StatusType.SUCCESS -> R.color.jetpack_green_50
StatusType.NEUTRAL -> R.color.gray_50
StatusType.WARNING -> R.color.orange_50
else -> R.color.red_50
}

private fun buildCtaItems(
hasCustomDomains: Boolean,
hasDomainCredit: Boolean,
Expand Down Expand Up @@ -161,7 +186,11 @@ class DomainsDashboardViewModel @Inject constructor(
return listItems
}

private fun buildCustomDomainItems(site: SiteModel, customDomains: List<Domain>): List<DomainsDashboardItem> {
private fun buildCustomDomainItems(
site: SiteModel,
customDomains: List<Domain>,
allDomains: List<AllDomainsDomain>
): List<DomainsDashboardItem> {
val listItems = mutableListOf<DomainsDashboardItem>()
listItems += SiteDomainsHeader(
UiStringResWithParams(
Expand All @@ -170,9 +199,18 @@ class DomainsDashboardViewModel @Inject constructor(
)
)
listItems += customDomains.map {
val allDomainsDomain = allDomains.find { allDomainsItem -> it.domain == allDomainsItem.domain }

SiteDomains(
UiStringText(it.domain.orEmpty()),
if (it.expirySoon) {
it.primaryDomain,
allDomainsDomain?.domainStatus?.status?.let { status ->
UiStringText(status)
} ?: UiStringRes(R.string.error),
getStatusColor(allDomainsDomain?.domainStatus?.statusType),
if (!it.hasRegistration) {
null
} else if (it.expirySoon) {
UiStringText(
htmlMessageUtils.getHtmlMessageFromStringFormatResId(
R.string.domains_site_domain_expires_soon,
Expand All @@ -185,14 +223,23 @@ class DomainsDashboardViewModel @Inject constructor(
listOf(UiStringText(it.expiry.orEmpty()))
)
},
it.primaryDomain
allDomainsDomain?.let { ListItemInteraction.create(allDomainsDomain, this::onDomainClick) }
)
}
return listItems
}

private fun getCleanUrl(url: String?) = StringUtils.removeTrailingSlash(UrlUtils.removeScheme(url))

private fun onDomainClick(allDomainsDomain: AllDomainsDomain) {
_onNavigation.value = Event(
OpenDomainManagement(
allDomainsDomain.domain ?: return,
allDomainsDomain.getDomainDetailsUrl() ?: return
)
)
}

private fun onGetDomainClick() {
analyticsTrackerWrapper.track(DOMAINS_DASHBOARD_GET_DOMAIN_TAPPED, site)
_onNavigation.value = Event(GetDomain(site))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.wordpress.android.ui.domains.usecases

import org.wordpress.android.fluxc.network.rest.wpcom.site.AllDomainsDomain
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.util.AppLog
import javax.inject.Inject

class FetchAllDomainsUseCase @Inject constructor(
Expand All @@ -10,7 +11,11 @@ class FetchAllDomainsUseCase @Inject constructor(
suspend fun execute(): AllDomains {
val result = siteStore.fetchAllDomains()
return when {
result.isError -> AllDomains.Error
result.isError -> {
AppLog.e(AppLog.T.API, "An error occurred while fetching all domains: ${result.error.message}")
AllDomains.Error
}

result.domains.isNullOrEmpty() -> AllDomains.Empty
else -> AllDomains.Success(requireNotNull(result.domains))
}
Expand All @@ -22,7 +27,7 @@ sealed interface AllDomains {
val domains: List<AllDomainsDomain>,
) : AllDomains

object Empty : AllDomains
data object Empty : AllDomains

object Error : AllDomains
data object Error : AllDomains
}
9 changes: 9 additions & 0 deletions WordPress/src/main/res/drawable/ic_dot_white_8dp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">

<size
android:width="8dp"
android:height="8dp" />
<solid android:color="@color/white" />
</shape>
33 changes: 20 additions & 13 deletions WordPress/src/main/res/layout/domain_site_domains_card.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,15 @@
android:layout_height="wrap_content"
android:padding="@dimen/margin_extra_large">

<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/primary_site_domain_actions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_ellipsis_vertical_white_24dp"
app:tint="?attr/wpColorOnSurfaceMedium" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/site_domain_expiry_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_medium_large"
android:text="@string/domains_site_domain_never_expires"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toEndOf="@id/site_domain_status"
app:layout_constraintTop_toBottomOf="@id/primary_site_domain_chip" />

<com.google.android.material.chip.Chip
Expand All @@ -55,14 +47,29 @@
app:layout_constraintTop_toBottomOf="@+id/site_domain"
app:textStartPadding="@dimen/margin_small" />

<com.google.android.material.textview.MaterialTextView
style="?attr/textAppearanceBody2"
android:id="@+id/site_domain_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_medium_large"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_dot_white_8dp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/primary_site_domain_chip"
tools:text="Active" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/site_domain"
style="?attr/textAppearanceSubtitle1"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/domains_site_domain"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="travelwithkids.wordpress.com" />

</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.wordpress.android.BaseUnitTest
import org.wordpress.android.R
import org.wordpress.android.fluxc.model.PlanModel
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpcom.site.AllDomainsDomain
import org.wordpress.android.fluxc.network.rest.wpcom.site.Domain
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.fluxc.store.SiteStore.FetchedDomainsPayload
Expand All @@ -19,6 +20,8 @@ import org.wordpress.android.ui.domains.DomainsDashboardItem.PurchaseDomain
import org.wordpress.android.ui.domains.DomainsDashboardItem.PurchasePlan
import org.wordpress.android.ui.domains.DomainsDashboardItem.SiteDomains
import org.wordpress.android.ui.domains.DomainsDashboardItem.SiteDomainsHeader
import org.wordpress.android.ui.domains.usecases.AllDomains
import org.wordpress.android.ui.domains.usecases.FetchAllDomainsUseCase
import org.wordpress.android.ui.domains.usecases.FetchPlansUseCase
import org.wordpress.android.ui.plans.PlansConstants.FREE_PLAN_ID
import org.wordpress.android.ui.plans.PlansConstants.PREMIUM_PLAN_ID
Expand All @@ -32,6 +35,7 @@ class DomainsDashboardViewModelTest : BaseUnitTest() {
private val analyticsTracker: AnalyticsTrackerWrapper = mock()
private val htmlMessageUtils: HtmlMessageUtils = mock()
private val fetchPlansUseCase: FetchPlansUseCase = mock()
private val fetchAllDomainsUseCase: FetchAllDomainsUseCase = mock()

private lateinit var viewModel: DomainsDashboardViewModel

Expand All @@ -44,6 +48,7 @@ class DomainsDashboardViewModelTest : BaseUnitTest() {
analyticsTracker,
htmlMessageUtils,
fetchPlansUseCase,
fetchAllDomainsUseCase,
testDispatcher()
)

Expand Down Expand Up @@ -171,6 +176,8 @@ class DomainsDashboardViewModelTest : BaseUnitTest() {

val plan = if (hasDomainCredits) planWithCredits else planWithNoCredits
whenever(fetchPlansUseCase.execute(site)).thenReturn(OnPlansFetched(site, listOf(plan)))
val allDomains = if (hasCustomDomains) listOf(allDomainsDomain) else emptyList()
whenever(fetchAllDomainsUseCase.execute()).thenReturn(AllDomains.Success(allDomains))

viewModel.start(site)
}
Expand All @@ -189,6 +196,8 @@ class DomainsDashboardViewModelTest : BaseUnitTest() {
wpcomDomain = false
)

private val allDomainsDomain = AllDomainsDomain(domain = "henna.tattoo")

private val siteWithFreePlan = SiteModel().apply {
siteId = TEST_SITE_ID
url = TEST_DOMAIN_NAME
Expand Down

0 comments on commit 54d9f46

Please sign in to comment.