Add Reader Page Preload option

Based on jobobby04@68bfba4

Closes #544

Co-Authored-By: jobobby04 <17078382+jobobby04@users.noreply.github.com>
This commit is contained in:
Jays2Kings 2021-04-07 01:41:05 -04:00
parent 9eaea6507d
commit 74826bc51b
6 changed files with 69 additions and 8 deletions

View File

@ -6,9 +6,15 @@ import com.github.salomonbrys.kotson.fromJson
import com.google.gson.Gson
import com.jakewharton.disklrucache.DiskLruCache
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.saveTo
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import okhttp3.Response
import okio.buffer
import okio.sink
@ -16,6 +22,8 @@ import rx.Observable
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.io.IOException
import kotlin.math.pow
import kotlin.math.roundToLong
/**
* Class used to create chapter cache
@ -39,19 +47,18 @@ class ChapterCache(private val context: Context) {
const val PARAMETER_VALUE_COUNT = 1
/** The maximum number of bytes this cache should use to store. */
const val PARAMETER_CACHE_SIZE = 75L * 1024 * 1024
const val PARAMETER_CACHE_SIZE = 50L * 1024 * 1024
}
/** Google Json class used for parsing JSON files. */
private val gson: Gson by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
private val scope = CoroutineScope(Job() + Dispatchers.IO)
/** Cache class used for cache management. */
private val diskCache = DiskLruCache.open(
File(context.cacheDir, PARAMETER_CACHE_DIRECTORY),
PARAMETER_APP_VERSION,
PARAMETER_VALUE_COUNT,
PARAMETER_CACHE_SIZE
)
private var diskCache = setupDiskCache(preferences.preloadSize().get())
/**
* Returns directory of cache.
@ -71,6 +78,27 @@ class ChapterCache(private val context: Context) {
val readableSize: String
get() = Formatter.formatFileSize(context, realSize)
init {
preferences.preloadSize().asFlow()
.onEach {
// Save old cache for destruction later
val oldCache = diskCache
diskCache = setupDiskCache(it)
oldCache.close()
}
.launchIn(scope)
}
private fun setupDiskCache(cacheSize: Int): DiskLruCache {
return DiskLruCache.open(
File(context.cacheDir, PARAMETER_CACHE_DIRECTORY),
PARAMETER_APP_VERSION,
PARAMETER_VALUE_COUNT,
// 4 pages = 115MB, 6 = ~150MB, 10 = ~200MB, 20 = ~300MB
(PARAMETER_CACHE_SIZE * cacheSize.toFloat().pow(0.6f)).roundToLong()
)
}
/**
* Remove file from cache.
*

View File

@ -70,6 +70,8 @@ object PreferenceKeys {
const val showNavigationOverlayNewUser = "reader_navigation_overlay_new_user"
const val showNavigationOverlayNewUserWebtoon = "reader_navigation_overlay_new_user_webtoon"
const val preloadSize = "preload_size"
const val webtoonSidePadding = "webtoon_side_padding"
const val webtoonEnableZoomOut = "webtoon_enable_zoom_out"

View File

@ -151,6 +151,8 @@ class PreferencesHelper(val context: Context) {
fun showNavigationOverlayNewUserWebtoon() = flowPrefs.getBoolean(Keys.showNavigationOverlayNewUserWebtoon, true)
fun preloadSize() = flowPrefs.getInt(Keys.preloadSize, 6)
fun updateOnlyNonCompleted() = prefs.getBoolean(Keys.updateOnlyNonCompleted, false)
fun autoUpdateTrack() = prefs.getBoolean(Keys.autoUpdateTrack, true)

View File

@ -10,6 +10,12 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerPageHolder
import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.system.ImageUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import rx.Completable
import rx.Observable
import rx.schedulers.Schedulers
@ -41,9 +47,16 @@ class HttpPageLoader(
private val subscriptions = CompositeSubscription()
private val preferences by injectLazy<PreferencesHelper>()
private val preloadSize = 4
private var preloadSize = preferences.preloadSize().get()
private val scope = CoroutineScope(Job() + Dispatchers.IO)
init {
// Adding flow since we can reach reader settings after this is created
preferences.preloadSize().asFlow()
.onEach {
preloadSize = it
}
.launchIn(scope)
subscriptions += Observable.defer { Observable.just(queue.take().page) }
.filter { it.status == Page.QUEUE }
.concatMap { source.fetchImageFromCacheThenNet(it) }
@ -65,6 +78,7 @@ class HttpPageLoader(
*/
override fun recycle() {
super.recycle()
scope.cancel()
subscriptions.unsubscribe()
queue.clear()

View File

@ -57,6 +57,14 @@ class SettingsReaderController : SettingsController() {
defaultValue = false
}
}
intListPreference(activity) {
key = Keys.preloadSize
titleRes = R.string.page_preload_amount
entryValues = listOf(4, 6, 8, 10, 12, 14, 16, 20)
entries = entryValues.map { context.resources.getQuantityString(R.plurals.pages_plural, it, it) }
defaultValue = 6
summaryRes = R.string.amount_of_pages_to_preload
}
}
preferenceCategory {

View File

@ -330,6 +330,8 @@
<string name="double_tap_anim_speed">Double tap animation speed</string>
<string name="show_page_number">Show page number</string>
<string name="true_32bit_color">32-bit color</string>
<string name="page_preload_amount">Page preload amount</string>
<string name="amount_of_pages_to_preload">The amount of pages to preload when reading. Higher values will result in a smoother reading experience, at the cost of higher cache and network usage.</string>
<string name="reduces_banding_impacts_performance">Reduces banding, but impacts
performance</string>
<string name="crop_borders">Crop borders</string>
@ -406,6 +408,11 @@
<string name="page_layout">Page layout</string>
<string name="automatic_can_still_switch">While using automatic page layout, you can still switch between layouts while reading without overriding this setting</string>
<string name="automatic_orientation">Automatic (based on orientation)</string>
<plurals name="pages_plural">
<item quantity="one">%1$d page</item>
<item quantity="other">%1$d pages</item>
</plurals>
<!-- Manga details -->
<string name="about_this_">About this %1$s</string>