On library cover load error, delete file and try again
In case file is corrupted
This commit is contained in:
parent
9f17e9116c
commit
f851c5536a
@ -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)
|
||||||
|
}
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,10 +411,10 @@ class MangaDetailsPresenter(
|
|||||||
|
|
||||||
if (thumbnailUrl != networkManga.thumbnail_url) {
|
if (thumbnailUrl != networkManga.thumbnail_url) {
|
||||||
coverCache.deleteFromCache(thumbnailUrl)
|
coverCache.deleteFromCache(thumbnailUrl)
|
||||||
|
}
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
controller.setPaletteColor()
|
controller.setPaletteColor()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
db.insertManga(manga).executeAsBlocking()
|
db.insertManga(manga).executeAsBlocking()
|
||||||
}
|
}
|
||||||
val finChapters = chapters.await()
|
val finChapters = chapters.await()
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user