mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2025-12-10 06:42:05 +01:00
Use interactors for chapter data calls
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class DeleteChapterDownload @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(mangaId: Long, index: Int) = asFlow(mangaId, index)
|
||||||
|
.catch { log.warn(it) { "Failed to delete chapter download for $index of $mangaId" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(manga: Manga, index: Int) = asFlow(manga, index)
|
||||||
|
.catch { log.warn(it) { "Failed to delete chapter download for $index of ${manga.title}(${manga.id})" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(chapter: Chapter) = asFlow(chapter)
|
||||||
|
.catch { log.warn(it) { "Failed to delete chapter download for ${chapter.index} of ${chapter.mangaId}" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
fun asFlow(mangaId: Long, index: Int) = chapterRepository.deleteChapterDownload(mangaId, index)
|
||||||
|
|
||||||
|
fun asFlow(manga: Manga, index: Int) = chapterRepository.deleteChapterDownload(manga.id, index)
|
||||||
|
|
||||||
|
fun asFlow(chapter: Chapter) = chapterRepository.deleteChapterDownload(chapter.mangaId, chapter.index)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.singleOrNull
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class GetChapter @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(mangaId: Long, index: Int) = asFlow(mangaId, index)
|
||||||
|
.catch { log.warn(it) { "Failed to get chapter $index for $mangaId" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
suspend fun await(manga: Manga, index: Int) = asFlow(manga, index)
|
||||||
|
.catch { log.warn(it) { "Failed to get chapter $index for ${manga.title}(${manga.id})" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
suspend fun await(chapter: Chapter) = asFlow(chapter)
|
||||||
|
.catch { log.warn(it) { "Failed to get chapter ${chapter.index} for ${chapter.mangaId}" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
fun asFlow(mangaId: Long, index: Int) = chapterRepository.getChapter(mangaId, index)
|
||||||
|
|
||||||
|
fun asFlow(manga: Manga, index: Int) = chapterRepository.getChapter(manga.id, index)
|
||||||
|
|
||||||
|
fun asFlow(chapter: Chapter) = chapterRepository.getChapter(chapter.mangaId, chapter.index)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import io.ktor.client.request.HttpRequestBuilder
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.singleOrNull
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class GetChapterPage @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
pageNum: Int,
|
||||||
|
block: HttpRequestBuilder.() -> Unit
|
||||||
|
) = asFlow(mangaId, index, pageNum, block)
|
||||||
|
.catch { log.warn(it) { "Failed to get page $pageNum for chapter $index for $mangaId" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
pageNum: Int,
|
||||||
|
block: HttpRequestBuilder.() -> Unit
|
||||||
|
) = asFlow(manga, index, pageNum, block)
|
||||||
|
.catch { log.warn(it) { "Failed to get page $pageNum for chapter $index for ${manga.title}(${manga.id})" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
suspend fun await(
|
||||||
|
chapter: Chapter,
|
||||||
|
pageNum: Int,
|
||||||
|
block: HttpRequestBuilder.() -> Unit
|
||||||
|
) = asFlow(chapter, pageNum, block)
|
||||||
|
.catch { log.warn(it) { "Failed to get page $pageNum for chapter ${chapter.index} for ${chapter.mangaId}" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
pageNum: Int,
|
||||||
|
block: HttpRequestBuilder.() -> Unit
|
||||||
|
) = chapterRepository.getPage(mangaId, index, pageNum, block)
|
||||||
|
|
||||||
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
pageNum: Int,
|
||||||
|
block: HttpRequestBuilder.() -> Unit
|
||||||
|
) = chapterRepository.getPage(manga.id, index, pageNum, block)
|
||||||
|
|
||||||
|
fun asFlow(
|
||||||
|
chapter: Chapter,
|
||||||
|
pageNum: Int,
|
||||||
|
block: HttpRequestBuilder.() -> Unit
|
||||||
|
) = chapterRepository.getPage(chapter.mangaId, chapter.index, pageNum, block)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import ca.gosyer.jui.domain.manga.service.MangaRepository
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.singleOrNull
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class GetChapters @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(mangaId: Long) = asFlow(mangaId)
|
||||||
|
.catch { log.warn(it) { "Failed to get chapters for $mangaId" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
suspend fun await(manga: Manga) = asFlow(manga)
|
||||||
|
.catch { log.warn(it) { "Failed to get chapters for ${manga.title}(${manga.id})" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
fun asFlow(mangaId: Long) = chapterRepository.getChapters(mangaId)
|
||||||
|
|
||||||
|
fun asFlow(manga: Manga) = chapterRepository.getChapters(manga.id)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class QueueChapterDownload @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(mangaId: Long, index: Int) = asFlow(mangaId, index)
|
||||||
|
.catch { log.warn(it) { "Failed to queue chapter $index of $mangaId for a download" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(manga: Manga, index: Int) = asFlow(manga, index)
|
||||||
|
.catch { log.warn(it) { "Failed to queue chapter $index of ${manga.title}(${manga.id}) for a download" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(chapter: Chapter) = asFlow(chapter)
|
||||||
|
.catch { log.warn(it) { "Failed to queue chapter ${chapter.index} of ${chapter.mangaId} for a download" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
fun asFlow(mangaId: Long, index: Int) = chapterRepository.queueChapterDownload(mangaId, index)
|
||||||
|
|
||||||
|
fun asFlow(manga: Manga, index: Int) = chapterRepository.queueChapterDownload(manga.id, index)
|
||||||
|
|
||||||
|
fun asFlow(chapter: Chapter) = chapterRepository.queueChapterDownload(chapter.mangaId, chapter.index)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.singleOrNull
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class RefreshChapters @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(mangaId: Long) = asFlow(mangaId)
|
||||||
|
.catch { log.warn(it) { "Failed to refresh chapters for $mangaId" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
suspend fun await(manga: Manga) = asFlow(manga)
|
||||||
|
.catch { log.warn(it) { "Failed to refresh chapters for ${manga.title}(${manga.id})" } }
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
|
fun asFlow(mangaId: Long) = chapterRepository.getChapters(mangaId, true)
|
||||||
|
|
||||||
|
fun asFlow(manga: Manga) = chapterRepository.getChapters(manga.id, true)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.singleOrNull
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class StopChapterDownload @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(mangaId: Long, index: Int) = asFlow(mangaId, index)
|
||||||
|
.catch { log.warn(it) { "Failed to stop chapter download for $index of $mangaId" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(manga: Manga, index: Int) = asFlow(manga, index)
|
||||||
|
.catch { log.warn(it) { "Failed to stop chapter download for $index of ${manga.title}(${manga.id})" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(chapter: Chapter) = asFlow(chapter)
|
||||||
|
.catch { log.warn(it) { "Failed to stop chapter download for ${chapter.index} of ${chapter.mangaId}" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
fun asFlow(mangaId: Long, index: Int) = chapterRepository.stopChapterDownload(mangaId, index)
|
||||||
|
|
||||||
|
fun asFlow(manga: Manga, index: Int) = chapterRepository.stopChapterDownload(manga.id, index)
|
||||||
|
|
||||||
|
fun asFlow(chapter: Chapter) = chapterRepository.stopChapterDownload(chapter.mangaId, chapter.index)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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.jui.domain.chapter.interactor
|
||||||
|
|
||||||
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
|
import ca.gosyer.jui.domain.chapter.service.ChapterRepository
|
||||||
|
import ca.gosyer.jui.domain.manga.model.Manga
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import me.tatarka.inject.annotations.Inject
|
||||||
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
|
class UpdateChapterFlags @Inject constructor(private val chapterRepository: ChapterRepository) {
|
||||||
|
|
||||||
|
suspend fun await(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
read: Boolean? = null,
|
||||||
|
bookmarked: Boolean? = null,
|
||||||
|
lastPageRead: Int? = null,
|
||||||
|
markPreviousRead: Boolean? = null
|
||||||
|
) = asFlow(mangaId, index, read, bookmarked, lastPageRead, markPreviousRead)
|
||||||
|
.catch { log.warn(it) { "Failed to update chapter flags for chapter $index of $mangaId" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
read: Boolean? = null,
|
||||||
|
bookmarked: Boolean? = null,
|
||||||
|
lastPageRead: Int? = null,
|
||||||
|
markPreviousRead: Boolean? = null
|
||||||
|
) = asFlow(manga, index, read, bookmarked, lastPageRead, markPreviousRead)
|
||||||
|
.catch { log.warn(it) { "Failed to update chapter flags for chapter $index of ${manga.title}(${manga.id})" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
suspend fun await(
|
||||||
|
chapter: Chapter,
|
||||||
|
read: Boolean? = null,
|
||||||
|
bookmarked: Boolean? = null,
|
||||||
|
lastPageRead: Int? = null,
|
||||||
|
markPreviousRead: Boolean? = null
|
||||||
|
) = asFlow(chapter, read, bookmarked, lastPageRead, markPreviousRead)
|
||||||
|
.catch { log.warn(it) { "Failed to update chapter flags for chapter ${chapter.index} of ${chapter.mangaId}" } }
|
||||||
|
.collect()
|
||||||
|
|
||||||
|
fun asFlow(
|
||||||
|
mangaId: Long,
|
||||||
|
index: Int,
|
||||||
|
read: Boolean? = null,
|
||||||
|
bookmarked: Boolean? = null,
|
||||||
|
lastPageRead: Int? = null,
|
||||||
|
markPreviousRead: Boolean? = null
|
||||||
|
) = chapterRepository.updateChapter(
|
||||||
|
mangaId = mangaId,
|
||||||
|
chapterIndex = index,
|
||||||
|
read = read,
|
||||||
|
bookmarked = bookmarked,
|
||||||
|
lastPageRead = lastPageRead,
|
||||||
|
markPreviousRead = markPreviousRead
|
||||||
|
)
|
||||||
|
|
||||||
|
fun asFlow(
|
||||||
|
manga: Manga,
|
||||||
|
index: Int,
|
||||||
|
read: Boolean? = null,
|
||||||
|
bookmarked: Boolean? = null,
|
||||||
|
lastPageRead: Int? = null,
|
||||||
|
markPreviousRead: Boolean? = null
|
||||||
|
) = chapterRepository.updateChapter(
|
||||||
|
mangaId = manga.id,
|
||||||
|
chapterIndex = index,
|
||||||
|
read = read,
|
||||||
|
bookmarked = bookmarked,
|
||||||
|
lastPageRead = lastPageRead,
|
||||||
|
markPreviousRead = markPreviousRead
|
||||||
|
)
|
||||||
|
|
||||||
|
fun asFlow(
|
||||||
|
chapter: Chapter,
|
||||||
|
read: Boolean? = null,
|
||||||
|
bookmarked: Boolean? = null,
|
||||||
|
lastPageRead: Int? = null,
|
||||||
|
markPreviousRead: Boolean? = null
|
||||||
|
) = chapterRepository.updateChapter(
|
||||||
|
mangaId = chapter.mangaId,
|
||||||
|
chapterIndex = chapter.index,
|
||||||
|
read = read,
|
||||||
|
bookmarked = bookmarked,
|
||||||
|
lastPageRead = lastPageRead,
|
||||||
|
markPreviousRead = markPreviousRead
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val log = logging()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,8 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
|
import ca.gosyer.jui.domain.chapter.interactor.DeleteChapterDownload
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.StopChapterDownload
|
||||||
import ca.gosyer.jui.domain.chapter.model.Chapter
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
import ca.gosyer.jui.domain.download.model.DownloadChapter
|
import ca.gosyer.jui.domain.download.model.DownloadChapter
|
||||||
import ca.gosyer.jui.domain.download.model.DownloadState
|
import ca.gosyer.jui.domain.download.model.DownloadState
|
||||||
@@ -40,11 +41,8 @@ import ca.gosyer.jui.i18n.MR
|
|||||||
import ca.gosyer.jui.uicore.components.DropdownIconButton
|
import ca.gosyer.jui.uicore.components.DropdownIconButton
|
||||||
import ca.gosyer.jui.uicore.components.DropdownMenuItem
|
import ca.gosyer.jui.uicore.components.DropdownMenuItem
|
||||||
import ca.gosyer.jui.uicore.resources.stringResource
|
import ca.gosyer.jui.uicore.resources.stringResource
|
||||||
import io.ktor.client.statement.HttpResponse
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
|
|
||||||
data class ChapterDownloadItem(
|
data class ChapterDownloadItem(
|
||||||
val manga: Manga?,
|
val manga: Manga?,
|
||||||
@@ -74,18 +72,14 @@ data class ChapterDownloadItem(
|
|||||||
_downloadChapterFlow.value = downloadingChapter
|
_downloadChapterFlow.value = downloadingChapter
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteDownload(chapterHandler: ChapterRepositoryImpl): Flow<HttpResponse> {
|
suspend fun deleteDownload(deleteChapterDownload: DeleteChapterDownload) {
|
||||||
return chapterHandler.deleteChapterDownload(chapter.mangaId, chapter.index)
|
deleteChapterDownload.await(chapter)
|
||||||
.onEach {
|
_downloadState.value = ChapterDownloadState.NotDownloaded
|
||||||
_downloadState.value = ChapterDownloadState.NotDownloaded
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopDownloading(chapterHandler: ChapterRepositoryImpl): Flow<HttpResponse> {
|
suspend fun stopDownloading(stopChapterDownload: StopChapterDownload) {
|
||||||
return chapterHandler.stopChapterDownload(chapter.mangaId, chapter.index)
|
stopChapterDownload.await(chapter)
|
||||||
.onEach {
|
_downloadState.value = ChapterDownloadState.NotDownloaded
|
||||||
_downloadState.value = ChapterDownloadState.NotDownloaded
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
|
|
||||||
package ca.gosyer.jui.ui.downloads
|
package ca.gosyer.jui.ui.downloads
|
||||||
|
|
||||||
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
|
|
||||||
import ca.gosyer.jui.domain.base.WebsocketService.Actions
|
import ca.gosyer.jui.domain.base.WebsocketService.Actions
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.QueueChapterDownload
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.StopChapterDownload
|
||||||
import ca.gosyer.jui.domain.chapter.model.Chapter
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
import ca.gosyer.jui.domain.download.interactor.ClearDownloadQueue
|
import ca.gosyer.jui.domain.download.interactor.ClearDownloadQueue
|
||||||
import ca.gosyer.jui.domain.download.interactor.StartDownloading
|
import ca.gosyer.jui.domain.download.interactor.StartDownloading
|
||||||
@@ -19,10 +20,6 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.catch
|
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
@@ -32,7 +29,8 @@ class DownloadsScreenViewModel @Inject constructor(
|
|||||||
private val startDownloading: StartDownloading,
|
private val startDownloading: StartDownloading,
|
||||||
private val stopDownloading: StopDownloading,
|
private val stopDownloading: StopDownloading,
|
||||||
private val clearDownloadQueue: ClearDownloadQueue,
|
private val clearDownloadQueue: ClearDownloadQueue,
|
||||||
private val chapterHandler: ChapterRepositoryImpl,
|
private val queueChapterDownload: QueueChapterDownload,
|
||||||
|
private val stopChapterDownload: StopChapterDownload,
|
||||||
private val contextWrapper: ContextWrapper,
|
private val contextWrapper: ContextWrapper,
|
||||||
standalone: Boolean
|
standalone: Boolean
|
||||||
) : ViewModel(contextWrapper) {
|
) : ViewModel(contextWrapper) {
|
||||||
@@ -60,26 +58,14 @@ class DownloadsScreenViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun stopDownload(chapter: Chapter) {
|
fun stopDownload(chapter: Chapter) {
|
||||||
chapterHandler.stopChapterDownload(chapter.mangaId, chapter.index)
|
scope.launch { stopChapterDownload.await(chapter) }
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error stop chapter download" }
|
|
||||||
}
|
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun moveToBottom(chapter: Chapter) {
|
fun moveToBottom(chapter: Chapter) {
|
||||||
chapterHandler.stopChapterDownload(chapter.mangaId, chapter.index)
|
scope.launch {
|
||||||
.onEach {
|
stopChapterDownload.await(chapter)
|
||||||
chapterHandler.queueChapterDownload(chapter.mangaId, chapter.index)
|
queueChapterDownload.await(chapter)
|
||||||
.catch {
|
}
|
||||||
log.warn(it) { "Error adding download" }
|
|
||||||
}
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error stop chapter download" }
|
|
||||||
}
|
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun restartDownloader() = startDownloadService(contextWrapper, downloadService, Actions.RESTART)
|
fun restartDownloader() = startDownloadService(contextWrapper, downloadService, Actions.RESTART)
|
||||||
|
|||||||
@@ -8,12 +8,17 @@ package ca.gosyer.jui.ui.manga
|
|||||||
|
|
||||||
import ca.gosyer.jui.core.lang.withIOContext
|
import ca.gosyer.jui.core.lang.withIOContext
|
||||||
import ca.gosyer.jui.data.base.DateHandler
|
import ca.gosyer.jui.data.base.DateHandler
|
||||||
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
|
|
||||||
import ca.gosyer.jui.domain.category.interactor.AddMangaToCategory
|
import ca.gosyer.jui.domain.category.interactor.AddMangaToCategory
|
||||||
import ca.gosyer.jui.domain.category.interactor.GetCategories
|
import ca.gosyer.jui.domain.category.interactor.GetCategories
|
||||||
import ca.gosyer.jui.domain.category.interactor.GetMangaCategories
|
import ca.gosyer.jui.domain.category.interactor.GetMangaCategories
|
||||||
import ca.gosyer.jui.domain.category.interactor.RemoveMangaFromCategory
|
import ca.gosyer.jui.domain.category.interactor.RemoveMangaFromCategory
|
||||||
import ca.gosyer.jui.domain.category.model.Category
|
import ca.gosyer.jui.domain.category.model.Category
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.DeleteChapterDownload
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.GetChapters
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.QueueChapterDownload
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.RefreshChapters
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.StopChapterDownload
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.UpdateChapterFlags
|
||||||
import ca.gosyer.jui.domain.chapter.model.Chapter
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
import ca.gosyer.jui.domain.download.service.DownloadService
|
import ca.gosyer.jui.domain.download.service.DownloadService
|
||||||
import ca.gosyer.jui.domain.library.interactor.AddMangaToLibrary
|
import ca.gosyer.jui.domain.library.interactor.AddMangaToLibrary
|
||||||
@@ -31,11 +36,9 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.mapLatest
|
import kotlinx.coroutines.flow.mapLatest
|
||||||
import kotlinx.coroutines.flow.single
|
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import me.tatarka.inject.annotations.Inject
|
import me.tatarka.inject.annotations.Inject
|
||||||
@@ -45,7 +48,12 @@ class MangaScreenViewModel @Inject constructor(
|
|||||||
private val dateHandler: DateHandler,
|
private val dateHandler: DateHandler,
|
||||||
private val getManga: GetManga,
|
private val getManga: GetManga,
|
||||||
private val refreshManga: RefreshManga,
|
private val refreshManga: RefreshManga,
|
||||||
private val chapterHandler: ChapterRepositoryImpl,
|
private val getChapters: GetChapters,
|
||||||
|
private val refreshChapters: RefreshChapters,
|
||||||
|
private val updateChapterFlags: UpdateChapterFlags,
|
||||||
|
private val queueChapterDownload: QueueChapterDownload,
|
||||||
|
private val stopChapterDownload: StopChapterDownload,
|
||||||
|
private val deleteChapterDownload: DeleteChapterDownload,
|
||||||
private val getCategories: GetCategories,
|
private val getCategories: GetCategories,
|
||||||
private val getMangaCategories: GetMangaCategories,
|
private val getMangaCategories: GetMangaCategories,
|
||||||
private val addMangaToCategory: AddMangaToCategory,
|
private val addMangaToCategory: AddMangaToCategory,
|
||||||
@@ -138,23 +146,31 @@ class MangaScreenViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
if (manga != null) {
|
if (manga != null) {
|
||||||
_manga.value = manga
|
_manga.value = manga
|
||||||
|
} else {
|
||||||
|
// TODO: 2022-07-01 Error toast
|
||||||
|
}
|
||||||
|
|
||||||
|
val mangaCategories = getMangaCategories.await(mangaId)
|
||||||
|
if (mangaCategories != null) {
|
||||||
|
_mangaCategories.value = mangaCategories
|
||||||
|
} else {
|
||||||
|
// TODO: 2022-07-01 Error toast
|
||||||
}
|
}
|
||||||
getMangaCategories.await(mangaId)
|
|
||||||
?.let {
|
|
||||||
_mangaCategories.value = it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun refreshChaptersAsync(mangaId: Long, refresh: Boolean = false) = withIOContext {
|
private suspend fun refreshChaptersAsync(mangaId: Long, refresh: Boolean = false) = withIOContext {
|
||||||
async {
|
async {
|
||||||
_chapters.value = chapterHandler.getChapters(mangaId, refresh)
|
val chapters = if (refresh) {
|
||||||
.catch {
|
refreshChapters.await(mangaId)
|
||||||
log.warn(it) { "Error getting chapters" }
|
} else {
|
||||||
emit(emptyList())
|
getChapters.await(mangaId)
|
||||||
}
|
}
|
||||||
.single()
|
if (chapters != null) {
|
||||||
.toDownloadChapters()
|
_chapters.value = chapters.toDownloadChapters()
|
||||||
|
} else {
|
||||||
|
// TODO: 2022-07-01 Error toast
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,48 +209,24 @@ class MangaScreenViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun findChapter(index: Int) = chapters.value.find { it.chapter.index == index }?.chapter
|
||||||
|
|
||||||
fun toggleRead(index: Int) {
|
fun toggleRead(index: Int) {
|
||||||
|
val chapter = findChapter(index) ?: return
|
||||||
scope.launch {
|
scope.launch {
|
||||||
manga.value?.let { manga ->
|
manga.value?.let { manga ->
|
||||||
chapterHandler.updateChapter(
|
updateChapterFlags.await(manga, index, read = chapter.read.not())
|
||||||
manga.id,
|
refreshChaptersAsync(manga.id).await()
|
||||||
index,
|
|
||||||
read = !_chapters.value.first { it.chapter.index == index }.chapter.read
|
|
||||||
)
|
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error toggling read" }
|
|
||||||
}
|
|
||||||
.collect()
|
|
||||||
_chapters.value = chapterHandler.getChapters(manga.id)
|
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error getting new chapters after toggling read" }
|
|
||||||
emit(emptyList())
|
|
||||||
}
|
|
||||||
.single()
|
|
||||||
.toDownloadChapters()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleBookmarked(index: Int) {
|
fun toggleBookmarked(index: Int) {
|
||||||
|
val chapter = findChapter(index) ?: return
|
||||||
scope.launch {
|
scope.launch {
|
||||||
manga.value?.let { manga ->
|
manga.value?.let { manga ->
|
||||||
chapterHandler.updateChapter(
|
updateChapterFlags.await(manga, index, bookmarked = chapter.bookmarked.not())
|
||||||
manga.id,
|
refreshChaptersAsync(manga.id).await()
|
||||||
index,
|
|
||||||
bookmarked = !_chapters.value.first { it.chapter.index == index }.chapter.bookmarked
|
|
||||||
)
|
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error toggling bookmarked" }
|
|
||||||
}
|
|
||||||
.collect()
|
|
||||||
_chapters.value = chapterHandler.getChapters(manga.id)
|
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error getting new chapters after toggling bookmarked" }
|
|
||||||
emit(emptyList())
|
|
||||||
}
|
|
||||||
.single()
|
|
||||||
.toDownloadChapters()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,48 +234,30 @@ class MangaScreenViewModel @Inject constructor(
|
|||||||
fun markPreviousRead(index: Int) {
|
fun markPreviousRead(index: Int) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
manga.value?.let { manga ->
|
manga.value?.let { manga ->
|
||||||
chapterHandler.updateChapter(manga.id, index, markPreviousRead = true)
|
updateChapterFlags.await(manga, index, markPreviousRead = true)
|
||||||
.catch {
|
refreshChaptersAsync(manga.id).await()
|
||||||
log.warn(it) { "Error marking previous as read" }
|
|
||||||
}
|
|
||||||
.collect()
|
|
||||||
_chapters.value = chapterHandler.getChapters(manga.id)
|
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error getting new chapters after marking previous as read" }
|
|
||||||
emit(emptyList())
|
|
||||||
}
|
|
||||||
.single()
|
|
||||||
.toDownloadChapters()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun downloadChapter(index: Int) {
|
fun downloadChapter(index: Int) {
|
||||||
manga.value?.let { manga ->
|
manga.value?.let { manga ->
|
||||||
chapterHandler.queueChapterDownload(manga.id, index)
|
scope.launch { queueChapterDownload.await(manga, index) }
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error downloading chapter" }
|
|
||||||
}
|
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteDownload(index: Int) {
|
fun deleteDownload(index: Int) {
|
||||||
chapters.value.find { it.chapter.index == index }
|
scope.launch {
|
||||||
?.deleteDownload(chapterHandler)
|
chapters.value.find { it.chapter.index == index }
|
||||||
?.catch {
|
?.deleteDownload(deleteChapterDownload)
|
||||||
log.warn(it) { "Error deleting download" }
|
}
|
||||||
}
|
|
||||||
?.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopDownloadingChapter(index: Int) {
|
fun stopDownloadingChapter(index: Int) {
|
||||||
chapters.value.find { it.chapter.index == index }
|
scope.launch {
|
||||||
?.stopDownloading(chapterHandler)
|
chapters.value.find { it.chapter.index == index }
|
||||||
?.catch {
|
?.stopDownloading(stopChapterDownload)
|
||||||
log.warn(it) { "Error stopping download" }
|
}
|
||||||
}
|
|
||||||
?.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Chapter>.toDownloadChapters() = map {
|
private fun List<Chapter>.toDownloadChapters() = map {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package ca.gosyer.jui.ui.reader
|
package ca.gosyer.jui.ui.reader
|
||||||
|
|
||||||
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
|
import ca.gosyer.jui.domain.chapter.interactor.GetChapterPage
|
||||||
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
|
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
|
||||||
import ca.gosyer.jui.ui.reader.loader.TachideskPageLoader
|
import ca.gosyer.jui.ui.reader.loader.TachideskPageLoader
|
||||||
import ca.gosyer.jui.ui.reader.model.ReaderChapter
|
import ca.gosyer.jui.ui.reader.model.ReaderChapter
|
||||||
@@ -20,7 +20,7 @@ import org.lighthousegames.logging.logging
|
|||||||
|
|
||||||
class ChapterLoader(
|
class ChapterLoader(
|
||||||
private val readerPreferences: ReaderPreferences,
|
private val readerPreferences: ReaderPreferences,
|
||||||
private val chapterHandler: ChapterRepositoryImpl
|
private val getChapterPage: GetChapterPage
|
||||||
) {
|
) {
|
||||||
fun loadChapter(chapter: ReaderChapter): StateFlow<List<ReaderPage>> {
|
fun loadChapter(chapter: ReaderChapter): StateFlow<List<ReaderPage>> {
|
||||||
if (chapterIsReady(chapter)) {
|
if (chapterIsReady(chapter)) {
|
||||||
@@ -29,7 +29,7 @@ class ChapterLoader(
|
|||||||
chapter.state = ReaderChapter.State.Loading
|
chapter.state = ReaderChapter.State.Loading
|
||||||
log.debug { "Loading pages for ${chapter.chapter.name}" }
|
log.debug { "Loading pages for ${chapter.chapter.name}" }
|
||||||
|
|
||||||
val loader = TachideskPageLoader(chapter, readerPreferences, chapterHandler)
|
val loader = TachideskPageLoader(chapter, readerPreferences, getChapterPage)
|
||||||
|
|
||||||
val pages = loader.getPages()
|
val pages = loader.getPages()
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ package ca.gosyer.jui.ui.reader
|
|||||||
|
|
||||||
import ca.gosyer.jui.core.lang.launchDefault
|
import ca.gosyer.jui.core.lang.launchDefault
|
||||||
import ca.gosyer.jui.core.prefs.getAsFlow
|
import ca.gosyer.jui.core.prefs.getAsFlow
|
||||||
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
|
import ca.gosyer.jui.domain.chapter.interactor.GetChapter
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.GetChapterPage
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.GetChapters
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.UpdateChapterFlags
|
||||||
import ca.gosyer.jui.domain.chapter.interactor.UpdateChapterMeta
|
import ca.gosyer.jui.domain.chapter.interactor.UpdateChapterMeta
|
||||||
import ca.gosyer.jui.domain.chapter.model.Chapter
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
import ca.gosyer.jui.domain.manga.interactor.GetManga
|
import ca.gosyer.jui.domain.manga.interactor.GetManga
|
||||||
@@ -51,7 +54,10 @@ import org.lighthousegames.logging.logging
|
|||||||
class ReaderMenuViewModel @Inject constructor(
|
class ReaderMenuViewModel @Inject constructor(
|
||||||
private val readerPreferences: ReaderPreferences,
|
private val readerPreferences: ReaderPreferences,
|
||||||
private val getManga: GetManga,
|
private val getManga: GetManga,
|
||||||
private val chapterHandler: ChapterRepositoryImpl,
|
private val getChapters: GetChapters,
|
||||||
|
private val getChapter: GetChapter,
|
||||||
|
private val getChapterPage: GetChapterPage,
|
||||||
|
private val updateChapterFlags: UpdateChapterFlags,
|
||||||
private val updateMangaMeta: UpdateMangaMeta,
|
private val updateMangaMeta: UpdateMangaMeta,
|
||||||
private val updateChapterMeta: UpdateChapterMeta,
|
private val updateChapterMeta: UpdateChapterMeta,
|
||||||
contextWrapper: ContextWrapper,
|
contextWrapper: ContextWrapper,
|
||||||
@@ -101,7 +107,7 @@ class ReaderMenuViewModel @Inject constructor(
|
|||||||
|
|
||||||
val readerModeSettings = ReaderModeWatch(readerPreferences, scope, readerMode)
|
val readerModeSettings = ReaderModeWatch(readerPreferences, scope, readerMode)
|
||||||
|
|
||||||
private val loader = ChapterLoader(readerPreferences, chapterHandler)
|
private val loader = ChapterLoader(readerPreferences, getChapterPage)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
init()
|
init()
|
||||||
@@ -217,7 +223,7 @@ class ReaderMenuViewModel @Inject constructor(
|
|||||||
private suspend fun initChapters(mangaId: Long, chapterIndex: Int) {
|
private suspend fun initChapters(mangaId: Long, chapterIndex: Int) {
|
||||||
resetValues()
|
resetValues()
|
||||||
val chapter = ReaderChapter(
|
val chapter = ReaderChapter(
|
||||||
chapterHandler.getChapter(mangaId, chapterIndex)
|
getChapter.asFlow(mangaId, chapterIndex)
|
||||||
.catch {
|
.catch {
|
||||||
_state.value = ReaderChapter.State.Error(it)
|
_state.value = ReaderChapter.State.Error(it)
|
||||||
log.warn(it) { "Error getting chapter" }
|
log.warn(it) { "Error getting chapter" }
|
||||||
@@ -227,9 +233,10 @@ class ReaderMenuViewModel @Inject constructor(
|
|||||||
val pages = loader.loadChapter(chapter)
|
val pages = loader.loadChapter(chapter)
|
||||||
viewerChapters.currChapter.value = chapter
|
viewerChapters.currChapter.value = chapter
|
||||||
scope.launchDefault {
|
scope.launchDefault {
|
||||||
val chapters = chapterHandler.getChapters(mangaId)
|
val chapters = getChapters.asFlow(mangaId)
|
||||||
.catch {
|
.catch {
|
||||||
log.warn(it) { "Error getting chapter list" }
|
log.warn(it) { "Error getting chapter list" }
|
||||||
|
// TODO: 2022-07-01 Error toast
|
||||||
emit(emptyList())
|
emit(emptyList())
|
||||||
}
|
}
|
||||||
.single()
|
.single()
|
||||||
@@ -273,29 +280,21 @@ class ReaderMenuViewModel @Inject constructor(
|
|||||||
.onEach { index ->
|
.onEach { index ->
|
||||||
pages.value.getOrNull(_currentPage.value - 1)?.let { chapter.pageLoader?.loadPage(it) }
|
pages.value.getOrNull(_currentPage.value - 1)?.let { chapter.pageLoader?.loadPage(it) }
|
||||||
if (index == pages.value.size) {
|
if (index == pages.value.size) {
|
||||||
markChapterRead(mangaId, chapter)
|
markChapterRead(chapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(chapter.scope)
|
.launchIn(chapter.scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markChapterRead(mangaId: Long, chapter: ReaderChapter) {
|
private fun markChapterRead(chapter: ReaderChapter) {
|
||||||
chapterHandler.updateChapter(mangaId, chapter.chapter.index, true)
|
scope.launch { updateChapterFlags.await(chapter.chapter, read = true) }
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error marking chapter read" }
|
|
||||||
}
|
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
fun sendProgress(chapter: Chapter? = this.chapter.value?.chapter, lastPageRead: Int = currentPage.value) {
|
fun sendProgress(chapter: Chapter? = this.chapter.value?.chapter, lastPageRead: Int = currentPage.value) {
|
||||||
chapter ?: return
|
chapter ?: return
|
||||||
if (chapter.read) return
|
if (chapter.read) return
|
||||||
chapterHandler.updateChapter(chapter.mangaId, chapter.index, lastPageRead = lastPageRead)
|
GlobalScope.launch { updateChapterFlags.await(chapter, lastPageRead = lastPageRead) }
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error sending progress" }
|
|
||||||
}
|
|
||||||
.launchIn(GlobalScope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateLastPageReadOffset(offset: Int) {
|
fun updateLastPageReadOffset(offset: Int) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ package ca.gosyer.jui.ui.reader.loader
|
|||||||
|
|
||||||
import ca.gosyer.jui.core.lang.IO
|
import ca.gosyer.jui.core.lang.IO
|
||||||
import ca.gosyer.jui.core.lang.throwIfCancellation
|
import ca.gosyer.jui.core.lang.throwIfCancellation
|
||||||
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
|
import ca.gosyer.jui.domain.chapter.interactor.GetChapterPage
|
||||||
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
|
import ca.gosyer.jui.domain.reader.service.ReaderPreferences
|
||||||
import ca.gosyer.jui.ui.reader.model.ReaderChapter
|
import ca.gosyer.jui.ui.reader.model.ReaderChapter
|
||||||
import ca.gosyer.jui.ui.reader.model.ReaderPage
|
import ca.gosyer.jui.ui.reader.model.ReaderPage
|
||||||
@@ -33,7 +33,7 @@ import org.lighthousegames.logging.logging
|
|||||||
class TachideskPageLoader(
|
class TachideskPageLoader(
|
||||||
val chapter: ReaderChapter,
|
val chapter: ReaderChapter,
|
||||||
readerPreferences: ReaderPreferences,
|
readerPreferences: ReaderPreferences,
|
||||||
chapterHandler: ChapterRepositoryImpl
|
getChapterPage: GetChapterPage
|
||||||
) : PageLoader() {
|
) : PageLoader() {
|
||||||
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||||
|
|
||||||
@@ -63,8 +63,7 @@ class TachideskPageLoader(
|
|||||||
val page = priorityPage.page
|
val page = priorityPage.page
|
||||||
log.debug { "Loading page ${page.index}" }
|
log.debug { "Loading page ${page.index}" }
|
||||||
if (page.status.value == ReaderPage.Status.QUEUE) {
|
if (page.status.value == ReaderPage.Status.QUEUE) {
|
||||||
chapterHandler
|
getChapterPage.asFlow(chapter.chapter, page.index) {
|
||||||
.getPage(chapter.chapter.mangaId, chapter.chapter.index, page.index) {
|
|
||||||
onDownload { bytesSentTotal, contentLength ->
|
onDownload { bytesSentTotal, contentLength ->
|
||||||
page.progress.value = (bytesSentTotal.toFloat() / contentLength).coerceAtMost(1.0F)
|
page.progress.value = (bytesSentTotal.toFloat() / contentLength).coerceAtMost(1.0F)
|
||||||
}
|
}
|
||||||
@@ -78,7 +77,7 @@ class TachideskPageLoader(
|
|||||||
page.bitmap.value = null
|
page.bitmap.value = null
|
||||||
page.status.value = ReaderPage.Status.ERROR
|
page.status.value = ReaderPage.Status.ERROR
|
||||||
page.error.value = it.message
|
page.error.value = it.message
|
||||||
log.warn(it) { "Error getting image" }
|
log.warn(it) { "Failed to get page ${page.index} for chapter ${chapter.chapter.index} for ${chapter.chapter.mangaId}" }
|
||||||
}
|
}
|
||||||
.flowOn(Dispatchers.IO)
|
.flowOn(Dispatchers.IO)
|
||||||
.collect()
|
.collect()
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import androidx.compose.runtime.mutableStateListOf
|
|||||||
import androidx.compose.runtime.mutableStateMapOf
|
import androidx.compose.runtime.mutableStateMapOf
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||||
import ca.gosyer.jui.data.chapter.ChapterRepositoryImpl
|
import ca.gosyer.jui.domain.chapter.interactor.DeleteChapterDownload
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.QueueChapterDownload
|
||||||
|
import ca.gosyer.jui.domain.chapter.interactor.StopChapterDownload
|
||||||
import ca.gosyer.jui.domain.chapter.model.Chapter
|
import ca.gosyer.jui.domain.chapter.model.Chapter
|
||||||
import ca.gosyer.jui.domain.download.service.DownloadService
|
import ca.gosyer.jui.domain.download.service.DownloadService
|
||||||
import ca.gosyer.jui.domain.updates.interactor.GetRecentUpdates
|
import ca.gosyer.jui.domain.updates.interactor.GetRecentUpdates
|
||||||
@@ -37,7 +39,9 @@ import me.tatarka.inject.annotations.Inject
|
|||||||
import org.lighthousegames.logging.logging
|
import org.lighthousegames.logging.logging
|
||||||
|
|
||||||
class UpdatesScreenViewModel @Inject constructor(
|
class UpdatesScreenViewModel @Inject constructor(
|
||||||
private val chapterHandler: ChapterRepositoryImpl,
|
private val queueChapterDownload: QueueChapterDownload,
|
||||||
|
private val stopChapterDownload: StopChapterDownload,
|
||||||
|
private val deleteChapterDownload: DeleteChapterDownload,
|
||||||
private val getRecentUpdates: GetRecentUpdates,
|
private val getRecentUpdates: GetRecentUpdates,
|
||||||
contextWrapper: ContextWrapper
|
contextWrapper: ContextWrapper
|
||||||
) : ViewModel(contextWrapper) {
|
) : ViewModel(contextWrapper) {
|
||||||
@@ -117,41 +121,33 @@ class UpdatesScreenViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun downloadChapter(chapter: Chapter) {
|
fun downloadChapter(chapter: Chapter) {
|
||||||
chapterHandler.queueChapterDownload(chapter.mangaId, chapter.index)
|
scope.launch { queueChapterDownload.await(chapter) }
|
||||||
.catch {
|
|
||||||
log.warn(it) { "Error queueing chapter" }
|
|
||||||
}
|
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteDownloadedChapter(chapter: Chapter) {
|
fun deleteDownloadedChapter(chapter: Chapter) {
|
||||||
_updates
|
scope.launch {
|
||||||
.firstNotNullOfOrNull { (_, chapters) ->
|
_updates
|
||||||
chapters.find {
|
.firstNotNullOfOrNull { (_, chapters) ->
|
||||||
it.chapter.mangaId == chapter.mangaId &&
|
chapters.find {
|
||||||
it.chapter.index == chapter.index
|
it.chapter.mangaId == chapter.mangaId &&
|
||||||
|
it.chapter.index == chapter.index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
?.deleteDownload(deleteChapterDownload)
|
||||||
?.deleteDownload(chapterHandler)
|
}
|
||||||
?.catch {
|
|
||||||
log.warn(it) { "Error deleting download" }
|
|
||||||
}
|
|
||||||
?.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopDownloadingChapter(chapter: Chapter) {
|
fun stopDownloadingChapter(chapter: Chapter) {
|
||||||
_updates
|
scope.launch {
|
||||||
.firstNotNullOfOrNull { (_, chapters) ->
|
_updates
|
||||||
chapters.find {
|
.firstNotNullOfOrNull { (_, chapters) ->
|
||||||
it.chapter.mangaId == chapter.mangaId &&
|
chapters.find {
|
||||||
it.chapter.index == chapter.index
|
it.chapter.mangaId == chapter.mangaId &&
|
||||||
|
it.chapter.index == chapter.index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
?.stopDownloading(stopChapterDownload)
|
||||||
?.stopDownloading(chapterHandler)
|
}
|
||||||
?.catch {
|
|
||||||
log.warn(it) { "Error stopping download" }
|
|
||||||
}
|
|
||||||
?.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
|||||||
Reference in New Issue
Block a user