feat(download): auto-download chapters during library update
Add configurable library-update download modes (disabled, next X unread, all) with settings UI and enqueue downloads after chapter sync completes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
4fce1fa940
commit
a81d717ca3
8 changed files with 106 additions and 3 deletions
|
|
@ -27,6 +27,7 @@ import eu.kanade.domain.track.interactor.SyncChapterProgressWithTrack
|
|||
import eu.kanade.domain.track.interactor.TrackChapter
|
||||
import mihon.data.repository.ExtensionRepoRepositoryImpl
|
||||
import mihon.domain.chapter.interactor.FilterChaptersForDownload
|
||||
import mihon.domain.chapter.interactor.GetChaptersForLibraryUpdateDownload
|
||||
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo
|
||||
import mihon.domain.extensionrepo.interactor.DeleteExtensionRepo
|
||||
import mihon.domain.extensionrepo.interactor.GetExtensionRepo
|
||||
|
|
@ -171,6 +172,7 @@ class DomainModule : InjektModule {
|
|||
addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get(), get(), get()) }
|
||||
addFactory { GetAvailableScanlators(get()) }
|
||||
addFactory { FilterChaptersForDownload(get(), get(), get(), get()) }
|
||||
addFactory { GetChaptersForLibraryUpdateDownload(get(), get()) }
|
||||
|
||||
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
|
||||
addFactory { GetHistory(get()) }
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import kotlinx.collections.immutable.toImmutableMap
|
|||
import tachiyomi.domain.category.interactor.GetCategories
|
||||
import tachiyomi.domain.category.model.Category
|
||||
import tachiyomi.domain.download.service.DownloadPreferences
|
||||
import tachiyomi.domain.download.service.LibraryUpdateDownloadMode
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.kmk.KMR
|
||||
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||
|
|
@ -77,6 +78,7 @@ object SettingsDownloadScreen : SearchableSettings {
|
|||
allCategories = allCategories,
|
||||
),
|
||||
getDownloadAheadGroup(downloadPreferences = downloadPreferences),
|
||||
getLibraryUpdateDownloadGroup(downloadPreferences = downloadPreferences),
|
||||
// KMK -->
|
||||
getDownloadCacheRenewInterval(downloadPreferences = downloadPreferences),
|
||||
// KMK <--
|
||||
|
|
@ -216,6 +218,39 @@ object SettingsDownloadScreen : SearchableSettings {
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getLibraryUpdateDownloadGroup(
|
||||
downloadPreferences: DownloadPreferences,
|
||||
): Preference.PreferenceGroup {
|
||||
val modePref = downloadPreferences.libraryUpdateDownloadMode()
|
||||
val amountPref = downloadPreferences.libraryUpdateDownloadAmount()
|
||||
val mode by modePref.collectAsState()
|
||||
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(KMR.strings.library_update_download),
|
||||
preferenceItems = persistentListOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
preference = modePref,
|
||||
entries = persistentMapOf(
|
||||
LibraryUpdateDownloadMode.DISABLED to stringResource(MR.strings.disabled),
|
||||
LibraryUpdateDownloadMode.NEXT_X to stringResource(KMR.strings.library_update_download_mode_next_x),
|
||||
LibraryUpdateDownloadMode.ALL to stringResource(KMR.strings.library_update_download_mode_all),
|
||||
),
|
||||
title = stringResource(KMR.strings.library_update_download_mode),
|
||||
),
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
preference = amountPref,
|
||||
entries = listOf(2, 3, 5, 10)
|
||||
.associateWith { pluralStringResource(MR.plurals.next_unread_chapters, count = it, it) }
|
||||
.toImmutableMap(),
|
||||
title = stringResource(KMR.strings.library_update_download_amount),
|
||||
enabled = mode == LibraryUpdateDownloadMode.NEXT_X,
|
||||
),
|
||||
Preference.PreferenceItem.InfoPreference(stringResource(KMR.strings.library_update_download_info)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
@Composable
|
||||
private fun getDownloadCacheRenewInterval(
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ import kotlinx.coroutines.sync.Semaphore
|
|||
import kotlinx.coroutines.sync.withPermit
|
||||
import logcat.LogPriority
|
||||
import mihon.domain.chapter.interactor.FilterChaptersForDownload
|
||||
import mihon.domain.chapter.interactor.GetChaptersForLibraryUpdateDownload
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.preference.getAndSet
|
||||
import tachiyomi.core.common.util.lang.withIOContext
|
||||
|
|
@ -119,6 +120,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get()
|
||||
private val fetchInterval: FetchInterval = Injekt.get()
|
||||
private val filterChaptersForDownload: FilterChaptersForDownload = Injekt.get()
|
||||
private val getChaptersForLibraryUpdateDownload: GetChaptersForLibraryUpdateDownload = Injekt.get()
|
||||
|
||||
// SY -->
|
||||
private val getFavorites: GetFavorites = Injekt.get()
|
||||
|
|
@ -465,6 +467,12 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||
// Convert to the manga that contains new chapters
|
||||
newUpdates.add(manga to newChapters.toTypedArray())
|
||||
}
|
||||
|
||||
val libraryUpdateChapters = getChaptersForLibraryUpdateDownload.await(manga)
|
||||
if (libraryUpdateChapters.isNotEmpty()) {
|
||||
downloadChapters(manga, libraryUpdateChapters)
|
||||
hasDownloads.store(true)
|
||||
}
|
||||
clearErrorFromDB(mangaId = manga.id)
|
||||
} catch (e: Throwable) {
|
||||
val errorMessage = when (e) {
|
||||
|
|
@ -493,10 +501,11 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||
|
||||
if (newUpdates.isNotEmpty()) {
|
||||
notifier.showUpdateNotifications(newUpdates)
|
||||
}
|
||||
|
||||
if (hasDownloads.load()) {
|
||||
downloadManager.startDownloads()
|
||||
}
|
||||
}
|
||||
|
||||
if (failedUpdates.isNotEmpty()) {
|
||||
notifier.showUpdateErrorNotification(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package mihon.domain.chapter.interactor
|
||||
|
||||
import tachiyomi.domain.chapter.model.Chapter
|
||||
import tachiyomi.domain.download.service.DownloadPreferences
|
||||
import tachiyomi.domain.download.service.LibraryUpdateDownloadMode
|
||||
import tachiyomi.domain.history.interactor.GetNextChapters
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
|
||||
class GetChaptersForLibraryUpdateDownload(
|
||||
private val downloadPreferences: DownloadPreferences,
|
||||
private val getNextChapters: GetNextChapters,
|
||||
) {
|
||||
|
||||
suspend fun await(manga: Manga): List<Chapter> {
|
||||
if (!manga.favorite) return emptyList()
|
||||
|
||||
val mode = downloadPreferences.libraryUpdateDownloadMode().get()
|
||||
if (mode == LibraryUpdateDownloadMode.DISABLED) return emptyList()
|
||||
|
||||
val chapters = getNextChapters.await(manga.id)
|
||||
if (chapters.isEmpty()) return emptyList()
|
||||
|
||||
return when (mode) {
|
||||
LibraryUpdateDownloadMode.NEXT_X -> {
|
||||
chapters.take(downloadPreferences.libraryUpdateDownloadAmount().get())
|
||||
}
|
||||
LibraryUpdateDownloadMode.ALL -> chapters
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -47,6 +47,13 @@ class DownloadPreferences(
|
|||
|
||||
// KMK -->
|
||||
fun downloadCacheRenewInterval() = preferenceStore.getInt("download_cache_renew_interval", 1)
|
||||
|
||||
fun libraryUpdateDownloadMode() = preferenceStore.getInt(
|
||||
"library_update_download_mode",
|
||||
LibraryUpdateDownloadMode.DISABLED,
|
||||
)
|
||||
|
||||
fun libraryUpdateDownloadAmount() = preferenceStore.getInt("library_update_download_amount", 10)
|
||||
// KMK <--
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
package tachiyomi.domain.download.service
|
||||
|
||||
object LibraryUpdateDownloadMode {
|
||||
const val DISABLED = 0
|
||||
const val NEXT_X = 1
|
||||
const val ALL = 2
|
||||
}
|
||||
|
|
@ -113,6 +113,12 @@
|
|||
<string name="download_cache_renew_interval_12hour">12 hours</string>
|
||||
<string name="download_cache_renew_interval_24hour">1 day</string>
|
||||
<string name="download_cache_renew_interval_info">If set to "manual", either refresh each manga or using the "Reindex downloads" action in "Advanced"</string>
|
||||
<string name="library_update_download">Download on library update</string>
|
||||
<string name="library_update_download_mode">Download chapters on library update</string>
|
||||
<string name="library_update_download_mode_next_x">Next unread chapters from current position</string>
|
||||
<string name="library_update_download_mode_all">All unread chapters from current position</string>
|
||||
<string name="library_update_download_amount">Number of chapters to download</string>
|
||||
<string name="library_update_download_info">Downloads unread chapters from your current reading position when the library is updated. Already downloaded chapters are skipped.</string>
|
||||
<!-- Tracking section -->
|
||||
<string name="pref_auto_sync_progress_from_trackers">Auto sync progress from Trackers</string>
|
||||
<string name="sync_progress_from_trackers_up_to_chapter">Sync progress from Trackers up to chapter %d</string>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@
|
|||
<string name="download_cache_renew_interval_12hour">12 Stunden</string>
|
||||
<string name="download_cache_renew_interval_24hour">1 Tag</string>
|
||||
<string name="download_cache_renew_interval_info">Wenn auf \"Manuell\" gesetzt, aktualisieren Sie entweder jedes Manga oder verwenden Sie die Aktion \"Downloads neu indizieren\" in \"Erweitert\"</string>
|
||||
<string name="library_update_download">Bei Bibliotheksaktualisierung herunterladen</string>
|
||||
<string name="library_update_download_mode">Kapitel bei Bibliotheksaktualisierung herunterladen</string>
|
||||
<string name="library_update_download_mode_next_x">Nächste ungelesene Kapitel ab aktueller Leseposition</string>
|
||||
<string name="library_update_download_mode_all">Alle ungelesenen Kapitel ab aktueller Leseposition</string>
|
||||
<string name="library_update_download_amount">Anzahl der herunterzuladenden Kapitel</string>
|
||||
<string name="library_update_download_info">Lädt ungelesene Kapitel ab deiner aktuellen Leseposition herunter, wenn die Bibliothek aktualisiert wird. Bereits heruntergeladene Kapitel werden übersprungen.</string>
|
||||
<string name="pref_clean_invalid_downloads">Ungültige Downloads bereinigen</string>
|
||||
<string name="pref_clean_invalid_downloads_summary">Finden und entfernen Sie alle Downloads, Dateien, Ordner die nicht in Ihrer Bibliothek gespeichert sind</string>
|
||||
<string name="invalid_downloads_cleaned">Ungültige Downloads bereinigt</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue