mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2025-12-10 14:52:03 +01:00
Implement paged updates
This commit is contained in:
@@ -3,9 +3,9 @@ import org.gradle.api.JavaVersion
|
|||||||
object Config {
|
object Config {
|
||||||
const val tachideskVersion = "v0.5.4"
|
const val tachideskVersion = "v0.5.4"
|
||||||
// Match this to the Tachidesk-Server commit count
|
// Match this to the Tachidesk-Server commit count
|
||||||
const val serverCode = 1031
|
const val serverCode = 1043
|
||||||
const val preview = true
|
const val preview = true
|
||||||
const val previewCommit = "420d14fc37a18269a9d7232519e3f9a21c6302a2"
|
const val previewCommit = "5e47b7ae6b37931ce3a8eee33cafb9475d7a77bb"
|
||||||
|
|
||||||
val jvmTarget = JavaVersion.VERSION_15
|
val jvmTarget = JavaVersion.VERSION_15
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ca.gosyer.data.models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Updates(
|
||||||
|
val page: List<MangaAndChapter>,
|
||||||
|
val hasNextPage: Boolean
|
||||||
|
)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package ca.gosyer.data.server.interactions
|
package ca.gosyer.data.server.interactions
|
||||||
|
|
||||||
import ca.gosyer.data.models.MangaAndChapter
|
import ca.gosyer.data.models.Updates
|
||||||
import ca.gosyer.data.server.Http
|
import ca.gosyer.data.server.Http
|
||||||
import ca.gosyer.data.server.ServerPreferences
|
import ca.gosyer.data.server.ServerPreferences
|
||||||
import ca.gosyer.data.server.requests.recentUpdatesQuery
|
import ca.gosyer.data.server.requests.recentUpdatesQuery
|
||||||
@@ -19,9 +19,9 @@ class UpdatesInteractionHandler @Inject constructor(
|
|||||||
serverPreferences: ServerPreferences
|
serverPreferences: ServerPreferences
|
||||||
) : BaseInteractionHandler(client, serverPreferences) {
|
) : BaseInteractionHandler(client, serverPreferences) {
|
||||||
|
|
||||||
suspend fun getRecentUpdates() = withIOContext {
|
suspend fun getRecentUpdates(pageNum: Int) = withIOContext {
|
||||||
client.get<List<MangaAndChapter>>(
|
client.get<Updates>(
|
||||||
serverUrl + recentUpdatesQuery()
|
serverUrl + recentUpdatesQuery(pageNum)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
package ca.gosyer.data.server.requests
|
package ca.gosyer.data.server.requests
|
||||||
|
|
||||||
@Get
|
@Get
|
||||||
fun recentUpdatesQuery() =
|
fun recentUpdatesQuery(pageNum: Int) =
|
||||||
"/api/v1/update/recentChapters"
|
"/api/v1/update/recentChapters/$pageNum"
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -54,11 +55,16 @@ fun UpdatesMenu(
|
|||||||
LoadingScreen(isLoading)
|
LoadingScreen(isLoading)
|
||||||
} else {
|
} else {
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
items(updates) {
|
itemsIndexed(updates) { index, item ->
|
||||||
val manga = it.manga!!
|
LaunchedEffect(Unit) {
|
||||||
val chapter = it.chapter
|
if (index == updates.lastIndex) {
|
||||||
|
vm.loadNextPage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val manga = item.manga!!
|
||||||
|
val chapter = item.chapter
|
||||||
UpdatesItem(
|
UpdatesItem(
|
||||||
it,
|
item,
|
||||||
onClickItem = { openChapter(chapter.index, chapter.mangaId) },
|
onClickItem = { openChapter(chapter.index, chapter.mangaId) },
|
||||||
onClickCover = { openManga(manga.id) },
|
onClickCover = { openManga(manga.id) },
|
||||||
onClickDownload = vm::downloadChapter,
|
onClickDownload = vm::downloadChapter,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import kotlinx.coroutines.flow.merge
|
import kotlinx.coroutines.flow.merge
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UpdatesMenuViewModel @Inject constructor(
|
class UpdatesMenuViewModel @Inject constructor(
|
||||||
@@ -35,13 +36,42 @@ class UpdatesMenuViewModel @Inject constructor(
|
|||||||
private val _updates = MutableStateFlow<List<ChapterDownloadItem>>(emptyList())
|
private val _updates = MutableStateFlow<List<ChapterDownloadItem>>(emptyList())
|
||||||
val updates = _updates.asStateFlow()
|
val updates = _updates.asStateFlow()
|
||||||
|
|
||||||
|
private val currentPage = MutableStateFlow(1)
|
||||||
|
private val hasNextPage = MutableStateFlow(false)
|
||||||
|
|
||||||
|
private val updatesMutex = Mutex()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
val updates = updatesHandler.getRecentUpdates()
|
getUpdates(1)
|
||||||
mangaIds = updates.map { it.manga.id }.toSet()
|
} catch (e: Exception) {
|
||||||
|
e.throwIfCancellation()
|
||||||
|
} finally {
|
||||||
|
_isLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_updates.value = updates.map {
|
fun loadNextPage() {
|
||||||
|
scope.launch {
|
||||||
|
if (hasNextPage.value && updatesMutex.tryLock()) {
|
||||||
|
try {
|
||||||
|
getUpdates(currentPage.value++)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.throwIfCancellation()
|
||||||
|
currentPage.value--
|
||||||
|
}
|
||||||
|
updatesMutex.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getUpdates(pageNum: Int) {
|
||||||
|
val updates = updatesHandler.getRecentUpdates(pageNum)
|
||||||
|
mangaIds = updates.page.map { it.manga.id }.toSet()
|
||||||
|
|
||||||
|
_updates.value += updates.page.map {
|
||||||
ChapterDownloadItem(
|
ChapterDownloadItem(
|
||||||
it.manga,
|
it.manga,
|
||||||
it.chapter
|
it.chapter
|
||||||
@@ -55,12 +85,8 @@ class UpdatesMenuViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(scope)
|
||||||
} catch (e: Exception) {
|
|
||||||
e.throwIfCancellation()
|
hasNextPage.value = updates.hasNextPage
|
||||||
} finally {
|
|
||||||
_isLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun downloadChapter(chapter: Chapter) {
|
fun downloadChapter(chapter: Chapter) {
|
||||||
|
|||||||
Reference in New Issue
Block a user