From 2784f274ec4320758b99030a8f5c0db0b7595d37 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 12 May 2026 13:24:58 +0000 Subject: [PATCH] fix(home): clear the Home tab dot when the only enabled tab is read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Home bottom-bar new-items dot was hardcoded to compare HomeFollows lastRead against the homeNewThreads feed. Each home tab writes to its own routeForLastRead (HomeFollows, HomeFollowsReplies, HomeFollowsEverything), so a user who only enabled the Everything tab could never clear the dot — reading items only advanced HomeFollowsEverything while the dot stayed lit on the untouched HomeFollows route. Recompute homeHasNewItems across all three (route, feed) pairs and gate each arm by its uiSettingsFlow toggle, so the dot reflects the state of whichever tabs the user has enabled. --- .../ui/screen/loggedIn/AccountViewModel.kt | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index af02c9f5d..7d16847a7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -159,6 +159,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -397,10 +398,13 @@ class AccountViewModel( .stateIn(viewModelScope, SharingStarted.WhileSubscribed(30000), false) @OptIn(ExperimentalCoroutinesApi::class) - val homeHasNewItems = + private fun tabHasNewItems( + route: String, + feedContent: StateFlow, + ): Flow = combineTransform( - account.loadLastReadFlow("HomeFollows"), - feedStates.homeNewThreads.feedContent + account.loadLastReadFlow(route), + feedContent .flatMapLatest { if (it is FeedState.Loaded) { it.feed @@ -412,15 +416,31 @@ class AccountViewModel( }, ) { lastRead, newestItemCreatedAt -> emit(newestItemCreatedAt != null && newestItemCreatedAt > lastRead) - }.onStart { - val lastRead = account.loadLastReadFlow("HomeFollows").value - val feed = feedStates.homeNewThreads.feedContent.value - if (feed is FeedState.Loaded) { - val newestItemCreatedAt = - feed.feed.value.list - .firstOrNull { it.event != null && it.event !is GenericRepostEvent && it.event !is RepostEvent } - ?.createdAt() - emit(newestItemCreatedAt != null && newestItemCreatedAt > lastRead) + } + + val homeHasNewItems: Flow = + combine( + settings.uiSettingsFlow.showHomeNewThreadsTab, + settings.uiSettingsFlow.showHomeConversationsTab, + settings.uiSettingsFlow.showHomeEverythingTab, + tabHasNewItems("HomeFollows", feedStates.homeNewThreads.feedContent), + tabHasNewItems("HomeFollowsReplies", feedStates.homeReplies.feedContent), + tabHasNewItems("HomeFollowsEverything", feedStates.homeEverything.feedContent), + ) { values -> + val showThreads = values[0] + val showReplies = values[1] + val showEverything = values[2] + val threadsHas = values[3] + val repliesHas = values[4] + val everythingHas = values[5] + val anyEnabled = showThreads || showReplies || showEverything + if (!anyEnabled) { + // HomeScreen falls back to the New Threads tab when the user disables every tab. + threadsHas + } else { + (showThreads && threadsHas) || + (showReplies && repliesHas) || + (showEverything && everythingHas) } }