From 2c95dbe492b585028d640e77043ca0a748d819ab Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Tue, 25 Jul 2023 21:56:20 -0300 Subject: [PATCH] [ISSUE-72] - Keep pagination data after recomposition --- .../screens/ListStreamViewModel.kt | 57 ++++++++----------- .../presentation/screens/ListStreamsScreen.kt | 5 +- .../screens/ListStreamsUIState.kt | 4 +- .../presentation/widgets/StreamsCarousel.kt | 21 ++++--- 4 files changed, 39 insertions(+), 48 deletions(-) diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt index b27b972a..affea6c7 100644 --- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt +++ b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt @@ -1,10 +1,9 @@ package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import androidx.paging.PagingData +import androidx.paging.cachedIn import androidx.paging.map import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure import com.codandotv.streamplayerapp.feature.list.streams.R @@ -17,7 +16,7 @@ import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.High import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.IconAndTextInfo import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Stream import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCardContent -import kotlinx.coroutines.flow.Flow +import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCarouselContent import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine @@ -37,7 +36,7 @@ class ListStreamViewModel( private val _uiState = MutableStateFlow( ListStreamsUIState( - genres = emptyList(), + streamsCarouselContent = emptyList(), isLoading = false ) ) @@ -47,9 +46,7 @@ class ListStreamViewModel( initialValue = _uiState.value ) - override fun onCreate(owner: LifecycleOwner) { - super.onCreate(owner) - + init { viewModelScope.launch { latestStream() .combine( @@ -64,29 +61,18 @@ class ListStreamViewModel( .catchFailure { println(">>>> ${it.errorMessage}") } - .collect { - val (latest, genres) = it + .collect { pair -> + val (latest, genres) = pair + _uiState.update { it.copy( - genres = genres, + streamsCarouselContent = genres.map { genreTarget -> + getStreamsByGenre(genreTarget) + }, highlightBanner = getHighlightBanner(latest) ) } } - - if (uiState.value.genres.isEmpty()) { - listGenres() - .onStart { onLoading() } - .catchFailure { - println(">>>> ${it.errorMessage}") - } - .onCompletion { loaded() } - .collect { genres -> - _uiState.update { - it.copy(genres = genres) - } - } - } } } @@ -114,16 +100,19 @@ class ListStreamViewModel( ), ) - fun loadMovies(genre: Genre): Flow> { - return listStreams(genre).map { - it.map { stream -> - StreamsCardContent( - contentDescription = stream.name, - url = stream.posterPathUrl, - id = stream.id - ) - } - } + private fun getStreamsByGenre(genre: Genre): StreamsCarouselContent { + return StreamsCarouselContent( + genre.name, + listStreams(genre).map { + it.map { stream -> + StreamsCardContent( + contentDescription = stream.name, + url = stream.posterPathUrl, + id = stream.id + ) + } + }.cachedIn(viewModelScope) + ) } private fun loaded() { diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt index 789dbfe6..273e80d0 100644 --- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt +++ b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt @@ -83,10 +83,9 @@ fun ListStreamsScreen( HighlightBanner(data = uiState.highlightBanner) - uiState.genres.forEach { genre -> + uiState.streamsCarouselContent.forEach { streamCarouselContent -> StreamsCarousel( - title = genre.name, - contentList = viewModel.loadMovies(genre), + content = streamCarouselContent, onNavigateDetailList = onNavigateDetailList, ) Spacer(modifier = Modifier.height(12.dp)) diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt index 472f921e..fba66712 100644 --- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt +++ b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt @@ -1,10 +1,10 @@ package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens -import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Genre import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.HighlightBanner +import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCarouselContent data class ListStreamsUIState( val highlightBanner: HighlightBanner? = null, - val genres: List, + val streamsCarouselContent: List, val isLoading: Boolean ) \ No newline at end of file diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCarousel.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCarousel.kt index 45293947..82861db5 100644 --- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCarousel.kt +++ b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCarousel.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview @@ -23,21 +22,23 @@ import androidx.paging.compose.itemKey import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow +data class StreamsCarouselContent( + val genreTitle: String, + val contentList: Flow> +) + @Composable fun StreamsCarousel( - title: String, - contentList: Flow>, + content: StreamsCarouselContent, modifier: Modifier = Modifier, onNavigateDetailList: (String) -> Unit = {}, ) { - val flow = remember { contentList } - - val lazyPagingItems = flow.collectAsLazyPagingItems() + val lazyPagingItems = content.contentList.collectAsLazyPagingItems() val lazyListState = rememberLazyListState() Column(modifier = modifier) { Text( - title, + content.genreTitle, style = MaterialTheme.typography.headlineMedium.copy( fontWeight = FontWeight.Bold, fontSize = 20.sp @@ -73,7 +74,9 @@ fun StreamsCarousel( @Preview fun StreamsCarouselPreview() { StreamsCarousel( - title = "Ação", - contentList = emptyFlow() + content = StreamsCarouselContent( + genreTitle = "Ação", + contentList = emptyFlow() + ) ) } \ No newline at end of file