mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Fix cover fetching in compose views (#7315)
Make sure it passed thru the custom fetcher
This commit is contained in:
		@@ -2,6 +2,7 @@ package eu.kanade.data.history
 | 
			
		||||
 | 
			
		||||
import eu.kanade.domain.history.model.History
 | 
			
		||||
import eu.kanade.domain.history.model.HistoryWithRelations
 | 
			
		||||
import eu.kanade.domain.manga.model.MangaCover
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
val historyMapper: (Long, Long, Date?, Long) -> History = { id, chapterId, readAt, readDuration ->
 | 
			
		||||
@@ -13,16 +14,22 @@ val historyMapper: (Long, Long, Date?, Long) -> History = { id, chapterId, readA
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
val historyWithRelationsMapper: (Long, Long, Long, String, String?, Float, Date?, Long) -> HistoryWithRelations = {
 | 
			
		||||
        historyId, mangaId, chapterId, title, thumbnailUrl, chapterNumber, readAt, readDuration ->
 | 
			
		||||
val historyWithRelationsMapper: (Long, Long, Long, String, String?, Long, Boolean, Long, Float, Date?, Long) -> HistoryWithRelations = {
 | 
			
		||||
        historyId, mangaId, chapterId, title, thumbnailUrl, sourceId, isFavorite, coverLastModified, chapterNumber, readAt, readDuration ->
 | 
			
		||||
    HistoryWithRelations(
 | 
			
		||||
        id = historyId,
 | 
			
		||||
        chapterId = chapterId,
 | 
			
		||||
        mangaId = mangaId,
 | 
			
		||||
        title = title,
 | 
			
		||||
        thumbnailUrl = thumbnailUrl ?: "",
 | 
			
		||||
        chapterNumber = chapterNumber,
 | 
			
		||||
        readAt = readAt,
 | 
			
		||||
        readDuration = readDuration,
 | 
			
		||||
        coverData = MangaCover(
 | 
			
		||||
            mangaId = mangaId,
 | 
			
		||||
            sourceId = sourceId,
 | 
			
		||||
            isMangaFavorite = isFavorite,
 | 
			
		||||
            url = thumbnailUrl,
 | 
			
		||||
            lastModified = coverLastModified,
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package eu.kanade.domain.history.model
 | 
			
		||||
 | 
			
		||||
import eu.kanade.domain.manga.model.MangaCover
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
data class HistoryWithRelations(
 | 
			
		||||
@@ -7,8 +8,8 @@ data class HistoryWithRelations(
 | 
			
		||||
    val chapterId: Long,
 | 
			
		||||
    val mangaId: Long,
 | 
			
		||||
    val title: String,
 | 
			
		||||
    val thumbnailUrl: String,
 | 
			
		||||
    val chapterNumber: Float,
 | 
			
		||||
    val readAt: Date?,
 | 
			
		||||
    val readDuration: Long,
 | 
			
		||||
    val coverData: MangaCover,
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								app/src/main/java/eu/kanade/domain/manga/model/MangaCover.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/src/main/java/eu/kanade/domain/manga/model/MangaCover.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
package eu.kanade.domain.manga.model
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Contains the required data for MangaCoverFetcher
 | 
			
		||||
 */
 | 
			
		||||
data class MangaCover(
 | 
			
		||||
    val mangaId: Long,
 | 
			
		||||
    val sourceId: Long,
 | 
			
		||||
    val isMangaFavorite: Boolean,
 | 
			
		||||
    val url: String?,
 | 
			
		||||
    val lastModified: Long,
 | 
			
		||||
)
 | 
			
		||||
@@ -21,7 +21,7 @@ enum class MangaCover(private val ratio: Float) {
 | 
			
		||||
    @Composable
 | 
			
		||||
    operator fun invoke(
 | 
			
		||||
        modifier: Modifier = Modifier,
 | 
			
		||||
        data: String?,
 | 
			
		||||
        data: Any?,
 | 
			
		||||
        contentDescription: String? = null,
 | 
			
		||||
        shape: Shape? = null,
 | 
			
		||||
    ) {
 | 
			
		||||
 
 | 
			
		||||
@@ -191,7 +191,7 @@ fun HistoryItem(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .fillMaxHeight()
 | 
			
		||||
                .clickable(onClick = onClickCover),
 | 
			
		||||
            data = history.thumbnailUrl,
 | 
			
		||||
            data = history.coverData,
 | 
			
		||||
        )
 | 
			
		||||
        Column(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ private val defaultCover: @Composable RowScope.(Manga, () -> Unit) -> Unit = { m
 | 
			
		||||
            .padding(vertical = 8.dp)
 | 
			
		||||
            .clickable(onClick = onClick)
 | 
			
		||||
            .fillMaxHeight(),
 | 
			
		||||
        data = manga.thumbnailUrl,
 | 
			
		||||
        data = manga,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,10 @@ import coil.decode.ImageDecoderDecoder
 | 
			
		||||
import coil.disk.DiskCache
 | 
			
		||||
import coil.util.DebugLogger
 | 
			
		||||
import eu.kanade.domain.DomainModule
 | 
			
		||||
import eu.kanade.tachiyomi.data.coil.DomainMangaKeyer
 | 
			
		||||
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
 | 
			
		||||
import eu.kanade.tachiyomi.data.coil.MangaCoverKeyer
 | 
			
		||||
import eu.kanade.tachiyomi.data.coil.MangaKeyer
 | 
			
		||||
import eu.kanade.tachiyomi.data.coil.TachiyomiImageDecoder
 | 
			
		||||
import eu.kanade.tachiyomi.data.notification.Notifications
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
 | 
			
		||||
@@ -139,6 +141,10 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
 | 
			
		||||
                }
 | 
			
		||||
                add(TachiyomiImageDecoder.Factory())
 | 
			
		||||
                add(MangaCoverFetcher.Factory(lazy(callFactoryInit), lazy(diskCacheInit)))
 | 
			
		||||
                add(MangaCoverFetcher.DomainMangaFactory(lazy(callFactoryInit), lazy(diskCacheInit)))
 | 
			
		||||
                add(MangaCoverFetcher.MangaCoverFactory(lazy(callFactoryInit), lazy(diskCacheInit)))
 | 
			
		||||
                add(MangaKeyer())
 | 
			
		||||
                add(DomainMangaKeyer())
 | 
			
		||||
                add(MangaCoverKeyer())
 | 
			
		||||
            }
 | 
			
		||||
            callFactory(callFactoryInit)
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ import coil.fetch.SourceResult
 | 
			
		||||
import coil.network.HttpException
 | 
			
		||||
import coil.request.Options
 | 
			
		||||
import coil.request.Parameters
 | 
			
		||||
import eu.kanade.domain.manga.model.MangaCover
 | 
			
		||||
import eu.kanade.tachiyomi.data.cache.CoverCache
 | 
			
		||||
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher.Companion.USE_CUSTOM_COVER
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
@@ -30,6 +31,7 @@ import okio.sink
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.net.HttpURLConnection
 | 
			
		||||
import eu.kanade.domain.manga.model.Manga as DomainManga
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A [Fetcher] that fetches cover image for [Manga] object.
 | 
			
		||||
@@ -290,7 +292,7 @@ class MangaCoverFetcher(
 | 
			
		||||
                options = options,
 | 
			
		||||
                coverFileLazy = lazy { coverCache.getCoverFile(data.thumbnail_url) },
 | 
			
		||||
                customCoverFileLazy = lazy { coverCache.getCustomCoverFile(data.id) },
 | 
			
		||||
                diskCacheKeyLazy = lazy { MangaCoverKeyer().key(data, options) },
 | 
			
		||||
                diskCacheKeyLazy = lazy { MangaKeyer().key(data, options) },
 | 
			
		||||
                sourceLazy = lazy { sourceManager.get(data.source) as? HttpSource },
 | 
			
		||||
                callFactoryLazy = callFactoryLazy,
 | 
			
		||||
                diskCacheLazy = diskCacheLazy,
 | 
			
		||||
@@ -298,6 +300,52 @@ class MangaCoverFetcher(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class DomainMangaFactory(
 | 
			
		||||
        private val callFactoryLazy: Lazy<Call.Factory>,
 | 
			
		||||
        private val diskCacheLazy: Lazy<DiskCache>,
 | 
			
		||||
    ) : Fetcher.Factory<DomainManga> {
 | 
			
		||||
 | 
			
		||||
        private val coverCache: CoverCache by injectLazy()
 | 
			
		||||
        private val sourceManager: SourceManager by injectLazy()
 | 
			
		||||
 | 
			
		||||
        override fun create(data: DomainManga, options: Options, imageLoader: ImageLoader): Fetcher {
 | 
			
		||||
            return MangaCoverFetcher(
 | 
			
		||||
                url = data.thumbnailUrl,
 | 
			
		||||
                isLibraryManga = data.favorite,
 | 
			
		||||
                options = options,
 | 
			
		||||
                coverFileLazy = lazy { coverCache.getCoverFile(data.thumbnailUrl) },
 | 
			
		||||
                customCoverFileLazy = lazy { coverCache.getCustomCoverFile(data.id) },
 | 
			
		||||
                diskCacheKeyLazy = lazy { DomainMangaKeyer().key(data, options) },
 | 
			
		||||
                sourceLazy = lazy { sourceManager.get(data.source) as? HttpSource },
 | 
			
		||||
                callFactoryLazy = callFactoryLazy,
 | 
			
		||||
                diskCacheLazy = diskCacheLazy,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class MangaCoverFactory(
 | 
			
		||||
        private val callFactoryLazy: Lazy<Call.Factory>,
 | 
			
		||||
        private val diskCacheLazy: Lazy<DiskCache>,
 | 
			
		||||
    ) : Fetcher.Factory<MangaCover> {
 | 
			
		||||
 | 
			
		||||
        private val coverCache: CoverCache by injectLazy()
 | 
			
		||||
        private val sourceManager: SourceManager by injectLazy()
 | 
			
		||||
 | 
			
		||||
        override fun create(data: MangaCover, options: Options, imageLoader: ImageLoader): Fetcher {
 | 
			
		||||
            return MangaCoverFetcher(
 | 
			
		||||
                url = data.url,
 | 
			
		||||
                isLibraryManga = data.isMangaFavorite,
 | 
			
		||||
                options = options,
 | 
			
		||||
                coverFileLazy = lazy { coverCache.getCoverFile(data.url) },
 | 
			
		||||
                customCoverFileLazy = lazy { coverCache.getCustomCoverFile(data.mangaId) },
 | 
			
		||||
                diskCacheKeyLazy = lazy { MangaCoverKeyer().key(data, options) },
 | 
			
		||||
                sourceLazy = lazy { sourceManager.get(data.sourceId) as? HttpSource },
 | 
			
		||||
                callFactoryLazy = callFactoryLazy,
 | 
			
		||||
                diskCacheLazy = diskCacheLazy,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val USE_CUSTOM_COVER = "use_custom_cover"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,16 @@ package eu.kanade.tachiyomi.data.coil
 | 
			
		||||
 | 
			
		||||
import coil.key.Keyer
 | 
			
		||||
import coil.request.Options
 | 
			
		||||
import eu.kanade.domain.manga.model.MangaCover
 | 
			
		||||
import eu.kanade.domain.manga.model.hasCustomCover
 | 
			
		||||
import eu.kanade.tachiyomi.data.cache.CoverCache
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.util.hasCustomCover
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import eu.kanade.domain.manga.model.Manga as DomainManga
 | 
			
		||||
 | 
			
		||||
class MangaCoverKeyer : Keyer<Manga> {
 | 
			
		||||
class MangaKeyer : Keyer<Manga> {
 | 
			
		||||
    override fun key(data: Manga, options: Options): String {
 | 
			
		||||
        return if (data.hasCustomCover()) {
 | 
			
		||||
            "${data.id};${data.cover_last_modified}"
 | 
			
		||||
@@ -14,3 +20,23 @@ class MangaCoverKeyer : Keyer<Manga> {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class DomainMangaKeyer : Keyer<DomainManga> {
 | 
			
		||||
    override fun key(data: DomainManga, options: Options): String {
 | 
			
		||||
        return if (data.hasCustomCover()) {
 | 
			
		||||
            "${data.id};${data.coverLastModified}"
 | 
			
		||||
        } else {
 | 
			
		||||
            "${data.thumbnailUrl};${data.coverLastModified}"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class MangaCoverKeyer : Keyer<MangaCover> {
 | 
			
		||||
    override fun key(data: MangaCover, options: Options): String {
 | 
			
		||||
        return if (Injekt.get<CoverCache>().getCustomCoverFile(data.mangaId).exists()) {
 | 
			
		||||
            "${data.mangaId};${data.lastModified}"
 | 
			
		||||
        } else {
 | 
			
		||||
            "${data.url};${data.lastModified}"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user