package eu.kanade.data.source import androidx.paging.PagingState import eu.kanade.domain.source.model.SourcePagingSourceType import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.util.lang.awaitSingle import eu.kanade.tachiyomi.util.lang.withIOContext abstract class SourcePagingSource( protected val source: CatalogueSource, ) : SourcePagingSourceType() { abstract suspend fun requestNextPage(currentPage: Int): MangasPage override suspend fun load(params: LoadParams): LoadResult { val page = params.key ?: 1 val mangasPage = try { withIOContext { requestNextPage(page.toInt()) .takeIf { it.mangas.isNotEmpty() } ?: throw NoResultsException() } } catch (e: Exception) { return LoadResult.Error(e) } return LoadResult.Page( data = mangasPage.mangas, prevKey = null, nextKey = if (mangasPage.hasNextPage) page + 1 else null, ) } override fun getRefreshKey(state: PagingState): Long? { return state.anchorPosition?.let { anchorPosition -> val anchorPage = state.closestPageToPosition(anchorPosition) anchorPage?.prevKey ?: anchorPage?.nextKey } } } class SourceSearchPagingSource(source: CatalogueSource, val query: String, val filters: FilterList) : SourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { return source.fetchSearchManga(currentPage, query, filters).awaitSingle() } } class SourcePopularPagingSource(source: CatalogueSource) : SourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { return source.fetchPopularManga(currentPage).awaitSingle() } } class SourceLatestPagingSource(source: CatalogueSource) : SourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { return source.fetchLatestUpdates(currentPage).awaitSingle() } }