Adds a list state saver to the messages screen

This commit is contained in:
Vitor Pamplona
2025-05-14 16:52:19 -04:00
parent 4ae86861f8
commit e0449a9d44
5 changed files with 19 additions and 13 deletions
@@ -41,6 +41,8 @@ object ScrollStateKeys {
const val VIDEO_SCREEN = "VideoFeed"
const val HOME_FOLLOWS = "HomeFollowsFeed"
const val HOME_REPLIES = "HomeFollowsRepliesFeed"
const val MESSAGES_KNOWN = "MessagesKnown"
const val MESSAGES_NEW = "MessagesNew"
const val PROFILE_GALLERY = "ProfileGalleryFeed"
const val DRAFTS = "DraftsFeed"
@@ -24,8 +24,8 @@ import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -40,7 +40,7 @@ import com.vitorpamplona.amethyst.ui.feeds.FeedError
import com.vitorpamplona.amethyst.ui.feeds.FeedState
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
import com.vitorpamplona.amethyst.ui.feeds.WatchScrollToTop
import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState
import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChatroomHeaderCompose
@@ -50,18 +50,22 @@ import com.vitorpamplona.amethyst.ui.theme.FeedPadding
@Composable
fun ChatroomListFeedView(
feedContentState: FeedContentState,
scrollStateKey: String,
accountViewModel: AccountViewModel,
nav: INav,
markAsRead: MutableState<Boolean>,
) {
RefresheableBox(feedContentState, true) {
CrossFadeState(feedContentState, accountViewModel, nav, markAsRead)
SaveableFeedContentState(feedContentState, scrollStateKey) { listState ->
CrossFadeState(feedContentState, listState, accountViewModel, nav, markAsRead)
}
}
}
@Composable
private fun CrossFadeState(
feedContentState: FeedContentState,
listState: LazyListState,
accountViewModel: AccountViewModel,
nav: INav,
markAsRead: MutableState<Boolean>,
@@ -81,7 +85,7 @@ private fun CrossFadeState(
FeedError(state.errorMessage) { feedContentState.invalidateData() }
}
is FeedState.Loaded -> {
FeedLoaded(state, feedContentState, accountViewModel, nav, markAsRead)
FeedLoaded(state, listState, accountViewModel, nav, markAsRead)
}
FeedState.Loading -> {
LoadingFeed()
@@ -93,23 +97,19 @@ private fun CrossFadeState(
@Composable
private fun FeedLoaded(
loaded: FeedState.Loaded,
feedContentState: FeedContentState,
listState: LazyListState,
accountViewModel: AccountViewModel,
nav: INav,
markAsRead: MutableState<Boolean>,
) {
val items by loaded.feed.collectAsStateWithLifecycle()
val listState = rememberLazyListState()
LaunchedEffect(key1 = markAsRead.value) {
if (markAsRead.value) {
accountViewModel.markAllAsRead(items.list, accountViewModel) { markAsRead.value = false }
}
}
WatchScrollToTop(feedContentState, listState)
LazyColumn(
contentPadding = FeedPadding,
state = listState,
@@ -60,6 +60,7 @@ import kotlinx.coroutines.launch
@Immutable
class MessagesTabItem(
val resource: Int,
val scrollStateKey: String,
val feedContentState: FeedContentState,
val markAsRead: MutableState<Boolean>,
)
@@ -128,6 +129,7 @@ fun MessagesPager(
) { page ->
ChatroomListFeedView(
feedContentState = tabs[page].feedContentState,
scrollStateKey = tabs[page].scrollStateKey,
accountViewModel = accountViewModel,
nav = nav,
markAsRead = tabs[page].markAsRead,
@@ -29,6 +29,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.feeds.FeedContentState
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
import com.vitorpamplona.amethyst.ui.navigation.AppBottomBar
@@ -63,8 +64,8 @@ fun MessagesSinglePane(
remember(knownFeedContentState, markKnownAsRead) {
derivedStateOf {
listOf(
MessagesTabItem(R.string.known, knownFeedContentState, markKnownAsRead),
MessagesTabItem(R.string.new_requests, newFeedContentState, markNewAsRead),
MessagesTabItem(R.string.known, ScrollStateKeys.MESSAGES_KNOWN, knownFeedContentState, markKnownAsRead),
MessagesTabItem(R.string.new_requests, ScrollStateKeys.MESSAGES_NEW, newFeedContentState, markNewAsRead),
)
}
}
@@ -31,6 +31,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.feeds.FeedContentState
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -60,8 +61,8 @@ fun ChatroomList(
remember(knownFeedContentState, markKnownAsRead) {
derivedStateOf {
listOf(
MessagesTabItem(R.string.known, knownFeedContentState, markKnownAsRead),
MessagesTabItem(R.string.new_requests, newFeedContentState, markNewAsRead),
MessagesTabItem(R.string.known, ScrollStateKeys.MESSAGES_KNOWN, knownFeedContentState, markKnownAsRead),
MessagesTabItem(R.string.new_requests, ScrollStateKeys.MESSAGES_NEW, newFeedContentState, markNewAsRead),
)
}
}