diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/latest/LatestCardHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/latest/LatestCardHolder.kt
index 844f41ea5..ad4de5acb 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/latest/LatestCardHolder.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/latest/LatestCardHolder.kt
@@ -3,15 +3,11 @@ package eu.kanade.tachiyomi.ui.browse.latest
import android.view.View
import androidx.core.view.isVisible
import coil.dispose
-import coil.imageLoader
-import coil.request.CachePolicy
-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 LatestCardHolder(view: View, adapter: LatestCardAdapter) :
FlexibleViewHolder(view, adapter) {
@@ -55,17 +51,8 @@ class LatestCardHolder(view: View, adapter: LatestCardAdapter) :
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)
- .diskCachePolicy(CachePolicy.DISABLED)
- .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/ui/browse/source/browse/SourceComfortableGridHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt
index bd156eecd..798cc1c3a 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,15 +2,12 @@ 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.R
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
import exh.metadata.metadata.MangaDexSearchMetadata
import exh.metadata.metadata.base.RaisedSearchMetadata
@@ -67,16 +64,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 49142f806..65fb3c777 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,15 +2,12 @@ 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.R
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
import exh.metadata.metadata.MangaDexSearchMetadata
import exh.metadata.metadata.base.RaisedSearchMetadata
@@ -67,16 +64,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/browse/SourceEnhancedEHentaiListHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceEnhancedEHentaiListHolder.kt
index 4336722d1..8447951af 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceEnhancedEHentaiListHolder.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceEnhancedEHentaiListHolder.kt
@@ -3,17 +3,13 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
import android.view.View
import androidx.core.view.isVisible
import coil.dispose
-import coil.imageLoader
-import coil.request.CachePolicy
-import coil.request.ImageRequest
-import coil.transition.CrossfadeTransition
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.databinding.SourceEnhancedEhentaiListItemBinding
import eu.kanade.tachiyomi.util.system.getResourceColor
-import eu.kanade.tachiyomi.widget.StateImageViewTarget
+import eu.kanade.tachiyomi.util.view.loadAutoPause
import exh.metadata.MetadataUtil
import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.base.RaisedSearchMetadata
@@ -50,10 +46,11 @@ class SourceEnhancedEHentaiListHolder(view: View, adapter: FlexibleAdapter<*>) :
binding.thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f
// For rounded corners
- binding.badges.clipToOutline = true
+ binding.badges.leftBadges.clipToOutline = true
+ binding.badges.rightBadges.clipToOutline = true
// Set favorite badge
- binding.favoriteText.isVisible = manga.favorite
+ binding.badges.favoriteText.isVisible = manga.favorite
setImage(manga)
}
@@ -103,21 +100,9 @@ class SourceEnhancedEHentaiListHolder(view: View, adapter: FlexibleAdapter<*>) :
}
override fun setImage(manga: Manga) {
- // For rounded corners
- binding.card.clipToOutline = true
-
binding.thumbnail.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)
- .diskCachePolicy(CachePolicy.DISABLED)
- .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/ui/browse/source/index/IndexCardHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/index/IndexCardHolder.kt
index fc4650b9c..6ef2626d3 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/index/IndexCardHolder.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/index/IndexCardHolder.kt
@@ -3,15 +3,11 @@ package eu.kanade.tachiyomi.ui.browse.source.index
import android.view.View
import androidx.core.view.isVisible
import coil.dispose
-import coil.imageLoader
-import coil.request.CachePolicy
-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 IndexCardHolder(view: View, adapter: IndexCardAdapter) :
FlexibleViewHolder(view, adapter) {
@@ -55,17 +51,8 @@ class IndexCardHolder(view: View, adapter: IndexCardAdapter) :
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)
- .diskCachePolicy(CachePolicy.DISABLED)
- .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 100755
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 ce8578e58..b86ddc316 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">
-
-
-
-
diff --git a/app/src/main/res/layout/source_enhanced_ehentai_list_item.xml b/app/src/main/res/layout/source_enhanced_ehentai_list_item.xml
index 012e41b31..5f3e7e5ba 100644
--- a/app/src/main/res/layout/source_enhanced_ehentai_list_item.xml
+++ b/app/src/main/res/layout/source_enhanced_ehentai_list_item.xml
@@ -8,58 +8,29 @@
android:foreground="@drawable/library_item_selector_overlay"
android:padding="4dp">
-
-
-
-
-
-
-
-
-
-
-
+ app:layout_constraintTop_toTopOf="parent"
+ app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Cover"
+ tools:ignore="ContentDescription"
+ tools:src="@mipmap/ic_launcher" />
+
@@ -83,7 +54,7 @@
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toEndOf="@+id/card"
+ app:layout_constraintStart_toEndOf="@+id/thumbnail"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="Manga title for the life of me I cant think yes totally" />
@@ -95,7 +66,7 @@
android:layout_marginBottom="8dp"
android:background="@drawable/rounded_rectangle"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@+id/card">
+ app:layout_constraintStart_toEndOf="@+id/thumbnail">
+ app:layout_constraintStart_toEndOf="@+id/thumbnail" />