Add option for bookmarked chapters to download dropdown (#2891)

This commit is contained in:
NarwhalHorns
2026-02-21 10:14:55 +00:00
committed by GitHub
parent ab214526c6
commit 3c6f0f1697
8 changed files with 69 additions and 10 deletions
+1
View File
@@ -15,6 +15,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
- Automatically remove downloads on Suwayomi after reading, configurable via extension settings ([@cpiber](https://github.com/cpiber)) ([#2673](https://github.com/mihonapp/mihon/pull/2673))
- Display author & artist name in MAL search results ([@MajorTanya](https://github.com/MajorTanya)) ([#2833](https://github.com/mihonapp/mihon/pull/2833))
- Add filter options to Updates tab ([@MajorTanya](https://github.com/MajorTanya)) ([#2851](https://github.com/mihonapp/mihon/pull/2851))
- Add bookmarked chapters to chapter download options ([@NarwhalHorns](https://github.com/NarwhalHorns)) ([#2891](https://github.com/mihonapp/mihon/pull/2891))
- Add `src:` prefix to search the library by source ID ([@MajorTanya](https://github.com/MajorTanya)) ([#2927](https://github.com/mihonapp/mihon/pull/2927))
- Add `src:local` as a way to search for Local Source entries ([@MajorTanya](https://github.com/MajorTanya)) ([#2928](https://github.com/mihonapp/mihon/pull/2928))
@@ -57,6 +57,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
@@ -157,6 +158,7 @@ class DomainModule : InjektModule {
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
addFactory { GetChapter(get()) }
addFactory { GetChaptersByMangaId(get()) }
addFactory { GetBookmarkedChaptersByMangaId(get()) }
addFactory { GetChapterByUrlAndMangaId(get()) }
addFactory { UpdateChapter(get()) }
addFactory { SetReadStatus(get(), get(), get(), get()) }
@@ -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) ->
@@ -6,6 +6,7 @@ enum class DownloadAction {
NEXT_10_CHAPTERS,
NEXT_25_CHAPTERS,
UNREAD_CHAPTERS,
BOOKMARKED_CHAPTERS,
}
enum class EditCoverAction {
@@ -47,6 +47,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.model.Chapter
import tachiyomi.domain.history.interactor.GetNextChapters
@@ -73,6 +74,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(),
@@ -465,15 +467,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 ->
val chapters = getNextChapters.await(manga.id)
@@ -494,6 +500,26 @@ class LibraryScreenModel(
}
}
private fun downloadBookmarkedChapters() {
val mangas = state.value.selectedManga
screenModelScope.launchNonCancellable {
mangas.forEach { manga ->
val chapters = getBookmarkedChaptersByMangaId.await(manga.id)
.fastFilterNot { chapter ->
downloadManager.getQueuedDownloadOrNull(chapter.id) != null ||
downloadManager.isChapterDownloaded(
chapter.name,
chapter.scanlator,
chapter.url,
manga.title,
manga.source,
)
}
downloadManager.downloadChapters(manga, chapters)
}
}
}
/**
* Marks mangas' chapters read status.
*/
@@ -650,6 +650,13 @@ class MangaScreenModel(
return if (manga.sortDescending()) chaptersSorted.reversed() else chaptersSorted
}
private fun getBookmarkedChapters(): List<Chapter> {
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<Chapter>,
startNow: Boolean,
@@ -712,6 +719,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)
@@ -0,0 +1,20 @@
package tachiyomi.domain.chapter.interactor
import logcat.LogPriority
import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.chapter.repository.ChapterRepository
class GetBookmarkedChaptersByMangaId(
private val chapterRepository: ChapterRepository,
) {
suspend fun await(mangaId: Long): List<Chapter> {
return try {
chapterRepository.getBookmarkedChaptersByMangaId(mangaId)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
emptyList()
}
}
}
@@ -759,6 +759,7 @@
<string name="sort_by_upload_date">By upload date</string>
<string name="manga_download">Download</string>
<string name="download_unread">Unread</string>
<string name="download_bookmarked">Bookmarked</string>
<string name="custom_cover">Custom cover</string>
<string name="manga_cover">Cover</string>
<string name="cover_saved">Cover saved</string>