Переглянути джерело

Split download preferences from PreferencesHelper (#8048)

Andreas 2 роки тому
батько
коміт
e82963c9ef

+ 3 - 3
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,

+ 34 - 0
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())
+}

+ 11 - 0
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<AndroidDownloadFolderProvider>(),
+                preferenceStore = get(),
+            )
+        }
         addSingletonFactory {
             PreferencesHelper(
                 context = application,

+ 5 - 5
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())
     }
 

+ 4 - 4
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<Chapter>, manga: Manga): List<Chapter> {
         // 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

+ 4 - 4
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)
     }

+ 3 - 3
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()

+ 4 - 4
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)

+ 3 - 3
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)
                                                         }

+ 3 - 3
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<String>, 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)

+ 0 - 29
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())

+ 3 - 1
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)
         }
     }

+ 4 - 2
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) {

+ 29 - 28
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()

+ 2 - 2
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<Long>, preferences: PreferencesHelper): Boolean {
+fun DomainManga.shouldDownloadNewChapters(dbCategories: List<Long>, preferences: DownloadPreferences): Boolean {
     if (!favorite) return false
 
     val categories = dbCategories.ifEmpty { listOf(0L) }

+ 25 - 0
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()
+    }
+
+}

+ 12 - 0
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
+
+}
+