Search algorithm improved

Language settings in default tag fixed
This commit is contained in:
tom5079
2019-07-03 19:40:19 +09:00
parent bd4b61d7ac
commit 7e87bb6838
6 changed files with 152 additions and 85 deletions

View File

@@ -14,7 +14,7 @@ android {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
versionCode 20 versionCode 20
versionName "2.11.1" versionName "2.12"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true

View File

@@ -90,8 +90,8 @@ class Tags(tag: List<Tag?>?) : ArrayList<Tag>() {
} }
} }
fun removeByArea(area: String) { fun removeByArea(area: String, isNegative: Boolean? = null) {
filter { it.area == area }.forEach { filter { it.area == area && (if(isNegative == null) true else (it.isNegative == isNegative)) }.forEach {
remove(it) remove(it)
} }
} }

View File

@@ -17,6 +17,7 @@ import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
@@ -45,6 +46,7 @@ import xyz.quaver.pupil.BuildConfig
import xyz.quaver.pupil.Pupil import xyz.quaver.pupil.Pupil
import xyz.quaver.pupil.R import xyz.quaver.pupil.R
import xyz.quaver.pupil.adapters.GalleryBlockAdapter import xyz.quaver.pupil.adapters.GalleryBlockAdapter
import xyz.quaver.pupil.types.SelectorSuggestion
import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.types.TagSuggestion import xyz.quaver.pupil.types.TagSuggestion
import xyz.quaver.pupil.types.Tags import xyz.quaver.pupil.types.Tags
@@ -755,7 +757,7 @@ class MainActivity : AppCompatActivity() {
if (query.isEmpty() or query.endsWith(' ')) { if (query.isEmpty() or query.endsWith(' ')) {
swapSuggestions(json.parse(serializer, favoritesFile.readText()).map { swapSuggestions(json.parse(serializer, favoritesFile.readText()).map {
TagSuggestion(it.tag, -1, "", it.area ?: "tag") TagSuggestion(it.tag, -1, "", it.area ?: "tag")
}) } + SelectorSuggestion())
return@setOnQueryChangeListener return@setOnQueryChangeListener
} }
@@ -782,13 +784,44 @@ class MainActivity : AppCompatActivity() {
} }
setOnBindSuggestionCallback { suggestionView, leftIcon, textView, item, _ -> setOnBindSuggestionCallback { suggestionView, leftIcon, textView, item, _ ->
val suggestion = item as TagSuggestion if (item is SelectorSuggestion) {
val tag = "${suggestion.n}:${suggestion.s.replace(Regex("\\s"), "_")}" var hasSelector = false
with(suggestionView as LinearLayout) {
for (i in 0 until childCount) {
val child = getChildAt(i)
if (child is ConstraintLayout) {
child.visibility = View.VISIBLE
hasSelector = true
}
else
child.visibility = View.GONE
}
}
if (!hasSelector) {
val view = LayoutInflater.from(context)
.inflate(R.layout.item_selector_suggestion, suggestionView, false)
suggestionView.addView(view)
}
} else if(item is TagSuggestion) {
with(suggestionView as LinearLayout) {
for (i in 0 until childCount) {
val child = getChildAt(i)
if (child is ConstraintLayout) {
child.visibility = View.GONE
}
else
child.visibility = View.VISIBLE
}
}
val tag = "${item.n}:${item.s.replace(Regex("\\s"), "_")}"
leftIcon.setImageDrawable( leftIcon.setImageDrawable(
ResourcesCompat.getDrawable( ResourcesCompat.getDrawable(
resources, resources,
when(suggestion.n) { when(item.n) {
"female" -> R.drawable.ic_gender_female "female" -> R.drawable.ic_gender_female
"male" -> R.drawable.ic_gender_male "male" -> R.drawable.ic_gender_male
"language" -> R.drawable.ic_translate "language" -> R.drawable.ic_translate
@@ -808,7 +841,6 @@ class MainActivity : AppCompatActivity() {
else else
setImageResource(R.drawable.ic_star_empty) setImageResource(R.drawable.ic_star_empty)
visibility = View.VISIBLE
rotation = 0f rotation = 0f
isEnabled = true isEnabled = true
@@ -835,13 +867,13 @@ class MainActivity : AppCompatActivity() {
} }
} }
if (suggestion.t == -1) { if (item.t == -1) {
textView.text = suggestion.s textView.text = item.s
} else { } else {
val text = "${suggestion.s}\n ${suggestion.t}" val text = "${item.s}\n ${item.t}"
val len = text.length val len = text.length
val left = suggestion.s.length val left = item.s.length
textView.text = SpannableString(text).apply { textView.text = SpannableString(text).apply {
val s = AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE) val s = AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE)
@@ -851,14 +883,16 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }
}
setOnSearchListener(object : FloatingSearchView.OnSearchListener { setOnSearchListener(object : FloatingSearchView.OnSearchListener {
override fun onSuggestionClicked(searchSuggestion: SearchSuggestion?) { override fun onSuggestionClicked(searchSuggestion: SearchSuggestion?) {
val suggestion = searchSuggestion as TagSuggestion if (searchSuggestion !is TagSuggestion)
return
with(searchInputView.text) { with(searchInputView.text) {
delete(if (lastIndexOf(' ') == -1) 0 else lastIndexOf(' ')+1, length) delete(if (lastIndexOf(' ') == -1) 0 else lastIndexOf(' ')+1, length)
append("${suggestion.n}:${suggestion.s.replace(Regex("\\s"), "_")} ") append("${searchSuggestion.n}:${searchSuggestion.s.replace(Regex("\\s"), "_")} ")
} }
} }
@@ -872,7 +906,7 @@ class MainActivity : AppCompatActivity() {
if (query.isEmpty() or query.endsWith(' ')) if (query.isEmpty() or query.endsWith(' '))
swapSuggestions(json.parse(serializer, favoritesFile.readText()).map { swapSuggestions(json.parse(serializer, favoritesFile.readText()).map {
TagSuggestion(it.tag, -1, "", it.area ?: "tag") TagSuggestion(it.tag, -1, "", it.area ?: "tag")
}) } + SelectorSuggestion())
} }
override fun onFocusCleared() { override fun onFocusCleared() {

View File

@@ -222,14 +222,14 @@ class SettingsActivity : AppCompatActivity() {
addAll(languages.values) addAll(languages.values)
} }
) )
if (tags.any { it.area == "language" }) { if (tags.any { it.area == "language" && !it.isNegative }) {
val tag = languages[tags.first { it.area == "language" }.tag] val tag = languages[tags.first { it.area == "language" }.tag]
if (tag != null) { if (tag != null) {
setSelection( setSelection(
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
(adapter as ArrayAdapter<String>).getPosition(tag) (adapter as ArrayAdapter<String>).getPosition(tag)
) )
tags.removeByArea("language") tags.removeByArea("language", false)
} }
} }
} }

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:layout_height="1dp"
android:background="@color/dark_gray"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<Button
style="?borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="favorite" />
<Button
style="?borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="history" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,13 +1,12 @@
package xyz.quaver.hitomi package xyz.quaver.hitomi
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.util.* import java.util.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
val searchDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
fun doSearch(query: String) : List<Int> { fun doSearch(query: String) : List<Int> {
val time = System.currentTimeMillis()
val terms = query val terms = query
.trim() .trim()
.replace(Regex("""^\?"""), "") .replace(Regex("""^\?"""), "")
@@ -43,24 +42,24 @@ fun doSearch(query: String) : List<Int> {
//positive results //positive results
positiveTerms.map { positiveTerms.map {
launch(searchDispatcher) { async(Dispatchers.IO) {
val newResults = getGalleryIDsForQuery(it) Pair(getGalleryIDsForQuery(it), true)
filterPositive(newResults.sorted()) }
}+negativeTerms.map {
async(Dispatchers.IO) {
Pair(getGalleryIDsForQuery(it), false)
} }
}.forEach { }.forEach {
it.join() val (result, isPositive) = it.await()
when {
isPositive -> filterPositive(result.sorted())
else -> filterNegative(result.sorted())
}
}
} }
//negative results println("PUPIL/SEARCH TIME ${System.currentTimeMillis() - time}ms")
negativeTerms.map {
launch(searchDispatcher) {
filterNegative(getGalleryIDsForQuery(it).sorted())
}
}.forEach {
it.join()
}
}
return results return results
} }