mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-14 05:15:10 +01:00
Coil updates
Non library manga goes into android's default cache Manga Fetcher now respects network cache policy Not showing error drawable on manga details Fixed manga notification icon sometimes not showing General cleanup
This commit is contained in:
parent
67a76da475
commit
cce6fdb765
@ -13,7 +13,6 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.Cache
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -36,8 +35,6 @@ class CoverCache(val context: Context) {
|
|||||||
private val cacheDir = context.getExternalFilesDir("covers")
|
private val cacheDir = context.getExternalFilesDir("covers")
|
||||||
?: File(context.filesDir, "covers").also { it.mkdirs() }
|
?: File(context.filesDir, "covers").also { it.mkdirs() }
|
||||||
|
|
||||||
val cache = Cache(cacheDir, 300 * 1024 * 1024) // 300MB
|
|
||||||
|
|
||||||
fun getChapterCacheSize(): String {
|
fun getChapterCacheSize(): String {
|
||||||
return Formatter.formatFileSize(context, DiskUtil.getDirectorySize(cacheDir))
|
return Formatter.formatFileSize(context, DiskUtil.getDirectorySize(cacheDir))
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ class ByteArrayFetcher : Fetcher<ByteArray> {
|
|||||||
size: Size,
|
size: Size,
|
||||||
options: Options
|
options: Options
|
||||||
): FetchResult {
|
): FetchResult {
|
||||||
val source = ByteArrayInputStream(data).source().buffer()
|
|
||||||
return SourceResult(
|
return SourceResult(
|
||||||
source = ByteArrayInputStream(data).source().buffer(),
|
source = ByteArrayInputStream(data).source().buffer(),
|
||||||
mimeType = "image/gif",
|
mimeType = "image/gif",
|
||||||
|
@ -9,7 +9,6 @@ import coil.decode.ImageDecoderDecoder
|
|||||||
import coil.decode.SvgDecoder
|
import coil.decode.SvgDecoder
|
||||||
import coil.util.CoilUtils
|
import coil.util.CoilUtils
|
||||||
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
class CoilSetup(context: Context) {
|
class CoilSetup(context: Context) {
|
||||||
@ -19,7 +18,6 @@ class CoilSetup(context: Context) {
|
|||||||
.crossfade(true)
|
.crossfade(true)
|
||||||
.allowRgb565(true)
|
.allowRgb565(true)
|
||||||
.allowHardware(false)
|
.allowHardware(false)
|
||||||
.error(R.drawable.ic_broken_image_grey_24dp)
|
|
||||||
.componentRegistry {
|
.componentRegistry {
|
||||||
if (Build.VERSION.SDK_INT >= 28) {
|
if (Build.VERSION.SDK_INT >= 28) {
|
||||||
add(ImageDecoderDecoder())
|
add(ImageDecoderDecoder())
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.data.download.coil
|
package eu.kanade.tachiyomi.data.download.coil
|
||||||
|
|
||||||
|
import android.webkit.MimeTypeMap
|
||||||
import coil.bitmappool.BitmapPool
|
import coil.bitmappool.BitmapPool
|
||||||
import coil.decode.DataSource
|
import coil.decode.DataSource
|
||||||
import coil.decode.Options
|
import coil.decode.Options
|
||||||
@ -10,11 +11,15 @@ import coil.size.Size
|
|||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
|
import eu.kanade.tachiyomi.network.await
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
|
import okhttp3.CacheControl
|
||||||
import okhttp3.Call
|
import okhttp3.Call
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import okhttp3.ResponseBody
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.sink
|
import okio.sink
|
||||||
import okio.source
|
import okio.source
|
||||||
@ -29,47 +34,51 @@ class MangaFetcher() : Fetcher<Manga> {
|
|||||||
private val sourceManager: SourceManager by injectLazy()
|
private val sourceManager: SourceManager by injectLazy()
|
||||||
private val defaultClient = Injekt.get<NetworkHelper>().client
|
private val defaultClient = Injekt.get<NetworkHelper>().client
|
||||||
|
|
||||||
override fun key(manga: Manga): String? {
|
override fun key(data: Manga): String? {
|
||||||
if (manga.thumbnail_url.isNullOrBlank()) return null
|
if (data.thumbnail_url.isNullOrBlank()) return null
|
||||||
return DiskUtil.hashKeyForDisk(manga.thumbnail_url!!)
|
return if (!data.favorite) {
|
||||||
|
data.thumbnail_url!!
|
||||||
|
} else {
|
||||||
|
DiskUtil.hashKeyForDisk(data.thumbnail_url!!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun fetch(pool: BitmapPool, manga: Manga, size: Size, options: Options): FetchResult {
|
override suspend fun fetch(pool: BitmapPool, data: Manga, size: Size, options: Options): FetchResult {
|
||||||
val cover = manga.thumbnail_url
|
val cover = data.thumbnail_url
|
||||||
when (getResourceType(cover)) {
|
return when (getResourceType(cover)) {
|
||||||
Type.File -> {
|
Type.File -> fileLoader(data)
|
||||||
return fileLoader(manga)
|
Type.URL -> httpLoader(data, options)
|
||||||
}
|
Type.CUSTOM -> customLoader(data, options)
|
||||||
Type.URL -> {
|
|
||||||
return httpLoader(manga)
|
|
||||||
}
|
|
||||||
Type.CUSTOM -> {
|
|
||||||
return customLoader(manga)
|
|
||||||
}
|
|
||||||
null -> error("Invalid image")
|
null -> error("Invalid image")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun customLoader(manga: Manga): FetchResult {
|
private suspend fun customLoader(manga: Manga, options: Options): FetchResult {
|
||||||
val coverFile = coverCache.getCoverFile(manga)
|
val coverFile = coverCache.getCoverFile(manga)
|
||||||
if (coverFile.exists()) {
|
if (coverFile.exists()) {
|
||||||
return fileLoader(coverFile)
|
return fileLoader(coverFile)
|
||||||
}
|
}
|
||||||
manga.thumbnail_url = manga.thumbnail_url!!.substringAfter("-J2K-").substringAfter("CUSTOM-")
|
manga.thumbnail_url = manga.thumbnail_url!!.substringAfter("-J2K-").substringAfter("CUSTOM-")
|
||||||
return httpLoader(manga)
|
return httpLoader(manga, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun httpLoader(manga: Manga): FetchResult {
|
private suspend fun httpLoader(manga: Manga, options: Options): FetchResult {
|
||||||
val coverFile = coverCache.getCoverFile(manga)
|
val coverFile = coverCache.getCoverFile(manga)
|
||||||
if (coverFile.exists()) {
|
if (coverFile.exists()) {
|
||||||
return fileLoader(coverFile)
|
return fileLoader(coverFile)
|
||||||
}
|
}
|
||||||
val call = getCall(manga)
|
if (!manga.favorite) {
|
||||||
|
val (response, body) = awaitGetCall(manga)
|
||||||
|
|
||||||
|
return SourceResult(
|
||||||
|
source = body.source(),
|
||||||
|
mimeType = getMimeType(manga.thumbnail_url!!, body),
|
||||||
|
dataSource = if (response.cacheResponse != null) DataSource.DISK else DataSource.NETWORK
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val (_, body) = awaitGetCall(manga, !options.networkCachePolicy.readEnabled)
|
||||||
|
|
||||||
val tmpFile = File(coverFile.absolutePath + "_tmp")
|
val tmpFile = File(coverFile.absolutePath + "_tmp")
|
||||||
|
|
||||||
val response = call.execute()
|
|
||||||
val body = checkNotNull(response.body) { "Null response source" }
|
|
||||||
|
|
||||||
body.source().use { input ->
|
body.source().use { input ->
|
||||||
tmpFile.sink().buffer().use { output ->
|
tmpFile.sink().buffer().use { output ->
|
||||||
output.writeAll(input)
|
output.writeAll(input)
|
||||||
@ -79,6 +88,42 @@ class MangaFetcher() : Fetcher<Manga> {
|
|||||||
tmpFile.renameTo(coverFile)
|
tmpFile.renameTo(coverFile)
|
||||||
return fileLoader(coverFile)
|
return fileLoader(coverFile)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun awaitGetCall(manga: Manga, onlyCache: Boolean = false): Pair<Response,
|
||||||
|
ResponseBody> {
|
||||||
|
val call = getCall(manga, onlyCache)
|
||||||
|
val response = call.await()
|
||||||
|
return response to checkNotNull(response.body) { "Null response source" }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "text/plain" is often used as a default/fallback MIME type.
|
||||||
|
* Attempt to guess a better MIME type from the file extension.
|
||||||
|
*/
|
||||||
|
private fun getMimeType(data: String, body: ResponseBody): String? {
|
||||||
|
val rawContentType = body.contentType()?.toString()
|
||||||
|
return if (rawContentType == null || rawContentType.startsWith("text/plain")) {
|
||||||
|
MimeTypeMap.getSingleton().getMimeTypeFromUrl(data) ?: rawContentType
|
||||||
|
} else {
|
||||||
|
rawContentType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Modified from [MimeTypeMap.getFileExtensionFromUrl] to be more permissive with special characters. */
|
||||||
|
private fun MimeTypeMap.getMimeTypeFromUrl(url: String?): String? {
|
||||||
|
if (url.isNullOrBlank()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val extension = url
|
||||||
|
.substringBeforeLast('#') // Strip the fragment.
|
||||||
|
.substringBeforeLast('?') // Strip the query.
|
||||||
|
.substringAfterLast('/') // Get the last path segment.
|
||||||
|
.substringAfterLast('.', missingDelimiterValue = "") // Get the file extension.
|
||||||
|
|
||||||
|
return getMimeTypeFromExtension(extension)
|
||||||
|
}
|
||||||
|
|
||||||
private fun fileLoader(manga: Manga): FetchResult {
|
private fun fileLoader(manga: Manga): FetchResult {
|
||||||
return fileLoader(File(manga.thumbnail_url!!.substringAfter("file://")))
|
return fileLoader(File(manga.thumbnail_url!!.substringAfter("file://")))
|
||||||
@ -92,18 +137,19 @@ class MangaFetcher() : Fetcher<Manga> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCall(manga: Manga): Call {
|
private fun getCall(manga: Manga, onlyCache: Boolean): Call {
|
||||||
val source = sourceManager.get(manga.source) as? HttpSource
|
val source = sourceManager.get(manga.source) as? HttpSource
|
||||||
val client = source?.client ?: defaultClient
|
val client = source?.client ?: defaultClient
|
||||||
|
|
||||||
val newClient = client.newBuilder()
|
val newClient = client.newBuilder().build()
|
||||||
.cache(coverCache.cache)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val request = Request.Builder().url(manga.thumbnail_url!!).also {
|
val request = Request.Builder().url(manga.thumbnail_url!!).also {
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
it.headers(source.headers)
|
it.headers(source.headers)
|
||||||
}
|
}
|
||||||
|
if (onlyCache) {
|
||||||
|
it.cacheControl(CacheControl.FORCE_CACHE)
|
||||||
|
}
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
return newClient.newCall(request)
|
return newClient.newCall(request)
|
||||||
|
@ -16,6 +16,7 @@ import androidx.core.app.NotificationManagerCompat
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import coil.Coil
|
import coil.Coil
|
||||||
import coil.request.CachePolicy
|
import coil.request.CachePolicy
|
||||||
|
import coil.request.GetRequest
|
||||||
import coil.request.LoadRequest
|
import coil.request.LoadRequest
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -603,7 +604,7 @@ class LibraryUpdateService(
|
|||||||
*
|
*
|
||||||
* @param updates a list of manga with new updates.
|
* @param updates a list of manga with new updates.
|
||||||
*/
|
*/
|
||||||
private fun showResultNotification(updates: Map<LibraryManga, Array<Chapter>>) {
|
private suspend fun showResultNotification(updates: Map<LibraryManga, Array<Chapter>>) {
|
||||||
val notifications = ArrayList<Pair<Notification, Int>>()
|
val notifications = ArrayList<Pair<Notification, Int>>()
|
||||||
updates.forEach {
|
updates.forEach {
|
||||||
val manga = it.key
|
val manga = it.key
|
||||||
@ -613,11 +614,15 @@ class LibraryUpdateService(
|
|||||||
setSmallIcon(R.drawable.ic_tachi)
|
setSmallIcon(R.drawable.ic_tachi)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
val request = LoadRequest.Builder(this@LibraryUpdateService).data(manga)
|
val request = GetRequest.Builder(this@LibraryUpdateService).data(manga)
|
||||||
|
.networkCachePolicy(CachePolicy.DISABLED)
|
||||||
.transformations(CircleCropTransformation()).size(width = 256, height = 256)
|
.transformations(CircleCropTransformation()).size(width = 256, height = 256)
|
||||||
.target { drawable -> setLargeIcon((drawable as BitmapDrawable).bitmap) }.build()
|
.build()
|
||||||
|
|
||||||
Coil.imageLoader(this@LibraryUpdateService).execute(request)
|
Coil.imageLoader(this@LibraryUpdateService)
|
||||||
|
.execute(request).drawable?.let { drawable ->
|
||||||
|
setLargeIcon((drawable as BitmapDrawable).bitmap)
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
}
|
}
|
||||||
setGroupAlertBehavior(GROUP_ALERT_SUMMARY)
|
setGroupAlertBehavior(GROUP_ALERT_SUMMARY)
|
||||||
|
@ -4,7 +4,6 @@ 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 coil.api.loadAny
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
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
|
||||||
@ -12,9 +11,7 @@ import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
|||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
import eu.kanade.tachiyomi.util.view.visibleIf
|
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||||
import kotlinx.android.synthetic.main.manga_list_item.*
|
import kotlinx.android.synthetic.main.manga_list_item.*
|
||||||
import kotlinx.android.synthetic.main.manga_list_item.title
|
|
||||||
import kotlinx.android.synthetic.main.manga_list_item.view.*
|
import kotlinx.android.synthetic.main.manga_list_item.view.*
|
||||||
import kotlinx.android.synthetic.main.recently_read_item.*
|
|
||||||
import kotlinx.android.synthetic.main.unread_download_badge.*
|
import kotlinx.android.synthetic.main.unread_download_badge.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,9 +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.loadAny(item.manga)
|
||||||
transformations(RoundedCornersTransformation(2f, 2f, 2f, 2f))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,6 @@ import androidx.transition.ChangeImageTransform
|
|||||||
import androidx.transition.TransitionManager
|
import androidx.transition.TransitionManager
|
||||||
import androidx.transition.TransitionSet
|
import androidx.transition.TransitionSet
|
||||||
import coil.Coil
|
import coil.Coil
|
||||||
import coil.api.clear
|
|
||||||
import coil.api.loadAny
|
|
||||||
import coil.request.LoadRequest
|
import coil.request.LoadRequest
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.afollestad.materialdialogs.checkbox.checkBoxPrompt
|
import com.afollestad.materialdialogs.checkbox.checkBoxPrompt
|
||||||
@ -308,7 +306,6 @@ class MangaDetailsController : BaseController,
|
|||||||
/** Get the color of the manga cover*/
|
/** Get the color of the manga cover*/
|
||||||
fun setPaletteColor() {
|
fun setPaletteColor() {
|
||||||
val view = view ?: return
|
val view = view ?: return
|
||||||
coverColor = null
|
|
||||||
|
|
||||||
val request = LoadRequest.Builder(view.context).data(manga).allowHardware(false)
|
val request = LoadRequest.Builder(view.context).data(manga).allowHardware(false)
|
||||||
.target { drawable ->
|
.target { drawable ->
|
||||||
@ -330,16 +327,12 @@ class MangaDetailsController : BaseController,
|
|||||||
activity?.window?.statusBarColor = translucentColor
|
activity?.window?.statusBarColor = translucentColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
manga_cover_full.setImageDrawable(drawable)
|
||||||
|
getHeader()?.updateCover(manga!!)
|
||||||
}.build()
|
}.build()
|
||||||
Coil.imageLoader(view.context).execute(request)
|
Coil.imageLoader(view.context).execute(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetCovers() {
|
|
||||||
manga_cover_full.clear()
|
|
||||||
manga_cover_full.loadAny(manga)
|
|
||||||
getHeader()?.updateCover(manga!!, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set toolbar theme for themes that are inverted (ie. light blue theme) */
|
/** Set toolbar theme for themes that are inverted (ie. light blue theme) */
|
||||||
private fun setActionBar(forThis: Boolean) {
|
private fun setActionBar(forThis: Boolean) {
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
@ -1258,7 +1251,6 @@ class MangaDetailsController : BaseController,
|
|||||||
currentAnimator?.cancel()
|
currentAnimator?.cancel()
|
||||||
|
|
||||||
// Load the high-resolution "zoomed-in" image.
|
// Load the high-resolution "zoomed-in" image.
|
||||||
manga_cover_full?.loadAny(manga)
|
|
||||||
val expandedImageView = manga_cover_full ?: return
|
val expandedImageView = manga_cover_full ?: return
|
||||||
val fullBackdrop = full_backdrop
|
val fullBackdrop = full_backdrop
|
||||||
|
|
||||||
|
@ -748,7 +748,6 @@ class MangaDetailsPresenter(
|
|||||||
fun forceUpdateCovers(deleteCache: Boolean = true) {
|
fun forceUpdateCovers(deleteCache: Boolean = true) {
|
||||||
if (deleteCache) coverCache.deleteFromCache(manga)
|
if (deleteCache) coverCache.deleteFromCache(manga)
|
||||||
controller.setPaletteColor()
|
controller.setPaletteColor()
|
||||||
controller.resetCovers()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun editCoverWithStream(uri: Uri): Boolean {
|
fun editCoverWithStream(uri: Uri): Boolean {
|
||||||
|
@ -9,8 +9,8 @@ import android.view.ViewGroup
|
|||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import coil.api.clear
|
|
||||||
import coil.api.loadAny
|
import coil.api.loadAny
|
||||||
|
import coil.request.CachePolicy
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
@ -308,12 +308,19 @@ class MangaHeaderHolder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateCover(manga: Manga, forceUpdate: Boolean = false) {
|
fun updateCover(manga: Manga) {
|
||||||
if (!isCached(manga) && !forceUpdate) return
|
if (!manga.initialized) return
|
||||||
manga_cover.clear()
|
val drawable = adapter.controller.manga_cover_full?.drawable
|
||||||
backdrop.clear()
|
manga_cover.loadAny(manga, builder = {
|
||||||
manga_cover.loadAny(manga)
|
placeholder(drawable)
|
||||||
backdrop.loadAny(manga)
|
error(drawable)
|
||||||
|
if (manga.favorite) networkCachePolicy(CachePolicy.DISABLED)
|
||||||
|
})
|
||||||
|
backdrop.loadAny(manga, builder = {
|
||||||
|
placeholder(drawable)
|
||||||
|
error(drawable)
|
||||||
|
if (manga.favorite) networkCachePolicy(CachePolicy.DISABLED)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCached(manga: Manga): Boolean {
|
private fun isCached(manga: Manga): Boolean {
|
||||||
|
@ -13,8 +13,6 @@ import eu.kanade.tachiyomi.ui.library.LibraryCategoryAdapter
|
|||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.widget.CoverViewTarget
|
import eu.kanade.tachiyomi.widget.CoverViewTarget
|
||||||
import kotlinx.android.synthetic.main.manga_grid_item.*
|
import kotlinx.android.synthetic.main.manga_grid_item.*
|
||||||
import kotlinx.android.synthetic.main.manga_grid_item.cover_thumbnail
|
|
||||||
import kotlinx.android.synthetic.main.manga_grid_item.title
|
|
||||||
import kotlinx.android.synthetic.main.unread_download_badge.*
|
import kotlinx.android.synthetic.main.unread_download_badge.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +61,8 @@ class BrowseSourceGridHolder(
|
|||||||
cover_thumbnail.clear()
|
cover_thumbnail.clear()
|
||||||
} else {
|
} else {
|
||||||
val id = manga.id ?: return
|
val id = manga.id ?: return
|
||||||
val request = LoadRequest.Builder(view.context).data(manga).target(CoverViewTarget(cover_thumbnail, progress)).build()
|
val request = LoadRequest.Builder(view.context).data(manga)
|
||||||
|
.target(CoverViewTarget(cover_thumbnail, progress)).build()
|
||||||
Coil.imageLoader(view.context).execute(request)
|
Coil.imageLoader(view.context).execute(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import coil.Coil
|
import coil.Coil
|
||||||
import coil.api.clear
|
import coil.api.clear
|
||||||
import coil.request.LoadRequest
|
import coil.request.LoadRequest
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -48,8 +47,8 @@ class BrowseSourceListHolder(private val view: View, adapter: FlexibleAdapter<IF
|
|||||||
cover_thumbnail.clear()
|
cover_thumbnail.clear()
|
||||||
} else {
|
} else {
|
||||||
val id = manga.id ?: return
|
val id = manga.id ?: return
|
||||||
val request = LoadRequest.Builder(view.context).data(manga).target(CoverViewTarget(cover_thumbnail))
|
val request = LoadRequest.Builder(view.context).data(manga)
|
||||||
.transformations(RoundedCornersTransformation(2f, 2f, 2f, 2f)).build()
|
.target(CoverViewTarget(cover_thumbnail)).build()
|
||||||
Coil.imageLoader(view.context).execute(request)
|
Coil.imageLoader(view.context).execute(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,23 +10,31 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
|
|||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
|
|
||||||
class CoverViewTarget(view: ImageView, val progress: View? = null) : ImageViewTarget(view) {
|
class CoverViewTarget(
|
||||||
|
view: ImageView,
|
||||||
|
val progress: View? = null,
|
||||||
|
val scaleType: ImageView.ScaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
) : ImageViewTarget(view) {
|
||||||
|
|
||||||
override fun onError(error: Drawable?) {
|
override fun onError(error: Drawable?) {
|
||||||
progress?.gone()
|
progress?.gone()
|
||||||
view.scaleType = ImageView.ScaleType.CENTER
|
view.scaleType = ImageView.ScaleType.CENTER
|
||||||
val vector = VectorDrawableCompat.create(view.context.resources, R.drawable.ic_broken_image_grey_24dp, null)
|
val vector = VectorDrawableCompat.create(
|
||||||
|
view.context.resources, R.drawable.ic_broken_image_grey_24dp, null
|
||||||
|
)
|
||||||
vector?.setTint(view.context.getResourceColor(android.R.attr.textColorSecondary))
|
vector?.setTint(view.context.getResourceColor(android.R.attr.textColorSecondary))
|
||||||
view.setImageDrawable(vector)
|
view.setImageDrawable(vector)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart(placeholder: Drawable?) {
|
override fun onStart(placeholder: Drawable?) {
|
||||||
progress?.visible()
|
progress?.visible()
|
||||||
|
view.scaleType = scaleType
|
||||||
super.onStart(placeholder)
|
super.onStart(placeholder)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(result: Drawable) {
|
override fun onSuccess(result: Drawable) {
|
||||||
progress?.gone()
|
progress?.gone()
|
||||||
|
view.scaleType = scaleType
|
||||||
super.onSuccess(result)
|
super.onSuccess(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user