refactor(coil): Move ImageView.loadManga() to its own directory

This commit is contained in:
Ahmad Ansori Palembani 2024-08-21 06:01:21 +07:00
parent 8a168f5581
commit e8fc16d166
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
8 changed files with 88 additions and 80 deletions

View file

@ -4,38 +4,32 @@ import android.graphics.BitmapFactory
import android.widget.ImageView
import androidx.palette.graphics.Palette
import coil3.Image
import coil3.ImageLoader
import coil3.imageLoader
import coil3.request.Disposable
import coil3.request.ImageRequest
import coil3.size.Precision
import coil3.size.SizeResolver
import coil3.target.ImageViewTarget
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.models.updateCoverLastModified
import eu.kanade.tachiyomi.domain.manga.models.Manga
import eu.kanade.tachiyomi.util.system.launchIO
import uy.kohesive.injekt.injectLazy
import yokai.domain.manga.models.MangaCover
class LibraryMangaImageTarget(
override val view: ImageView,
val cover: MangaCover,
val libraryManga: Manga,
) : ImageViewTarget(view) {
private val coverCache: CoverCache by injectLazy()
override fun onError(error: Image?) {
super.onError(error)
if (cover.inLibrary) {
if (libraryManga.favorite) {
launchIO {
val file = coverCache.getCoverFile(cover.url, false)
val file = coverCache.getCoverFile(libraryManga.thumbnail_url, false)
// if the file exists and the there was still an error then the file is corrupted
if (file != null && file.exists()) {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(file.path, options)
if (options.outWidth == -1 || options.outHeight == -1) {
cover.updateCoverLastModified()
libraryManga.updateCoverLastModified()
file.delete()
}
}
@ -44,22 +38,6 @@ class LibraryMangaImageTarget(
}
}
@JvmSynthetic
inline fun ImageView.loadManga(
cover: MangaCover,
imageLoader: ImageLoader = context.imageLoader,
builder: ImageRequest.Builder.() -> Unit = {},
): Disposable {
val request = ImageRequest.Builder(context)
.data(cover)
.target(LibraryMangaImageTarget(this, cover))
.size(SizeResolver.ORIGINAL)
.precision(Precision.INEXACT)
.apply(builder)
.build()
return imageLoader.enqueue(request)
}
fun Palette.getBestColor(defaultColor: Int) = getBestColor() ?: defaultColor
fun Palette.getBestColor(): Int? {

View file

@ -13,7 +13,6 @@ import androidx.core.view.updateLayoutParams
import coil3.dispose
import coil3.size.Scale
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.coil.loadManga
import eu.kanade.tachiyomi.data.database.models.dominantCoverColors
import eu.kanade.tachiyomi.databinding.MangaGridItemBinding
import eu.kanade.tachiyomi.domain.manga.models.Manga
@ -24,7 +23,7 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.view.backgroundColor
import eu.kanade.tachiyomi.util.view.setCards
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import yokai.domain.manga.models.cover
import yokai.presentation.core.util.coil.loadManga
/**
* Class used to hold the displayed data of a manga in the library, like the cover or the title.
@ -125,7 +124,7 @@ class LibraryGridHolder(
private fun setCover(manga: Manga) {
if ((adapter.recyclerView.context as? Activity)?.isDestroyed == true) return
binding.coverThumbnail.loadManga(manga.cover()) {
binding.coverThumbnail.loadManga(manga) {
val hasRatio = binding.coverThumbnail.layoutParams.height != ViewGroup.LayoutParams.WRAP_CONTENT
if (!fixedSize && !hasRatio) {
scale(Scale.FIT)

View file

@ -5,13 +5,12 @@ import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import coil3.dispose
import eu.kanade.tachiyomi.data.coil.loadManga
import eu.kanade.tachiyomi.databinding.MangaListItemBinding
import eu.kanade.tachiyomi.util.lang.highlightText
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.setCards
import yokai.domain.manga.models.cover
import yokai.i18n.MR
import yokai.presentation.core.util.coil.loadManga
import yokai.util.lang.getString
/**
@ -96,7 +95,7 @@ class LibraryListHolder(
// Update the cover.
binding.coverThumbnail.dispose()
binding.coverThumbnail.loadManga(item.manga.cover())
binding.coverThumbnail.loadManga(item.manga)
}
override fun onActionStateChanged(position: Int, actionState: Int) {

View file

@ -18,7 +18,6 @@ import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
import eu.kanade.tachiyomi.data.coil.loadManga
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.seriesType
import eu.kanade.tachiyomi.databinding.EditMangaDialogBinding
@ -41,8 +40,8 @@ import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import yokai.domain.manga.models.cover
import yokai.i18n.MR
import yokai.presentation.core.util.coil.loadManga
import yokai.util.lang.getString
import android.R as AR
@ -99,7 +98,7 @@ class EditMangaDialog : DialogController {
fun onViewCreated() {
val context = binding.root.context
binding.mangaCover.loadManga(manga.cover())
binding.mangaCover.loadManga(manga)
val isLocal = manga.isLocal()
binding.mangaLang.isVisible = isLocal

View file

@ -32,7 +32,6 @@ import coil3.request.placeholder
import com.google.android.material.button.MaterialButton
import com.google.android.material.chip.Chip
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.coil.loadManga
import eu.kanade.tachiyomi.data.database.models.seriesType
import eu.kanade.tachiyomi.databinding.ChapterHeaderItemBinding
import eu.kanade.tachiyomi.databinding.MangaHeaderItemBinding
@ -47,8 +46,8 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.isInNightMode
import eu.kanade.tachiyomi.util.system.isLTR
import eu.kanade.tachiyomi.util.view.resetStrokeColor
import yokai.domain.manga.models.cover
import yokai.i18n.MR
import yokai.presentation.core.util.coil.loadManga
import yokai.util.lang.getString
import android.R as AR
@ -671,41 +670,35 @@ class MangaHeaderHolder(
binding ?: return
if (!manga.initialized) return
val drawable = adapter.controller.binding.mangaCoverFull.drawable
binding.mangaCover.loadManga(
manga.cover(),
builder = {
placeholder(drawable)
error(drawable)
if (manga.favorite) networkCachePolicy(CachePolicy.READ_ONLY)
diskCachePolicy(CachePolicy.READ_ONLY)
},
)
binding.backdrop.loadManga(
manga.cover(),
builder = {
placeholder(drawable)
error(drawable)
if (manga.favorite) networkCachePolicy(CachePolicy.READ_ONLY)
diskCachePolicy(CachePolicy.READ_ONLY)
target(
onSuccess = {
val result = it.asDrawable(itemView.resources)
val bitmap = (result as? BitmapDrawable)?.bitmap
if (bitmap == null) {
binding.backdrop.setImageDrawable(result)
return@target
}
val yOffset = (bitmap.height / 2 * 0.33).toInt()
binding.mangaCover.loadManga(manga) {
placeholder(drawable)
error(drawable)
if (manga.favorite) networkCachePolicy(CachePolicy.READ_ONLY)
diskCachePolicy(CachePolicy.READ_ONLY)
}
binding.backdrop.loadManga(manga) {
placeholder(drawable)
error(drawable)
if (manga.favorite) networkCachePolicy(CachePolicy.READ_ONLY)
diskCachePolicy(CachePolicy.READ_ONLY)
target(
onSuccess = {
val result = it.asDrawable(itemView.resources)
val bitmap = (result as? BitmapDrawable)?.bitmap
if (bitmap == null) {
binding.backdrop.setImageDrawable(result)
return@target
}
val yOffset = (bitmap.height / 2 * 0.33).toInt()
binding.backdrop.setImageDrawable(
Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height - yOffset)
.toDrawable(itemView.resources),
)
applyBlur()
},
)
},
)
binding.backdrop.setImageDrawable(
Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height - yOffset)
.toDrawable(itemView.resources),
)
applyBlur()
},
)
}
}
fun expand() {

View file

@ -5,11 +5,10 @@ import androidx.recyclerview.widget.RecyclerView
import coil3.dispose
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.data.coil.loadManga
import eu.kanade.tachiyomi.databinding.MangaListItemBinding
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.util.view.setCards
import yokai.domain.manga.models.cover
import yokai.presentation.core.util.coil.loadManga
class MangaHolder(
view: View,
@ -30,6 +29,6 @@ class MangaHolder(
// Update the cover.
binding.coverThumbnail.dispose()
binding.coverThumbnail.loadManga(item.manga.cover())
binding.coverThumbnail.loadManga(item.manga)
}
}

View file

@ -16,7 +16,6 @@ import androidx.core.view.updatePaddingRelative
import androidx.transition.TransitionManager
import androidx.transition.TransitionSet
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.coil.loadManga
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.ChapterHistory
import eu.kanade.tachiyomi.data.download.model.Download
@ -32,10 +31,10 @@ import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.timeSpanFromNow
import eu.kanade.tachiyomi.util.view.setAnimVectorCompat
import eu.kanade.tachiyomi.util.view.setCards
import java.util.*
import java.util.concurrent.*
import yokai.domain.manga.models.cover
import java.util.Date
import java.util.concurrent.TimeUnit
import yokai.i18n.MR
import yokai.presentation.core.util.coil.loadManga
import yokai.util.lang.getString
import android.R as AR
@ -213,7 +212,7 @@ class RecentMangaHolder(
else -> context.timeSpanFromNow(MR.strings.read_, item.mch.history.last_read)
}
if ((context as? Activity)?.isDestroyed != true) {
binding.coverThumbnail.loadManga(item.mch.manga.cover())
binding.coverThumbnail.loadManga(item.mch.manga)
}
if (!item.mch.manga.isLocal()) {
notifyStatus(

View file

@ -0,0 +1,42 @@
package yokai.presentation.core.util.coil
import android.widget.ImageView
import coil3.ImageLoader
import coil3.imageLoader
import coil3.request.Disposable
import coil3.request.ImageRequest
import coil3.size.Precision
import coil3.size.SizeResolver
import eu.kanade.tachiyomi.data.coil.LibraryMangaImageTarget
import eu.kanade.tachiyomi.domain.manga.models.Manga
import yokai.domain.manga.models.MangaCover
import yokai.domain.manga.models.cover
fun ImageView.loadManga(
manga: Manga,
imageLoader: ImageLoader = context.imageLoader,
builder: ImageRequest.Builder.() -> Unit = {},
): Disposable {
val request = ImageRequest.Builder(context)
.data(manga.cover())
.target(LibraryMangaImageTarget(this, manga))
.size(SizeResolver.ORIGINAL)
.precision(Precision.INEXACT)
.apply(builder)
.build()
return imageLoader.enqueue(request)
}
fun ImageView.loadManga(
cover: MangaCover,
imageLoader: ImageLoader = context.imageLoader,
builder: ImageRequest.Builder.() -> Unit = {},
): Disposable {
val request = ImageRequest.Builder(context)
.data(cover)
.size(SizeResolver.ORIGINAL)
.precision(Precision.INEXACT)
.apply(builder)
.build()
return imageLoader.enqueue(request)
}