On library cover load error, delete file and try again

In case file is corrupted
This commit is contained in:
Jay 2020-05-20 20:24:58 -04:00
parent 9f17e9116c
commit f851c5536a
9 changed files with 75 additions and 17 deletions

View File

@ -0,0 +1,51 @@
package eu.kanade.tachiyomi.data.download.coil
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.widget.ImageView
import coil.Coil
import coil.ImageLoader
import coil.request.LoadRequest
import coil.request.LoadRequestBuilder
import coil.request.RequestDisposable
import coil.target.ImageViewTarget
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.models.Manga
import uy.kohesive.injekt.injectLazy
class LibraryMangaImageTarget(
override val view: ImageView,
val manga: Manga
) : ImageViewTarget(view) {
private val coverCache: CoverCache by injectLazy()
override fun onError(error: Drawable?) {
super.onError(error)
val file = coverCache.getCoverFile(manga)
// if the file exists and the there was still an error then the file is corrupted
if (file.exists()) {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(file.path, options)
if (options.outWidth == -1 || options.outHeight == -1) {
file.delete()
Coil.imageLoader(view.context).invalidate(manga.key())
}
}
}
}
@JvmSynthetic
inline fun ImageView.loadLibraryManga(
manga: Manga,
imageLoader: ImageLoader = Coil.imageLoader(context),
builder: LoadRequestBuilder.() -> Unit = {}
): RequestDisposable {
val request = LoadRequest.Builder(context)
.data(manga)
.target(LibraryMangaImageTarget(this, manga))
.apply(builder)
.build()
return imageLoader.execute(request)
}

View File

@ -62,7 +62,7 @@ class MangaFetcher : Fetcher<Manga> {
return fileLoader(customCoverFile) return fileLoader(customCoverFile)
} }
val coverFile = coverCache.getCoverFile(manga) val coverFile = coverCache.getCoverFile(manga)
if (coverFile.exists()) { if (coverFile.exists() && options.diskCachePolicy.readEnabled) {
return fileLoader(coverFile) return fileLoader(coverFile)
} }
if (!manga.favorite) { if (!manga.favorite) {

View File

@ -5,10 +5,10 @@ import android.view.Gravity
import android.view.View import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import coil.api.clear import coil.api.clear
import coil.api.loadAny
import coil.size.Precision import coil.size.Precision
import coil.size.Scale import coil.size.Scale
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.coil.loadLibraryManga
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visibleIf import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.manga_grid_item.* import kotlinx.android.synthetic.main.manga_grid_item.*
@ -79,7 +79,7 @@ class LibraryGridHolder(
private fun setCover(manga: Manga) { private fun setCover(manga: Manga) {
if ((adapter.recyclerView.context as? Activity)?.isDestroyed == true) return if ((adapter.recyclerView.context as? Activity)?.isDestroyed == true) return
cover_thumbnail.loadAny(manga) { cover_thumbnail.loadLibraryManga(manga) {
if (!fixedSize) { if (!fixedSize) {
precision(Precision.INEXACT) precision(Precision.INEXACT)
scale(Scale.FIT) scale(Scale.FIT)

View File

@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.ui.library
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import coil.api.clear import coil.api.clear
import coil.api.loadAny
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.coil.loadLibraryManga
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updateLayoutParams
@ -79,7 +79,7 @@ class LibraryListHolder(
cover_thumbnail.clear() cover_thumbnail.clear()
} else { } else {
val id = item.manga.id ?: return val id = item.manga.id ?: return
cover_thumbnail.loadAny(item.manga) cover_thumbnail.loadLibraryManga(item.manga)
} }
} }

View File

@ -307,7 +307,7 @@ class MangaDetailsController : BaseController,
val view = view ?: return val view = view ?: return
val request = LoadRequest.Builder(view.context).data(presenter.manga).allowHardware(false) val request = LoadRequest.Builder(view.context).data(presenter.manga).allowHardware(false)
.target { drawable -> .target(onSuccess = { drawable ->
val bitmap = (drawable as BitmapDrawable).bitmap val bitmap = (drawable as BitmapDrawable).bitmap
// Generate the Palette on a background thread. // Generate the Palette on a background thread.
Palette.from(bitmap).generate { Palette.from(bitmap).generate {
@ -316,7 +316,8 @@ class MangaDetailsController : BaseController,
android.R.attr.colorBackground android.R.attr.colorBackground
) )
// this makes the color more consistent regardless of theme // this makes the color more consistent regardless of theme
val backDropColor = ColorUtils.blendARGB(it.getVibrantColor(colorBack), colorBack, .35f) val backDropColor =
ColorUtils.blendARGB(it.getVibrantColor(colorBack), colorBack, .35f)
coverColor = backDropColor coverColor = backDropColor
getHeader()?.setBackDrop(backDropColor) getHeader()?.setBackDrop(backDropColor)
@ -328,7 +329,13 @@ class MangaDetailsController : BaseController,
} }
manga_cover_full.setImageDrawable(drawable) manga_cover_full.setImageDrawable(drawable)
getHeader()?.updateCover(manga!!) getHeader()?.updateCover(manga!!)
}.build() }, onError = {
val file = presenter.coverCache.getCoverFile(manga!!)
if (file.exists()) {
file.delete()
setPaletteColor()
}
}).build()
Coil.imageLoader(view.context).execute(request) Coil.imageLoader(view.context).execute(request)
} }

View File

@ -411,9 +411,9 @@ class MangaDetailsPresenter(
if (thumbnailUrl != networkManga.thumbnail_url) { if (thumbnailUrl != networkManga.thumbnail_url) {
coverCache.deleteFromCache(thumbnailUrl) coverCache.deleteFromCache(thumbnailUrl)
withContext(Dispatchers.Main) { }
controller.setPaletteColor() withContext(Dispatchers.Main) {
} controller.setPaletteColor()
} }
db.insertManga(manga).executeAsBlocking() db.insertManga(manga).executeAsBlocking()
} }

View File

@ -4,9 +4,9 @@ import android.app.Activity
import android.view.View import android.view.View
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import coil.api.clear import coil.api.clear
import coil.api.loadAny
import coil.transform.CircleCropTransformation import coil.transform.CircleCropTransformation
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.coil.loadLibraryManga
import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterHolder import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterHolder
import eu.kanade.tachiyomi.util.chapter.ChapterUtil import eu.kanade.tachiyomi.util.chapter.ChapterUtil
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
@ -73,7 +73,7 @@ class RecentChapterHolder(private val view: View, private val adapter: RecentCha
// Set cover // Set cover
if ((view.context as? Activity)?.isDestroyed != true) { if ((view.context as? Activity)?.isDestroyed != true) {
manga_cover.clear() manga_cover.clear()
manga_cover.loadAny(item.manga) { manga_cover.loadLibraryManga(item.manga) {
transformations(CircleCropTransformation()) transformations(CircleCropTransformation())
} }
} }

View File

@ -2,9 +2,9 @@ package eu.kanade.tachiyomi.ui.recently_read
import android.view.View import android.view.View
import coil.api.clear import coil.api.clear
import coil.api.loadAny
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
import eu.kanade.tachiyomi.data.download.coil.loadLibraryManga
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.util.lang.toTimestampString import eu.kanade.tachiyomi.util.lang.toTimestampString
import kotlinx.android.synthetic.main.recently_read_item.* import kotlinx.android.synthetic.main.recently_read_item.*
@ -60,6 +60,6 @@ class RecentlyReadHolder(
// Set cover // Set cover
cover.clear() cover.clear()
cover.loadAny(manga) cover.loadLibraryManga(manga)
} }
} }

View File

@ -2,8 +2,8 @@ package eu.kanade.tachiyomi.ui.recents
import android.app.Activity import android.app.Activity
import android.view.View import android.view.View
import coil.api.loadAny
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.coil.loadLibraryManga
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterHolder import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterHolder
@ -69,7 +69,7 @@ class RecentMangaHolder(
) )
} }
if ((itemView.context as? Activity)?.isDestroyed != true) { if ((itemView.context as? Activity)?.isDestroyed != true) {
cover_thumbnail.loadAny(item.mch.manga) cover_thumbnail.loadLibraryManga(item.mch.manga)
} }
notifyStatus( notifyStatus(
if (adapter.isSelected(adapterPosition)) Download.CHECKED else item.status, if (adapter.isSelected(adapterPosition)) Download.CHECKED else item.status,