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