diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index d6091f0a1..5907b79d1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -85,8 +85,10 @@ import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.isTaggedAddressableNote +import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.tags.events.isTaggedEvent import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohash import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes @@ -1001,7 +1003,7 @@ class Account( hashtags = (listEvent.hashtags() + listEvent.filterHashtags(privateTagList)).toSet(), geotags = (listEvent.geohashes() + listEvent.filterGeohashes(privateTagList)).toSet(), addresses = - (listEvent.taggedAddresses() + listEvent.filterAddresses(privateTagList)) + (listEvent.taggedATags() + listEvent.filterATags(privateTagList)) .map { it.toTag() } .toSet(), ), @@ -1124,7 +1126,9 @@ class Account( fun getEmojiPackSelectionFlow(): StateFlow = getEmojiPackSelectionNote().flow().metadata.stateFlow - fun getEmojiPackSelectionNote(): AddressableNote = LocalCache.getOrCreateAddressableNote(EmojiPackSelectionEvent.createAddressATag(userProfile().pubkeyHex)) + fun getEmojiPackSelectionAddress() = EmojiPackSelectionEvent.createAddress(userProfile().pubkeyHex) + + fun getEmojiPackSelectionNote(): AddressableNote = LocalCache.getOrCreateAddressableNote(getEmojiPackSelectionAddress()) fun convertEmojiSelectionPack(selection: EmojiPackSelectionEvent?): List>? = selection?.taggedAddresses()?.map { @@ -1849,7 +1853,7 @@ class Account( val contactList = userProfile().latestContactList if (contactList != null) { - ContactListEvent.followAddressableEvent(contactList, community.address, signer) { + ContactListEvent.followAddressableEvent(contactList, community.toATag(), signer) { Amethyst.instance.client.send(it) LocalCache.justConsume(it, null) } @@ -1862,7 +1866,7 @@ class Account( followUsers = emptyList(), followTags = emptyList(), followGeohashes = emptyList(), - followCommunities = listOf(community.address), + followCommunities = listOf(community.toATag()), followEvents = DefaultChannels.toList(), relayUse = relays, signer = signer, @@ -2008,7 +2012,7 @@ class Account( if (contactList != null && contactList.tags.isNotEmpty()) { ContactListEvent.unfollowAddressableEvent( contactList, - community.address, + community.toATag(), signer, onReady = this::onNewEventCreated, ) @@ -2860,7 +2864,7 @@ class Account( if (note is AddressableNote) { BookmarkListEvent.addReplaceable( userProfile().latestBookmarkList, - note.address, + note.toATag(), isPrivate, signer, ) { @@ -2891,7 +2895,7 @@ class Account( if (note is AddressableNote) { BookmarkListEvent.removeReplaceable( bookmarks, - note.address, + note.toATag(), isPrivate, signer, ) { @@ -2954,7 +2958,7 @@ class Account( } if (note is AddressableNote) { - userProfile().latestBookmarkList?.privateTaggedAddresses(signer) { + userProfile().latestBookmarkList?.privateAddress(signer) { onReady(it.contains(note.address)) } } else { @@ -2968,40 +2972,19 @@ class Account( if (!isWriteable()) return false if (note is AddressableNote) { - return userProfile().latestBookmarkList?.taggedAddresses()?.contains(note.address) == true + return userProfile().latestBookmarkList?.isTaggedAddressableNote(note.idHex) == true } else { - return userProfile().latestBookmarkList?.taggedEventIds()?.contains(note.idHex) == true + return userProfile().latestBookmarkList?.isTaggedEvent(note.idHex) == true } } - fun getAppSpecificDataNote(): AddressableNote { - val aTag = AppSpecificDataEvent.createTag(userProfile().pubkeyHex, APP_SPECIFIC_DATA_D_TAG) - return LocalCache.getOrCreateAddressableNote(aTag) - } + fun getAppSpecificDataNote() = LocalCache.getOrCreateAddressableNote(AppSpecificDataEvent.createAddress(userProfile().pubkeyHex, APP_SPECIFIC_DATA_D_TAG)) fun getAppSpecificDataFlow(): StateFlow = getAppSpecificDataNote().flow().metadata.stateFlow - fun getBlockListNote(): AddressableNote { - val aTag = - ATag( - PeopleListEvent.KIND, - userProfile().pubkeyHex, - PeopleListEvent.BLOCK_LIST_D_TAG, - null, - ) - return LocalCache.getOrCreateAddressableNote(aTag) - } + fun getBlockListNote() = LocalCache.getOrCreateAddressableNote(PeopleListEvent.createBlockAddress(userProfile().pubkeyHex)) - fun getMuteListNote(): AddressableNote { - val aTag = - ATag( - MuteListEvent.KIND, - userProfile().pubkeyHex, - "", - null, - ) - return LocalCache.getOrCreateAddressableNote(aTag) - } + fun getMuteListNote() = LocalCache.getOrCreateAddressableNote(MuteListEvent.createAddress(userProfile().pubkeyHex)) fun getMuteListFlow(): StateFlow = getMuteListNote().flow().metadata.stateFlow @@ -3345,10 +3328,7 @@ class Account( ) } - fun getDMRelayListNote(): AddressableNote = - LocalCache.getOrCreateAddressableNote( - ChatMessageRelayListEvent.createAddressATag(signer.pubKey), - ) + fun getDMRelayListNote(): AddressableNote = LocalCache.getOrCreateAddressableNote(ChatMessageRelayListEvent.createAddress(signer.pubKey)) fun getDMRelayListFlow(): StateFlow = getDMRelayListNote().flow().metadata.stateFlow @@ -3380,7 +3360,7 @@ class Account( fun getPrivateOutboxRelayListNote(): AddressableNote = LocalCache.getOrCreateAddressableNote( - PrivateOutboxRelayListEvent.createAddressATag(signer.pubKey), + PrivateOutboxRelayListEvent.createAddress(signer.pubKey), ) fun getPrivateOutboxRelayListFlow(): StateFlow = getPrivateOutboxRelayListNote().flow().metadata.stateFlow @@ -3414,7 +3394,7 @@ class Account( fun getSearchRelayListNote(): AddressableNote = LocalCache.getOrCreateAddressableNote( - SearchRelayListEvent.createAddressATag(signer.pubKey), + SearchRelayListEvent.createAddress(signer.pubKey), ) fun getSearchRelayListFlow(): StateFlow = getSearchRelayListNote().flow().metadata.stateFlow @@ -3448,7 +3428,7 @@ class Account( fun getNIP65RelayListNote(pubkey: HexKey = signer.pubKey): AddressableNote = LocalCache.getOrCreateAddressableNote( - AdvertisedRelayListEvent.createAddressATag(pubkey), + AdvertisedRelayListEvent.createAddress(pubkey), ) fun getNIP65RelayListFlow(pubkey: HexKey = signer.pubKey): StateFlow = getNIP65RelayListNote(pubkey).flow().metadata.stateFlow @@ -3484,13 +3464,13 @@ class Account( fun getFileServersListFlow(): StateFlow = getFileServersNote().flow().metadata.stateFlow - fun getFileServersNote(): AddressableNote = LocalCache.getOrCreateAddressableNote(FileServersEvent.createAddressATag(userProfile().pubkeyHex)) + fun getFileServersNote(): AddressableNote = LocalCache.getOrCreateAddressableNote(FileServersEvent.createAddress(userProfile().pubkeyHex)) fun getBlossomServersList(): BlossomServersEvent? = getBlossomServersNote().event as? BlossomServersEvent fun getBlossomServersListFlow(): StateFlow = getBlossomServersNote().flow().metadata.stateFlow - fun getBlossomServersNote(): AddressableNote = LocalCache.getOrCreateAddressableNote(BlossomServersEvent.createAddressATag(userProfile().pubkeyHex)) + fun getBlossomServersNote(): AddressableNote = LocalCache.getOrCreateAddressableNote(BlossomServersEvent.createAddress(userProfile().pubkeyHex)) fun host(url: String): String = try { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt index 09f4b9527..ded1755e6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Channel.kt @@ -32,6 +32,8 @@ import com.vitorpamplona.ammolite.relays.Relay import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address +import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress import com.vitorpamplona.quartz.nip19Bech32.toNAddr import com.vitorpamplona.quartz.nip19Bech32.toNEvent import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent @@ -81,11 +83,11 @@ class PublicChatChannel( @Stable class LiveActivitiesChannel( - val address: ATag, -) : Channel(address.toTag()) { + val address: Address, +) : Channel(address.toValue()) { var info: LiveActivitiesEvent? = null - override fun idNote() = address.toNAddr() + override fun idNote() = toNAddr() override fun idDisplayNote() = idNote().toShortenHex() @@ -93,6 +95,8 @@ class LiveActivitiesChannel( override fun relays() = info?.allRelayUrls() ?: super.relays() + fun relayHintUrl() = relays().firstOrNull() + fun updateChannelInfo( creator: User, channelInfo: LiveActivitiesEvent, @@ -112,6 +116,10 @@ class LiveActivitiesChannel( listOfNotNull(info?.title(), info?.summary()) .filter { it.contains(prefix, true) } .isNotEmpty() + + fun toNAddr() = NAddress.create(address.kind, address.pubKeyHex, address.dTag, relayHintUrl()) + + fun toATag() = ATag(address, relayHintUrl()) } data class Counter( @@ -167,6 +175,15 @@ abstract class Channel( } } + fun addRelay(relay: Relay) { + val counter = relays[relay.brief] + if (counter != null) { + counter.number++ + } else { + addRelaySync(relay.brief) + } + } + fun addNote( note: Note, relay: Relay? = null, @@ -178,12 +195,7 @@ abstract class Channel( } if (relay != null) { - val counter = relays[relay.brief] - if (counter != null) { - counter.number++ - } else { - addRelaySync(relay.brief) - } + addRelay(relay) } } 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 3f7623439..51047d5fc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -55,6 +55,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.tagValueContains import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.addressables.mapTaggedAddress import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses import com.vitorpamplona.quartz.nip01Core.tags.events.ETag @@ -275,6 +276,8 @@ object LocalCache { fun getAddressableNoteIfExists(key: String): AddressableNote? = addressables.get(key) + fun getAddressableNoteIfExists(address: Address): AddressableNote? = getAddressableNoteIfExists(address.toValue()) + fun getNoteIfExists(key: String): Note? = addressables.get(key) ?: notes.get(key) fun getNoteIfExists(key: ETag): Note? = notes.get(key.eventId) @@ -290,7 +293,7 @@ object LocalCache { fun getOrCreateNote(event: Event): Note = if (event is AddressableEvent) { - getOrCreateAddressableNote(event.aTag()) + getOrCreateAddressableNote(event.address()) } else { getOrCreateNote(event.id) } @@ -304,8 +307,6 @@ object LocalCache { return null } - fun checkGetOrCreateNote(atag: ATag) = getOrCreateAddressableNote(atag) - fun checkGetOrCreateNote(key: String): Note? { checkNotInMainThread() @@ -371,9 +372,10 @@ object LocalCache { if (isValidHex(key)) { return channels.getOrCreate(key) { PublicChatChannel(key) } } - val aTag = ATag.parse(key, null) - if (aTag != null) { - return channels.getOrCreate(aTag.toTag()) { LiveActivitiesChannel(aTag) } + + val address = Address.parse(key) + if (address != null) { + return channels.getOrCreate(address.toValue()) { LiveActivitiesChannel(address) } } return null } @@ -387,7 +389,7 @@ object LocalCache { fun checkGetOrCreateAddressableNote(key: String): AddressableNote? = try { - val addr = ATag.parse(key, null) // relay doesn't matter for the index. + val addr = Address.parse(key) if (addr != null) { getOrCreateAddressableNote(addr) } else { @@ -398,17 +400,12 @@ object LocalCache { null } - fun getOrCreateAddressableNoteInternal(key: ATag): AddressableNote { - // checkNotInMainThread() - - // we can't use naddr here because naddr might include relay info and - // the preferred relay should not be part of the index. - return addressables.getOrCreate(key.toTag()) { + fun getOrCreateAddressableNoteInternal(key: Address): AddressableNote = + addressables.getOrCreate(key.toValue()) { AddressableNote(key) } - } - fun getOrCreateAddressableNote(key: ATag): AddressableNote { + fun getOrCreateAddressableNote(key: Address): AddressableNote { val note = getOrCreateAddressableNoteInternal(key) // Loads the user outside a Syncronized block to avoid blocking if (note.author == null) { @@ -598,7 +595,7 @@ object LocalCache { relay: Relay?, ) { val version = getOrCreateNote(event.id) - val note = getOrCreateAddressableNote(event.aTag()) + val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) if (version.event == null) { @@ -632,7 +629,7 @@ object LocalCache { relay: Relay?, ) { val version = getOrCreateNote(event.id) - val note = getOrCreateAddressableNote(event.aTag()) + val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) if (version.event == null) { @@ -693,7 +690,7 @@ object LocalCache { event.taggedAddresses().map { getOrCreateAddressableNote(it) } is CommunityPostApprovalEvent -> event.approvedEvents().mapNotNull { checkGetOrCreateNote(it) } + - event.approvedAddresses().map { checkGetOrCreateNote(it) } + event.approvedAddresses().map { getOrCreateAddressableNote(it) } is ReactionEvent -> event.originalPost().mapNotNull { checkGetOrCreateNote(it) } + event.taggedAddresses().map { getOrCreateAddressableNote(it) } @@ -730,7 +727,7 @@ object LocalCache { relay: Relay?, ) { val version = getOrCreateNote(event.id) - val note = getOrCreateAddressableNote(event.aTag()) + val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) if (version.event == null) { @@ -743,9 +740,11 @@ object LocalCache { if (event.createdAt > (note.createdAt() ?: 0)) { note.loadEvent(event, author, emptyList()) - val channel = - getOrCreateChannel(note.idHex) { LiveActivitiesChannel(note.address) } - as? LiveActivitiesChannel + val channel = getOrCreateChannel(note.idHex) { LiveActivitiesChannel(note.address) } as? LiveActivitiesChannel + + if (relay != null) { + channel?.addRelay(relay) + } val creator = event.host()?.let { checkGetOrCreateUser(it.pubKey) } ?: author @@ -900,7 +899,7 @@ object LocalCache { relay: Relay?, ) { val version = getOrCreateNote(event.id) - val note = getOrCreateAddressableNote(event.aTag()) + val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) if (version.event == null) { @@ -957,7 +956,7 @@ object LocalCache { fun consume(event: BadgeProfilesEvent) { val version = getOrCreateNote(event.id) - val note = getOrCreateAddressableNote(event.aTag()) + val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) if (version.event == null) { @@ -1029,7 +1028,7 @@ object LocalCache { relay: Relay?, ) { val version = getOrCreateNote(event.id) - val note = getOrCreateAddressableNote(event.aTag()) + val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) val replyTos = computeReplyTo(event) @@ -1131,7 +1130,7 @@ object LocalCache { } } - val addressList = event.deleteAddressTags() + val addressList = event.deleteAddressIds() val addressSet = addressList.toSet() addressList @@ -1296,7 +1295,7 @@ object LocalCache { val author = getOrCreateUser(event.pubKey) - val communities = event.communities() + val communities = event.communityAddresses() val eventsApproved = computeReplyTo(event) val repliesTo = communities.map { getOrCreateAddressableNote(it) } @@ -1470,9 +1469,9 @@ object LocalCache { event: LiveActivitiesChatMessageEvent, relay: Relay?, ) { - val activityId = event.activity() ?: return + val activityAddress = event.activityAddress() ?: return - val channel = getOrCreateChannel(activityId.toTag()) { LiveActivitiesChannel(activityId) } + val channel = getOrCreateChannel(activityAddress.toValue()) { LiveActivitiesChannel(activityAddress) } val note = getOrCreateNote(event.id) channel.addNote(note, relay) @@ -2348,7 +2347,7 @@ object LocalCache { draftWrap: DraftEvent, draft: Event, ) { - val note = getOrCreateAddressableNote(draftWrap.aTag()) + val note = getOrCreateAddressableNote(draftWrap.address()) val author = getOrCreateUser(draftWrap.pubKey) when (draft) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 3d370479c..5d1f1d9db 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -46,6 +46,7 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference import com.vitorpamplona.quartz.nip01Core.tags.hashtags.anyHashTag @@ -54,6 +55,7 @@ import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent import com.vitorpamplona.quartz.nip19Bech32.toNAddr import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent @@ -85,11 +87,11 @@ import kotlin.coroutines.resume @Stable class AddressableNote( - val address: ATag, -) : Note(address.toTag()) { - override fun idNote() = address.toNAddr(relayHintUrl()) + val address: Address, +) : Note(address.toValue()) { + override fun idNote() = toNAddr() - override fun toNEvent() = address.toNAddr(relayHintUrl()) + override fun toNEvent() = toNAddr() override fun idDisplayNote() = idNote().toShortenHex() @@ -108,13 +110,15 @@ class AddressableNote( override fun wasOrShouldBeDeletedBy( deletionEvents: Set, - deletionAddressables: Set, + deletionAddressables: Set
, ): Boolean { val thisEvent = event return deletionAddressables.contains(address) || (thisEvent != null && deletionEvents.contains(thisEvent.id)) } - override fun toATag() = ATag.parse(idHex, relayHintUrl()) + fun toNAddr() = NAddress.create(address.kind, address.pubKeyHex, address.dTag, relayHintUrl()) + + fun toATag() = ATag(address, relayHintUrl()) } @Stable @@ -211,7 +215,7 @@ open class Note( null } - open fun address(): ATag? = null + open fun address(): Address? = null open fun createdAt() = event?.createdAt @@ -915,10 +919,10 @@ open class Note( open fun wasOrShouldBeDeletedBy( deletionEvents: Set, - deletionAddressables: Set, + deletionAddressables: Set
, ): Boolean { val thisEvent = event - return deletionEvents.contains(idHex) || (thisEvent is AddressableEvent && deletionAddressables.contains(thisEvent.aTag())) + return deletionEvents.contains(idHex) || (thisEvent is AddressableEvent && deletionAddressables.contains(thisEvent.address())) } fun toETag(): ETag { @@ -950,15 +954,6 @@ open class Note( MarkedETag(idHex, relayHintUrl(), marker, author?.pubkeyHex) } } - - open fun toATag(): ATag? { - val noteEvent = event - return if (noteEvent is AddressableEvent) { - ATag(noteEvent.kind, noteEvent.pubKey, noteEvent.dTag(), relayHintUrl()) - } else { - null - } - } } @Stable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt index b89437a33..0a7b9e5b0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.model import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent import com.vitorpamplona.quartz.nip18Reposts.RepostEvent import kotlinx.collections.immutable.ImmutableSet @@ -132,7 +132,7 @@ class ThreadAssembler { } class OnlyLatestVersionSet : MutableSet { - val map = hashMapOf() + val map = hashMapOf() val set = hashSetOf() override fun add(element: Note): Boolean { @@ -142,14 +142,14 @@ class OnlyLatestVersionSet : MutableSet { return if (element is AddressableNote && loadedCreatedAt != null) { innerAdd(element.address, element, loadedCreatedAt) } else if (noteEvent is AddressableEvent && loadedCreatedAt != null) { - innerAdd(noteEvent.aTag(), element, loadedCreatedAt) + innerAdd(noteEvent.address(), element, loadedCreatedAt) } else { set.add(element) } } private fun innerAdd( - address: ATag, + address: Address, element: Note, loadedCreatedAt: Long, ): Boolean { @@ -193,7 +193,7 @@ class OnlyLatestVersionSet : MutableSet { element.address()?.let { map.remove(it) } - (element.event as? AddressableEvent)?.aTag()?.let { + (element.event as? AddressableEvent)?.address()?.let { map.remove(it) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt index a7c5ce451..70e74ee5b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrCommunityDataSource.kt @@ -50,7 +50,7 @@ object NostrCommunityDataSource : AmethystNostrDataSource("SingleCommunityFeed") authors = authors, tags = mapOf( - "a" to listOf(myCommunityToWatch.address.toTag()), + "a" to listOf(myCommunityToWatch.address.toValue()), ), kinds = listOf(CommunityPostApprovalEvent.KIND), limit = 500, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt index a62e423dd..7ba8259da 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt @@ -81,7 +81,7 @@ object NostrSingleEventDataSource : AmethystNostrDataSource("SingleEventFeed") { CommunityPostApprovalEvent.KIND, LiveActivitiesChatMessageEvent.KIND, ), - tags = mapOf("a" to it.mapNotNull { it.address()?.toTag() }), + tags = mapOf("a" to it.mapNotNull { it.address()?.toValue() }), since = findMinimumEOSEs(it), // Max amount of "replies" to download on a specific event. limit = 1000, @@ -95,7 +95,7 @@ object NostrSingleEventDataSource : AmethystNostrDataSource("SingleEventFeed") { listOf( DeletionEvent.KIND, ), - tags = mapOf("a" to it.mapNotNull { it.address()?.toTag() }), + tags = mapOf("a" to it.mapNotNull { it.address()?.toValue() }), since = findMinimumEOSEs(it), // Max amount of "replies" to download on a specific event. limit = 10, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt index dc8af5447..3f5be7875 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt @@ -792,11 +792,7 @@ open class NewPostViewModel : ViewModel() { imetas(usedAttachments) } } else { - if (channel.address.relay == null) { - channel.address.relay = channelRelays.firstOrNull() ?: replyingToEvent?.relay - } - - LiveActivitiesChatMessageEvent.message(tagger.message, channel.address) { + LiveActivitiesChatMessageEvent.message(tagger.message, channel.toATag()) { tagger.pTags?.let { notify(it.map { it.toPTag() }) } hashtags(findHashtags(tagger.message)) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt index e5584738e..6737d99be 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverCommunityFeedFilter.kt @@ -23,8 +23,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag -import com.vitorpamplona.quartz.nip19Bech32.parseAtagUnckecked +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip51Lists.MuteListEvent import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent @@ -54,7 +53,7 @@ open class DiscoverCommunityFeedFilter( val notes = LocalCache.addressables.mapNotNullIntoSet { key, note -> val noteEvent = note.event - if (noteEvent == null && shouldInclude(ATag.parseAtagUnckecked(key), filterParams)) { + if (noteEvent == null && shouldInclude(Address.parse(key), filterParams)) { // send unloaded communities to the screen note } else if (noteEvent is CommunityDefinitionEvent && filterParams.match(noteEvent)) { @@ -86,7 +85,7 @@ open class DiscoverCommunityFeedFilter( if (noteEvent is CommunityDefinitionEvent && filterParams.match(noteEvent)) { listOf(note) } else if (noteEvent is CommunityPostApprovalEvent) { - noteEvent.communities().mapNotNull { + noteEvent.communityAddresses().mapNotNull { val definitionNote = LocalCache.getOrCreateAddressableNote(it) val definitionEvent = definitionNote.event @@ -106,7 +105,7 @@ open class DiscoverCommunityFeedFilter( } private fun shouldInclude( - aTag: ATag?, + aTag: Address?, params: FilterByListParams, ) = aTag != null && aTag.kind == CommunityDefinitionEvent.KIND && params.match(aTag) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt index 49e3e5715..4f3d850b5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt @@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.AROUND_ME import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.quartz.nip01Core.core.Event -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.addressables.isTaggedAddressableNotes import com.vitorpamplona.quartz.nip01Core.tags.geohash.isTaggedGeoHashes import com.vitorpamplona.quartz.nip01Core.tags.hashtags.isTaggedHashes @@ -68,10 +68,10 @@ class FilterByListParams( } } - fun isATagInList(aTag: ATag): Boolean { + fun isAuthorInFollows(address: Address): Boolean { if (followLists == null) return false - return aTag.pubKeyHex in followLists.authors + return address.pubKeyHex in followLists.authors } fun match( @@ -81,10 +81,10 @@ class FilterByListParams( (isHiddenList || isNotHidden(noteEvent.pubKey)) && isNotInTheFuture(noteEvent) - fun match(aTag: ATag?) = - aTag != null && - (isGlobal || isATagInList(aTag)) && - (isHiddenList || isNotHidden(aTag.pubKeyHex)) + fun match(address: Address?) = + address != null && + (isGlobal || isAuthorInFollows(address)) && + (isHiddenList || isNotHidden(address.pubKeyHex)) companion object { fun showHiddenKey( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt index a6b515f5b..af5b729fc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/UserProfileAppRecommendationsFeedFilter.kt @@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent class UserProfileAppRecommendationsFeedFilter( @@ -48,7 +47,7 @@ class UserProfileAppRecommendationsFeedFilter( val noteEvent = it.event if (noteEvent is AppRecommendationEvent) { if (noteEvent.pubKey == user.pubkeyHex) { - return noteEvent.recommendations().map { LocalCache.getOrCreateAddressableNote(ATag(it.address)) } + return noteEvent.recommendations().map { LocalCache.getOrCreateAddressableNote(it.address) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt index 817aeb1ec..c7f924a69 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt @@ -113,7 +113,7 @@ import com.vitorpamplona.amethyst.ui.theme.profileContentHeaderModifier import com.vitorpamplona.amethyst.ui.tor.ConnectTorDialog import com.vitorpamplona.ammolite.relays.RelayPoolStatus import com.vitorpamplona.quartz.nip01Core.HexKey -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip02FollowList.ImmutableListOfLists @Composable @@ -278,7 +278,7 @@ private fun EditStatusBoxes( @Composable fun StatusEditBar( savedStatus: String? = null, - tag: ATag? = null, + address: Address? = null, accountViewModel: AccountViewModel, nav: INav, ) { @@ -311,10 +311,10 @@ fun StatusEditBar( keyboardActions = KeyboardActions( onSend = { - if (tag == null) { + if (address == null) { accountViewModel.createStatus(currentStatus.value) } else { - accountViewModel.updateStatus(tag, currentStatus.value) + accountViewModel.updateStatus(address, currentStatus.value) } focusManager.clearFocus(true) @@ -324,17 +324,17 @@ fun StatusEditBar( trailingIcon = { if (hasChanged.value) { SendButton { - if (tag == null) { + if (address == null) { accountViewModel.createStatus(currentStatus.value) } else { - accountViewModel.updateStatus(tag, currentStatus.value) + accountViewModel.updateStatus(address, currentStatus.value) } focusManager.clearFocus(true) } } else { - if (tag != null) { + if (address != null) { UserStatusDeleteButton { - accountViewModel.deleteStatus(tag) + accountViewModel.deleteStatus(address) focusManager.clearFocus(true) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt index 556b522d4..b49180a09 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Loaders.kt @@ -39,7 +39,7 @@ import com.vitorpamplona.amethyst.service.CachedGeoLocations import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.equalImmutableLists -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.Dispatchers @@ -112,20 +112,20 @@ fun LoadAddressableNote( @Composable fun LoadAddressableNote( - aTag: ATag, + address: Address, accountViewModel: AccountViewModel, content: @Composable (AddressableNote?) -> Unit, ) { var note by - remember(aTag) { - mutableStateOf(accountViewModel.getAddressableNoteIfExists(aTag.toTag())) + remember(address) { + mutableStateOf(accountViewModel.getAddressableNoteIfExists(address.toValue())) } if (note == null) { - LaunchedEffect(key1 = aTag) { + LaunchedEffect(key1 = address) { val newNote = withContext(Dispatchers.IO) { - accountViewModel.getOrCreateAddressableNote(aTag) + accountViewModel.getOrCreateAddressableNote(address) } if (note != newNote) { note = newNote diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index 78f5b10e0..f0a477015 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -73,7 +73,7 @@ import com.vitorpamplona.amethyst.ui.theme.lessImportantLink import com.vitorpamplona.amethyst.ui.theme.nip05 import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.addressables.firstTaggedAddress import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent @@ -276,7 +276,7 @@ fun DisplayStatusInner( content: String, type: String, url: String?, - nostrATag: ATag?, + nostrATag: Address?, nostrETag: ETag?, accountViewModel: AccountViewModel, nav: INav, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index 7aec26e14..49c617e1c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -125,13 +125,13 @@ val njumpLink = { nip19BechAddress: String -> val externalLinkForNote = { note: Note -> if (note is AddressableNote) { if (note.event?.bountyBaseReward() != null) { - "https://nostrbounties.com/b/${note.address().toNAddr()}" + "https://nostrbounties.com/b/${note.toNAddr()}" } else if (note.event is PeopleListEvent) { - "https://listr.lol/a/${note.address().toNAddr()}" + "https://listr.lol/a/${note.toNAddr()}" } else if (note.event is AudioTrackEvent) { - "https://zapstr.live/?track=${note.address().toNAddr()}" + "https://zapstr.live/?track=${note.toNAddr()}" } else { - njumpLink(note.address().toNAddr()) + njumpLink(note.toNAddr()) } } else { if (note.event is FileHeaderEvent) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt index a6e229c3f..fa5a6bfb5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ShowEmojiSuggestionList.kt @@ -61,7 +61,7 @@ import kotlinx.coroutines.flow.Flow @Composable fun WatchAndLoadMyEmojiList(accountViewModel: AccountViewModel) { LoadAddressableNote( - EmojiPackSelectionEvent.createAddressATag(accountViewModel.userProfile().pubkeyHex), + EmojiPackSelectionEvent.createAddress(accountViewModel.userProfile().pubkeyHex), accountViewModel, ) { emptyNote -> emptyNote?.let { usersEmojiList -> @@ -73,7 +73,7 @@ fun WatchAndLoadMyEmojiList(accountViewModel: AccountViewModel) { .observeAsState((usersEmojiList.event as? EmojiPackSelectionEvent)?.taggedAddresses()?.toImmutableList()) collections?.forEach { - LoadAddressableNote(aTag = it, accountViewModel) { + LoadAddressableNote(it, accountViewModel) { it?.live()?.metadata?.observeAsState() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt index f157feeee..7730ba824 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt @@ -86,7 +86,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag @@ -340,13 +340,7 @@ private fun EmojiSelector( onClick: ((EmojiUrlTag) -> Unit)? = null, ) { LoadAddressableNote( - aTag = - ATag( - EmojiPackSelectionEvent.KIND, - accountViewModel.userProfile().pubkeyHex, - "", - null, - ), + accountViewModel.account.getEmojiPackSelectionAddress(), accountViewModel, ) { emptyNote -> emptyNote?.let { usersEmojiList -> @@ -369,7 +363,7 @@ private fun EmojiSelector( @Composable fun EmojiCollectionGallery( - emojiCollections: ImmutableList, + emojiCollections: ImmutableList
, accountViewModel: AccountViewModel, nav: INav, onClick: ((EmojiUrlTag) -> Unit)? = null, @@ -382,8 +376,8 @@ fun EmojiCollectionGallery( LazyColumn( state = listState, ) { - itemsIndexed(emojiCollections, key = { _, item -> item.toTag() }) { _, item -> - LoadAddressableNote(aTag = item, accountViewModel) { + itemsIndexed(emojiCollections, key = { _, item -> item }) { _, item -> + LoadAddressableNote(item, accountViewModel) { it?.let { WatchAndRenderNote(it, bgColor, accountViewModel, nav, onClick) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt index 54af94aca..5d734079e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt @@ -59,16 +59,13 @@ fun ShowForkInformation( val forkedAddress = remember(noteEvent) { noteEvent.forkFromAddress() } val forkedEvent = remember(noteEvent) { noteEvent.forkFromVersion() } if (forkedAddress != null) { - LoadAddressableNote( - aTag = forkedAddress, - accountViewModel = accountViewModel, - ) { addressableNote -> + LoadAddressableNote(forkedAddress, accountViewModel) { addressableNote -> if (addressableNote != null) { ForkInformationRowLightColor(addressableNote, modifier, accountViewModel, nav) } } } else if (forkedEvent != null) { - LoadNote(forkedEvent.eventId, accountViewModel = accountViewModel) { event -> + LoadNote(forkedEvent.eventId, accountViewModel) { event -> if (event != null) { ForkInformationRowLightColor(event, modifier, accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt index 239ae4656..708e3df98 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt @@ -56,11 +56,9 @@ import com.vitorpamplona.amethyst.ui.note.elements.RemoveButton import com.vitorpamplona.amethyst.ui.note.getGradient import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.Size35Modifier -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag import com.vitorpamplona.quartz.nip01Core.tags.addressables.isTaggedAddressableNote import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent -import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent import com.vitorpamplona.quartz.nip30CustomEmoji.taggedEmojis @Composable @@ -180,13 +178,7 @@ private fun EmojiListOptions( emojiPackNote: Note, ) { LoadAddressableNote( - aTag = - ATag( - EmojiPackSelectionEvent.KIND, - accountViewModel.userProfile().pubkeyHex, - "", - null, - ), + accountViewModel.account.getEmojiPackSelectionAddress(), accountViewModel, ) { it?.let { usersEmojiList -> diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt index 03e3304ca..17387b223 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Git.kt @@ -137,10 +137,10 @@ private fun RenderGitPatchEvent( accountViewModel: AccountViewModel, nav: INav, ) { - val repository = remember(noteEvent) { noteEvent.repository() } + val repository = remember(noteEvent) { noteEvent.repositoryAddress() } if (repository != null) { - LoadAddressableNote(aTag = repository, accountViewModel = accountViewModel) { + LoadAddressableNote(repository, accountViewModel) { if (it != null) { RenderShortRepositoryHeader(it, accountViewModel, nav) Spacer(modifier = DoubleVertSpacer) @@ -242,10 +242,10 @@ private fun RenderGitIssueEvent( accountViewModel: AccountViewModel, nav: INav, ) { - val repository = remember(noteEvent) { noteEvent.repository() } + val repository = remember(noteEvent) { noteEvent.repositoryAddress() } if (repository != null) { - LoadAddressableNote(aTag = repository, accountViewModel = accountViewModel) { + LoadAddressableNote(repository, accountViewModel) { if (it != null) { RenderShortRepositoryHeader(it, accountViewModel, nav) Spacer(modifier = DoubleVertSpacer) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt index b0f0c9c96..bfbe43494 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt @@ -54,7 +54,7 @@ import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.routeFor import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.firstTagValueFor -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent @@ -81,7 +81,7 @@ fun RenderHighlight( context = noteEvent.context(), authorHex = noteEvent.pubKey, url = noteEvent.inUrl(), - postAddress = noteEvent.inPost(), + postAddress = noteEvent.inPostAddress(), postVersion = noteEvent.inPostVersion(), makeItShort = makeItShort, canPreview = canPreview, @@ -99,7 +99,7 @@ fun DisplayHighlight( context: String?, authorHex: String?, url: String?, - postAddress: ATag?, + postAddress: Address?, postVersion: ETag?, makeItShort: Boolean, canPreview: Boolean, @@ -149,7 +149,7 @@ private fun DisplayQuoteAuthor( highlightQuote: String, authorHex: String?, baseUrl: String?, - postAddress: ATag?, + postAddress: Address?, postVersion: ETag?, accountViewModel: AccountViewModel, nav: INav, @@ -165,7 +165,7 @@ private fun DisplayQuoteAuthor( } var addressable by remember { - mutableStateOf(postAddress?.let { accountViewModel.getAddressableNoteIfExists(it.toTag()) }) + mutableStateOf(postAddress?.let { accountViewModel.getAddressableNoteIfExists(it) }) } if (addressable == null && postAddress != null) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt index 5237d3a03..e7bc61026 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/InteractiveStory.kt @@ -66,13 +66,13 @@ fun RenderInteractiveStory( val rootEvent = note.value?.note?.event as? InteractiveStoryBaseEvent ?: return // keep updating the reading state event with new versions - val readingStateNote = accountViewModel.getInteractiveStoryReadingState(address.toTag()) + val readingStateNote = accountViewModel.getInteractiveStoryReadingState(address.toValue()) val latestReadingNoteState = readingStateNote.live().metadata.observeAsState() val readingState = latestReadingNoteState.value?.note?.event as? InteractiveStoryReadingStateEvent val currentScene = readingState?.currentScene() - if (currentScene != null && currentScene != rootEvent.aTag()) { + if (currentScene != null && currentScene != rootEvent.address()) { LoadAddressableNote(currentScene, accountViewModel) { currentSceneBaseNote -> val currentScene = currentSceneBaseNote?.live()?.metadata?.observeAsState() val currentSceneEvent = currentScene?.value?.note?.event as? InteractiveStoryBaseEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt index b67dcf95e..8b0b10280 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RenderPostApproval.kt @@ -56,7 +56,7 @@ fun RenderPostApproval( val noteEvent = note.event as? CommunityPostApprovalEvent ?: return Column(Modifier.fillMaxWidth()) { - noteEvent.communities().forEach { tag -> + noteEvent.communityAddresses().forEach { tag -> LoadAddressableNote(tag, accountViewModel) { baseNote -> baseNote?.let { RenderCommunity( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt index c6bfd6c39..c98795a6f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FollowListState.kt @@ -127,7 +127,7 @@ class FollowListState( checkNotInMainThread() val hasNewList = - newNotes.any { + newNotes.any { it -> val noteEvent = it.event noteEvent?.pubKey == account.userProfile().pubkeyHex && diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index b9cbc1ef1..0c12b1f17 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -79,7 +79,7 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.people.PubKeyReferenceTag import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds @@ -987,17 +987,17 @@ class AccountViewModel( } fun updateStatus( - it: ATag, + address: Address, newStatus: String, ) { viewModelScope.launch(Dispatchers.IO) { - account.updateStatus(LocalCache.getOrCreateAddressableNote(it), newStatus) + account.updateStatus(LocalCache.getOrCreateAddressableNote(address), newStatus) } } - fun deleteStatus(it: ATag) { + fun deleteStatus(address: Address) { viewModelScope.launch(Dispatchers.IO) { - account.deleteStatus(LocalCache.getOrCreateAddressableNote(it)) + account.deleteStatus(LocalCache.getOrCreateAddressableNote(address)) } } @@ -1124,10 +1124,10 @@ class AccountViewModel( viewModelScope.launch(Dispatchers.IO) { onResult(checkGetOrCreateAddressableNote(key)) } } - suspend fun getOrCreateAddressableNote(key: ATag): AddressableNote = LocalCache.getOrCreateAddressableNote(key) + suspend fun getOrCreateAddressableNote(key: Address): AddressableNote = LocalCache.getOrCreateAddressableNote(key) fun getOrCreateAddressableNote( - key: ATag, + key: Address, onResult: (AddressableNote?) -> Unit, ) { viewModelScope.launch(Dispatchers.IO) { onResult(getOrCreateAddressableNote(key)) } @@ -1135,6 +1135,8 @@ class AccountViewModel( fun getAddressableNoteIfExists(key: String): AddressableNote? = LocalCache.getAddressableNoteIfExists(key) + fun getAddressableNoteIfExists(key: Address): AddressableNote? = LocalCache.getAddressableNoteIfExists(key) + suspend fun findStatusesForUser( myUser: User, onResult: (ImmutableList) -> Unit, @@ -1539,7 +1541,7 @@ class AccountViewModel( ): Note { val note = if (innerEvent is AddressableEvent) { - AddressableNote(innerEvent.aTag()) + AddressableNote(innerEvent.address()) } else { Note(innerEvent.id) } @@ -1598,14 +1600,14 @@ class AccountViewModel( AdvertisedRelayListEvent.createAddressTag(user.pubkeyHex), ) - fun getInteractiveStoryReadingState(dATag: String): AddressableNote = LocalCache.getOrCreateAddressableNote(InteractiveStoryReadingStateEvent.createAddressATag(account.signer.pubKey, dATag)) + fun getInteractiveStoryReadingState(dATag: String): AddressableNote = LocalCache.getOrCreateAddressableNote(InteractiveStoryReadingStateEvent.createAddress(account.signer.pubKey, dATag)) fun updateInteractiveStoryReadingState( root: InteractiveStoryBaseEvent, readingScene: InteractiveStoryBaseEvent, ) { viewModelScope.launch(Dispatchers.IO) { - val sceneNoteRelayHint = LocalCache.getOrCreateAddressableNote(readingScene.aTag()).relayHintUrl() + val sceneNoteRelayHint = LocalCache.getOrCreateAddressableNote(readingScene.address()).relayHintUrl() val readingState = getInteractiveStoryReadingState(root.addressTag()) val readingStateEvent = readingState.event as? InteractiveStoryReadingStateEvent @@ -1613,7 +1615,7 @@ class AccountViewModel( if (readingStateEvent != null) { account.updateInteractiveStoryReadingState(readingStateEvent, readingScene, sceneNoteRelayHint) } else { - val rootNoteRelayHint = LocalCache.getOrCreateAddressableNote(root.aTag()).relayHintUrl() + val rootNoteRelayHint = LocalCache.getOrCreateAddressableNote(root.address()).relayHintUrl() account.createInteractiveStoryReadingState(root, rootNoteRelayHint, readingScene, sceneNoteRelayHint) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt index a2d4e5ab6..38e95cb17 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chatrooms/ChannelScreen.kt @@ -486,11 +486,7 @@ private suspend fun innerSendPost( imetas(usedAttachments) } } else { - if (channel.address.relay == null) { - channel.address.relay = channelRelays.firstOrNull() ?: replyingToEvent?.relay - } - - LiveActivitiesChatMessageEvent.message(tagger.message, channel.address) { + LiveActivitiesChatMessageEvent.message(tagger.message, channel.toATag()) { hashtags(findHashtags(tagger.message)) references(findURLs(tagger.message)) quotes(findNostrUris(tagger.message)) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt index 2073699c1..4231abf3d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/ProfileScreen.kt @@ -176,7 +176,7 @@ import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.userProfileBorderModifier -import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList @@ -704,7 +704,7 @@ private fun BookmarkTabHeader(baseUser: User) { ( bookmarkList?.taggedEvents()?.count() ?: 0 - ) + (bookmarkList?.taggedAddresses()?.count() ?: 0) + ) + (bookmarkList?.taggedATags()?.count() ?: 0) if (newBookmarks != userBookmarks) { userBookmarks = newBookmarks @@ -1349,8 +1349,8 @@ private fun DisplayBadges( nav: INav, ) { LoadAddressableNote( - aTag = BadgeProfilesEvent.createAddressTag(baseUser.pubkeyHex), - accountViewModel = accountViewModel, + BadgeProfilesEvent.createAddress(baseUser.pubkeyHex), + accountViewModel, ) { note -> if (note != null) { WatchAndRenderBadgeList( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt index c067946cd..c16820c48 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt @@ -1004,7 +1004,7 @@ private fun RenderWikiHeaderForThread( } forkedAddress?.let { - LoadAddressableNote(aTag = it, accountViewModel = accountViewModel) { originalVersion -> + LoadAddressableNote(it, accountViewModel) { originalVersion -> if (originalVersion != null) { ForkInformationRow(originalVersion, Modifier.fillMaxWidth(), accountViewModel, nav) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomServersEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomServersEvent.kt index 822a634aa..2847cb4bc 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomServersEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/blossom/BlossomServersEvent.kt @@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -50,6 +51,8 @@ class BlossomServersEvent( const val KIND = 10063 const val ALT = "File servers used by the author" + fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) + fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null) fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/PrivateOutboxRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/PrivateOutboxRelayListEvent.kt index 74b069dc4..80340b407 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/PrivateOutboxRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/edits/PrivateOutboxRelayListEvent.kt @@ -29,6 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -102,6 +103,8 @@ class PrivateOutboxRelayListEvent( const val KIND = 10013 val TAGS = arrayOf(AltTag.assemble("Relay list to store private content from this author")) + fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) + fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null) fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/forks/BaseThreadedEventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/forks/BaseThreadedEventExt.kt index 45c97f641..af5f4e101 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/forks/BaseThreadedEventExt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/forks/BaseThreadedEventExt.kt @@ -21,7 +21,7 @@ package com.vitorpamplona.quartz.experimental.forks import com.vitorpamplona.quartz.nip01Core.HexKey -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag @@ -30,9 +30,7 @@ fun BaseThreadedEvent.isAFork() = tags.any { it.size > 3 && (it[0] == "a" || it[ fun BaseThreadedEvent.forkFromAddress() = tags.firstOrNull { it.size > 3 && it[0] == "a" && it[3] == "fork" }?.let { val aTagValue = it[1] - val relay = it.getOrNull(2) - - ATag.parse(aTagValue, relay) + Address.parse(aTagValue) } fun BaseThreadedEvent.forkFromVersion() = tags.firstNotNullOfOrNull(MarkedETag::parseFork) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt index c81c9ab4e..1ee7fab68 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt @@ -30,6 +30,7 @@ import com.vitorpamplona.quartz.nip01Core.core.builder import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag @@ -57,13 +58,18 @@ class InteractiveStoryReadingStateEvent( fun root() = tags.firstNotNullOfOrNull(RootSceneTag::parse) - fun currentScene() = tags.firstNotNullOfOrNull(ATag::parse) + fun currentScene() = tags.firstNotNullOfOrNull(ATag::parseAddress) companion object { const val KIND = 30298 const val ALT1 = "Interactive Story Reading state" const val ALT2 = "The reading state of " + fun createAddress( + pubKey: HexKey, + dtag: String, + ): Address = Address(KIND, pubKey, dtag) + fun createAddressATag( pubKey: HexKey, dtag: String, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/tags/StoryOptionTag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/tags/StoryOptionTag.kt index b4a5fabc9..6327c0527 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/tags/StoryOptionTag.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/interactiveStories/tags/StoryOptionTag.kt @@ -20,14 +20,16 @@ */ package com.vitorpamplona.quartz.experimental.interactiveStories.tags -import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address +import com.vitorpamplona.quartz.nip46RemoteSigner.getOrNull import com.vitorpamplona.quartz.utils.arrayOfNotNull class StoryOptionTag( val option: String, - val address: ATag, + val address: Address, + val relay: String?, ) { - fun toTagArray() = assemble(option, address) + fun toTagArray() = assemble(option, address, relay) companion object { const val TAG_NAME = "option" @@ -37,13 +39,16 @@ class StoryOptionTag( fun parse(tag: Array): StoryOptionTag? { if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null - return ATag.parse(tag[2], tag.getOrNull(3))?.let { StoryOptionTag(tag[1], it) } + val address = Address.parse(tag[2]) ?: return null + + return StoryOptionTag(tag[1], address, tag.getOrNull(3)) } @JvmStatic fun assemble( title: String, - destination: ATag, - ) = arrayOfNotNull(TAG_NAME, title, destination.toTag(), destination.relay) + address: Address, + relay: String?, + ) = arrayOfNotNull(TAG_NAME, title, address.toValue(), relay) } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseAddressableEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseAddressableEvent.kt index 04d0a2d45..16019c726 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseAddressableEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseAddressableEvent.kt @@ -46,5 +46,5 @@ open class BaseAddressableEvent( /** * Creates the tag in a memory efficient way (without creating the ATag class */ - override fun addressTag() = ATag.assembleATagId(kind, pubKey, dTag()) + override fun addressTag() = Address.assemble(kind, pubKey, dTag()) } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseReplaceableEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseReplaceableEvent.kt index 9535c08bb..184fe4eea 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseReplaceableEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/core/BaseReplaceableEvent.kt @@ -44,7 +44,7 @@ open class BaseReplaceableEvent( /** * Creates the tag in a memory efficient way (without creating the ATag class */ - override fun addressTag() = ATag.assembleATagId(kind, pubKey, FIXED_D_TAG) + override fun addressTag() = Address.assemble(kind, pubKey, dTag()) companion object { const val FIXED_D_TAG = "" diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATag.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATag.kt index a6decad3f..10c9e6750 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATag.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATag.kt @@ -34,19 +34,9 @@ data class ATag( val kind: Int, val pubKeyHex: String, val dTag: String, + val relay: String? = null, ) { - var relay: String? = null - - constructor(address: Address) : this(address.kind, address.pubKeyHex, address.dTag) - - constructor( - kind: Int, - pubKeyHex: HexKey, - dTag: String, - relayHint: String?, - ) : this(kind, pubKeyHex, dTag) { - this.relay = relayHint - } + constructor(address: Address, relayHint: String? = null) : this(address.kind, address.pubKeyHex, address.dTag, relayHint) fun countMemory(): Long = 5 * pointerSizeInBytes + // 7 fields, 4 bytes each reference (32bit) @@ -129,6 +119,9 @@ data class ATag( @JvmStatic fun parseAddress(tag: Array) = ATagParser.parseAddress(TAG_NAME, tag) + @JvmStatic + fun parseAddressId(tag: Array) = ATagParser.parseAddressId(TAG_NAME, tag) + @JvmStatic fun assemble( aTagId: HexKey, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATagParser.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATagParser.kt index 9d8c64ffb..252360007 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATagParser.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/ATagParser.kt @@ -99,6 +99,15 @@ class ATagParser { fun parseAddress( tagName: String, tag: Array, + ): Address? { + if (tag.isNotName(tagName, TAG_SIZE)) return null + return Address.parse(tag[1]) + } + + @JvmStatic + fun parseAddressId( + tagName: String, + tag: Array, ): String? { if (tag.isNotName(tagName, TAG_SIZE)) return null return tag[1] diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/Address.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/Address.kt index 0591f2ac3..aa9ffe4da 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/Address.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/Address.kt @@ -26,7 +26,7 @@ import com.vitorpamplona.quartz.utils.Hex import com.vitorpamplona.quartz.utils.bytesUsedInMemory import com.vitorpamplona.quartz.utils.pointerSizeInBytes -class Address( +data class Address( val kind: Int, val pubKeyHex: HexKey, val dTag: String, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/EventExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/EventExt.kt index d0ba9582e..175953648 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/EventExt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/EventExt.kt @@ -34,6 +34,10 @@ fun Event.isTaggedAddressableKind(kind: Int) = tags.isTaggedAddressableKind(kind fun Event.getTagOfAddressableKind(kind: Int) = tags.getTagOfAddressableKind(kind) +fun Event.taggedATags() = tags.taggedATags() + +fun Event.firstTaggedATag() = tags.firstTaggedATag() + fun Event.taggedAddresses() = tags.taggedAddresses() fun Event.firstTaggedAddress() = tags.firstTaggedAddress() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/TagArrayExt.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/TagArrayExt.kt index fe2fd46f0..d7e8deb0e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/TagArrayExt.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/tags/addressables/TagArrayExt.kt @@ -29,14 +29,18 @@ fun TagArray.mapTaggedAddress(map: (address: String) -> R) = this.mapValueTa fun TagArray.firstIsTaggedAddressableNote(addressableNotes: Set) = this.firstNotNullOfOrNull(ATag::parseIfIsIn, addressableNotes) -fun TagArray.isTaggedAddressableNote(idHex: String) = this.any(ATag::isTagged, idHex) +fun TagArray.isTaggedAddressableNote(addressId: String) = this.any(ATag::isTagged, addressId) -fun TagArray.isTaggedAddressableNotes(idHexes: Set) = this.any(ATag::isIn, idHexes) +fun TagArray.isTaggedAddressableNotes(addressIds: Set) = this.any(ATag::isIn, addressIds) fun TagArray.isTaggedAddressableKind(kind: Int) = this.any(ATag::isTaggedWithKind, kind.toString()) fun TagArray.getTagOfAddressableKind(kind: Int) = this.firstNotNullOfOrNull(ATag::parseIfOfKind, kind.toString()) -fun TagArray.taggedAddresses() = this.mapNotNull(ATag::parse) +fun TagArray.taggedATags() = this.mapNotNull(ATag::parse) -fun TagArray.firstTaggedAddress() = this.firstNotNullOfOrNull(ATag::parse) +fun TagArray.firstTaggedATag() = this.firstNotNullOfOrNull(ATag::parse) + +fun TagArray.taggedAddresses() = this.mapNotNull(ATag::parseAddress) + +fun TagArray.firstTaggedAddress() = this.firstNotNullOfOrNull(ATag::parseAddress) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt index 7eeb1be6d..0714508b5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt @@ -55,7 +55,7 @@ class DeletionEvent( fun deleteAddresses() = taggedAddresses() - fun deleteAddressTags() = tags.mapNotNull(ATag::parseAddress) + fun deleteAddressIds() = tags.mapNotNull(ATag::parseAddressId) companion object { const val KIND = 5 diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/BaseThreadedEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/BaseThreadedEvent.kt index 310d67085..bef9ca4b4 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/BaseThreadedEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip10Notes/BaseThreadedEvent.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.quartz.nip10Notes import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.core.Event -import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers import com.vitorpamplona.quartz.nip10Notes.content.findIndexTagsWithEventsOrAddresses import com.vitorpamplona.quartz.nip10Notes.content.findIndexTagsWithPeople @@ -141,7 +141,7 @@ open class BaseThreadedEvent( val uncertainRepliesTo = unmarkedReplyTos() val tagAddresses = - taggedAddresses() + taggedATags() .filter { it.kind != CommunityDefinitionEvent.KIND && (kind != WikiNoteEvent.KIND || it.kind != WikiNoteEvent.KIND) // removes forks from itself. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt index b6177171a..c53ccaca2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -50,6 +51,8 @@ class ChatMessageRelayListEvent( companion object { const val KIND = 10050 + fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) + fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null) fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NAddress.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NAddress.kt index ed507b003..83720e5b2 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NAddress.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NAddress.kt @@ -75,12 +75,14 @@ data class NAddress( kind: Int, pubKeyHex: String, dTag: String, - relay: String?, + vararg relays: String?, ): String = TlvBuilder() .apply { addString(TlvTypes.SPECIAL, dTag) - addStringIfNotNull(TlvTypes.RELAY, relay) + relays.forEach { + addStringIfNotNull(TlvTypes.RELAY, it) + } addHex(TlvTypes.AUTHOR, pubKeyHex) addInt(TlvTypes.KIND, kind) }.build() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NEvent.kt index bf36b9978..7d7d1ae2e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NEvent.kt @@ -59,12 +59,14 @@ data class NEvent( idHex: String, author: String?, kind: Int?, - relay: String?, + vararg relays: String?, ): String = TlvBuilder() .apply { addHex(TlvTypes.SPECIAL, idHex) - addStringIfNotNull(TlvTypes.RELAY, relay) + relays.forEach { + addStringIfNotNull(TlvTypes.RELAY, it) + } addHexIfNotNull(TlvTypes.AUTHOR, author) addIntIfNotNull(TlvTypes.KIND, kind) }.build() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt index fe75d9034..1729b0d84 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt @@ -54,7 +54,7 @@ class LongTextNoteEvent( override fun address() = Address(kind, pubKey, dTag()) - override fun addressTag() = ATag.assembleATagId(kind, pubKey, dTag()) + override fun addressTag() = Address.assemble(kind, pubKey, dTag()) fun topics() = hashtags() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt index aeacfc2c2..b55cb6eb8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt @@ -28,7 +28,8 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag -import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address +import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @@ -42,13 +43,14 @@ class EmojiPackSelectionEvent( content: String, sig: HexKey, ) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun emojiPacks() = taggedAddresses() + fun emojiPacks() = taggedATags() companion object { const val KIND = 10030 const val ALT_DESCRIPTION = "Emoji selection" + const val FIXED_D_TAG = "" - fun createAddressATag(pubKey: HexKey) = ATag(KIND, pubKey, FIXED_D_TAG, null) + fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) fun createAddressTag(pubKey: HexKey) = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt index 8f441aebd..2ca47f138 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt @@ -43,7 +43,9 @@ class GitIssueEvent( content: String, sig: HexKey, ) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun repositoryHex() = tags.firstNotNullOfOrNull(ATag::parseAddress) + fun repositoryHex() = tags.firstNotNullOfOrNull(ATag::parseAddressId) + + fun repositoryAddress() = tags.firstNotNullOfOrNull(ATag::parseAddress) fun repository() = tags.firstNotNullOfOrNull(ATag::parse) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt index 5f7a6cbf3..f7bfa6750 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt @@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -43,6 +44,15 @@ class GitPatchEvent( private fun repositoryHex() = innerRepository()?.getOrNull(1) + fun repositoryAddress() = + innerRepository()?.let { + if (it.size > 1) { + Address.parse(it[1]) + } else { + null + } + } + fun repository() = innerRepository()?.let { if (it.size > 1) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt index d8f6e1ba1..538a4e51f 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip34Git/reply/GitReplyEvent.kt @@ -44,7 +44,7 @@ class GitReplyEvent( content: String, sig: HexKey, ) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - fun repositoryHex() = tags.firstNotNullOfOrNull(ATag::parseAddress) + fun repositoryHex() = tags.firstNotNullOfOrNull(ATag::parseAddressId) fun repository() = tags.firstNotNullOfOrNull(ATag::parse) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt index 1e17ada6a..5f78cb5a0 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -50,6 +51,8 @@ class SearchRelayListEvent( companion object { const val KIND = 10007 + fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) + fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null) fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/GeneralListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/GeneralListEvent.kt index 07920511c..ef8aec468 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/GeneralListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/GeneralListEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.isTagged import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds @@ -113,9 +114,14 @@ abstract class GeneralListEvent( onReady: (List) -> Unit, ) = privateTags(signer) { onReady(filterEvents(it)) } - fun privateTaggedAddresses( + fun privateATags( signer: NostrSigner, onReady: (List) -> Unit, + ) = privateTags(signer) { onReady(filterATags(it)) } + + fun privateAddress( + signer: NostrSigner, + onReady: (List
) -> Unit, ) = privateTags(signer) { onReady(filterAddresses(it)) } fun filterUsers(tags: Array>): List = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] } @@ -126,15 +132,9 @@ abstract class GeneralListEvent( fun filterEvents(tags: Array>): List = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] } - fun filterAddresses(tags: Array>): List = - tags - .filter { it.firstOrNull() == "a" } - .mapNotNull { - val aTagValue = it.getOrNull(1) - val relay = it.getOrNull(2) + fun filterATags(tags: Array>): List = tags.mapNotNull(ATag::parse) - if (aTagValue != null) ATag.parse(aTagValue, relay) else null - } + fun filterAddresses(tags: Array>): List
= tags.mapNotNull(ATag::parseAddress) companion object { fun createPrivateTags( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/MuteListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/MuteListEvent.kt index 23d91f889..8c1c589f8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/MuteListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/MuteListEvent.kt @@ -22,8 +22,8 @@ package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent.Companion.FIXED_D_TAG import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory @@ -77,8 +77,11 @@ class MuteListEvent( companion object { const val KIND = 10000 + const val FIXED_D_TAG = "" const val ALT = "Mute List" + fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) + fun blockListFor(pubKeyHex: HexKey): String = "10000:$pubKeyHex:" fun createListWithTag( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PeopleListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PeopleListEvent.kt index 809825853..8b03f1ec7 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PeopleListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip51Lists/PeopleListEvent.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip51Lists import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.bytesUsedInMemory @@ -127,6 +128,8 @@ class PeopleListEvent( const val BLOCK_LIST_D_TAG = "mute" const val ALT = "List of people" + fun createBlockAddress(pubKey: HexKey) = Address(KIND, pubKey, BLOCK_LIST_D_TAG) + fun blockListFor(pubKeyHex: HexKey): String = "30000:$pubKeyHex:$BLOCK_LIST_D_TAG" fun createListWithTag( diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/chat/LiveActivitiesChatMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/chat/LiveActivitiesChatMessageEvent.kt index c1ab8889d..ebf5926dc 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/chat/LiveActivitiesChatMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip53LiveActivities/chat/LiveActivitiesChatMessageEvent.kt @@ -39,10 +39,12 @@ class LiveActivitiesChatMessageEvent( content: String, sig: HexKey, ) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig) { - private fun activityHex() = tags.firstNotNullOfOrNull(ATag::parseAddress) + private fun activityHex() = tags.firstNotNullOfOrNull(ATag::parseAddressId) fun activity() = tags.firstNotNullOfOrNull(ATag::parse) + fun activityAddress() = tags.firstNotNullOfOrNull(ATag::parseAddress) + override fun markedReplyTos() = super.markedReplyTos().minus(activityHex() ?: "") override fun unmarkedReplyTos() = super.markedReplyTos().minus(activityHex() ?: "") diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt index 705a1501e..2b3b27b45 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt @@ -48,7 +48,7 @@ class WikiNoteEvent( override fun address() = Address(kind, pubKey, dTag()) - override fun addressTag() = ATag.assembleATagId(kind, pubKey, dTag()) + override fun addressTag() = Address.assemble(kind, pubKey, dTag()) fun topics() = hashtags() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeProfilesEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeProfilesEvent.kt index a312c559e..8493516a5 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeProfilesEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip58Badges/BadgeProfilesEvent.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents @@ -45,6 +46,8 @@ class BadgeProfilesEvent( private const val STANDARD_D_TAG = "profile_badges" private const val ALT = "List of accepted badges by the author" + fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, STANDARD_D_TAG) + fun createAddressTag(pubKey: HexKey): ATag = ATag(KIND, pubKey, STANDARD_D_TAG, null) } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/AdvertisedRelayListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/AdvertisedRelayListEvent.kt index 3cd3bc662..e0b918f44 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/AdvertisedRelayListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip65RelayList/AdvertisedRelayListEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -85,6 +86,8 @@ class AdvertisedRelayListEvent( const val KIND = 10002 const val ALT = "Relay list to discover the user's content" + fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) + fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null) fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt index 3ff83eaba..049843e0b 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt @@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate +import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind @@ -54,10 +55,14 @@ class CommunityPostApprovalEvent( null } - fun communities() = taggedAddresses().filter { it.kind == CommunityDefinitionEvent.KIND } + fun communities() = taggedATags().filter { it.kind == CommunityDefinitionEvent.KIND } + + fun communityAddresses() = taggedAddresses().filter { it.kind == CommunityDefinitionEvent.KIND } fun approvedEvents() = taggedEvents() + fun approvedATags() = taggedATags().filter { it.kind != CommunityDefinitionEvent.KIND } + fun approvedAddresses() = taggedAddresses().filter { it.kind != CommunityDefinitionEvent.KIND } companion object { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt index b030fb84e..e02f6e034 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt @@ -24,6 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -39,6 +40,11 @@ class AppSpecificDataEvent( const val KIND = 30078 const val ALT = "Arbitrary app data" + fun createAddress( + pubKey: HexKey, + dTag: String, + ) = Address(KIND, pubKey, dTag) + fun createTag( pubkey: HexKey, dTag: String, diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt index 6b50b3c81..9f8bcc63c 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip84Highlights import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.tags.addressables.firstTaggedATag import com.vitorpamplona.quartz.nip01Core.tags.addressables.firstTaggedAddress import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent import com.vitorpamplona.quartz.nip01Core.tags.people.firstTaggedUser @@ -49,7 +50,9 @@ class HighlightEvent( fun context() = tags.firstNotNullOfOrNull(ContextTag::parse) - fun inPost() = firstTaggedAddress() + fun inPost() = firstTaggedATag() + + fun inPostAddress() = firstTaggedAddress() fun inPostVersion() = firstTaggedEvent() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt index 072418170..ffaefe659 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag +import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip96FileStorage.config.tags.ServerTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -45,6 +46,8 @@ class FileServersEvent( const val KIND = 10096 const val ALT_DESCRIPTOR = "File servers used by the author" + fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) + fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null) fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)