mirror of
https://github.com/Suwayomi/Tachidesk.git
synced 2025-12-12 15:52:05 +01:00
add pagination to recentChapters (#246)
* add pagination to recentChapters * Use kotlin native library Co-authored-by: Mitchell Syer <Mitchellptbo@gmail.com> Co-authored-by: Mitchell Syer <Mitchellptbo@gmail.com>
This commit is contained in:
@@ -112,7 +112,7 @@ object MangaAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
path("update") {
|
path("update") {
|
||||||
get("recentChapters", UpdateController::recentChapters)
|
get("recentChapters/{pageNum}", UpdateController::recentChapters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ import suwayomi.tachidesk.server.JavalinSetup.future
|
|||||||
object UpdateController {
|
object UpdateController {
|
||||||
/** get recently updated manga chapters */
|
/** get recently updated manga chapters */
|
||||||
fun recentChapters(ctx: Context) {
|
fun recentChapters(ctx: Context) {
|
||||||
|
val pageNum = ctx.pathParam("pageNum").toInt()
|
||||||
|
|
||||||
ctx.future(
|
ctx.future(
|
||||||
future {
|
future {
|
||||||
Chapter.getRecentChapters()
|
Chapter.getRecentChapters(pageNum)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource.getCatalogue
|
|||||||
import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse
|
import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse
|
||||||
import suwayomi.tachidesk.manga.model.dataclass.ChapterDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.ChapterDataClass
|
||||||
import suwayomi.tachidesk.manga.model.dataclass.MangaChapterDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.MangaChapterDataClass
|
||||||
|
import suwayomi.tachidesk.manga.model.dataclass.PaginatedList
|
||||||
|
import suwayomi.tachidesk.manga.model.dataclass.paginatedFrom
|
||||||
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
||||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
@@ -321,17 +323,19 @@ object Chapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRecentChapters(): List<MangaChapterDataClass> {
|
fun getRecentChapters(pageNum: Int): PaginatedList<MangaChapterDataClass> {
|
||||||
return transaction {
|
return paginatedFrom(pageNum) {
|
||||||
(ChapterTable innerJoin MangaTable)
|
transaction {
|
||||||
.select { (MangaTable.inLibrary eq true) and (ChapterTable.fetchedAt greater MangaTable.inLibraryAt) }
|
(ChapterTable innerJoin MangaTable)
|
||||||
.orderBy(ChapterTable.fetchedAt to SortOrder.DESC)
|
.select { (MangaTable.inLibrary eq true) and (ChapterTable.fetchedAt greater MangaTable.inLibraryAt) }
|
||||||
.map {
|
.orderBy(ChapterTable.fetchedAt to SortOrder.DESC)
|
||||||
MangaChapterDataClass(
|
.map {
|
||||||
MangaTable.toDataClass(it),
|
MangaChapterDataClass(
|
||||||
ChapterTable.toDataClass(it)
|
MangaTable.toDataClass(it),
|
||||||
)
|
ChapterTable.toDataClass(it)
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package suwayomi.tachidesk.manga.model.dataclass
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
data class PaginatedList<T>(
|
||||||
|
val page: List<T>,
|
||||||
|
val hasNextPage: Boolean,
|
||||||
|
)
|
||||||
|
|
||||||
|
const val PaginationFactor = 50
|
||||||
|
|
||||||
|
fun <T> paginatedFrom(
|
||||||
|
pageNum: Int,
|
||||||
|
paginationFactor: Int = PaginationFactor,
|
||||||
|
lister: () -> List<T>
|
||||||
|
): PaginatedList<T> {
|
||||||
|
val list = lister()
|
||||||
|
val lastIndex = list.size - 1
|
||||||
|
|
||||||
|
val lowerIndex = pageNum * paginationFactor
|
||||||
|
val higherIndex = (pageNum + 1) * paginationFactor - 1
|
||||||
|
|
||||||
|
if (lowerIndex > lastIndex) {
|
||||||
|
return PaginatedList(emptyList(), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
val sliced = list.slice(lowerIndex..min(lastIndex, higherIndex))
|
||||||
|
|
||||||
|
return PaginatedList(
|
||||||
|
sliced,
|
||||||
|
higherIndex < lastIndex
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package suwayomi.tachidesk.manga.model
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import suwayomi.tachidesk.manga.model.dataclass.PaginatedList
|
||||||
|
import suwayomi.tachidesk.manga.model.dataclass.PaginationFactor
|
||||||
|
import suwayomi.tachidesk.manga.model.dataclass.paginatedFrom
|
||||||
|
import suwayomi.tachidesk.test.ApplicationTest
|
||||||
|
|
||||||
|
class PaginatedListTest : ApplicationTest() {
|
||||||
|
@Test
|
||||||
|
fun `empty list`() {
|
||||||
|
val paginated = paginatedFrom(0) { listIndicesOf(0, 0) }
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(emptyList<Int>(), false),
|
||||||
|
paginated
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `size smaller than PaginationFactor`() {
|
||||||
|
val paginated = paginatedFrom(0) { listIndicesOf(0, PaginationFactor - 1) }
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(0, PaginationFactor - 1), false),
|
||||||
|
paginated,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `one less than two times PaginationFactor`() {
|
||||||
|
val masterLister = { listIndicesOf(0, PaginationFactor * 2 - 1) }
|
||||||
|
|
||||||
|
val firstPage = paginatedFrom(0, lister = masterLister)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(0, PaginationFactor), true),
|
||||||
|
firstPage,
|
||||||
|
)
|
||||||
|
|
||||||
|
val secondPage = paginatedFrom(1, lister = masterLister)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(PaginationFactor, PaginationFactor * 2 - 1), false),
|
||||||
|
secondPage,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `two times PaginationFactor`() {
|
||||||
|
val masterLister = { listIndicesOf(0, PaginationFactor * 2) }
|
||||||
|
|
||||||
|
val firstPage = paginatedFrom(0, lister = masterLister)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(0, PaginationFactor), true),
|
||||||
|
firstPage,
|
||||||
|
)
|
||||||
|
|
||||||
|
val secondPage = paginatedFrom(1, lister = masterLister)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(PaginationFactor, PaginationFactor * 2), false),
|
||||||
|
secondPage,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `one more than two times PaginationFactor`() {
|
||||||
|
val masterLister = { listIndicesOf(0, PaginationFactor * 2 + 1) }
|
||||||
|
|
||||||
|
val firstPage = paginatedFrom(0, lister = masterLister)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(0, PaginationFactor), true),
|
||||||
|
firstPage,
|
||||||
|
)
|
||||||
|
|
||||||
|
val secondPage = paginatedFrom(1, lister = masterLister)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(PaginationFactor, PaginationFactor * 2), true),
|
||||||
|
secondPage,
|
||||||
|
)
|
||||||
|
|
||||||
|
val thirdPage = paginatedFrom(2, lister = masterLister)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
PaginatedList(listIndicesOf(PaginationFactor * 2, PaginationFactor * 2 + 1), false),
|
||||||
|
thirdPage,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun listIndicesOf(first: Int, last: Int): List<Int> {
|
||||||
|
return (first until last).toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user