mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Migrate to kotlinx.serialization for download store and deleter
This commit is contained in:
parent
152fa0cb9c
commit
f81a6dd8d1
2 changed files with 46 additions and 53 deletions
|
@ -1,10 +1,13 @@
|
||||||
package eu.kanade.tachiyomi.data.download
|
package eu.kanade.tachiyomi.data.download
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
import androidx.core.content.edit
|
||||||
import com.google.gson.Gson
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
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
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,15 +17,12 @@ import uy.kohesive.injekt.injectLazy
|
||||||
*/
|
*/
|
||||||
class DownloadPendingDeleter(context: Context) {
|
class DownloadPendingDeleter(context: Context) {
|
||||||
|
|
||||||
/**
|
private val json: Json by injectLazy()
|
||||||
* Gson instance to encode and decode chapters.
|
|
||||||
*/
|
|
||||||
private val gson by injectLazy<Gson>()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preferences used to store the list of chapters to delete.
|
* 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.
|
* 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
|
// Last entry matches the manga, reuse it to avoid decoding json from preferences
|
||||||
lastEntry.copy(chapters = newChapters)
|
lastEntry.copy(chapters = newChapters)
|
||||||
} else {
|
} else {
|
||||||
val existingEntry = prefs.getString(manga.id!!.toString(), null)
|
val existingEntry = preferences.getString(manga.id!!.toString(), null)
|
||||||
if (existingEntry != null) {
|
if (existingEntry != null) {
|
||||||
// Existing entry found on preferences, decode json and add the new chapter
|
// Existing entry found on preferences, decode json and add the new chapter
|
||||||
val savedEntry = gson.fromJson<Entry>(existingEntry)
|
val savedEntry = json.decodeFromString<Entry>(existingEntry)
|
||||||
|
|
||||||
// Append new chapters
|
// Append new chapters
|
||||||
val newChapters = savedEntry.chapters.addUniqueById(chapters)
|
val newChapters = savedEntry.chapters.addUniqueById(chapters)
|
||||||
|
@ -68,8 +68,10 @@ class DownloadPendingDeleter(context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save current state
|
// Save current state
|
||||||
val json = gson.toJson(newEntry)
|
val json = json.encodeToString(newEntry)
|
||||||
prefs.edit().putString(newEntry.manga.id.toString(), json).apply()
|
preferences.edit {
|
||||||
|
putString(newEntry.manga.id.toString(), json)
|
||||||
|
}
|
||||||
lastAddedEntry = newEntry
|
lastAddedEntry = newEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,37 +84,23 @@ class DownloadPendingDeleter(context: Context) {
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun getPendingChapters(): Map<Manga, List<Chapter>> {
|
fun getPendingChapters(): Map<Manga, List<Chapter>> {
|
||||||
val entries = decodeAll()
|
val entries = decodeAll()
|
||||||
prefs.edit().clear().apply()
|
preferences.edit {
|
||||||
lastAddedEntry = null
|
clear()
|
||||||
|
|
||||||
return entries.associate { entry ->
|
|
||||||
entry.manga.toModel() to entry.chapters.map { it.toModel() }
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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<Chapter>? {
|
|
||||||
val entries = decodeAll()
|
|
||||||
prefs.edit().clear().apply()
|
|
||||||
lastAddedEntry = null
|
lastAddedEntry = null
|
||||||
|
|
||||||
val entry = entries.find { it.manga.id == manga.id }
|
return entries.associate { (chapters, manga) ->
|
||||||
return entry?.chapters?.map { it.toModel() }
|
manga.toModel() to chapters.map { it.toModel() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes all the chapters from preferences.
|
* Decodes all the chapters from preferences.
|
||||||
*/
|
*/
|
||||||
private fun decodeAll(): List<Entry> {
|
private fun decodeAll(): List<Entry> {
|
||||||
return prefs.all.values.mapNotNull { rawEntry ->
|
return preferences.all.values.mapNotNull { rawEntry ->
|
||||||
try {
|
try {
|
||||||
(rawEntry as? String)?.let { gson.fromJson<Entry>(it) }
|
(rawEntry as? String)?.let { json.decodeFromString<Entry>(it) }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -135,29 +123,32 @@ class DownloadPendingDeleter(context: Context) {
|
||||||
/**
|
/**
|
||||||
* Class used to save an entry of chapters with their manga into preferences.
|
* Class used to save an entry of chapters with their manga into preferences.
|
||||||
*/
|
*/
|
||||||
|
@Serializable
|
||||||
private data class Entry(
|
private data class Entry(
|
||||||
val chapters: List<ChapterEntry>,
|
val chapters: List<ChapterEntry>,
|
||||||
val manga: MangaEntry
|
val manga: MangaEntry,
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to save an entry for a chapter into preferences.
|
* Class used to save an entry for a chapter into preferences.
|
||||||
*/
|
*/
|
||||||
|
@Serializable
|
||||||
private data class ChapterEntry(
|
private data class ChapterEntry(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val url: String,
|
val url: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val scanlator: String?
|
val scanlator: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to save an entry for a manga into preferences.
|
* Class used to save an entry for a manga into preferences.
|
||||||
*/
|
*/
|
||||||
|
@Serializable
|
||||||
private data class MangaEntry(
|
private data class MangaEntry(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val url: String,
|
val url: String,
|
||||||
val title: String,
|
val title: String,
|
||||||
val source: Long
|
val source: Long,
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,9 +180,9 @@ class DownloadPendingDeleter(context: Context) {
|
||||||
private fun ChapterEntry.toModel(): Chapter {
|
private fun ChapterEntry.toModel(): Chapter {
|
||||||
return Chapter.create().also {
|
return Chapter.create().also {
|
||||||
it.id = id
|
it.id = id
|
||||||
it.scanlator = scanlator
|
|
||||||
it.url = url
|
it.url = url
|
||||||
it.name = name
|
it.name = name
|
||||||
|
it.scanlator = scanlator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
package eu.kanade.tachiyomi.data.download
|
package eu.kanade.tachiyomi.data.download
|
||||||
|
|
||||||
import android.content.Context
|
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.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
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 kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +20,7 @@ import uy.kohesive.injekt.injectLazy
|
||||||
*/
|
*/
|
||||||
class DownloadStore(
|
class DownloadStore(
|
||||||
context: Context,
|
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)
|
private val preferences = context.getSharedPreferences("active_downloads", Context.MODE_PRIVATE)
|
||||||
|
|
||||||
/**
|
private val json: Json by injectLazy()
|
||||||
* Gson instance to serialize/deserialize downloads.
|
|
||||||
*/
|
|
||||||
private val gson: Gson by injectLazy()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Database helper.
|
|
||||||
*/
|
|
||||||
private val db: DatabaseHelper by injectLazy()
|
private val db: DatabaseHelper by injectLazy()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,9 +42,9 @@ class DownloadStore(
|
||||||
* @param downloads the list of downloads to add.
|
* @param downloads the list of downloads to add.
|
||||||
*/
|
*/
|
||||||
fun addAll(downloads: List<Download>) {
|
fun addAll(downloads: List<Download>) {
|
||||||
val editor = preferences.edit()
|
preferences.edit {
|
||||||
downloads.forEach { editor.putString(getKey(it), serialize(it)) }
|
downloads.forEach { putString(getKey(it), serialize(it)) }
|
||||||
editor.apply()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,14 +53,18 @@ class DownloadStore(
|
||||||
* @param download the download to remove.
|
* @param download the download to remove.
|
||||||
*/
|
*/
|
||||||
fun remove(download: Download) {
|
fun remove(download: Download) {
|
||||||
preferences.edit().remove(getKey(download)).apply()
|
preferences.edit {
|
||||||
|
remove(getKey(download))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all the downloads from the store.
|
* Removes all the downloads from the store.
|
||||||
*/
|
*/
|
||||||
fun clear() {
|
fun clear() {
|
||||||
preferences.edit().clear().apply()
|
preferences.edit {
|
||||||
|
clear()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,7 +110,7 @@ class DownloadStore(
|
||||||
*/
|
*/
|
||||||
private fun serialize(download: Download): String {
|
private fun serialize(download: Download): String {
|
||||||
val obj = DownloadObject(download.manga.id!!, download.chapter.id!!, counter++)
|
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? {
|
private fun deserialize(string: String): DownloadObject? {
|
||||||
return try {
|
return try {
|
||||||
gson.fromJson(string, DownloadObject::class.java)
|
json.decodeFromString<DownloadObject>(string)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -132,5 +133,6 @@ class DownloadStore(
|
||||||
* @param chapterId the id of the chapter.
|
* @param chapterId the id of the chapter.
|
||||||
* @param order the order of the download in the queue.
|
* @param order the order of the download in the queue.
|
||||||
*/
|
*/
|
||||||
|
@Serializable
|
||||||
data class DownloadObject(val mangaId: Long, val chapterId: Long, val order: Int)
|
data class DownloadObject(val mangaId: Long, val chapterId: Long, val order: Int)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue