mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-11 14:22:55 -05:00
add pull to refresh to home screen
This commit is contained in:
@@ -2,6 +2,8 @@ package com.owenlejeune.tvtime.api.tmdb.api
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.paging.Pager
|
import androidx.paging.Pager
|
||||||
@@ -19,19 +21,22 @@ import retrofit2.Response
|
|||||||
|
|
||||||
fun <T: Any, S> ViewModel.createPagingFlow(
|
fun <T: Any, S> ViewModel.createPagingFlow(
|
||||||
fetcher: suspend (Int) -> Response<S>,
|
fetcher: suspend (Int) -> Response<S>,
|
||||||
processor: (S) -> List<T>
|
processor: (S) -> List<T>,
|
||||||
|
refreshState: MutableState<Boolean> = mutableStateOf(false)
|
||||||
): Flow<PagingData<T>> {
|
): Flow<PagingData<T>> {
|
||||||
return Pager(PagingConfig(pageSize = ViewModelConstants.PAGING_SIZE)) {
|
return Pager(PagingConfig(pageSize = ViewModelConstants.PAGING_SIZE)) {
|
||||||
BasePagingSource(
|
BasePagingSource(
|
||||||
fetcher = fetcher,
|
fetcher = fetcher,
|
||||||
processor = processor
|
processor = processor,
|
||||||
|
refreshState = refreshState
|
||||||
)
|
)
|
||||||
}.flow.cachedIn(viewModelScope)
|
}.flow.cachedIn(viewModelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasePagingSource<T: Any, S>(
|
class BasePagingSource<T: Any, S>(
|
||||||
private val fetcher: suspend (Int) -> Response<S>,
|
private val fetcher: suspend (Int) -> Response<S>,
|
||||||
private val processor: (S) -> List<T>
|
private val processor: (S) -> List<T>,
|
||||||
|
private val refreshState: MutableState<Boolean>
|
||||||
): PagingSource<Int, T>(), KoinComponent {
|
): PagingSource<Int, T>(), KoinComponent {
|
||||||
|
|
||||||
private val context: Context by inject()
|
private val context: Context by inject()
|
||||||
@@ -43,16 +48,21 @@ class BasePagingSource<T: Any, S>(
|
|||||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {
|
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {
|
||||||
return try {
|
return try {
|
||||||
val page = params.key ?: 1
|
val page = params.key ?: 1
|
||||||
|
if (page == 1) {
|
||||||
|
refreshState.value = true
|
||||||
|
}
|
||||||
val response = fetcher(page)
|
val response = fetcher(page)
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
val responseBody = response.body()
|
val responseBody = response.body()
|
||||||
val results = responseBody?.let(processor) ?: emptyList()
|
val results = responseBody?.let(processor) ?: emptyList()
|
||||||
|
refreshState.value = false
|
||||||
LoadResult.Page(
|
LoadResult.Page(
|
||||||
data = results,
|
data = results,
|
||||||
prevKey = if (page == 1) { null } else { page - 1},
|
prevKey = if (page == 1) { null } else { page - 1},
|
||||||
nextKey = if (results.isEmpty()) { null } else { page + 1}
|
nextKey = if (results.isEmpty()) { null } else { page + 1}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
refreshState.value = false
|
||||||
// Toast.makeText(context, context.getString(R.string.no_result_found), Toast.LENGTH_SHORT).show()
|
// Toast.makeText(context, context.getString(R.string.no_result_found), Toast.LENGTH_SHORT).show()
|
||||||
LoadResult.Invalid()
|
LoadResult.Invalid()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,12 @@ class MoviesService: KoinComponent, DetailService, HomePageService {
|
|||||||
val releaseDatesLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
val releaseDatesLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
||||||
val accountStatesLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
val accountStatesLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
||||||
|
|
||||||
|
val isPopularMoviesLoading = mutableStateOf(false)
|
||||||
|
val isTopRatedMoviesLoading = mutableStateOf(false)
|
||||||
|
val isNowPlayingMoviesLoading = mutableStateOf(false)
|
||||||
|
val isUpcomingMoviesLoading = mutableStateOf(false)
|
||||||
|
val isTrendingMoviesLoading = mutableStateOf(false)
|
||||||
|
|
||||||
override suspend fun getById(id: Int, refreshing: Boolean) {
|
override suspend fun getById(id: Int, refreshing: Boolean) {
|
||||||
loadRemoteData(
|
loadRemoteData(
|
||||||
{ movieService.getMovieById(id) },
|
{ movieService.getMovieById(id) },
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ class PeopleService: KoinComponent {
|
|||||||
val imagesLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
val imagesLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
||||||
val externalIdsLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
val externalIdsLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
||||||
|
|
||||||
|
val isPopularPeopleLoading = mutableStateOf(false)
|
||||||
|
val isTrendingPeopleLoading = mutableStateOf(false
|
||||||
|
)
|
||||||
|
|
||||||
suspend fun getPerson(id: Int, refreshing: Boolean) {
|
suspend fun getPerson(id: Int, refreshing: Boolean) {
|
||||||
loadRemoteData(
|
loadRemoteData(
|
||||||
{ service.getPerson(id) },
|
{ service.getPerson(id) },
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ class TvService: KoinComponent, DetailService, HomePageService {
|
|||||||
val seasonVideosLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
val seasonVideosLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
||||||
val seasonWatchProvidersLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
val seasonWatchProvidersLoadingState = mutableStateOf(LoadingState.INACTIVE)
|
||||||
|
|
||||||
|
val isPopularTvLoading = mutableStateOf(false)
|
||||||
|
val isTopRatedTvLoading = mutableStateOf(false)
|
||||||
|
val isAiringTodayTvLoading = mutableStateOf(false)
|
||||||
|
val isOnTheAirTvLoading = mutableStateOf(false)
|
||||||
|
val isTrendingTvLoading = mutableStateOf(false)
|
||||||
|
|
||||||
override suspend fun getById(id: Int, refreshing: Boolean) {
|
override suspend fun getById(id: Int, refreshing: Boolean) {
|
||||||
loadRemoteData(
|
loadRemoteData(
|
||||||
{ service.getTvShowById(id) },
|
{ service.getTvShowById(id) },
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens.tabs
|
package com.owenlejeune.tvtime.ui.screens.tabs
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
|
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||||
|
import androidx.compose.material.pullrefresh.pullRefresh
|
||||||
|
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
@@ -63,6 +69,7 @@ fun MediaTab(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun MediaTabContent(
|
fun MediaTabContent(
|
||||||
appNavController: NavHostController,
|
appNavController: NavHostController,
|
||||||
@@ -71,17 +78,34 @@ fun MediaTabContent(
|
|||||||
) {
|
) {
|
||||||
val viewModel = viewModel<MainViewModel>()
|
val viewModel = viewModel<MainViewModel>()
|
||||||
val mediaListItems = viewModel.produceMediaTabFlowFor(mediaType, mediaTabItem.type).collectAsLazyPagingItems()
|
val mediaListItems = viewModel.produceMediaTabFlowFor(mediaType, mediaTabItem.type).collectAsLazyPagingItems()
|
||||||
|
val isRefreshing = remember { viewModel.produceMediaTabLoadingFor(mediaType, mediaTabItem.type) }
|
||||||
|
|
||||||
PagingPosterGrid(
|
val pullRefreshState = rememberPullRefreshState(
|
||||||
lazyPagingItems = mediaListItems,
|
refreshing = isRefreshing.value,
|
||||||
onClick = { id ->
|
onRefresh = { mediaListItems.refresh() }
|
||||||
appNavController.navigate(
|
|
||||||
AppNavItem.DetailView.withArgs(mediaType, id)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.pullRefresh(state = pullRefreshState)
|
||||||
|
) {
|
||||||
|
PagingPosterGrid(
|
||||||
|
lazyPagingItems = mediaListItems,
|
||||||
|
onClick = { id ->
|
||||||
|
appNavController.navigate(
|
||||||
|
AppNavItem.DetailView.withArgs(mediaType, id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
PullRefreshIndicator(
|
||||||
|
refreshing = isRefreshing.value,
|
||||||
|
state = pullRefreshState,
|
||||||
|
modifier = Modifier.align(alignment = Alignment.TopCenter)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun MediaTabTrendingContent(
|
fun MediaTabTrendingContent(
|
||||||
appNavController: NavHostController,
|
appNavController: NavHostController,
|
||||||
@@ -92,6 +116,7 @@ fun MediaTabTrendingContent(
|
|||||||
|
|
||||||
val timeWindow = remember { mutableStateOf(TimeWindow.DAY) }
|
val timeWindow = remember { mutableStateOf(TimeWindow.DAY) }
|
||||||
val flow = remember { mutableStateOf(viewModel.produceTrendingFor(mediaType, timeWindow.value)) }
|
val flow = remember { mutableStateOf(viewModel.produceTrendingFor(mediaType, timeWindow.value)) }
|
||||||
|
val isRefreshing = remember { viewModel.produceTrendingLoadingFor(mediaType) }
|
||||||
|
|
||||||
LaunchedEffect(timeWindow.value) {
|
LaunchedEffect(timeWindow.value) {
|
||||||
flow.value = viewModel.produceTrendingFor(mediaType, timeWindow.value)
|
flow.value = viewModel.produceTrendingFor(mediaType, timeWindow.value)
|
||||||
@@ -99,33 +124,50 @@ fun MediaTabTrendingContent(
|
|||||||
|
|
||||||
val mediaListItems = flow.value.collectAsLazyPagingItems()
|
val mediaListItems = flow.value.collectAsLazyPagingItems()
|
||||||
|
|
||||||
PagingPosterGrid(
|
val pullRefreshState = rememberPullRefreshState(
|
||||||
lazyPagingItems = mediaListItems,
|
refreshing = isRefreshing.value,
|
||||||
headerContent = {
|
onRefresh = {
|
||||||
val options = listOf(TimeWindow.DAY, TimeWindow.WEEK)
|
mediaListItems.refresh()
|
||||||
|
|
||||||
val context = LocalContext.current
|
|
||||||
PillSegmentedControl(
|
|
||||||
items = options,
|
|
||||||
itemLabel = { _, i ->
|
|
||||||
when (i) {
|
|
||||||
TimeWindow.DAY -> context.getString(R.string.time_window_day)
|
|
||||||
TimeWindow.WEEK -> context.getString(R.string.time_window_week)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onItemSelected = { _, i -> timeWindow.value = i },
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 4.dp)
|
|
||||||
.padding(bottom = 4.dp)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onClick = { id ->
|
|
||||||
appNavController.navigate(
|
|
||||||
AppNavItem.DetailView.withArgs(mediaType, id)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.pullRefresh(pullRefreshState)
|
||||||
|
) {
|
||||||
|
PagingPosterGrid(
|
||||||
|
lazyPagingItems = mediaListItems,
|
||||||
|
headerContent = {
|
||||||
|
val options = listOf(TimeWindow.DAY, TimeWindow.WEEK)
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
PillSegmentedControl(
|
||||||
|
items = options,
|
||||||
|
itemLabel = { _, i ->
|
||||||
|
when (i) {
|
||||||
|
TimeWindow.DAY -> context.getString(R.string.time_window_day)
|
||||||
|
TimeWindow.WEEK -> context.getString(R.string.time_window_week)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onItemSelected = { _, i -> timeWindow.value = i },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 4.dp)
|
||||||
|
.padding(bottom = 4.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = { id ->
|
||||||
|
appNavController.navigate(
|
||||||
|
AppNavItem.DetailView.withArgs(mediaType, id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
PullRefreshIndicator(
|
||||||
|
refreshing = isRefreshing.value,
|
||||||
|
state = pullRefreshState,
|
||||||
|
modifier = Modifier.align(alignment = Alignment.TopCenter)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.owenlejeune.tvtime.ui.viewmodel
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
@@ -28,6 +29,7 @@ import com.owenlejeune.tvtime.utils.types.MediaViewType
|
|||||||
import com.owenlejeune.tvtime.utils.types.TimeWindow
|
import com.owenlejeune.tvtime.utils.types.TimeWindow
|
||||||
import com.owenlejeune.tvtime.utils.types.ViewableMediaTypeException
|
import com.owenlejeune.tvtime.utils.types.ViewableMediaTypeException
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.cancellable
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
|
|
||||||
@@ -62,28 +64,38 @@ class MainViewModel: ViewModel(), KoinComponent {
|
|||||||
val movieReleaseDatesLoadingState = movieService.releaseDatesLoadingState
|
val movieReleaseDatesLoadingState = movieService.releaseDatesLoadingState
|
||||||
val movieAccountStatesLoadingState = movieService.accountStatesLoadingState
|
val movieAccountStatesLoadingState = movieService.accountStatesLoadingState
|
||||||
|
|
||||||
|
val isPopularMoviesLoading = movieService.isPopularMoviesLoading
|
||||||
|
val isTopRatedMoviesLoading = movieService.isTopRatedMoviesLoading
|
||||||
|
val isNowPlayingMoviesLoading = movieService.isNowPlayingMoviesLoading
|
||||||
|
val isUpcomingMoviesLoading = movieService.isUpcomingMoviesLoading
|
||||||
|
val isTrendingMoviesLoading = movieService.isTrendingMoviesLoading
|
||||||
|
|
||||||
val popularMovies by lazy {
|
val popularMovies by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> movieService.getPopular(p) },
|
fetcher = { p -> movieService.getPopular(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isPopularMoviesLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val topRatedMovies by lazy {
|
val topRatedMovies by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> movieService.getTopRated(p) },
|
fetcher = { p -> movieService.getTopRated(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isTopRatedMoviesLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val nowPlayingMovies by lazy {
|
val nowPlayingMovies by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> movieService.getNowPlaying(p) },
|
fetcher = { p -> movieService.getNowPlaying(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isNowPlayingMoviesLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val upcomingMovies by lazy {
|
val upcomingMovies by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> movieService.getUpcoming(p) },
|
fetcher = { p -> movieService.getUpcoming(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isUpcomingMoviesLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,28 +137,38 @@ class MainViewModel: ViewModel(), KoinComponent {
|
|||||||
val tvSeasonVideosLoadingState = tvService.seasonVideosLoadingState
|
val tvSeasonVideosLoadingState = tvService.seasonVideosLoadingState
|
||||||
val tvSeasonWatchProvidersLoadingState = tvService.seasonWatchProvidersLoadingState
|
val tvSeasonWatchProvidersLoadingState = tvService.seasonWatchProvidersLoadingState
|
||||||
|
|
||||||
|
val isPopularTvLoading = tvService.isPopularTvLoading
|
||||||
|
val isTopRatedTvLoading = tvService.isTopRatedTvLoading
|
||||||
|
val isAiringTodayTvLoading = tvService.isAiringTodayTvLoading
|
||||||
|
val isOnTheAirTvLoading = tvService.isOnTheAirTvLoading
|
||||||
|
val isTrendingTvLoading = tvService.isTrendingTvLoading
|
||||||
|
|
||||||
val popularTv by lazy {
|
val popularTv by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> tvService.getPopular(p) },
|
fetcher = { p -> tvService.getPopular(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
isPopularTvLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val topRatedTv by lazy{
|
val topRatedTv by lazy{
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> tvService.getTopRated(p) },
|
fetcher = { p -> tvService.getTopRated(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
isTopRatedTvLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val airingTodayTv by lazy {
|
val airingTodayTv by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> tvService.getNowPlaying(p) },
|
fetcher = { p -> tvService.getNowPlaying(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isAiringTodayTvLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val onTheAirTv by lazy {
|
val onTheAirTv by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> tvService.getUpcoming(p) },
|
fetcher = { p -> tvService.getUpcoming(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isOnTheAirTvLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,10 +183,14 @@ class MainViewModel: ViewModel(), KoinComponent {
|
|||||||
val peopleImagesLoadingState = peopleService.imagesLoadingState
|
val peopleImagesLoadingState = peopleService.imagesLoadingState
|
||||||
val peopleExternalIdsLoadingState = peopleService.externalIdsLoadingState
|
val peopleExternalIdsLoadingState = peopleService.externalIdsLoadingState
|
||||||
|
|
||||||
|
val isPopularPeopleLoading = peopleService.isPopularPeopleLoading
|
||||||
|
val isTrendingPeopleLoading = peopleService.isTrendingPeopleLoading
|
||||||
|
|
||||||
val popularPeople by lazy {
|
val popularPeople by lazy {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> peopleService.getPopular(p) },
|
fetcher = { p -> peopleService.getPopular(p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isPopularPeopleLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +275,30 @@ class MainViewModel: ViewModel(), KoinComponent {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun produceMediaTabLoadingFor(mediaType: MediaViewType, contentType: MediaTabNavItem.Type): MutableState<Boolean> {
|
||||||
|
return providesForType(
|
||||||
|
mediaType,
|
||||||
|
{
|
||||||
|
when (contentType) {
|
||||||
|
MediaTabNavItem.Type.UPCOMING -> isUpcomingMoviesLoading
|
||||||
|
MediaTabNavItem.Type.TOP_RATED -> isTopRatedMoviesLoading
|
||||||
|
MediaTabNavItem.Type.NOW_PLAYING -> isNowPlayingMoviesLoading
|
||||||
|
MediaTabNavItem.Type.POPULAR -> isPopularMoviesLoading
|
||||||
|
else -> throw Exception("Can't produce media flow for $mediaType")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when (contentType) {
|
||||||
|
MediaTabNavItem.Type.UPCOMING -> isOnTheAirTvLoading
|
||||||
|
MediaTabNavItem.Type.TOP_RATED -> isTopRatedTvLoading
|
||||||
|
MediaTabNavItem.Type.NOW_PLAYING -> isAiringTodayTvLoading
|
||||||
|
MediaTabNavItem.Type.POPULAR -> isPopularTvLoading
|
||||||
|
else -> throw Exception("Can't produce media flow for $mediaType")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun produceKeywordsResultsFor(mediaType: MediaViewType): Map<Int, Flow<PagingData<SearchResultMedia>>> {
|
fun produceKeywordsResultsFor(mediaType: MediaViewType): Map<Int, Flow<PagingData<SearchResultMedia>>> {
|
||||||
return providesForType(mediaType, { movieKeywordResults }, { tvKeywordResults })
|
return providesForType(mediaType, { movieKeywordResults }, { tvKeywordResults })
|
||||||
}
|
}
|
||||||
@@ -258,25 +308,37 @@ class MainViewModel: ViewModel(), KoinComponent {
|
|||||||
MediaViewType.MOVIE -> {
|
MediaViewType.MOVIE -> {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> movieService.getTrending(timeWindow, p) },
|
fetcher = { p -> movieService.getTrending(timeWindow, p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isTrendingMoviesLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
MediaViewType.TV -> {
|
MediaViewType.TV -> {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> tvService.getTrending(timeWindow, p) },
|
fetcher = { p -> tvService.getTrending(timeWindow, p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isTrendingTvLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
MediaViewType.PERSON -> {
|
MediaViewType.PERSON -> {
|
||||||
createPagingFlow(
|
createPagingFlow(
|
||||||
fetcher = { p -> peopleService.getTrending(timeWindow, p) },
|
fetcher = { p -> peopleService.getTrending(timeWindow, p) },
|
||||||
processor = { it.results }
|
processor = { it.results },
|
||||||
|
refreshState = isTrendingPeopleLoading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> throw ViewableMediaTypeException(mediaType)
|
else -> throw ViewableMediaTypeException(mediaType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun produceTrendingLoadingFor(mediaType: MediaViewType): MutableState<Boolean> {
|
||||||
|
return when (mediaType) {
|
||||||
|
MediaViewType.MOVIE -> isTrendingMoviesLoading
|
||||||
|
MediaViewType.TV -> isTrendingTvLoading
|
||||||
|
MediaViewType.PERSON -> isTrendingPeopleLoading
|
||||||
|
else -> throw ViewableMediaTypeException(mediaType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun produceDetailsLoadingStateFor(mediaType: MediaViewType): MutableState<LoadingState> {
|
fun produceDetailsLoadingStateFor(mediaType: MediaViewType): MutableState<LoadingState> {
|
||||||
return providesForType(mediaType, { movieDetailsLoadingState }, { tvDetailsLoadingState})
|
return providesForType(mediaType, { movieDetailsLoadingState }, { tvDetailsLoadingState})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user