diff --git a/app/src/main/java/org/koitharu/kotatsu/local/data/PagesCache.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/PagesCache.kt index bf0da97f9..73dd83bb4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/data/PagesCache.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/PagesCache.kt @@ -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() } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt b/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt index 250a63a49..523a18881 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt @@ -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 + } + } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt index c9a07f0fe..f9c6ea3d6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt @@ -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(), +class PagesThumbnailsSheet : + BaseBottomSheet(), OnListItemClickListener { private lateinit var thumbnails: List 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(), 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().gridSize / 100f, this) @@ -90,9 +93,17 @@ class PagesThumbnailsSheet : BaseBottomSheet(), } } + 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(), putString(ARG_TITLE, title) putInt(ARG_CURRENT, currentPage) }.show(fm, TAG) - } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt index 416b520d2..201a4f4ae 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt @@ -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 + loader: PageLoader, + clickListener: OnListItemClickListener, ) = adapterDelegateViewBinding( { 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) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt index 0d8161670..b293d2865 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt @@ -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, coil: ImageLoader, scope: CoroutineScope, - cache: PagesCache, + loader: PageLoader, clickListener: OnListItemClickListener ) : ListDelegationAdapter>() { init { - delegatesManager.addDelegate(pageThumbnailAD(coil, scope, cache, clickListener)) + delegatesManager.addDelegate(pageThumbnailAD(coil, scope, loader, clickListener)) setItems(dataSet) } } \ No newline at end of file