improvement: More stable search that prefers title
This commit is contained in:
parent
390c999f65
commit
b533c6a876
|
@ -929,10 +929,10 @@ fun vaultListScreenState(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
val indexed = mutableListOf<SearchToken>()
|
val indexed = mutableListOf<SearchToken>()
|
||||||
indexed += SearchToken(
|
//indexed += SearchToken(
|
||||||
priority = 2f,
|
// priority = 2f,
|
||||||
value = secret.name,
|
// value = secret.name,
|
||||||
)
|
//)
|
||||||
if (secret.login != null) {
|
if (secret.login != null) {
|
||||||
// Make username searchable
|
// Make username searchable
|
||||||
if (secret.login.username != null) {
|
if (secret.login.username != null) {
|
||||||
|
@ -2005,7 +2005,8 @@ private suspend fun List<IndexedModel<VaultItem2.Item>>.search(
|
||||||
source = x.tokens,
|
source = x.tokens,
|
||||||
query = queryComponents,
|
query = queryComponents,
|
||||||
)
|
)
|
||||||
}.div(it.indexedOther.size.coerceAtLeast(1))
|
}
|
||||||
|
.div(it.indexedOther.size.coerceAtLeast(1))
|
||||||
val r = it.indexedText.find(
|
val r = it.indexedText.find(
|
||||||
query = query,
|
query = query,
|
||||||
colorBackground = highlightBackgroundColor,
|
colorBackground = highlightBackgroundColor,
|
||||||
|
@ -2014,15 +2015,24 @@ private suspend fun List<IndexedModel<VaultItem2.Item>>.search(
|
||||||
if (r == null && q <= 0.0001f) {
|
if (r == null && q <= 0.0001f) {
|
||||||
return@parallelSearch null
|
return@parallelSearch null
|
||||||
}
|
}
|
||||||
|
// Slightly prefer favorite items, but by a very small
|
||||||
|
// margin. The idea is that favorite items are show on top
|
||||||
|
// anyway, so if a user is using the search, then he probably
|
||||||
|
// searches for something other than the favorite items.
|
||||||
|
val favoriteScoreModifier = if (it.model.favourite) 1.35f else 1f
|
||||||
|
val finalScore = if (r != null) {
|
||||||
|
r.score + r.score * q / 10f
|
||||||
|
} else {
|
||||||
|
q / 15f
|
||||||
|
} * favoriteScoreModifier
|
||||||
FilteredModel(
|
FilteredModel(
|
||||||
model = it.model,
|
model = it.model,
|
||||||
score = q + (r?.score ?: 0f),
|
score = finalScore,
|
||||||
result = r,
|
result = r,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.sortedWith(
|
.sortedWith(
|
||||||
compareBy(
|
compareBy(
|
||||||
{ !it.model.favourite },
|
|
||||||
{ -it.score },
|
{ -it.score },
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -54,7 +54,7 @@ fun IndexedText.find(
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
var x = query.components.map { false }.toMutableList()
|
val x = MutableList(query.components.size) { false }
|
||||||
|
|
||||||
var score = 0f
|
var score = 0f
|
||||||
val text = buildAnnotatedString {
|
val text = buildAnnotatedString {
|
||||||
|
@ -77,14 +77,20 @@ fun IndexedText.find(
|
||||||
return@forEachIndexed
|
return@forEachIndexed
|
||||||
}
|
}
|
||||||
|
|
||||||
val queryPositionScore = 1f - i.toFloat() / comp.lowercase.length.toFloat()
|
// We want to prefer results that start with a given query
|
||||||
val queryLengthScore =
|
val queryPositionScore = if (i == 0) { // starts with a query
|
||||||
queryComp.lowercase.length.toFloat() / comp.lowercase.length.toFloat()
|
1f
|
||||||
val s = 0f +
|
} else {
|
||||||
queryPositionScore +
|
val penalty = 0.25f
|
||||||
|
val ratio = i.toFloat() / comp.lowercase.length.toFloat()
|
||||||
|
(1f - penalty) * (1f - ratio)
|
||||||
|
}
|
||||||
|
val queryLengthScore = queryComp.lowercase.length.toFloat()
|
||||||
|
val totalScore = 0f +
|
||||||
|
queryPositionScore *
|
||||||
queryLengthScore
|
queryLengthScore
|
||||||
if (s > max) {
|
if (totalScore > max) {
|
||||||
max = s
|
max = totalScore
|
||||||
// remember the position of the match, so we can draw it.
|
// remember the position of the match, so we can draw it.
|
||||||
start = i
|
start = i
|
||||||
end = i + queryComp.lowercase.length
|
end = i + queryComp.lowercase.length
|
||||||
|
@ -104,19 +110,21 @@ fun IndexedText.find(
|
||||||
end = offset + end,
|
end = offset + end,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
score += max *
|
|
||||||
// We want to prioritize when the component starts with
|
val componentPositionScoreModifier = kotlin.run {
|
||||||
// a given query.
|
val compIndexNormalized = compIndex.toFloat() / components.size.toFloat()
|
||||||
((1f - compIndex.toFloat() / components.size.toFloat()) / 5f + 0.8f)
|
(1f - compIndexNormalized) * 0.5f + 0.5f
|
||||||
|
}
|
||||||
|
score += max * componentPositionScoreModifier
|
||||||
}
|
}
|
||||||
|
|
||||||
if (score < 0.01f || !x.all { it } && requireAll) return null
|
if (score < 0.01f || requireAll && !x.all { it }) return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return IndexedText.FindResult(
|
return IndexedText.FindResult(
|
||||||
text = this.text,
|
text = this.text,
|
||||||
components = this.components,
|
components = this.components,
|
||||||
highlightedText = text,
|
highlightedText = text,
|
||||||
score = score / components.size.toFloat(),
|
score = score / this.text.length.toFloat(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue