fix(home): clear the Home tab dot when the only enabled tab is read

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.
This commit is contained in:
Claude
2026-05-12 13:24:58 +00:00
parent abd565a460
commit 2784f274ec
@@ -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<FeedState>,
): Flow<Boolean> =
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<Boolean> =
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)
}
}