SlimeReadTheme: Fix pagination and add scan id (#7152)
Fix pagination and add scan id
This commit is contained in:
parent
d3d31ec815
commit
49efe333db
|
@ -2,4 +2,4 @@ plugins {
|
||||||
id("lib-multisrc")
|
id("lib-multisrc")
|
||||||
}
|
}
|
||||||
|
|
||||||
baseVersionCode = 2
|
baseVersionCode = 3
|
||||||
|
|
|
@ -33,6 +33,7 @@ abstract class SlimeReadTheme(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val baseUrl: String,
|
override val baseUrl: String,
|
||||||
override val lang: String,
|
override val lang: String,
|
||||||
|
private val scanId: String = "",
|
||||||
) : HttpSource() {
|
) : HttpSource() {
|
||||||
|
|
||||||
protected open val apiUrl: String by lazy { getApiUrlFromPage() }
|
protected open val apiUrl: String by lazy { getApiUrlFromPage() }
|
||||||
|
@ -72,35 +73,19 @@ abstract class SlimeReadTheme(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================== Popular ===============================
|
// ============================== Popular ===============================
|
||||||
private var currentSlice = 0
|
|
||||||
private var popularMangeCache: MangasPage? = null
|
private var popularMangeCache: MangasPage? = null
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int) =
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
GET("$apiUrl/book_search?order=1&status=0", headers)
|
val url = "$apiUrl/book_search?order=1&status=0".toHttpUrl().newBuilder()
|
||||||
|
.addIfNotBlank("scan_id", scanId)
|
||||||
|
.build()
|
||||||
|
return GET(url, headers)
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a large JSON, so the app can't handle the list without pagination
|
|
||||||
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
||||||
if (page == 1 || popularMangeCache == null) {
|
popularMangeCache = popularMangeCache?.takeIf { page != 1 }
|
||||||
popularMangeCache = super.fetchPopularManga(page)
|
?: super.fetchPopularManga(page).toBlocking().last()
|
||||||
.toBlocking()
|
return pageableOf(page, popularMangeCache!!)
|
||||||
.last()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handling a large manga list
|
|
||||||
return Observable.just(popularMangeCache!!)
|
|
||||||
.map { mangaPage ->
|
|
||||||
val mangas = mangaPage.mangas
|
|
||||||
val pageSize = 15
|
|
||||||
|
|
||||||
currentSlice = (page - 1) * pageSize
|
|
||||||
|
|
||||||
val startIndex = min(mangas.size - 1, currentSlice)
|
|
||||||
val endIndex = min(mangas.size, currentSlice + pageSize)
|
|
||||||
|
|
||||||
val slice = mangas.subList(startIndex, endIndex)
|
|
||||||
|
|
||||||
MangasPage(slice, slice.isNotEmpty())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
|
@ -110,7 +95,13 @@ abstract class SlimeReadTheme(
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================== Latest ===============================
|
// =============================== Latest ===============================
|
||||||
override fun latestUpdatesRequest(page: Int) = GET("$apiUrl/books?page=$page", headers)
|
|
||||||
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
|
val url = "$apiUrl/books?page=$page".toHttpUrl().newBuilder()
|
||||||
|
.addIfNotBlank("scan_id", scanId)
|
||||||
|
.build()
|
||||||
|
return GET(url, headers)
|
||||||
|
}
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||||
val dto = response.parseAs<LatestResponseDto>()
|
val dto = response.parseAs<LatestResponseDto>()
|
||||||
|
@ -120,6 +111,9 @@ abstract class SlimeReadTheme(
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================== Search ===============================
|
// =============================== Search ===============================
|
||||||
|
|
||||||
|
private var searchMangaCache: MangasPage? = null
|
||||||
|
|
||||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
||||||
return if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler
|
return if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler
|
||||||
val id = query.removePrefix(PREFIX_SEARCH)
|
val id = query.removePrefix(PREFIX_SEARCH)
|
||||||
|
@ -127,7 +121,9 @@ abstract class SlimeReadTheme(
|
||||||
.asObservableSuccess()
|
.asObservableSuccess()
|
||||||
.map(::searchMangaByIdParse)
|
.map(::searchMangaByIdParse)
|
||||||
} else {
|
} else {
|
||||||
super.fetchSearchManga(page, query, filters)
|
searchMangaCache = searchMangaCache?.takeIf { page != 1 }
|
||||||
|
?: super.fetchSearchManga(page, query, filters).toBlocking().last()
|
||||||
|
pageableOf(page, searchMangaCache!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +142,7 @@ abstract class SlimeReadTheme(
|
||||||
.addIfNotBlank("genre[]", params.genre)
|
.addIfNotBlank("genre[]", params.genre)
|
||||||
.addIfNotBlank("status", params.status)
|
.addIfNotBlank("status", params.status)
|
||||||
.addIfNotBlank("searchMethod", params.searchMethod)
|
.addIfNotBlank("searchMethod", params.searchMethod)
|
||||||
|
.addIfNotBlank("scan_id", scanId)
|
||||||
.apply {
|
.apply {
|
||||||
params.categories.forEach {
|
params.categories.forEach {
|
||||||
addQueryParameter("categories[]", it)
|
addQueryParameter("categories[]", it)
|
||||||
|
@ -237,6 +234,28 @@ abstract class SlimeReadTheme(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================= Utilities ==============================
|
// ============================= Utilities ==============================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a large manga list and returns a paginated response.
|
||||||
|
* The app can't handle the large JSON list without pagination.
|
||||||
|
*
|
||||||
|
* @param page The page number to retrieve.
|
||||||
|
* @param cache The cached manga page containing the full list of mangas.
|
||||||
|
*/
|
||||||
|
private fun pageableOf(page: Int, cache: MangasPage) = Observable.just(cache).map { mangaPage ->
|
||||||
|
val mangas = mangaPage.mangas
|
||||||
|
val pageSize = 15
|
||||||
|
|
||||||
|
val currentSlice = (page - 1) * pageSize
|
||||||
|
|
||||||
|
val startIndex = min(mangas.size, currentSlice)
|
||||||
|
val endIndex = min(mangas.size, currentSlice + pageSize)
|
||||||
|
|
||||||
|
val slice = mangas.subList(startIndex, endIndex)
|
||||||
|
|
||||||
|
MangasPage(slice, hasNextPage = endIndex < mangas.size)
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun <reified T> Response.parseAs(): T = use {
|
private inline fun <reified T> Response.parseAs(): T = use {
|
||||||
json.decodeFromStream(it.body.byteStream())
|
json.decodeFromStream(it.body.byteStream())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ class MahouScan : SlimeReadTheme(
|
||||||
"MahouScan",
|
"MahouScan",
|
||||||
"https://mahouscan.com",
|
"https://mahouscan.com",
|
||||||
"pt-BR",
|
"pt-BR",
|
||||||
|
scanId = "1292193100",
|
||||||
) {
|
) {
|
||||||
override val client = super.client.newBuilder()
|
override val client = super.client.newBuilder()
|
||||||
.rateLimit(2)
|
.rateLimit(2)
|
||||||
|
|
Loading…
Reference in New Issue