Merge pull request #2591 from vitorpamplona/claude/audit-feedfilterspinner-GHhgH

Refactor FeedFilterSpinner to pass FeedDefinition objects instead of indices
This commit is contained in:
Vitor Pamplona
2026-04-26 15:16:33 -04:00
committed by GitHub
20 changed files with 106 additions and 157 deletions
@@ -35,6 +35,7 @@ import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
import com.vitorpamplona.quartz.nip51Lists.interestSet.InterestSetEvent
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.relayLists.BroadcastRelayListEvent import com.vitorpamplona.quartz.nip51Lists.relayLists.BroadcastRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
@@ -73,6 +74,7 @@ val AccountInfoAndListsFromKeyKinds2 =
TrustProviderListEvent.KIND, TrustProviderListEvent.KIND,
PaymentTargetsEvent.KIND, PaymentTargetsEvent.KIND,
RelayFeedsListEvent.KIND, RelayFeedsListEvent.KIND,
InterestSetEvent.KIND,
) )
val AmethystMetadataKinds = listOf(AppSpecificDataEvent.KIND) val AmethystMetadataKinds = listOf(AppSpecificDataEvent.KIND)
@@ -102,7 +104,7 @@ fun filterAccountInfoAndListsFromKey(
Filter( Filter(
kinds = AccountInfoAndListsFromKeyKinds2, kinds = AccountInfoAndListsFromKeyKinds2,
authors = listOf(pubkey), authors = listOf(pubkey),
limit = 20, limit = 80,
since = since, since = since,
), ),
), ),
@@ -31,6 +31,7 @@ import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
import com.vitorpamplona.quartz.nip51Lists.interestSet.InterestSetEvent
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.relayLists.BroadcastRelayListEvent import com.vitorpamplona.quartz.nip51Lists.relayLists.BroadcastRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
@@ -65,6 +66,7 @@ val BasicAccountInfoKinds2 =
GeohashListEvent.KIND, GeohashListEvent.KIND,
TrustProviderListEvent.KIND, TrustProviderListEvent.KIND,
RelayFeedsListEvent.KIND, RelayFeedsListEvent.KIND,
InterestSetEvent.KIND,
) )
fun filterBasicAccountInfoFromKeys( fun filterBasicAccountInfoFromKeys(
@@ -34,15 +34,14 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@@ -69,7 +68,6 @@ import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.model.TopFilter import com.vitorpamplona.amethyst.model.TopFilter
import com.vitorpamplona.amethyst.service.location.LocationState import com.vitorpamplona.amethyst.service.location.LocationState
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote
@@ -92,10 +90,6 @@ import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@OptIn(ExperimentalPermissionsApi::class) @OptIn(ExperimentalPermissionsApi::class)
@@ -104,32 +98,27 @@ fun FeedFilterSpinner(
placeholderCode: TopFilter, placeholderCode: TopFilter,
explainer: String, explainer: String,
options: ImmutableList<FeedDefinition>, options: ImmutableList<FeedDefinition>,
onSelect: (Int) -> Unit, onSelect: (FeedDefinition) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
var optionsShowing by remember { mutableStateOf(false) } var optionsShowing by remember { mutableStateOf(false) }
val context = LocalContext.current val context = LocalContext.current
val selectAnOption = val selectAnOption = stringRes(id = R.string.select_an_option)
stringRes(
id = R.string.select_an_option,
)
var selected by val selected =
remember(placeholderCode, options) { remember(placeholderCode, options) {
mutableStateOf( // Match by both subclass and code string to avoid collisions between
options.firstOrNull { it.code.code == placeholderCode.code }, // TopFilter variants that derive `code` from the same Address (e.g.
) // PeopleList vs MuteList).
} options.firstOrNull {
it.code::class == placeholderCode::class && it.code.code == placeholderCode.code
val currentText by
remember(placeholderCode, options) {
derivedStateOf {
selected?.name?.name(context) ?: selectAnOption
} }
} }
val currentText = selected?.name?.name(context) ?: selectAnOption
val accessibilityDescription = val accessibilityDescription =
if (selected != null) { if (selected != null) {
stringRes(R.string.feed_filter_selected, currentText) stringRes(R.string.feed_filter_selected, currentText)
@@ -282,10 +271,9 @@ fun FeedFilterSpinner(
title = explainer, title = explainer,
options = options, options = options,
onDismiss = { optionsShowing = false }, onDismiss = { optionsShowing = false },
onSelect = { onSelect = { definition ->
selected = options[it]
optionsShowing = false optionsShowing = false
onSelect(it) onSelect(definition)
}, },
) { ) {
RenderOption(it.name, accountViewModel) RenderOption(it.name, accountViewModel)
@@ -298,6 +286,7 @@ fun RenderOption(
option: Name, option: Name,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
val context = LocalContext.current
when (option) { when (option) {
is GeoHashName -> { is GeoHashName -> {
LoadCityName(option.geoHashTag) { LoadCityName(option.geoHashTag) {
@@ -305,74 +294,35 @@ fun RenderOption(
} }
} }
is HashtagName -> { // Note-backed names: subscribe to the note so the displayed title updates as
Text(text = option.name(), fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface) // the corresponding event arrives from relays. The displayed string itself is
} // produced by Name.name(), which already has the right precedence rules.
is ResourceName -> {
Text(
text = stringRes(id = option.resourceId),
fontSize = Font14SP,
color = MaterialTheme.colorScheme.onSurface,
)
}
is PeopleListName -> { is PeopleListName -> {
val noteState by observeNote(option.note, accountViewModel) val noteState by observeNote(option.note, accountViewModel)
val name = remember(noteState) { option.name(context) }
val noteEvent = noteState.note.event
val name =
when (noteEvent) {
is PeopleListEvent -> {
noteEvent.titleOrName() ?: option.note.dTag()
}
is FollowListEvent -> {
noteEvent.title() ?: option.note.dTag()
}
else -> {
option.note.dTag()
}
}
Text(text = name, fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface) Text(text = name, fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface)
} }
is CommunityName -> { is CommunityName -> {
val it by observeNote(option.note, accountViewModel) val noteState by observeNote(option.note, accountViewModel)
val name = remember(noteState) { option.name(context) }
val addressable = it.note as? AddressableNote Text(text = name, fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface)
val definition = addressable?.event as? CommunityDefinitionEvent
val label = definition?.name()?.ifBlank { null } ?: addressable?.dTag() ?: ""
Text(text = "/n/$label", fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface)
}
is RelayName -> {
Text(
text = option.name(),
fontSize = Font14SP,
color = MaterialTheme.colorScheme.onSurface,
)
} }
is FavoriteAlgoFeedName -> { is FavoriteAlgoFeedName -> {
val noteState by observeNote(option.note, accountViewModel) val noteState by observeNote(option.note, accountViewModel)
val name = val name = remember(noteState) { option.name(context) }
(noteState.note.event as? AppDefinitionEvent) Text(text = name, fontSize = Font14SP, color = MaterialTheme.colorScheme.onSurface)
?.appMetaData()
?.name
?.takeIf { it.isNotBlank() } ?: option.note.dTag()
Text(
text = name,
fontSize = Font14SP,
color = MaterialTheme.colorScheme.onSurface,
)
} }
is InterestSetName -> { // Pure names: no relay subscription needed.
is HashtagName,
is ResourceName,
is RelayName,
is InterestSetName,
-> {
Text( Text(
text = option.name(), text = option.name(context),
fontSize = Font14SP, fontSize = Font14SP,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
) )
@@ -380,12 +330,6 @@ fun RenderOption(
} }
} }
@Immutable
private data class IndexedFeedDefinition(
val originalIndex: Int,
val item: FeedDefinition,
)
private enum class FeedGroup( private enum class FeedGroup(
@param:androidx.annotation.StringRes val labelRes: Int, @param:androidx.annotation.StringRes val labelRes: Int,
) { ) {
@@ -399,48 +343,51 @@ private enum class FeedGroup(
RELAYS(R.string.feed_group_relays), RELAYS(R.string.feed_group_relays),
} }
private fun groupFeedDefinitions(options: ImmutableList<FeedDefinition>): Map<FeedGroup, List<IndexedFeedDefinition>> { private fun FeedDefinition.group(): FeedGroup =
val indexed = options.mapIndexed { index, item -> IndexedFeedDefinition(index, item) } when (name) {
return indexed.groupBy { entry -> is HashtagName -> {
when (entry.item.name) { FeedGroup.HASHTAGS
is HashtagName -> { }
FeedGroup.HASHTAGS
}
is CommunityName -> { is CommunityName -> {
FeedGroup.COMMUNITIES FeedGroup.COMMUNITIES
} }
is PeopleListName -> { is PeopleListName -> {
FeedGroup.LISTS FeedGroup.LISTS
} }
is RelayName -> { is RelayName -> {
FeedGroup.RELAYS FeedGroup.RELAYS
} }
is GeoHashName -> { is GeoHashName -> {
FeedGroup.LOCATIONS FeedGroup.LOCATIONS
} }
is FavoriteAlgoFeedName -> { is FavoriteAlgoFeedName -> {
FeedGroup.DVMS FeedGroup.DVMS
} }
is InterestSetName -> { is InterestSetName -> {
FeedGroup.INTEREST_SETS FeedGroup.INTEREST_SETS
} }
is ResourceName -> { is ResourceName -> {
when (entry.item.code) { when (code) {
is TopFilter.AroundMe -> FeedGroup.LOCATIONS is TopFilter.AroundMe -> FeedGroup.LOCATIONS
is TopFilter.Global -> FeedGroup.RELAYS is TopFilter.Global -> FeedGroup.RELAYS
is TopFilter.AllFavoriteAlgoFeeds -> FeedGroup.DVMS is TopFilter.AllFavoriteAlgoFeeds -> FeedGroup.DVMS
else -> FeedGroup.FEEDS else -> FeedGroup.FEEDS
}
} }
} }
} }
private fun groupFeedDefinitions(options: ImmutableList<FeedDefinition>): List<Pair<FeedGroup, List<FeedDefinition>>> {
val grouped = options.groupBy { it.group() }
return FeedGroup.entries.mapNotNull { group ->
grouped[group]?.takeIf { it.isNotEmpty() }?.let { group to it }
}
} }
@OptIn(ExperimentalLayoutApi::class) @OptIn(ExperimentalLayoutApi::class)
@@ -448,7 +395,7 @@ private fun groupFeedDefinitions(options: ImmutableList<FeedDefinition>): Map<Fe
private fun GroupedFeedFilterDialog( private fun GroupedFeedFilterDialog(
title: String, title: String,
options: ImmutableList<FeedDefinition>, options: ImmutableList<FeedDefinition>,
onSelect: (Int) -> Unit, onSelect: (FeedDefinition) -> Unit,
onDismiss: () -> Unit, onDismiss: () -> Unit,
onRenderItem: @Composable (FeedDefinition) -> Unit, onRenderItem: @Composable (FeedDefinition) -> Unit,
) { ) {
@@ -472,18 +419,15 @@ private fun GroupedFeedFilterDialog(
) )
} }
FeedGroup.entries.forEach { group -> grouped.forEach { (group, items) ->
val items = grouped[group] item(key = group) {
if (!items.isNullOrEmpty()) { GroupSection(
item { label = stringRes(group.labelRes),
GroupSection( items = items,
label = stringRes(group.labelRes), isChipLayout = group == FeedGroup.HASHTAGS,
items = items, onSelect = onSelect,
isChipLayout = group == FeedGroup.HASHTAGS, onRenderItem = onRenderItem,
onSelect = onSelect, )
onRenderItem = onRenderItem,
)
}
} }
} }
} }
@@ -495,11 +439,12 @@ private fun GroupedFeedFilterDialog(
@Composable @Composable
private fun GroupSection( private fun GroupSection(
label: String, label: String,
items: List<IndexedFeedDefinition>, items: List<FeedDefinition>,
isChipLayout: Boolean, isChipLayout: Boolean,
onSelect: (Int) -> Unit, onSelect: (FeedDefinition) -> Unit,
onRenderItem: @Composable (FeedDefinition) -> Unit, onRenderItem: @Composable (FeedDefinition) -> Unit,
) { ) {
val context = LocalContext.current
Surface( Surface(
modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp),
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
@@ -523,13 +468,13 @@ private fun GroupSection(
) { ) {
items.forEach { entry -> items.forEach { entry ->
Surface( Surface(
modifier = Modifier.clickable { onSelect(entry.originalIndex) }, modifier = Modifier.clickable { onSelect(entry) },
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline), border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline),
color = Color.Transparent, color = Color.Transparent,
) { ) {
Text( Text(
text = entry.item.name.name(), text = entry.name.name(context),
fontSize = 13.sp, fontSize = 13.sp,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.padding(horizontal = 14.dp, vertical = 7.dp), modifier = Modifier.padding(horizontal = 14.dp, vertical = 7.dp),
@@ -545,15 +490,15 @@ private fun GroupSection(
modifier = modifier =
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { onSelect(entry.originalIndex) } .clickable { onSelect(entry) }
.padding(horizontal = 16.dp, vertical = 6.dp), .padding(horizontal = 16.dp, vertical = 6.dp),
) { ) {
FeedIcon( FeedIcon(
item = entry.item, item = entry,
modifier = Size20Modifier, modifier = Size20Modifier,
) )
Spacer(modifier = Modifier.padding(start = 12.dp)) Spacer(modifier = Modifier.width(12.dp))
Column(modifier = Modifier.weight(1f)) { onRenderItem(entry.item) } Column(modifier = Modifier.weight(1f)) { onRenderItem(entry) }
} }
} }
} }
@@ -64,7 +64,7 @@ private fun ArticlesTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun AudioRoomsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun BadgesTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun CommunitiesTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun TopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun BrowseEmojiSetsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun FollowPacksTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -69,7 +69,7 @@ private fun TopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun LiveStreamsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun LongsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun TopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun PicturesTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun PollsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun ProductsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun PublicChatsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -64,7 +64,7 @@ private fun ShortsTopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }
@@ -65,7 +65,7 @@ private fun TopNavFilterBar(
placeholderCode = listName, placeholderCode = listName,
explainer = stringRes(R.string.select_list_to_filter), explainer = stringRes(R.string.select_list_to_filter),
options = allLists, options = allLists,
onSelect = { onChange(allLists.getOrNull(it) ?: followListsModel.allFollows) }, onSelect = onChange,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) )
} }