diff --git a/feature/characters/presentation/src/main/kotlin/com/example/architecture/feature/characters/presentation/CharacterListViewModel.kt b/feature/characters/presentation/src/main/kotlin/com/example/architecture/feature/characters/presentation/CharacterListViewModel.kt index 3858449..c131025 100644 --- a/feature/characters/presentation/src/main/kotlin/com/example/architecture/feature/characters/presentation/CharacterListViewModel.kt +++ b/feature/characters/presentation/src/main/kotlin/com/example/architecture/feature/characters/presentation/CharacterListViewModel.kt @@ -52,9 +52,9 @@ class CharacterListViewModel( } private fun restore(targetPage: Int) { + // Flip the flag synchronously so a guard reading state sees it immediately. + _state.update { it.copy(isLoading = true, error = null) } viewModelScope.launch { - _state.update { it.copy(isLoading = true, error = null) } - val accumulated = mutableListOf() var lastLoadedPage = 0 var endReached = false @@ -77,9 +77,14 @@ class CharacterListViewModel( page++ } - if (accumulated.isEmpty() && error != null) { - _state.update { it.copy(isLoading = false, error = error) } + // Always surface a failure — even a partial one where earlier pages loaded. + if (error != null) { _events.send(CharacterListEvent.ShowSnackbar(error)) + } + + if (accumulated.isEmpty()) { + // Nothing loaded → full-screen error (or an empty list if the API simply had none). + _state.update { it.copy(isLoading = false, error = error) } } else { val loadedPage = lastLoadedPage.coerceAtLeast(1) _state.update { @@ -88,6 +93,7 @@ class CharacterListViewModel( isLoading = false, currentPage = loadedPage, endReached = endReached, + // The list is shown; the snackbar already surfaced any partial failure. error = null, ) } @@ -112,8 +118,11 @@ class CharacterListViewModel( } private fun loadPage(page: Int) { + // Flip the loading flag SYNCHRONOUSLY (before launching) so a rapid second OnLoadNextPage is + // guarded out before its coroutine starts — otherwise the same page loads twice and items + // get appended twice. + _state.update { it.copy(isLoadingNextPage = true, error = null) } viewModelScope.launch { - _state.update { it.copy(isLoadingNextPage = true, error = null) } characterRepository.getCharacters(page) .onSuccess { pageData -> _state.update { state ->