Use TachiWeb filter serializer for saving filters

This commit is contained in:
NerdNumber9
2019-04-06 09:45:28 -04:00
parent 4e2c9dc083
commit 57d83e3d1b
8 changed files with 336 additions and 48 deletions

View File

@@ -143,7 +143,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END)
// EXH -->
navView.setSavedSearches(presenter.loadSearches().map { it.second })
navView.setSavedSearches(presenter.source.id, presenter.loadSearches())
navView.onSaveClicked = {
MaterialDialog.Builder(navView.context)
.title("Save current search query?")
@@ -151,13 +151,13 @@ open class BrowseCatalogueController(bundle: Bundle) :
val oldSavedSearches = presenter.loadSearches()
if(searchName.isNotBlank()
&& oldSavedSearches.size < CatalogueNavigationView.MAX_SAVED_SEARCHES) {
val newSearches = oldSavedSearches + (presenter.source.id to EXHSavedSearch(
val newSearches = oldSavedSearches + EXHSavedSearch(
searchName.toString().trim(),
presenter.query,
presenter.sourceFilters.toList()
))
presenter.sourceFilters
)
presenter.saveSearches(newSearches)
navView.setSavedSearches(newSearches.map { it.second })
navView.setSavedSearches(presenter.source.id, newSearches)
}
}
.positiveText("Save")
@@ -182,23 +182,23 @@ open class BrowseCatalogueController(bundle: Bundle) :
return@cb
}
presenter.sourceFilters = FilterList(search.second.filterList)
presenter.sourceFilters = FilterList(search.filterList)
navView.setFilters(presenter.filterItems)
val allDefault = presenter.sourceFilters == presenter.source.getFilterList()
showProgressBar()
adapter?.clear()
drawer.closeDrawer(Gravity.END)
presenter.restartPager(search.second.query, if (allDefault) FilterList() else presenter.sourceFilters)
presenter.restartPager(search.query, if (allDefault) FilterList() else presenter.sourceFilters)
activity?.invalidateOptionsMenu()
}
navView.onSavedSearchDeleteClicked = cb@{ indexToDelete ->
navView.onSavedSearchDeleteClicked = cb@{ indexToDelete, name ->
val savedSearches = presenter.loadSearches()
val search = savedSearches.getOrNull(indexToDelete)
if(search == null) {
if(search == null || search.name != name) {
MaterialDialog.Builder(navView.context)
.title("Failed to delete saved search!")
.content("An error occurred while deleting the search.")
@@ -210,7 +210,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
MaterialDialog.Builder(navView.context)
.title("Delete saved search query?")
.content("Are you sure you wish to delete your saved search query: '${search.second.name}'?")
.content("Are you sure you wish to delete your saved search query: '${search.name}'?")
.positiveText("Cancel")
.negativeText("Confirm")
.onNegative { _, _ ->
@@ -218,7 +218,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
index != indexToDelete
}
presenter.saveSearches(newSearches)
navView.setSavedSearches(newSearches.map { it.second })
navView.setSavedSearches(presenter.source.id, newSearches)
}
.cancelable(true)
.canceledOnTouchOutside(true)

View File

@@ -1,14 +1,9 @@
package eu.kanade.tachiyomi.ui.catalogue.browse
import android.os.Bundle
import com.fasterxml.jackson.annotation.JsonAutoDetect
import com.fasterxml.jackson.annotation.PropertyAccessor
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.type.TypeFactory
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.github.salomonbrys.kotson.*
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.flexibleadapter.items.ISectionable
import eu.kanade.tachiyomi.data.cache.CoverCache
@@ -35,6 +30,8 @@ import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import xyz.nulldev.ts.api.http.serializer.FilterSerializer
import java.lang.RuntimeException
/**
* Presenter of [BrowseCatalogueController].
@@ -386,31 +383,35 @@ open class BrowseCataloguePresenter(
}
// EXH -->
private val sourceManager: SourceManager by injectLazy()
private fun mapper() = jacksonObjectMapper().enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
fun saveSearches(searches: List<Pair<Long, EXHSavedSearch>>) {
val m = mapper()
val serialized = searches.map {
"${it.first}:" + m.writeValueAsString(it.second)
}.toSet()
prefs.eh_savedSearches().set(serialized)
private val jsonParser = JsonParser()
private val filterSerializer = FilterSerializer()
fun saveSearches(searches: List<EXHSavedSearch>) {
val otherSerialized = prefs.eh_savedSearches().getOrDefault().filter {
!it.startsWith("${source.id}:")
}
val newSerialized = searches.map {
"${source.id}:" + jsonObject(
"name" to it.name,
"query" to it.query,
"filters" to filterSerializer.serialize(it.filterList)
).toString()
}
prefs.eh_savedSearches().set((otherSerialized + newSerialized).toSet())
}
fun loadSearches(): List<Pair<Long, EXHSavedSearch>> {
fun loadSearches(): List<EXHSavedSearch> {
val loaded = prefs.eh_savedSearches().getOrDefault()
return loaded.map {
try {
val id = it.substringBefore(':').toLong()
val content = it.substringAfter(':')
val newMapper = mapper()
.setTypeFactory(TypeFactory.defaultInstance()
.withClassLoader(sourceManager.getOrStub(id).javaClass.classLoader))
id to newMapper.readValue<EXHSavedSearch>(content)
} catch(t: JsonProcessingException) {
if(id != source.id) return@map null
val content = jsonParser.parse(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(content["name"].string,
content["query"].string,
originalFilters)
} catch(t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
t.printStackTrace()

View File

@@ -38,7 +38,7 @@ class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs:
// EXH <--
// EXH -->
var onSavedSearchDeleteClicked: (Int) -> Unit = {}
var onSavedSearchDeleteClicked: (Int, String) -> Unit = { index, name -> }
// EXH <--
init {
@@ -58,7 +58,7 @@ class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs:
}
// EXH -->
fun setSavedSearches(searches: List<EXHSavedSearch>) {
fun setSavedSearches(id: Long, searches: List<EXHSavedSearch>) {
saved_searches.removeAllViews()
val outValue = TypedValue()
@@ -76,7 +76,7 @@ class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs:
restoreBtn.setBackgroundResource(outValue.resourceId)
restoreBtn.setPadding(8.dpToPx, 8.dpToPx, 8.dpToPx, 8.dpToPx)
restoreBtn.setOnClickListener { onSavedSearchClicked(index) }
restoreBtn.setOnLongClickListener { onSavedSearchDeleteClicked(index); true }
restoreBtn.setOnLongClickListener { onSavedSearchDeleteClicked(index, search.name); true }
saved_searches.addView(restoreBtn)
}
}