Migrates LocalCache from being based on ATags to Addresses, removing the need to use memory space to store relay hints
This commit is contained in:
@@ -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<NoteState> = 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<StateFlow<NoteState>>? =
|
||||
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<NoteState> = 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<NoteState> = 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<NoteState> = 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<NoteState> = 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<NoteState> = 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<NoteState> = getNIP65RelayListNote(pubkey).flow().metadata.stateFlow
|
||||
@@ -3484,13 +3464,13 @@ class Account(
|
||||
|
||||
fun getFileServersListFlow(): StateFlow<NoteState> = 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<NoteState> = 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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<HexKey>,
|
||||
deletionAddressables: Set<ATag>,
|
||||
deletionAddressables: Set<Address>,
|
||||
): 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<HexKey>,
|
||||
deletionAddressables: Set<ATag>,
|
||||
deletionAddressables: Set<Address>,
|
||||
): 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
|
||||
|
||||
@@ -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<Note> {
|
||||
val map = hashMapOf<ATag, Long>()
|
||||
val map = hashMapOf<Address, Long>()
|
||||
val set = hashSetOf<Note>()
|
||||
|
||||
override fun add(element: Note): Boolean {
|
||||
@@ -142,14 +142,14 @@ class OnlyLatestVersionSet : MutableSet<Note> {
|
||||
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<Note> {
|
||||
element.address()?.let {
|
||||
map.remove(it)
|
||||
}
|
||||
(element.event as? AddressableEvent)?.aTag()?.let {
|
||||
(element.event as? AddressableEvent)?.address()?.let {
|
||||
map.remove(it)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+2
-2
@@ -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,
|
||||
|
||||
@@ -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))
|
||||
|
||||
+4
-5
@@ -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)
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
+1
-2
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<AddressableNote?>(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
|
||||
|
||||
+2
-2
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+2
-2
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
+5
-11
@@ -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<ATag>,
|
||||
emojiCollections: ImmutableList<Address>,
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<AddressableNote?>(postAddress?.let { accountViewModel.getAddressableNoteIfExists(it.toTag()) })
|
||||
mutableStateOf<AddressableNote?>(postAddress?.let { accountViewModel.getAddressableNoteIfExists(it) })
|
||||
}
|
||||
|
||||
if (addressable == null && postAddress != null) {
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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(
|
||||
|
||||
@@ -127,7 +127,7 @@ class FollowListState(
|
||||
checkNotInMainThread()
|
||||
|
||||
val hasNewList =
|
||||
newNotes.any {
|
||||
newNotes.any { it ->
|
||||
val noteEvent = it.event
|
||||
|
||||
noteEvent?.pubKey == account.userProfile().pubkeyHex &&
|
||||
|
||||
+13
-11
@@ -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<AddressableNote>) -> 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)
|
||||
}
|
||||
|
||||
+1
-5
@@ -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))
|
||||
|
||||
+4
-4
@@ -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(
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
+3
@@ -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)
|
||||
|
||||
+2
-4
@@ -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)
|
||||
|
||||
+7
-1
@@ -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,
|
||||
|
||||
+11
-6
@@ -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<String>): 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)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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())
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 = ""
|
||||
|
||||
@@ -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<String>) = ATagParser.parseAddress(TAG_NAME, tag)
|
||||
|
||||
@JvmStatic
|
||||
fun parseAddressId(tag: Array<String>) = ATagParser.parseAddressId(TAG_NAME, tag)
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
aTagId: HexKey,
|
||||
|
||||
+9
@@ -99,6 +99,15 @@ class ATagParser {
|
||||
fun parseAddress(
|
||||
tagName: String,
|
||||
tag: Array<String>,
|
||||
): Address? {
|
||||
if (tag.isNotName(tagName, TAG_SIZE)) return null
|
||||
return Address.parse(tag[1])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAddressId(
|
||||
tagName: String,
|
||||
tag: Array<String>,
|
||||
): String? {
|
||||
if (tag.isNotName(tagName, TAG_SIZE)) return null
|
||||
return tag[1]
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
+8
-4
@@ -29,14 +29,18 @@ fun <R> TagArray.mapTaggedAddress(map: (address: String) -> R) = this.mapValueTa
|
||||
|
||||
fun TagArray.firstIsTaggedAddressableNote(addressableNotes: Set<String>) = 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<String>) = this.any(ATag::isIn, idHexes)
|
||||
fun TagArray.isTaggedAddressableNotes(addressIds: Set<String>) = 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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
+3
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
+5
-3
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<String>) -> Unit,
|
||||
) = privateTags(signer) { onReady(filterEvents(it)) }
|
||||
|
||||
fun privateTaggedAddresses(
|
||||
fun privateATags(
|
||||
signer: NostrSigner,
|
||||
onReady: (List<ATag>) -> Unit,
|
||||
) = privateTags(signer) { onReady(filterATags(it)) }
|
||||
|
||||
fun privateAddress(
|
||||
signer: NostrSigner,
|
||||
onReady: (List<Address>) -> Unit,
|
||||
) = privateTags(signer) { onReady(filterAddresses(it)) }
|
||||
|
||||
fun filterUsers(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] }
|
||||
@@ -126,15 +132,9 @@ abstract class GeneralListEvent(
|
||||
|
||||
fun filterEvents(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] }
|
||||
|
||||
fun filterAddresses(tags: Array<Array<String>>): List<ATag> =
|
||||
tags
|
||||
.filter { it.firstOrNull() == "a" }
|
||||
.mapNotNull {
|
||||
val aTagValue = it.getOrNull(1)
|
||||
val relay = it.getOrNull(2)
|
||||
fun filterATags(tags: Array<Array<String>>): List<ATag> = tags.mapNotNull(ATag::parse)
|
||||
|
||||
if (aTagValue != null) ATag.parse(aTagValue, relay) else null
|
||||
}
|
||||
fun filterAddresses(tags: Array<Array<String>>): List<Address> = tags.mapNotNull(ATag::parseAddress)
|
||||
|
||||
companion object {
|
||||
fun createPrivateTags(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
+3
-1
@@ -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() ?: "")
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -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)
|
||||
|
||||
+6
-1
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
+3
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user