Implement paged updates

This commit is contained in:
Syer10
2021-11-27 12:13:30 -05:00
parent 5dd9808e71
commit 5b74241a19
6 changed files with 77 additions and 30 deletions

View File

@@ -3,9 +3,9 @@ import org.gradle.api.JavaVersion
object Config {
const val tachideskVersion = "v0.5.4"
// Match this to the Tachidesk-Server commit count
const val serverCode = 1031
const val serverCode = 1043
const val preview = true
const val previewCommit = "420d14fc37a18269a9d7232519e3f9a21c6302a2"
const val previewCommit = "5e47b7ae6b37931ce3a8eee33cafb9475d7a77bb"
val jvmTarget = JavaVersion.VERSION_15
}

View File

@@ -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
)

View File

@@ -6,7 +6,7 @@
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.ServerPreferences
import ca.gosyer.data.server.requests.recentUpdatesQuery
@@ -19,9 +19,9 @@ class UpdatesInteractionHandler @Inject constructor(
serverPreferences: ServerPreferences
) : BaseInteractionHandler(client, serverPreferences) {
suspend fun getRecentUpdates() = withIOContext {
client.get<List<MangaAndChapter>>(
serverUrl + recentUpdatesQuery()
suspend fun getRecentUpdates(pageNum: Int) = withIOContext {
client.get<Updates>(
serverUrl + recentUpdatesQuery(pageNum)
)
}
}

View File

@@ -7,5 +7,5 @@
package ca.gosyer.data.server.requests
@Get
fun recentUpdatesQuery() =
"/api/v1/update/recentChapters"
fun recentUpdatesQuery(pageNum: Int) =
"/api/v1/update/recentChapters/$pageNum"

View File

@@ -14,9 +14,10 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
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.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
@@ -54,11 +55,16 @@ fun UpdatesMenu(
LoadingScreen(isLoading)
} else {
LazyColumn {
items(updates) {
val manga = it.manga!!
val chapter = it.chapter
itemsIndexed(updates) { index, item ->
LaunchedEffect(Unit) {
if (index == updates.lastIndex) {
vm.loadNextPage()
}
}
val manga = item.manga!!
val chapter = item.chapter
UpdatesItem(
it,
item,
onClickItem = { openChapter(chapter.index, chapter.mangaId) },
onClickCover = { openManga(manga.id) },
onClickDownload = vm::downloadChapter,

View File

@@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import javax.inject.Inject
class UpdatesMenuViewModel @Inject constructor(
@@ -35,26 +36,15 @@ class UpdatesMenuViewModel @Inject constructor(
private val _updates = MutableStateFlow<List<ChapterDownloadItem>>(emptyList())
val updates = _updates.asStateFlow()
private val currentPage = MutableStateFlow(1)
private val hasNextPage = MutableStateFlow(false)
private val updatesMutex = Mutex()
init {
scope.launch {
try {
val updates = updatesHandler.getRecentUpdates()
mangaIds = updates.map { it.manga.id }.toSet()
_updates.value = updates.map {
ChapterDownloadItem(
it.manga,
it.chapter
)
}
downloadService.registerWatches(mangaIds).merge()
.onEach { (mangaId, chapters) ->
_updates.value.filter { it.chapter.mangaId == mangaId }
.forEach {
it.updateFrom(chapters)
}
}
.launchIn(scope)
getUpdates(1)
} catch (e: Exception) {
e.throwIfCancellation()
} finally {
@@ -63,6 +53,42 @@ class UpdatesMenuViewModel @Inject constructor(
}
}
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(
it.manga,
it.chapter
)
}
downloadService.registerWatches(mangaIds).merge()
.onEach { (mangaId, chapters) ->
_updates.value.filter { it.chapter.mangaId == mangaId }
.forEach {
it.updateFrom(chapters)
}
}
.launchIn(scope)
hasNextPage.value = updates.hasNextPage
}
fun downloadChapter(chapter: Chapter) {
scope.launch {
chapterHandler.queueChapterDownload(chapter)