Content prefetch settings

pull/293/head
Koitharu 3 years ago
parent e6ae9e8bd6
commit 3413fe6943

@ -14,3 +14,4 @@
-keep class org.koitharu.kotatsu.core.exceptions.* { *; } -keep class org.koitharu.kotatsu.core.exceptions.* { *; }
-keep class org.koitharu.kotatsu.settings.NotificationSettingsLegacyFragment -keep class org.koitharu.kotatsu.settings.NotificationSettingsLegacyFragment
-keep class org.koitharu.kotatsu.core.prefs.ScreenshotsPolicy { *; }

@ -2,7 +2,6 @@ package org.koitharu.kotatsu.core.prefs
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.ConnectivityManager
import android.net.Uri import android.net.Uri
import android.provider.Settings import android.provider.Settings
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
@ -17,6 +16,7 @@ import org.koitharu.kotatsu.core.network.DoHProvider
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.SortOrder import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.shelf.domain.ShelfSection import org.koitharu.kotatsu.shelf.domain.ShelfSection
import org.koitharu.kotatsu.utils.ext.connectivityManager
import org.koitharu.kotatsu.utils.ext.getEnumValue import org.koitharu.kotatsu.utils.ext.getEnumValue
import org.koitharu.kotatsu.utils.ext.observe import org.koitharu.kotatsu.utils.ext.observe
import org.koitharu.kotatsu.utils.ext.putEnumValue import org.koitharu.kotatsu.utils.ext.putEnumValue
@ -34,6 +34,7 @@ import javax.inject.Singleton
class AppSettings @Inject constructor(@ApplicationContext context: Context) { class AppSettings @Inject constructor(@ApplicationContext context: Context) {
private val prefs = PreferenceManager.getDefaultSharedPreferences(context) private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
private val connectivityManager = context.connectivityManager
private val remoteSources = EnumSet.allOf(MangaSource::class.java).apply { private val remoteSources = EnumSet.allOf(MangaSource::class.java).apply {
remove(MangaSource.LOCAL) remove(MangaSource.LOCAL)
@ -156,6 +157,11 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val isDynamicShortcutsEnabled: Boolean val isDynamicShortcutsEnabled: Boolean
get() = prefs.getBoolean(KEY_SHORTCUTS, true) get() = prefs.getBoolean(KEY_SHORTCUTS, true)
fun isContentPrefetchEnabled(): Boolean {
val policy = NetworkPolicy.from(prefs.getString(KEY_PREFETCH_CONTENT, null), NetworkPolicy.NEVER)
return policy.isNetworkAllowed(connectivityManager)
}
var sourcesOrder: List<String> var sourcesOrder: List<String>
get() = prefs.getString(KEY_SOURCES_ORDER, null) get() = prefs.getString(KEY_SOURCES_ORDER, null)
?.split('|') ?.split('|')
@ -234,12 +240,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val isWebtoonZoomEnable: Boolean val isWebtoonZoomEnable: Boolean
get() = prefs.getBoolean(KEY_WEBTOON_ZOOM, true) get() = prefs.getBoolean(KEY_WEBTOON_ZOOM, true)
fun isPagesPreloadAllowed(cm: ConnectivityManager): Boolean { fun isPagesPreloadEnabled(): Boolean {
return when (prefs.getString(KEY_PAGES_PRELOAD, null)?.toIntOrNull()) { val policy = NetworkPolicy.from(prefs.getString(KEY_PAGES_PRELOAD, null), NetworkPolicy.NON_METERED)
NETWORK_ALWAYS -> true return policy.isNetworkAllowed(connectivityManager)
NETWORK_NEVER -> false
else -> cm.isActiveNetworkMetered
}
} }
fun getDateFormat(format: String = prefs.getString(KEY_DATE_FORMAT, "").orEmpty()): DateFormat = fun getDateFormat(format: String = prefs.getString(KEY_DATE_FORMAT, "").orEmpty()): DateFormat =
@ -293,7 +296,6 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val TRACK_FAVOURITES = "favourites" const val TRACK_FAVOURITES = "favourites"
const val KEY_LIST_MODE = "list_mode_2" const val KEY_LIST_MODE = "list_mode_2"
const val KEY_APP_SECTION = "app_section_2"
const val KEY_THEME = "theme" const val KEY_THEME = "theme"
const val KEY_DYNAMIC_THEME = "dynamic_theme" const val KEY_DYNAMIC_THEME = "dynamic_theme"
const val KEY_THEME_AMOLED = "amoled_theme" const val KEY_THEME_AMOLED = "amoled_theme"
@ -355,13 +357,10 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_LOCAL_LIST_ORDER = "local_order" const val KEY_LOCAL_LIST_ORDER = "local_order"
const val KEY_WEBTOON_ZOOM = "webtoon_zoom" const val KEY_WEBTOON_ZOOM = "webtoon_zoom"
const val KEY_SHELF_SECTIONS = "shelf_sections_2" const val KEY_SHELF_SECTIONS = "shelf_sections_2"
const val KEY_PREFETCH_CONTENT = "prefetch_content"
// About // About
const val KEY_APP_UPDATE = "app_update" const val KEY_APP_UPDATE = "app_update"
const val KEY_APP_TRANSLATION = "about_app_translation" const val KEY_APP_TRANSLATION = "about_app_translation"
private const val NETWORK_NEVER = 0
private const val NETWORK_ALWAYS = 1
private const val NETWORK_NON_METERED = 2
} }
} }

@ -0,0 +1,26 @@
package org.koitharu.kotatsu.core.prefs
import android.net.ConnectivityManager
enum class NetworkPolicy(
private val key: Int,
) {
NEVER(0),
ALWAYS(1),
NON_METERED(2);
fun isNetworkAllowed(cm: ConnectivityManager) = when (this) {
NEVER -> false
ALWAYS -> true
NON_METERED -> !cm.isActiveNetworkMetered
}
companion object {
fun from(key: String?, default: NetworkPolicy): NetworkPolicy {
val intKey = key?.toIntOrNull() ?: return default
return enumValues<NetworkPolicy>().find { it.key == intKey } ?: default
}
}
}

@ -90,7 +90,7 @@ class MangaPrefetchService : CoroutineIntentService() {
if (entryPoint.contentCache is StubContentCache) { if (entryPoint.contentCache is StubContentCache) {
return false return false
} }
return true return entryPoint.settings.isContentPrefetchEnabled()
} }
} }
} }

@ -1,12 +1,10 @@
package org.koitharu.kotatsu.reader.domain package org.koitharu.kotatsu.reader.domain
import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.net.Uri import android.net.Uri
import androidx.collection.LongSparseArray import androidx.collection.LongSparseArray
import androidx.collection.set import androidx.collection.set
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -31,7 +29,6 @@ import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.util.await import org.koitharu.kotatsu.parsers.util.await
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
import org.koitharu.kotatsu.utils.ext.connectivityManager
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
import org.koitharu.kotatsu.utils.ext.withProgress import org.koitharu.kotatsu.utils.ext.withProgress
import org.koitharu.kotatsu.utils.progress.ProgressDeferred import org.koitharu.kotatsu.utils.progress.ProgressDeferred
@ -50,13 +47,11 @@ class PageLoader @Inject constructor(
private val okHttp: OkHttpClient, private val okHttp: OkHttpClient,
private val cache: PagesCache, private val cache: PagesCache,
private val settings: AppSettings, private val settings: AppSettings,
@ApplicationContext context: Context,
private val mangaRepositoryFactory: MangaRepository.Factory, private val mangaRepositoryFactory: MangaRepository.Factory,
) : Closeable { ) : Closeable {
val loaderScope = CoroutineScope(SupervisorJob() + InternalErrorHandler() + Dispatchers.Default) val loaderScope = CoroutineScope(SupervisorJob() + InternalErrorHandler() + Dispatchers.Default)
private val connectivityManager = context.connectivityManager
private val tasks = LongSparseArray<ProgressDeferred<File, Float>>() private val tasks = LongSparseArray<ProgressDeferred<File, Float>>()
private val convertLock = Mutex() private val convertLock = Mutex()
private var repository: MangaRepository? = null private var repository: MangaRepository? = null
@ -73,7 +68,7 @@ class PageLoader @Inject constructor(
} }
fun isPrefetchApplicable(): Boolean { fun isPrefetchApplicable(): Boolean {
return repository is RemoteMangaRepository && settings.isPagesPreloadAllowed(connectivityManager) return repository is RemoteMangaRepository && settings.isPagesPreloadEnabled()
} }
fun prefetch(pages: List<ReaderPage>) { fun prefetch(pages: List<ReaderPage>) {

@ -399,4 +399,5 @@
<string name="clear_new_chapters_counters">Also clear information about new chapters</string> <string name="clear_new_chapters_counters">Also clear information about new chapters</string>
<string name="compact">Compact</string> <string name="compact">Compact</string>
<string name="source_disabled">Source disabled</string> <string name="source_disabled">Source disabled</string>
<string name="prefetch_content">Content preloading</string>
</resources> </resources>

@ -19,6 +19,14 @@
android:title="@string/dns_over_https" android:title="@string/dns_over_https"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<ListPreference
android:defaultValue="0"
android:entries="@array/network_policy"
android:entryValues="@array/values_network_policy"
android:key="prefetch_content"
android:title="@string/prefetch_content"
app:useSimpleSummaryProvider="true" />
<Preference <Preference
android:key="local_storage" android:key="local_storage"
android:persistent="false" android:persistent="false"

@ -61,20 +61,19 @@
android:title="@string/show_pages_numbers" /> android:title="@string/show_pages_numbers" />
<ListPreference <ListPreference
android:defaultValue="allow"
android:entries="@array/screenshots_policy" android:entries="@array/screenshots_policy"
android:entryValues="@array/values_screenshots_policy" android:entryValues="@array/values_screenshots_policy"
android:key="screenshots_policy" android:key="screenshots_policy"
android:title="@string/screenshots_policy" android:title="@string/screenshots_policy"
app:defaultValue="allow"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<ListPreference <ListPreference
android:defaultValue="2"
android:entries="@array/network_policy" android:entries="@array/network_policy"
android:entryValues="@array/values_network_policy" android:entryValues="@array/values_network_policy"
android:key="pages_preload" android:key="pages_preload"
android:title="@string/preload_pages" android:title="@string/preload_pages"
app:defaultValue="2"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
</PreferenceScreen> </PreferenceScreen>

Loading…
Cancel
Save