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 { 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
} }

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

View File

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

View File

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

View File

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