diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt index d81ae629a1..57c78e5f17 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt @@ -1,10 +1,13 @@ package eu.kanade.tachiyomi.data.download import android.content.Context -import com.github.salomonbrys.kotson.fromJson -import com.google.gson.Gson +import androidx.core.content.edit import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import uy.kohesive.injekt.injectLazy /** @@ -14,15 +17,12 @@ import uy.kohesive.injekt.injectLazy */ class DownloadPendingDeleter(context: Context) { - /** - * Gson instance to encode and decode chapters. - */ - private val gson by injectLazy() + private val json: Json by injectLazy() /** * Preferences used to store the list of chapters to delete. */ - private val prefs = context.getSharedPreferences("chapters_to_delete", Context.MODE_PRIVATE) + private val preferences = context.getSharedPreferences("chapters_to_delete", Context.MODE_PRIVATE) /** * Last added chapter, used to avoid decoding from the preference too often. @@ -49,10 +49,10 @@ class DownloadPendingDeleter(context: Context) { // Last entry matches the manga, reuse it to avoid decoding json from preferences lastEntry.copy(chapters = newChapters) } else { - val existingEntry = prefs.getString(manga.id!!.toString(), null) + val existingEntry = preferences.getString(manga.id!!.toString(), null) if (existingEntry != null) { // Existing entry found on preferences, decode json and add the new chapter - val savedEntry = gson.fromJson(existingEntry) + val savedEntry = json.decodeFromString(existingEntry) // Append new chapters val newChapters = savedEntry.chapters.addUniqueById(chapters) @@ -68,8 +68,10 @@ class DownloadPendingDeleter(context: Context) { } // Save current state - val json = gson.toJson(newEntry) - prefs.edit().putString(newEntry.manga.id.toString(), json).apply() + val json = json.encodeToString(newEntry) + preferences.edit { + putString(newEntry.manga.id.toString(), json) + } lastAddedEntry = newEntry } @@ -82,37 +84,23 @@ class DownloadPendingDeleter(context: Context) { @Synchronized fun getPendingChapters(): Map> { val entries = decodeAll() - prefs.edit().clear().apply() - lastAddedEntry = null - - return entries.associate { entry -> - entry.manga.toModel() to entry.chapters.map { it.toModel() } + preferences.edit { + clear() } - } - - /** - * Returns the list of chapters to be deleted grouped by its manga. - * - * Note: the returned list of manga and chapters only contain basic information needed by the - * downloader, so don't use them for anything else. - */ - @Synchronized - fun getPendingChapters(manga: Manga): List? { - val entries = decodeAll() - prefs.edit().clear().apply() lastAddedEntry = null - val entry = entries.find { it.manga.id == manga.id } - return entry?.chapters?.map { it.toModel() } + return entries.associate { (chapters, manga) -> + manga.toModel() to chapters.map { it.toModel() } + } } /** * Decodes all the chapters from preferences. */ private fun decodeAll(): List { - return prefs.all.values.mapNotNull { rawEntry -> + return preferences.all.values.mapNotNull { rawEntry -> try { - (rawEntry as? String)?.let { gson.fromJson(it) } + (rawEntry as? String)?.let { json.decodeFromString(it) } } catch (e: Exception) { null } @@ -135,29 +123,32 @@ class DownloadPendingDeleter(context: Context) { /** * Class used to save an entry of chapters with their manga into preferences. */ + @Serializable private data class Entry( val chapters: List, - val manga: MangaEntry + val manga: MangaEntry, ) /** * Class used to save an entry for a chapter into preferences. */ + @Serializable private data class ChapterEntry( val id: Long, val url: String, val name: String, - val scanlator: String? + val scanlator: String? = null, ) /** * Class used to save an entry for a manga into preferences. */ + @Serializable private data class MangaEntry( val id: Long, val url: String, val title: String, - val source: Long + val source: Long, ) /** @@ -189,9 +180,9 @@ class DownloadPendingDeleter(context: Context) { private fun ChapterEntry.toModel(): Chapter { return Chapter.create().also { it.id = id - it.scanlator = scanlator it.url = url it.name = name + it.scanlator = scanlator } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadStore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadStore.kt index 9ae4229c42..0f4624d3ab 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadStore.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadStore.kt @@ -1,12 +1,16 @@ package eu.kanade.tachiyomi.data.download import android.content.Context -import com.google.gson.Gson +import androidx.core.content.edit import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.online.HttpSource +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import uy.kohesive.injekt.injectLazy /** @@ -16,7 +20,7 @@ import uy.kohesive.injekt.injectLazy */ class DownloadStore( context: Context, - private val sourceManager: SourceManager + private val sourceManager: SourceManager, ) { /** @@ -24,14 +28,7 @@ class DownloadStore( */ private val preferences = context.getSharedPreferences("active_downloads", Context.MODE_PRIVATE) - /** - * Gson instance to serialize/deserialize downloads. - */ - private val gson: Gson by injectLazy() - - /** - * Database helper. - */ + private val json: Json by injectLazy() private val db: DatabaseHelper by injectLazy() /** @@ -45,9 +42,9 @@ class DownloadStore( * @param downloads the list of downloads to add. */ fun addAll(downloads: List) { - val editor = preferences.edit() - downloads.forEach { editor.putString(getKey(it), serialize(it)) } - editor.apply() + preferences.edit { + downloads.forEach { putString(getKey(it), serialize(it)) } + } } /** @@ -56,14 +53,18 @@ class DownloadStore( * @param download the download to remove. */ fun remove(download: Download) { - preferences.edit().remove(getKey(download)).apply() + preferences.edit { + remove(getKey(download)) + } } /** * Removes all the downloads from the store. */ fun clear() { - preferences.edit().clear().apply() + preferences.edit { + clear() + } } /** @@ -109,7 +110,7 @@ class DownloadStore( */ private fun serialize(download: Download): String { val obj = DownloadObject(download.manga.id!!, download.chapter.id!!, counter++) - return gson.toJson(obj) + return json.encodeToString(obj) } /** @@ -119,7 +120,7 @@ class DownloadStore( */ private fun deserialize(string: String): DownloadObject? { return try { - gson.fromJson(string, DownloadObject::class.java) + json.decodeFromString(string) } catch (e: Exception) { null } @@ -132,5 +133,6 @@ class DownloadStore( * @param chapterId the id of the chapter. * @param order the order of the download in the queue. */ + @Serializable data class DownloadObject(val mangaId: Long, val chapterId: Long, val order: Int) }