Use PageLoader for thumbnails

This commit is contained in:
Koitharu
2022-04-20 12:57:07 +03:00
parent 44d8d0f246
commit 6bf4e0cf89
5 changed files with 69 additions and 43 deletions

View File

@@ -2,13 +2,13 @@ package org.koitharu.kotatsu.local.data
import android.content.Context
import com.tomclaw.cache.DiskLruCache
import java.io.File
import java.io.InputStream
import kotlinx.coroutines.flow.MutableStateFlow
import org.koitharu.kotatsu.parsers.util.longHashCode
import org.koitharu.kotatsu.utils.FileSize
import org.koitharu.kotatsu.utils.ext.subdir
import org.koitharu.kotatsu.utils.ext.takeIfReadable
import java.io.File
import java.io.InputStream
class PagesCache(context: Context) {
@@ -60,4 +60,4 @@ class PagesCache(context: Context) {
progress.value = (bytesCopied.toDouble() / contentLength.toDouble()).toFloat()
}
}
}
}

View File

@@ -6,10 +6,6 @@ import android.graphics.BitmapFactory
import android.net.Uri
import androidx.collection.LongSparseArray
import androidx.collection.set
import java.io.File
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
import java.util.zip.ZipFile
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -31,6 +27,10 @@ import org.koitharu.kotatsu.parsers.util.await
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
import org.koitharu.kotatsu.utils.ext.connectivityManager
import org.koitharu.kotatsu.utils.progress.ProgressDeferred
import java.io.File
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
import java.util.zip.ZipFile
private const val PROGRESS_UNDEFINED = -1f
private const val PREFETCH_LIMIT_DEFAULT = 10
@@ -115,8 +115,13 @@ class PageLoader : KoinComponent, Closeable {
private fun onIdle() {
synchronized(prefetchQueue) {
val page = prefetchQueue.pollFirst() ?: return
tasks[page.id] = loadPageAsyncImpl(page)
while (prefetchQueue.isNotEmpty()) {
val page = prefetchQueue.pollFirst() ?: return
if (cache[page.url] == null) {
tasks[page.id] = loadPageAsyncImpl(page)
return
}
}
}
}

View File

@@ -19,17 +19,20 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.databinding.SheetPagesBinding
import org.koitharu.kotatsu.list.ui.MangaListSpanResolver
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.reader.domain.PageLoader
import org.koitharu.kotatsu.reader.ui.thumbnails.adapter.PageThumbnailAdapter
import org.koitharu.kotatsu.utils.BottomSheetToolbarController
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
import org.koitharu.kotatsu.utils.ext.withArgs
class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
class PagesThumbnailsSheet :
BaseBottomSheet<SheetPagesBinding>(),
OnListItemClickListener<MangaPage> {
private lateinit var thumbnails: List<PageThumbnail>
private val spanResolver = MangaListSpanResolver()
private var currentPageIndex = -1
private var pageLoader: PageLoader? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -75,11 +78,11 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing))
)
adapter = PageThumbnailAdapter(
thumbnails,
get(),
viewLifecycleScope,
get(),
this@PagesThumbnailsSheet
dataSet = thumbnails,
coil = get(),
scope = viewLifecycleScope,
loader = PageLoader().also { pageLoader = it },
clickListener = this@PagesThumbnailsSheet
)
addOnLayoutChangeListener(spanResolver)
spanResolver.setGridSize(get<AppSettings>().gridSize / 100f, this)
@@ -90,9 +93,17 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
}
}
override fun onDestroyView() {
super.onDestroyView()
pageLoader?.close()
pageLoader = null
}
override fun onItemClick(item: MangaPage, view: View) {
((parentFragment as? OnPageSelectListener)
?: (activity as? OnPageSelectListener))?.run {
(
(parentFragment as? OnPageSelectListener)
?: (activity as? OnPageSelectListener)
)?.run {
onPageSelected(item)
dismiss()
}
@@ -127,6 +138,5 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
putString(ARG_TITLE, title)
putInt(ARG_CURRENT, currentPage)
}.show(fm, TAG)
}
}

View File

@@ -1,27 +1,26 @@
package org.koitharu.kotatsu.reader.ui.thumbnails.adapter
import androidx.core.net.toUri
import android.graphics.drawable.Drawable
import coil.ImageLoader
import coil.request.ImageRequest
import coil.size.PixelSize
import com.google.android.material.R as materialR
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import kotlinx.coroutines.*
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.databinding.ItemPageThumbBinding
import org.koitharu.kotatsu.local.data.PagesCache
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.reader.domain.PageLoader
import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail
import org.koitharu.kotatsu.utils.ext.IgnoreErrors
import org.koitharu.kotatsu.utils.ext.referer
import org.koitharu.kotatsu.utils.ext.setTextColorAttr
import com.google.android.material.R as materialR
fun pageThumbnailAD(
coil: ImageLoader,
scope: CoroutineScope,
cache: PagesCache,
clickListener: OnListItemClickListener<MangaPage>
loader: PageLoader,
clickListener: OnListItemClickListener<MangaPage>,
) = adapterDelegateViewBinding<PageThumbnail, PageThumbnail, ItemPageThumbBinding>(
{ inflater, parent -> ItemPageThumbBinding.inflate(inflater, parent, false) }
) {
@@ -33,6 +32,29 @@ fun pageThumbnailAD(
height = (gridWidth * 13f / 18f).toInt()
)
suspend fun loadPageThumbnail(item: PageThumbnail): Drawable? = withContext(Dispatchers.Default) {
item.page.preview?.let { url ->
coil.execute(
ImageRequest.Builder(context)
.data(url)
.referer(item.page.referer)
.size(thumbSize)
.allowRgb565(true)
.build()
).drawable
}?.let { drawable ->
return@withContext drawable
}
val file = loader.loadPage(item.page, force = false)
coil.execute(
ImageRequest.Builder(context)
.data(file)
.size(thumbSize)
.allowRgb565(true)
.build()
).drawable
}
binding.root.setOnClickListener {
clickListener.onItemClick(item.page, itemView)
}
@@ -45,22 +67,11 @@ fun pageThumbnailAD(
setTextColorAttr(if (item.isCurrent) materialR.attr.colorOnTertiary else android.R.attr.textColorPrimary)
text = (item.number).toString()
}
job = scope.launch(Dispatchers.Default + IgnoreErrors) {
val url = item.page.preview ?: item.page.url.let {
val pageUrl = item.repository.getPageUrl(item.page)
cache[pageUrl]?.toUri()?.toString() ?: pageUrl
}
val drawable = coil.execute(
ImageRequest.Builder(context)
.data(url)
.referer(item.page.referer)
.size(thumbSize)
.allowRgb565(true)
.build()
).drawable
withContext(Dispatchers.Main) {
binding.imageViewThumb.setImageDrawable(drawable)
}
job = scope.launch {
val drawable = runCatching {
loadPageThumbnail(item)
}.getOrNull()
binding.imageViewThumb.setImageDrawable(drawable)
}
}

View File

@@ -4,20 +4,20 @@ import coil.ImageLoader
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
import kotlinx.coroutines.CoroutineScope
import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.local.data.PagesCache
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.reader.domain.PageLoader
import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail
class PageThumbnailAdapter(
dataSet: List<PageThumbnail>,
coil: ImageLoader,
scope: CoroutineScope,
cache: PagesCache,
loader: PageLoader,
clickListener: OnListItemClickListener<MangaPage>
) : ListDelegationAdapter<List<PageThumbnail>>() {
init {
delegatesManager.addDelegate(pageThumbnailAD(coil, scope, cache, clickListener))
delegatesManager.addDelegate(pageThumbnailAD(coil, scope, loader, clickListener))
setItems(dataSet)
}
}