|
|
|
@ -1,5 +1,6 @@
|
|
|
|
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
|
|
|
|
@ -8,6 +9,7 @@ import androidx.collection.LongSparseArray
|
|
|
|
import androidx.collection.set
|
|
|
|
import androidx.collection.set
|
|
|
|
import dagger.hilt.android.ActivityRetainedLifecycle
|
|
|
|
import dagger.hilt.android.ActivityRetainedLifecycle
|
|
|
|
import dagger.hilt.android.lifecycle.RetainedLifecycle
|
|
|
|
import dagger.hilt.android.lifecycle.RetainedLifecycle
|
|
|
|
|
|
|
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
|
|
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
|
|
|
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
|
|
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
|
|
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
@ -27,8 +29,10 @@ import org.koitharu.kotatsu.core.network.MangaHttpClient
|
|
|
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
|
|
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
|
|
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
|
|
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
|
|
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
|
|
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
|
|
|
|
|
|
|
import org.koitharu.kotatsu.core.util.FileSize
|
|
|
|
import org.koitharu.kotatsu.core.util.RetainedLifecycleCoroutineScope
|
|
|
|
import org.koitharu.kotatsu.core.util.RetainedLifecycleCoroutineScope
|
|
|
|
import org.koitharu.kotatsu.core.util.ext.ensureSuccess
|
|
|
|
import org.koitharu.kotatsu.core.util.ext.ensureSuccess
|
|
|
|
|
|
|
|
import org.koitharu.kotatsu.core.util.ext.ramAvailable
|
|
|
|
import org.koitharu.kotatsu.core.util.ext.withProgress
|
|
|
|
import org.koitharu.kotatsu.core.util.ext.withProgress
|
|
|
|
import org.koitharu.kotatsu.core.util.progress.ProgressDeferred
|
|
|
|
import org.koitharu.kotatsu.core.util.progress.ProgressDeferred
|
|
|
|
import org.koitharu.kotatsu.local.data.CbzFilter
|
|
|
|
import org.koitharu.kotatsu.local.data.CbzFilter
|
|
|
|
@ -47,6 +51,7 @@ import kotlin.coroutines.CoroutineContext
|
|
|
|
|
|
|
|
|
|
|
|
@ActivityRetainedScoped
|
|
|
|
@ActivityRetainedScoped
|
|
|
|
class PageLoader @Inject constructor(
|
|
|
|
class PageLoader @Inject constructor(
|
|
|
|
|
|
|
|
@ApplicationContext private val context: Context,
|
|
|
|
lifecycle: ActivityRetainedLifecycle,
|
|
|
|
lifecycle: ActivityRetainedLifecycle,
|
|
|
|
@MangaHttpClient private val okHttp: OkHttpClient,
|
|
|
|
@MangaHttpClient private val okHttp: OkHttpClient,
|
|
|
|
private val cache: PagesCache,
|
|
|
|
private val cache: PagesCache,
|
|
|
|
@ -76,7 +81,7 @@ class PageLoader @Inject constructor(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun isPrefetchApplicable(): Boolean {
|
|
|
|
fun isPrefetchApplicable(): Boolean {
|
|
|
|
return repository is RemoteMangaRepository && settings.isPagesPreloadEnabled
|
|
|
|
return repository is RemoteMangaRepository && settings.isPagesPreloadEnabled && !isLowRam()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@AnyThread
|
|
|
|
@AnyThread
|
|
|
|
@ -117,6 +122,9 @@ class PageLoader @Inject constructor(
|
|
|
|
|
|
|
|
|
|
|
|
suspend fun convertInPlace(file: File) {
|
|
|
|
suspend fun convertInPlace(file: File) {
|
|
|
|
convertLock.withLock {
|
|
|
|
convertLock.withLock {
|
|
|
|
|
|
|
|
if (context.ramAvailable < file.length() * 2) {
|
|
|
|
|
|
|
|
return@withLock
|
|
|
|
|
|
|
|
}
|
|
|
|
runInterruptible(Dispatchers.Default) {
|
|
|
|
runInterruptible(Dispatchers.Default) {
|
|
|
|
val image = BitmapFactory.decodeFile(file.absolutePath)
|
|
|
|
val image = BitmapFactory.decodeFile(file.absolutePath)
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
@ -204,6 +212,10 @@ class PageLoader @Inject constructor(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun isLowRam(): Boolean {
|
|
|
|
|
|
|
|
return context.ramAvailable <= FileSize.MEGABYTES.convert(PREFETCH_MIN_RAM_MB, FileSize.BYTES)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private class InternalErrorHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler),
|
|
|
|
private class InternalErrorHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler),
|
|
|
|
CoroutineExceptionHandler {
|
|
|
|
CoroutineExceptionHandler {
|
|
|
|
|
|
|
|
|
|
|
|
@ -216,6 +228,7 @@ class PageLoader @Inject constructor(
|
|
|
|
|
|
|
|
|
|
|
|
private const val PROGRESS_UNDEFINED = -1f
|
|
|
|
private const val PROGRESS_UNDEFINED = -1f
|
|
|
|
private const val PREFETCH_LIMIT_DEFAULT = 10
|
|
|
|
private const val PREFETCH_LIMIT_DEFAULT = 10
|
|
|
|
|
|
|
|
private const val PREFETCH_MIN_RAM_MB = 80L
|
|
|
|
|
|
|
|
|
|
|
|
fun createPageRequest(page: MangaPage, pageUrl: String) = Request.Builder()
|
|
|
|
fun createPageRequest(page: MangaPage, pageUrl: String) = Request.Builder()
|
|
|
|
.url(pageUrl)
|
|
|
|
.url(pageUrl)
|
|
|
|
|