diff --git a/app/src/main/java/io/legado/app/data/repository/ExploreRepository.kt b/app/src/main/java/io/legado/app/data/repository/ExploreRepository.kt index 863d00ff5..d0319b656 100644 --- a/app/src/main/java/io/legado/app/data/repository/ExploreRepository.kt +++ b/app/src/main/java/io/legado/app/data/repository/ExploreRepository.kt @@ -19,7 +19,6 @@ interface ExploreRepository { fun getExploreGroups(): Flow> fun getExploreSources(query: String, selectedGroup: String): Flow> suspend fun getBookSource(sourceUrl: String): BookSource? - suspend fun saveSearchBooks(books: List) suspend fun getSourceExploreKinds(sourceUrl: String): List suspend fun topSource(bookSource: BookSourcePart) suspend fun deleteSource(sourceUrl: String) @@ -91,10 +90,6 @@ class ExploreRepositoryImpl( return@withContext source?.exploreKinds() ?: emptyList() } - override suspend fun saveSearchBooks(books: List) { - appDb.searchBookDao.insert(*books.toTypedArray()) - } - override suspend fun topSource(bookSource: BookSourcePart) { val minOrder = appDb.bookSourceDao.minOrder appDb.bookSourceDao.upOrder(bookSource.copy(customOrder = minOrder - 1)) diff --git a/app/src/main/java/io/legado/app/domain/usecase/AddToBookshelfUseCase.kt b/app/src/main/java/io/legado/app/domain/usecase/AddToBookshelfUseCase.kt index be1728f81..c29c10adc 100644 --- a/app/src/main/java/io/legado/app/domain/usecase/AddToBookshelfUseCase.kt +++ b/app/src/main/java/io/legado/app/domain/usecase/AddToBookshelfUseCase.kt @@ -1,20 +1,20 @@ package io.legado.app.domain.usecase import io.legado.app.constant.BookType -import io.legado.app.data.appDb import io.legado.app.data.entities.SearchBook +import io.legado.app.data.repository.BookRepository import io.legado.app.help.book.removeType -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -class AddToBookshelfUseCase { +class AddToBookshelfUseCase( + private val bookRepository: BookRepository, +) { - suspend fun execute(book: SearchBook) = withContext(Dispatchers.IO) { + suspend fun execute(book: SearchBook) { val b = book.toBook() b.removeType(BookType.notShelf) if (b.order == 0) { - b.order = appDb.bookDao.minOrder - 1 + b.order = bookRepository.getMinOrder() - 1 } - b.save() + bookRepository.insert(b) } } diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowContract.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowContract.kt index 0bcc0e6b1..0b22e18e9 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowContract.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowContract.kt @@ -36,7 +36,7 @@ sealed interface ExploreShowSheet { sealed interface ExploreShowIntent { data class InitData( - val sourceUrl: String?, + val sourceUrl: String, val exploreUrl: String?, ) : ExploreShowIntent diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt index b827e9990..26291c908 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt @@ -135,30 +135,38 @@ fun ExploreShowScreen( val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior() val isGridMode = state.layoutState == 1 val hazeState = remember { HazeState() } - val shouldLoadMoreList = remember { + val showLoadMoreFooter = !state.isRefreshing && + (state.isLoading || state.errorMsg != null || state.isEnd) + val canLoadMore = state.books.isNotEmpty() && + !state.isLoading && + !state.isRefreshing && + !state.isEnd && + state.errorMsg == null + val shouldLoadMore by remember(isGridMode) { derivedStateOf { - val total = listState.layoutInfo.totalItemsCount - val last = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 - total > 0 && last >= total - 3 + if (isGridMode) { + val total = gridState.layoutInfo.totalItemsCount + val last = gridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 + total > 0 && last >= total - 1 + } else { + val total = listState.layoutInfo.totalItemsCount + val last = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 + total > 0 && last >= total - 3 + } } } - val shouldLoadMoreGrid = remember { - derivedStateOf { - val total = gridState.layoutInfo.totalItemsCount - val last = gridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 - total > 0 && last >= total - 1 + LaunchedEffect( + shouldLoadMore, + isGridMode, + canLoadMore, + state.books.size, + ) { + if (shouldLoadMore && canLoadMore) { + viewModel.onIntent(ExploreShowIntent.LoadMore) } } - LaunchedEffect(shouldLoadMoreList.value, isGridMode) { - if (!isGridMode && shouldLoadMoreList.value) viewModel.onIntent(ExploreShowIntent.LoadMore) - } - - LaunchedEffect(shouldLoadMoreGrid.value, isGridMode) { - if (isGridMode && shouldLoadMoreGrid.value) viewModel.onIntent(ExploreShowIntent.LoadMore) - } - LaunchedEffect(isGridMode) { if (isGridMode) { if (listState.firstVisibleItemIndex > 0) { @@ -325,14 +333,14 @@ fun ExploreShowScreen( ) } - item(span = { GridItemSpan(maxLineSpan) }) { - LoadMoreFooter( - isLoading = state.isLoading && !state.isRefreshing, - errorMsg = state.errorMsg, - isEnd = state.isEnd, - onRetry = { viewModel.onIntent(ExploreShowIntent.LoadMore) }, - onLoadMore = { viewModel.onIntent(ExploreShowIntent.ForceLoadNext) } - ) + if (showLoadMoreFooter) { + item(span = { GridItemSpan(maxLineSpan) }) { + ExploreShowLoadMoreFooter( + state = state, + onRetry = { viewModel.onIntent(ExploreShowIntent.LoadMore) }, + onLoadMore = { viewModel.onIntent(ExploreShowIntent.ForceLoadNext) }, + ) + } } } } else { @@ -376,14 +384,14 @@ fun ExploreShowScreen( ) } - item { - LoadMoreFooter( - isLoading = state.isLoading && !state.isRefreshing, - errorMsg = state.errorMsg, - isEnd = state.isEnd, - onRetry = { viewModel.onIntent(ExploreShowIntent.LoadMore) }, - onLoadMore = { viewModel.onIntent(ExploreShowIntent.ForceLoadNext) } - ) + if (showLoadMoreFooter) { + item { + ExploreShowLoadMoreFooter( + state = state, + onRetry = { viewModel.onIntent(ExploreShowIntent.LoadMore) }, + onLoadMore = { viewModel.onIntent(ExploreShowIntent.ForceLoadNext) }, + ) + } } } } @@ -410,6 +418,22 @@ fun ExploreShowScreen( ) } +@Composable +private fun ExploreShowLoadMoreFooter( + state: ExploreShowUiState, + onRetry: () -> Unit, + onLoadMore: () -> Unit, +) { + LoadMoreFooter( + isLoading = state.isLoading, + errorMsg = state.errorMsg, + isEnd = state.isEnd, + onRetry = onRetry, + onLoadMore = onLoadMore, + autoLoad = false, + ) +} + @OptIn(ExperimentalSharedTransitionApi::class) @Composable fun ExploreBookItem( diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt index 0d85b22b6..f7e2f98d9 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt @@ -2,7 +2,6 @@ package io.legado.app.ui.book.explore import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.rule.ExploreKind import io.legado.app.data.repository.ExploreRepository @@ -25,6 +24,25 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import splitties.init.appCtx +private data class ExploreShowLoadState( + val isLoading: Boolean = false, + val isRefreshing: Boolean = false, + val isEnd: Boolean = false, + val errorMsg: String? = null, +) + +private data class ExploreShowKindState( + val kinds: List = emptyList(), + val selectedKindTitle: String? = null, +) + +private data class ExploreShowDisplayState( + val sourceUrl: String? = null, + val layoutState: Int, + val gridCount: Int, + val sheet: ExploreShowSheet = ExploreShowSheet.None, +) + class ExploreShowViewModel( private val repository: ExploreRepository, private val resolveBookShelfStateUseCase: ResolveBookShelfStateUseCase, @@ -35,15 +53,18 @@ class ExploreShowViewModel( private val _rawBooks = MutableStateFlow>(emptyList()) private val _bookshelf = MutableStateFlow>(emptySet()) - private val _isLoading = MutableStateFlow(false) - private val _isEnd = MutableStateFlow(false) - private val _errorMsg = MutableStateFlow(null) - private val _kinds = MutableStateFlow>(emptyList()) - private val _selectedKindTitle = MutableStateFlow(null) + private val _loadState = MutableStateFlow(ExploreShowLoadState()) + private val _kindState = MutableStateFlow(ExploreShowKindState()) + private val _displayState = MutableStateFlow( + ExploreShowDisplayState( + layoutState = AppConfig.exploreLayoutState, + gridCount = appCtx.exploreLayoutGrid, + ) + ) - private var bookSource: BookSource? = null private var sourceUrl: String? = null private var exploreUrl: String? = null + private var initialized = false private var page = 1 private var autoPageCount = 0 @@ -54,8 +75,8 @@ class ExploreShowViewModel( private val _uiState = MutableStateFlow( ExploreShowUiState( - layoutState = AppConfig.exploreLayoutState, - gridCount = appCtx.exploreLayoutGrid, + layoutState = _displayState.value.layoutState, + gridCount = _displayState.value.gridCount, ) ) val uiState = _uiState.asStateFlow() @@ -77,8 +98,8 @@ class ExploreShowViewModel( is ExploreShowIntent.SwitchKind -> switchKind(intent.kind) ExploreShowIntent.ToggleLayout -> toggleLayout() is ExploreShowIntent.SaveGridCount -> saveGridCount(intent.count) - is ExploreShowIntent.ShowSheet -> _uiState.update { it.copy(sheet = intent.sheet) } - ExploreShowIntent.DismissSheet -> _uiState.update { it.copy(sheet = ExploreShowSheet.None) } + is ExploreShowIntent.ShowSheet -> _displayState.update { it.copy(sheet = intent.sheet) } + ExploreShowIntent.DismissSheet -> _displayState.update { it.copy(sheet = ExploreShowSheet.None) } is ExploreShowIntent.OpenBook -> emitEffect( ExploreShowEffect.OpenBookInfo( name = intent.book.name, @@ -111,21 +132,10 @@ class ExploreShowViewModel( combine( _rawBooks, _bookshelf, - _isLoading, - _isEnd, - _errorMsg, - _kinds, - _selectedKindTitle, - ) { values -> - @Suppress("UNCHECKED_CAST") - val rawBooks = values[0] as List - val bookshelf = values[1] as Set - val isLoading = values[2] as Boolean - val isEnd = values[3] as Boolean - val errorMsg = values[4] as String? - val kinds = values[5] as List - val selectedKindTitle = values[6] as String? - + _loadState, + _kindState, + _displayState, + ) { rawBooks, bookshelf, loadState, kindState, displayState -> val books = rawBooks.map { item -> ExploreBookItemUi( book = item, @@ -139,154 +149,154 @@ class ExploreShowViewModel( } ExploreShowUiState( - sourceUrl = sourceUrl, + sourceUrl = displayState.sourceUrl, books = books.toImmutableList(), - kinds = kinds.toImmutableList(), - selectedKindTitle = selectedKindTitle, - layoutState = _uiState.value.layoutState, - gridCount = _uiState.value.gridCount, - isLoading = isLoading, - isRefreshing = isLoading && page == 1, - isEnd = isEnd, - errorMsg = errorMsg, - sheet = _uiState.value.sheet, + kinds = kindState.kinds.toImmutableList(), + selectedKindTitle = kindState.selectedKindTitle, + layoutState = displayState.layoutState, + gridCount = displayState.gridCount, + isLoading = loadState.isLoading, + isRefreshing = loadState.isRefreshing, + isEnd = loadState.isEnd, + errorMsg = loadState.errorMsg, + sheet = displayState.sheet, ) }.collect { newState -> - val oldState = _uiState.value _uiState.value = newState - - if (newState.books.isEmpty() && _rawBooks.value.isNotEmpty() && !newState.isEnd && !newState.isLoading) { - loadMore() - } } } } - private fun initData(incomingSourceUrl: String?, incomingExploreUrl: String?) { - if (sourceUrl == incomingSourceUrl && exploreUrl == incomingExploreUrl && bookSource != null) { + private fun initData(incomingSourceUrl: String, incomingExploreUrl: String?) { + if (initialized && sourceUrl == incomingSourceUrl && exploreUrl == incomingExploreUrl) { return } + initialized = true sourceUrl = incomingSourceUrl exploreUrl = incomingExploreUrl page = 1 autoPageCount = 0 - bookSource = null _rawBooks.value = emptyList() - _isEnd.value = false - _errorMsg.value = null - _selectedKindTitle.value = null - _kinds.value = emptyList() - - viewModelScope.launch { - if (bookSource == null && incomingSourceUrl != null) { - bookSource = repository.getBookSource(incomingSourceUrl) - } - - if (exploreUrl == null && bookSource != null) { - loadKinds(incomingSourceUrl!!) - } - - loadMore(isRefresh = true) + _loadState.value = ExploreShowLoadState() + _kindState.value = ExploreShowKindState() + _displayState.update { + it.copy( + sourceUrl = incomingSourceUrl, + sheet = ExploreShowSheet.None, + ) } + + if (incomingExploreUrl == null) { + viewModelScope.launch { + loadKinds(incomingSourceUrl) + } + } + + loadMore(isRefresh = true) } - private fun loadKinds(sourceUrl: String) { - viewModelScope.launch { - _kinds.value = repository.getSourceExploreKinds(sourceUrl) - } + private suspend fun loadKinds(sourceUrl: String) { + _kindState.update { it.copy(kinds = repository.getSourceExploreKinds(sourceUrl)) } } private fun switchKind(kind: ExploreKind) { - _selectedKindTitle.value = kind.title + _kindState.update { it.copy(selectedKindTitle = kind.title) } exploreUrl = kind.url - _isEnd.value = false + _loadState.update { it.copy(isEnd = false) } autoPageCount = 0 loadMore(isRefresh = true) } private fun toggleLayout() { - _uiState.update { - val newState = if (it.layoutState == 0) 1 else 0 - AppConfig.exploreLayoutState = newState - it.copy(layoutState = newState) + _displayState.update { + val layoutState = if (it.layoutState == 0) 1 else 0 + AppConfig.exploreLayoutState = layoutState + it.copy(layoutState = layoutState) } } private fun saveGridCount(count: Int) { appCtx.exploreLayoutGrid = count - _uiState.update { it.copy(gridCount = count) } + _displayState.update { it.copy(gridCount = count) } } private fun loadMore(isRefresh: Boolean = false, forceLoad: Boolean = false) { - val source = bookSource - val url = exploreUrl ?: source?.exploreUrl - if (source == null || url == null || _isLoading.value || (_isEnd.value && !isRefresh && !forceLoad)) return + val source = sourceUrl + val url = exploreUrl + val loadState = _loadState.value + if (source == null || loadState.isLoading || (loadState.isEnd && !isRefresh && !forceLoad)) return + + _loadState.update { + it.copy( + isLoading = true, + isRefreshing = isRefresh, + isEnd = if (isRefresh || forceLoad) false else it.isEnd, + errorMsg = null, + ) + } viewModelScope.launch { - _isLoading.value = true - _errorMsg.value = null - if (isRefresh) { page = 1 - _isEnd.value = false autoPageCount = 0 _rawBooks.value = emptyList() } if (forceLoad) { autoPageCount = 0 - _isEnd.value = false } fetchPage(source, url) } } - private suspend fun fetchPage(source: BookSource, url: String) { + private suspend fun fetchPage(sourceUrl: String, url: String?) { kotlin.runCatching { - exploreBooksUseCase.execute(source.bookSourceUrl, url, args = null, page) + exploreBooksUseCase.execute(sourceUrl, url, args = null, page) }.onSuccess { result -> - if (result.books.isEmpty()) { - page++ - autoPageCount++ - if (autoPageCount >= MAX_AUTO_PAGES) { - _isEnd.value = true - _isLoading.value = false - } else { - delay(AUTO_PAGE_DELAY_MS) - fetchPage(source, url) - } - } else { + val currentList = _rawBooks.value + val existingUrls = currentList.map { it.bookUrl }.toSet() + val uniqueNewBooks = result.books + .filter { it.bookUrl !in existingUrls } + .distinctBy { it.bookUrl } + + if (result.books.isNotEmpty()) { saveSearchBooksUseCase.save(result.books) - - val currentList = _rawBooks.value - val existingUrls = currentList.map { it.bookUrl }.toSet() - - val uniqueNewBooks = result.books - .filter { it.bookUrl !in existingUrls } - .distinctBy { it.bookUrl } - - if (uniqueNewBooks.isEmpty()) { - page++ - autoPageCount++ - if (autoPageCount >= MAX_AUTO_PAGES) { - _isEnd.value = true - _isLoading.value = false - } else { - delay(AUTO_PAGE_DELAY_MS) - fetchPage(source, url) - } - } else { - _rawBooks.value = currentList + uniqueNewBooks - page++ - autoPageCount = 0 - _isEnd.value = false - _isLoading.value = false - } } - }.onFailure { - _errorMsg.value = it.stackTraceStr - _isLoading.value = false + + if (uniqueNewBooks.isEmpty()) { + fetchNextAutoPageOrFinish(sourceUrl, url) + } else { + _rawBooks.value = currentList + uniqueNewBooks + page++ + autoPageCount = 0 + _loadState.update { it.copy(isEnd = false) } + finishLoading() + } + }.onFailure { throwable -> + _loadState.update { it.copy(errorMsg = throwable.stackTraceStr) } + finishLoading() + } + } + + private suspend fun fetchNextAutoPageOrFinish(sourceUrl: String, url: String?) { + page++ + autoPageCount++ + if (autoPageCount >= MAX_AUTO_PAGES) { + _loadState.update { it.copy(isEnd = true) } + finishLoading() + } else { + delay(AUTO_PAGE_DELAY_MS) + fetchPage(sourceUrl, url) + } + } + + private fun finishLoading() { + _loadState.update { + it.copy( + isLoading = false, + isRefreshing = false, + ) } } diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchScreen.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchScreen.kt index 13db03ff0..e2e50addc 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchScreen.kt @@ -899,6 +899,7 @@ private fun ExpandedSourceSheet( title = sourceName, ) { val listState = rememberLazyListState() + val showLoadMoreFooter = isLoading || errorMsg != null || isEnd val shouldLoadMore by remember { derivedStateOf { @@ -935,13 +936,16 @@ private fun ExpandedSourceSheet( ) } - item { - LoadMoreFooter( - isLoading = isLoading, - errorMsg = errorMsg, - isEnd = isEnd, - onRetry = onLoadMore, - ) + if (showLoadMoreFooter) { + item { + LoadMoreFooter( + isLoading = isLoading, + errorMsg = errorMsg, + isEnd = isEnd, + onRetry = onLoadMore, + autoLoad = false, + ) + } } } } diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesCompose.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesCompose.kt index 4e41f5a76..2964a612b 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesCompose.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesCompose.kt @@ -135,6 +135,8 @@ fun RssArticlesPage( modifier = modifier.fillMaxSize(), topPadding = paddingValues.calculateTopPadding() ) { + val showLoadMoreFooter = !loadState.isRefreshing && + (loadState.isLoadingMore || loadState.errorMessage != null || !loadState.hasMore) when (layout) { RssArticleLayout.List, RssArticleLayout.LargeCard -> { val listState = rememberLazyListState() @@ -160,13 +162,16 @@ fun RssArticlesPage( onClick = onRead ) } - item { - LoadMoreFooter( - isLoading = loadState.isRefreshing || loadState.isLoadingMore, - errorMsg = loadState.errorMessage, - isEnd = !loadState.hasMore, - onRetry = { rssSource?.let(viewModel::loadMore) } - ) + if (showLoadMoreFooter) { + item { + LoadMoreFooter( + isLoading = loadState.isLoadingMore, + errorMsg = loadState.errorMessage, + isEnd = !loadState.hasMore, + onRetry = { rssSource?.let(viewModel::loadMore) }, + autoLoad = false + ) + } } } } @@ -197,13 +202,16 @@ fun RssArticlesPage( onClick = onRead ) } - item(span = { GridItemSpan(maxLineSpan) }) { - LoadMoreFooter( - isLoading = loadState.isRefreshing || loadState.isLoadingMore, - errorMsg = loadState.errorMessage, - isEnd = !loadState.hasMore, - onRetry = { rssSource?.let(viewModel::loadMore) } - ) + if (showLoadMoreFooter) { + item(span = { GridItemSpan(maxLineSpan) }) { + LoadMoreFooter( + isLoading = loadState.isLoadingMore, + errorMsg = loadState.errorMessage, + isEnd = !loadState.hasMore, + onRetry = { rssSource?.let(viewModel::loadMore) }, + autoLoad = false + ) + } } } } @@ -234,13 +242,16 @@ fun RssArticlesPage( onClick = onRead ) } - item(span = StaggeredGridItemSpan.FullLine) { - LoadMoreFooter( - isLoading = loadState.isRefreshing || loadState.isLoadingMore, - errorMsg = loadState.errorMessage, - isEnd = !loadState.hasMore, - onRetry = { rssSource?.let(viewModel::loadMore) } - ) + if (showLoadMoreFooter) { + item(span = StaggeredGridItemSpan.FullLine) { + LoadMoreFooter( + isLoading = loadState.isLoadingMore, + errorMsg = loadState.errorMessage, + isEnd = !loadState.hasMore, + onRetry = { rssSource?.let(viewModel::loadMore) }, + autoLoad = false + ) + } } } } diff --git a/app/src/main/java/io/legado/app/ui/widget/components/LoadMoreFooter.kt b/app/src/main/java/io/legado/app/ui/widget/components/LoadMoreFooter.kt index 3de08feca..b077f480a 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/LoadMoreFooter.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/LoadMoreFooter.kt @@ -44,16 +44,23 @@ fun LoadMoreFooter( isEnd: Boolean, onRetry: () -> Unit, onLoadMore: (() -> Unit)? = null, + autoLoad: Boolean = true, ) { val context = LocalContext.current var showFullError by remember { mutableStateOf(null) } - LaunchedEffect(isLoading, errorMsg, isEnd) { - if (!isLoading && errorMsg == null && !isEnd) { - onRetry() + if (autoLoad) { + LaunchedEffect(isLoading, errorMsg, isEnd) { + if (!isLoading && errorMsg == null && !isEnd) { + onRetry() + } } } + if (autoLoad && !isLoading && errorMsg == null && !isEnd) { + return + } + AppAlertDialog( data = showFullError, onDismissRequest = { showFullError = null }, @@ -270,39 +277,41 @@ fun LoadMoreFooter( } else -> { - GlassCard( - modifier = Modifier - .fillMaxWidth(), - containerColor = LegadoTheme.colorScheme.surfaceContainer, - onClick = onRetry - ) { - Column( - modifier = Modifier.fillMaxWidth() + if (!autoLoad) { + GlassCard( + modifier = Modifier + .fillMaxWidth(), + containerColor = LegadoTheme.colorScheme.surfaceContainer, + onClick = onRetry ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding( - all = 16.dp - ), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp) + Column( + modifier = Modifier.fillMaxWidth() ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding( + all = 16.dp + ), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { - AppIcon( - imageVector = Icons.Outlined.Info, - contentDescription = null, - tint = LegadoTheme.colorScheme.onSurface - ) + AppIcon( + imageVector = Icons.Outlined.Info, + contentDescription = null, + tint = LegadoTheme.colorScheme.onSurface + ) - AppText( - text = "加载更多", - color = LegadoTheme.colorScheme.onSurface, - style = LegadoTheme.typography.bodySmall, - modifier = Modifier.weight(1f), - maxLines = 2, - overflow = TextOverflow.Ellipsis, - ) + AppText( + text = "加载更多", + color = LegadoTheme.colorScheme.onSurface, + style = LegadoTheme.typography.bodySmall, + modifier = Modifier.weight(1f), + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + } } } }