Skip to content

Commit

Permalink
Merge pull request #19279 from wordpress-mobile/issue/19270-quick-lin…
Browse files Browse the repository at this point in the history
…k-ribbon-builder

Implements: the quick link item logic in Unified Menu
  • Loading branch information
zwarm authored Sep 28, 2023
2 parents eabf4a6 + 0c9f8c6 commit 15a45f2
Show file tree
Hide file tree
Showing 15 changed files with 581 additions and 850 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,13 @@ sealed class MySiteCardAndItem(open val type: Type, open val activeQuickStartIte
) : MySiteCardAndItem(type, activeQuickStartItem) {
data class QuickLinkRibbon(
val quickLinkRibbonItems: List<QuickLinkRibbonItem>,
val showPagesFocusPoint: Boolean = false,
val showStatsFocusPoint: Boolean = false,
val showMediaFocusPoint: Boolean = false
val showMoreFocusPoint : Boolean = false
) : Card(
QUICK_LINK_RIBBON,
activeQuickStartItem = showPagesFocusPoint || showStatsFocusPoint || showMediaFocusPoint
activeQuickStartItem = showMoreFocusPoint
) {
data class QuickLinkRibbonItem(
@StringRes val label: Int,
val label: UiString.UiStringRes,
@DrawableRes val icon: Int,
val onClick: ListItemInteraction,
val showFocusPoint: Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map
import androidx.lifecycle.switchMap
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineDispatcher
Expand All @@ -28,8 +27,6 @@ import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel
import org.wordpress.android.fluxc.model.dashboard.CardModel.TodaysStatsCardModel
import org.wordpress.android.fluxc.store.AccountStore
import org.wordpress.android.fluxc.store.PostStore.OnPostUploaded
import org.wordpress.android.fluxc.store.QuickStartStore.Companion.QUICK_START_CHECK_STATS_LABEL
import org.wordpress.android.fluxc.store.QuickStartStore.Companion.QUICK_START_UPLOAD_MEDIA_LABEL
import org.wordpress.android.fluxc.store.QuickStartStore.Companion.QUICK_START_VIEW_SITE_LABEL
import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask
import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTask
Expand All @@ -56,7 +53,6 @@ import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.DashboardC
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.DomainRegistrationCardBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.InfoItemBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.JetpackInstallFullPluginCardBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.QuickLinkRibbonBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.QuickStartCardBuilderParams
import org.wordpress.android.ui.mysite.MySiteUiState.PartialState
import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.BlazeCardUpdate
Expand All @@ -81,6 +77,7 @@ import org.wordpress.android.ui.mysite.cards.jpfullplugininstall.JetpackInstallF
import org.wordpress.android.ui.mysite.cards.nocards.NoCardsMessageViewModelSlice
import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardBuilder
import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardViewModelSlice
import org.wordpress.android.ui.mysite.cards.quicklinksribbon.QuickLinksItemViewModelSlice
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardBuilder
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardType
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository
Expand Down Expand Up @@ -172,7 +169,8 @@ class MySiteViewModel @Inject constructor(
private val personalizeCardBuilder: PersonalizeCardBuilder,
private val bloggingPromptCardViewModelSlice: BloggingPromptCardViewModelSlice,
private val noCardsMessageViewModelSlice: NoCardsMessageViewModelSlice,
private val siteInfoHeaderCardViewModelSlice: SiteInfoHeaderCardViewModelSlice
private val siteInfoHeaderCardViewModelSlice: SiteInfoHeaderCardViewModelSlice,
private val quickLinksItemViewModelSlice: QuickLinksItemViewModelSlice
) : ScopedViewModel(mainDispatcher) {
private val _onSnackbarMessage = MutableLiveData<Event<SnackbarMessageHolder>>()
private val _onNavigation = MutableLiveData<Event<SiteNavigationAction>>()
Expand Down Expand Up @@ -208,7 +206,8 @@ class MySiteViewModel @Inject constructor(
quickStartRepository.onSnackbar,
siteItemsViewModelSlice.onSnackbarMessage,
bloggingPromptCardViewModelSlice.onSnackbarMessage,
siteInfoHeaderCardViewModelSlice.onSnackbarMessage
siteInfoHeaderCardViewModelSlice.onSnackbarMessage,
quickLinksItemViewModelSlice.onSnackbarMessage
)
val onQuickStartMySitePrompts = quickStartRepository.onQuickStartMySitePrompts

Expand All @@ -228,7 +227,8 @@ class MySiteViewModel @Inject constructor(
siteItemsViewModelSlice.onNavigation,
bloggingPromptCardViewModelSlice.onNavigation,
personalizeCardViewModelSlice.onNavigation,
siteInfoHeaderCardViewModelSlice.onNavigation
siteInfoHeaderCardViewModelSlice.onNavigation,
quickLinksItemViewModelSlice.navigation
)

val onMediaUpload = siteInfoHeaderCardViewModelSlice.onMediaUpload
Expand Down Expand Up @@ -265,41 +265,43 @@ class MySiteViewModel @Inject constructor(
result.filter { it.siteId == null || it.state.site != null }.mapSafe { it.state }
}

val uiModel: LiveData<UiModel> = state.map {
with(it) {
val state = if (site != null) {
cardsUpdate?.checkAndShowSnackbarError()
val state = buildSiteSelectedStateAndScroll(
site,
showSiteIconProgressBar,
activeTask,
isDomainCreditAvailable,
quickStartCategories,
backupAvailable,
scanAvailable,
cardsUpdate,
bloggingPromptsUpdate,
blazeCardUpdate
)
trackCardsAndItemsShownIfNeeded(state)

bloggingPromptCardViewModelSlice.onDashboardCardsUpdated(
viewModelScope,
state.dashboardCardsAndItems.filterIsInstance<MySiteCardAndItem.Card.BloggingPromptCard>()
)
val uiModel: LiveData<UiModel> = merge(state, quickLinksItemViewModelSlice.uiState) { cards, quickLinks ->
cards?.let { nonNullCards ->
with(nonNullCards) {
val state = if (site != null) {
cardsUpdate?.checkAndShowSnackbarError()
val state = buildSiteSelectedStateAndScroll(
site,
showSiteIconProgressBar,
activeTask,
isDomainCreditAvailable,
quickStartCategories,
backupAvailable,
scanAvailable,
cardsUpdate,
bloggingPromptsUpdate,
blazeCardUpdate,
quickLinks
)
trackCardsAndItemsShownIfNeeded(state)

state
} else {
buildNoSiteState()
}
bloggingPromptCardViewModelSlice.onDashboardCardsUpdated(
viewModelScope,
state.dashboardCardsAndItems.filterIsInstance<MySiteCardAndItem.Card.BloggingPromptCard>()
)
state
} else {
buildNoSiteState()
}

bloggingPromptCardViewModelSlice.onSiteChanged(site?.id)
bloggingPromptCardViewModelSlice.onSiteChanged(site?.id)

dashboardCardPlansUtils.onSiteChanged(site?.id, state as? SiteSelected)
dashboardCardPlansUtils.onSiteChanged(site?.id, state as? SiteSelected)

domainTransferCardViewModel.onSiteChanged(site?.id, state as? SiteSelected)
domainTransferCardViewModel.onSiteChanged(site?.id, state as? SiteSelected)

UiModel(currentAvatarUrl.orEmpty(), state)
UiModel(currentAvatarUrl.orEmpty(), state)
}
}
}

Expand All @@ -314,6 +316,8 @@ class MySiteViewModel @Inject constructor(
dispatcher.register(this)
bloggingPromptCardViewModelSlice.initialize(viewModelScope, mySiteSourceManager)
siteInfoHeaderCardViewModelSlice.initialize(viewModelScope)
quickLinksItemViewModelSlice.initialization(viewModelScope)
quickLinksItemViewModelSlice.start()
}

@Suppress("LongParameterList")
Expand All @@ -327,7 +331,8 @@ class MySiteViewModel @Inject constructor(
scanAvailable: Boolean,
cardsUpdate: CardsUpdate?,
bloggingPromptUpdate: BloggingPromptUpdate?,
blazeCardUpdate: BlazeCardUpdate?
blazeCardUpdate: BlazeCardUpdate?,
quickLinks: MySiteCardAndItem.Card.QuickLinkRibbon? = null
): SiteSelected {
val siteItems = buildSiteSelectedState(
site,
Expand All @@ -338,7 +343,8 @@ class MySiteViewModel @Inject constructor(
scanAvailable,
cardsUpdate,
bloggingPromptUpdate,
blazeCardUpdate
blazeCardUpdate,
quickLinks
)

val siteInfo = siteInfoHeaderCardBuilder.buildSiteInfoCard(
Expand Down Expand Up @@ -378,7 +384,7 @@ class MySiteViewModel @Inject constructor(
else -> false
}

@Suppress("LongParameterList","CyclomaticComplexMethod")
@Suppress("LongParameterList", "CyclomaticComplexMethod")
private fun buildSiteSelectedState(
site: SiteModel,
activeTask: QuickStartTask?,
Expand All @@ -388,7 +394,8 @@ class MySiteViewModel @Inject constructor(
scanAvailable: Boolean,
cardsUpdate: CardsUpdate?,
bloggingPromptUpdate: BloggingPromptUpdate?,
blazeCardUpdate: BlazeCardUpdate?
blazeCardUpdate: BlazeCardUpdate?,
quickLinks: MySiteCardAndItem.Card.QuickLinkRibbon?
): Map<MySiteTabType, List<MySiteCardAndItem>> {
val infoItem = mySiteInfoItemBuilder.build(
InfoItemBuilderParams(
Expand Down Expand Up @@ -452,17 +459,7 @@ class MySiteViewModel @Inject constructor(
cardsUpdate?.cards?.firstOrNull { it is ActivityCardModel } as? ActivityCardModel
),
),
QuickLinkRibbonBuilderParams(
siteModel = site,
onPagesClick = this::onQuickLinkRibbonPagesClick,
onPostsClick = this::onQuickLinkRibbonPostsClick,
onMediaClick = this::onQuickLinkRibbonMediaClick,
onStatsClick = this::onQuickLinkRibbonStatsClick,
onMoreClick = this::onQuickLinkRibbonMoreClick,
activeTask = activeTask
),
jetpackInstallFullPluginCardParams,
isMySiteTabsEnabled
jetpackInstallFullPluginCardParams
)

val siteItems = siteItemsBuilder.build(
Expand Down Expand Up @@ -495,6 +492,7 @@ class MySiteViewModel @Inject constructor(
infoItem?.let { add(infoItem) }
migrationSuccessCard?.let { add(migrationSuccessCard) }
jetpackInstallFullPluginCard?.let { add(jetpackInstallFullPluginCard) }
quickLinks?.let { add(quickLinks) }
addAll(cardsResult)
noCardsMessage?.let { add(noCardsMessage) }
personalizeCard?.let { add(personalizeCard) }
Expand Down Expand Up @@ -639,43 +637,6 @@ class MySiteViewModel @Inject constructor(
mySiteSourceManager.refreshQuickStart()
}

private fun onQuickLinkRibbonStatsClick() {
val selectedSite = requireNotNull(selectedSiteRepository.getSelectedSite())
analyticsTrackerWrapper.track(Stat.QUICK_LINK_RIBBON_STATS_TAPPED)
quickStartRepository.completeTask(
quickStartRepository.quickStartType.getTaskFromString(QUICK_START_CHECK_STATS_LABEL)
)
_onNavigation.value = Event(getStatsNavigationActionForSite(selectedSite))
}

private fun onQuickLinkRibbonPagesClick() {
val selectedSite = requireNotNull(selectedSiteRepository.getSelectedSite())
analyticsTrackerWrapper.track(Stat.QUICK_LINK_RIBBON_PAGES_TAPPED)
quickStartRepository.completeTask(QuickStartNewSiteTask.REVIEW_PAGES)
_onNavigation.value = Event(SiteNavigationAction.OpenPages(selectedSite))
}

private fun onQuickLinkRibbonPostsClick() {
val selectedSite = requireNotNull(selectedSiteRepository.getSelectedSite())
analyticsTrackerWrapper.track(Stat.QUICK_LINK_RIBBON_POSTS_TAPPED)
_onNavigation.value = Event(SiteNavigationAction.OpenPosts(selectedSite))
}

private fun onQuickLinkRibbonMediaClick() {
val selectedSite = requireNotNull(selectedSiteRepository.getSelectedSite())
analyticsTrackerWrapper.track(Stat.QUICK_LINK_RIBBON_MEDIA_TAPPED)
quickStartRepository.requestNextStepOfTask(
quickStartRepository.quickStartType.getTaskFromString(QUICK_START_UPLOAD_MEDIA_LABEL)
)
_onNavigation.value = Event(SiteNavigationAction.OpenMedia(selectedSite))
}

private fun onQuickLinkRibbonMoreClick() {
val selectedSite = requireNotNull(selectedSiteRepository.getSelectedSite())
analyticsTrackerWrapper.track(Stat.QUICK_LINK_RIBBON_MORE_TAPPED)
_onNavigation.value = Event(SiteNavigationAction.OpenMore(selectedSite))
}

private fun domainRegistrationClick() {
val selectedSite = requireNotNull(selectedSiteRepository.getSelectedSite())
analyticsTrackerWrapper.track(Stat.DOMAIN_CREDIT_REDEMPTION_TAPPED, selectedSite)
Expand All @@ -685,6 +646,7 @@ class MySiteViewModel @Inject constructor(
fun refresh(isPullToRefresh: Boolean = false) {
if (isPullToRefresh) analyticsTrackerWrapper.track(Stat.MY_SITE_PULL_TO_REFRESH)
mySiteSourceManager.refresh()
quickLinksItemViewModelSlice.onRefresh()
}

fun onResume(currentTab: MySiteTabType) {
Expand All @@ -694,6 +656,7 @@ class MySiteViewModel @Inject constructor(
checkAndShowQuickStartNotice()
bloggingPromptCardViewModelSlice.onResume(currentTab)
dashboardCardPlansUtils.onResume(currentTab, uiModel.value?.state as? SiteSelected)
quickLinksItemViewModelSlice.onResume()
}

private fun checkAndShowJetpackFullPluginInstallOnboarding() {
Expand Down Expand Up @@ -751,21 +714,6 @@ class MySiteViewModel @Inject constructor(
_onSnackbarMessage.postValue(Event(SnackbarMessageHolder(getEmailValidationMessage(email))))
}

private fun getStatsNavigationActionForSite(site: SiteModel): SiteNavigationAction = when {
// if we are in static posters phase - we don't want to show any connection/login messages
jetpackFeatureRemovalPhaseHelper.shouldShowStaticPage() ->
SiteNavigationAction.ShowJetpackRemovalStaticPostersView

// If the user is not logged in and the site is already connected to Jetpack, ask to login.
!accountStore.hasAccessToken() && site.isJetpackConnected -> SiteNavigationAction.StartWPComLoginForJetpackStats

// If it's a WordPress.com or Jetpack site, show the Stats screen.
site.isWPCom || site.isJetpackInstalled && site.isJetpackConnected -> SiteNavigationAction.OpenStats(site)

// If it's a self-hosted site, ask to connect to Jetpack.
else -> SiteNavigationAction.ConnectJetpackForStats(site)
}

fun onAvatarPressed() {
_onNavigation.value = Event(SiteNavigationAction.OpenMeScreen)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DomainRegistration
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.DashboardCardsBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.DomainRegistrationCardBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.JetpackInstallFullPluginCardBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.QuickLinkRibbonBuilderParams
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.QuickStartCardBuilderParams
import org.wordpress.android.ui.mysite.cards.dashboard.CardsBuilder
import org.wordpress.android.ui.mysite.cards.jpfullplugininstall.JetpackInstallFullPluginCardBuilder
import org.wordpress.android.ui.mysite.cards.quicklinksribbon.QuickLinkRibbonBuilder
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardBuilder
import org.wordpress.android.ui.utils.ListItemInteraction
import javax.inject.Inject

class CardsBuilder @Inject constructor(
private val quickStartCardBuilder: QuickStartCardBuilder,
private val quickLinkRibbonBuilder: QuickLinkRibbonBuilder,
private val dashboardCardsBuilder: CardsBuilder,
private val jetpackInstallFullPluginCardBuilder: JetpackInstallFullPluginCardBuilder,
) {
Expand All @@ -25,14 +22,9 @@ class CardsBuilder @Inject constructor(
domainRegistrationCardBuilderParams: DomainRegistrationCardBuilderParams,
quickStartCardBuilderParams: QuickStartCardBuilderParams,
dashboardCardsBuilderParams: DashboardCardsBuilderParams,
quickLinkRibbonBuilderParams: QuickLinkRibbonBuilderParams,
jetpackInstallFullPluginCardBuilderParams: JetpackInstallFullPluginCardBuilderParams,
isMySiteTabsEnabled: Boolean
): List<MySiteCardAndItem> {
val cards = mutableListOf<MySiteCardAndItem>()
if (isMySiteTabsEnabled) {
cards.add(quickLinkRibbonBuilder.build(quickLinkRibbonBuilderParams))
}
jetpackInstallFullPluginCardBuilder.build(jetpackInstallFullPluginCardBuilderParams)?.let {
cards.add(it)
}
Expand Down
Loading

0 comments on commit 15a45f2

Please sign in to comment.