diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt index 4983a0f12..f7436d0e6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt @@ -2,14 +2,11 @@ package eu.kanade.tachiyomi.ui.browse.source.browse import androidx.core.view.isVisible import coil.dispose -import coil.imageLoader -import coil.request.ImageRequest -import coil.transition.CrossfadeTransition import eu.davidea.flexibleadapter.FlexibleAdapter import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding -import eu.kanade.tachiyomi.widget.StateImageViewTarget +import eu.kanade.tachiyomi.util.view.loadAutoPause /** * Class used to hold the displayed data of a manga in the catalogue, like the cover or the title. @@ -49,16 +46,8 @@ class SourceComfortableGridHolder( override fun setImage(manga: Manga) { binding.thumbnail.dispose() - if (!manga.thumbnail_url.isNullOrEmpty()) { - val crossfadeDuration = binding.root.context.imageLoader.defaults.transitionFactory.let { - if (it is CrossfadeTransition.Factory) it.durationMillis else 0 - } - val request = ImageRequest.Builder(binding.root.context) - .data(manga) - .setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) - .target(StateImageViewTarget(binding.thumbnail, binding.progress, crossfadeDuration)) - .build() - itemView.context.imageLoader.enqueue(request) + binding.thumbnail.loadAutoPause(manga) { + setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceCompactGridHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceCompactGridHolder.kt index a502c4c31..ba2a57aaf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceCompactGridHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceCompactGridHolder.kt @@ -2,14 +2,11 @@ package eu.kanade.tachiyomi.ui.browse.source.browse import androidx.core.view.isVisible import coil.dispose -import coil.imageLoader -import coil.request.ImageRequest -import coil.transition.CrossfadeTransition import eu.davidea.flexibleadapter.FlexibleAdapter import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding -import eu.kanade.tachiyomi.widget.StateImageViewTarget +import eu.kanade.tachiyomi.util.view.loadAutoPause /** * Class used to hold the displayed data of a manga in the catalogue, like the cover or the title. @@ -49,16 +46,8 @@ class SourceCompactGridHolder( override fun setImage(manga: Manga) { binding.thumbnail.dispose() - if (!manga.thumbnail_url.isNullOrEmpty()) { - val crossfadeDuration = binding.root.context.imageLoader.defaults.transitionFactory.let { - if (it is CrossfadeTransition.Factory) it.durationMillis else 0 - } - val request = ImageRequest.Builder(binding.root.context) - .data(manga) - .setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) - .target(StateImageViewTarget(binding.thumbnail, binding.progress, crossfadeDuration)) - .build() - itemView.context.imageLoader.enqueue(request) + binding.thumbnail.loadAutoPause(manga) { + setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt index fd31f1005..58888764c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchCardHolder.kt @@ -3,14 +3,11 @@ package eu.kanade.tachiyomi.ui.browse.source.globalsearch import android.view.View import androidx.core.view.isVisible import coil.dispose -import coil.imageLoader -import coil.request.ImageRequest -import coil.transition.CrossfadeTransition import eu.davidea.viewholders.FlexibleViewHolder import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.databinding.GlobalSearchControllerCardItemBinding -import eu.kanade.tachiyomi.widget.StateImageViewTarget +import eu.kanade.tachiyomi.util.view.loadAutoPause class GlobalSearchCardHolder(view: View, adapter: GlobalSearchCardAdapter) : FlexibleViewHolder(view, adapter) { @@ -54,16 +51,8 @@ class GlobalSearchCardHolder(view: View, adapter: GlobalSearchCardAdapter) : fun setImage(manga: Manga) { binding.cover.dispose() - if (!manga.thumbnail_url.isNullOrEmpty()) { - val crossfadeDuration = itemView.context.imageLoader.defaults.transitionFactory.let { - if (it is CrossfadeTransition.Factory) it.durationMillis else 0 - } - val request = ImageRequest.Builder(itemView.context) - .data(manga) - .setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) - .target(StateImageViewTarget(binding.cover, binding.progress, crossfadeDuration)) - .build() - itemView.context.imageLoader.enqueue(request) + binding.cover.loadAutoPause(manga) { + setParameter(MangaCoverFetcher.USE_CUSTOM_COVER, false) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/view/ImageViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/view/ImageViewExtensions.kt index a8fddfd39..c64f04575 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/view/ImageViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/view/ImageViewExtensions.kt @@ -1,11 +1,14 @@ package eu.kanade.tachiyomi.util.view import android.content.Context +import android.graphics.Color import android.graphics.drawable.Animatable +import android.graphics.drawable.ColorDrawable import android.widget.ImageView import androidx.annotation.AttrRes import androidx.annotation.DrawableRes import androidx.appcompat.content.res.AppCompatResources +import androidx.core.graphics.ColorUtils import coil.ImageLoader import coil.imageLoader import coil.load @@ -38,20 +41,22 @@ fun ImageView.loadAutoPause( loader: ImageLoader = context.imageLoader, builder: ImageRequest.Builder.() -> Unit = {} ) { - // Build the original request so we can add on our success listener load(data, loader) { + val placeholderColor = ColorUtils.setAlphaComponent(Color.GRAY, 0x1F) // 12% gray + placeholder(ColorDrawable(placeholderColor)) + // Build the original request so we can add on our success listener - val originalBuild = apply(builder).build() + val originalListener = apply(builder).build().listener listener( onSuccess = { request, metadata -> (request.target as? ImageViewTarget)?.drawable.let { if (it is Animatable && context.animatorDurationScale == 0f) it.stop() } - originalBuild.listener?.onSuccess(request, metadata) + originalListener?.onSuccess(request, metadata) }, - onStart = { request -> originalBuild.listener?.onStart(request) }, - onCancel = { request -> originalBuild.listener?.onCancel(request) }, - onError = { request, throwable -> originalBuild.listener?.onError(request, throwable) } + onStart = { request -> originalListener?.onStart(request) }, + onCancel = { request -> originalListener?.onCancel(request) }, + onError = { request, throwable -> originalListener?.onError(request, throwable) } ) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/StateImageViewTarget.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/StateImageViewTarget.kt deleted file mode 100644 index 0600e5d61..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/StateImageViewTarget.kt +++ /dev/null @@ -1,43 +0,0 @@ -package eu.kanade.tachiyomi.widget - -import android.graphics.drawable.Drawable -import android.view.View -import android.widget.ImageView -import androidx.core.view.isVisible -import coil.drawable.CrossfadeDrawable -import coil.target.ImageViewTarget - -/** - * A Coil target to display an image with an optional view to show while loading. - * - * @param target the view where the image will be loaded - * @param progress the view to show when the image is loading. - * @param crossfadeDuration duration in millisecond to crossfade the result drawable - */ -class StateImageViewTarget( - private val target: ImageView, - private val progress: View, - private val crossfadeDuration: Int = 0 -) : ImageViewTarget(target) { - override fun onStart(placeholder: Drawable?) { - progress.isVisible = true - } - - override fun onSuccess(result: Drawable) { - progress.isVisible = false - if (crossfadeDuration > 0) { - val crossfadeResult = CrossfadeDrawable(target.drawable, result, durationMillis = crossfadeDuration) - target.setImageDrawable(crossfadeResult) - crossfadeResult.start() - } else { - target.setImageDrawable(result) - } - } - - override fun onError(error: Drawable?) { - progress.isVisible = false - if (error != null) { - target.setImageDrawable(error) - } - } -} diff --git a/app/src/main/res/layout/source_comfortable_grid_item.xml b/app/src/main/res/layout/source_comfortable_grid_item.xml index 5adca6416..b9c364619 100644 --- a/app/src/main/res/layout/source_comfortable_grid_item.xml +++ b/app/src/main/res/layout/source_comfortable_grid_item.xml @@ -9,19 +9,6 @@ android:foreground="@drawable/library_item_selector_overlay" android:padding="4dp"> - - - -