diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt index 750812a24..7f4918e66 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt @@ -2,8 +2,6 @@ package eu.kanade.tachiyomi.data.cache import android.content.Context import android.text.format.Formatter -import com.github.salomonbrys.kotson.fromJson -import com.google.gson.Gson import com.jakewharton.disklrucache.DiskLruCache import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.preference.PreferencesHelper @@ -15,10 +13,12 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import okhttp3.Response import okio.buffer import okio.sink -import rx.Observable import uy.kohesive.injekt.injectLazy import java.io.File import java.io.IOException @@ -48,14 +48,12 @@ class ChapterCache(private val context: Context) { private val scope = CoroutineScope(Job() + Dispatchers.Main) /** Google Json class used for parsing JSON files. */ - private val gson: Gson by injectLazy() + private val json: Json by injectLazy() // --> EH private val prefs: PreferencesHelper by injectLazy() - // <-- EH /** Cache class used for cache management. */ - // --> EH private var diskCache = setupDiskCache(prefs.cacheSize().get().toLong()) init { @@ -73,7 +71,7 @@ class ChapterCache(private val context: Context) { /** * Returns directory of cache. */ - val cacheDir: File + private val cacheDir: File get() = diskCache.directory /** @@ -100,43 +98,19 @@ class ChapterCache(private val context: Context) { } // <-- EH - /** - * Remove file from cache. - * - * @param file name of file "md5.0". - * @return status of deletion for the file. - */ - fun removeFileFromCache(file: String): Boolean { - // Make sure we don't delete the journal file (keeps track of cache). - if (file == "journal" || file.startsWith("journal.")) { - return false - } - - return try { - // Remove the extension from the file to get the key of the cache - val key = file.substringBeforeLast(".") - // Remove file from cache. - diskCache.remove(key) - } catch (e: Exception) { - false - } - } - /** * Get page list from cache. * * @param chapter the chapter. - * @return an observable of the list of pages. + * @return the list of pages. */ - fun getPageListFromCache(chapter: Chapter): Observable> { - return Observable.fromCallable { - // Get the key for the chapter. - val key = DiskUtil.hashKeyForDisk(getKey(chapter)) + fun getPageListFromCache(chapter: Chapter): List { + // Get the key for the chapter. + val key = DiskUtil.hashKeyForDisk(getKey(chapter)) - // Convert JSON string to list of objects. Throws an exception if snapshot is null - diskCache.get(key).use { - gson.fromJson>(it.getString(0)) - } + // Convert JSON string to list of objects. Throws an exception if snapshot is null + return diskCache.get(key).use { + json.decodeFromString(it.getString(0)) } } @@ -148,7 +122,7 @@ class ChapterCache(private val context: Context) { */ fun putPageListToCache(chapter: Chapter, pages: List) { // Convert list of pages to json string. - val cachedValue = gson.toJson(pages) + val cachedValue = json.encodeToString(pages) // Initialize the editor (edits the values for an entry). var editor: DiskLruCache.Editor? = null @@ -228,6 +202,38 @@ class ChapterCache(private val context: Context) { } } + fun clear(): Int { + var deletedFiles = 0 + cacheDir.listFiles()?.forEach { + if (removeFileFromCache(it.name)) { + deletedFiles++ + } + } + return deletedFiles + } + + /** + * Remove file from cache. + * + * @param file name of file "md5.0". + * @return status of deletion for the file. + */ + private fun removeFileFromCache(file: String): Boolean { + // Make sure we don't delete the journal file (keeps track of cache). + if (file == "journal" || file.startsWith("journal.")) { + return false + } + + return try { + // Remove the extension from the file to get the key of the cache + val key = file.substringBeforeLast(".") + // Remove file from cache. + diskCache.remove(key) + } catch (e: Exception) { + false + } + } + private fun getKey(chapter: Chapter): String { return "${chapter.manga_id}${chapter.url}" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index 587bd9a65..736771374 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -99,8 +99,7 @@ class HttpPageLoader( * the local cache, otherwise fallbacks to network. */ override fun getPages(): Observable> { - return chapterCache - .getPageListFromCache(chapter.chapter) + return Observable.fromCallable { chapterCache.getPageListFromCache(chapter.chapter) } .onErrorResumeNext { source.fetchPageList(chapter.chapter) } .map { pages -> // SY --> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt index 6d9ed0fb6..66489cb01 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt @@ -29,7 +29,8 @@ import eu.kanade.tachiyomi.source.SourceManager.Companion.DELEGATED_SOURCES import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.util.CrashLogUtil -import eu.kanade.tachiyomi.util.lang.launchUI +import eu.kanade.tachiyomi.util.lang.launchIO +import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.preference.defaultValue import eu.kanade.tachiyomi.util.preference.editTextPreference import eu.kanade.tachiyomi.util.preference.intListPreference @@ -53,9 +54,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch -import rx.Observable -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy @@ -372,8 +370,8 @@ class SettingsAdvancedController : SettingsController() { foldersCleared += downloadManager.cleanupChapters(chapterList, manga, source, removeRead, removeNonFavorite) } } - launchUI { - val activity = activity ?: return@launchUI + withUIContext { + val activity = activity ?: return@withUIContext val cleanupString = if (foldersCleared == 0) activity.getString(R.string.no_folders_to_cleanup) else resources!!.getQuantityString( @@ -389,27 +387,18 @@ class SettingsAdvancedController : SettingsController() { private fun clearChapterCache() { if (activity == null) return - val files = chapterCache.cacheDir.listFiles() ?: return - - var deletedFiles = 0 - - Observable.defer { Observable.from(files) } - .doOnNext { file -> - if (chapterCache.removeFileFromCache(file.name)) { - deletedFiles++ + launchIO { + try { + val deletedFiles = chapterCache.clear() + withUIContext { + activity?.toast(resources?.getString(R.string.cache_deleted, deletedFiles)) + findPreference(CLEAR_CACHE_KEY)?.summary = + resources?.getString(R.string.used_cache, chapterCache.readableSize) } + } catch (e: Throwable) { + withUIContext { activity?.toast(R.string.cache_delete_error) } } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .doOnError { - activity?.toast(R.string.cache_delete_error) - } - .doOnCompleted { - activity?.toast(resources?.getString(R.string.cache_deleted, deletedFiles)) - findPreference(CLEAR_CACHE_KEY)?.summary = - resources?.getString(R.string.used_cache, chapterCache.readableSize) - } - .subscribe() + } } class ClearDatabaseDialogController : DialogController() {