mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-10-10 21:04:22 +02:00
Refining the outbox relay selection with all hints.
This commit is contained in:
@@ -97,7 +97,10 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
|
|||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
|
||||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.acessories.downloadFirstEvent
|
import com.vitorpamplona.quartz.nip01Core.relay.client.acessories.downloadFirstEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
|
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
|
||||||
@@ -131,7 +134,6 @@ import com.vitorpamplona.quartz.nip10Notes.content.findURLs
|
|||||||
import com.vitorpamplona.quartz.nip17Dm.NIP17Factory
|
import com.vitorpamplona.quartz.nip17Dm.NIP17Factory
|
||||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
|
||||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
|
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
|
||||||
@@ -793,31 +795,15 @@ class Account(
|
|||||||
relaysItCameFrom
|
relaysItCameFrom
|
||||||
}
|
}
|
||||||
|
|
||||||
fun computeRelayListToBroadcast(event: Event): Set<NormalizedRelayUrl> {
|
private fun computeRelayListForLinkedUser(user: User): Set<NormalizedRelayUrl> =
|
||||||
val author = cache.getUserIfExists(event.pubKey)
|
if (user == userProfile()) {
|
||||||
|
notificationRelays.flow.value
|
||||||
val authorOutboxRelays =
|
|
||||||
if (author != null) {
|
|
||||||
if (author == userProfile()) {
|
|
||||||
outboxRelays.flow.value
|
|
||||||
} else {
|
} else {
|
||||||
author.outboxRelays().ifEmpty { null }?.toSet()
|
user.inboxRelays().ifEmpty { null }?.toSet()
|
||||||
?: cache.relayHints
|
?: (cache.relayHints.hintsForKey(user.pubkeyHex).toSet() + user.relaysBeingUsed.keys)
|
||||||
.hintsForKey(author.pubkeyHex)
|
|
||||||
.ifEmpty { null }
|
|
||||||
?.toSet()
|
|
||||||
?: emptySet()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cache.relayHints
|
|
||||||
.hintsForKey(event.pubKey)
|
|
||||||
.ifEmpty { null }
|
|
||||||
?.toSet()
|
|
||||||
emptySet()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val taggedUserInboxRelays =
|
private fun computeRelayListForLinkedUser(pubkey: HexKey): Set<NormalizedRelayUrl> =
|
||||||
event.taggedUserIds().flatMapTo(mutableSetOf()) { pubkey ->
|
|
||||||
if (pubkey == userProfile().pubkeyHex) {
|
if (pubkey == userProfile().pubkeyHex) {
|
||||||
notificationRelays.flow.value
|
notificationRelays.flow.value
|
||||||
} else {
|
} else {
|
||||||
@@ -828,8 +814,8 @@ class Account(
|
|||||||
?.toSet()
|
?.toSet()
|
||||||
?: cache.relayHints.hintsForKey(pubkey).toSet()
|
?: cache.relayHints.hintsForKey(pubkey).toSet()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
private fun computeRelaysForChannels(event: Event): Set<NormalizedRelayUrl> {
|
||||||
val isInChannel =
|
val isInChannel =
|
||||||
if (
|
if (
|
||||||
event is ChannelMessageEvent ||
|
event is ChannelMessageEvent ||
|
||||||
@@ -849,109 +835,118 @@ class Account(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
val channelRelays =
|
return if (isInChannel != null) {
|
||||||
if (isInChannel != null) {
|
|
||||||
val channel = LocalCache.checkGetOrCreateChannel(isInChannel)
|
val channel = LocalCache.checkGetOrCreateChannel(isInChannel)
|
||||||
channel?.relays() ?: emptySet()
|
channel?.relays() ?: emptySet()
|
||||||
} else {
|
} else {
|
||||||
emptySet()
|
emptySet()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val replyRelays =
|
fun computeRelayListToBroadcast(event: Event): Set<NormalizedRelayUrl> {
|
||||||
cache.computeReplyTo(event).flatMapTo(mutableSetOf()) {
|
if (event is GiftWrapEvent) {
|
||||||
val existingRelays = it.relays.toSet()
|
val receiver = event.recipientPubKey()
|
||||||
val replyToAuthor = it.author
|
if (receiver != null) {
|
||||||
|
val relayList =
|
||||||
val replyAuthorRelays =
|
cache
|
||||||
if (replyToAuthor != null) {
|
.getOrCreateUser(receiver)
|
||||||
if (replyToAuthor == userProfile()) {
|
.dmInboxRelayList()
|
||||||
outboxRelays.flow.value
|
?.relays()
|
||||||
|
?.ifEmpty { null }
|
||||||
|
if (relayList != null) {
|
||||||
|
client.send(event, relayList.toSet())
|
||||||
} else {
|
} else {
|
||||||
replyToAuthor.outboxRelays().ifEmpty { null }?.toSet()
|
val publicRelayList = computeRelayListForLinkedUser(receiver)
|
||||||
?: cache.relayHints
|
client.send(event, publicRelayList)
|
||||||
.hintsForKey(replyToAuthor.pubkeyHex)
|
|
||||||
.ifEmpty { null }
|
|
||||||
?.toSet()
|
|
||||||
?: emptySet()
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emptySet()
|
return emptySet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event is WrappedEvent) {
|
||||||
|
return emptySet()
|
||||||
}
|
}
|
||||||
|
|
||||||
existingRelays + replyAuthorRelays
|
val relayList = mutableSetOf<NormalizedRelayUrl>()
|
||||||
|
|
||||||
|
val author = cache.getUserIfExists(event.pubKey)
|
||||||
|
|
||||||
|
if (author != null) {
|
||||||
|
if (author == userProfile()) {
|
||||||
|
relayList.addAll(outboxRelays.flow.value)
|
||||||
|
} else {
|
||||||
|
relayList.addAll(
|
||||||
|
author.outboxRelays().ifEmpty { null }
|
||||||
|
?: cache.relayHints.hintsForKey(author.pubkeyHex),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
relayList.addAll(cache.relayHints.hintsForKey(event.pubKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
return authorOutboxRelays + taggedUserInboxRelays + channelRelays + replyRelays
|
if (event is PubKeyHintProvider) {
|
||||||
|
event.pubKeyHints().forEach {
|
||||||
|
relayList.add(it.relay)
|
||||||
|
}
|
||||||
|
event.linkedPubKeys().forEach { pubkey ->
|
||||||
|
relayList.addAll(computeRelayListForLinkedUser(pubkey))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event is EventHintProvider) {
|
||||||
|
event.eventHints().forEach {
|
||||||
|
relayList.add(it.relay)
|
||||||
|
}
|
||||||
|
event.linkedEventIds().forEach { eventId ->
|
||||||
|
cache.getNoteIfExists(eventId)?.let { linkedNote ->
|
||||||
|
val linkedNoteAuthor = linkedNote.author
|
||||||
|
|
||||||
|
if (linkedNoteAuthor != null) {
|
||||||
|
relayList.addAll(computeRelayListForLinkedUser(linkedNoteAuthor))
|
||||||
|
} else {
|
||||||
|
relayList.addAll(linkedNote.relays.toSet())
|
||||||
|
}
|
||||||
|
|
||||||
|
linkedNote.event?.let { linkedEvent ->
|
||||||
|
relayList.addAll(computeRelaysForChannels(linkedEvent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event is AddressHintProvider) {
|
||||||
|
event.addressHints().forEach {
|
||||||
|
relayList.add(it.relay)
|
||||||
|
}
|
||||||
|
event.linkedAddressIds().forEach { addressId ->
|
||||||
|
cache.getAddressableNoteIfExists(addressId)?.let { linkedNote ->
|
||||||
|
val linkedNoteAuthor = linkedNote.author
|
||||||
|
|
||||||
|
if (linkedNoteAuthor != null) {
|
||||||
|
relayList.addAll(computeRelayListForLinkedUser(linkedNoteAuthor))
|
||||||
|
} else {
|
||||||
|
relayList.addAll(linkedNote.relays.toSet())
|
||||||
|
}
|
||||||
|
|
||||||
|
linkedNote.event?.let { linkedEvent ->
|
||||||
|
relayList.addAll(computeRelaysForChannels(linkedEvent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
relayList.addAll(computeRelaysForChannels(event))
|
||||||
|
|
||||||
|
return relayList
|
||||||
}
|
}
|
||||||
|
|
||||||
fun computeRelayListToBroadcast(note: Note): Set<NormalizedRelayUrl> {
|
fun computeRelayListToBroadcast(note: Note): Set<NormalizedRelayUrl> {
|
||||||
val author = note.author
|
val noteEvent = note.event
|
||||||
|
return if (noteEvent != null) {
|
||||||
val authorOutboxRelays =
|
computeRelayListToBroadcast(noteEvent)
|
||||||
if (author != null) {
|
|
||||||
if (author == userProfile()) {
|
|
||||||
outboxRelays.flow.value
|
|
||||||
} else {
|
} else {
|
||||||
author.outboxRelays().ifEmpty { null }?.toSet()
|
note.relays.toSet()
|
||||||
?: cache.relayHints
|
|
||||||
.hintsForKey(author.pubkeyHex)
|
|
||||||
.ifEmpty { null }
|
|
||||||
?.toSet()
|
|
||||||
?: emptySet()
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
val taggedUserInboxRelays =
|
|
||||||
note.event?.taggedUserIds()?.flatMapTo(mutableSetOf()) { pubkey ->
|
|
||||||
if (pubkey == userProfile().pubkeyHex) {
|
|
||||||
notificationRelays.flow.value
|
|
||||||
} else {
|
|
||||||
LocalCache
|
|
||||||
.getUserIfExists(pubkey)
|
|
||||||
?.inboxRelays()
|
|
||||||
?.ifEmpty { null }
|
|
||||||
?.toSet()
|
|
||||||
?: cache.relayHints.hintsForKey(pubkey).toSet()
|
|
||||||
}
|
|
||||||
} ?: emptySet()
|
|
||||||
|
|
||||||
val isInChannel = note.channelHex()
|
|
||||||
val channelRelays =
|
|
||||||
if (isInChannel != null) {
|
|
||||||
val channel = LocalCache.checkGetOrCreateChannel(isInChannel)
|
|
||||||
channel?.relays() ?: emptySet()
|
|
||||||
} else {
|
|
||||||
emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
val replyRelays =
|
|
||||||
note.replyTo?.flatMapTo(mutableSetOf()) {
|
|
||||||
val existingRelays = it.relays.toSet()
|
|
||||||
|
|
||||||
val replyToAuthor = it.author
|
|
||||||
|
|
||||||
val replyAuthorRelays =
|
|
||||||
if (replyToAuthor != null) {
|
|
||||||
if (replyToAuthor == userProfile()) {
|
|
||||||
outboxRelays.flow.value
|
|
||||||
} else {
|
|
||||||
replyToAuthor.outboxRelays().ifEmpty { null }?.toSet()
|
|
||||||
?: cache.relayHints
|
|
||||||
.hintsForKey(replyToAuthor.pubkeyHex)
|
|
||||||
.ifEmpty { null }
|
|
||||||
?.toSet()
|
|
||||||
?: emptySet()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
existingRelays + replyAuthorRelays
|
|
||||||
} ?: emptySet()
|
|
||||||
|
|
||||||
return authorOutboxRelays + taggedUserInboxRelays + channelRelays + replyRelays
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun broadcast(note: Note) {
|
fun broadcast(note: Note) {
|
||||||
@@ -1735,37 +1730,8 @@ class Account(
|
|||||||
cache.getOrAddAliasNote(wrap.id, mineNote)
|
cache.getOrAddAliasNote(wrap.id, mineNote)
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiver = wrap.recipientPubKey()
|
val relayList = computeRelayListToBroadcast(wrap)
|
||||||
if (receiver != null) {
|
client.send(wrap, relayList)
|
||||||
val relayList =
|
|
||||||
(
|
|
||||||
cache
|
|
||||||
.getAddressableNoteIfExists(ChatMessageRelayListEvent.createAddressTag(receiver))
|
|
||||||
?.event as? ChatMessageRelayListEvent
|
|
||||||
)?.relays()?.ifEmpty { null }?.toSet()
|
|
||||||
|
|
||||||
if (relayList != null) {
|
|
||||||
client.send(event = wrap, relayList = relayList)
|
|
||||||
} else {
|
|
||||||
val taggedUserInboxRelays =
|
|
||||||
wrap.taggedUserIds().flatMapTo(mutableSetOf()) { pubkey ->
|
|
||||||
if (pubkey == userProfile().pubkeyHex) {
|
|
||||||
notificationRelays.flow.value
|
|
||||||
} else {
|
|
||||||
LocalCache
|
|
||||||
.getUserIfExists(pubkey)
|
|
||||||
?.inboxRelays()
|
|
||||||
?.ifEmpty { null }
|
|
||||||
?.toSet()
|
|
||||||
?: cache.relayHints.hintsForKey(pubkey).toSet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client.send(wrap, taggedUserInboxRelays)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
client.send(wrap, outboxRelays.flow.value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user