Kavita: Filter and search update (#13526)
* Refactored code and removed hack to make search work - Added queryfield to MetadataDto.kt - Changed how we encode volumes in chapter_number in chapterFromVolume (tracking) * Implemented query in filter Removed PDFs, Epubs from format filter Added Year Release filter Added time to read Sort Refactored some variables Bumped version * Changelog and bump version
This commit is contained in:
parent
3c64171991
commit
a7c19b4959
@ -1,3 +1,14 @@
|
|||||||
|
## 1.3.7
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* New Sort filter: Time to read
|
||||||
|
* New Filter: Year release filter
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
* Filters can now be used together with search
|
||||||
|
* Epub and pdfs no longer show in format filter (currently not supported)
|
||||||
|
|
||||||
## 1.3.6
|
## 1.3.6
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
@ -6,7 +6,7 @@ ext {
|
|||||||
extName = 'Kavita'
|
extName = 'Kavita'
|
||||||
pkgNameSuffix = 'all.kavita'
|
pkgNameSuffix = 'all.kavita'
|
||||||
extClass = '.KavitaFactory'
|
extClass = '.KavitaFactory'
|
||||||
extVersionCode = 6
|
extVersionCode = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -21,10 +21,8 @@ import eu.kanade.tachiyomi.extension.all.kavita.dto.MetadataPeople
|
|||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.MetadataPubStatus
|
import eu.kanade.tachiyomi.extension.all.kavita.dto.MetadataPubStatus
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.MetadataTag
|
import eu.kanade.tachiyomi.extension.all.kavita.dto.MetadataTag
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.PersonRole
|
import eu.kanade.tachiyomi.extension.all.kavita.dto.PersonRole
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.SearchResultsDto
|
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.SeriesDto
|
import eu.kanade.tachiyomi.extension.all.kavita.dto.SeriesDto
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.SeriesMetadataDto
|
import eu.kanade.tachiyomi.extension.all.kavita.dto.SeriesMetadataDto
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.SeriesSearchDto
|
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.ServerInfoDto
|
import eu.kanade.tachiyomi.extension.all.kavita.dto.ServerInfoDto
|
||||||
import eu.kanade.tachiyomi.extension.all.kavita.dto.VolumeDto
|
import eu.kanade.tachiyomi.extension.all.kavita.dto.VolumeDto
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
@ -48,7 +46,6 @@ import kotlinx.serialization.json.buildJsonObject
|
|||||||
import kotlinx.serialization.json.put
|
import kotlinx.serialization.json.put
|
||||||
import okhttp3.Dns
|
import okhttp3.Dns
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
@ -142,7 +139,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
return POST(
|
return POST(
|
||||||
"$apiUrl/series/all?pageNumber=$page&libraryId=0&pageSize=20",
|
"$apiUrl/series/all?pageNumber=$page&libraryId=0&pageSize=20",
|
||||||
headersBuilder().build(),
|
headersBuilder().build(),
|
||||||
buildFilterBody()
|
buildFilterBody(currentFilter)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,71 +173,71 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
/**
|
/**
|
||||||
* SEARCH MANGA
|
* SEARCH MANGA
|
||||||
* **/
|
* **/
|
||||||
private var isFilterOn = false // If any filter option is enabled this is true
|
|
||||||
private var toFilter = MetadataPayload()
|
private var currentFilter: MetadataPayload = MetadataPayload()
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
toFilter = MetadataPayload() // need to reset it or will double
|
val newFilter = MetadataPayload() // need to reset it or will double
|
||||||
isFilterOn = false
|
|
||||||
filters.forEach { filter ->
|
filters.forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
|
|
||||||
is SortFilter -> {
|
is SortFilter -> {
|
||||||
if (filter.state != null) {
|
if (filter.state != null) {
|
||||||
toFilter.sorting = filter.state!!.index + 1
|
newFilter.sorting = filter.state!!.index + 1
|
||||||
toFilter.sorting_asc = filter.state!!.ascending
|
newFilter.sorting_asc = filter.state!!.ascending
|
||||||
// Disabled until search is stable
|
|
||||||
// isFilterOn = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is StatusFilterGroup -> {
|
is StatusFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.readStatus.add(content.name)
|
newFilter.readStatus.add(content.name)
|
||||||
isFilterOn = true
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ReleaseYearRangeGroup -> {
|
||||||
|
filter.state.forEach { content ->
|
||||||
|
if (content.state.isNotEmpty()) {
|
||||||
|
if (content.name == "Min")
|
||||||
|
newFilter.releaseYearRangeMin = content.state.toInt()
|
||||||
|
if (content.name == "Max")
|
||||||
|
newFilter.releaseYearRangeMax = content.state.toInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is GenreFilterGroup -> {
|
is GenreFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.genres.add(genresListMeta.find { it.title == content.name }!!.id)
|
newFilter.genres.add(genresListMeta.find { it.title == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is UserRating -> {
|
is UserRating -> {
|
||||||
toFilter.userRating = filter.state
|
newFilter.userRating = filter.state
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
is TagFilterGroup -> {
|
is TagFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.tags.add(tagsListMeta.find { it.title == content.name }!!.id)
|
newFilter.tags.add(tagsListMeta.find { it.title == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is AgeRatingFilterGroup -> {
|
is AgeRatingFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.ageRating.add(ageRatingsListMeta.find { it.title == content.name }!!.value)
|
newFilter.ageRating.add(ageRatingsListMeta.find { it.title == content.name }!!.value)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FormatsFilterGroup -> {
|
is FormatsFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.formats.add(MangaFormat.valueOf(content.name).ordinal)
|
newFilter.formats.add(MangaFormat.valueOf(content.name).ordinal)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CollectionFilterGroup -> {
|
is CollectionFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.collections.add(collectionsListMeta.find { it.title == content.name }!!.id)
|
newFilter.collections.add(collectionsListMeta.find { it.title == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,16 +245,14 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
is LanguageFilterGroup -> {
|
is LanguageFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.language.add(languagesListMeta.find { it.title == content.name }!!.isoCode)
|
newFilter.language.add(languagesListMeta.find { it.title == content.name }!!.isoCode)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is LibrariesFilterGroup -> {
|
is LibrariesFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.libraries.add(libraryListMeta.find { it.name == content.name }!!.id)
|
newFilter.libraries.add(libraryListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,8 +260,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
is PubStatusFilterGroup -> {
|
is PubStatusFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.pubStatus.add(pubStatusListMeta.find { it.title == content.name }!!.value)
|
newFilter.pubStatus.add(pubStatusListMeta.find { it.title == content.name }!!.value)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,116 +268,84 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
is WriterPeopleFilterGroup -> {
|
is WriterPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peopleWriters.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peopleWriters.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is PencillerPeopleFilterGroup -> {
|
is PencillerPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peoplePenciller.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peoplePenciller.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is InkerPeopleFilterGroup -> {
|
is InkerPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peopleInker.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peopleInker.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is ColoristPeopleFilterGroup -> {
|
is ColoristPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peoplePeoplecolorist.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peoplePeoplecolorist.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is LettererPeopleFilterGroup -> {
|
is LettererPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peopleLetterer.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peopleLetterer.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CoverArtistPeopleFilterGroup -> {
|
is CoverArtistPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peopleCoverArtist.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peopleCoverArtist.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is EditorPeopleFilterGroup -> {
|
is EditorPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peopleEditor.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peopleEditor.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is PublisherPeopleFilterGroup -> {
|
is PublisherPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peoplePublisher.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peoplePublisher.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CharacterPeopleFilterGroup -> {
|
is CharacterPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peopleCharacter.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peopleCharacter.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is TranslatorPeopleFilterGroup -> {
|
is TranslatorPeopleFilterGroup -> {
|
||||||
filter.state.forEach { content ->
|
filter.state.forEach { content ->
|
||||||
if (content.state) {
|
if (content.state) {
|
||||||
toFilter.peopleTranslator.add(peopleListMeta.find { it.name == content.name }!!.id)
|
newFilter.peopleTranslator.add(peopleListMeta.find { it.name == content.name }!!.id)
|
||||||
isFilterOn = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> isFilterOn = false
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.isEmpty()) {
|
newFilter.seriesNameQuery = query
|
||||||
isFilterOn = true
|
currentFilter = newFilter
|
||||||
return popularMangaRequest(page)
|
return popularMangaRequest(page)
|
||||||
} else {
|
|
||||||
isFilterOn = false
|
|
||||||
val url = "$apiUrl/Library/search".toHttpUrl().newBuilder()
|
|
||||||
.addQueryParameter("queryString", query)
|
|
||||||
return GET(url.toString(), headers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
if (isFilterOn) {
|
|
||||||
return popularMangaParse(response)
|
return popularMangaParse(response)
|
||||||
} else {
|
|
||||||
if (response.request.url.toString().contains("api/series/all"))
|
|
||||||
return popularMangaParse(response)
|
|
||||||
|
|
||||||
val result = response.parseAs<SearchResultsDto>().series
|
|
||||||
val mangaList = result.map(::searchMangaFromObject)
|
|
||||||
return MangasPage(mangaList, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun searchMangaFromObject(obj: SeriesSearchDto): SManga = SManga.create().apply {
|
|
||||||
title = obj.name
|
|
||||||
thumbnail_url = "$apiUrl/Image/series-cover?seriesId=${obj.seriesId}"
|
|
||||||
description = "None"
|
|
||||||
url = "$apiUrl/Series/${obj.seriesId}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -448,12 +410,12 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
|
|
||||||
private fun chapterFromObject(obj: ChapterDto): SChapter = SChapter.create().apply {
|
private fun chapterFromObject(obj: ChapterDto): SChapter = SChapter.create().apply {
|
||||||
url = obj.id.toString()
|
url = obj.id.toString()
|
||||||
if (obj.number == "0" && obj.isSpecial) {
|
name = if (obj.number == "0" && obj.isSpecial) {
|
||||||
// This is a special. Chapter name is special name
|
// This is a special. Chapter name is special name
|
||||||
name = obj.range
|
obj.range
|
||||||
} else {
|
} else {
|
||||||
val cleanedName = obj.title.replaceFirst("^0+(?!$)".toRegex(), "")
|
val cleanedName = obj.title.replaceFirst("^0+(?!$)".toRegex(), "")
|
||||||
name = "Chapter $cleanedName"
|
"Chapter $cleanedName"
|
||||||
}
|
}
|
||||||
date_upload = helper.parseDate(obj.created)
|
date_upload = helper.parseDate(obj.created)
|
||||||
chapter_number = obj.number.toFloat()
|
chapter_number = obj.number.toFloat()
|
||||||
@ -487,7 +449,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
// Is a single-file volume
|
// Is a single-file volume
|
||||||
// We encode the chapter number to support tracking
|
// We encode the chapter number to support tracking
|
||||||
name = "Volume ${volume.number}"
|
name = "Volume ${volume.number}"
|
||||||
chapter_number = volume.number.toFloat() / 100
|
chapter_number = volume.number.toFloat() / 10000
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
name = "Unhandled Else Volume ${volume.number}"
|
name = "Unhandled Else Volume ${volume.number}"
|
||||||
@ -579,7 +541,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
"Translator"
|
"Translator"
|
||||||
)
|
)
|
||||||
|
|
||||||
private class UserRating() :
|
private class UserRating :
|
||||||
Filter.Select<String>(
|
Filter.Select<String>(
|
||||||
"Minimum Rating",
|
"Minimum Rating",
|
||||||
arrayOf(
|
arrayOf(
|
||||||
@ -594,16 +556,21 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
|
|
||||||
private class SortFilter(sortables: Array<String>) : Filter.Sort("Sort by", sortables, Selection(0, true))
|
private class SortFilter(sortables: Array<String>) : Filter.Sort("Sort by", sortables, Selection(0, true))
|
||||||
|
|
||||||
val sortableList = listOf(
|
private val sortableList = listOf(
|
||||||
Pair("Sort name", 1),
|
Pair("Sort name", 1),
|
||||||
Pair("Created", 2),
|
Pair("Created", 2),
|
||||||
Pair("Last modified", 3),
|
Pair("Last modified", 3),
|
||||||
Pair("Item added", 4),
|
Pair("Item added", 4),
|
||||||
|
Pair("Time to Read", 5)
|
||||||
)
|
)
|
||||||
|
|
||||||
private class StatusFilter(name: String) : Filter.CheckBox(name, false)
|
private class StatusFilter(name: String) : Filter.CheckBox(name, false)
|
||||||
private class StatusFilterGroup(filters: List<StatusFilter>) :
|
private class StatusFilterGroup(filters: List<StatusFilter>) :
|
||||||
Filter.Group<StatusFilter>("Status", filters)
|
Filter.Group<StatusFilter>("Status", filters)
|
||||||
|
|
||||||
|
private class ReleaseYearRange(name: String) : Filter.Text(name)
|
||||||
|
private class ReleaseYearRangeGroup(filters: List<ReleaseYearRange>) :
|
||||||
|
Filter.Group<ReleaseYearRange>("Release Year", filters)
|
||||||
private class GenreFilter(name: String) : Filter.CheckBox(name, false)
|
private class GenreFilter(name: String) : Filter.CheckBox(name, false)
|
||||||
private class GenreFilterGroup(genres: List<GenreFilter>) :
|
private class GenreFilterGroup(genres: List<GenreFilter>) :
|
||||||
Filter.Group<GenreFilter>("Genres", genres)
|
Filter.Group<GenreFilter>("Genres", genres)
|
||||||
@ -637,7 +604,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
|
|
||||||
private class PeopleHeaderFilter(name: String) :
|
private class PeopleHeaderFilter(name: String) :
|
||||||
Filter.Header(name)
|
Filter.Header(name)
|
||||||
private class PeopleSeparatorFilter() :
|
private class PeopleSeparatorFilter :
|
||||||
Filter.Separator()
|
Filter.Separator()
|
||||||
|
|
||||||
private class WriterPeopleFilter(name: String) : Filter.CheckBox(name, false)
|
private class WriterPeopleFilter(name: String) : Filter.CheckBox(name, false)
|
||||||
@ -713,6 +680,13 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (toggledFilters.contains("ReleaseYearRange")) {
|
||||||
|
filtersLoaded.add(
|
||||||
|
ReleaseYearRangeGroup(
|
||||||
|
listOf("Min", "Max").map { ReleaseYearRange(it) }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (genresListMeta.isNotEmpty() and toggledFilters.contains("Genres")) {
|
if (genresListMeta.isNotEmpty() and toggledFilters.contains("Genres")) {
|
||||||
filtersLoaded.add(
|
filtersLoaded.add(
|
||||||
@ -736,8 +710,6 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
"Image",
|
"Image",
|
||||||
"Archive",
|
"Archive",
|
||||||
"Unknown",
|
"Unknown",
|
||||||
"Epub",
|
|
||||||
"Pdf"
|
|
||||||
).map { FormatFilter(it) }
|
).map { FormatFilter(it) }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -890,11 +862,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
.add("Content-Type", "application/json")
|
.add("Content-Type", "application/json")
|
||||||
.add("Authorization", "Bearer $jwtToken")
|
.add("Authorization", "Bearer $jwtToken")
|
||||||
}
|
}
|
||||||
private fun buildFilterBody(filter: MetadataPayload = toFilter): RequestBody {
|
private fun buildFilterBody(filter: MetadataPayload): RequestBody {
|
||||||
var filter = filter
|
|
||||||
if (!isFilterOn and !filter.forceUseMetadataPayload) {
|
|
||||||
filter = MetadataPayload()
|
|
||||||
}
|
|
||||||
|
|
||||||
val formats = if (filter.formats.isEmpty()) {
|
val formats = if (filter.formats.isEmpty()) {
|
||||||
buildJsonArray {
|
buildJsonArray {
|
||||||
@ -946,6 +914,14 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
put("isAscending", JsonPrimitive(filter.sorting_asc))
|
put("isAscending", JsonPrimitive(filter.sorting_asc))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
put("seriesNameQuery", filter.seriesNameQuery)
|
||||||
|
put(
|
||||||
|
"releaseYearRange",
|
||||||
|
buildJsonObject {
|
||||||
|
put("min", filter.releaseYearRangeMin)
|
||||||
|
put("max", filter.releaseYearRangeMax)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return payload.toString().toRequestBody(JSON_MEDIA_TYPE)
|
return payload.toString().toRequestBody(JSON_MEDIA_TYPE)
|
||||||
}
|
}
|
||||||
@ -1052,7 +1028,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
|
|
||||||
private fun getPrefBaseUrl(): String = preferences.getString("BASEURL", "")!!
|
private fun getPrefBaseUrl(): String = preferences.getString("BASEURL", "")!!
|
||||||
private fun getPrefApiUrl(): String = preferences.getString("APIURL", "")!!
|
private fun getPrefApiUrl(): String = preferences.getString("APIURL", "")!!
|
||||||
private fun getPrefKey(key: String): String = preferences.getString(key, "")!!
|
private fun getPrefKey(): String = preferences.getString("APIKEY", "")!!
|
||||||
private fun getToggledFilters() = preferences.getStringSet(KavitaConstants.toggledFiltersPref, KavitaConstants.defaultFilterPrefEntries)!!
|
private fun getToggledFilters() = preferences.getStringSet(KavitaConstants.toggledFiltersPref, KavitaConstants.defaultFilterPrefEntries)!!
|
||||||
|
|
||||||
// We strip the last slash since we will append it above
|
// We strip the last slash since we will append it above
|
||||||
@ -1129,7 +1105,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
if (jwtToken.isEmpty()) setupLogin()
|
if (jwtToken.isEmpty()) setupLogin()
|
||||||
Log.v(LOG_TAG, "[Login] Starting login")
|
Log.v(LOG_TAG, "[Login] Starting login")
|
||||||
val request = POST(
|
val request = POST(
|
||||||
"$apiUrl/Plugin/authenticate?apiKey=${getPrefKey("APIKEY")}&pluginName=Tachiyomi-Kavita",
|
"$apiUrl/Plugin/authenticate?apiKey=${getPrefKey()}&pluginName=Tachiyomi-Kavita",
|
||||||
setupLoginHeaders().build(), "{}".toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
|
setupLoginHeaders().build(), "{}".toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
|
||||||
)
|
)
|
||||||
client.newCall(request).execute().use {
|
client.newCall(request).execute().use {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.extension.all.kavita
|
package eu.kanade.tachiyomi.extension.all.kavita
|
||||||
|
|
||||||
object KavitaConstants {
|
object KavitaConstants {
|
||||||
// togle filters
|
// toggle filters
|
||||||
const val toggledFiltersPref = "toggledFilters"
|
const val toggledFiltersPref = "toggledFilters"
|
||||||
val filterPrefEntries = arrayOf(
|
val filterPrefEntries = arrayOf(
|
||||||
"Sort Options",
|
"Sort Options",
|
||||||
@ -24,7 +24,8 @@ object KavitaConstants {
|
|||||||
"Editor",
|
"Editor",
|
||||||
"Publisher",
|
"Publisher",
|
||||||
"Character",
|
"Character",
|
||||||
"Translators"
|
"Translators",
|
||||||
|
"ReleaseYearRange"
|
||||||
)
|
)
|
||||||
val filterPrefEntriesValue = arrayOf(
|
val filterPrefEntriesValue = arrayOf(
|
||||||
"Sort Options",
|
"Sort Options",
|
||||||
@ -47,7 +48,8 @@ object KavitaConstants {
|
|||||||
"Editor",
|
"Editor",
|
||||||
"Publisher",
|
"Publisher",
|
||||||
"Character",
|
"Character",
|
||||||
"Translators"
|
"Translators",
|
||||||
|
"ReleaseYearRange"
|
||||||
)
|
)
|
||||||
val defaultFilterPrefEntries = setOf(
|
val defaultFilterPrefEntries = setOf(
|
||||||
"Sort Options",
|
"Sort Options",
|
||||||
@ -70,7 +72,8 @@ object KavitaConstants {
|
|||||||
"Editor",
|
"Editor",
|
||||||
"Publisher",
|
"Publisher",
|
||||||
"Character",
|
"Character",
|
||||||
"Translators"
|
"Translators",
|
||||||
|
"ReleaseYearRange"
|
||||||
)
|
)
|
||||||
|
|
||||||
const val customSourceNamePref = "customSourceName"
|
const val customSourceNamePref = "customSourceName"
|
||||||
|
@ -96,20 +96,3 @@ data class ChapterDto(
|
|||||||
val volumeId: Int,
|
val volumeId: Int,
|
||||||
val created: String
|
val created: String
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class SearchResultsDto(
|
|
||||||
val series: List<SeriesSearchDto>
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class SeriesSearchDto(
|
|
||||||
val seriesId: Int,
|
|
||||||
val name: String,
|
|
||||||
val originalName: String,
|
|
||||||
val sortName: String,
|
|
||||||
val localizedName: String,
|
|
||||||
val format: Int,
|
|
||||||
val libraryName: String,
|
|
||||||
val libraryId: Int
|
|
||||||
)
|
|
||||||
|
@ -63,6 +63,9 @@ data class MetadataPayload(
|
|||||||
var language: ArrayList<String> = arrayListOf<String>(),
|
var language: ArrayList<String> = arrayListOf<String>(),
|
||||||
var libraries: ArrayList<Int> = arrayListOf<Int>(),
|
var libraries: ArrayList<Int> = arrayListOf<Int>(),
|
||||||
var pubStatus: ArrayList<Int> = arrayListOf<Int>(),
|
var pubStatus: ArrayList<Int> = arrayListOf<Int>(),
|
||||||
|
var seriesNameQuery: String = "",
|
||||||
|
var releaseYearRangeMin: Int = 0,
|
||||||
|
var releaseYearRangeMax: Int = 0,
|
||||||
|
|
||||||
var peopleWriters: ArrayList<Int> = arrayListOf<Int>(),
|
var peopleWriters: ArrayList<Int> = arrayListOf<Int>(),
|
||||||
var peoplePenciller: ArrayList<Int> = arrayListOf<Int>(),
|
var peoplePenciller: ArrayList<Int> = arrayListOf<Int>(),
|
||||||
@ -74,5 +77,4 @@ data class MetadataPayload(
|
|||||||
var peoplePublisher: ArrayList<Int> = arrayListOf<Int>(),
|
var peoplePublisher: ArrayList<Int> = arrayListOf<Int>(),
|
||||||
var peopleCharacter: ArrayList<Int> = arrayListOf<Int>(),
|
var peopleCharacter: ArrayList<Int> = arrayListOf<Int>(),
|
||||||
var peopleTranslator: ArrayList<Int> = arrayListOf<Int>(),
|
var peopleTranslator: ArrayList<Int> = arrayListOf<Int>(),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user