Optimize and cleanup data saver
This commit is contained in:
parent
90253f3bd4
commit
048eecf655
@ -289,8 +289,6 @@ object PreferenceKeys {
|
|||||||
|
|
||||||
const val mangaDexLowQualityCovers = "manga_dex_low_quality_covers"
|
const val mangaDexLowQualityCovers = "manga_dex_low_quality_covers"
|
||||||
|
|
||||||
const val experimentalFeatures = "experimental_features"
|
|
||||||
|
|
||||||
const val dataSaver = "data_saver"
|
const val dataSaver = "data_saver"
|
||||||
|
|
||||||
const val ignoreJpeg = "ignore_jpeg"
|
const val ignoreJpeg = "ignore_jpeg"
|
||||||
|
@ -394,8 +394,6 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun mangaDexLowQualityCovers() = flowPrefs.getBoolean(Keys.mangaDexLowQualityCovers, false)
|
fun mangaDexLowQualityCovers() = flowPrefs.getBoolean(Keys.mangaDexLowQualityCovers, false)
|
||||||
|
|
||||||
fun experimentalFeatures() = flowPrefs.getBoolean(Keys.experimentalFeatures, false)
|
|
||||||
|
|
||||||
fun dataSaver() = flowPrefs.getBoolean(Keys.dataSaver, false)
|
fun dataSaver() = flowPrefs.getBoolean(Keys.dataSaver, false)
|
||||||
|
|
||||||
fun ignoreJpeg() = flowPrefs.getBoolean(Keys.ignoreJpeg, false)
|
fun ignoreJpeg() = flowPrefs.getBoolean(Keys.ignoreJpeg, false)
|
||||||
|
@ -2,22 +2,25 @@ package eu.kanade.tachiyomi.source.model
|
|||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import eu.kanade.tachiyomi.network.ProgressListener
|
import eu.kanade.tachiyomi.network.ProgressListener
|
||||||
import eu.kanade.tachiyomi.util.DataSaver
|
import exh.util.DataSaver
|
||||||
import rx.subjects.Subject
|
import rx.subjects.Subject
|
||||||
|
|
||||||
open class Page(
|
open class Page(
|
||||||
val index: Int,
|
val index: Int,
|
||||||
/* SY --> */
|
/* SY --> */
|
||||||
var /* SY <-- */ url: String = "",
|
var /* SY <-- */ url: String = "",
|
||||||
|
/* SY --> var <-- SY */
|
||||||
imageUrl: String? = null,
|
imageUrl: String? = null,
|
||||||
@Transient var uri: Uri? = null // Deprecated but can't be deleted due to extensions
|
@Transient var uri: Uri? = null // Deprecated but can't be deleted due to extensions
|
||||||
) : ProgressListener {
|
) : ProgressListener {
|
||||||
|
|
||||||
|
// SY -->
|
||||||
var imageUrl = imageUrl
|
var imageUrl = imageUrl
|
||||||
get() {
|
get() {
|
||||||
if (field == null) return null
|
if (field == null) return null
|
||||||
return DataSaver().compress(field!!)
|
return DataSaver().compress(field!!)
|
||||||
}
|
}
|
||||||
|
// SY <--
|
||||||
|
|
||||||
val number: Int
|
val number: Int
|
||||||
get() = index + 1
|
get() = index + 1
|
||||||
|
@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
|||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Target
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Target
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||||
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.SourceManager.Companion.DELEGATED_SOURCES
|
import eu.kanade.tachiyomi.source.SourceManager.Companion.DELEGATED_SOURCES
|
||||||
@ -26,6 +27,7 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
|||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import eu.kanade.tachiyomi.util.preference.defaultValue
|
import eu.kanade.tachiyomi.util.preference.defaultValue
|
||||||
|
import eu.kanade.tachiyomi.util.preference.editTextPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.intListPreference
|
import eu.kanade.tachiyomi.util.preference.intListPreference
|
||||||
import eu.kanade.tachiyomi.util.preference.onChange
|
import eu.kanade.tachiyomi.util.preference.onChange
|
||||||
import eu.kanade.tachiyomi.util.preference.onClick
|
import eu.kanade.tachiyomi.util.preference.onClick
|
||||||
@ -45,6 +47,7 @@ import kotlinx.coroutines.CoroutineStart
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
@ -158,6 +161,77 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preferenceCategory {
|
||||||
|
titleRes = R.string.data_saver
|
||||||
|
|
||||||
|
switchPreference {
|
||||||
|
titleRes = R.string.data_saver
|
||||||
|
summaryRes = R.string.data_saver_summary
|
||||||
|
key = Keys.dataSaver
|
||||||
|
defaultValue = false
|
||||||
|
}
|
||||||
|
|
||||||
|
editTextPreference {
|
||||||
|
titleRes = R.string.data_saver_server
|
||||||
|
key = Keys.dataSaverServer
|
||||||
|
defaultValue = ""
|
||||||
|
summaryRes = R.string.data_saver_server_summary
|
||||||
|
|
||||||
|
preferences.dataSaver().asImmediateFlow { isVisible = it }
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
switchPreference {
|
||||||
|
titleRes = R.string.ignore_jpeg
|
||||||
|
key = Keys.ignoreJpeg
|
||||||
|
defaultValue = false
|
||||||
|
|
||||||
|
preferences.dataSaver().asImmediateFlow { isVisible = it }
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
switchPreference {
|
||||||
|
titleRes = R.string.ignore_gif
|
||||||
|
key = Keys.ignoreGif
|
||||||
|
defaultValue = true
|
||||||
|
|
||||||
|
preferences.dataSaver().asImmediateFlow { isVisible = it }
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
intListPreference {
|
||||||
|
titleRes = R.string.data_saver_image_quality
|
||||||
|
key = Keys.dataSaverImageQuality
|
||||||
|
entries = arrayOf("10", "20", "40", "50", "70", "80", "90", "95")
|
||||||
|
entryValues = entries
|
||||||
|
defaultValue = "80"
|
||||||
|
summaryRes = R.string.data_saver_image_quality_summary
|
||||||
|
|
||||||
|
preferences.dataSaver().asImmediateFlow { isVisible = it }
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
switchPreference {
|
||||||
|
titleRes = R.string.data_saver_image_format
|
||||||
|
key = Keys.dataSaverImageFormatJpeg
|
||||||
|
defaultValue = false
|
||||||
|
summaryOn = context.getString(R.string.data_saver_image_format_summary_on)
|
||||||
|
summaryOff = context.getString(R.string.data_saver_image_format_summary_off)
|
||||||
|
|
||||||
|
preferences.dataSaver().asImmediateFlow { isVisible = it }
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
switchPreference {
|
||||||
|
titleRes = R.string.data_saver_color_bw
|
||||||
|
key = Keys.dataSaverColorBW
|
||||||
|
defaultValue = false
|
||||||
|
|
||||||
|
preferences.dataSaver().asImmediateFlow { isVisible = it }
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
preferenceCategory {
|
preferenceCategory {
|
||||||
titleRes = R.string.developer_tools
|
titleRes = R.string.developer_tools
|
||||||
isPersistent = false
|
isPersistent = false
|
||||||
@ -195,13 +269,6 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
summary = context.getString(R.string.toggle_delegated_sources_summary, context.getString(R.string.app_name), DELEGATED_SOURCES.values.map { it.sourceName }.distinct().joinToString())
|
summary = context.getString(R.string.toggle_delegated_sources_summary, context.getString(R.string.app_name), DELEGATED_SOURCES.values.map { it.sourceName }.distinct().joinToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
switchPreference {
|
|
||||||
titleRes = R.string.toggle_experimental_features
|
|
||||||
key = Keys.experimentalFeatures
|
|
||||||
defaultValue = false
|
|
||||||
summary = context.getString(R.string.toggle_experimental_features_summary)
|
|
||||||
}
|
|
||||||
|
|
||||||
intListPreference {
|
intListPreference {
|
||||||
key = Keys.eh_logLevel
|
key = Keys.eh_logLevel
|
||||||
titleRes = R.string.log_level
|
titleRes = R.string.log_level
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.ui.setting
|
|
||||||
|
|
||||||
import androidx.preference.PreferenceScreen
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
|
||||||
import eu.kanade.tachiyomi.util.preference.defaultValue
|
|
||||||
import eu.kanade.tachiyomi.util.preference.editTextPreference
|
|
||||||
import eu.kanade.tachiyomi.util.preference.intListPreference
|
|
||||||
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
|
||||||
import eu.kanade.tachiyomi.util.preference.summaryRes
|
|
||||||
import eu.kanade.tachiyomi.util.preference.switchPreference
|
|
||||||
import eu.kanade.tachiyomi.util.preference.titleRes
|
|
||||||
|
|
||||||
class SettingsExperimentalFeatures : SettingsController() {
|
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
|
|
||||||
titleRes = R.string.expermental_feature_sttings
|
|
||||||
|
|
||||||
preferenceCategory {
|
|
||||||
titleRes = R.string.data_saver
|
|
||||||
summaryRes = R.string.data_saver_summary
|
|
||||||
|
|
||||||
switchPreference {
|
|
||||||
titleRes = R.string.enable_data_saver
|
|
||||||
key = Keys.dataSaver
|
|
||||||
defaultValue = false
|
|
||||||
}
|
|
||||||
|
|
||||||
switchPreference {
|
|
||||||
titleRes = R.string.ignore_jpeg
|
|
||||||
key = Keys.ignoreJpeg
|
|
||||||
defaultValue = false
|
|
||||||
}
|
|
||||||
|
|
||||||
switchPreference {
|
|
||||||
titleRes = R.string.ignore_gif
|
|
||||||
key = Keys.ignoreGif
|
|
||||||
defaultValue = true
|
|
||||||
}
|
|
||||||
|
|
||||||
intListPreference {
|
|
||||||
titleRes = R.string.data_saver_image_quality
|
|
||||||
key = Keys.dataSaverImageQuality
|
|
||||||
entries = arrayOf("10", "20", "40", "50", "70", "80", "90", "95")
|
|
||||||
entryValues = entries
|
|
||||||
defaultValue = "80"
|
|
||||||
}
|
|
||||||
|
|
||||||
switchPreference {
|
|
||||||
titleRes = R.string.data_saver_image_format
|
|
||||||
key = Keys.dataSaverImageFormatJpeg
|
|
||||||
defaultValue = false
|
|
||||||
summaryRes = R.string.data_saver_image_format_summary
|
|
||||||
}
|
|
||||||
|
|
||||||
switchPreference {
|
|
||||||
titleRes = R.string.data_saver_color_bw
|
|
||||||
key = Keys.dataSaverColorBW
|
|
||||||
defaultValue = false
|
|
||||||
}
|
|
||||||
|
|
||||||
editTextPreference {
|
|
||||||
titleRes = R.string.data_saver_server
|
|
||||||
key = Keys.dataSaverServer
|
|
||||||
defaultValue = ""
|
|
||||||
summaryRes = R.string.data_saver_server_summary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -80,7 +80,6 @@ class SettingsMainController : SettingsController() {
|
|||||||
onClick { navigateTo(SettingsEhController()) }
|
onClick { navigateTo(SettingsEhController()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SY <--
|
// SY <--
|
||||||
preference {
|
preference {
|
||||||
iconRes = R.drawable.ic_code_24dp
|
iconRes = R.drawable.ic_code_24dp
|
||||||
@ -88,15 +87,6 @@ class SettingsMainController : SettingsController() {
|
|||||||
titleRes = R.string.pref_category_advanced
|
titleRes = R.string.pref_category_advanced
|
||||||
onClick { navigateTo(SettingsAdvancedController()) }
|
onClick { navigateTo(SettingsAdvancedController()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preferences.experimentalFeatures().get()) {
|
|
||||||
preference {
|
|
||||||
iconRes = R.drawable.ic_code_24dp
|
|
||||||
iconTint = tintColor
|
|
||||||
titleRes = R.string.expermental_feature_sttings
|
|
||||||
onClick { navigateTo(SettingsExperimentalFeatures()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateTo(controller: SettingsController) {
|
private fun navigateTo(controller: SettingsController) {
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.util
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
|
|
||||||
class DataSaver() {
|
|
||||||
|
|
||||||
private val prefs: PreferencesHelper by injectLazy()
|
|
||||||
|
|
||||||
fun compress(imageUrl: String): String {
|
|
||||||
val server = prefs.dataSaverServer().get() + "/?"
|
|
||||||
val format = "jpeg=${if (prefs.dataSaverImageFormatJpeg().get()) "1" else "0"}"
|
|
||||||
val quality = "&l=${prefs.dataSaverImageQuality().get()}"
|
|
||||||
val colorBW = "&bw=${if (prefs.dataSaverColorBW().get()) "1" else "0"}"
|
|
||||||
val url = "$server$format$quality$colorBW&url="
|
|
||||||
val ignoreJpeg: Boolean = prefs.ignoreJpeg().get()
|
|
||||||
val ignoreGif: Boolean = prefs.ignoreGif().get()
|
|
||||||
val dataSaverStatus: Boolean = prefs.dataSaver().get()
|
|
||||||
var process = false
|
|
||||||
var processedUrl = imageUrl
|
|
||||||
|
|
||||||
if (dataSaverStatus) process = true
|
|
||||||
if (imageUrl.contains(server)) process = false
|
|
||||||
if (ignoreJpeg) {
|
|
||||||
if (imageUrl.contains(".jpeg", true) || imageUrl.contains(".jpg", true)) process = false
|
|
||||||
}
|
|
||||||
if (ignoreGif) {
|
|
||||||
if (imageUrl.contains(".gif", true)) process = false
|
|
||||||
}
|
|
||||||
if (process) processedUrl = url + imageUrl
|
|
||||||
|
|
||||||
return processedUrl
|
|
||||||
}
|
|
||||||
}
|
|
29
app/src/main/java/exh/util/DataSaver.kt
Normal file
29
app/src/main/java/exh/util/DataSaver.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package exh.util
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
class DataSaver {
|
||||||
|
private val preferences: PreferencesHelper = Injekt.get()
|
||||||
|
|
||||||
|
fun compress(imageUrl: String): String {
|
||||||
|
return if (preferences.dataSaver().get() && preferences.dataSaverServer().get().isNotBlank() && !imageUrl.contains(preferences.dataSaverServer().get() + "/?")) {
|
||||||
|
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)
|
||||||
|
else -> getUrl(imageUrl)
|
||||||
|
}
|
||||||
|
} else imageUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUrl(imageUrl: String): String {
|
||||||
|
val server = preferences.dataSaverServer().get() + "/?"
|
||||||
|
val format = "jpeg=${if (preferences.dataSaverImageFormatJpeg().get()) "1" else "0"}"
|
||||||
|
val quality = "&l=${preferences.dataSaverImageQuality().get()}"
|
||||||
|
val colorBW = "&bw=${if (preferences.dataSaverColorBW().get()) "1" else "0"}"
|
||||||
|
val url = "$server$format$quality$colorBW&url="
|
||||||
|
|
||||||
|
return url + imageUrl
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,6 @@
|
|||||||
<string name="pref_category_all_sources">All Sources</string>
|
<string name="pref_category_all_sources">All Sources</string>
|
||||||
<string name="pref_category_eh">E-Hentai</string>
|
<string name="pref_category_eh">E-Hentai</string>
|
||||||
<string name="pref_category_fork">Fork Settings</string>
|
<string name="pref_category_fork">Fork Settings</string>
|
||||||
<string name="expermental_feature_sttings">Experimental Features</string>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- EH Settings -->
|
<!-- EH Settings -->
|
||||||
@ -121,8 +120,6 @@
|
|||||||
<string name="toggle_hentai_features_summary">This is a experimental feature that will disable all hentai features if toggled off</string>
|
<string name="toggle_hentai_features_summary">This is a experimental feature that will disable all hentai features if toggled off</string>
|
||||||
<string name="toggle_delegated_sources">Enable delegated sources</string>
|
<string name="toggle_delegated_sources">Enable delegated sources</string>
|
||||||
<string name="toggle_delegated_sources_summary">Apply %1$s enhancements to the following sources if they are installed: %2$s</string>
|
<string name="toggle_delegated_sources_summary">Apply %1$s enhancements to the following sources if they are installed: %2$s</string>
|
||||||
<string name="toggle_experimental_features">Show Experimental Features</string>
|
|
||||||
<string name="toggle_experimental_features_summary">Show features that are experimental and not for normal users</string>
|
|
||||||
<string name="log_level">Log level</string>
|
<string name="log_level">Log level</string>
|
||||||
<string name="log_level_summary">Changing this can impact app performance. Force-restart app after changing. Current value: %s</string>
|
<string name="log_level_summary">Changing this can impact app performance. Force-restart app after changing. Current value: %s</string>
|
||||||
<string name="enable_source_blacklist">Enable source blacklist</string>
|
<string name="enable_source_blacklist">Enable source blacklist</string>
|
||||||
@ -137,6 +134,18 @@
|
|||||||
<item quantity="one">Cleanup done. Removed %d folder</item>
|
<item quantity="one">Cleanup done. Removed %d folder</item>
|
||||||
<item quantity="other">Cleanup done. Removed %d folders</item>
|
<item quantity="other">Cleanup done. Removed %d folders</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<string name="data_saver">Data Saver</string>
|
||||||
|
<string name="data_saver_summary">Compress images before downloading or loading in reader, requires a Bandwidth Hero Proxy server</string>
|
||||||
|
<string name="ignore_jpeg">Ignore Jpeg Images</string>
|
||||||
|
<string name="ignore_gif">Ignore Gif Animations</string>
|
||||||
|
<string name="data_saver_image_quality">Image Quality</string>
|
||||||
|
<string name="data_saver_image_quality_summary">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</string>
|
||||||
|
<string name="data_saver_image_format">Compress to Jpeg</string>
|
||||||
|
<string name="data_saver_image_format_summary_on">The Jpeg file size is considerably smaller then Webp is(meaning more data is saved), but it makes the images lose more quality as well.\nCurrently compresses to Jpeg</string>
|
||||||
|
<string name="data_saver_image_format_summary_off">The Jpeg file size is considerably smaller then Webp is(meaning more data is saved), but it makes the images lose more quality as well.\nCurrently compresses to Webp</string>
|
||||||
|
<string name="data_saver_color_bw">Convert to Black And White</string>
|
||||||
|
<string name="data_saver_server">Bandwidth Hero Proxy Server</string>
|
||||||
|
<string name="data_saver_server_summary">Put Bandwidth Hero Proxy server url here</string>
|
||||||
|
|
||||||
<!-- Log Level -->
|
<!-- Log Level -->
|
||||||
<string name="log_minimal">Minimal</string>
|
<string name="log_minimal">Minimal</string>
|
||||||
@ -469,18 +478,5 @@
|
|||||||
<item quantity="other">%2$s, %1$d pages</item>
|
<item quantity="other">%2$s, %1$d pages</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<!-- Experimental Features -->
|
|
||||||
<string name="data_saver">Data Saver</string>
|
|
||||||
<string name="data_saver_summary">Compress images before downloading or loading in reader</string>
|
|
||||||
<string name="enable_data_saver">Enable Data Saver</string>
|
|
||||||
<string name="ignore_jpeg">Ignore Jpeg Images</string>
|
|
||||||
<string name="ignore_gif">Ignore Gif Animation</string>
|
|
||||||
<string name="data_saver_image_quality">Image Quality</string>
|
|
||||||
<string name="data_saver_image_format">Compress to Jpeg</string>
|
|
||||||
<string name="data_saver_color_bw">Convert to Black And White</string>
|
|
||||||
<string name="data_saver_image_format_summary">Compresses to webp if this option is turned off</string>
|
|
||||||
<string name="data_saver_server">Data Saver Server</string>
|
|
||||||
<string name="data_saver_server_summary">It uses Bandwidth Hero Proxy as Server.To use it you need to create a Bandwidth Hero server and give the server URL</string>
|
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user