mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Change cover placeholder (#6756)
This commit is contained in:
		| @@ -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) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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) } | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user