diff --git a/app/build.gradle b/app/build.gradle index d716c40b3..78f7e1e6b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -124,7 +124,7 @@ dependencies { implementation 'io.coil-kt:coil-base:2.2.1' implementation 'io.coil-kt:coil-svg:2.2.1' - implementation 'com.github.KotatsuApp:subsampling-scale-image-view:fc92ecb766' + implementation 'com.github.KotatsuApp:subsampling-scale-image-view:cf1fcaa84e' implementation 'com.github.solkin:disk-lru-cache:1.4' implementation 'ch.acra:acra-http:5.9.6' diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/SectionedSelectionController.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/SectionedSelectionController.kt index 5e96cd066..a7edfeea3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/list/SectionedSelectionController.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/SectionedSelectionController.kt @@ -16,6 +16,7 @@ import androidx.savedstate.SavedStateRegistryOwner import kotlin.coroutines.EmptyCoroutineContext import kotlinx.coroutines.Dispatchers import org.koitharu.kotatsu.base.ui.list.decor.AbstractSelectionItemDecoration +import org.koitharu.kotatsu.utils.ext.removeItemDecoration private const val PROVIDER_NAME = "selection_decoration_sectioned" @@ -60,12 +61,24 @@ class SectionedSelectionController( startActionMode() notifySelectionChanged() } + recyclerView.removeItemDecoration(decoration.javaClass) recyclerView.addItemDecoration(decoration) if (pendingData?.isEmpty() == true) { pendingData = null } } + fun isAttached(recyclerView: RecyclerView): Boolean { + if (decorations.isEmpty()) return false + val anyDecoration = decorations.valueAt(0) + for (i in 0 until recyclerView.itemDecorationCount) { + if (recyclerView.getItemDecorationAt(i).javaClass == anyDecoration.javaClass) { + return true + } + } + return false + } + override fun saveState(): Bundle { val bundle = Bundle(decorations.size) for ((k, v) in decorations) { diff --git a/app/src/main/java/org/koitharu/kotatsu/image/ui/ImageActivity.kt b/app/src/main/java/org/koitharu/kotatsu/image/ui/ImageActivity.kt index f8761040a..c8e5300a2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/image/ui/ImageActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/image/ui/ImageActivity.kt @@ -79,7 +79,7 @@ class ImageActivity : BaseActivity() { private fun setDrawable(drawable: Drawable?) { if (drawable != null) { - view.setImage(ImageSource.bitmap(drawable.toBitmap())) + view.setImage(ImageSource.Bitmap(drawable.toBitmap())) } else { view.recycle() } diff --git a/app/src/main/java/org/koitharu/kotatsu/library/ui/adapter/LibraryGroupAD.kt b/app/src/main/java/org/koitharu/kotatsu/library/ui/adapter/LibraryGroupAD.kt index 2fb3b9f42..1d3035fbb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/library/ui/adapter/LibraryGroupAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/library/ui/adapter/LibraryGroupAD.kt @@ -56,8 +56,7 @@ fun libraryGroupAD( binding.buttonMore.setOnClickListener(listenerAdapter) bind { payloads -> - if (payloads.isEmpty()) { - binding.recyclerView.removeItemDecoration(AbstractSelectionItemDecoration::class.java) + if (payloads.isEmpty() || !selectionController.isAttached(binding.recyclerView)) { selectionController.attachToRecyclerView(item, binding.recyclerView) } binding.textViewTitle.text = item.getTitle(context.resources) diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt index ca83488bd..4b8a1d29b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt @@ -3,6 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager import android.net.Uri import androidx.core.net.toUri import androidx.lifecycle.Observer +import com.davemorrissey.labs.subscaleview.OnImageEventListener import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import java.io.File import java.io.IOException @@ -21,7 +22,7 @@ class PageHolderDelegate( private val readerSettings: ReaderSettings, private val callback: Callback, private val exceptionResolver: ExceptionResolver, -) : SubsamplingScaleImageView.DefaultOnImageEventListener(), Observer { +) : OnImageEventListener, Observer { private val scope = loader.loaderScope + Dispatchers.Main.immediate private var state = State.EMPTY @@ -76,7 +77,7 @@ class PageHolderDelegate( callback.onImageShown() } - override fun onImageLoadError(e: Exception) { + override fun onImageLoadError(e: Throwable) { val file = this.file error = e if (state == State.LOADED && e is IOException && file != null && file.exists()) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt index cdc5b53a9..f89930ec0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt @@ -32,11 +32,11 @@ class ReversedPageHolder( binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter() when (settings.zoomMode) { ZoomMode.FIT_CENTER -> { - setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE resetScaleAndCenter() } ZoomMode.FIT_HEIGHT -> { - setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM minScale = height / sHeight.toFloat() setScaleAndCenter( minScale, @@ -44,7 +44,7 @@ class ReversedPageHolder( ) } ZoomMode.FIT_WIDTH -> { - setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM minScale = width / sWidth.toFloat() setScaleAndCenter( minScale, @@ -52,7 +52,7 @@ class ReversedPageHolder( ) } ZoomMode.KEEP_START -> { - setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE setScaleAndCenter( maxScale, PointF(sWidth.toFloat(), 0f), diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt index fba2d45cf..aba8e32bd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt @@ -7,6 +7,7 @@ import android.view.View import androidx.core.view.isVisible import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.asExecutor import org.koitharu.kotatsu.R @@ -28,8 +29,7 @@ open class PageHolder( View.OnClickListener { init { - binding.ssiv.setExecutor(Dispatchers.Default.asExecutor()) - binding.ssiv.setEagerLoadingEnabled(!isLowRamDevice(context)) + binding.ssiv.isEagerLoadingEnabled = !isLowRamDevice(context) binding.ssiv.setOnImageEventListener(delegate) @Suppress("LeakingThis") bindingInfo.buttonRetry.setOnClickListener(this) @@ -63,7 +63,7 @@ open class PageHolder( } override fun onImageReady(uri: Uri) { - binding.ssiv.setImage(ImageSource.uri(uri)) + binding.ssiv.setImage(ImageSource.Uri(uri)) } override fun onImageShowing(settings: ReaderSettings) { @@ -74,11 +74,11 @@ open class PageHolder( binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter() when (settings.zoomMode) { ZoomMode.FIT_CENTER -> { - binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE binding.ssiv.resetScaleAndCenter() } ZoomMode.FIT_HEIGHT -> { - binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM binding.ssiv.minScale = binding.ssiv.height / binding.ssiv.sHeight.toFloat() binding.ssiv.setScaleAndCenter( binding.ssiv.minScale, @@ -86,7 +86,7 @@ open class PageHolder( ) } ZoomMode.FIT_WIDTH -> { - binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM binding.ssiv.minScale = binding.ssiv.width / binding.ssiv.sWidth.toFloat() binding.ssiv.setScaleAndCenter( binding.ssiv.minScale, @@ -94,7 +94,7 @@ open class PageHolder( ) } ZoomMode.KEEP_START -> { - binding.ssiv.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE) + binding.ssiv.minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE binding.ssiv.setScaleAndCenter( binding.ssiv.maxScale, PointF(0f, 0f), diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt index 89fb75aa6..bbdbb1869 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt @@ -5,6 +5,7 @@ import android.view.View import androidx.core.view.isVisible import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.databinding.ItemPageWebtoonBinding @@ -26,6 +27,7 @@ class WebtoonHolder( private var scrollToRestore = 0 init { + binding.ssiv.regionDecoderFactory = SkiaPooledImageRegionDecoder.Factory() binding.ssiv.setOnImageEventListener(delegate) bindingInfo.buttonRetry.setOnClickListener(this) GoneOnInvisibleListener(bindingInfo.progressBar).attach() @@ -56,13 +58,13 @@ class WebtoonHolder( } override fun onImageReady(uri: Uri) { - binding.ssiv.setImage(ImageSource.uri(uri)) + binding.ssiv.setImage(ImageSource.Uri(uri)) } override fun onImageShowing(settings: ReaderSettings) { binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter() with(binding.ssiv) { - setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM) + minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM minScale = width / sWidth.toFloat() maxScale = minScale scrollTo( diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonImageView.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonImageView.kt index 3404d2911..55aa6540a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonImageView.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonImageView.kt @@ -5,10 +5,7 @@ import android.graphics.PointF import android.util.AttributeSet import androidx.recyclerview.widget.RecyclerView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.asExecutor import org.koitharu.kotatsu.parsers.util.toIntUp -import org.koitharu.kotatsu.utils.ext.isLowRamDevice import org.koitharu.kotatsu.utils.ext.parents private const val SCROLL_UNKNOWN = -1 @@ -23,11 +20,6 @@ class WebtoonImageView @JvmOverloads constructor( private var scrollPos = 0 private var scrollRange = SCROLL_UNKNOWN - init { - setExecutor(Dispatchers.Default.asExecutor()) - setEagerLoadingEnabled(!isLowRamDevice(context)) - } - fun scrollBy(delta: Int) { val maxScroll = getScrollRange() if (maxScroll == 0) { @@ -113,4 +105,4 @@ class WebtoonImageView @JvmOverloads constructor( private fun parentHeight(): Int { return parents.firstNotNullOfOrNull { it as? RecyclerView }?.height ?: 0 } -} \ No newline at end of file +}