Skip to content

Commit 8dea753

Browse files
authored
Merge pull request #15620 from wordpress-mobile/issue/15215-mysite-sources-to-manager
My Site Dashboard: Phase 2: MySiteSourceManager implementation
2 parents 2895dae + 364fca1 commit 8dea753

File tree

5 files changed

+446
-297
lines changed

5 files changed

+446
-297
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package org.wordpress.android.ui.mysite
2+
3+
import androidx.lifecycle.LiveData
4+
import androidx.lifecycle.distinctUntilChanged
5+
import kotlinx.coroutines.CoroutineScope
6+
import org.wordpress.android.analytics.AnalyticsTracker.Stat
7+
import org.wordpress.android.ui.mysite.MySiteSource.MySiteRefreshSource
8+
import org.wordpress.android.ui.mysite.MySiteSource.SiteIndependentSource
9+
import org.wordpress.android.ui.mysite.MySiteUiState.PartialState
10+
import org.wordpress.android.ui.mysite.cards.domainregistration.DomainRegistrationSource
11+
import org.wordpress.android.ui.mysite.cards.post.PostCardsSource
12+
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardSource
13+
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction
14+
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction.Hide
15+
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction.Pin
16+
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction.Unpin
17+
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardsSource
18+
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
19+
import org.wordpress.android.util.config.MySiteDashboardPhase2FeatureConfig
20+
import javax.inject.Inject
21+
22+
class MySiteSourceManager @Inject constructor(
23+
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper,
24+
private val currentAvatarSource: CurrentAvatarSource,
25+
private val domainRegistrationSource: DomainRegistrationSource,
26+
private val dynamicCardsSource: DynamicCardsSource,
27+
private val quickStartCardSource: QuickStartCardSource,
28+
private val scanAndBackupSource: ScanAndBackupSource,
29+
private val selectedSiteSource: SelectedSiteSource,
30+
postCardsSource: PostCardsSource,
31+
siteIconProgressSource: SiteIconProgressSource,
32+
private val mySiteDashboardPhase2FeatureConfig: MySiteDashboardPhase2FeatureConfig
33+
) {
34+
private val mySiteSources: List<MySiteSource<*>> = listOf(
35+
selectedSiteSource,
36+
siteIconProgressSource,
37+
quickStartCardSource,
38+
currentAvatarSource,
39+
domainRegistrationSource,
40+
scanAndBackupSource,
41+
dynamicCardsSource,
42+
postCardsSource
43+
)
44+
45+
fun build(coroutineScope: CoroutineScope, siteLocalId: Int?): List<LiveData<out PartialState>> {
46+
return if (siteLocalId != null) {
47+
mySiteSources.map { source -> source.build(coroutineScope, siteLocalId).distinctUntilChanged() }
48+
} else {
49+
mySiteSources.filterIsInstance(SiteIndependentSource::class.java)
50+
.map { source -> source.build(coroutineScope).distinctUntilChanged() }
51+
}
52+
}
53+
54+
fun isRefreshing(): Boolean {
55+
if (mySiteDashboardPhase2FeatureConfig.isEnabled()) {
56+
mySiteSources.filterIsInstance(MySiteRefreshSource::class.java).forEach {
57+
if (it.isRefreshing() == true) {
58+
return true
59+
}
60+
}
61+
}
62+
return false
63+
}
64+
65+
fun refresh() {
66+
if (mySiteDashboardPhase2FeatureConfig.isEnabled()) {
67+
refreshAllSources()
68+
} else {
69+
refreshSubsetOfAllSources()
70+
}
71+
}
72+
73+
fun onResume(isFirstResume: Boolean) {
74+
when (isFirstResume) {
75+
true -> refreshSubsetOfAllSources()
76+
false -> refresh()
77+
}
78+
}
79+
80+
fun clear() {
81+
domainRegistrationSource.clear()
82+
scanAndBackupSource.clear()
83+
selectedSiteSource.clear()
84+
}
85+
86+
private fun refreshAllSources() {
87+
mySiteSources.filterIsInstance(MySiteRefreshSource::class.java).forEach { it.refresh() }
88+
}
89+
90+
private fun refreshSubsetOfAllSources() {
91+
selectedSiteSource.updateSiteSettingsIfNecessary()
92+
currentAvatarSource.refresh()
93+
quickStartCardSource.refresh()
94+
}
95+
96+
/* QUICK START */
97+
98+
fun refreshQuickStart() {
99+
quickStartCardSource.refresh()
100+
}
101+
102+
suspend fun onQuickStartMenuInteraction(interaction: DynamicCardMenuInteraction) {
103+
when (interaction) {
104+
is DynamicCardMenuInteraction.Remove -> {
105+
analyticsTrackerWrapper.track(Stat.QUICK_START_REMOVE_CARD_TAPPED)
106+
dynamicCardsSource.removeItem(interaction.cardType)
107+
quickStartCardSource.refresh()
108+
}
109+
is Pin -> dynamicCardsSource.pinItem(interaction.cardType)
110+
is Unpin -> dynamicCardsSource.unpinItem()
111+
is Hide -> {
112+
analyticsTrackerWrapper.track(Stat.QUICK_START_HIDE_CARD_TAPPED)
113+
dynamicCardsSource.hideItem(interaction.cardType)
114+
quickStartCardSource.refresh()
115+
}
116+
}
117+
}
118+
}

WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt

Lines changed: 10 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,21 @@ import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.QuickActio
2828
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.QuickStartCardBuilderParams
2929
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.SiteInfoCardBuilderParams
3030
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.SiteItemsBuilderParams
31-
import org.wordpress.android.ui.mysite.MySiteSource.MySiteRefreshSource
32-
import org.wordpress.android.ui.mysite.MySiteSource.SiteIndependentSource
3331
import org.wordpress.android.ui.mysite.MySiteUiState.PartialState
3432
import org.wordpress.android.ui.mysite.MySiteViewModel.State.NoSites
3533
import org.wordpress.android.ui.mysite.MySiteViewModel.State.SiteSelected
3634
import org.wordpress.android.ui.mysite.SiteDialogModel.AddSiteIconDialogModel
3735
import org.wordpress.android.ui.mysite.SiteDialogModel.ChangeSiteIconDialogModel
3836
import org.wordpress.android.ui.mysite.SiteDialogModel.ShowRemoveNextStepsDialog
3937
import org.wordpress.android.ui.mysite.cards.CardsBuilder
40-
import org.wordpress.android.ui.mysite.cards.domainregistration.DomainRegistrationSource
4138
import org.wordpress.android.ui.mysite.cards.post.PostCardType
42-
import org.wordpress.android.ui.mysite.cards.post.PostCardsSource
4339
import org.wordpress.android.ui.mysite.cards.post.mockdata.MockedPostsData
4440
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardBuilder
45-
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardSource
4641
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository
4742
import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository.QuickStartCategory
4843
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuFragment.DynamicCardMenuModel
4944
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction
50-
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction.Hide
51-
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction.Pin
52-
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardMenuViewModel.DynamicCardMenuInteraction.Unpin
5345
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardsBuilder
54-
import org.wordpress.android.ui.mysite.dynamiccards.DynamicCardsSource
5546
import org.wordpress.android.ui.mysite.items.SiteItemsBuilder
5647
import org.wordpress.android.ui.mysite.items.listitem.ListItemAction
5748
import org.wordpress.android.ui.pages.SnackbarMessageHolder
@@ -101,24 +92,17 @@ class MySiteViewModel @Inject constructor(
10192
private val contextProvider: ContextProvider,
10293
private val siteIconUploadHandler: SiteIconUploadHandler,
10394
private val siteStoriesHandler: SiteStoriesHandler,
104-
private val domainRegistrationSource: DomainRegistrationSource,
105-
private val scanAndBackupSource: ScanAndBackupSource,
10695
private val displayUtilsWrapper: DisplayUtilsWrapper,
10796
private val quickStartRepository: QuickStartRepository,
108-
private val quickStartCardSource: QuickStartCardSource,
10997
private val quickStartCardBuilder: QuickStartCardBuilder,
110-
private val currentAvatarSource: CurrentAvatarSource,
111-
private val dynamicCardsSource: DynamicCardsSource,
11298
private val unifiedCommentsListFeatureConfig: UnifiedCommentsListFeatureConfig,
11399
private val quickStartDynamicCardsFeatureConfig: QuickStartDynamicCardsFeatureConfig,
114100
private val quickStartUtilsWrapper: QuickStartUtilsWrapper,
115101
private val snackbarSequencer: SnackbarSequencer,
116102
private val cardsBuilder: CardsBuilder,
117103
private val dynamicCardsBuilder: DynamicCardsBuilder,
118-
postCardsSource: PostCardsSource,
119-
private val selectedSiteSource: SelectedSiteSource,
120-
siteIconProgressSource: SiteIconProgressSource,
121-
private val mySiteDashboardPhase2FeatureConfig: MySiteDashboardPhase2FeatureConfig
104+
private val mySiteDashboardPhase2FeatureConfig: MySiteDashboardPhase2FeatureConfig,
105+
private val mySiteSourceManager: MySiteSourceManager
122106
) : ScopedViewModel(mainDispatcher) {
123107
private val _onSnackbarMessage = MutableLiveData<Event<SnackbarMessageHolder>>()
124108
private val _onTechInputDialogShown = MutableLiveData<Event<TextInputDialogModel>>()
@@ -149,27 +133,10 @@ class MySiteViewModel @Inject constructor(
149133
val onUploadedItem = siteIconUploadHandler.onUploadedItem
150134
val onShowSwipeRefreshLayout = _onShowSwipeRefreshLayout
151135

152-
private val mySiteSources: List<MySiteSource<*>> = listOf(
153-
selectedSiteSource,
154-
siteIconProgressSource,
155-
quickStartCardSource,
156-
currentAvatarSource,
157-
domainRegistrationSource,
158-
scanAndBackupSource,
159-
dynamicCardsSource,
160-
postCardsSource
161-
)
162-
163136
val state: LiveData<MySiteUiState> =
164137
selectedSiteRepository.siteSelected.switchMap { siteLocalId ->
165138
val result = MediatorLiveData<SiteIdToState>()
166-
val currentSources = if (siteLocalId != null) {
167-
mySiteSources.map { source -> source.build(viewModelScope, siteLocalId).distinctUntilChanged() }
168-
} else {
169-
mySiteSources.filterIsInstance(SiteIndependentSource::class.java)
170-
.map { source -> source.build(viewModelScope).distinctUntilChanged() }
171-
}
172-
for (newSource in currentSources) {
139+
for (newSource in mySiteSourceManager.build(viewModelScope, siteLocalId)) {
173140
result.addSource(newSource) { partialState ->
174141
if (partialState != null) {
175142
result.value = (result.value ?: SiteIdToState(siteLocalId)).update(partialState)
@@ -390,7 +357,7 @@ class MySiteViewModel @Inject constructor(
390357
}
391358

392359
fun onQuickStartFullScreenDialogDismiss() {
393-
quickStartCardSource.refresh()
360+
mySiteSourceManager.refreshQuickStart()
394361
}
395362

396363
private fun titleClick() {
@@ -484,33 +451,10 @@ class MySiteViewModel @Inject constructor(
484451
_onNavigation.value = Event(SiteNavigationAction.OpenDomainRegistration(selectedSite))
485452
}
486453

487-
fun refresh() {
488-
if (mySiteDashboardPhase2FeatureConfig.isEnabled()) {
489-
refreshNew()
490-
} else {
491-
refreshOld()
492-
}
493-
}
494-
495-
private fun refreshNew() {
496-
mySiteSources.filterIsInstance(MySiteRefreshSource::class.java).forEach { it.refresh() }
497-
}
498-
499-
private fun refreshOld() {
500-
selectedSiteRepository.updateSiteSettingsIfNecessary()
501-
quickStartCardSource.refresh()
502-
currentAvatarSource.refresh()
503-
}
454+
fun refresh() = mySiteSourceManager.refresh()
504455

505456
fun onResume(isFirstResume: Boolean) {
506-
when (isFirstResume) {
507-
true -> refreshOld()
508-
false -> if (mySiteDashboardPhase2FeatureConfig.isEnabled()) {
509-
refreshNew()
510-
} else {
511-
refreshOld()
512-
}
513-
}
457+
mySiteSourceManager.onResume(isFirstResume)
514458
checkAndShowQuickStartNotice()
515459
_onShowSwipeRefreshLayout.postValue(Event(mySiteDashboardPhase2FeatureConfig.isEnabled()))
516460
}
@@ -695,10 +639,8 @@ class MySiteViewModel @Inject constructor(
695639
override fun onCleared() {
696640
siteIconUploadHandler.clear()
697641
siteStoriesHandler.clear()
698-
domainRegistrationSource.clear()
699642
quickStartRepository.clear()
700-
scanAndBackupSource.clear()
701-
selectedSiteSource.clear()
643+
mySiteSourceManager.clear()
702644
super.onCleared()
703645
}
704646

@@ -719,27 +661,12 @@ class MySiteViewModel @Inject constructor(
719661
private fun startQuickStart(siteLocalId: Int) {
720662
if (siteLocalId != SelectedSiteRepository.UNAVAILABLE) {
721663
quickStartUtilsWrapper.startQuickStart(siteLocalId)
722-
quickStartCardSource.refresh()
664+
mySiteSourceManager.refreshQuickStart()
723665
}
724666
}
725667

726668
fun onQuickStartMenuInteraction(interaction: DynamicCardMenuInteraction) {
727-
launch {
728-
when (interaction) {
729-
is DynamicCardMenuInteraction.Remove -> {
730-
analyticsTrackerWrapper.track(Stat.QUICK_START_REMOVE_CARD_TAPPED)
731-
dynamicCardsSource.removeItem(interaction.cardType)
732-
quickStartCardSource.refresh()
733-
}
734-
is Pin -> dynamicCardsSource.pinItem(interaction.cardType)
735-
is Unpin -> dynamicCardsSource.unpinItem()
736-
is Hide -> {
737-
analyticsTrackerWrapper.track(Stat.QUICK_START_HIDE_CARD_TAPPED)
738-
dynamicCardsSource.hideItem(interaction.cardType)
739-
quickStartCardSource.refresh()
740-
}
741-
}
742-
}
669+
launch { mySiteSourceManager.onQuickStartMenuInteraction(interaction) }
743670
}
744671

745672
private fun showQuickStartDialog(siteModel: SiteModel?) {
@@ -783,18 +710,7 @@ class MySiteViewModel @Inject constructor(
783710
}
784711
}
785712

786-
fun isRefreshing() = areSourcesRefreshing()
787-
788-
private fun areSourcesRefreshing(): Boolean {
789-
if (mySiteDashboardPhase2FeatureConfig.isEnabled()) {
790-
mySiteSources.filterIsInstance(MySiteRefreshSource::class.java).forEach {
791-
if (it.isRefreshing() == true) {
792-
return true
793-
}
794-
}
795-
}
796-
return false
797-
}
713+
fun isRefreshing() = mySiteSourceManager.isRefreshing()
798714

799715
fun setActionableEmptyViewGone(isVisible: Boolean, setGone: () -> Unit) {
800716
if (isVisible) analyticsTrackerWrapper.track(Stat.MY_SITE_NO_SITES_VIEW_HIDDEN)

WordPress/src/main/java/org/wordpress/android/ui/mysite/SelectedSiteSource.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ class SelectedSiteSource @Inject constructor(
2727
.map { SelectedSite(it) }
2828

2929
override fun refresh() {
30-
selectedSiteRepository.updateSiteSettingsIfNecessary()
30+
updateSiteSettingsIfNecessary()
3131
selectedSiteRepository.getSelectedSite()?.let {
3232
super.refresh()
3333
dispatcher.dispatch(SiteActionBuilder.newFetchSiteAction(it))
3434
}
3535
}
3636

37+
fun updateSiteSettingsIfNecessary() = selectedSiteRepository.updateSiteSettingsIfNecessary()
38+
3739
init {
3840
dispatcher.register(this)
3941
}

0 commit comments

Comments
 (0)