Split download preferences from PreferencesHelper (#8048)

This commit is contained in:
Andreas 2022-09-21 23:45:07 +02:00 committed by GitHub
parent ec34977a64
commit e82963c9ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 149 additions and 91 deletions

View File

@ -4,16 +4,16 @@ import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.ChapterUpdate import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.repository.ChapterRepository import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.domain.download.interactor.DeleteDownload import eu.kanade.domain.download.interactor.DeleteDownload
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.repository.MangaRepository import eu.kanade.domain.manga.repository.MangaRepository
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import logcat.LogPriority import logcat.LogPriority
class SetReadStatus( class SetReadStatus(
private val preferences: PreferencesHelper, private val downloadPreferences: DownloadPreferences,
private val deleteDownload: DeleteDownload, private val deleteDownload: DeleteDownload,
private val mangaRepository: MangaRepository, private val mangaRepository: MangaRepository,
private val chapterRepository: ChapterRepository, private val chapterRepository: ChapterRepository,
@ -52,7 +52,7 @@ class SetReadStatus(
return@withContext Result.InternalError(e) return@withContext Result.InternalError(e)
} }
if (read && preferences.removeAfterMarkedAsRead().get()) { if (read && downloadPreferences.removeAfterMarkedAsRead().get()) {
manga.forEach { manga.forEach {
deleteDownload.awaitAll( deleteDownload.awaitAll(
manga = it, manga = it,

View File

@ -0,0 +1,34 @@
package eu.kanade.domain.download.service
import eu.kanade.tachiyomi.core.preference.PreferenceStore
import eu.kanade.tachiyomi.core.provider.FolderProvider
class DownloadPreferences(
private val folderProvider: FolderProvider,
private val preferenceStore: PreferenceStore,
) {
fun downloadsDirectory() = preferenceStore.getString("download_directory", folderProvider.path())
fun downloadOnlyOverWifi() = preferenceStore.getBoolean("pref_download_only_over_wifi_key", true)
fun saveChaptersAsCBZ() = preferenceStore.getBoolean("save_chapter_as_cbz", true)
fun splitTallImages() = preferenceStore.getBoolean("split_tall_images", false)
fun autoDownloadWhileReading() = preferenceStore.getInt("auto_download_while_reading", 0)
fun removeAfterReadSlots() = preferenceStore.getInt("remove_after_read_slots", -1)
fun removeAfterMarkedAsRead() = preferenceStore.getBoolean("pref_remove_after_marked_as_read_key", false)
fun removeBookmarkedChapters() = preferenceStore.getBoolean("pref_remove_bookmarked", false)
fun removeExcludeCategories() = preferenceStore.getStringSet("remove_exclude_categories", emptySet())
fun downloadNewChapters() = preferenceStore.getBoolean("download_new", false)
fun downloadNewChapterCategories() = preferenceStore.getStringSet("download_new_categories", emptySet())
fun downloadNewChapterCategoriesExclude() = preferenceStore.getStringSet("download_new_categories_exclude", emptySet())
}

View File

@ -13,11 +13,13 @@ import eu.kanade.data.AndroidDatabaseHandler
import eu.kanade.data.DatabaseHandler import eu.kanade.data.DatabaseHandler
import eu.kanade.data.dateAdapter import eu.kanade.data.dateAdapter
import eu.kanade.data.listOfStringsAdapter import eu.kanade.data.listOfStringsAdapter
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.library.service.LibraryPreferences import eu.kanade.domain.library.service.LibraryPreferences
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore
import eu.kanade.tachiyomi.core.preference.PreferenceStore import eu.kanade.tachiyomi.core.preference.PreferenceStore
import eu.kanade.tachiyomi.core.provider.AndroidDownloadFolderProvider
import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.cache.ChapterCache import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
@ -159,6 +161,15 @@ class PreferenceModule(val application: Application) : InjektModule {
addSingletonFactory { addSingletonFactory {
TrackPreferences(get()) TrackPreferences(get())
} }
addSingletonFactory {
AndroidDownloadFolderProvider(application)
}
addSingletonFactory {
DownloadPreferences(
folderProvider = get<AndroidDownloadFolderProvider>(),
preferenceStore = get(),
)
}
addSingletonFactory { addSingletonFactory {
PreferencesHelper( PreferencesHelper(
context = application, context = application,

View File

@ -3,9 +3,9 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context import android.content.Context
import androidx.core.net.toUri import androidx.core.net.toUri
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -21,13 +21,13 @@ import java.util.concurrent.TimeUnit
* @param context the application context. * @param context the application context.
* @param provider the downloads directories provider. * @param provider the downloads directories provider.
* @param sourceManager the source manager. * @param sourceManager the source manager.
* @param preferences the preferences of the app. * @param downloadPreferences the preferences of the app.
*/ */
class DownloadCache( class DownloadCache(
private val context: Context, private val context: Context,
private val provider: DownloadProvider, private val provider: DownloadProvider,
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get(), private val downloadPreferences: DownloadPreferences = Injekt.get(),
) { ) {
/** /**
@ -47,7 +47,7 @@ class DownloadCache(
private var rootDir = RootDirectory(getDirectoryFromPreference()) private var rootDir = RootDirectory(getDirectoryFromPreference())
init { init {
preferences.downloadsDirectory().changes() downloadPreferences.downloadsDirectory().changes()
.onEach { .onEach {
lastRenew = 0L // invalidate cache lastRenew = 0L // invalidate cache
rootDir = RootDirectory(getDirectoryFromPreference()) rootDir = RootDirectory(getDirectoryFromPreference())
@ -58,7 +58,7 @@ class DownloadCache(
* Returns the downloads directory from the user's preferences. * Returns the downloads directory from the user's preferences.
*/ */
private fun getDirectoryFromPreference(): UniFile { private fun getDirectoryFromPreference(): UniFile {
val dir = preferences.downloadsDirectory().get() val dir = downloadPreferences.downloadsDirectory().get()
return UniFile.fromUri(context, dir.toUri()) return UniFile.fromUri(context, dir.toUri())
} }

View File

@ -4,12 +4,12 @@ import android.content.Context
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.download.model.DownloadQueue import eu.kanade.tachiyomi.data.download.model.DownloadQueue
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -32,7 +32,7 @@ class DownloadManager(
private val context: Context, private val context: Context,
private val getCategories: GetCategories = Injekt.get(), private val getCategories: GetCategories = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get(), private val downloadPreferences: DownloadPreferences = Injekt.get(),
) { ) {
/** /**
@ -405,7 +405,7 @@ class DownloadManager(
private fun getChaptersToDelete(chapters: List<Chapter>, manga: Manga): List<Chapter> { private fun getChaptersToDelete(chapters: List<Chapter>, manga: Manga): List<Chapter> {
// Retrieve the categories that are set to exclude from being deleted on read // Retrieve the categories that are set to exclude from being deleted on read
val categoriesToExclude = preferences.removeExcludeCategories().get().map(String::toLong) val categoriesToExclude = downloadPreferences.removeExcludeCategories().get().map(String::toLong)
val categoriesForManga = runBlocking { getCategories.await(manga.id) } val categoriesForManga = runBlocking { getCategories.await(manga.id) }
.map { it.id } .map { it.id }
@ -414,7 +414,7 @@ class DownloadManager(
return if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) { return if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) {
chapters.filterNot { it.read } chapters.filterNot { it.read }
} else if (!preferences.removeBookmarkedChapters().get()) { } else if (!downloadPreferences.removeBookmarkedChapters().get()) {
chapters.filterNot { it.bookmark } chapters.filterNot { it.bookmark }
} else { } else {
chapters chapters

View File

@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context import android.content.Context
import androidx.core.net.toUri import androidx.core.net.toUri
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
@ -25,21 +25,21 @@ import eu.kanade.domain.chapter.model.Chapter as DomainChapter
*/ */
class DownloadProvider(private val context: Context) { class DownloadProvider(private val context: Context) {
private val preferences: PreferencesHelper by injectLazy() private val downloadPreferences: DownloadPreferences by injectLazy()
private val scope = MainScope() private val scope = MainScope()
/** /**
* The root directory for downloads. * The root directory for downloads.
*/ */
private var downloadsDir = preferences.downloadsDirectory().get().let { private var downloadsDir = downloadPreferences.downloadsDirectory().get().let {
val dir = UniFile.fromUri(context, it.toUri()) val dir = UniFile.fromUri(context, it.toUri())
DiskUtil.createNoMediaFile(dir, context) DiskUtil.createNoMediaFile(dir, context)
dir dir
} }
init { init {
preferences.downloadsDirectory().changes() downloadPreferences.downloadsDirectory().changes()
.onEach { downloadsDir = UniFile.fromUri(context, it.toUri()) } .onEach { downloadsDir = UniFile.fromUri(context, it.toUri()) }
.launchIn(scope) .launchIn(scope)
} }

View File

@ -9,9 +9,9 @@ import android.os.PowerManager
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.lang.plusAssign import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.acquireWakeLock
@ -84,7 +84,7 @@ class DownloadService : Service() {
private val downloadManager: DownloadManager by injectLazy() private val downloadManager: DownloadManager by injectLazy()
private val preferences: PreferencesHelper by injectLazy() private val downloadPreferences: DownloadPreferences by injectLazy()
/** /**
* Wake lock to prevent the device to enter sleep mode. * Wake lock to prevent the device to enter sleep mode.
@ -164,7 +164,7 @@ class DownloadService : Service() {
*/ */
private fun onNetworkStateChanged() { private fun onNetworkStateChanged() {
if (isOnline()) { if (isOnline()) {
if (preferences.downloadOnlyOverWifi().get() && !isConnectedToWifi()) { if (downloadPreferences.downloadOnlyOverWifi().get() && !isConnectedToWifi()) {
stopDownloads(R.string.download_notifier_text_only_wifi) stopDownloads(R.string.download_notifier_text_only_wifi)
} else { } else {
val started = downloadManager.startDownloads() val started = downloadManager.startDownloads()

View File

@ -4,6 +4,7 @@ import android.content.Context
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.PublishRelay import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.ChapterCache import eu.kanade.tachiyomi.data.cache.ChapterCache
@ -12,7 +13,6 @@ import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.download.model.DownloadQueue import eu.kanade.tachiyomi.data.download.model.DownloadQueue
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -62,7 +62,7 @@ class Downloader(
private val cache: DownloadCache, private val cache: DownloadCache,
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val chapterCache: ChapterCache = Injekt.get(), private val chapterCache: ChapterCache = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get(), private val downloadPreferences: DownloadPreferences = Injekt.get(),
) { ) {
/** /**
@ -480,7 +480,7 @@ class Downloader(
} }
private fun splitTallImageIfNeeded(page: Page, tmpDir: UniFile): Boolean { private fun splitTallImageIfNeeded(page: Page, tmpDir: UniFile): Boolean {
if (!preferences.splitTallImages().get()) return true if (!downloadPreferences.splitTallImages().get()) return true
val filename = String.format("%03d", page.number) val filename = String.format("%03d", page.number)
val imageFile = tmpDir.listFiles()?.find { it.name!!.startsWith(filename) } val imageFile = tmpDir.listFiles()?.find { it.name!!.startsWith(filename) }
@ -518,7 +518,7 @@ class Downloader(
download.status = if (downloadedImages.size == download.pages!!.size) { download.status = if (downloadedImages.size == download.pages!!.size) {
// Only rename the directory if it's downloaded. // Only rename the directory if it's downloaded.
if (preferences.saveChaptersAsCBZ().get()) { if (downloadPreferences.saveChaptersAsCBZ().get()) {
archiveChapter(mangaDir, dirname, tmpDir) archiveChapter(mangaDir, dirname, tmpDir)
} else { } else {
tmpDir.renameTo(dirname) tmpDir.renameTo(dirname)

View File

@ -13,6 +13,7 @@ import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.chapter.model.toDbChapter import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.library.service.LibraryPreferences import eu.kanade.domain.library.service.LibraryPreferences
import eu.kanade.domain.manga.interactor.GetLibraryManga import eu.kanade.domain.manga.interactor.GetLibraryManga
import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.manga.interactor.GetManga
@ -36,7 +37,6 @@ import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.MANGA_HAS_UNREAD import eu.kanade.tachiyomi.data.preference.MANGA_HAS_UNREAD
import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED
import eu.kanade.tachiyomi.data.preference.MANGA_NON_READ import eu.kanade.tachiyomi.data.preference.MANGA_NON_READ
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
@ -86,7 +86,7 @@ import eu.kanade.domain.manga.model.Manga as DomainManga
*/ */
class LibraryUpdateService( class LibraryUpdateService(
val sourceManager: SourceManager = Injekt.get(), val sourceManager: SourceManager = Injekt.get(),
val preferences: PreferencesHelper = Injekt.get(), val downloadPreferences: DownloadPreferences = Injekt.get(),
val libraryPreferences: LibraryPreferences = Injekt.get(), val libraryPreferences: LibraryPreferences = Injekt.get(),
val downloadManager: DownloadManager = Injekt.get(), val downloadManager: DownloadManager = Injekt.get(),
val trackManager: TrackManager = Injekt.get(), val trackManager: TrackManager = Injekt.get(),
@ -355,7 +355,7 @@ class LibraryUpdateService(
if (newChapters.isNotEmpty()) { if (newChapters.isNotEmpty()) {
val categoryIds = getCategories.await(domainManga.id).map { it.id } val categoryIds = getCategories.await(domainManga.id).map { it.id }
if (domainManga.shouldDownloadNewChapters(categoryIds, preferences)) { if (domainManga.shouldDownloadNewChapters(categoryIds, downloadPreferences)) {
downloadChapters(mangaWithNotif, newDbChapters) downloadChapters(mangaWithNotif, newDbChapters)
hasDownloads.set(true) hasDownloads.set(true)
} }

View File

@ -13,6 +13,7 @@ import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.model.Chapter import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.toChapterUpdate import eu.kanade.domain.chapter.model.toChapterUpdate
import eu.kanade.domain.chapter.model.toDbChapter import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.model.Manga import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -20,7 +21,6 @@ import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.updater.AppUpdateService import eu.kanade.tachiyomi.data.updater.AppUpdateService
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
@ -241,14 +241,14 @@ class NotificationReceiver : BroadcastReceiver() {
* @param mangaId id of manga * @param mangaId id of manga
*/ */
private fun markAsRead(chapterUrls: Array<String>, mangaId: Long) { private fun markAsRead(chapterUrls: Array<String>, mangaId: Long) {
val preferences: PreferencesHelper = Injekt.get() val downloadPreferences: DownloadPreferences = Injekt.get()
val sourceManager: SourceManager = Injekt.get() val sourceManager: SourceManager = Injekt.get()
launchIO { launchIO {
val toUpdate = chapterUrls.mapNotNull { getChapter.await(it, mangaId) } val toUpdate = chapterUrls.mapNotNull { getChapter.await(it, mangaId) }
.map { .map {
val chapter = it.copy(read = true) val chapter = it.copy(read = true)
if (preferences.removeAfterMarkedAsRead().get()) { if (downloadPreferences.removeAfterMarkedAsRead().get()) {
val manga = getManga.await(mangaId) val manga = getManga.await(mangaId)
if (manga != null) { if (manga != null) {
val source = sourceManager.get(manga.source) val source = sourceManager.get(manga.source)

View File

@ -23,12 +23,6 @@ class PreferencesHelper(
private val preferenceStore: PreferenceStore, private val preferenceStore: PreferenceStore,
) { ) {
private val defaultDownloadsDir = File(
Environment.getExternalStorageDirectory().absolutePath + File.separator +
context.getString(R.string.app_name),
"downloads",
).toUri()
private val defaultBackupDir = File( private val defaultBackupDir = File(
Environment.getExternalStorageDirectory().absolutePath + File.separator + Environment.getExternalStorageDirectory().absolutePath + File.separator +
context.getString(R.string.app_name), context.getString(R.string.app_name),
@ -62,26 +56,10 @@ class PreferencesHelper(
else -> SimpleDateFormat(format, Locale.getDefault()) else -> SimpleDateFormat(format, Locale.getDefault())
} }
fun downloadsDirectory() = preferenceStore.getString("download_directory", defaultDownloadsDir.toString())
fun downloadOnlyOverWifi() = preferenceStore.getBoolean("pref_download_only_over_wifi_key", true)
fun saveChaptersAsCBZ() = preferenceStore.getBoolean("save_chapter_as_cbz", true)
fun splitTallImages() = preferenceStore.getBoolean("split_tall_images", false)
fun numberOfBackups() = preferenceStore.getInt("backup_slots", 2) fun numberOfBackups() = preferenceStore.getInt("backup_slots", 2)
fun backupInterval() = preferenceStore.getInt("backup_interval", 12) fun backupInterval() = preferenceStore.getInt("backup_interval", 12)
fun removeAfterReadSlots() = preferenceStore.getInt("remove_after_read_slots", -1)
fun removeAfterMarkedAsRead() = preferenceStore.getBoolean("pref_remove_after_marked_as_read_key", false)
fun removeBookmarkedChapters() = preferenceStore.getBoolean("pref_remove_bookmarked", false)
fun removeExcludeCategories() = preferenceStore.getStringSet("remove_exclude_categories", emptySet())
fun downloadedOnly() = preferenceStore.getBoolean("pref_downloaded_only", false) fun downloadedOnly() = preferenceStore.getBoolean("pref_downloaded_only", false)
fun automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true) fun automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true)
@ -89,13 +67,6 @@ class PreferencesHelper(
fun lastAppCheck() = preferenceStore.getLong("last_app_check", 0) fun lastAppCheck() = preferenceStore.getLong("last_app_check", 0)
fun lastExtCheck() = preferenceStore.getLong("last_ext_check", 0) fun lastExtCheck() = preferenceStore.getLong("last_ext_check", 0)
fun downloadNewChapters() = preferenceStore.getBoolean("download_new", false)
fun downloadNewChapterCategories() = preferenceStore.getStringSet("download_new_categories", emptySet())
fun downloadNewChapterCategoriesExclude() = preferenceStore.getStringSet("download_new_categories_exclude", emptySet())
fun autoDownloadWhileReading() = preferenceStore.getInt("auto_download_while_reading", 0)
fun migrateFlags() = preferenceStore.getInt("migrate_flags", Int.MAX_VALUE) fun migrateFlags() = preferenceStore.getInt("migrate_flags", Int.MAX_VALUE)
fun filterChapterByRead() = preferenceStore.getInt("default_chapter_filter_by_read", DomainManga.SHOW_ALL.toInt()) fun filterChapterByRead() = preferenceStore.getInt("default_chapter_filter_by_read", DomainManga.SHOW_ALL.toInt())

View File

@ -15,6 +15,7 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.model.ChapterUpdate import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.model.toDbChapter import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.library.service.LibraryPreferences import eu.kanade.domain.library.service.LibraryPreferences
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
import eu.kanade.domain.manga.interactor.GetMangaWithChapters import eu.kanade.domain.manga.interactor.GetMangaWithChapters
@ -82,6 +83,7 @@ class MangaPresenter(
val mangaId: Long, val mangaId: Long,
val isFromSource: Boolean, val isFromSource: Boolean,
private val preferences: PreferencesHelper = Injekt.get(), private val preferences: PreferencesHelper = Injekt.get(),
private val downloadPreferences: DownloadPreferences = Injekt.get(),
private val libraryPreferences: LibraryPreferences = Injekt.get(), private val libraryPreferences: LibraryPreferences = Injekt.get(),
private val trackManager: TrackManager = Injekt.get(), private val trackManager: TrackManager = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
@ -679,7 +681,7 @@ class MangaPresenter(
presenterScope.launchNonCancellableIO { presenterScope.launchNonCancellableIO {
val manga = successState?.manga ?: return@launchNonCancellableIO val manga = successState?.manga ?: return@launchNonCancellableIO
val categories = getCategories.await(manga.id).map { it.id } val categories = getCategories.await(manga.id).map { it.id }
if (chapters.isEmpty() || !manga.shouldDownloadNewChapters(categories, preferences)) return@launchNonCancellableIO if (chapters.isEmpty() || !manga.shouldDownloadNewChapters(categories, downloadPreferences)) return@launchNonCancellableIO
downloadChapters(chapters) downloadChapters(chapters)
} }
} }

View File

@ -9,6 +9,7 @@ import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.model.ChapterUpdate import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.model.toDbChapter import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.history.interactor.UpsertHistory import eu.kanade.domain.history.interactor.UpsertHistory
import eu.kanade.domain.history.model.HistoryUpdate import eu.kanade.domain.history.model.HistoryUpdate
import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.manga.interactor.GetManga
@ -80,6 +81,7 @@ class ReaderPresenter(
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val downloadManager: DownloadManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get(), private val preferences: PreferencesHelper = Injekt.get(),
private val downloadPreferences: DownloadPreferences = Injekt.get(),
private val readerPreferences: ReaderPreferences = Injekt.get(), private val readerPreferences: ReaderPreferences = Injekt.get(),
private val trackPreferences: TrackPreferences = Injekt.get(), private val trackPreferences: TrackPreferences = Injekt.get(),
private val delayedTrackingStore: DelayedTrackingStore = Injekt.get(), private val delayedTrackingStore: DelayedTrackingStore = Injekt.get(),
@ -452,7 +454,7 @@ class ReaderPresenter(
val manga = manga ?: return val manga = manga ?: return
if (getCurrentChapter()?.pageLoader !is DownloadPageLoader) return if (getCurrentChapter()?.pageLoader !is DownloadPageLoader) return
val nextChapter = viewerChaptersRelay.value?.nextChapter?.chapter ?: return val nextChapter = viewerChaptersRelay.value?.nextChapter?.chapter ?: return
val chaptersNumberToDownload = preferences.autoDownloadWhileReading().get() val chaptersNumberToDownload = downloadPreferences.autoDownloadWhileReading().get()
if (chaptersNumberToDownload == 0 || !manga.favorite) return if (chaptersNumberToDownload == 0 || !manga.favorite) return
val isNextChapterDownloadedOrQueued = downloadManager.isChapterDownloaded( val isNextChapterDownloadedOrQueued = downloadManager.isChapterDownloaded(
nextChapter.name, nextChapter.name,
@ -506,7 +508,7 @@ class ReaderPresenter(
private fun deleteChapterIfNeeded(currentChapter: ReaderChapter) { private fun deleteChapterIfNeeded(currentChapter: ReaderChapter) {
// Determine which chapter should be deleted and enqueue // Determine which chapter should be deleted and enqueue
val currentChapterPosition = chapterList.indexOf(currentChapter) val currentChapterPosition = chapterList.indexOf(currentChapter)
val removeAfterReadSlots = preferences.removeAfterReadSlots().get() val removeAfterReadSlots = downloadPreferences.removeAfterReadSlots().get()
val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots) val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots)
if (removeAfterReadSlots != 0 && chapterDownload != null) { if (removeAfterReadSlots != 0 && chapterDownload != null) {

View File

@ -12,9 +12,9 @@ import androidx.preference.PreferenceScreen
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.presentation.category.visualName import eu.kanade.presentation.category.visualName
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.util.preference.bindTo import eu.kanade.tachiyomi.util.preference.bindTo
import eu.kanade.tachiyomi.util.preference.entriesRes import eu.kanade.tachiyomi.util.preference.entriesRes
@ -41,6 +41,7 @@ import java.io.File
class SettingsDownloadController : SettingsController() { class SettingsDownloadController : SettingsController() {
private val getCategories: GetCategories by injectLazy() private val getCategories: GetCategories by injectLazy()
private val downloadPreferences: DownloadPreferences by injectLazy()
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
titleRes = R.string.pref_category_downloads titleRes = R.string.pref_category_downloads
@ -48,7 +49,7 @@ class SettingsDownloadController : SettingsController() {
val categories = runBlocking { getCategories.await() } val categories = runBlocking { getCategories.await() }
preference { preference {
bindTo(preferences.downloadsDirectory()) bindTo(downloadPreferences.downloadsDirectory())
titleRes = R.string.pref_download_directory titleRes = R.string.pref_download_directory
onClick { onClick {
val ctrl = DownloadDirectoriesDialog() val ctrl = DownloadDirectoriesDialog()
@ -56,7 +57,7 @@ class SettingsDownloadController : SettingsController() {
ctrl.showDialog(router) ctrl.showDialog(router)
} }
preferences.downloadsDirectory().changes() downloadPreferences.downloadsDirectory().changes()
.onEach { path -> .onEach { path ->
val dir = UniFile.fromUri(context, path.toUri()) val dir = UniFile.fromUri(context, path.toUri())
summary = dir.filePath ?: path summary = dir.filePath ?: path
@ -64,15 +65,15 @@ class SettingsDownloadController : SettingsController() {
.launchIn(viewScope) .launchIn(viewScope)
} }
switchPreference { switchPreference {
bindTo(preferences.downloadOnlyOverWifi()) bindTo(downloadPreferences.downloadOnlyOverWifi())
titleRes = R.string.connected_to_wifi titleRes = R.string.connected_to_wifi
} }
switchPreference { switchPreference {
bindTo(preferences.saveChaptersAsCBZ()) bindTo(downloadPreferences.saveChaptersAsCBZ())
titleRes = R.string.save_chapter_as_cbz titleRes = R.string.save_chapter_as_cbz
} }
switchPreference { switchPreference {
bindTo(preferences.splitTallImages()) bindTo(downloadPreferences.splitTallImages())
titleRes = R.string.split_tall_images titleRes = R.string.split_tall_images
summaryRes = R.string.split_tall_images_summary summaryRes = R.string.split_tall_images_summary
} }
@ -81,11 +82,11 @@ class SettingsDownloadController : SettingsController() {
titleRes = R.string.pref_category_delete_chapters titleRes = R.string.pref_category_delete_chapters
switchPreference { switchPreference {
bindTo(preferences.removeAfterMarkedAsRead()) bindTo(downloadPreferences.removeAfterMarkedAsRead())
titleRes = R.string.pref_remove_after_marked_as_read titleRes = R.string.pref_remove_after_marked_as_read
} }
intListPreference { intListPreference {
bindTo(preferences.removeAfterReadSlots()) bindTo(downloadPreferences.removeAfterReadSlots())
titleRes = R.string.pref_remove_after_read titleRes = R.string.pref_remove_after_read
entriesRes = arrayOf( entriesRes = arrayOf(
R.string.disabled, R.string.disabled,
@ -99,16 +100,16 @@ class SettingsDownloadController : SettingsController() {
summary = "%s" summary = "%s"
} }
switchPreference { switchPreference {
bindTo(preferences.removeBookmarkedChapters()) bindTo(downloadPreferences.removeBookmarkedChapters())
titleRes = R.string.pref_remove_bookmarked_chapters titleRes = R.string.pref_remove_bookmarked_chapters
} }
multiSelectListPreference { multiSelectListPreference {
bindTo(preferences.removeExcludeCategories()) bindTo(downloadPreferences.removeExcludeCategories())
titleRes = R.string.pref_remove_exclude_categories titleRes = R.string.pref_remove_exclude_categories
entries = categories.map { it.visualName(context) }.toTypedArray() entries = categories.map { it.visualName(context) }.toTypedArray()
entryValues = categories.map { it.id.toString() }.toTypedArray() entryValues = categories.map { it.id.toString() }.toTypedArray()
preferences.removeExcludeCategories().changes() downloadPreferences.removeExcludeCategories().changes()
.onEach { mutable -> .onEach { mutable ->
val selected = mutable val selected = mutable
.mapNotNull { id -> categories.find { it.id == id.toLong() } } .mapNotNull { id -> categories.find { it.id == id.toLong() } }
@ -127,20 +128,20 @@ class SettingsDownloadController : SettingsController() {
titleRes = R.string.pref_download_new titleRes = R.string.pref_download_new
switchPreference { switchPreference {
bindTo(preferences.downloadNewChapters()) bindTo(downloadPreferences.downloadNewChapters())
titleRes = R.string.pref_download_new titleRes = R.string.pref_download_new
} }
preference { preference {
bindTo(preferences.downloadNewChapterCategories()) bindTo(downloadPreferences.downloadNewChapterCategories())
titleRes = R.string.categories titleRes = R.string.categories
onClick { onClick {
DownloadCategoriesDialog().showDialog(router) DownloadCategoriesDialog().showDialog(router)
} }
visibleIf(preferences.downloadNewChapters()) { it } visibleIf(downloadPreferences.downloadNewChapters()) { it }
fun updateSummary() { fun updateSummary() {
val selectedCategories = preferences.downloadNewChapterCategories().get() val selectedCategories = downloadPreferences.downloadNewChapterCategories().get()
.mapNotNull { id -> categories.find { it.id == id.toLong() } } .mapNotNull { id -> categories.find { it.id == id.toLong() } }
.sortedBy { it.order } .sortedBy { it.order }
val includedItemsText = if (selectedCategories.isEmpty()) { val includedItemsText = if (selectedCategories.isEmpty()) {
@ -149,7 +150,7 @@ class SettingsDownloadController : SettingsController() {
selectedCategories.joinToString { it.visualName(context) } selectedCategories.joinToString { it.visualName(context) }
} }
val excludedCategories = preferences.downloadNewChapterCategoriesExclude().get() val excludedCategories = downloadPreferences.downloadNewChapterCategoriesExclude().get()
.mapNotNull { id -> categories.find { it.id == id.toLong() } } .mapNotNull { id -> categories.find { it.id == id.toLong() } }
.sortedBy { it.order } .sortedBy { it.order }
val excludedItemsText = if (excludedCategories.isEmpty()) { val excludedItemsText = if (excludedCategories.isEmpty()) {
@ -165,10 +166,10 @@ class SettingsDownloadController : SettingsController() {
} }
} }
preferences.downloadNewChapterCategories().changes() downloadPreferences.downloadNewChapterCategories().changes()
.onEach { updateSummary() } .onEach { updateSummary() }
.launchIn(viewScope) .launchIn(viewScope)
preferences.downloadNewChapterCategoriesExclude().changes() downloadPreferences.downloadNewChapterCategoriesExclude().changes()
.onEach { updateSummary() } .onEach { updateSummary() }
.launchIn(viewScope) .launchIn(viewScope)
} }
@ -178,7 +179,7 @@ class SettingsDownloadController : SettingsController() {
titleRes = R.string.download_ahead titleRes = R.string.download_ahead
intListPreference { intListPreference {
bindTo(preferences.autoDownloadWhileReading()) bindTo(downloadPreferences.autoDownloadWhileReading())
titleRes = R.string.auto_download_while_reading titleRes = R.string.auto_download_while_reading
entries = arrayOf( entries = arrayOf(
context.getString(R.string.disabled), context.getString(R.string.disabled),
@ -208,14 +209,14 @@ class SettingsDownloadController : SettingsController() {
} }
val file = UniFile.fromUri(context, uri) val file = UniFile.fromUri(context, uri)
preferences.downloadsDirectory().set(file.uri.toString()) downloadPreferences.downloadsDirectory().set(file.uri.toString())
} }
} }
} }
fun predefinedDirectorySelected(selectedDir: String) { fun predefinedDirectorySelected(selectedDir: String) {
val path = File(selectedDir).toUri() val path = File(selectedDir).toUri()
preferences.downloadsDirectory().set(path.toString()) downloadPreferences.downloadsDirectory().set(path.toString())
} }
fun customDirectorySelected() { fun customDirectorySelected() {
@ -229,11 +230,11 @@ class SettingsDownloadController : SettingsController() {
class DownloadDirectoriesDialog : DialogController() { class DownloadDirectoriesDialog : DialogController() {
private val preferences: PreferencesHelper = Injekt.get() private val downloadPreferences: DownloadPreferences = Injekt.get()
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val activity = activity!! val activity = activity!!
val currentDir = preferences.downloadsDirectory().get() val currentDir = downloadPreferences.downloadsDirectory().get()
val externalDirs = listOf(getDefaultDownloadDir(), File(activity.getString(R.string.custom_dir))).map(File::toString) val externalDirs = listOf(getDefaultDownloadDir(), File(activity.getString(R.string.custom_dir))).map(File::toString)
var selectedIndex = externalDirs.indexOfFirst { it in currentDir } var selectedIndex = externalDirs.indexOfFirst { it in currentDir }
@ -264,7 +265,7 @@ class SettingsDownloadController : SettingsController() {
class DownloadCategoriesDialog : DialogController() { class DownloadCategoriesDialog : DialogController() {
private val preferences: PreferencesHelper = Injekt.get() private val downloadPreferences: DownloadPreferences = Injekt.get()
private val getCategories: GetCategories = Injekt.get() private val getCategories: GetCategories = Injekt.get()
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
@ -274,8 +275,8 @@ class SettingsDownloadController : SettingsController() {
var selected = categories var selected = categories
.map { .map {
when (it.id.toString()) { when (it.id.toString()) {
in preferences.downloadNewChapterCategories().get() -> QuadStateTextView.State.CHECKED.ordinal in downloadPreferences.downloadNewChapterCategories().get() -> QuadStateTextView.State.CHECKED.ordinal
in preferences.downloadNewChapterCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal in downloadPreferences.downloadNewChapterCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal
else -> QuadStateTextView.State.UNCHECKED.ordinal else -> QuadStateTextView.State.UNCHECKED.ordinal
} }
} }
@ -302,8 +303,8 @@ class SettingsDownloadController : SettingsController() {
.map { categories[it].id.toString() } .map { categories[it].id.toString() }
.toSet() .toSet()
preferences.downloadNewChapterCategories().set(included) downloadPreferences.downloadNewChapterCategories().set(included)
preferences.downloadNewChapterCategoriesExclude().set(excluded) downloadPreferences.downloadNewChapterCategoriesExclude().set(excluded)
} }
.setNegativeButton(android.R.string.cancel, null) .setNegativeButton(android.R.string.cancel, null)
.create() .create()

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.util package eu.kanade.tachiyomi.util
import android.content.Context import android.content.Context
import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.hasCustomCover import eu.kanade.domain.manga.model.hasCustomCover
import eu.kanade.domain.manga.model.isLocal import eu.kanade.domain.manga.model.isLocal
@ -8,7 +9,6 @@ import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -57,7 +57,7 @@ fun DomainManga.removeCovers(coverCache: CoverCache = Injekt.get()): DomainManga
return copy(coverLastModified = Date().time) return copy(coverLastModified = Date().time)
} }
fun DomainManga.shouldDownloadNewChapters(dbCategories: List<Long>, preferences: PreferencesHelper): Boolean { fun DomainManga.shouldDownloadNewChapters(dbCategories: List<Long>, preferences: DownloadPreferences): Boolean {
if (!favorite) return false if (!favorite) return false
val categories = dbCategories.ifEmpty { listOf(0L) } val categories = dbCategories.ifEmpty { listOf(0L) }

View File

@ -0,0 +1,25 @@
package eu.kanade.tachiyomi.core.provider
import android.content.Context
import android.os.Environment
import androidx.core.net.toUri
import eu.kanade.tachiyomi.core.R
import java.io.File
class AndroidDownloadFolderProvider(
val context: Context
) : FolderProvider {
override fun directory(): File {
return File(
Environment.getExternalStorageDirectory().absolutePath + File.separator +
context.getString(R.string.app_name),
"downloads",
)
}
override fun path(): String {
return directory().toUri().toString()
}
}

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.core.provider
import java.io.File
interface FolderProvider {
fun directory(): File
fun path(): String
}