diff --git a/app/src/main/java/eu/kanade/domain/DomainModule.kt b/app/src/main/java/eu/kanade/domain/DomainModule.kt index 733283a26..a7c136368 100644 --- a/app/src/main/java/eu/kanade/domain/DomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/DomainModule.kt @@ -60,6 +60,7 @@ import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.interactor.SetSortModeForCategory import tachiyomi.domain.category.interactor.UpdateCategory import tachiyomi.domain.category.repository.CategoryRepository +import tachiyomi.domain.chapter.interactor.GetBookmarkedChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChapter import tachiyomi.domain.chapter.interactor.GetChapterByUrlAndMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId @@ -156,6 +157,7 @@ class DomainModule : InjektModule { addSingletonFactory { ChapterRepositoryImpl(get()) } addFactory { GetChapter(get()) } addFactory { GetChaptersByMangaId(get()) } + addFactory { GetBookmarkedChaptersByMangaId(get(), get(), get()) } addFactory { GetChapterByUrlAndMangaId(get()) } addFactory { UpdateChapter(get()) } addFactory { SetReadStatus(get(), get(), get(), get(), get()) } diff --git a/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt b/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt index e3391ec5a..b6cebc932 100644 --- a/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt +++ b/app/src/main/java/eu/kanade/presentation/components/DownloadDropdownMenu.kt @@ -1,6 +1,5 @@ package eu.kanade.presentation.components -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -14,11 +13,11 @@ import tachiyomi.presentation.core.i18n.stringResource @Composable fun DownloadDropdownMenu( + modifier: Modifier = Modifier, expanded: Boolean, onDismissRequest: () -> Unit, onDownloadClicked: (DownloadAction) -> Unit, offset: DpOffset? = null, - modifier: Modifier = Modifier, ) { if (offset != null) { DropdownMenu( @@ -49,7 +48,7 @@ fun DownloadDropdownMenu( } @Composable -private fun ColumnScope.DownloadDropdownMenuItems( +private fun DownloadDropdownMenuItems( onDismissRequest: () -> Unit, onDownloadClicked: (DownloadAction) -> Unit, ) { @@ -59,6 +58,7 @@ private fun ColumnScope.DownloadDropdownMenuItems( DownloadAction.NEXT_10_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 10, 10), DownloadAction.NEXT_25_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 25, 25), DownloadAction.UNREAD_CHAPTERS to stringResource(MR.strings.download_unread), + DownloadAction.BOOKMARKED_CHAPTERS to stringResource(MR.strings.download_bookmarked), ) options.map { (downloadAction, string) -> diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt index f4671eef4..1ba235657 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreenConstants.kt @@ -6,6 +6,7 @@ enum class DownloadAction { NEXT_10_CHAPTERS, NEXT_25_CHAPTERS, UNREAD_CHAPTERS, + BOOKMARKED_CHAPTERS, } enum class EditCoverAction { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt index 14ebba850..b89beb2bb 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt @@ -84,6 +84,7 @@ import tachiyomi.core.common.util.lang.launchNonCancellable import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.model.Category +import tachiyomi.domain.chapter.interactor.GetBookmarkedChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetMergedChaptersByMangaId import tachiyomi.domain.chapter.model.Chapter @@ -122,6 +123,7 @@ class LibraryScreenModel( private val getTracksPerManga: GetTracksPerManga = Injekt.get(), private val getNextChapters: GetNextChapters = Injekt.get(), private val getChaptersByMangaId: GetChaptersByMangaId = Injekt.get(), + private val getBookmarkedChaptersByMangaId: GetBookmarkedChaptersByMangaId = Injekt.get(), private val setReadStatus: SetReadStatus = Injekt.get(), private val updateManga: UpdateManga = Injekt.get(), private val setMangaCategories: SetMangaCategories = Injekt.get(), @@ -734,15 +736,19 @@ class LibraryScreenModel( * Queues the amount specified of unread chapters from the list of selected manga */ fun performDownloadAction(action: DownloadAction) { - val mangas = state.value.selectedManga - val amount = when (action) { - DownloadAction.NEXT_1_CHAPTER -> 1 - DownloadAction.NEXT_5_CHAPTERS -> 5 - DownloadAction.NEXT_10_CHAPTERS -> 10 - DownloadAction.NEXT_25_CHAPTERS -> 25 - DownloadAction.UNREAD_CHAPTERS -> null + when (action) { + DownloadAction.NEXT_1_CHAPTER -> downloadNextChapters(1) + DownloadAction.NEXT_5_CHAPTERS -> downloadNextChapters(5) + DownloadAction.NEXT_10_CHAPTERS -> downloadNextChapters(10) + DownloadAction.NEXT_25_CHAPTERS -> downloadNextChapters(25) + DownloadAction.UNREAD_CHAPTERS -> downloadNextChapters(null) + DownloadAction.BOOKMARKED_CHAPTERS -> downloadBookmarkedChapters() } clearSelection() + } + + private fun downloadNextChapters(amount: Int?) { + val mangas = state.value.selectedManga screenModelScope.launchNonCancellable { mangas.forEach { manga -> // SY --> @@ -792,6 +798,54 @@ class LibraryScreenModel( } } + private fun downloadBookmarkedChapters() { + val mangas = state.value.selectedManga + screenModelScope.launchNonCancellable { + mangas.forEach { manga -> + // SY --> + if (manga.source == MERGED_SOURCE_ID) { + val mergedMangas = getMergedMangaById.await(manga.id) + .associateBy { it.id } + getBookmarkedChaptersByMangaId.await(manga.id) + .groupBy { it.mangaId } + .forEach ab@{ (mangaId, chapters) -> + val mergedManga = mergedMangas[mangaId] ?: return@ab + val downloadChapters = chapters.fastFilterNot { chapter -> + downloadManager.queueState.value.fastAny { chapter.id == it.chapter.id } || + downloadManager.isChapterDownloaded( + chapter.name, + chapter.scanlator, + chapter.url, + mergedManga.ogTitle, + mergedManga.source, + ) + } + + downloadManager.downloadChapters(mergedManga, downloadChapters) + } + + return@forEach + } + // SY <-- + + val chapters = getBookmarkedChaptersByMangaId.await(manga.id) + .fastFilterNot { chapter -> + downloadManager.getQueuedDownloadOrNull(chapter.id) != null || + downloadManager.isChapterDownloaded( + chapter.name, + chapter.scanlator, + chapter.url, + // SY --> + manga.ogTitle, + // SY <-- + manga.source, + ) + } + downloadManager.downloadChapters(manga, chapters) + } + } + } + // SY --> fun cleanTitles() { state.value.selectedManga.fastFilter { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index 8da38535f..436c9ed29 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -1175,6 +1175,13 @@ class MangaScreenModel( return if (manga.sortDescending()) chaptersSorted.reversed() else chaptersSorted } + private fun getBookmarkedChapters(): List { + val chapterItems = if (skipFiltered) filteredChapters.orEmpty() else allChapters.orEmpty() + return chapterItems + .filter { (chapter, dlStatus) -> chapter.bookmark && dlStatus == Download.State.NOT_DOWNLOADED } + .map { it.chapter } + } + private fun startDownload( chapters: List, startNow: Boolean, @@ -1237,6 +1244,7 @@ class MangaScreenModel( DownloadAction.NEXT_10_CHAPTERS -> getUnreadChaptersSorted().take(10) DownloadAction.NEXT_25_CHAPTERS -> getUnreadChaptersSorted().take(25) DownloadAction.UNREAD_CHAPTERS -> getUnreadChapters() + DownloadAction.BOOKMARKED_CHAPTERS -> getBookmarkedChapters() } if (chaptersToDownload.isNotEmpty()) { startDownload(chaptersToDownload, false) diff --git a/domain/src/main/java/tachiyomi/domain/chapter/interactor/GetBookmarkedChaptersByMangaId.kt b/domain/src/main/java/tachiyomi/domain/chapter/interactor/GetBookmarkedChaptersByMangaId.kt new file mode 100644 index 000000000..b70d5895d --- /dev/null +++ b/domain/src/main/java/tachiyomi/domain/chapter/interactor/GetBookmarkedChaptersByMangaId.kt @@ -0,0 +1,33 @@ +package tachiyomi.domain.chapter.interactor + +import exh.source.MERGED_SOURCE_ID +import logcat.LogPriority +import tachiyomi.core.common.util.system.logcat +import tachiyomi.domain.chapter.model.Chapter +import tachiyomi.domain.chapter.repository.ChapterRepository +import tachiyomi.domain.manga.interactor.GetManga + +class GetBookmarkedChaptersByMangaId( + private val chapterRepository: ChapterRepository, + // SY --> + private val getManga: GetManga, + private val getMergedChaptersByMangaId: GetMergedChaptersByMangaId, + // SY <-- +) { + + suspend fun await(mangaId: Long): List { + return try { + // SY --> + val manga = getManga.await(mangaId) ?: return emptyList() + if (manga.source == MERGED_SOURCE_ID) { + return getMergedChaptersByMangaId.await(mangaId, applyScanlatorFilter = true) + .filter { it.bookmark } + } + // SY <-- + chapterRepository.getBookmarkedChaptersByMangaId(mangaId) + } catch (e: Exception) { + logcat(LogPriority.ERROR, e) + emptyList() + } + } +} diff --git a/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml index 6ab2cc211..341ffe8aa 100755 --- a/i18n/src/commonMain/moko-resources/base/strings.xml +++ b/i18n/src/commonMain/moko-resources/base/strings.xml @@ -757,6 +757,7 @@ By upload date Download Unread + Bookmarked Custom cover Cover Cover saved