Moves metadata methods from User to UserCache object

This commit is contained in:
Vitor Pamplona
2026-02-07 10:18:13 -05:00
parent 823624f8f2
commit 4e39a531b7
7 changed files with 62 additions and 74 deletions
@@ -2149,7 +2149,7 @@ object LocalCache : ILocalCache, ICacheProvider {
val finds =
users.filter { _, user: User ->
(
(user.anyNameStartsWith(username)) ||
(user.metadataOrNull()?.anyNameStartsWith(username) == true) ||
user.pubkeyHex.startsWith(username, true) ||
user.pubkeyNpub().startsWith(username, true)
) &&
@@ -22,6 +22,5 @@ package com.vitorpamplona.amethyst.model
// Re-export from commons for backwards compatibility
typealias Note = com.vitorpamplona.amethyst.commons.model.Note
typealias NotesGatherer = com.vitorpamplona.amethyst.commons.model.NotesGatherer
typealias AddressableNote = com.vitorpamplona.amethyst.commons.model.AddressableNote
typealias NoteState = com.vitorpamplona.amethyst.commons.model.NoteState
@@ -108,7 +108,7 @@ class AddressableNote(
@Stable
open class Note(
val idHex: String,
val idHex: HexKey,
) : NotesGatherer {
// These fields are only available after the Text Note event is received.
// They are immutable after that.
@@ -97,33 +97,11 @@ class User(
fun toNostrUri() = "nostr:${toNProfile()}"
fun toBestDisplayName(): String =
metadataOrNull()
?.flow
?.value
?.info
?.bestName() ?: pubkeyDisplayHex()
fun toBestDisplayName(): String = metadataOrNull()?.bestName() ?: pubkeyDisplayHex()
fun nip05(): String? =
metadataOrNull()
?.flow
?.value
?.info
?.nip05
fun profilePicture(): String? = metadataOrNull()?.profilePicture()
fun profilePicture(): String? =
metadataOrNull()
?.flow
?.value
?.info
?.picture
fun lnAddress(): String? =
metadataOrNull()
?.flow
?.value
?.info
?.lnAddress()
fun lnAddress(): String? = metadataOrNull()?.lnAddress()
fun addZap(
zapRequest: Note,
@@ -227,52 +205,9 @@ class User(
fun containsAny(hiddenWordsCase: List<DualCase>): Boolean {
if (hiddenWordsCase.isEmpty()) return false
metadata?.flow?.value?.let { userInfo ->
val info = userInfo.info
if (info.name?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.displayName?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.picture?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.banner?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.about?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.lud06?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.lud16?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.nip05?.containsAny(hiddenWordsCase) == true) {
return true
}
}
return false
return metadataOrNull()?.containsAny(hiddenWordsCase) == true
}
fun anyNameStartsWith(username: String): Boolean =
metadata
?.flow
?.value
?.info
?.anyNameStartsWith(username) ?: false
@Synchronized
fun createOrDestroyFlowSync(create: Boolean) {
if (create) {
@@ -27,6 +27,8 @@ import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata
import com.vitorpamplona.quartz.nip39ExtIdentities.IdentityClaimTag
import com.vitorpamplona.quartz.nip39ExtIdentities.identityClaims
import com.vitorpamplona.quartz.utils.DualCase
import com.vitorpamplona.quartz.utils.containsAny
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
@@ -57,4 +59,56 @@ class UserMetadataCache {
}
fun shouldUpdateWith(event: MetadataEvent) = event.createdAt > (flow.value?.createdAt ?: 0)
fun anyNameStartsWith(username: String): Boolean = flow.value?.info?.anyNameStartsWith(username) ?: false
fun containsAny(hiddenWordsCase: List<DualCase>): Boolean {
if (hiddenWordsCase.isEmpty()) return false
flow.value?.let { userInfo ->
val info = userInfo.info
if (info.name?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.displayName?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.picture?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.banner?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.about?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.lud06?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.lud16?.containsAny(hiddenWordsCase) == true) {
return true
}
if (info.nip05?.containsAny(hiddenWordsCase) == true) {
return true
}
}
return false
}
fun bestName(): String? = flow.value?.info?.bestName()
fun nip05(): String? = flow.value?.info?.nip05
fun profilePicture(): String? = flow.value?.info?.picture
fun lnAddress(): String? = flow.value?.info?.lnAddress()
}
@@ -78,7 +78,7 @@ fun UserSearchCard(
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onSurface,
)
val nip05 = user.nip05()
val nip05 = user.metadataOrNull()?.nip05()
if (nip05 != null) {
Text(
nip05,
@@ -88,7 +88,7 @@ class DesktopLocalCache : ICacheProvider {
// Search by name/displayName/nip05/lud16
return users.values
.filter { user ->
user.anyNameStartsWith(prefix) ||
user.metadataOrNull()?.anyNameStartsWith(prefix) == true ||
user.pubkeyHex.startsWith(prefix, ignoreCase = true) ||
user.pubkeyNpub().startsWith(prefix, ignoreCase = true)
}.sortedWith(