From 4bc0e1106d0bdd27621137eda22d7ca3923ced80 Mon Sep 17 00:00:00 2001 From: williamrai Date: Thu, 11 Sep 2025 14:15:36 -0400 Subject: [PATCH 1/3] - adds new flow event for loading changes in activity tab timeline --- .../activitytab/ActivityTabFragment.kt | 35 +++++++++++++++++-- .../activitytab/ActivityTabViewModel.kt | 14 +++++++- .../timeline/TimelineRepository.kt | 2 +- .../org/wikipedia/concurrency/FlowEventBus.kt | 19 +++++++++- .../diff/ArticleEditDetailsFragment.kt | 3 ++ .../wikipedia/page/PageFragmentLoadState.kt | 4 +++ 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt b/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt index 396caa43938..91b262f7f7a 100644 --- a/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt +++ b/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt @@ -84,6 +84,7 @@ import org.wikipedia.compose.components.error.WikiErrorClickEvents import org.wikipedia.compose.extensions.shimmerEffect import org.wikipedia.compose.theme.BaseTheme import org.wikipedia.compose.theme.WikipediaTheme +import org.wikipedia.concurrency.ActivityTabEventBus import org.wikipedia.concurrency.FlowEventBus import org.wikipedia.dataclient.WikiSite import org.wikipedia.dataclient.growthtasks.GrowthUserImpact @@ -136,6 +137,35 @@ class ActivityTabFragment : Fragment() { } } } + + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + ActivityTabEventBus.events.collectLatest { event -> + println("orange ActivityTabEventBus event --> $event") + when (event) { + ActivityTabUpdateEvent.ReadingHistoryChanged -> { + println("orange ReadingHistoryChanged") + viewModel.loadReadingHistory() + viewModel.shouldRefreshTimelineSilently = true + viewModel.refreshTimeline() + } + ActivityTabUpdateEvent.DonationsChanged -> { + println("orange DonationsChanged") + viewModel.loadDonationResults() + } + ActivityTabUpdateEvent.GamesChanged -> { + println("orange GamesChanged") + viewModel.loadWikiGamesStats() + } + ActivityTabUpdateEvent.ImpactChanged -> { + println("orange ImpactChanged") + viewModel.loadImpact() + } + } + } + } + } + viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { viewModel.allDataLoaded.collectLatest { @@ -175,13 +205,14 @@ class ActivityTabFragment : Fragment() { override fun onResume() { super.onResume() + println("orange onResume") requireActivity().addMenuProvider(menuProvider, viewLifecycleOwner) - viewModel.loadAll() requireActivity().invalidateOptionsMenu() } override fun onPause() { super.onPause() + println("orange onPause") requireActivity().removeMenuProvider(menuProvider) } @@ -540,7 +571,7 @@ class ActivityTabFragment : Fragment() { val isRefreshing = timelineItems.loadState.refresh is LoadState.Loading val isEmpty = timelineItems.itemCount == 0 when { - isRefreshing -> { + isRefreshing && !viewModel.shouldRefreshTimelineSilently -> { item { ActivityTabShimmerView() } diff --git a/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt b/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt index 82767a69920..4f8b795a717 100644 --- a/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt +++ b/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt @@ -69,6 +69,7 @@ class ActivityTabViewModel() : ViewModel() { else -> WikiSite.forLanguageCode(langCode) } } + var shouldRefreshTimelineSilently = false val timelineFlow = Pager( config = PagingConfig( @@ -110,6 +111,10 @@ class ActivityTabViewModel() : ViewModel() { impact !is UiState.Loading }.stateIn(viewModelScope, SharingStarted.Lazily, false) + init { + loadAll() + } + fun loadAll() { loadReadingHistory() if (!AccountUtil.isLoggedIn) { @@ -121,7 +126,7 @@ class ActivityTabViewModel() : ViewModel() { refreshTimeline() } - private fun refreshTimeline() { + fun refreshTimeline() { currentTimelinePagingSource?.invalidate() } @@ -320,3 +325,10 @@ sealed class TimelineDisplayItem { data class DateSeparator(val date: Date) : TimelineDisplayItem() data class TimelineEntry(val item: TimelineItem) : TimelineDisplayItem() } + +sealed class ActivityTabUpdateEvent { + object ReadingHistoryChanged : ActivityTabUpdateEvent() + object ImpactChanged : ActivityTabUpdateEvent() + object DonationsChanged : ActivityTabUpdateEvent() + object GamesChanged : ActivityTabUpdateEvent() +} diff --git a/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt b/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt index 52ae080281f..da91ca07fc9 100644 --- a/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt +++ b/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt @@ -64,7 +64,7 @@ class UserContribPagingSource( override suspend fun fetch(pageSize: Int, cursor: Cursor?): Pair, Cursor?> { val token = (cursor as? Cursor.UserContribCursor)?.token val service = ServiceFactory.get(wikiSite) - val userContribResponse = service.getUserContrib(username = userName, maxCount = pageSize, ns = null, filter = null, uccontinue = token, ucdir = "older") + val userContribResponse = service.getUserContrib(username = "Cooltey", maxCount = pageSize, ns = null, filter = null, uccontinue = token, ucdir = "older") val missingPageInfoIds = mutableListOf() val timelineItemsByPageId = mutableMapOf() diff --git a/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt b/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt index 1695f432e95..d1a721fd321 100644 --- a/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt +++ b/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt @@ -3,11 +3,12 @@ package org.wikipedia.concurrency import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow +import org.wikipedia.activitytab.ActivityTabUpdateEvent import org.wikipedia.util.log.L object FlowEventBus { - private val _events = MutableSharedFlow(extraBufferCapacity = 8, onBufferOverflow = BufferOverflow.DROP_OLDEST) + private val _events = MutableSharedFlow(replay = 1, extraBufferCapacity = 8, onBufferOverflow = BufferOverflow.DROP_OLDEST) val events = _events.asSharedFlow() fun post(event: Any) { @@ -16,3 +17,19 @@ object FlowEventBus { } } } + +object ActivityTabEventBus { + private val _events = MutableSharedFlow( + replay = 1, + extraBufferCapacity = 8, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + val events = _events.asSharedFlow() + + fun post(event: ActivityTabUpdateEvent) { + println("orange ActivityTabEventBus post event $event") + if (!_events.tryEmit(event)) { + _events.tryEmit(event) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt index 7261e69340f..25cbd02aca8 100644 --- a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt +++ b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt @@ -31,10 +31,13 @@ import org.wikipedia.Constants import org.wikipedia.Constants.InvokeSource import org.wikipedia.R import org.wikipedia.activity.FragmentUtil +import org.wikipedia.activitytab.ActivityTabUpdateEvent import org.wikipedia.analytics.eventplatform.EditAttemptStepEvent import org.wikipedia.analytics.eventplatform.PatrollerExperienceEvent import org.wikipedia.auth.AccountUtil import org.wikipedia.commons.FilePageActivity +import org.wikipedia.concurrency.ActivityTabEventBus +import org.wikipedia.concurrency.FlowEventBus import org.wikipedia.databinding.FragmentArticleEditDetailsBinding import org.wikipedia.dataclient.mwapi.MwQueryPage.Revision import org.wikipedia.dataclient.okhttp.HttpStatusException diff --git a/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt b/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt index 40e93e7f658..6b6eb5b5b3b 100644 --- a/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt +++ b/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt @@ -8,12 +8,15 @@ import kotlinx.coroutines.async import kotlinx.coroutines.launch import org.wikipedia.R import org.wikipedia.WikipediaApp +import org.wikipedia.activitytab.ActivityTabUpdateEvent import org.wikipedia.analytics.eventplatform.ArticleLinkPreviewInteractionEvent import org.wikipedia.analytics.metricsplatform.ArticleLinkPreviewInteraction import org.wikipedia.auth.AccountUtil import org.wikipedia.bridge.CommunicationBridge import org.wikipedia.bridge.JavaScriptActionHandler import org.wikipedia.categories.db.Category +import org.wikipedia.concurrency.ActivityTabEventBus +import org.wikipedia.concurrency.FlowEventBus import org.wikipedia.database.AppDatabase import org.wikipedia.dataclient.ServiceFactory import org.wikipedia.dataclient.mwapi.MwQueryResponse @@ -287,6 +290,7 @@ class PageFragmentLoadState(private var model: PageViewModel, WikipediaApp.instance.appSessionEvent.pageViewed(entry) ArticleLinkPreviewInteractionEvent(title.wikiSite.dbName(), pageSummary?.pageId ?: 0, entry.source).logNavigate() ArticleLinkPreviewInteraction(fragment, entry.source).logNavigate() + ActivityTabEventBus.post(ActivityTabUpdateEvent.ReadingHistoryChanged) } } } From f2c30e9fe91857e3463502e7ad08d3f4f9e33bfd Mon Sep 17 00:00:00 2001 From: williamrai Date: Thu, 11 Sep 2025 16:26:16 -0400 Subject: [PATCH 2/3] - code fixes --- .../activitytab/ActivityTabFragment.kt | 21 +++++++---------- .../activitytab/ActivityTabViewModel.kt | 7 ------ .../org/wikipedia/concurrency/FlowEventBus.kt | 23 ++++++++++--------- .../diff/ArticleEditDetailsFragment.kt | 3 --- .../wikipedia/page/PageFragmentLoadState.kt | 7 +++--- 5 files changed, 23 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt b/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt index 91b262f7f7a..c6e1810c30b 100644 --- a/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt +++ b/app/src/main/java/org/wikipedia/activitytab/ActivityTabFragment.kt @@ -84,7 +84,8 @@ import org.wikipedia.compose.components.error.WikiErrorClickEvents import org.wikipedia.compose.extensions.shimmerEffect import org.wikipedia.compose.theme.BaseTheme import org.wikipedia.compose.theme.WikipediaTheme -import org.wikipedia.concurrency.ActivityTabEventBus +import org.wikipedia.concurrency.AppEvent +import org.wikipedia.concurrency.AppEventBus import org.wikipedia.concurrency.FlowEventBus import org.wikipedia.dataclient.WikiSite import org.wikipedia.dataclient.growthtasks.GrowthUserImpact @@ -140,25 +141,21 @@ class ActivityTabFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { - ActivityTabEventBus.events.collectLatest { event -> - println("orange ActivityTabEventBus event --> $event") + AppEventBus.events.collectLatest { event -> + println("orange event $event") when (event) { - ActivityTabUpdateEvent.ReadingHistoryChanged -> { - println("orange ReadingHistoryChanged") + AppEvent.ReadingHistoryChanged -> { viewModel.loadReadingHistory() viewModel.shouldRefreshTimelineSilently = true viewModel.refreshTimeline() } - ActivityTabUpdateEvent.DonationsChanged -> { - println("orange DonationsChanged") + AppEvent.DonationsChanged -> { viewModel.loadDonationResults() } - ActivityTabUpdateEvent.GamesChanged -> { - println("orange GamesChanged") + AppEvent.GamesChanged -> { viewModel.loadWikiGamesStats() } - ActivityTabUpdateEvent.ImpactChanged -> { - println("orange ImpactChanged") + AppEvent.ImpactChanged -> { viewModel.loadImpact() } } @@ -205,14 +202,12 @@ class ActivityTabFragment : Fragment() { override fun onResume() { super.onResume() - println("orange onResume") requireActivity().addMenuProvider(menuProvider, viewLifecycleOwner) requireActivity().invalidateOptionsMenu() } override fun onPause() { super.onPause() - println("orange onPause") requireActivity().removeMenuProvider(menuProvider) } diff --git a/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt b/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt index 4f8b795a717..37b9399ca8e 100644 --- a/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt +++ b/app/src/main/java/org/wikipedia/activitytab/ActivityTabViewModel.kt @@ -325,10 +325,3 @@ sealed class TimelineDisplayItem { data class DateSeparator(val date: Date) : TimelineDisplayItem() data class TimelineEntry(val item: TimelineItem) : TimelineDisplayItem() } - -sealed class ActivityTabUpdateEvent { - object ReadingHistoryChanged : ActivityTabUpdateEvent() - object ImpactChanged : ActivityTabUpdateEvent() - object DonationsChanged : ActivityTabUpdateEvent() - object GamesChanged : ActivityTabUpdateEvent() -} diff --git a/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt b/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt index d1a721fd321..b270c2ee800 100644 --- a/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt +++ b/app/src/main/java/org/wikipedia/concurrency/FlowEventBus.kt @@ -3,12 +3,11 @@ package org.wikipedia.concurrency import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow -import org.wikipedia.activitytab.ActivityTabUpdateEvent import org.wikipedia.util.log.L object FlowEventBus { - private val _events = MutableSharedFlow(replay = 1, extraBufferCapacity = 8, onBufferOverflow = BufferOverflow.DROP_OLDEST) + private val _events = MutableSharedFlow(extraBufferCapacity = 8, onBufferOverflow = BufferOverflow.DROP_OLDEST) val events = _events.asSharedFlow() fun post(event: Any) { @@ -18,18 +17,20 @@ object FlowEventBus { } } -object ActivityTabEventBus { - private val _events = MutableSharedFlow( - replay = 1, - extraBufferCapacity = 8, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) +object AppEventBus { + private val _events = MutableSharedFlow(replay = 1, extraBufferCapacity = 8, onBufferOverflow = BufferOverflow.DROP_OLDEST) val events = _events.asSharedFlow() - fun post(event: ActivityTabUpdateEvent) { - println("orange ActivityTabEventBus post event $event") + fun post(event: AppEvent) { if (!_events.tryEmit(event)) { _events.tryEmit(event) } } -} \ No newline at end of file +} + +sealed class AppEvent { + object ReadingHistoryChanged : AppEvent() + object ImpactChanged : AppEvent() + object DonationsChanged : AppEvent() + object GamesChanged : AppEvent() +} diff --git a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt index 25cbd02aca8..7261e69340f 100644 --- a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt +++ b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt @@ -31,13 +31,10 @@ import org.wikipedia.Constants import org.wikipedia.Constants.InvokeSource import org.wikipedia.R import org.wikipedia.activity.FragmentUtil -import org.wikipedia.activitytab.ActivityTabUpdateEvent import org.wikipedia.analytics.eventplatform.EditAttemptStepEvent import org.wikipedia.analytics.eventplatform.PatrollerExperienceEvent import org.wikipedia.auth.AccountUtil import org.wikipedia.commons.FilePageActivity -import org.wikipedia.concurrency.ActivityTabEventBus -import org.wikipedia.concurrency.FlowEventBus import org.wikipedia.databinding.FragmentArticleEditDetailsBinding import org.wikipedia.dataclient.mwapi.MwQueryPage.Revision import org.wikipedia.dataclient.okhttp.HttpStatusException diff --git a/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt b/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt index 6b6eb5b5b3b..c9488b688a1 100644 --- a/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt +++ b/app/src/main/java/org/wikipedia/page/PageFragmentLoadState.kt @@ -8,15 +8,14 @@ import kotlinx.coroutines.async import kotlinx.coroutines.launch import org.wikipedia.R import org.wikipedia.WikipediaApp -import org.wikipedia.activitytab.ActivityTabUpdateEvent import org.wikipedia.analytics.eventplatform.ArticleLinkPreviewInteractionEvent import org.wikipedia.analytics.metricsplatform.ArticleLinkPreviewInteraction import org.wikipedia.auth.AccountUtil import org.wikipedia.bridge.CommunicationBridge import org.wikipedia.bridge.JavaScriptActionHandler import org.wikipedia.categories.db.Category -import org.wikipedia.concurrency.ActivityTabEventBus -import org.wikipedia.concurrency.FlowEventBus +import org.wikipedia.concurrency.AppEvent +import org.wikipedia.concurrency.AppEventBus import org.wikipedia.database.AppDatabase import org.wikipedia.dataclient.ServiceFactory import org.wikipedia.dataclient.mwapi.MwQueryResponse @@ -290,7 +289,7 @@ class PageFragmentLoadState(private var model: PageViewModel, WikipediaApp.instance.appSessionEvent.pageViewed(entry) ArticleLinkPreviewInteractionEvent(title.wikiSite.dbName(), pageSummary?.pageId ?: 0, entry.source).logNavigate() ArticleLinkPreviewInteraction(fragment, entry.source).logNavigate() - ActivityTabEventBus.post(ActivityTabUpdateEvent.ReadingHistoryChanged) + AppEventBus.post(AppEvent.ReadingHistoryChanged) } } } From e3dffeafd7efd601b58d8675705a078e2c7a7d08 Mon Sep 17 00:00:00 2001 From: williamrai Date: Thu, 11 Sep 2025 16:47:45 -0400 Subject: [PATCH 3/3] - code fixes --- .../org/wikipedia/activitytab/timeline/TimelineRepository.kt | 2 +- .../java/org/wikipedia/readinglist/ReadingListBehaviorsUtil.kt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt b/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt index da91ca07fc9..52ae080281f 100644 --- a/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt +++ b/app/src/main/java/org/wikipedia/activitytab/timeline/TimelineRepository.kt @@ -64,7 +64,7 @@ class UserContribPagingSource( override suspend fun fetch(pageSize: Int, cursor: Cursor?): Pair, Cursor?> { val token = (cursor as? Cursor.UserContribCursor)?.token val service = ServiceFactory.get(wikiSite) - val userContribResponse = service.getUserContrib(username = "Cooltey", maxCount = pageSize, ns = null, filter = null, uccontinue = token, ucdir = "older") + val userContribResponse = service.getUserContrib(username = userName, maxCount = pageSize, ns = null, filter = null, uccontinue = token, ucdir = "older") val missingPageInfoIds = mutableListOf() val timelineItemsByPageId = mutableMapOf() diff --git a/app/src/main/java/org/wikipedia/readinglist/ReadingListBehaviorsUtil.kt b/app/src/main/java/org/wikipedia/readinglist/ReadingListBehaviorsUtil.kt index 78551e3cad5..5923ba7d34e 100644 --- a/app/src/main/java/org/wikipedia/readinglist/ReadingListBehaviorsUtil.kt +++ b/app/src/main/java/org/wikipedia/readinglist/ReadingListBehaviorsUtil.kt @@ -16,6 +16,8 @@ import kotlinx.coroutines.withContext import org.apache.commons.lang3.StringUtils import org.wikipedia.Constants.InvokeSource import org.wikipedia.R +import org.wikipedia.concurrency.AppEvent +import org.wikipedia.concurrency.AppEventBus import org.wikipedia.database.AppDatabase import org.wikipedia.dataclient.ServiceFactory import org.wikipedia.extensions.isStarted @@ -379,6 +381,7 @@ object ReadingListBehaviorsUtil { } else { FeedbackUtil.showMessage(activity, activity.getString(R.string.reading_list_article_already_exists_message, defaultList.title, title.displayText)) } + AppEventBus.post(AppEvent.ReadingHistoryChanged) } } else { ExclusiveBottomSheetPresenter.show((activity as AppCompatActivity).supportFragmentManager,