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 4983a0f125..f7436d0e6f 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 a502c4c31f..ba2a57aaf2 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 fd31f10057..58888764cb 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 a8fddfd390..c64f045759 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 0600e5d619..0000000000
--- 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 5adca64169..b9c3646191 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">
-
-
-
-