Skip to content

Commit

Permalink
Merge pull request #20735 from wordpress-mobile/issue/20689-subscribe…
Browse files Browse the repository at this point in the history
…rs-card

Add subscribers list card
  • Loading branch information
aditi-bhatia authored May 2, 2024
2 parents 5837010 + 7329299 commit f51cb45
Show file tree
Hide file tree
Showing 18 changed files with 458 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
import org.wordpress.android.ui.stats.refresh.lists.InsightsDetailListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.InsightsListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.MonthsListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.SubscribersDetailListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.SubscribersListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.TotalCommentsDetailListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.TotalFollowersDetailListViewModel;
Expand Down Expand Up @@ -199,11 +198,6 @@ abstract class ViewModelModule {
@ViewModelKey(InsightsDetailListViewModel.class)
abstract ViewModel insightsDetailListViewModel(InsightsDetailListViewModel viewModel);

@Binds
@IntoMap
@ViewModelKey(SubscribersDetailListViewModel.class)
abstract ViewModel subscribersDetailListViewModel(SubscribersDetailListViewModel viewModel);

@Binds
@IntoMap
@ViewModelKey(DetailListViewModel.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ enum class StatsViewType {
TOTAL_LIKES,
TOTAL_COMMENTS,
TOTAL_FOLLOWERS,
EMAILS,
SUBSCRIBERS,
EMAILS
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ sealed class NavigationTarget {
val selectedDate: Date?
) : NavigationTarget()

data object SubscribersStats : NavigationTarget()
data object EmailsStats : NavigationTarget()

object SetBloggingReminders : NavigationTarget()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.T
import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.TotalLikesUseCase.TotalLikesUseCaseFactory
import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.ViewsAndVisitorsUseCase.ViewsAndVisitorsUseCaseFactory
import org.wordpress.android.ui.stats.refresh.lists.sections.subscribers.usecases.EmailsUseCase.EmailsUseCaseFactory
import org.wordpress.android.ui.stats.refresh.lists.sections.subscribers.usecases.SubscribersUseCase
import org.wordpress.android.ui.stats.refresh.lists.sections.subscribers.usecases.SubscribersChartUseCase
import org.wordpress.android.ui.stats.refresh.lists.sections.subscribers.usecases.SubscribersUseCase.SubscribersUseCaseFactory
import org.wordpress.android.ui.stats.refresh.utils.SelectedTrafficGranularityManager
import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider
import org.wordpress.android.util.config.StatsTrafficSubscribersTabFeatureConfig
Expand Down Expand Up @@ -180,6 +181,7 @@ class StatsModule {
postAverageViewsPerDayUseCaseFactory: PostAverageViewsPerDayUseCaseFactory,
postRecentWeeksUseCaseFactory: PostRecentWeeksUseCaseFactory,
annualSiteStatsUseCaseFactory: AnnualSiteStatsUseCaseFactory,
subscribersUseCaseFactory: SubscribersUseCaseFactory,
emailsUseCaseFactory: EmailsUseCaseFactory
): List<@JvmSuppressWildcards BaseStatsUseCase<*, *>> {
return listOf(
Expand All @@ -190,6 +192,7 @@ class StatsModule {
postAverageViewsPerDayUseCaseFactory.build(VIEW_ALL),
postRecentWeeksUseCaseFactory.build(VIEW_ALL),
annualSiteStatsUseCaseFactory.build(VIEW_ALL),
subscribersUseCaseFactory.build(VIEW_ALL),
emailsUseCaseFactory.build(VIEW_ALL)
)
}
Expand Down Expand Up @@ -258,10 +261,14 @@ class StatsModule {
@Named(BLOCK_SUBSCRIBERS_USE_CASES)
@Suppress("LongParameterList")
fun provideBlockSubscribersUseCases(
subscribersUseCase: SubscribersUseCase,
subscribersChartUseCase: SubscribersChartUseCase,
subscribersUseCaseFactory: SubscribersUseCaseFactory,
emailsUseCaseFactory: EmailsUseCaseFactory
): List<@JvmSuppressWildcards BaseStatsUseCase<*, *>> =
listOf(subscribersUseCase, emailsUseCaseFactory.build(BLOCK))
): List<@JvmSuppressWildcards BaseStatsUseCase<*, *>> = listOf(
subscribersChartUseCase,
subscribersUseCaseFactory.build(BLOCK),
emailsUseCaseFactory.build(BLOCK)
)

/**
* Provides a singleton usecase that represents the Insights screen. It consists of list of use cases that build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.wordpress.android.ui.stats.StatsViewType.INSIGHTS_VIEWS_AND_VISITORS
import org.wordpress.android.ui.stats.StatsViewType.PUBLICIZE
import org.wordpress.android.ui.stats.StatsViewType.REFERRERS
import org.wordpress.android.ui.stats.StatsViewType.SEARCH_TERMS
import org.wordpress.android.ui.stats.StatsViewType.SUBSCRIBERS
import org.wordpress.android.ui.stats.StatsViewType.TAGS_AND_CATEGORIES
import org.wordpress.android.ui.stats.StatsViewType.TOP_POSTS_AND_PAGES
import org.wordpress.android.ui.stats.StatsViewType.VIDEO_PLAYS
Expand Down Expand Up @@ -54,6 +55,7 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.T
import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.TodayStatsUseCase
import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.ViewsAndVisitorsUseCase
import org.wordpress.android.ui.stats.refresh.lists.sections.subscribers.usecases.EmailsUseCase
import org.wordpress.android.ui.stats.refresh.lists.sections.subscribers.usecases.SubscribersUseCase
import org.wordpress.android.ui.stats.refresh.utils.StatsDateSelector
import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider
import java.security.InvalidParameterException
Expand Down Expand Up @@ -208,6 +210,10 @@ class StatsViewAllViewModelFactory(
it is PostRecentWeeksUseCase
} to R.string.stats_detail_recent_weeks

SUBSCRIBERS -> Pair(
insightsUseCases.first { it is SubscribersUseCase },
R.string.stats_view_subscribers
)
EMAILS -> Pair(
insightsUseCases.first { it is EmailsUseCase },
R.string.stats_view_emails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,19 +336,6 @@ class InsightsDetailListViewModel @Inject constructor(
dateSelectorFactory.build(StatsGranularity.WEEKS)
)

// Using Weeks granularity on Subscribers detail screens
class SubscribersDetailListViewModel @Inject constructor(
@Named(UI_THREAD) mainDispatcher: CoroutineDispatcher,
@Named(SUBSCRIBERS_USE_CASE) statsUseCase: BaseListUseCase,
analyticsTracker: AnalyticsTrackerWrapper,
dateSelectorFactory: StatsDateSelector.Factory
) : StatsListViewModel(
mainDispatcher,
statsUseCase,
analyticsTracker,
dateSelectorFactory.build(StatsGranularity.WEEKS)
)

class TotalLikesDetailListViewModel @Inject constructor(
@Named(UI_THREAD) mainDispatcher: CoroutineDispatcher,
@Named(TOTAL_LIKES_DETAIL_USE_CASE) statsUseCase: BaseListUseCase,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class EmailsUseCase @Inject constructor(
override suspend fun loadCachedData() =
emailsStore.getEmails(statsSiteProvider.siteModel, LimitMode.Top(VIEW_ALL_ITEM_SIZE), sortField)

override fun buildLoadingItem() = listOf(BlockListItem.Title(R.string.stats_subscribers_emails))
override fun buildLoadingItem() = listOf(BlockListItem.Title(R.string.stats_view_emails))

override fun buildEmptyItem() = listOf(buildTitle(), BlockListItem.Empty())

Expand Down Expand Up @@ -91,7 +91,7 @@ class EmailsUseCase @Inject constructor(
return items
}

private fun buildTitle() = BlockListItem.Title(R.string.stats_subscribers_emails)
private fun buildTitle() = BlockListItem.Title(R.string.stats_view_emails)

private fun mapPost(post: PostsModel.PostModel) = BlockListItem.ListItemWithTwoValues(
text = post.title,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package org.wordpress.android.ui.stats.refresh.lists.sections.subscribers.usecases

import kotlinx.coroutines.CoroutineDispatcher
import org.wordpress.android.R
import org.wordpress.android.analytics.AnalyticsTracker
import org.wordpress.android.fluxc.model.stats.LimitMode
import org.wordpress.android.fluxc.model.stats.subscribers.SubscribersModel
import org.wordpress.android.fluxc.network.utils.StatsGranularity.DAYS
import org.wordpress.android.fluxc.store.StatsStore.SubscriberType.SUBSCRIBERS_CHART
import org.wordpress.android.fluxc.store.stats.subscribers.SubscribersStore
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.modules.UI_THREAD
import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.StatelessUseCase
import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem
import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Title
import org.wordpress.android.ui.stats.refresh.lists.sections.insights.InsightUseCaseFactory
import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider
import org.wordpress.android.util.AppLog
import org.wordpress.android.util.AppLog.T
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
import javax.inject.Inject
import javax.inject.Named

const val SUBSCRIBERS_CHART_ITEMS_TO_LOAD = 30

class SubscribersChartUseCase @Inject constructor(
private val subscribersStore: SubscribersStore,
private val statsSiteProvider: StatsSiteProvider,
private val subscribersMapper: SubscribersMapper,
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher,
@Named(BG_THREAD) private val backgroundDispatcher: CoroutineDispatcher,
private val analyticsTracker: AnalyticsTrackerWrapper
) : StatelessUseCase<SubscribersModel>(SUBSCRIBERS_CHART, mainDispatcher, backgroundDispatcher) {
override fun buildLoadingItem(): List<BlockListItem> = listOf()

override suspend fun loadCachedData() = subscribersStore.getSubscribers(
statsSiteProvider.siteModel,
DAYS,
LimitMode.Top(SUBSCRIBERS_CHART_ITEMS_TO_LOAD)
)

override suspend fun fetchRemoteData(forced: Boolean): State<SubscribersModel> {
val response = subscribersStore.fetchSubscribers(
statsSiteProvider.siteModel,
DAYS,
LimitMode.Top(SUBSCRIBERS_CHART_ITEMS_TO_LOAD),
forced
)
val model = response.model
val error = response.error

return when {
error != null -> State.Error(error.message ?: error.type.name)
model != null && model.dates.isNotEmpty() -> State.Data(model)
else -> State.Empty()
}
}

override fun buildUiModel(domainModel: SubscribersModel): List<BlockListItem> {
val items = mutableListOf<BlockListItem>()
if (domainModel.dates.isEmpty()) {
AppLog.e(T.STATS, "There is no data to be shown in the subscribers chart block")
} else {
items.add(buildTitle())

items.add(subscribersMapper.buildChart(domainModel.dates, this::onLineSelected))
}
return items
}

private fun buildTitle() = Title(R.string.stats_view_subscribers_chart)

private fun onLineSelected() {
analyticsTracker.track(AnalyticsTracker.Stat.STATS_SUBSCRIBERS_CHART_TAPPED)
}

class SubscribersUseCaseFactory @Inject constructor(
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher,
@Named(BG_THREAD) private val backgroundDispatcher: CoroutineDispatcher,
private val statsSiteProvider: StatsSiteProvider,
private val subscribersMapper: SubscribersMapper,
private val subscribersStore: SubscribersStore,
private val analyticsTracker: AnalyticsTrackerWrapper
) : InsightUseCaseFactory {
override fun build(useCaseMode: UseCaseMode) =
SubscribersChartUseCase(
subscribersStore,
statsSiteProvider,
subscribersMapper,
mainDispatcher,
backgroundDispatcher,
analyticsTracker
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SubscribersMapper @Inject constructor(
}

val contentDescriptions = statsUtils.getSubscribersChartEntryContentDescriptions(
R.string.stats_subscribers_subscribers,
R.string.stats_view_subscribers_chart,
chartItems
)

Expand Down
Loading

0 comments on commit f51cb45

Please sign in to comment.