From eb36489094fa78df0507694fd879d9917c9e3bfa Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 5 Dec 2024 17:55:59 -0500 Subject: [PATCH] Adds basic support for RelationshipStatus to Quartz --- .../amethyst/model/LocalCache.kt | 9 ++ .../service/NostrSingleUserDataSource.kt | 3 +- .../quartz/events/EventFactory.kt | 1 + .../quartz/events/RelationshipStatusEvent.kt | 83 +++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 quartz/src/main/java/com/vitorpamplona/quartz/events/RelationshipStatusEvent.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index dc6f74c66..25de3555e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -114,6 +114,7 @@ import com.vitorpamplona.quartz.events.PrivateOutboxRelayListEvent import com.vitorpamplona.quartz.events.ProfileGalleryEntryEvent import com.vitorpamplona.quartz.events.ReactionEvent import com.vitorpamplona.quartz.events.RecommendRelayEvent +import com.vitorpamplona.quartz.events.RelationshipStatusEvent import com.vitorpamplona.quartz.events.RelaySetEvent import com.vitorpamplona.quartz.events.ReportEvent import com.vitorpamplona.quartz.events.RepostEvent @@ -869,6 +870,13 @@ object LocalCache { } } + fun consume( + event: RelationshipStatusEvent, + relay: Relay?, + ) { + consumeBaseReplaceable(event, relay) + } + fun consume( event: OtsEvent, relay: Relay?, @@ -2444,6 +2452,7 @@ object LocalCache { is PollNoteEvent -> consume(event, relay) is ReactionEvent -> consume(event) is RecommendRelayEvent -> consume(event) + is RelationshipStatusEvent -> consume(event, relay) is RelaySetEvent -> consume(event, relay) is ReportEvent -> consume(event, relay) is RepostEvent -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt index a9a362cb2..404fd70ab 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt @@ -28,6 +28,7 @@ import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent import com.vitorpamplona.quartz.events.ChatMessageRelayListEvent import com.vitorpamplona.quartz.events.MetadataEvent +import com.vitorpamplona.quartz.events.RelationshipStatusEvent import com.vitorpamplona.quartz.events.ReportEvent import com.vitorpamplona.quartz.events.StatusEvent @@ -71,7 +72,7 @@ object NostrSingleUserDataSource : AmethystNostrDataSource("SingleUserFeed") { types = EVENT_FINDER_TYPES, filter = SincePerRelayFilter( - kinds = listOf(MetadataEvent.KIND, StatusEvent.KIND, AdvertisedRelayListEvent.KIND, ChatMessageRelayListEvent.KIND), + kinds = listOf(MetadataEvent.KIND, StatusEvent.KIND, RelationshipStatusEvent.KIND, AdvertisedRelayListEvent.KIND, ChatMessageRelayListEvent.KIND), authors = groupIds, since = minEOSEs, ), diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt index 065b3b25e..3d9b0e58e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/EventFactory.kt @@ -128,6 +128,7 @@ class EventFactory { PrivateOutboxRelayListEvent.KIND -> PrivateOutboxRelayListEvent(id, pubKey, createdAt, tags, content, sig) ReactionEvent.KIND -> ReactionEvent(id, pubKey, createdAt, tags, content, sig) RecommendRelayEvent.KIND -> RecommendRelayEvent(id, pubKey, createdAt, tags, content, sig) + RelationshipStatusEvent.KIND -> RelationshipStatusEvent(id, pubKey, createdAt, tags, content, sig) RelayAuthEvent.KIND -> RelayAuthEvent(id, pubKey, createdAt, tags, content, sig) RelaySetEvent.KIND -> RelaySetEvent(id, pubKey, createdAt, tags, content, sig) ReportEvent.KIND -> ReportEvent(id, pubKey, createdAt, tags, content, sig) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/RelationshipStatusEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/RelationshipStatusEvent.kt new file mode 100644 index 000000000..e96df12e5 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/RelationshipStatusEvent.kt @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2024 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.events + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.signers.NostrSigner +import com.vitorpamplona.quartz.utils.TimeUtils + +@Immutable +class RelationshipStatusEvent( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + tags: Array>, + content: String, + sig: HexKey, +) : PrivateTagArrayEvent(id, pubKey, createdAt, KIND, tags, content, sig) { + companion object { + const val KIND = 30382 + const val ALT = "Relationship Status" + + const val EDITS_PREFERENCE = "edits-pref" + const val PETNAME = "petname" + const val SUMMARY = "summary" + + private fun create( + content: String, + tags: Array>, + signer: NostrSigner, + createdAt: Long = TimeUtils.now(), + onReady: (RelationshipStatusEvent) -> Unit, + ) { + val newTags = + if (tags.any { it.size > 1 && it[0] == "alt" }) { + tags + } else { + tags + arrayOf("alt", ALT) + } + + signer.sign(createdAt, KIND, newTags, content, onReady) + } + + fun create( + targetUser: HexKey, + petname: String? = null, + summary: String? = null, + signer: NostrSigner, + createdAt: Long = TimeUtils.now(), + onReady: (RelationshipStatusEvent) -> Unit, + ) { + val tags = mutableListOf>() + tags.add(arrayOf("d", targetUser)) + tags.add(arrayOf("alt", ALT)) + + val privateTags = mutableListOf>() + petname?.let { privateTags.add(arrayOf(PETNAME, it)) } + summary?.let { privateTags.add(arrayOf(SUMMARY, it)) } + + encryptTags(privateTags.toTypedArray(), signer) { content -> + signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady) + } + } + } +}