From 798e16eab033d90baf966e74888a52a7acee9cee Mon Sep 17 00:00:00 2001 From: Syer10 Date: Fri, 28 May 2021 19:06:20 -0400 Subject: [PATCH] Save the scroll state for sources --- .../ca/gosyer/ui/sources/SourcesMenu.kt | 11 +++++---- .../ui/sources/components/SourceScreen.kt | 13 +++++----- .../kotlin/ca/gosyer/util/compose/State.kt | 24 +++++++++++++++++++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/ca/gosyer/ui/sources/SourcesMenu.kt b/src/main/kotlin/ca/gosyer/ui/sources/SourcesMenu.kt index 0da25636..b62b919e 100644 --- a/src/main/kotlin/ca/gosyer/ui/sources/SourcesMenu.kt +++ b/src/main/kotlin/ca/gosyer/ui/sources/SourcesMenu.kt @@ -33,6 +33,7 @@ import ca.gosyer.ui.sources.components.SourceHomeScreen import ca.gosyer.ui.sources.components.SourceScreen import ca.gosyer.util.compose.ThemedWindow import com.github.zsoltk.compose.savedinstancestate.Bundle +import com.github.zsoltk.compose.savedinstancestate.BundleScope import com.github.zsoltk.compose.savedinstancestate.LocalSavedInstanceState fun openSourcesMenu() { @@ -85,10 +86,12 @@ fun SourcesMenu(bundle: Bundle, onMangaClick: (Long) -> Unit) { } val selectedSource: Source? = selectedSourceTab - if (selectedSource != null) { - SourceScreen(selectedSource, onMangaClick) - } else { - SourceHomeScreen(isLoading, sources, serverUrl, vm::addTab) + BundleScope(selectedSource?.id.toString(), autoDispose = false) { + if (selectedSource != null) { + SourceScreen(selectedSource, onMangaClick) + } else { + SourceHomeScreen(isLoading, sources, serverUrl, vm::addTab) + } } } } diff --git a/src/main/kotlin/ca/gosyer/ui/sources/components/SourceScreen.kt b/src/main/kotlin/ca/gosyer/ui/sources/components/SourceScreen.kt index b4fd8090..ebfe5663 100644 --- a/src/main/kotlin/ca/gosyer/ui/sources/components/SourceScreen.kt +++ b/src/main/kotlin/ca/gosyer/ui/sources/components/SourceScreen.kt @@ -26,6 +26,7 @@ import ca.gosyer.data.models.Source import ca.gosyer.ui.base.components.LoadingScreen import ca.gosyer.ui.base.components.MangaGridItem import ca.gosyer.ui.base.vm.viewModel +import ca.gosyer.util.compose.persistentLazyListState import com.github.zsoltk.compose.savedinstancestate.Bundle import com.github.zsoltk.compose.savedinstancestate.LocalSavedInstanceState @@ -34,13 +35,8 @@ fun SourceScreen( source: Source, onMangaClick: (Long) -> Unit ) { - val upstream = LocalSavedInstanceState.current - + val bundle = LocalSavedInstanceState.current val vm = viewModel() - val bundle = remember(source.id) { - upstream.getBundle(source.id.toString()) - ?: Bundle().also { upstream.putBundle(source.id.toString(), it) } - } remember(source.id) { vm.init(source, bundle) } @@ -51,6 +47,7 @@ fun SourceScreen( val serverUrl by vm.serverUrl.collectAsState() MangaTable( + bundle, mangas, loading, hasNextPage, @@ -64,6 +61,7 @@ fun SourceScreen( @Composable private fun MangaTable( + bundle: Bundle, mangas: List, isLoading: Boolean = false, hasNextPage: Boolean = false, @@ -95,7 +93,8 @@ private fun MangaTable( } } - LazyVerticalGrid(GridCells.Adaptive(160.dp)) { + val persistentState = persistentLazyListState(bundle) + LazyVerticalGrid(GridCells.Adaptive(160.dp), state = persistentState) { items(mangas) { manga -> MangaGridItem( title = manga.title, diff --git a/src/main/kotlin/ca/gosyer/util/compose/State.kt b/src/main/kotlin/ca/gosyer/util/compose/State.kt index 9920eb8f..77af242c 100644 --- a/src/main/kotlin/ca/gosyer/util/compose/State.kt +++ b/src/main/kotlin/ca/gosyer/util/compose/State.kt @@ -6,11 +6,35 @@ package ca.gosyer.util.compose +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.State +import androidx.compose.runtime.remember +import com.github.zsoltk.compose.savedinstancestate.Bundle import com.github.zsoltk.compose.savedinstancestate.LocalSavedInstanceState @Composable fun State.persistent(key: String) { val bundle = LocalSavedInstanceState.current } + +const val LAZY_LIST_ITEM = "lazy_list_item" +const val LAZY_LIST_OFFSET = "lazy_list_offset" + +@Composable +fun persistentLazyListState(bundle: Bundle = LocalSavedInstanceState.current): LazyListState { + val state = rememberLazyListState( + remember { bundle.getInt(LAZY_LIST_ITEM, 0) }, + remember { bundle.getInt(LAZY_LIST_OFFSET, 0) } + ) + DisposableEffect(Unit) { + onDispose { + bundle.putInt(LAZY_LIST_ITEM, state.firstVisibleItemIndex) + bundle.putInt(LAZY_LIST_OFFSET, state.firstVisibleItemScrollOffset) + } + } + + return state +}