MovieHunt blog part3. list data source
class MovieListDataSource( | |
private val category: MovieCategory, | |
private val initLoadState: BehaviorSubject<NetworkState>, | |
private val loadMoreState: BehaviorSubject<NetworkState> | |
) : PageKeyedDataSource<Int, MovieModel>(), KoinComponent { | |
private val api: MovieApiService by inject() | |
private var currentPage: Int = -1 | |
override fun loadInitial( | |
params: LoadInitialParams<Int>, | |
callback: LoadInitialCallback<Int, MovieModel> | |
) { | |
currentPage = 1 | |
api.fetchMovieList(category.key, currentPage) | |
.doOnSubscribe { initLoadState.onNext(NetworkState.LOADING) } | |
.doOnSuccess { | |
it.results?.run { | |
callback.onResult( | |
this.mapToMovieModels(), | |
null, | |
calculateNextPage(it.totalPages) | |
) | |
} | |
initLoadState.onNext(NetworkState.IDLE) | |
} | |
.doOnError { initLoadState.onNext(NetworkState.ERROR) } | |
.subscribe() | |
} | |
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, MovieModel>) { | |
if (-1 == params.key || NetworkState.LOADING == loadMoreState.value) return | |
api.fetchMovieList(category.key, params.key) | |
.doOnSubscribe { loadMoreState.onNext(NetworkState.LOADING) } | |
.doOnSuccess { | |
it.results?.run { | |
callback.onResult(this.mapToMovieModels(), calculateNextPage(it.totalPages)) | |
} | |
loadMoreState.onNext(NetworkState.IDLE) | |
} | |
.doOnError { loadMoreState.onNext(NetworkState.ERROR) } | |
.subscribe() | |
} | |
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, MovieModel>) { | |
// we don't need this | |
} | |
private fun calculateNextPage(totalPage: Int?): Int { | |
totalPage?.run { | |
currentPage = if (currentPage in 1 until totalPage) { | |
currentPage.plus(1) | |
} else { | |
-1 | |
} | |
} | |
return currentPage | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment