Procházet zdrojové kódy

feat: 保留ExpandedSourceSheet的浏览进度

合并 PR #1279 by woruteyqi
aoi před 5 měsíci
rodič
revize
5da2e85395

+ 4 - 0
app/src/main/java/io/legado/app/ui/book/search/SearchContract.kt

@@ -51,6 +51,9 @@ data class SearchUiState(
     val expandedSourceEnd: Boolean = false,
     val expandedSourceEnd: Boolean = false,
     val expandedSourceError: String? = null,
     val expandedSourceError: String? = null,
     val expandedSourcePage: Int = 1,
     val expandedSourcePage: Int = 1,
+    val showExpandedSource: Boolean = false,
+    val expandedSourceSavedScrollIndex: Int = 0,
+    val expandedSourceSavedScrollOffset: Int = 0,
 )
 )
 
 
 data class SearchEmptyScopeAction(
 data class SearchEmptyScopeAction(
@@ -90,6 +93,7 @@ sealed interface SearchIntent {
     data object DismissEmptyScopeAction : SearchIntent
     data object DismissEmptyScopeAction : SearchIntent
     data object OpenSourceManage : SearchIntent
     data object OpenSourceManage : SearchIntent
     data class SaveScrollState(val index: Int, val offset: Int) : SearchIntent
     data class SaveScrollState(val index: Int, val offset: Int) : SearchIntent
+    data class SaveExpandedSourceScrollState(val index: Int, val offset: Int) : SearchIntent
 }
 }
 
 
 sealed interface SearchEffect {
 sealed interface SearchEffect {

+ 27 - 2
app/src/main/java/io/legado/app/ui/book/search/SearchScreen.kt

@@ -698,14 +698,19 @@ fun SearchScreen(
     )
     )
 
 
     ExpandedSourceSheet(
     ExpandedSourceSheet(
-        show = state.expandedSourceUrl != null,
+        show = state.showExpandedSource,
         sourceName = state.expandedSourceName ?: "",
         sourceName = state.expandedSourceName ?: "",
         books = state.expandedSourceBooks,
         books = state.expandedSourceBooks,
         isLoading = state.expandedSourceLoading,
         isLoading = state.expandedSourceLoading,
         isEnd = state.expandedSourceEnd,
         isEnd = state.expandedSourceEnd,
         errorMsg = state.expandedSourceError,
         errorMsg = state.expandedSourceError,
+        savedScrollIndex = state.expandedSourceSavedScrollIndex,
+        savedScrollOffset = state.expandedSourceSavedScrollOffset,
         onDismiss = { viewModel.onIntent(SearchIntent.DismissExpandedSource) },
         onDismiss = { viewModel.onIntent(SearchIntent.DismissExpandedSource) },
         onLoadMore = { viewModel.onIntent(SearchIntent.LoadMoreExpandedSource) },
         onLoadMore = { viewModel.onIntent(SearchIntent.LoadMoreExpandedSource) },
+        onSaveScrollState = { index, offset ->
+            viewModel.onIntent(SearchIntent.SaveExpandedSourceScrollState(index, offset))
+        },
         onBookClick = { book, coverKey ->
         onBookClick = { book, coverKey ->
             viewModel.onIntent(SearchIntent.OpenExpandedSourceBook(book, coverKey))
             viewModel.onIntent(SearchIntent.OpenExpandedSourceBook(book, coverKey))
         },
         },
@@ -888,8 +893,11 @@ private fun ExpandedSourceSheet(
     isLoading: Boolean,
     isLoading: Boolean,
     isEnd: Boolean,
     isEnd: Boolean,
     errorMsg: String?,
     errorMsg: String?,
+    savedScrollIndex: Int,
+    savedScrollOffset: Int,
     onDismiss: () -> Unit,
     onDismiss: () -> Unit,
     onLoadMore: () -> Unit,
     onLoadMore: () -> Unit,
+    onSaveScrollState: (Int, Int) -> Unit,
     onBookClick: (SearchBook, String?) -> Unit,
     onBookClick: (SearchBook, String?) -> Unit,
     onBookLongClick: ((SearchBook, String?) -> Unit)? = null,
     onBookLongClick: ((SearchBook, String?) -> Unit)? = null,
 ) {
 ) {
@@ -900,7 +908,7 @@ private fun ExpandedSourceSheet(
     ) {
     ) {
         val listState = rememberLazyListState()
         val listState = rememberLazyListState()
         val showLoadMoreFooter = isLoading || errorMsg != null || isEnd
         val showLoadMoreFooter = isLoading || errorMsg != null || isEnd
-
+        val currentOnSaveScrollState by rememberUpdatedState(onSaveScrollState)
         val shouldLoadMore by remember {
         val shouldLoadMore by remember {
             derivedStateOf {
             derivedStateOf {
                 val total = listState.layoutInfo.totalItemsCount
                 val total = listState.layoutInfo.totalItemsCount
@@ -915,6 +923,23 @@ private fun ExpandedSourceSheet(
             }
             }
         }
         }
 
 
+        LaunchedEffect(savedScrollIndex, savedScrollOffset) {
+            if (savedScrollIndex > 0 || savedScrollOffset > 0) {
+                listState.scrollToItem(savedScrollIndex, savedScrollOffset)
+                onSaveScrollState(0, 0)
+            }
+        }
+
+        DisposableEffect(listState) {
+            onDispose {
+                val first = listState.firstVisibleItemIndex
+                val offset = listState.firstVisibleItemScrollOffset
+                if (first > 0 || offset > 0) {
+                    currentOnSaveScrollState(first, offset)
+                }
+            }
+        }
+
         LazyColumn(
         LazyColumn(
             state = listState,
             state = listState,
             modifier = Modifier.fillMaxSize(),
             modifier = Modifier.fillMaxSize(),

+ 38 - 20
app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt

@@ -225,6 +225,11 @@ class SearchViewModel(
             SearchIntent.OpenSourceManage -> emitEffect(SearchEffect.OpenSourceManage)
             SearchIntent.OpenSourceManage -> emitEffect(SearchEffect.OpenSourceManage)
 
 
             is SearchIntent.ExpandSource -> {
             is SearchIntent.ExpandSource -> {
+                val state = _uiState.value
+                if (state.expandedSourceUrl == intent.sourceUrl) {
+                    _uiState.update { it.copy(showExpandedSource = true) }
+                    return
+                }
                 _uiState.update {
                 _uiState.update {
                     it.copy(
                     it.copy(
                         expandedSourceUrl = intent.sourceUrl,
                         expandedSourceUrl = intent.sourceUrl,
@@ -234,6 +239,9 @@ class SearchViewModel(
                         expandedSourceEnd = false,
                         expandedSourceEnd = false,
                         expandedSourceError = null,
                         expandedSourceError = null,
                         expandedSourcePage = 1,
                         expandedSourcePage = 1,
+                        showExpandedSource = true,
+                        expandedSourceSavedScrollIndex = 0,
+                        expandedSourceSavedScrollOffset = 0,
                     )
                     )
                 }
                 }
                 loadExpandedSourcePage(intent.sourceUrl, page = 1)
                 loadExpandedSourcePage(intent.sourceUrl, page = 1)
@@ -241,15 +249,7 @@ class SearchViewModel(
 
 
             SearchIntent.DismissExpandedSource -> {
             SearchIntent.DismissExpandedSource -> {
                 _uiState.update {
                 _uiState.update {
-                    it.copy(
-                        expandedSourceUrl = null,
-                        expandedSourceName = null,
-                        expandedSourceBooks = persistentListOf(),
-                        expandedSourceLoading = false,
-                        expandedSourceEnd = false,
-                        expandedSourceError = null,
-                        expandedSourcePage = 1,
-                    )
+                    it.copy(showExpandedSource = false)
                 }
                 }
             }
             }
 
 
@@ -267,17 +267,6 @@ class SearchViewModel(
             }
             }
 
 
             is SearchIntent.OpenExpandedSourceBook -> {
             is SearchIntent.OpenExpandedSourceBook -> {
-                _uiState.update {
-                    it.copy(
-                        expandedSourceUrl = null,
-                        expandedSourceName = null,
-                        expandedSourceBooks = persistentListOf(),
-                        expandedSourceLoading = false,
-                        expandedSourceEnd = false,
-                        expandedSourceError = null,
-                        expandedSourcePage = 1,
-                    )
-                }
                 emitEffect(
                 emitEffect(
                     SearchEffect.OpenBookInfo(
                     SearchEffect.OpenBookInfo(
                         name = intent.book.name,
                         name = intent.book.name,
@@ -298,6 +287,15 @@ class SearchViewModel(
                     )
                     )
                 }
                 }
             }
             }
+
+            is SearchIntent.SaveExpandedSourceScrollState -> {
+                _uiState.update {
+                    it.copy(
+                        expandedSourceSavedScrollIndex = intent.index,
+                        expandedSourceSavedScrollOffset = intent.offset,
+                    )
+                }
+            }
         }
         }
     }
     }
 
 
@@ -426,6 +424,16 @@ class SearchViewModel(
                 processedSources = 0,
                 processedSources = 0,
                 totalSources = 0,
                 totalSources = 0,
                 emptyScopeAction = null,
                 emptyScopeAction = null,
+                expandedSourceUrl = null,
+                expandedSourceName = null,
+                expandedSourceBooks = persistentListOf(),
+                expandedSourceLoading = false,
+                expandedSourceEnd = false,
+                expandedSourceError = null,
+                expandedSourcePage = 1,
+                showExpandedSource = false,
+                expandedSourceSavedScrollIndex = 0,
+                expandedSourceSavedScrollOffset = 0,
             )
             )
         }
         }
 
 
@@ -550,6 +558,16 @@ class SearchViewModel(
                 hasMore = true,
                 hasMore = true,
                 showSuggestions = true,
                 showSuggestions = true,
                 emptyScopeAction = null,
                 emptyScopeAction = null,
+                expandedSourceUrl = null,
+                expandedSourceName = null,
+                expandedSourceBooks = persistentListOf(),
+                expandedSourceLoading = false,
+                expandedSourceEnd = false,
+                expandedSourceError = null,
+                expandedSourcePage = 1,
+                showExpandedSource = false,
+                expandedSourceSavedScrollIndex = 0,
+                expandedSourceSavedScrollOffset = 0,
             )
             )
         }
         }
     }
     }