diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/service/ChapterRepository.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/service/ChapterRepository.kt index b193eb9c..cd3b4f64 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/service/ChapterRepository.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/service/ChapterRepository.kt @@ -92,18 +92,6 @@ interface ChapterRepository { @Path("chapterIndex") chapterIndex: Int ): Flow - @GET("api/v1/download/{mangaId}/chapter/{chapterIndex}") - fun queueChapterDownload( - @Path("mangaId") mangaId: Long, - @Path("chapterIndex") chapterIndex: Int - ): Flow - - @DELETE("api/v1/download/{mangaId}/chapter/{chapterIndex}") - fun stopChapterDownload( - @Path("mangaId") mangaId: Long, - @Path("chapterIndex") chapterIndex: Int - ): Flow - @FormUrlEncoded @PATCH("api/v1/manga/{mangaId}/chapter/{chapterIndex}/meta") fun updateChapterMeta( diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/BatchChapterDownload.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/BatchChapterDownload.kt new file mode 100644 index 00000000..527d8000 --- /dev/null +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/BatchChapterDownload.kt @@ -0,0 +1,39 @@ +/* + * 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.download.interactor + +import ca.gosyer.jui.domain.download.model.DownloadEnqueue +import ca.gosyer.jui.domain.download.service.DownloadRepository +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.collect +import me.tatarka.inject.annotations.Inject +import org.lighthousegames.logging.logging + +class BatchChapterDownload @Inject constructor(private val downloadRepository: DownloadRepository) { + + suspend fun await(chapterIds: List, onError: suspend (Throwable) -> Unit = {}) = asFlow(chapterIds) + .catch { + onError(it) + log.warn(it) { "Failed to queue chapters $chapterIds for a download" } + } + .collect() + + suspend fun await(vararg chapterIds: Long, onError: suspend (Throwable) -> Unit = {}) = asFlow(*chapterIds) + .catch { + onError(it) + log.warn(it) { "Failed to queue chapters ${chapterIds.asList()} for a download" } + } + .collect() + + fun asFlow(chapterIds: List) = downloadRepository.batchDownload(DownloadEnqueue(chapterIds)) + + fun asFlow(vararg chapterIds: Long) = downloadRepository.batchDownload(DownloadEnqueue(chapterIds.asList())) + + companion object { + private val log = logging() + } +} \ No newline at end of file diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/interactor/QueueChapterDownload.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/QueueChapterDownload.kt similarity index 72% rename from domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/interactor/QueueChapterDownload.kt rename to domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/QueueChapterDownload.kt index 25555332..a35a6fc3 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/interactor/QueueChapterDownload.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/QueueChapterDownload.kt @@ -4,17 +4,17 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -package ca.gosyer.jui.domain.chapter.interactor +package ca.gosyer.jui.domain.download.interactor import ca.gosyer.jui.domain.chapter.model.Chapter -import ca.gosyer.jui.domain.chapter.service.ChapterRepository +import ca.gosyer.jui.domain.download.service.DownloadRepository 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) { +class QueueChapterDownload @Inject constructor(private val downloadRepository: DownloadRepository) { suspend fun await(mangaId: Long, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, index) .catch { @@ -37,11 +37,11 @@ class QueueChapterDownload @Inject constructor(private val chapterRepository: Ch } .collect() - fun asFlow(mangaId: Long, index: Int) = chapterRepository.queueChapterDownload(mangaId, index) + fun asFlow(mangaId: Long, index: Int) = downloadRepository.queueChapterDownload(mangaId, index) - fun asFlow(manga: Manga, index: Int) = chapterRepository.queueChapterDownload(manga.id, index) + fun asFlow(manga: Manga, index: Int) = downloadRepository.queueChapterDownload(manga.id, index) - fun asFlow(chapter: Chapter) = chapterRepository.queueChapterDownload(chapter.mangaId, chapter.index) + fun asFlow(chapter: Chapter) = downloadRepository.queueChapterDownload(chapter.mangaId, chapter.index) companion object { private val log = logging() diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/interactor/StopChapterDownload.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/StopChapterDownload.kt similarity index 72% rename from domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/interactor/StopChapterDownload.kt rename to domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/StopChapterDownload.kt index ffa6e1c3..ccd01386 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/chapter/interactor/StopChapterDownload.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/interactor/StopChapterDownload.kt @@ -4,17 +4,17 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -package ca.gosyer.jui.domain.chapter.interactor +package ca.gosyer.jui.domain.download.interactor import ca.gosyer.jui.domain.chapter.model.Chapter -import ca.gosyer.jui.domain.chapter.service.ChapterRepository +import ca.gosyer.jui.domain.download.service.DownloadRepository 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 StopChapterDownload @Inject constructor(private val chapterRepository: ChapterRepository) { +class StopChapterDownload @Inject constructor(private val downloadRepository: DownloadRepository) { suspend fun await(mangaId: Long, index: Int, onError: suspend (Throwable) -> Unit = {}) = asFlow(mangaId, index) .catch { @@ -37,11 +37,11 @@ class StopChapterDownload @Inject constructor(private val chapterRepository: Cha } .collect() - fun asFlow(mangaId: Long, index: Int) = chapterRepository.stopChapterDownload(mangaId, index) + fun asFlow(mangaId: Long, index: Int) = downloadRepository.stopChapterDownload(mangaId, index) - fun asFlow(manga: Manga, index: Int) = chapterRepository.stopChapterDownload(manga.id, index) + fun asFlow(manga: Manga, index: Int) = downloadRepository.stopChapterDownload(manga.id, index) - fun asFlow(chapter: Chapter) = chapterRepository.stopChapterDownload(chapter.mangaId, chapter.index) + fun asFlow(chapter: Chapter) = downloadRepository.stopChapterDownload(chapter.mangaId, chapter.index) companion object { private val log = logging() diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/model/DownloadEnqueue.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/model/DownloadEnqueue.kt new file mode 100644 index 00000000..d9d9312e --- /dev/null +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/model/DownloadEnqueue.kt @@ -0,0 +1,14 @@ +/* + * 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.download.model + +import kotlinx.serialization.Serializable + +@Serializable +data class DownloadEnqueue( + val chapterIds: List +) diff --git a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadRepository.kt b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadRepository.kt index 984639f6..b35b1b40 100644 --- a/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadRepository.kt +++ b/domain/src/commonMain/kotlin/ca/gosyer/jui/domain/download/service/DownloadRepository.kt @@ -6,7 +6,13 @@ package ca.gosyer.jui.domain.download.service +import ca.gosyer.jui.domain.download.model.DownloadEnqueue +import de.jensklingenberg.ktorfit.http.Body +import de.jensklingenberg.ktorfit.http.DELETE import de.jensklingenberg.ktorfit.http.GET +import de.jensklingenberg.ktorfit.http.Headers +import de.jensklingenberg.ktorfit.http.POST +import de.jensklingenberg.ktorfit.http.Path import io.ktor.client.statement.HttpResponse import kotlinx.coroutines.flow.Flow @@ -19,4 +25,22 @@ interface DownloadRepository { @GET("api/v1/downloads/clear") fun clearDownloadQueue(): Flow + + @GET("api/v1/download/{mangaId}/chapter/{chapterIndex}") + fun queueChapterDownload( + @Path("mangaId") mangaId: Long, + @Path("chapterIndex") chapterIndex: Int + ): Flow + + @DELETE("api/v1/download/{mangaId}/chapter/{chapterIndex}") + fun stopChapterDownload( + @Path("mangaId") mangaId: Long, + @Path("chapterIndex") chapterIndex: Int + ): Flow + + @POST("api/v1/download/batch") + @Headers("Content-Type: application/json") + fun batchDownload( + @Body downloadEnqueue: DownloadEnqueue + ): Flow } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt index f6ac47c5..5551e54f 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt @@ -33,8 +33,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp 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.download.interactor.StopChapterDownload import ca.gosyer.jui.domain.download.model.DownloadChapter import ca.gosyer.jui.domain.download.model.DownloadState import ca.gosyer.jui.domain.manga.model.Manga diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt index ff4495f9..be4899c9 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt @@ -7,11 +7,11 @@ package ca.gosyer.jui.ui.downloads 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.download.interactor.ClearDownloadQueue +import ca.gosyer.jui.domain.download.interactor.QueueChapterDownload import ca.gosyer.jui.domain.download.interactor.StartDownloading +import ca.gosyer.jui.domain.download.interactor.StopChapterDownload import ca.gosyer.jui.domain.download.interactor.StopDownloading import ca.gosyer.jui.domain.download.service.DownloadService import ca.gosyer.jui.uicore.vm.ContextWrapper diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt index 31a5d89b..5f7c75b9 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt @@ -15,13 +15,13 @@ import ca.gosyer.jui.domain.category.interactor.RemoveMangaFromCategory 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.UpdateChapterBookmarked import ca.gosyer.jui.domain.chapter.interactor.UpdateChapterMarkPreviousRead import ca.gosyer.jui.domain.chapter.interactor.UpdateChapterRead import ca.gosyer.jui.domain.chapter.model.Chapter +import ca.gosyer.jui.domain.download.interactor.QueueChapterDownload +import ca.gosyer.jui.domain.download.interactor.StopChapterDownload import ca.gosyer.jui.domain.download.service.DownloadService import ca.gosyer.jui.domain.library.interactor.AddMangaToLibrary import ca.gosyer.jui.domain.library.interactor.RemoveMangaFromLibrary diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/UpdatesScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/UpdatesScreenViewModel.kt index 3965bb76..010a0472 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/UpdatesScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/updates/UpdatesScreenViewModel.kt @@ -7,9 +7,9 @@ package ca.gosyer.jui.ui.updates 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.download.interactor.QueueChapterDownload +import ca.gosyer.jui.domain.download.interactor.StopChapterDownload import ca.gosyer.jui.domain.download.service.DownloadService import ca.gosyer.jui.domain.updates.interactor.GetRecentUpdates import ca.gosyer.jui.ui.base.chapter.ChapterDownloadItem