Extend library search by adding -<source> option (#5387)

* extend library search to enable -<source> search

library search already allows for <source> search to select manga from a
particular source. Similarly, -<source> allows to search for manga that
aren't from the said source. TachiyomiSy has this feature but it heavily
depends on exh methods

A problem when you directly add a negation check is that although
it will work, the genre search kicks in adds back every manga since
-<source> returns true for all genres of a manga

Thus, the solution I decided on was do source search first, and then
move to genre check when it fails. A perhaps useful addition is that,
now you're able to search like this:
 <genre1>, -<source>, -<genre2>

* make if-else statements more readable

* refactor containsSourceOrGenre() using `when`

* add comment describing the function

* remove lazy

not really required anymore now that containsSourceOrGenre was rewritten
using `when`
This commit is contained in:
curche 2021-06-28 21:02:03 +05:30 committed by GitHub
parent e2cf157857
commit 7e3ea9074c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -101,18 +101,37 @@ class LibraryItem(
* @return true if the manga should be included, false otherwise. * @return true if the manga should be included, false otherwise.
*/ */
override fun filter(constraint: String): Boolean { override fun filter(constraint: String): Boolean {
val sourceName by lazy { sourceManager.getOrStub(manga.source).name }
val genres by lazy { manga.getGenres() }
return manga.title.contains(constraint, true) || return manga.title.contains(constraint, true) ||
(manga.author?.contains(constraint, true) ?: false) || (manga.author?.contains(constraint, true) ?: false) ||
(manga.artist?.contains(constraint, true) ?: false) || (manga.artist?.contains(constraint, true) ?: false) ||
(manga.description?.contains(constraint, true) ?: false) || (manga.description?.contains(constraint, true) ?: false) ||
sourceManager.getOrStub(manga.source).name.contains(constraint, true) ||
if (constraint.contains(",")) { if (constraint.contains(",")) {
constraint.split(",").all { containsGenre(it.trim(), manga.getGenres()) } constraint.split(",").all { containsSourceOrGenre(it.trim(), sourceName, genres) }
} else { } else {
containsGenre(constraint, manga.getGenres()) containsSourceOrGenre(constraint, sourceName, genres)
} }
} }
/**
* Filters a manga by checking whether the query is the manga's source OR part of
* the genres of the manga
* Checking for genre is done only if the query isn't part of the source name.
*
* @param query the query to check
* @param sourceName name of the manga's source
* @param genres list containing manga's genres
*/
private fun containsSourceOrGenre(query: String, sourceName: String, genres: List<String>?): Boolean {
val minus = query.startsWith("-")
val tag = if (minus) { query.substringAfter("-") } else query
return when (sourceName.contains(tag, true)) {
false -> containsGenre(query, genres)
else -> !minus
}
}
private fun containsGenre(tag: String, genres: List<String>?): Boolean { private fun containsGenre(tag: String, genres: List<String>?): Boolean {
return if (tag.startsWith("-")) { return if (tag.startsWith("-")) {
genres?.find { genres?.find {