diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsModule.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsModule.kt index a3cbd2848638..74984c278010 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsModule.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsModule.kt @@ -67,6 +67,7 @@ import javax.inject.Named import javax.inject.Singleton const val INSIGHTS_USE_CASE = "InsightsUseCase" +const val TRAFFIC_USE_CASE = "TrafficStatsUseCase" const val DAY_STATS_USE_CASE = "DayStatsUseCase" const val WEEK_STATS_USE_CASE = "WeekStatsUseCase" const val MONTH_STATS_USE_CASE = "MonthStatsUseCase" @@ -265,6 +266,32 @@ class StatsModule { ) } + /** + * Provides a singleton usecase that represents the TRAFFIC stats screen. + * @param useCasesFactories build the use cases for the DAYS granularity + */ + @Provides + @Singleton + @Named(TRAFFIC_USE_CASE) + @Suppress("LongParameterList") + fun provideTrafficUseCase( + statsStore: StatsStore, + @Named(BG_THREAD) bgDispatcher: CoroutineDispatcher, + @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, + statsSiteProvider: StatsSiteProvider, + @Named(GRANULAR_USE_CASE_FACTORIES) useCasesFactories: List<@JvmSuppressWildcards GranularUseCaseFactory>, + uiModelMapper: UiModelMapper + ): BaseListUseCase { + return BaseListUseCase( + bgDispatcher, + mainDispatcher, + statsSiteProvider, + useCasesFactories.map { it.build(DAYS, BLOCK) }, + { statsStore.getTimeStatsTypes(it) }, + uiModelMapper::mapTimeStats + ) + } + /** * Provides a singleton usecase that represents the Day stats screen. * @param useCasesFactories build the use cases for the DAYS granularity @@ -374,8 +401,10 @@ class StatsModule { @Provides @Singleton @Named(LIST_STATS_USE_CASES) + @Suppress("LongParameterList") fun provideListStatsUseCases( @Named(INSIGHTS_USE_CASE) insightsUseCase: BaseListUseCase, + @Named(TRAFFIC_USE_CASE) trafficUseCase: BaseListUseCase, @Named(DAY_STATS_USE_CASE) dayStatsUseCase: BaseListUseCase, @Named(WEEK_STATS_USE_CASE) weekStatsUseCase: BaseListUseCase, @Named(MONTH_STATS_USE_CASE) monthStatsUseCase: BaseListUseCase, @@ -383,6 +412,7 @@ class StatsModule { ): Map { return mapOf( StatsSection.INSIGHTS to insightsUseCase, + StatsSection.TRAFFIC to trafficUseCase, StatsSection.DAYS to dayStatsUseCase, StatsSection.WEEKS to weekStatsUseCase, StatsSection.MONTHS to monthStatsUseCase, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsViewAllViewModelFactory.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsViewAllViewModelFactory.kt index 463afd2eee92..cec09374d5c0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsViewAllViewModelFactory.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/StatsViewAllViewModelFactory.kt @@ -29,7 +29,6 @@ import org.wordpress.android.ui.stats.StatsViewType.SEARCH_TERMS 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 -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection import org.wordpress.android.ui.stats.refresh.lists.detail.PostAverageViewsPerDayUseCase import org.wordpress.android.ui.stats.refresh.lists.detail.PostMonthsAndYearsUseCase import org.wordpress.android.ui.stats.refresh.lists.detail.PostRecentWeeksUseCase @@ -55,7 +54,6 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.T import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.ViewsAndVisitorsUseCase import org.wordpress.android.ui.stats.refresh.utils.StatsDateSelector import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider -import org.wordpress.android.ui.stats.refresh.utils.toStatsSection import java.security.InvalidParameterException import javax.inject.Inject import javax.inject.Named @@ -106,7 +104,7 @@ class StatsViewAllViewModelFactory( val dateSelector = if (granularity == null) { null } else { - dateSelectorFactory.build(granularity.toStatsSection()) + dateSelectorFactory.build(granularity) } return StatsViewAllViewModelFactory( mainDispatcher, @@ -127,7 +125,7 @@ class StatsViewAllViewModelFactory( bgDispatcher, useCase, statsSiteProvider, - dateSelectorFactory.build(StatsSection.ANNUAL_STATS), + dateSelectorFactory.build(StatsGranularity.YEARS), R.string.stats_insights_annual_site_stats ) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/BaseListUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/BaseListUseCase.kt index 6c8632bbb5f3..b01c21f2abc7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/BaseListUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/BaseListUseCase.kt @@ -9,10 +9,10 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.wordpress.android.R import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.fluxc.store.StatsStore.StatsType import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.ui.stats.refresh.NavigationTarget -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.UiModel import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.UseCaseModel @@ -140,8 +140,8 @@ class BaseListUseCase( data.value = null } - suspend fun onDateChanged(selectedSection: StatsSection) { - onParamChanged(UseCaseParam.SelectedDateParam(selectedSection)) + suspend fun onDateChanged(selectedGranularity: StatsGranularity) { + onParamChanged(UseCaseParam.SelectedDateParam(selectedGranularity)) } fun onListSelected() { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListFragment.kt index 30ca269635ce..1469325b5c26 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListFragment.kt @@ -27,6 +27,7 @@ import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.UiModel.E import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.UiModel.Error import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.UiModel.Success import org.wordpress.android.ui.stats.refresh.lists.detail.DetailListViewModel +import org.wordpress.android.ui.stats.refresh.utils.SelectedTrafficGranularityManager import org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter import org.wordpress.android.ui.stats.refresh.utils.StatsNavigator import org.wordpress.android.ui.stats.refresh.utils.drawDateSelector @@ -57,6 +58,9 @@ class StatsListFragment : ViewPagerFragment(R.layout.stats_list_fragment) { @Inject lateinit var statsTrafficTabFeatureConfig: StatsTrafficTabFeatureConfig + @Inject + lateinit var selectedTrafficGranularityManager: SelectedTrafficGranularityManager + private lateinit var viewModel: StatsListViewModel private lateinit var statsSection: StatsSection @@ -158,9 +162,14 @@ class StatsListFragment : ViewPagerFragment(R.layout.stats_list_fragment) { StatsGranularity.entries.map { getString(it.toNameResource()) } ).apply { setDropDownViewResource(R.layout.toolbar_spinner_dropdown_item) } + val selectedGranularityItemPos = StatsGranularity.entries.indexOf( + selectedTrafficGranularityManager.getSelectedTrafficGranularity() + ) + dateSelector.granularitySpinner.setSelection(selectedGranularityItemPos) + dateSelector.granularitySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - // TODO update TRAFFIC tab + selectedTrafficGranularityManager.setSelectedTrafficGranularity(StatsGranularity.entries[position]) } @Suppress("EmptyFunctionBlock") @@ -245,7 +254,7 @@ class StatsListFragment : ViewPagerFragment(R.layout.stats_list_fragment) { viewModel.selectedDate?.observe(viewLifecycleOwner) { event -> if (event != null) { - viewModel.onDateChanged(event.selectedSection) + viewModel.onDateChanged(event.selectedGranularity) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListViewModel.kt index a3b14286a6f8..1643bedabaae 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/StatsListViewModel.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.delay import org.wordpress.android.R import org.wordpress.android.analytics.AnalyticsTracker.Stat +import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.modules.UI_THREAD import org.wordpress.android.ui.stats.refresh.DAY_STATS_USE_CASE import org.wordpress.android.ui.stats.refresh.INSIGHTS_USE_CASE @@ -20,15 +21,10 @@ import org.wordpress.android.ui.stats.refresh.StatsViewModel.DateSelectorUiModel import org.wordpress.android.ui.stats.refresh.TOTAL_COMMENTS_DETAIL_USE_CASE import org.wordpress.android.ui.stats.refresh.TOTAL_FOLLOWERS_DETAIL_USE_CASE import org.wordpress.android.ui.stats.refresh.TOTAL_LIKES_DETAIL_USE_CASE +import org.wordpress.android.ui.stats.refresh.TRAFFIC_USE_CASE import org.wordpress.android.ui.stats.refresh.VIEWS_AND_VISITORS_USE_CASE import org.wordpress.android.ui.stats.refresh.WEEK_STATS_USE_CASE import org.wordpress.android.ui.stats.refresh.YEAR_STATS_USE_CASE -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.DAYS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.INSIGHTS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.MONTHS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.TRAFFIC -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.WEEKS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.YEARS import org.wordpress.android.ui.stats.refresh.utils.ActionCardHandler import org.wordpress.android.ui.stats.refresh.utils.ItemPopupMenuHandler import org.wordpress.android.ui.stats.refresh.utils.NewsCardHandler @@ -131,9 +127,9 @@ abstract class StatsListViewModel( } } - fun onDateChanged(selectedSection: StatsSection) { + fun onDateChanged(selectedGranularity: StatsGranularity) { launch { - statsUseCase.onDateChanged(selectedSection) + statsUseCase.onDateChanged(selectedGranularity) } } @@ -185,7 +181,6 @@ class InsightsListViewModel @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(INSIGHTS_USE_CASE) private val insightsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, - dateSelectorFactory: StatsDateSelector.Factory, popupMenuHandler: ItemPopupMenuHandler, newsCardHandler: NewsCardHandler, actionCardHandler: ActionCardHandler @@ -193,72 +188,117 @@ class InsightsListViewModel mainDispatcher, insightsUseCase, analyticsTracker, - dateSelectorFactory.build(INSIGHTS), + null, popupMenuHandler, newsCardHandler, actionCardHandler ) +class TrafficListViewModel @Inject constructor( + @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, + @Named(TRAFFIC_USE_CASE) statsUseCase: BaseListUseCase, + analyticsTracker: AnalyticsTrackerWrapper, + dateSelectorFactory: StatsDateSelector.Factory +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.DAYS, isGranularitySpinnerVisible = true) +) + class YearsListViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(YEAR_STATS_USE_CASE) statsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(YEARS)) +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.YEARS) +) class MonthsListViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(MONTH_STATS_USE_CASE) statsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(MONTHS)) +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.MONTHS) +) class WeeksListViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(WEEK_STATS_USE_CASE) statsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(WEEKS)) +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.WEEKS) +) class DaysListViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(DAY_STATS_USE_CASE) statsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(DAYS)) - -class TrafficListViewModel @Inject constructor( - @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, - @Named(DAY_STATS_USE_CASE) statsUseCase: BaseListUseCase, - analyticsTracker: AnalyticsTrackerWrapper, - dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(TRAFFIC)) +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.DAYS) +) -// Using Weeks granularity on new insight details screens +// Using Weeks granularity on insight details screens class InsightsDetailListViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(VIEWS_AND_VISITORS_USE_CASE) statsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(WEEKS)) +) : 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, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(WEEKS)) +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.WEEKS) +) class TotalCommentsDetailListViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(TOTAL_COMMENTS_DETAIL_USE_CASE) statsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(WEEKS)) +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.WEEKS) +) class TotalFollowersDetailListViewModel @Inject constructor( @Named(UI_THREAD) mainDispatcher: CoroutineDispatcher, @Named(TOTAL_FOLLOWERS_DETAIL_USE_CASE) statsUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, statsUseCase, analyticsTracker, dateSelectorFactory.build(WEEKS)) +) : StatsListViewModel( + mainDispatcher, + statsUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.WEEKS) +) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/DetailListViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/DetailListViewModel.kt index 23199d7b74f4..9ceb3563f701 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/DetailListViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/DetailListViewModel.kt @@ -1,11 +1,11 @@ package org.wordpress.android.ui.stats.refresh.lists.detail import kotlinx.coroutines.CoroutineDispatcher +import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.modules.UI_THREAD import org.wordpress.android.ui.stats.refresh.BLOCK_DETAIL_USE_CASE import org.wordpress.android.ui.stats.refresh.lists.BaseListUseCase import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.DETAIL import org.wordpress.android.ui.stats.refresh.utils.StatsDateSelector import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper import javax.inject.Inject @@ -17,7 +17,12 @@ class DetailListViewModel @Named(BLOCK_DETAIL_USE_CASE) private val detailUseCase: BaseListUseCase, analyticsTracker: AnalyticsTrackerWrapper, dateSelectorFactory: StatsDateSelector.Factory -) : StatsListViewModel(mainDispatcher, detailUseCase, analyticsTracker, dateSelectorFactory.build(DETAIL)) { +) : StatsListViewModel( + mainDispatcher, + detailUseCase, + analyticsTracker, + dateSelectorFactory.build(StatsGranularity.DAYS) +) { override fun onCleared() { super.onCleared() dateSelector?.clear() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/PostDayViewsUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/PostDayViewsUseCase.kt index c5e7c1809c52..d6dd4e02c4d6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/PostDayViewsUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/detail/PostDayViewsUseCase.kt @@ -8,7 +8,6 @@ import org.wordpress.android.fluxc.store.StatsStore.PostDetailType import org.wordpress.android.fluxc.store.stats.PostDetailStore import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.modules.UI_THREAD -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.DETAIL import org.wordpress.android.ui.stats.refresh.lists.detail.PostDayViewsUseCase.UiState import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem @@ -39,7 +38,7 @@ class PostDayViewsUseCase mainDispatcher, backgroundDispatcher, UiState(), - uiUpdateParams = listOf(UseCaseParam.SelectedDateParam(DETAIL)) + uiUpdateParams = listOf(UseCaseParam.SelectedDateParam(DAYS)) ) { override suspend fun loadCachedData(): PostDetailStatsModel? { return statsPostProvider.postId?.let { postId -> @@ -59,15 +58,15 @@ class PostDayViewsUseCase return when { error != null -> { - selectedDateProvider.onDateLoadingFailed(DETAIL) + selectedDateProvider.onDateLoadingFailed(DAYS) State.Error(error.message ?: error.type.name) } model != null && model.hasData() -> { - selectedDateProvider.onDateLoadingSucceeded(DETAIL) + selectedDateProvider.onDateLoadingSucceeded(DAYS) State.Data(model) } else -> { - selectedDateProvider.onDateLoadingSucceeded(DETAIL) + selectedDateProvider.onDateLoadingSucceeded(DAYS) State.Empty() } } @@ -78,14 +77,14 @@ class PostDayViewsUseCase val visibleBarCount = uiState.visibleBarCount ?: domainModel.dayViews.size if (domainModel.hasData() && visibleBarCount > 0) { - val periodFromProvider = selectedDateProvider.getSelectedDate(DETAIL) + val periodFromProvider = selectedDateProvider.getSelectedDate(DAYS) val availablePeriods = domainModel.dayViews.takeLast(visibleBarCount) val availableDates = availablePeriods.map { statsDateFormatter.parseStatsDate(DAYS, it.period) } val selectedPeriod = periodFromProvider ?: availableDates.last() val index = availableDates.indexOf(selectedPeriod) - selectedDateProvider.selectDate(selectedPeriod, availableDates, DETAIL) + selectedDateProvider.selectDate(selectedPeriod, availableDates, DAYS) val shiftedIndex = index + domainModel.dayViews.size - visibleBarCount val selectedItem = domainModel.dayViews.getOrNull(shiftedIndex) ?: domainModel.dayViews.last() @@ -107,7 +106,7 @@ class PostDayViewsUseCase ) ) } else { - selectedDateProvider.onDateLoadingFailed(DETAIL) + selectedDateProvider.onDateLoadingFailed(DAYS) AppLog.e(T.STATS, "There is no data to be shown in the post day view block") } return items @@ -129,7 +128,7 @@ class PostDayViewsUseCase val selectedDate = statsDateFormatter.parseStatsDate(DAYS, period) selectedDateProvider.selectDate( selectedDate, - DETAIL + DAYS ) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BaseStatsUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BaseStatsUseCase.kt index ec7c148fdc3c..7b86388e0e3a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BaseStatsUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BaseStatsUseCase.kt @@ -9,9 +9,9 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.wordpress.android.R +import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.fluxc.store.StatsStore.StatsType import org.wordpress.android.ui.stats.refresh.NavigationTarget -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.State.Data import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.State.Empty import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.State.Error @@ -282,6 +282,6 @@ abstract class BaseStatsUseCase( } sealed class UseCaseParam { - data class SelectedDateParam(val statsSection: StatsSection) : UseCaseParam() + data class SelectedDateParam(val statsGranularity: StatsGranularity) : UseCaseParam() } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatefulUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatefulUseCase.kt index 30d1e2ae7bc3..dce50cf9b582 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatefulUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatefulUseCase.kt @@ -8,7 +8,6 @@ import org.wordpress.android.fluxc.store.StatsStore.StatsType import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider -import org.wordpress.android.ui.stats.refresh.utils.toStatsSection import java.util.Date @Suppress("LongParameterList") @@ -25,7 +24,7 @@ abstract class GranularStatefulUseCase( mainDispatcher, backgroundDispatcher, defaultUiState, - listOf(UseCaseParam.SelectedDateParam(statsGranularity.toStatsSection())) + listOf(UseCaseParam.SelectedDateParam(statsGranularity)) ) { abstract suspend fun loadCachedData(selectedDate: Date, site: SiteModel): DOMAIN_MODEL? diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatelessUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatelessUseCase.kt index 8b6ffb02ff39..f4fc676d1b99 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatelessUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/GranularStatelessUseCase.kt @@ -8,7 +8,6 @@ import org.wordpress.android.fluxc.store.StatsStore.StatsType 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.utils.StatsSiteProvider -import org.wordpress.android.ui.stats.refresh.utils.toStatsSection import java.util.Date abstract class GranularStatelessUseCase( @@ -22,7 +21,7 @@ abstract class GranularStatelessUseCase( type, mainDispatcher, backgroundDispatcher, - listOf(UseCaseParam.SelectedDateParam(statsGranularity.toStatsSection())) + listOf(UseCaseParam.SelectedDateParam(statsGranularity)) ) { abstract suspend fun loadCachedData(selectedDate: Date, site: SiteModel): DOMAIN_MODEL? diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/SelectedDateProvider.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/SelectedDateProvider.kt index 6cc52b2e5572..1ce18f0db9b7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/SelectedDateProvider.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/SelectedDateProvider.kt @@ -11,17 +11,11 @@ import kotlinx.parcelize.Parcelize import org.wordpress.android.analytics.AnalyticsTracker.Stat.STATS_NEXT_DATE_TAPPED import org.wordpress.android.analytics.AnalyticsTracker.Stat.STATS_PREVIOUS_DATE_TAPPED import org.wordpress.android.fluxc.network.utils.StatsGranularity -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.DAYS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.MONTHS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.WEEKS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.YEARS import org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter -import org.wordpress.android.ui.stats.refresh.utils.toStatsSection -import org.wordpress.android.ui.stats.refresh.utils.trackWithSection +import org.wordpress.android.ui.stats.refresh.utils.trackWithGranularity import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper -import org.wordpress.android.util.extensions.readListCompat import org.wordpress.android.util.extensions.getParcelableCompat +import org.wordpress.android.util.extensions.readListCompat import org.wordpress.android.util.filter import java.util.Date import javax.inject.Inject @@ -36,121 +30,100 @@ class SelectedDateProvider private val analyticsTrackerWrapper: AnalyticsTrackerWrapper ) { private val mutableDates = mutableMapOf( - DAYS to SelectedDate(loading = true), - WEEKS to SelectedDate(loading = true), - MONTHS to SelectedDate(loading = true), - YEARS to SelectedDate(loading = true) + StatsGranularity.DAYS to SelectedDate(loading = true), + StatsGranularity.WEEKS to SelectedDate(loading = true), + StatsGranularity.MONTHS to SelectedDate(loading = true), + StatsGranularity.YEARS to SelectedDate(loading = true) ) - private val selectedDateChanged = MutableLiveData() - - fun granularSelectedDateChanged(statsSection: StatsSection): LiveData { - return selectedDateChanged.filter { it?.selectedSection == statsSection } - } + private val selectedDateChanged = MutableLiveData() - fun selectDate(date: Date, statsSection: StatsSection) { - val selectedDate = getSelectedDateState(statsSection) - updateSelectedDate(selectedDate.copy(dateValue = date), statsSection) + fun granularSelectedDateChanged(statsGranularity: StatsGranularity): LiveData { + return selectedDateChanged.filter { it?.selectedGranularity == statsGranularity } } fun selectDate(date: Date, statsGranularity: StatsGranularity) { - selectDate(date, statsGranularity.toStatsSection()) + val selectedDate = getSelectedDateState(statsGranularity) + updateSelectedDate(selectedDate.copy(dateValue = date), statsGranularity) } - fun selectDate(updatedDate: Date, availableDates: List, statsSection: StatsSection) { - val selectedDate = getSelectedDateState(statsSection) + fun selectDate(updatedDate: Date, availableDates: List, statsGranularity: StatsGranularity) { + val selectedDate = getSelectedDateState(statsGranularity) if (selectedDate.dateValue != updatedDate || selectedDate.availableDates != availableDates) { updateSelectedDate( selectedDate.copy(dateValue = updatedDate, availableDates = availableDates), - statsSection + statsGranularity ) } } - fun selectDate(updatedDate: Date, availableDates: List, statsGranularity: StatsGranularity) { - selectDate(updatedDate, availableDates, statsGranularity.toStatsSection()) - } - - fun updateSelectedDate(selectedDate: SelectedDate, statsSection: StatsSection) { - val currentDate = mutableDates[statsSection] - mutableDates[statsSection] = selectedDate + fun updateSelectedDate(selectedDate: SelectedDate, statsGranularity: StatsGranularity) { + val currentDate = mutableDates[statsGranularity] + mutableDates[statsGranularity] = selectedDate if (selectedDate != currentDate) { - selectedDateChanged.postValue(SectionChange(statsSection)) + selectedDateChanged.postValue(GranularityChange(statsGranularity)) } } fun setInitialSelectedPeriod(statsGranularity: StatsGranularity, period: String) { val updatedDate = statsDateFormatter.parseStatsDate(statsGranularity, period) val selectedDate = getSelectedDateState(statsGranularity) - updateSelectedDate(selectedDate.copy(dateValue = updatedDate), statsGranularity.toStatsSection()) + updateSelectedDate(selectedDate.copy(dateValue = updatedDate), statsGranularity) } fun getSelectedDate(statsGranularity: StatsGranularity): Date? { - return getSelectedDate(statsGranularity.toStatsSection()) - } - - fun getSelectedDate(statsSection: StatsSection): Date? { - return getSelectedDateState(statsSection).dateValue + return getSelectedDateState(statsGranularity).dateValue } fun getSelectedDateState(statsGranularity: StatsGranularity): SelectedDate { - return getSelectedDateState(statsGranularity.toStatsSection()) + return mutableDates[statsGranularity] ?: SelectedDate(loading = true) } - fun getSelectedDateState(statsSection: StatsSection): SelectedDate { - return mutableDates[statsSection] ?: SelectedDate(loading = true) - } - - fun hasPreviousDate(statsSection: StatsSection): Boolean { - val selectedDate = getSelectedDateState(statsSection) + fun hasPreviousDate(statsGranularity: StatsGranularity): Boolean { + val selectedDate = getSelectedDateState(statsGranularity) return selectedDate.hasData() && selectedDate.getDateIndex() > 0 } - fun hasNextDate(statsSection: StatsSection): Boolean { - val selectedDate = getSelectedDateState(statsSection) + fun hasNextDate(statsGranularity: StatsGranularity): Boolean { + val selectedDate = getSelectedDateState(statsGranularity) return selectedDate.hasData() && selectedDate.getDateIndex() < selectedDate.availableDates.size - 1 } - fun selectPreviousDate(statsSection: StatsSection) { - val selectedDateState = getSelectedDateState(statsSection) + fun selectPreviousDate(statsGranularity: StatsGranularity) { + val selectedDateState = getSelectedDateState(statsGranularity) if (selectedDateState.hasData()) { - analyticsTrackerWrapper.trackWithSection(STATS_PREVIOUS_DATE_TAPPED, statsSection) - updateSelectedDate(selectedDateState.copy(dateValue = selectedDateState.getPreviousDate()), statsSection) + analyticsTrackerWrapper.trackWithGranularity(STATS_PREVIOUS_DATE_TAPPED, statsGranularity) + updateSelectedDate( + selectedDateState.copy(dateValue = selectedDateState.getPreviousDate()), + statsGranularity + ) } } - fun selectNextDate(statsSection: StatsSection) { - val selectedDateState = getSelectedDateState(statsSection) + fun selectNextDate(statsGranularity: StatsGranularity) { + val selectedDateState = getSelectedDateState(statsGranularity) if (selectedDateState.hasData()) { - analyticsTrackerWrapper.trackWithSection(STATS_NEXT_DATE_TAPPED, statsSection) - updateSelectedDate(selectedDateState.copy(dateValue = selectedDateState.getNextDate()), statsSection) + analyticsTrackerWrapper.trackWithGranularity(STATS_NEXT_DATE_TAPPED, statsGranularity) + updateSelectedDate(selectedDateState.copy(dateValue = selectedDateState.getNextDate()), statsGranularity) } } fun onDateLoadingFailed(statsGranularity: StatsGranularity) { - onDateLoadingFailed(statsGranularity.toStatsSection()) - } - - fun onDateLoadingFailed(statsSection: StatsSection) { - val selectedDate = getSelectedDateState(statsSection) + val selectedDate = getSelectedDateState(statsGranularity) if (selectedDate.dateValue != null && !selectedDate.error) { - updateSelectedDate(selectedDate.copy(error = true, loading = false), statsSection) + updateSelectedDate(selectedDate.copy(error = true, loading = false), statsGranularity) } else if (selectedDate.dateValue == null) { - updateSelectedDate(SelectedDate(error = true, loading = false), statsSection) + updateSelectedDate(SelectedDate(error = true, loading = false), statsGranularity) } } fun onDateLoadingSucceeded(statsGranularity: StatsGranularity) { - onDateLoadingSucceeded(statsGranularity.toStatsSection()) - } - - fun onDateLoadingSucceeded(statsSection: StatsSection) { - val selectedDate = getSelectedDateState(statsSection) + val selectedDate = getSelectedDateState(statsGranularity) if (selectedDate.dateValue != null && selectedDate.error) { - updateSelectedDate(selectedDate.copy(error = false, loading = false), statsSection) + updateSelectedDate(selectedDate.copy(error = false, loading = false), statsGranularity) } else if (selectedDate.dateValue == null) { - updateSelectedDate(SelectedDate(error = false, loading = false), statsSection) + updateSelectedDate(SelectedDate(error = false, loading = false), statsGranularity) } } @@ -161,8 +134,8 @@ class SelectedDateProvider selectedDateChanged.value = null } - fun clear(statsSection: StatsSection) { - mutableDates[statsSection] = SelectedDate(loading = true) + fun clear(statsGranularity: StatsGranularity) { + mutableDates[statsGranularity] = SelectedDate(loading = true) selectedDateChanged.value = null } @@ -173,7 +146,12 @@ class SelectedDateProvider } fun onRestoreInstanceState(savedState: Bundle) { - for (period in listOf(DAYS, WEEKS, MONTHS, YEARS)) { + for (period in listOf( + StatsGranularity.DAYS, + StatsGranularity.WEEKS, + StatsGranularity.MONTHS, + StatsGranularity.YEARS + )) { val selectedDate = savedState.getParcelableCompat(buildStateKey(period)) if (selectedDate != null) { mutableDates[period] = selectedDate @@ -181,7 +159,7 @@ class SelectedDateProvider } } - private fun buildStateKey(key: StatsSection) = SELECTED_DATE_STATE_KEY + key + private fun buildStateKey(key: StatsGranularity) = SELECTED_DATE_STATE_KEY + key @Parcelize @SuppressLint("ParcelCreator") @@ -241,5 +219,5 @@ class SelectedDateProvider } } - data class SectionChange(val selectedSection: StatsSection) + data class GranularityChange(val selectedGranularity: StatsGranularity) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/usecases/OverviewUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/usecases/OverviewUseCase.kt index ef7b192d6ba7..104ebebb120c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/usecases/OverviewUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/granular/usecases/OverviewUseCase.kt @@ -24,7 +24,6 @@ import org.wordpress.android.ui.stats.refresh.lists.widget.WidgetUpdater.StatsWi import org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider import org.wordpress.android.ui.stats.refresh.utils.StatsUtils -import org.wordpress.android.ui.stats.refresh.utils.toStatsSection import org.wordpress.android.ui.stats.refresh.utils.trackGranular import org.wordpress.android.util.AppLog import org.wordpress.android.util.AppLog.T @@ -60,7 +59,7 @@ class OverviewUseCase constructor( mainDispatcher, backgroundDispatcher, UiState(), - uiUpdateParams = listOf(UseCaseParam.SelectedDateParam(statsGranularity.toStatsSection())) + uiUpdateParams = listOf(UseCaseParam.SelectedDateParam(statsGranularity)) ) { override fun buildLoadingItem(): List = listOf( diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCase.kt index 3b4faa13812e..f9e5d4e8a284 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCase.kt @@ -4,12 +4,12 @@ import android.view.View import kotlinx.coroutines.CoroutineDispatcher import org.wordpress.android.R import org.wordpress.android.fluxc.model.stats.YearsInsightsModel +import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.fluxc.store.StatsStore.InsightType.ANNUAL_SITE_STATS import org.wordpress.android.fluxc.store.stats.insights.MostPopularInsightsStore import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.modules.UI_THREAD import org.wordpress.android.ui.stats.refresh.NavigationTarget -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.ANNUAL_STATS 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.Link @@ -59,13 +59,13 @@ class AnnualSiteStatsUseCase( override fun buildLoadingItem(): List = listOf(Title(R.string.stats_insights_this_year_site_stats)) override fun buildUiModel(domainModel: YearsInsightsModel): List { - val periodFromProvider = selectedDateProvider.getSelectedDate(ANNUAL_STATS) + val periodFromProvider = selectedDateProvider.getSelectedDate(StatsGranularity.YEARS) val availablePeriods = domainModel.years val availableDates = availablePeriods.map { yearToDate(it.year) } val selectedPeriod = periodFromProvider ?: availableDates.last() val index = availableDates.indexOf(selectedPeriod) - selectedDateProvider.selectDate(selectedPeriod, availableDates, ANNUAL_STATS) + selectedDateProvider.selectDate(selectedPeriod, availableDates, StatsGranularity.YEARS) val items = mutableListOf() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/ViewsAndVisitorsUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/ViewsAndVisitorsUseCase.kt index 930d1bd04e49..01b1e4d5d106 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/ViewsAndVisitorsUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/ViewsAndVisitorsUseCase.kt @@ -29,7 +29,6 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.V import org.wordpress.android.ui.stats.refresh.lists.widget.WidgetUpdater.StatsWidgetUpdaters import org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider -import org.wordpress.android.ui.stats.refresh.utils.toStatsSection import org.wordpress.android.ui.stats.refresh.utils.trackGranular import org.wordpress.android.ui.stats.refresh.utils.trackViewsVisitorsChips import org.wordpress.android.ui.stats.refresh.utils.trackWithType @@ -68,7 +67,7 @@ class ViewsAndVisitorsUseCase mainDispatcher, backgroundDispatcher, UiState(), - uiUpdateParams = listOf(UseCaseParam.SelectedDateParam(statsGranularity.toStatsSection())) + uiUpdateParams = listOf(UseCaseParam.SelectedDateParam(statsGranularity)) ) { override fun buildLoadingItem(): List = listOf( diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/SelectedSectionManager.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/SelectedSectionManager.kt index a71f504a41af..fc69e6cd1837 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/SelectedSectionManager.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/SelectedSectionManager.kt @@ -10,12 +10,7 @@ import org.wordpress.android.fluxc.network.utils.StatsGranularity.MONTHS import org.wordpress.android.fluxc.network.utils.StatsGranularity.WEEKS import org.wordpress.android.fluxc.network.utils.StatsGranularity.YEARS import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.ANNUAL_STATS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.DETAIL import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.INSIGHTS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.TOTAL_COMMENTS_DETAIL -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.TOTAL_FOLLOWERS_DETAIL -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.TOTAL_LIKES_DETAIL import javax.inject.Inject const val SELECTED_SECTION_KEY = "SELECTED_STATS_SECTION_KEY" @@ -47,9 +42,14 @@ class SelectedSectionManager fun StatsSection.toStatsGranularity(): StatsGranularity? { return when (this) { - ANNUAL_STATS, DETAIL, TOTAL_LIKES_DETAIL, TOTAL_COMMENTS_DETAIL, TOTAL_FOLLOWERS_DETAIL, INSIGHTS -> null + StatsSection.TRAFFIC, + StatsSection.ANNUAL_STATS, + StatsSection.DETAIL, + StatsSection.TOTAL_LIKES_DETAIL, + StatsSection.TOTAL_COMMENTS_DETAIL, + StatsSection.TOTAL_FOLLOWERS_DETAIL, + StatsSection.INSIGHTS -> null StatsSection.INSIGHT_DETAIL, - StatsSection.TRAFFIC -> DAYS // Replace with TRAFFIC when it's implemented StatsSection.DAYS -> DAYS StatsSection.WEEKS -> WEEKS StatsSection.MONTHS -> MONTHS diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/SelectedTrafficGranularityManager.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/SelectedTrafficGranularityManager.kt new file mode 100644 index 000000000000..c17ec67b92aa --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/SelectedTrafficGranularityManager.kt @@ -0,0 +1,20 @@ +package org.wordpress.android.ui.stats.refresh.utils + +import android.content.SharedPreferences +import org.wordpress.android.fluxc.network.utils.StatsGranularity +import org.wordpress.android.fluxc.network.utils.StatsGranularity.DAYS +import javax.inject.Inject + +const val SELECTED_TRAFFIC_GRANULARITY_KEY = "SELECTED_TRAFFIC_GRANULARITY_KEY" + +class SelectedTrafficGranularityManager +@Inject constructor(private val sharedPrefs: SharedPreferences) { + fun getSelectedTrafficGranularity(): StatsGranularity { + val value = sharedPrefs.getString(SELECTED_TRAFFIC_GRANULARITY_KEY, DAYS.name) + return value?.let { StatsGranularity.valueOf(value) } ?: DAYS + } + + fun setSelectedTrafficGranularity(selectedTrafficGranularity: StatsGranularity) { + sharedPrefs.edit().putString(SELECTED_TRAFFIC_GRANULARITY_KEY, selectedTrafficGranularity.name).apply() + } +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsAnalyticsUtils.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsAnalyticsUtils.kt index 95bb9b5e0f79..8113a9b097e7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsAnalyticsUtils.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsAnalyticsUtils.kt @@ -4,9 +4,6 @@ import org.wordpress.android.analytics.AnalyticsTracker.Stat import org.wordpress.android.analytics.AnalyticsTracker.Stat.STATS_INSIGHTS_VIEWS_VISITORS_TOGGLED import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.fluxc.store.StatsStore.InsightType -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.INSIGHT_DETAIL -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.TRAFFIC import org.wordpress.android.ui.stats.refresh.lists.widget.configuration.StatsWidgetConfigureFragment.WidgetType import org.wordpress.android.ui.stats.refresh.lists.widget.configuration.StatsWidgetConfigureFragment.WidgetType.ALL_TIME_VIEWS import org.wordpress.android.ui.stats.refresh.lists.widget.configuration.StatsWidgetConfigureFragment.WidgetType.TODAY_VIEWS @@ -19,9 +16,6 @@ private const val DAYS_PROPERTY = "days" private const val WEEKS_PROPERTY = "weeks" private const val MONTHS_PROPERTY = "months" private const val YEARS_PROPERTY = "years" -private const val INSIGHTS_PROPERTY = "insights" -private const val DETAIL_PROPERTY = "detail" -private const val ANNUAL_STATS_PROPERTY = "annual_stats" private const val TYPE = "type" private const val TYPES = "types" private const val WIDGET_TYPE = "widget_type" @@ -30,9 +24,6 @@ private const val WEEKLY_VIEWS_WIDGET_PROPERTY = "weekly_views" private const val WEEK_TOTALS_WIDGET_PROPERTY = "week_totals" private const val ALL_TIME_WIDGET_PROPERTY = "all_time" private const val MINIFIED_WIDGET_PROPERTY = "minified" -private const val TOTAL_LIKES_PROPERTY = "total_likes_detail" -private const val TOTAL_COMMENTS_PROPERTY = "total_comments_detail" -private const val TOTAL_FOLLOWERS_PROPERTY = "total_followers_detail" private const val CHIP_VIEWS_PROPERTY = "views" private const val CHIP_VISITORS__PROPERTY = "visitors" @@ -54,20 +45,8 @@ fun AnalyticsTrackerWrapper.trackViewsVisitorsChips(position: Int) { this.track(STATS_INSIGHTS_VIEWS_VISITORS_TOGGLED, mapOf(TYPE to property)) } -fun AnalyticsTrackerWrapper.trackWithSection(stat: Stat, section: StatsSection) { - val property = when (section) { - StatsSection.DAYS, TRAFFIC -> DAYS_PROPERTY // Replace with TRAFFIC when it's implemented - StatsSection.WEEKS -> WEEKS_PROPERTY - StatsSection.MONTHS -> MONTHS_PROPERTY - StatsSection.YEARS -> YEARS_PROPERTY - StatsSection.INSIGHTS, INSIGHT_DETAIL -> INSIGHTS_PROPERTY - StatsSection.DETAIL -> DETAIL_PROPERTY - StatsSection.ANNUAL_STATS -> ANNUAL_STATS_PROPERTY - StatsSection.TOTAL_LIKES_DETAIL -> TOTAL_LIKES_PROPERTY - StatsSection.TOTAL_COMMENTS_DETAIL -> TOTAL_COMMENTS_PROPERTY - StatsSection.TOTAL_FOLLOWERS_DETAIL -> TOTAL_FOLLOWERS_PROPERTY - } - this.track(stat, mapOf(GRANULARITY_PROPERTY to property)) +fun AnalyticsTrackerWrapper.trackWithGranularity(stat: Stat, granularity: StatsGranularity) { + this.track(stat, mapOf(GRANULARITY_PROPERTY to granularity)) } fun AnalyticsTrackerWrapper.trackWithType(stat: Stat, insightType: InsightType) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsDateSelector.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsDateSelector.kt index 89a34a9786bf..bf7d89e37a20 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsDateSelector.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsDateSelector.kt @@ -3,14 +3,7 @@ package org.wordpress.android.ui.stats.refresh.utils import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import org.wordpress.android.fluxc.network.utils.StatsGranularity -import org.wordpress.android.fluxc.network.utils.StatsGranularity.DAYS -import org.wordpress.android.fluxc.network.utils.StatsGranularity.MONTHS -import org.wordpress.android.fluxc.network.utils.StatsGranularity.WEEKS -import org.wordpress.android.fluxc.network.utils.StatsGranularity.YEARS import org.wordpress.android.ui.stats.refresh.StatsViewModel.DateSelectorUiModel -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.INSIGHTS -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.TRAFFIC import org.wordpress.android.ui.stats.refresh.lists.sections.granular.SelectedDateProvider import org.wordpress.android.ui.stats.refresh.lists.sections.granular.SelectedDateProvider.SelectedDate import org.wordpress.android.util.config.StatsTrafficTabFeatureConfig @@ -22,45 +15,39 @@ constructor( private val selectedDateProvider: SelectedDateProvider, private val statsDateFormatter: StatsDateFormatter, private val siteProvider: StatsSiteProvider, - private val statsTrafficTabFeatureConfig: StatsTrafficTabFeatureConfig, - private val statsSection: StatsSection + private val statsGranularity: StatsGranularity, + private val isGranularitySpinnerVisible: Boolean, + private val statsTrafficTabFeatureConfig: StatsTrafficTabFeatureConfig ) { private val _dateSelectorUiModel = MutableLiveData() val dateSelectorData: LiveData = _dateSelectorUiModel - val selectedDate = selectedDateProvider.granularSelectedDateChanged(this.statsSection) + val selectedDate = selectedDateProvider.granularSelectedDateChanged(statsGranularity) .perform { updateDateSelector() } fun start(startDate: SelectedDate) { - selectedDateProvider.updateSelectedDate(startDate, statsSection) + selectedDateProvider.updateSelectedDate(startDate, statsGranularity) } fun updateDateSelector() { - val shouldShowDateSelection = this.statsSection != INSIGHTS - val shouldShowGranularitySpinner = statsTrafficTabFeatureConfig.isEnabled() && this.statsSection == TRAFFIC - val updatedDate = getDateLabelForSection() val currentState = dateSelectorData.value - if (!shouldShowDateSelection && currentState?.isVisible != false) { - emitValue(currentState, DateSelectorUiModel(false)) + val timeZone = if (statsTrafficTabFeatureConfig.isEnabled()) { + null } else { - val timeZone = if (statsTrafficTabFeatureConfig.isEnabled()) { - null - } else { - statsDateFormatter.printTimeZone(siteProvider.siteModel) - } - val updatedState = DateSelectorUiModel( - shouldShowDateSelection, - shouldShowGranularitySpinner, - updatedDate, - enableSelectPrevious = selectedDateProvider.hasPreviousDate(statsSection), - enableSelectNext = selectedDateProvider.hasNextDate(statsSection), - timeZone = timeZone - ) - emitValue(currentState, updatedState) + statsDateFormatter.printTimeZone(siteProvider.siteModel) } + val updatedState = DateSelectorUiModel( + true, + isGranularitySpinnerVisible, + updatedDate, + enableSelectPrevious = selectedDateProvider.hasPreviousDate(statsGranularity), + enableSelectNext = selectedDateProvider.hasNextDate(statsGranularity), + timeZone = timeZone + ) + emitValue(currentState, updatedState) } private fun emitValue( @@ -74,41 +61,25 @@ constructor( private fun getDateLabelForSection(): String? { return statsDateFormatter.printGranularDate( - selectedDateProvider.getSelectedDate(statsSection) ?: selectedDateProvider.getCurrentDate(), - toStatsGranularity() + selectedDateProvider.getSelectedDate(statsGranularity) ?: selectedDateProvider.getCurrentDate(), + statsGranularity ) } - private fun toStatsGranularity(): StatsGranularity { - return when (statsSection) { - StatsSection.DETAIL, - StatsSection.TOTAL_LIKES_DETAIL, - StatsSection.TOTAL_COMMENTS_DETAIL, - StatsSection.TOTAL_FOLLOWERS_DETAIL, - StatsSection.INSIGHTS, - StatsSection.INSIGHT_DETAIL, - StatsSection.DAYS, TRAFFIC -> DAYS // Replace with TRAFFIC when it's implemented - StatsSection.WEEKS -> WEEKS - StatsSection.MONTHS -> MONTHS - StatsSection.ANNUAL_STATS, - StatsSection.YEARS -> YEARS - } - } - fun onNextDateSelected() { - selectedDateProvider.selectNextDate(statsSection) + selectedDateProvider.selectNextDate(statsGranularity) } fun onPreviousDateSelected() { - selectedDateProvider.selectPreviousDate(statsSection) + selectedDateProvider.selectPreviousDate(statsGranularity) } fun clear() { - selectedDateProvider.clear(statsSection) + selectedDateProvider.clear(statsGranularity) } fun getSelectedDate(): SelectedDate { - return selectedDateProvider.getSelectedDateState(statsSection) + return selectedDateProvider.getSelectedDateState(statsGranularity) } class Factory @@ -118,13 +89,14 @@ constructor( private val statsDateFormatter: StatsDateFormatter, private val statsTrafficTabFeatureConfig: StatsTrafficTabFeatureConfig ) { - fun build(statsSection: StatsSection): StatsDateSelector { + fun build(statsGranularity: StatsGranularity, isGranularitySpinnerVisible: Boolean = false): StatsDateSelector { return StatsDateSelector( selectedDateProvider, statsDateFormatter, siteProvider, - statsTrafficTabFeatureConfig, - statsSection + statsGranularity, + isGranularitySpinnerVisible, + statsTrafficTabFeatureConfig ) } } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/StatsDateSelectorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/StatsDateSelectorTest.kt index dd6096d09abd..af7fd0adf5f2 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/StatsDateSelectorTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/StatsDateSelectorTest.kt @@ -10,9 +10,8 @@ import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.ui.stats.refresh.StatsViewModel.DateSelectorUiModel -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection import org.wordpress.android.ui.stats.refresh.lists.sections.granular.SelectedDateProvider -import org.wordpress.android.ui.stats.refresh.lists.sections.granular.SelectedDateProvider.SectionChange +import org.wordpress.android.ui.stats.refresh.lists.sections.granular.SelectedDateProvider.GranularityChange import org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter import org.wordpress.android.ui.stats.refresh.utils.StatsDateSelector import org.wordpress.android.ui.stats.refresh.utils.StatsSiteProvider @@ -34,28 +33,29 @@ class StatsDateSelectorTest : BaseUnitTest() { lateinit var statsTrafficTabFeatureConfig: StatsTrafficTabFeatureConfig private val selectedDate = Date(0) private val selectedDateLabel = "Jan 1" - private val statsSection = StatsSection.DAYS private val statsGranularity = StatsGranularity.DAYS private val updatedDate = Date(10) private val updatedLabel = "Jan 2" - private val dateProviderSelectedDate = MutableLiveData() + private val dateProviderSelectedDate = MutableLiveData() private lateinit var dateSelector: StatsDateSelector @Before fun setUp() { - dateProviderSelectedDate.value = SectionChange(statsSection) - whenever(selectedDateProvider.granularSelectedDateChanged(statsSection)).thenReturn(dateProviderSelectedDate) + dateProviderSelectedDate.value = GranularityChange(statsGranularity) + whenever(selectedDateProvider.granularSelectedDateChanged(statsGranularity)) + .thenReturn(dateProviderSelectedDate) dateSelector = StatsDateSelector( selectedDateProvider, statsDateFormatter, siteProvider, - statsTrafficTabFeatureConfig, - statsSection + statsGranularity, + false, + statsTrafficTabFeatureConfig ) - whenever(selectedDateProvider.getSelectedDate(statsSection)).thenReturn(selectedDate) + whenever(selectedDateProvider.getSelectedDate(statsGranularity)).thenReturn(selectedDate) whenever(statsDateFormatter.printGranularDate(selectedDate, statsGranularity)).thenReturn(selectedDateLabel) whenever(statsDateFormatter.printGranularDate(updatedDate, statsGranularity)).thenReturn(updatedLabel) whenever(statsTrafficTabFeatureConfig.isEnabled()).thenReturn(true) @@ -77,9 +77,9 @@ class StatsDateSelectorTest : BaseUnitTest() { @Test fun `shows date selector on days screen`() { - whenever(selectedDateProvider.getSelectedDate(statsSection)).thenReturn(selectedDate) - whenever(selectedDateProvider.hasPreviousDate(statsSection)).thenReturn(true) - whenever(selectedDateProvider.hasNextDate(statsSection)).thenReturn(true) + whenever(selectedDateProvider.getSelectedDate(statsGranularity)).thenReturn(selectedDate) + whenever(selectedDateProvider.hasPreviousDate(statsGranularity)).thenReturn(true) + whenever(selectedDateProvider.hasNextDate(statsGranularity)).thenReturn(true) var model: DateSelectorUiModel? = null dateSelector.dateSelectorData.observeForever { model = it } @@ -95,8 +95,8 @@ class StatsDateSelectorTest : BaseUnitTest() { @Test fun `updates date selector on date change`() { - whenever(selectedDateProvider.hasPreviousDate(statsSection)).thenReturn(true) - whenever(selectedDateProvider.hasNextDate(statsSection)).thenReturn(true) + whenever(selectedDateProvider.hasPreviousDate(statsGranularity)).thenReturn(true) + whenever(selectedDateProvider.hasNextDate(statsGranularity)).thenReturn(true) var model: DateSelectorUiModel? = null dateSelector.dateSelectorData.observeForever { model = it } @@ -104,31 +104,10 @@ class StatsDateSelectorTest : BaseUnitTest() { Assertions.assertThat(model?.date).isEqualTo(selectedDateLabel) - whenever(selectedDateProvider.getSelectedDate(statsSection)).thenReturn(updatedDate) + whenever(selectedDateProvider.getSelectedDate(statsGranularity)).thenReturn(updatedDate) dateSelector.updateDateSelector() Assertions.assertThat(model?.date).isEqualTo(updatedLabel) } - - @Test - fun `verify date selector hidden for insights`() { - whenever(selectedDateProvider.granularSelectedDateChanged(StatsSection.INSIGHTS)).thenReturn( - dateProviderSelectedDate - ) - dateSelector = StatsDateSelector( - selectedDateProvider, - statsDateFormatter, - siteProvider, - statsTrafficTabFeatureConfig, - StatsSection.INSIGHTS - ) - var model: DateSelectorUiModel? = null - dateSelector.dateSelectorData.observeForever { model = it } - - dateSelector.updateDateSelector() - - Assertions.assertThat(model).isNotNull - Assertions.assertThat(model?.isVisible).isFalse() - } } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCaseTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCaseTest.kt index 260266fd77dd..22bddae81009 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCaseTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/stats/refresh/lists/sections/insights/usecases/AnnualSiteStatsUseCaseTest.kt @@ -13,12 +13,12 @@ import org.wordpress.android.R import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.model.stats.YearsInsightsModel import org.wordpress.android.fluxc.model.stats.YearsInsightsModel.YearInsights +import org.wordpress.android.fluxc.network.utils.StatsGranularity import org.wordpress.android.fluxc.store.StatsStore.OnStatsFetched import org.wordpress.android.fluxc.store.StatsStore.StatsError import org.wordpress.android.fluxc.store.StatsStore.StatsErrorType.GENERIC_ERROR import org.wordpress.android.fluxc.store.stats.insights.MostPopularInsightsStore import org.wordpress.android.ui.stats.refresh.NavigationTarget -import org.wordpress.android.ui.stats.refresh.lists.StatsListViewModel.StatsSection.ANNUAL_STATS import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.UseCaseMode.BLOCK import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.UseCaseMode.VIEW_ALL import org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase.UseCaseModel @@ -107,7 +107,11 @@ class AnnualSiteStatsUseCaseTest : BaseUnitTest() { selectedDate.set(Calendar.YEAR, 2019) selectedDate.set(Calendar.MONTH, Calendar.DECEMBER) selectedDate.set(Calendar.DAY_OF_MONTH, 31) - verify(selectedDateProvider, times(1)).selectDate(selectedDate.time, listOf(selectedDate.time), ANNUAL_STATS) + verify(selectedDateProvider, times(1)).selectDate( + selectedDate.time, + listOf(selectedDate.time), + StatsGranularity.YEARS + ) } @Test