Эх сурвалжийг харах

Change cover memory key (#7276)

Use different key for custom cover and add last modified time for updating
cover without clearing the whole memory cache
Ivan Iskandar 2 жил өмнө
parent
commit
59837bbb90

+ 0 - 8
app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.kt

@@ -1,7 +1,6 @@
 package eu.kanade.tachiyomi.data.cache
 
 import android.content.Context
-import coil.imageLoader
 import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.util.storage.DiskUtil
 import java.io.File
@@ -100,13 +99,6 @@ class CoverCache(private val context: Context) {
         }
     }
 
-    /**
-     * Clear coil's memory cache.
-     */
-    fun clearMemoryCache() {
-        context.imageLoader.memoryCache?.clear()
-    }
-
     private fun getCacheDir(dir: String): File {
         return context.getExternalFilesDir(dir)
             ?: File(context.filesDir, dir).also { it.mkdirs() }

+ 31 - 18
app/src/main/java/eu/kanade/tachiyomi/data/coil/MangaCoverFetcher.kt

@@ -42,28 +42,32 @@ import java.net.HttpURLConnection
  * - [USE_CUSTOM_COVER]: Use custom cover if set by user, default is true
  */
 class MangaCoverFetcher(
-    private val manga: Manga,
-    private val sourceLazy: Lazy<HttpSource?>,
+    private val url: String?,
+    private val isLibraryManga: Boolean,
     private val options: Options,
-    private val coverCache: CoverCache,
+    private val coverFileLazy: Lazy<File?>,
+    private val customCoverFileLazy: Lazy<File>,
+    private val diskCacheKeyLazy: Lazy<String>,
+    private val sourceLazy: Lazy<HttpSource?>,
     private val callFactoryLazy: Lazy<Call.Factory>,
     private val diskCacheLazy: Lazy<DiskCache>,
 ) : Fetcher {
 
-    // For non-custom cover
-    private val diskCacheKey: String? by lazy { MangaCoverKeyer().key(manga, options) }
-    private lateinit var url: String
+    private val diskCacheKey: String
+        get() = diskCacheKeyLazy.value
 
     override suspend fun fetch(): FetchResult {
         // Use custom cover if exists
         val useCustomCover = options.parameters.value(USE_CUSTOM_COVER) ?: true
-        val customCoverFile = coverCache.getCustomCoverFile(manga.id)
-        if (useCustomCover && customCoverFile.exists()) {
-            return fileLoader(customCoverFile)
+        if (useCustomCover) {
+            val customCoverFile = customCoverFileLazy.value
+            if (customCoverFile.exists()) {
+                return fileLoader(customCoverFile)
+            }
         }
 
         // diskCacheKey is thumbnail_url
-        url = diskCacheKey ?: error("No cover specified")
+        if (url == null) error("No cover specified")
         return when (getResourceType(url)) {
             Type.URL -> httpLoader()
             Type.File -> fileLoader(File(url.substringAfter("file://")))
@@ -81,8 +85,8 @@ class MangaCoverFetcher(
 
     private suspend fun httpLoader(): FetchResult {
         // Only cache separately if it's a library item
-        val libraryCoverCacheFile = if (manga.favorite) {
-            coverCache.getCoverFile(manga.thumbnail_url) ?: error("No cover specified")
+        val libraryCoverCacheFile = if (isLibraryManga) {
+            coverFileLazy.value ?: error("No cover specified")
         } else {
             null
         }
@@ -156,7 +160,7 @@ class MangaCoverFetcher(
 
     private fun newRequest(): Request {
         val request = Request.Builder()
-            .url(url)
+            .url(url!!)
             .headers(sourceLazy.value?.headers ?: options.headers)
             // Support attaching custom data to the network request.
             .tag(Parameters::class.java, options.parameters)
@@ -188,7 +192,7 @@ class MangaCoverFetcher(
                 fileSystem.source(snapshot.data).use { input ->
                     writeSourceToCoverCache(input, cacheFile)
                 }
-                remove(diskCacheKey!!)
+                remove(diskCacheKey)
             }
             cacheFile.takeIf { it.exists() }
         } catch (e: Exception) {
@@ -224,7 +228,7 @@ class MangaCoverFetcher(
     }
 
     private fun readFromDiskCache(): DiskCache.Snapshot? {
-        return if (options.diskCachePolicy.readEnabled) diskCacheLazy.value[diskCacheKey!!] else null
+        return if (options.diskCachePolicy.readEnabled) diskCacheLazy.value[diskCacheKey] else null
     }
 
     private fun writeToDiskCache(
@@ -238,7 +242,7 @@ class MangaCoverFetcher(
         val editor = if (snapshot != null) {
             snapshot.closeAndEdit()
         } else {
-            diskCacheLazy.value.edit(diskCacheKey!!)
+            diskCacheLazy.value.edit(diskCacheKey)
         } ?: return null
         try {
             diskCacheLazy.value.fileSystem.write(editor.data) {
@@ -280,8 +284,17 @@ class MangaCoverFetcher(
         private val sourceManager: SourceManager by injectLazy()
 
         override fun create(data: Manga, options: Options, imageLoader: ImageLoader): Fetcher {
-            val source = lazy { sourceManager.get(data.source) as? HttpSource }
-            return MangaCoverFetcher(data, source, options, coverCache, callFactoryLazy, diskCacheLazy)
+            return MangaCoverFetcher(
+                url = data.thumbnail_url,
+                isLibraryManga = data.favorite,
+                options = options,
+                coverFileLazy = lazy { coverCache.getCoverFile(data.thumbnail_url) },
+                customCoverFileLazy = lazy { coverCache.getCustomCoverFile(data.id) },
+                diskCacheKeyLazy = lazy { MangaCoverKeyer().key(data, options) },
+                sourceLazy = lazy { sourceManager.get(data.source) as? HttpSource },
+                callFactoryLazy = callFactoryLazy,
+                diskCacheLazy = diskCacheLazy,
+            )
         }
     }
 

+ 7 - 2
app/src/main/java/eu/kanade/tachiyomi/data/coil/MangaCoverKeyer.kt

@@ -3,9 +3,14 @@ package eu.kanade.tachiyomi.data.coil
 import coil.key.Keyer
 import coil.request.Options
 import eu.kanade.tachiyomi.data.database.models.Manga
+import eu.kanade.tachiyomi.util.hasCustomCover
 
 class MangaCoverKeyer : Keyer<Manga> {
-    override fun key(data: Manga, options: Options): String? {
-        return data.thumbnail_url?.takeIf { it.isNotBlank() }
+    override fun key(data: Manga, options: Options): String {
+        return if (data.hasCustomCover()) {
+            "${data.id};${data.cover_last_modified}"
+        } else {
+            "${data.thumbnail_url};${data.cover_last_modified}"
+        }
     }
 }

+ 0 - 1
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt

@@ -473,7 +473,6 @@ class LibraryUpdateService(
                 .awaitAll()
         }
 
-        coverCache.clearMemoryCache()
         notifier.cancelProgressNotification()
     }
 

+ 0 - 1
app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt

@@ -290,7 +290,6 @@ class LocalSource(
                 }
             }
         }
-            .also { coverCache.clearMemoryCache() }
     }
 
     sealed class Format {

+ 1 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt

@@ -316,12 +316,11 @@ class MangaPresenter(
                         LocalSource.updateCover(context, manga, it)
                         manga.updateCoverLastModified(db)
                         db.insertManga(manga).executeAsBlocking()
-                        coverCache.clearMemoryCache()
                     } else if (manga.favorite) {
                         coverCache.setCustomCoverToCache(manga, it)
                         manga.updateCoverLastModified(db)
-                        coverCache.clearMemoryCache()
                     }
+                    true
                 }
             }
             .subscribeOn(Schedulers.io())
@@ -337,7 +336,6 @@ class MangaPresenter(
             .fromCallable {
                 coverCache.deleteCustomCover(manga.id)
                 manga.updateCoverLastModified(db)
-                coverCache.clearMemoryCache()
             }
             .subscribeOn(Schedulers.io())
             .observeOn(AndroidSchedulers.mainThread())

+ 0 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt

@@ -704,13 +704,11 @@ class ReaderPresenter(
                         val context = Injekt.get<Application>()
                         LocalSource.updateCover(context, manga, it)
                         manga.updateCoverLastModified(db)
-                        coverCache.clearMemoryCache()
                         SetAsCoverResult.Success
                     } else {
                         if (manga.favorite) {
                             coverCache.setCustomCoverToCache(manga, it)
                             manga.updateCoverLastModified(db)
-                            coverCache.clearMemoryCache()
                             SetAsCoverResult.Success
                         } else {
                             SetAsCoverResult.AddToLibraryFirst

+ 3 - 1
app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt

@@ -6,6 +6,8 @@ import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.source.LocalSource
 import eu.kanade.tachiyomi.source.model.SManga
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
 import java.util.Date
 
 fun Manga.isLocal() = source == LocalSource.ID
@@ -36,7 +38,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
     }
 }
 
-fun Manga.hasCustomCover(coverCache: CoverCache): Boolean {
+fun Manga.hasCustomCover(coverCache: CoverCache = Injekt.get()): Boolean {
     return coverCache.getCustomCoverFile(id).exists()
 }