Improves the order of search results

This commit is contained in:
Vitor Pamplona
2026-03-09 11:25:00 -04:00
parent 76598c304e
commit 2387a1bb91
7 changed files with 105 additions and 59 deletions
@@ -22,6 +22,9 @@ package com.vitorpamplona.quartz.nip01Core.metadata
import androidx.compose.runtime.Stable
import com.vitorpamplona.quartz.lightning.Lud06
import com.vitorpamplona.quartz.utils.DualCase
import com.vitorpamplona.quartz.utils.containsAny
import com.vitorpamplona.quartz.utils.startsWithAny
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -47,11 +50,6 @@ class UserMetadata {
fun anyName(): String? = displayName ?: name
fun anyNameStartsWith(prefix: String): Boolean =
listOfNotNull(name, displayName, nip05, lud06, lud16).any {
it.contains(prefix, true)
}
fun lnAddress(): String? = lud16 ?: lud06
fun bestName(): String? = displayName ?: name
@@ -104,6 +102,33 @@ class UserMetadata {
if (pronouns?.isBlank() == true) pronouns = null
}
fun anyNameOrAddressContains(terms: List<DualCase>): Boolean =
name?.containsAny(terms) == true ||
displayName?.containsAny(terms) == true ||
lud16?.containsAny(terms) == true ||
nip05?.containsAny(terms) == true ||
website?.containsAny(terms) == true
fun anyNameStartsWith(terms: List<DualCase>): Boolean =
name?.startsWithAny(terms) == true ||
displayName?.startsWithAny(terms) == true
fun anyAddressStartsWith(terms: List<DualCase>): Boolean =
lud16?.startsWithAny(terms) == true ||
nip05?.startsWithAny(terms) == true ||
website?.startsWithAny(terms) == true
fun anyPropertyContains(terms: List<DualCase>): Boolean =
name?.containsAny(terms) == true ||
displayName?.containsAny(terms) == true ||
picture?.containsAny(terms) == true ||
banner?.containsAny(terms) == true ||
about?.containsAny(terms) == true ||
lud06?.containsAny(terms) == true ||
lud16?.containsAny(terms) == true ||
nip05?.containsAny(terms) == true ||
website?.containsAny(terms) == true
fun convertLud06toLud16IfNeeded() {
if (lud16.isNullOrBlank()) {
lud06?.let {
@@ -68,6 +68,27 @@ fun String.containsIgnoreCase(
return false
}
fun String.startsWithIgnoreCase(
whatLowercase: String,
whatUppercase: String,
): Boolean {
val termLength = min(whatUppercase.length, whatLowercase.length)
// If the search term is longer than the string itself, it can't be a prefix
if (this.length < termLength) return false
var offset = 0
while (offset < termLength) {
val current = this[offset]
if (current != whatLowercase[offset] && current != whatUppercase[offset]) {
return false
}
offset++
}
return true
}
fun String.containsAny(terms: List<DualCase>): Boolean {
if (terms.isEmpty()) return true // Empty string is contained
@@ -78,6 +99,16 @@ fun String.containsAny(terms: List<DualCase>): Boolean {
return terms.any { containsIgnoreCase(it.lowercase, it.uppercase) }
}
fun String.startsWithAny(terms: List<DualCase>): Boolean {
if (terms.isEmpty()) return true // Empty string is contained
if (terms.size == 1) {
return startsWithIgnoreCase(terms[0].lowercase, terms[0].uppercase)
}
return terms.any { startsWithIgnoreCase(it.lowercase, it.uppercase) }
}
class DualCase(
val lowercase: String,
val uppercase: String,