mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 08:27:04 +00:00
refactor: render pinned followed chats as a separate LazyColumn section
Instead of sorting followed chats to the top of the existing feed (which
hides them when the feed filter or TopFilter excludes them), render them
in a dedicated items{} block above the rest of the feed and skip them in
the main itemsIndexed{} block. This keeps the feed filter, feedKey, and
screen watchers untouched.
This commit is contained in:
+46
-13
@@ -23,14 +23,19 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.publicChats
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
@@ -47,30 +52,58 @@ fun PublicChatsFeedLoaded(
|
||||
nav: INav,
|
||||
) {
|
||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||
val followedSet by accountViewModel.account.publicChatList.flowSet
|
||||
.collectAsStateWithLifecycle()
|
||||
|
||||
val pinned =
|
||||
remember(followedSet) {
|
||||
followedSet.mapNotNull { idHex ->
|
||||
LocalCache.getNoteIfExists(idHex)?.takeIf { it.event is ChannelCreateEvent }
|
||||
}
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||
state = listState,
|
||||
) {
|
||||
items(
|
||||
pinned,
|
||||
key = { item -> "pinned-" + item.idHex },
|
||||
contentType = { item -> item.event?.kind ?: -1 },
|
||||
) { item ->
|
||||
PublicChatRow(item, accountViewModel, nav)
|
||||
}
|
||||
|
||||
itemsIndexed(
|
||||
items.list,
|
||||
key = { _, item -> item.idHex },
|
||||
contentType = { _, item -> item.event?.kind ?: -1 },
|
||||
) { _, item ->
|
||||
Row(Modifier.fillMaxWidth().animateItem()) {
|
||||
ChannelCardCompose(
|
||||
baseNote = item,
|
||||
routeForLastRead = "PublicChatsFeed",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
forceEventKind = ChannelCreateEvent.KIND,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
if (item.idHex !in followedSet) {
|
||||
PublicChatRow(item, accountViewModel, nav)
|
||||
}
|
||||
|
||||
HorizontalDivider(
|
||||
thickness = DividerThickness,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LazyItemScope.PublicChatRow(
|
||||
item: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
Row(Modifier.fillMaxWidth().animateItem()) {
|
||||
ChannelCardCompose(
|
||||
baseNote = item,
|
||||
routeForLastRead = "PublicChatsFeed",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
forceEventKind = ChannelCreateEvent.KIND,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
HorizontalDivider(
|
||||
thickness = DividerThickness,
|
||||
)
|
||||
}
|
||||
|
||||
+1
-3
@@ -106,10 +106,8 @@ fun WatchAccountForPublicChatsScreen(
|
||||
val hiddenUsers =
|
||||
accountViewModel.account.hiddenUsers.flow
|
||||
.collectAsStateWithLifecycle()
|
||||
val followedChats by accountViewModel.account.publicChatList.flowSet
|
||||
.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(accountViewModel, listState, hiddenUsers, followedChats) {
|
||||
LaunchedEffect(accountViewModel, listState, hiddenUsers) {
|
||||
publicChatsFeedState.checkKeysInvalidateDataAndSendToTop()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-8
@@ -32,10 +32,7 @@ import com.vitorpamplona.quartz.nip28PublicChat.base.IsInPublicChatChannel
|
||||
class PublicChatsFeedFilter(
|
||||
val account: Account,
|
||||
) : AdditiveFeedFilter<Note>() {
|
||||
override fun feedKey(): String =
|
||||
account.userProfile().pubkeyHex + "-" + followList().code + "-" +
|
||||
account.publicChatList.flowSet.value
|
||||
.hashCode()
|
||||
override fun feedKey(): String = account.userProfile().pubkeyHex + "-" + followList().code
|
||||
|
||||
override fun limit() = 200
|
||||
|
||||
@@ -108,8 +105,6 @@ class PublicChatsFeedFilter(
|
||||
}
|
||||
|
||||
override fun sort(items: Set<Note>): List<Note> {
|
||||
val followedSet = account.publicChatList.flowSet.value
|
||||
|
||||
val lastNote =
|
||||
items.associateWith { note ->
|
||||
LocalCache.getPublicChatChannelIfExists(note.idHex)?.lastNote?.createdAt() ?: 0L
|
||||
@@ -122,8 +117,6 @@ class PublicChatsFeedFilter(
|
||||
|
||||
val comparator: Comparator<Note> =
|
||||
compareByDescending<Note> {
|
||||
it.idHex in followedSet
|
||||
}.thenByDescending {
|
||||
lastNote[it]
|
||||
}.thenByDescending {
|
||||
createdNote[it]
|
||||
|
||||
Reference in New Issue
Block a user