From e82963c9ef15416f6bf818c4043cf802c3033105 Mon Sep 17 00:00:00 2001 From: Andreas Date: Wed, 21 Sep 2022 23:45:07 +0200 Subject: [PATCH] Split download preferences from PreferencesHelper (#8048) --- .../chapter/interactor/SetReadStatus.kt | 6 +- .../download/service/DownloadPreferences.kt | 34 +++++++++++ .../java/eu/kanade/tachiyomi/AppModule.kt | 11 ++++ .../tachiyomi/data/download/DownloadCache.kt | 10 ++-- .../data/download/DownloadManager.kt | 8 +-- .../data/download/DownloadProvider.kt | 8 +-- .../data/download/DownloadService.kt | 6 +- .../tachiyomi/data/download/Downloader.kt | 8 +-- .../data/library/LibraryUpdateService.kt | 6 +- .../data/notification/NotificationReceiver.kt | 6 +- .../data/preference/PreferencesHelper.kt | 29 ---------- .../tachiyomi/ui/manga/MangaPresenter.kt | 4 +- .../tachiyomi/ui/reader/ReaderPresenter.kt | 6 +- .../ui/setting/SettingsDownloadController.kt | 57 ++++++++++--------- .../kanade/tachiyomi/util/MangaExtensions.kt | 4 +- .../provider/AndroidDownloadFolderProvider.kt | 25 ++++++++ .../tachiyomi/core/provider/FolderProvider.kt | 12 ++++ 17 files changed, 149 insertions(+), 91 deletions(-) create mode 100644 app/src/main/java/eu/kanade/domain/download/service/DownloadPreferences.kt create mode 100644 core/src/main/java/eu/kanade/tachiyomi/core/provider/AndroidDownloadFolderProvider.kt create mode 100644 core/src/main/java/eu/kanade/tachiyomi/core/provider/FolderProvider.kt diff --git a/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt b/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt index 9813b7325e..8cf80a6928 100644 --- a/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt +++ b/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt @@ -4,16 +4,16 @@ import eu.kanade.domain.chapter.model.Chapter import eu.kanade.domain.chapter.model.ChapterUpdate import eu.kanade.domain.chapter.repository.ChapterRepository 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.repository.MangaRepository -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext import logcat.LogPriority class SetReadStatus( - private val preferences: PreferencesHelper, + private val downloadPreferences: DownloadPreferences, private val deleteDownload: DeleteDownload, private val mangaRepository: MangaRepository, private val chapterRepository: ChapterRepository, @@ -52,7 +52,7 @@ class SetReadStatus( return@withContext Result.InternalError(e) } - if (read && preferences.removeAfterMarkedAsRead().get()) { + if (read && downloadPreferences.removeAfterMarkedAsRead().get()) { manga.forEach { deleteDownload.awaitAll( manga = it, diff --git a/app/src/main/java/eu/kanade/domain/download/service/DownloadPreferences.kt b/app/src/main/java/eu/kanade/domain/download/service/DownloadPreferences.kt new file mode 100644 index 0000000000..76b0465a6b --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/download/service/DownloadPreferences.kt @@ -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()) +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt index 77bc465d97..308de67be9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt @@ -13,11 +13,13 @@ import eu.kanade.data.AndroidDatabaseHandler import eu.kanade.data.DatabaseHandler import eu.kanade.data.dateAdapter import eu.kanade.data.listOfStringsAdapter +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.domain.library.service.LibraryPreferences import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore 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.data.cache.ChapterCache import eu.kanade.tachiyomi.data.cache.CoverCache @@ -159,6 +161,15 @@ class PreferenceModule(val application: Application) : InjektModule { addSingletonFactory { TrackPreferences(get()) } + addSingletonFactory { + AndroidDownloadFolderProvider(application) + } + addSingletonFactory { + DownloadPreferences( + folderProvider = get(), + preferenceStore = get(), + ) + } addSingletonFactory { PreferencesHelper( context = application, diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt index 931f011763..71948c176c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt @@ -3,9 +3,9 @@ package eu.kanade.tachiyomi.data.download import android.content.Context import androidx.core.net.toUri import com.hippo.unifile.UniFile +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.data.database.models.Chapter -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.SourceManager import kotlinx.coroutines.flow.onEach import uy.kohesive.injekt.Injekt @@ -21,13 +21,13 @@ import java.util.concurrent.TimeUnit * @param context the application context. * @param provider the downloads directories provider. * @param sourceManager the source manager. - * @param preferences the preferences of the app. + * @param downloadPreferences the preferences of the app. */ class DownloadCache( private val context: Context, private val provider: DownloadProvider, 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()) init { - preferences.downloadsDirectory().changes() + downloadPreferences.downloadsDirectory().changes() .onEach { lastRenew = 0L // invalidate cache rootDir = RootDirectory(getDirectoryFromPreference()) @@ -58,7 +58,7 @@ class DownloadCache( * Returns the downloads directory from the user's preferences. */ private fun getDirectoryFromPreference(): UniFile { - val dir = preferences.downloadsDirectory().get() + val dir = downloadPreferences.downloadsDirectory().get() return UniFile.fromUri(context, dir.toUri()) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt index ebc0c1b338..96951e82cb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt @@ -4,12 +4,12 @@ import android.content.Context import com.hippo.unifile.UniFile import com.jakewharton.rxrelay.BehaviorRelay import eu.kanade.domain.category.interactor.GetCategories +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.download.model.Download 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.SourceManager import eu.kanade.tachiyomi.source.model.Page @@ -32,7 +32,7 @@ class DownloadManager( private val context: Context, private val getCategories: GetCategories = 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, manga: Manga): List { // 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) } .map { it.id } @@ -414,7 +414,7 @@ class DownloadManager( return if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) { chapters.filterNot { it.read } - } else if (!preferences.removeBookmarkedChapters().get()) { + } else if (!downloadPreferences.removeBookmarkedChapters().get()) { chapters.filterNot { it.bookmark } } else { chapters diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt index 395692f44c..5d5e2e8944 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt @@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.data.download import android.content.Context import androidx.core.net.toUri import com.hippo.unifile.UniFile +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.R 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.util.storage.DiskUtil 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) { - private val preferences: PreferencesHelper by injectLazy() + private val downloadPreferences: DownloadPreferences by injectLazy() private val scope = MainScope() /** * 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()) DiskUtil.createNoMediaFile(dir, context) dir } init { - preferences.downloadsDirectory().changes() + downloadPreferences.downloadsDirectory().changes() .onEach { downloadsDir = UniFile.fromUri(context, it.toUri()) } .launchIn(scope) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt index 4da0263730..06420659b5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt @@ -9,9 +9,9 @@ import android.os.PowerManager import androidx.annotation.StringRes import androidx.core.content.ContextCompat import com.jakewharton.rxrelay.BehaviorRelay +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.tachiyomi.R 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.withUIContext import eu.kanade.tachiyomi.util.system.acquireWakeLock @@ -84,7 +84,7 @@ class DownloadService : Service() { 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. @@ -164,7 +164,7 @@ class DownloadService : Service() { */ private fun onNetworkStateChanged() { if (isOnline()) { - if (preferences.downloadOnlyOverWifi().get() && !isConnectedToWifi()) { + if (downloadPreferences.downloadOnlyOverWifi().get() && !isConnectedToWifi()) { stopDownloads(R.string.download_notifier_text_only_wifi) } else { val started = downloadManager.startDownloads() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index 856418c757..8f99dbb543 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -4,6 +4,7 @@ import android.content.Context import com.hippo.unifile.UniFile import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.PublishRelay +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.R 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.library.LibraryUpdateNotifier 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.UnmeteredSource import eu.kanade.tachiyomi.source.model.Page @@ -62,7 +62,7 @@ class Downloader( private val cache: DownloadCache, private val sourceManager: SourceManager = 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 { - if (!preferences.splitTallImages().get()) return true + if (!downloadPreferences.splitTallImages().get()) return true val filename = String.format("%03d", page.number) val imageFile = tmpDir.listFiles()?.find { it.name!!.startsWith(filename) } @@ -518,7 +518,7 @@ class Downloader( download.status = if (downloadedImages.size == download.pages!!.size) { // Only rename the directory if it's downloaded. - if (preferences.saveChaptersAsCBZ().get()) { + if (downloadPreferences.saveChaptersAsCBZ().get()) { archiveChapter(mangaDir, dirname, tmpDir) } else { tmpDir.renameTo(dirname) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index a55e3b7e8e..8c3cc051a4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -13,6 +13,7 @@ import eu.kanade.domain.chapter.interactor.GetChapterByMangaId import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay 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.manga.interactor.GetLibraryManga 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_NON_COMPLETED 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.TrackManager import eu.kanade.tachiyomi.data.track.TrackService @@ -86,7 +86,7 @@ import eu.kanade.domain.manga.model.Manga as DomainManga */ class LibraryUpdateService( val sourceManager: SourceManager = Injekt.get(), - val preferences: PreferencesHelper = Injekt.get(), + val downloadPreferences: DownloadPreferences = Injekt.get(), val libraryPreferences: LibraryPreferences = Injekt.get(), val downloadManager: DownloadManager = Injekt.get(), val trackManager: TrackManager = Injekt.get(), @@ -355,7 +355,7 @@ class LibraryUpdateService( if (newChapters.isNotEmpty()) { val categoryIds = getCategories.await(domainManga.id).map { it.id } - if (domainManga.shouldDownloadNewChapters(categoryIds, preferences)) { + if (domainManga.shouldDownloadNewChapters(categoryIds, downloadPreferences)) { downloadChapters(mangaWithNotif, newDbChapters) hasDownloads.set(true) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt index f8d2323976..fa359febd5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt @@ -13,6 +13,7 @@ import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.model.Chapter import eu.kanade.domain.chapter.model.toChapterUpdate 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.model.Manga 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.DownloadService 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.source.SourceManager import eu.kanade.tachiyomi.ui.main.MainActivity @@ -241,14 +241,14 @@ class NotificationReceiver : BroadcastReceiver() { * @param mangaId id of manga */ private fun markAsRead(chapterUrls: Array, mangaId: Long) { - val preferences: PreferencesHelper = Injekt.get() + val downloadPreferences: DownloadPreferences = Injekt.get() val sourceManager: SourceManager = Injekt.get() launchIO { val toUpdate = chapterUrls.mapNotNull { getChapter.await(it, mangaId) } .map { val chapter = it.copy(read = true) - if (preferences.removeAfterMarkedAsRead().get()) { + if (downloadPreferences.removeAfterMarkedAsRead().get()) { val manga = getManga.await(mangaId) if (manga != null) { val source = sourceManager.get(manga.source) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 653a1efe95..a64b045198 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -23,12 +23,6 @@ class PreferencesHelper( 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( Environment.getExternalStorageDirectory().absolutePath + File.separator + context.getString(R.string.app_name), @@ -62,26 +56,10 @@ class PreferencesHelper( 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 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 automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true) @@ -89,13 +67,6 @@ class PreferencesHelper( fun lastAppCheck() = preferenceStore.getLong("last_app_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 filterChapterByRead() = preferenceStore.getInt("default_chapter_filter_by_read", DomainManga.SHOW_ALL.toInt()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index 9f7c0cd216..ca770eafbc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -15,6 +15,7 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.model.ChapterUpdate 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.manga.interactor.GetDuplicateLibraryManga import eu.kanade.domain.manga.interactor.GetMangaWithChapters @@ -82,6 +83,7 @@ class MangaPresenter( val mangaId: Long, val isFromSource: Boolean, private val preferences: PreferencesHelper = Injekt.get(), + private val downloadPreferences: DownloadPreferences = Injekt.get(), private val libraryPreferences: LibraryPreferences = Injekt.get(), private val trackManager: TrackManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(), @@ -679,7 +681,7 @@ class MangaPresenter( presenterScope.launchNonCancellableIO { val manga = successState?.manga ?: return@launchNonCancellableIO 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) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 231f2c0ee1..d85a316f4f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -9,6 +9,7 @@ import eu.kanade.domain.chapter.interactor.GetChapterByMangaId import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.model.ChapterUpdate 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.model.HistoryUpdate import eu.kanade.domain.manga.interactor.GetManga @@ -80,6 +81,7 @@ class ReaderPresenter( private val sourceManager: SourceManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(), private val preferences: PreferencesHelper = Injekt.get(), + private val downloadPreferences: DownloadPreferences = Injekt.get(), private val readerPreferences: ReaderPreferences = Injekt.get(), private val trackPreferences: TrackPreferences = Injekt.get(), private val delayedTrackingStore: DelayedTrackingStore = Injekt.get(), @@ -452,7 +454,7 @@ class ReaderPresenter( val manga = manga ?: return if (getCurrentChapter()?.pageLoader !is DownloadPageLoader) return val nextChapter = viewerChaptersRelay.value?.nextChapter?.chapter ?: return - val chaptersNumberToDownload = preferences.autoDownloadWhileReading().get() + val chaptersNumberToDownload = downloadPreferences.autoDownloadWhileReading().get() if (chaptersNumberToDownload == 0 || !manga.favorite) return val isNextChapterDownloadedOrQueued = downloadManager.isChapterDownloaded( nextChapter.name, @@ -506,7 +508,7 @@ class ReaderPresenter( private fun deleteChapterIfNeeded(currentChapter: ReaderChapter) { // Determine which chapter should be deleted and enqueue val currentChapterPosition = chapterList.indexOf(currentChapter) - val removeAfterReadSlots = preferences.removeAfterReadSlots().get() + val removeAfterReadSlots = downloadPreferences.removeAfterReadSlots().get() val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots) if (removeAfterReadSlots != 0 && chapterDownload != null) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt index 7101fc7bdd..1ad9f997d3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt @@ -12,9 +12,9 @@ import androidx.preference.PreferenceScreen import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.hippo.unifile.UniFile import eu.kanade.domain.category.interactor.GetCategories +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.presentation.category.visualName import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.util.preference.bindTo import eu.kanade.tachiyomi.util.preference.entriesRes @@ -41,6 +41,7 @@ import java.io.File class SettingsDownloadController : SettingsController() { private val getCategories: GetCategories by injectLazy() + private val downloadPreferences: DownloadPreferences by injectLazy() override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { titleRes = R.string.pref_category_downloads @@ -48,7 +49,7 @@ class SettingsDownloadController : SettingsController() { val categories = runBlocking { getCategories.await() } preference { - bindTo(preferences.downloadsDirectory()) + bindTo(downloadPreferences.downloadsDirectory()) titleRes = R.string.pref_download_directory onClick { val ctrl = DownloadDirectoriesDialog() @@ -56,7 +57,7 @@ class SettingsDownloadController : SettingsController() { ctrl.showDialog(router) } - preferences.downloadsDirectory().changes() + downloadPreferences.downloadsDirectory().changes() .onEach { path -> val dir = UniFile.fromUri(context, path.toUri()) summary = dir.filePath ?: path @@ -64,15 +65,15 @@ class SettingsDownloadController : SettingsController() { .launchIn(viewScope) } switchPreference { - bindTo(preferences.downloadOnlyOverWifi()) + bindTo(downloadPreferences.downloadOnlyOverWifi()) titleRes = R.string.connected_to_wifi } switchPreference { - bindTo(preferences.saveChaptersAsCBZ()) + bindTo(downloadPreferences.saveChaptersAsCBZ()) titleRes = R.string.save_chapter_as_cbz } switchPreference { - bindTo(preferences.splitTallImages()) + bindTo(downloadPreferences.splitTallImages()) titleRes = R.string.split_tall_images summaryRes = R.string.split_tall_images_summary } @@ -81,11 +82,11 @@ class SettingsDownloadController : SettingsController() { titleRes = R.string.pref_category_delete_chapters switchPreference { - bindTo(preferences.removeAfterMarkedAsRead()) + bindTo(downloadPreferences.removeAfterMarkedAsRead()) titleRes = R.string.pref_remove_after_marked_as_read } intListPreference { - bindTo(preferences.removeAfterReadSlots()) + bindTo(downloadPreferences.removeAfterReadSlots()) titleRes = R.string.pref_remove_after_read entriesRes = arrayOf( R.string.disabled, @@ -99,16 +100,16 @@ class SettingsDownloadController : SettingsController() { summary = "%s" } switchPreference { - bindTo(preferences.removeBookmarkedChapters()) + bindTo(downloadPreferences.removeBookmarkedChapters()) titleRes = R.string.pref_remove_bookmarked_chapters } multiSelectListPreference { - bindTo(preferences.removeExcludeCategories()) + bindTo(downloadPreferences.removeExcludeCategories()) titleRes = R.string.pref_remove_exclude_categories entries = categories.map { it.visualName(context) }.toTypedArray() entryValues = categories.map { it.id.toString() }.toTypedArray() - preferences.removeExcludeCategories().changes() + downloadPreferences.removeExcludeCategories().changes() .onEach { mutable -> val selected = mutable .mapNotNull { id -> categories.find { it.id == id.toLong() } } @@ -127,20 +128,20 @@ class SettingsDownloadController : SettingsController() { titleRes = R.string.pref_download_new switchPreference { - bindTo(preferences.downloadNewChapters()) + bindTo(downloadPreferences.downloadNewChapters()) titleRes = R.string.pref_download_new } preference { - bindTo(preferences.downloadNewChapterCategories()) + bindTo(downloadPreferences.downloadNewChapterCategories()) titleRes = R.string.categories onClick { DownloadCategoriesDialog().showDialog(router) } - visibleIf(preferences.downloadNewChapters()) { it } + visibleIf(downloadPreferences.downloadNewChapters()) { it } fun updateSummary() { - val selectedCategories = preferences.downloadNewChapterCategories().get() + val selectedCategories = downloadPreferences.downloadNewChapterCategories().get() .mapNotNull { id -> categories.find { it.id == id.toLong() } } .sortedBy { it.order } val includedItemsText = if (selectedCategories.isEmpty()) { @@ -149,7 +150,7 @@ class SettingsDownloadController : SettingsController() { selectedCategories.joinToString { it.visualName(context) } } - val excludedCategories = preferences.downloadNewChapterCategoriesExclude().get() + val excludedCategories = downloadPreferences.downloadNewChapterCategoriesExclude().get() .mapNotNull { id -> categories.find { it.id == id.toLong() } } .sortedBy { it.order } val excludedItemsText = if (excludedCategories.isEmpty()) { @@ -165,10 +166,10 @@ class SettingsDownloadController : SettingsController() { } } - preferences.downloadNewChapterCategories().changes() + downloadPreferences.downloadNewChapterCategories().changes() .onEach { updateSummary() } .launchIn(viewScope) - preferences.downloadNewChapterCategoriesExclude().changes() + downloadPreferences.downloadNewChapterCategoriesExclude().changes() .onEach { updateSummary() } .launchIn(viewScope) } @@ -178,7 +179,7 @@ class SettingsDownloadController : SettingsController() { titleRes = R.string.download_ahead intListPreference { - bindTo(preferences.autoDownloadWhileReading()) + bindTo(downloadPreferences.autoDownloadWhileReading()) titleRes = R.string.auto_download_while_reading entries = arrayOf( context.getString(R.string.disabled), @@ -208,14 +209,14 @@ class SettingsDownloadController : SettingsController() { } val file = UniFile.fromUri(context, uri) - preferences.downloadsDirectory().set(file.uri.toString()) + downloadPreferences.downloadsDirectory().set(file.uri.toString()) } } } fun predefinedDirectorySelected(selectedDir: String) { val path = File(selectedDir).toUri() - preferences.downloadsDirectory().set(path.toString()) + downloadPreferences.downloadsDirectory().set(path.toString()) } fun customDirectorySelected() { @@ -229,11 +230,11 @@ class SettingsDownloadController : SettingsController() { class DownloadDirectoriesDialog : DialogController() { - private val preferences: PreferencesHelper = Injekt.get() + private val downloadPreferences: DownloadPreferences = Injekt.get() override fun onCreateDialog(savedViewState: Bundle?): Dialog { 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) var selectedIndex = externalDirs.indexOfFirst { it in currentDir } @@ -264,7 +265,7 @@ class SettingsDownloadController : SettingsController() { class DownloadCategoriesDialog : DialogController() { - private val preferences: PreferencesHelper = Injekt.get() + private val downloadPreferences: DownloadPreferences = Injekt.get() private val getCategories: GetCategories = Injekt.get() override fun onCreateDialog(savedViewState: Bundle?): Dialog { @@ -274,8 +275,8 @@ class SettingsDownloadController : SettingsController() { var selected = categories .map { when (it.id.toString()) { - in preferences.downloadNewChapterCategories().get() -> QuadStateTextView.State.CHECKED.ordinal - in preferences.downloadNewChapterCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal + in downloadPreferences.downloadNewChapterCategories().get() -> QuadStateTextView.State.CHECKED.ordinal + in downloadPreferences.downloadNewChapterCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal else -> QuadStateTextView.State.UNCHECKED.ordinal } } @@ -302,8 +303,8 @@ class SettingsDownloadController : SettingsController() { .map { categories[it].id.toString() } .toSet() - preferences.downloadNewChapterCategories().set(included) - preferences.downloadNewChapterCategoriesExclude().set(excluded) + downloadPreferences.downloadNewChapterCategories().set(included) + downloadPreferences.downloadNewChapterCategoriesExclude().set(excluded) } .setNegativeButton(android.R.string.cancel, null) .create() diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt index 4fdb2a34d2..4c60ab0ca6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.util import android.content.Context +import eu.kanade.domain.download.service.DownloadPreferences import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.model.hasCustomCover 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.database.models.Manga 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.model.SManga import uy.kohesive.injekt.Injekt @@ -57,7 +57,7 @@ fun DomainManga.removeCovers(coverCache: CoverCache = Injekt.get()): DomainManga return copy(coverLastModified = Date().time) } -fun DomainManga.shouldDownloadNewChapters(dbCategories: List, preferences: PreferencesHelper): Boolean { +fun DomainManga.shouldDownloadNewChapters(dbCategories: List, preferences: DownloadPreferences): Boolean { if (!favorite) return false val categories = dbCategories.ifEmpty { listOf(0L) } diff --git a/core/src/main/java/eu/kanade/tachiyomi/core/provider/AndroidDownloadFolderProvider.kt b/core/src/main/java/eu/kanade/tachiyomi/core/provider/AndroidDownloadFolderProvider.kt new file mode 100644 index 0000000000..f9a5f035f1 --- /dev/null +++ b/core/src/main/java/eu/kanade/tachiyomi/core/provider/AndroidDownloadFolderProvider.kt @@ -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() + } + +} diff --git a/core/src/main/java/eu/kanade/tachiyomi/core/provider/FolderProvider.kt b/core/src/main/java/eu/kanade/tachiyomi/core/provider/FolderProvider.kt new file mode 100644 index 0000000000..1f3fc30a86 --- /dev/null +++ b/core/src/main/java/eu/kanade/tachiyomi/core/provider/FolderProvider.kt @@ -0,0 +1,12 @@ +package eu.kanade.tachiyomi.core.provider + +import java.io.File + +interface FolderProvider { + + fun directory(): File + + fun path(): String + +} +