Skip to content

Instantly share code, notes, and snippets.

@enginebai
Created September 13, 2020 23:12
Show Gist options
  • Save enginebai/1e8f6c8543a697ade7892846649b720a to your computer and use it in GitHub Desktop.
Save enginebai/1e8f6c8543a697ade7892846649b720a to your computer and use it in GitHub Desktop.
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