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 592d779a0..11717eb6e 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.util.storage.saveTo import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.toast +import exh.util.DataSaver import kotlinx.coroutines.async import logcat.LogPriority import okhttp3.Response @@ -319,6 +320,10 @@ class Downloader( Observable.just(download.pages!!) } + val dataSaver = if (preferences.dataSaverDownloader().get()) { + DataSaver(download.source, preferences) + } else DataSaver.NoOp + pageListObservable .doOnNext { _ -> // Delete all temporary (unfinished) files @@ -333,7 +338,7 @@ class Downloader( .flatMap { download.source.fetchAllImageUrlsFromPageList(it) } // Start downloading images, consider we can have downloaded images already // Concurrently do 5 pages at a time - .flatMap({ page -> getOrDownloadImage(page, download, tmpDir) }, 5) + .flatMap({ page -> getOrDownloadImage(page, download, tmpDir, dataSaver) }, 5) .onBackpressureLatest() // Do when page is downloaded. .doOnNext { notifier.onProgressChange(download) } @@ -357,7 +362,7 @@ class Downloader( * @param download the download of the page. * @param tmpDir the temporary directory of the download. */ - private fun getOrDownloadImage(page: Page, download: Download, tmpDir: UniFile): Observable { + private fun getOrDownloadImage(page: Page, download: Download, tmpDir: UniFile, dataSaver: DataSaver): Observable { // If the image URL is empty, do nothing if (page.imageUrl == null) { return Observable.just(page) @@ -376,7 +381,7 @@ class Downloader( val pageObservable = when { imageFile != null -> Observable.just(imageFile) chapterCache.isImageInCache(page.imageUrl!!) -> copyImageFromCache(chapterCache.getImageFile(page.imageUrl!!), tmpDir, filename) - else -> downloadImage(page, download.source, tmpDir, filename) + else -> downloadImage(page, download.source, tmpDir, filename, dataSaver) } return pageObservable @@ -404,11 +409,16 @@ class Downloader( * @param tmpDir the temporary directory of the download. * @param filename the filename of the image. */ - private fun downloadImage(page: Page, source: HttpSource, tmpDir: UniFile, filename: String): Observable { + private fun downloadImage(page: Page, source: HttpSource, tmpDir: UniFile, filename: String, dataSaver: DataSaver): Observable { page.status = Page.DOWNLOAD_IMAGE page.progress = 0 + val imageUrl = page.imageUrl!! + page.imageUrl = dataSaver.compress(imageUrl) return source.fetchImage(page) .map { response -> + // SY --> + page.imageUrl = imageUrl + // SY <-- val file = tmpDir.createFile("$filename.tmp") try { response.body!!.source().saveTo(file.openOutputStream()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index ca285ec4a..9abf7d4d5 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -369,6 +369,10 @@ object PreferenceKeys { const val dataSaverColorBW = "data_saver_color_bw" + const val dataSaverExcludedSources = "data_saver_excluded" + + const val dataSaverDownloaer = "data_saver_downloader" + const val saveChaptersAsCBZ = "save_chapter_as_cbz" const val saveChaptersAsCBZLevel = "save_chapter_as_cbz_level" 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 5c39ec74b..d8f59f697 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -491,6 +491,10 @@ class PreferencesHelper(val context: Context) { fun dataSaverColorBW() = flowPrefs.getBoolean(Keys.dataSaverColorBW, false) + fun dataSaverExcludedSources() = flowPrefs.getStringSet(Keys.dataSaverExcludedSources, emptySet()) + + fun dataSaverDownloader() = flowPrefs.getBoolean(Keys.dataSaverDownloaer, true) + fun saveChaptersAsCBZ() = flowPrefs.getBoolean(Keys.saveChaptersAsCBZ, false) fun saveChaptersAsCBZLevel() = flowPrefs.getInt(Keys.saveChaptersAsCBZLevel, 0) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt b/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt index a34f304cf..1065afda3 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/model/Page.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.source.model import android.net.Uri import eu.kanade.tachiyomi.network.ProgressListener -import exh.util.DataSaver import rx.subjects.Subject import tachiyomi.source.model.PageUrl @@ -10,16 +9,10 @@ open class Page( val index: Int, /* SY --> */ var /* SY <-- */ url: String = "", - /* SY --> var <-- SY */ - imageUrl: String? = null, + var imageUrl: String? = null, @Transient var uri: Uri? = null // Deprecated but can't be deleted due to extensions ) : ProgressListener { - // SY --> - var imageUrl = imageUrl - get() = field?.let { DataSaver.compress(it) } - // SY <-- - val number: Int get() = index + 1 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt index 83c5c22e0..c0387b694 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt @@ -186,7 +186,7 @@ class SourceController(bundle: Bundle? = null) : } // SY --> - val isWatched = preferences.latestTabSources().get().contains(item.source.id.toString()) + val isWatched = item.source.id.toString() in preferences.latestTabSources().get() if (item.source.supportsLatest) { items.add( @@ -203,6 +203,16 @@ class SourceController(bundle: Bundle? = null) : { addToCategories(item.source) } ) ) + + if (preferences.dataSaver().get()) { + val isExcluded = item.source.id.toString() in preferences.dataSaverExcludedSources().get() + items.add( + Pair( + activity.getString(if (isExcluded) R.string.data_saver_stop_exclude else R.string.data_saver_exclude), + { excludeFromDataSaver(item.source, isExcluded) } + ) + ) + } // SY <-- SourceOptionsDialog(item.source.toString(), items).showDialog(router) @@ -287,6 +297,14 @@ class SourceController(bundle: Bundle? = null) : ) presenter.updateSources() } + + private fun excludeFromDataSaver(source: Source, isExcluded: Boolean) { + if (isExcluded) { + preferences.dataSaverExcludedSources() -= source.id.toString() + } else { + preferences.dataSaverExcludedSources() += source.id.toString() + } + } // SY <-- /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index af5d139aa..d49a5a075 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.util.lang.plusAssign import eu.kanade.tachiyomi.util.system.logcat import exh.source.isEhBasedSource +import exh.util.DataSaver import logcat.LogPriority import rx.Completable import rx.Observable @@ -46,6 +47,10 @@ class HttpPageLoader( private val preloadSize = /* SY --> */ preferences.preloadSize().get() /* SY <-- */ + // SY --> + private val dataSaver = DataSaver(source, preferences) + // SY <-- + init { // EXH --> repeat(preferences.readerThreads().get()) { @@ -270,8 +275,17 @@ class HttpPageLoader( */ private fun HttpSource.cacheImage(page: ReaderPage): Observable { page.status = Page.DOWNLOAD_IMAGE + // SY --> + val imageUrl = page.imageUrl!! + page.imageUrl = dataSaver.compress(imageUrl) + // SY <-- return fetchImage(page) - .doOnNext { chapterCache.putImageToCache(page.imageUrl!!, it) } + .doOnNext { + // SY --> + page.imageUrl = imageUrl + // SY <-- + chapterCache.putImageToCache(page.imageUrl!!, it) + } .map { page } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt index 91cb43547..e50c7e1b7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt @@ -307,7 +307,16 @@ class SettingsAdvancedController : SettingsController() { } switchPreference { - titleRes = R.string.ignore_jpeg + titleRes = R.string.data_saver_downloader + key = Keys.dataSaverDownloaer + defaultValue = true + + preferences.dataSaver().asImmediateFlow { isVisible = it } + .launchIn(viewScope) + } + + switchPreference { + titleRes = R.string.data_saver_ignore_jpeg key = Keys.ignoreJpeg defaultValue = false @@ -316,7 +325,7 @@ class SettingsAdvancedController : SettingsController() { } switchPreference { - titleRes = R.string.ignore_gif + titleRes = R.string.data_saver_ignore_gif key = Keys.ignoreGif defaultValue = true diff --git a/app/src/main/java/exh/util/DataSaver.kt b/app/src/main/java/exh/util/DataSaver.kt index dd6e84aed..828d0a5ca 100644 --- a/app/src/main/java/exh/util/DataSaver.kt +++ b/app/src/main/java/exh/util/DataSaver.kt @@ -2,29 +2,51 @@ package exh.util import com.tfcporciuncula.flow.Preference import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import uy.kohesive.injekt.injectLazy +import tachiyomi.source.Source -object DataSaver { - private val preferences: PreferencesHelper by injectLazy() +interface DataSaver { - fun compress(imageUrl: String): String { - return if (preferences.dataSaver().get() && preferences.dataSaverServer().get().isNotBlank() && !imageUrl.contains(preferences.dataSaverServer().get() + "/?")) { + fun compress(imageUrl: String): String + + companion object { + val NoOp = object : DataSaver { + override fun compress(imageUrl: String): String { + return imageUrl + } + } + } +} + +fun DataSaver(source: Source, preferences: PreferencesHelper): DataSaver { + return if (preferences.dataSaver().get() && source.id.toString() !in preferences.dataSaverExcludedSources().get()) { + return DataSaverImpl(preferences) + } else { + DataSaver.NoOp + } +} + +private class DataSaverImpl(preferences: PreferencesHelper): DataSaver { + private val dataSavedServer = preferences.dataSaverServer().get().trimEnd('/') + + private val ignoreJpg = preferences.ignoreJpeg().get() + private val ignoreGif = preferences.ignoreGif().get() + + private val format = preferences.dataSaverImageFormatJpeg().toIntRepresentation() + private val quality = preferences.dataSaverImageQuality().get() + private val colorBW = preferences.dataSaverColorBW().toIntRepresentation() + + override fun compress(imageUrl: String): String { + return if (dataSavedServer.isNotBlank() && !imageUrl.contains(dataSavedServer)) { when { - imageUrl.contains(".jpeg", true) || imageUrl.contains(".jpg", true) -> if (preferences.ignoreJpeg().get()) imageUrl else getUrl(imageUrl) - imageUrl.contains(".gif", true) -> if (preferences.ignoreGif().get()) imageUrl else getUrl(imageUrl) + imageUrl.contains(".jpeg", true) || imageUrl.contains(".jpg", true) -> if (ignoreJpg) imageUrl else getUrl(imageUrl) + imageUrl.contains(".gif", true) -> if (ignoreGif) imageUrl else getUrl(imageUrl) else -> getUrl(imageUrl) } } else imageUrl } private fun getUrl(imageUrl: String): String { - val server = preferences.dataSaverServer().get() + "/?" - val format = "jpg=" + preferences.dataSaverImageFormatJpeg().toIntRepresentation() - val quality = "l=" + preferences.dataSaverImageQuality().get() - val colorBW = "bw=" + preferences.dataSaverColorBW().toIntRepresentation() - val url = "url=$imageUrl" - - return "$server&$format&$quality&$colorBW&$url" + return "$dataSavedServer/?jpg=$format&l=$quality&bw=$colorBW&url=$imageUrl" } private fun Preference.toIntRepresentation() = if (get()) "1" else "0" diff --git a/app/src/main/res/values-fr/strings_sy.xml b/app/src/main/res/values-fr/strings_sy.xml index a14996c4f..6d8f7d73f 100644 --- a/app/src/main/res/values-fr/strings_sy.xml +++ b/app/src/main/res/values-fr/strings_sy.xml @@ -143,8 +143,8 @@ Économiseur de données Compresser les images avant le téléchargement ou le chargement dans le lecteur, nécessite un serveur Proxy Bandwidth Hero - Ignorer les images Jpeg - Ignorer les animations Gif + Ignorer les images Jpeg + Ignorer les animations Gif Qualité d\'image Des valeurs plus élevées signifient qu\'un pourcentage plus élevé de la qualité d\'image est enregistré, mais cela signifie également que la taille du fichier est plus grande, 80 \% est une bonne médiane entre la taille du fichier et la qualité de l\'image Compresser en Jpeg diff --git a/app/src/main/res/values-pt-rBR/strings_sy.xml b/app/src/main/res/values-pt-rBR/strings_sy.xml index 6bf04e3ed..f23369f06 100644 --- a/app/src/main/res/values-pt-rBR/strings_sy.xml +++ b/app/src/main/res/values-pt-rBR/strings_sy.xml @@ -148,8 +148,8 @@ Economizar Dados Comprime imagens antes de baixar ou carregar no leitor, requer um servidor Bandwidth Hero Proxy - Ignorar Imagens Jpeg - Ignorar Animações Gif + Ignorar Imagens Jpeg + Ignorar Animações Gif Qualidade da Imagem Valores maiores indicam que um maior percentual da qualidade de imagem é salva, mas implicam aumento no tamanho do arquivo, 80 por cento é uma boa média entre tamanho de arquivo e qualidade de imagem Comprimir em Jpeg diff --git a/app/src/main/res/values-ru/strings_sy.xml b/app/src/main/res/values-ru/strings_sy.xml index fcdcbb4f3..45c6631dc 100644 --- a/app/src/main/res/values-ru/strings_sy.xml +++ b/app/src/main/res/values-ru/strings_sy.xml @@ -145,8 +145,8 @@ Экономия данных Сжатие изображений перед скачиванием или загрузкой в Читалке требует наличия прокси-сервера Bandwidth Hero - Игнорировать изображения Jpeg - Игнорировать Gif-Анимацию + Игнорировать изображения Jpeg + Игнорировать Gif-Анимацию Качество изображения Более высокие значения означают, что сохраняется более высокий процент качества изображения, но это также означает, что размер файла больше, 80 процентов-это хорошая промежуточная величина между размером файла и качеством изображения Сжатие в Jpeg diff --git a/app/src/main/res/values/strings_sy.xml b/app/src/main/res/values/strings_sy.xml index 5e9024ea1..54bbb8a1c 100644 --- a/app/src/main/res/values/strings_sy.xml +++ b/app/src/main/res/values/strings_sy.xml @@ -148,8 +148,9 @@ Data Saver Compress images before downloading or loading in reader, requires a Bandwidth Hero Proxy server - Ignore Jpeg Images - Ignore Gif Animations + Use data saver in the downloader + Ignore Jpeg Images + Ignore Gif Animations Image Quality Higher values mean that a higher percentage of the image quality is saved, but it also means the file size is larger, 80 percent is a good median between file size and image quality Compress to Jpeg @@ -329,6 +330,8 @@ Find in another source + Exclude from data saver + Stop excluding from data saver Searching source…