mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-03-17 21:31:57 +01:00
- Normalizes the use of ETag
- Creates a BaseReplaceable event to avoid duplicates of empty d tags.
This commit is contained in:
parent
5a3c821da4
commit
c25d64558e
@ -74,17 +74,18 @@ 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.taggedAddresses
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.hasAnyTaggedUser
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers
|
||||
import com.vitorpamplona.quartz.nip02FollowList.Contact
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.ETag
|
||||
import com.vitorpamplona.quartz.nip10Notes.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
@ -954,7 +955,7 @@ class Account(
|
||||
onReady: (LiveFollowList) -> Unit,
|
||||
) {
|
||||
listEvent.privateTags(signer) { privateTagList ->
|
||||
val users = (listEvent.bookmarkedPeople() + listEvent.filterUsers(privateTagList)).toSet()
|
||||
val users = (listEvent.taggedUsers() + listEvent.filterUsers(privateTagList)).toSet()
|
||||
onReady(
|
||||
LiveFollowList(
|
||||
authors = users,
|
||||
@ -970,6 +971,11 @@ class Account(
|
||||
}
|
||||
}
|
||||
|
||||
fun decryptPeopleList(
|
||||
event: GeneralListEvent,
|
||||
onReady: (Array<Array<String>>) -> Unit,
|
||||
) = event.privateTags(signer, onReady)
|
||||
|
||||
suspend fun waitToDecrypt(peopleListFollows: GeneralListEvent): LiveFollowList? =
|
||||
tryAndWait { continuation ->
|
||||
decryptLiveFollows(peopleListFollows) {
|
||||
@ -2445,7 +2451,7 @@ class Account(
|
||||
directMentionsNotes
|
||||
.mapNotNullTo(HashSet(directMentionsNotes.size)) { note ->
|
||||
if (note !is AddressableNote) {
|
||||
ETag(note.idHex, note.author?.pubkeyHex, note.relayHintUrl())
|
||||
ETag(note.idHex, note.relayHintUrl(), note.author?.pubkeyHex)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@ -2556,7 +2562,7 @@ class Account(
|
||||
directMentionsNotes
|
||||
.mapNotNullTo(HashSet(directMentionsNotes.size)) { note ->
|
||||
if (note !is AddressableNote) {
|
||||
ETag(note.idHex, note.author?.pubkeyHex, note.relayHintUrl())
|
||||
ETag(note.idHex, note.relayHintUrl(), note.author?.pubkeyHex)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@ -3520,7 +3526,7 @@ class Account(
|
||||
if (note is AddressableNote) {
|
||||
return userProfile().latestBookmarkList?.taggedAddresses()?.contains(note.address) == true
|
||||
} else {
|
||||
return userProfile().latestBookmarkList?.taggedEvents()?.contains(note.idHex) == true
|
||||
return userProfile().latestBookmarkList?.taggedEventIds()?.contains(note.idHex) == true
|
||||
}
|
||||
}
|
||||
|
||||
@ -3675,7 +3681,7 @@ class Account(
|
||||
|
||||
fun selectedChatsFollowList(): Set<String> {
|
||||
val contactList = userProfile().latestContactList
|
||||
return contactList?.taggedEvents()?.toSet() ?: DefaultChannels
|
||||
return contactList?.taggedEventIds()?.toSet() ?: DefaultChannels
|
||||
}
|
||||
|
||||
fun sendChangeChannel(
|
||||
|
@ -57,9 +57,10 @@ import com.vitorpamplona.quartz.nip01Core.hasValidSignature
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.mapTaggedAddress
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.forEachTaggedEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.forEachTaggedEventId
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.isTaggedEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.mapTaggedEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.mapTaggedEventId
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUsers
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
@ -78,7 +79,6 @@ import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodeEventIdAsHexOrNull
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodePublicKeyAsHexOrNull
|
||||
import com.vitorpamplona.quartz.nip19Bech32.isATag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parse
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
@ -239,7 +239,7 @@ object LocalCache {
|
||||
|
||||
private fun updateObservables(event: Event) {
|
||||
observablesByKindAndETag[event.kind]?.let { observablesOfKind ->
|
||||
event.forEachTaggedEvent {
|
||||
event.forEachTaggedEventId {
|
||||
observablesOfKind[it]?.updateIfMatches(event)
|
||||
}
|
||||
}
|
||||
@ -274,6 +274,8 @@ object LocalCache {
|
||||
|
||||
fun getNoteIfExists(key: String): Note? = addressables.get(key) ?: notes.get(key)
|
||||
|
||||
fun getNoteIfExists(key: ETag): Note? = notes.get(key.eventId)
|
||||
|
||||
fun getChannelIfExists(key: String): Channel? = channels.get(key)
|
||||
|
||||
fun getNoteIfExists(event: Event): Note? =
|
||||
@ -290,6 +292,15 @@ object LocalCache {
|
||||
getOrCreateNote(event.id)
|
||||
}
|
||||
|
||||
fun checkGetOrCreateNote(etag: ETag): Note? {
|
||||
checkNotInMainThread()
|
||||
|
||||
if (isValidHex(etag.eventId)) {
|
||||
return getOrCreateNote(etag)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun checkGetOrCreateNote(key: String): Note? {
|
||||
checkNotInMainThread()
|
||||
|
||||
@ -401,6 +412,16 @@ object LocalCache {
|
||||
return note
|
||||
}
|
||||
|
||||
fun getOrCreateNote(key: ETag): Note {
|
||||
val note = getOrCreateNote(key.eventId)
|
||||
// Loads the user outside a Syncronized block to avoid blocking
|
||||
val possibleAuthor = key.authorPubKeyHex
|
||||
if (note.author == null && possibleAuthor != null) {
|
||||
note.author = checkGetOrCreateUser(possibleAuthor)
|
||||
}
|
||||
return note
|
||||
}
|
||||
|
||||
fun consume(
|
||||
event: MetadataEvent,
|
||||
relay: Relay?,
|
||||
@ -681,7 +702,7 @@ object LocalCache {
|
||||
event.tagsWithoutCitations().mapNotNull { checkGetOrCreateNote(it) }
|
||||
|
||||
is DraftEvent -> {
|
||||
event.mapTaggedEvent { checkGetOrCreateNote(it) } + event.mapTaggedAddress { checkGetOrCreateAddressableNote(it) }
|
||||
event.mapTaggedEventId { checkGetOrCreateNote(it) } + event.mapTaggedAddress { checkGetOrCreateAddressableNote(it) }
|
||||
}
|
||||
|
||||
else -> emptyList<Note>()
|
||||
@ -1562,7 +1583,7 @@ object LocalCache {
|
||||
note.loadEvent(event, author, emptyList())
|
||||
|
||||
event.editedNote()?.let {
|
||||
checkGetOrCreateNote(it)?.let { editedNote ->
|
||||
checkGetOrCreateNote(it.eventId)?.let { editedNote ->
|
||||
modificationCache.remove(editedNote.idHex)
|
||||
// must update list of Notes to quickly update the user.
|
||||
editedNote.liveSet?.innerModifications?.invalidateData()
|
||||
|
@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.actions.relays.updated
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.ChannelMessageEvent
|
||||
@ -141,7 +141,7 @@ class ChatroomListKnownFeedFilter(
|
||||
account
|
||||
.userProfile()
|
||||
.latestContactList
|
||||
?.taggedEvents()
|
||||
?.taggedEventIds()
|
||||
?.toSet() ?: emptySet()
|
||||
val newRelevantPublicMessages = mutableMapOf<String, Note>()
|
||||
newItems
|
||||
|
@ -120,7 +120,7 @@ class FeedContentState(
|
||||
if (deletionEvents.isEmpty()) {
|
||||
oldNotesState.feed.value.list
|
||||
} else {
|
||||
val deletedEventIds = deletionEvents.flatMapTo(HashSet()) { it.deleteEvents() }
|
||||
val deletedEventIds = deletionEvents.flatMapTo(HashSet()) { it.deleteEventIds() }
|
||||
val deletedEventAddresses = deletionEvents.flatMapTo(HashSet()) { it.deleteAddresses() }
|
||||
oldNotesState.feed.value.list
|
||||
.filter { !it.wasOrShouldBeDeletedBy(deletedEventIds, deletedEventAddresses) }
|
||||
|
@ -75,6 +75,7 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import com.vitorpamplona.quartz.nip01Core.UserMetadata
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.firstTaggedAddress
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent
|
||||
import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@ -264,7 +265,7 @@ fun DisplayStatus(
|
||||
event.dTag(),
|
||||
event.firstTaggedUrl()?.ifBlank { null },
|
||||
event.firstTaggedAddress(),
|
||||
event.firstTaggedEvent()?.ifBlank { null },
|
||||
event.firstTaggedEvent(),
|
||||
accountViewModel,
|
||||
nav,
|
||||
)
|
||||
@ -276,7 +277,7 @@ fun DisplayStatusInner(
|
||||
type: String,
|
||||
url: String?,
|
||||
nostrATag: ATag?,
|
||||
nostrHexID: String?,
|
||||
nostrETag: ETag?,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@ -335,8 +336,8 @@ fun DisplayStatusInner(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (nostrHexID != null) {
|
||||
LoadNote(baseNoteHex = nostrHexID, accountViewModel) {
|
||||
} else if (nostrETag != null) {
|
||||
LoadNote(baseNoteHex = nostrETag.eventId, accountViewModel) {
|
||||
if (it != null) {
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
IconButton(
|
||||
|
@ -53,9 +53,9 @@ import com.vitorpamplona.amethyst.ui.components.measureSpaceWidth
|
||||
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.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstTagValueFor
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNIP19
|
||||
@ -100,7 +100,7 @@ fun DisplayHighlight(
|
||||
authorHex: String?,
|
||||
url: String?,
|
||||
postAddress: ATag?,
|
||||
postVersion: HexKey?,
|
||||
postVersion: ETag?,
|
||||
makeItShort: Boolean,
|
||||
canPreview: Boolean,
|
||||
quotesLeft: Int,
|
||||
@ -150,7 +150,7 @@ private fun DisplayQuoteAuthor(
|
||||
authorHex: String?,
|
||||
baseUrl: String?,
|
||||
postAddress: ATag?,
|
||||
postVersion: HexKey?,
|
||||
postVersion: ETag?,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@ -181,14 +181,14 @@ private fun DisplayQuoteAuthor(
|
||||
}
|
||||
|
||||
var version by remember {
|
||||
mutableStateOf<Note?>(postVersion?.let { accountViewModel.getNoteIfExists(it) })
|
||||
mutableStateOf<Note?>(postVersion?.let { accountViewModel.getNoteIfExists(it.eventId) })
|
||||
}
|
||||
|
||||
if (version == null && postVersion != null) {
|
||||
LaunchedEffect(key1 = postVersion) {
|
||||
val newNote =
|
||||
withContext(Dispatchers.IO) {
|
||||
accountViewModel.getOrCreateNote(postVersion)
|
||||
accountViewModel.getOrCreateNote(postVersion.eventId)
|
||||
}
|
||||
if (version != newNote) {
|
||||
version = newNote
|
||||
|
@ -84,13 +84,13 @@ fun RenderTextModificationEvent(
|
||||
val isAuthorTheLoggedUser =
|
||||
remember {
|
||||
val authorOfTheOriginalNote =
|
||||
noteEvent.editedNote()?.let { accountViewModel.getNoteIfExists(it)?.author }
|
||||
noteEvent.editedNote()?.let { accountViewModel.getNoteIfExists(it.eventId)?.author?.pubkeyHex ?: it.authorPubKeyHex }
|
||||
|
||||
mutableStateOf(accountViewModel.isLoggedUser(authorOfTheOriginalNote))
|
||||
}
|
||||
|
||||
noteEvent.editedNote()?.let {
|
||||
LoadNote(baseNoteHex = it, accountViewModel = accountViewModel) { baseOriginalNote ->
|
||||
LoadNote(baseNoteHex = it.eventId, accountViewModel = accountViewModel) { baseOriginalNote ->
|
||||
baseOriginalNote?.let {
|
||||
}
|
||||
}
|
||||
@ -128,7 +128,7 @@ fun RenderTextModificationEvent(
|
||||
}
|
||||
|
||||
noteEvent.editedNote()?.let {
|
||||
LoadNote(baseNoteHex = it, accountViewModel = accountViewModel) { baseNote ->
|
||||
LoadNote(baseNoteHex = it.eventId, accountViewModel = accountViewModel) { baseNote ->
|
||||
baseNote?.let {
|
||||
val noteState by baseNote.live().metadata.observeAsState()
|
||||
|
||||
|
@ -140,7 +140,7 @@ class FollowListState(
|
||||
(
|
||||
noteEvent is DeletionEvent &&
|
||||
(
|
||||
noteEvent.deleteEvents().any {
|
||||
noteEvent.deleteEventIds().any {
|
||||
LocalCache.getNoteIfExists(it)?.event is PeopleListEvent
|
||||
} ||
|
||||
noteEvent.deleteAddresses().any {
|
||||
|
@ -82,6 +82,7 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers
|
||||
import com.vitorpamplona.quartz.nip11RelayInfo.Nip11RelayInformation
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
|
||||
@ -99,6 +100,7 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NSec
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Response
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
@ -1071,7 +1073,7 @@ class AccountViewModel(
|
||||
viewModelScope.launch(Dispatchers.IO) { runOnIO() }
|
||||
}
|
||||
|
||||
suspend fun checkGetOrCreateUser(key: HexKey): User? = LocalCache.checkGetOrCreateUser(key)
|
||||
fun checkGetOrCreateUser(key: HexKey): User? = LocalCache.checkGetOrCreateUser(key)
|
||||
|
||||
override suspend fun getOrCreateUser(key: HexKey): User = LocalCache.getOrCreateUser(key)
|
||||
|
||||
@ -1201,7 +1203,7 @@ class AccountViewModel(
|
||||
hexList: List<String>,
|
||||
onReady: (ImmutableList<User>) -> Unit,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
onReady(
|
||||
hexList
|
||||
.mapNotNull { hex -> checkGetOrCreateUser(hex) }
|
||||
@ -1212,6 +1214,24 @@ class AccountViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun loadUsers(
|
||||
event: GeneralListEvent,
|
||||
onReady: (ImmutableList<User>) -> Unit,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
account.decryptPeopleList(event) { privateTagList ->
|
||||
onReady(
|
||||
(event.taggedUsers() + event.filterUsers(privateTagList))
|
||||
.toSet()
|
||||
.mapNotNull { hex -> checkGetOrCreateUser(hex) }
|
||||
.sortedBy { account.isFollowing(it) }
|
||||
.reversed()
|
||||
.toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkVideoIsOnline(
|
||||
videoUrl: String,
|
||||
onDone: (Boolean) -> Unit,
|
||||
|
@ -177,6 +177,7 @@ 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.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||
import com.vitorpamplona.quartz.nip39ExtIdentities.GitHubIdentity
|
||||
@ -1383,7 +1384,7 @@ private fun WatchAndRenderBadgeList(
|
||||
@Composable
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
private fun RenderBadgeList(
|
||||
list: ImmutableList<String>,
|
||||
list: ImmutableList<ETag>,
|
||||
loadProfilePicture: Boolean,
|
||||
loadRobohash: Boolean,
|
||||
nav: INav,
|
||||
@ -1398,17 +1399,17 @@ private fun RenderBadgeList(
|
||||
|
||||
@Composable
|
||||
private fun LoadAndRenderBadge(
|
||||
badgeAwardEventHex: String,
|
||||
badgeAwardEvent: ETag,
|
||||
loadProfilePicture: Boolean,
|
||||
loadRobohash: Boolean,
|
||||
nav: INav,
|
||||
) {
|
||||
var baseNote by remember(badgeAwardEventHex) { mutableStateOf(LocalCache.getNoteIfExists(badgeAwardEventHex)) }
|
||||
var baseNote by remember(badgeAwardEvent) { mutableStateOf(LocalCache.getNoteIfExists(badgeAwardEvent)) }
|
||||
|
||||
LaunchedEffect(key1 = badgeAwardEventHex) {
|
||||
LaunchedEffect(key1 = badgeAwardEvent) {
|
||||
if (baseNote == null) {
|
||||
withContext(Dispatchers.IO) {
|
||||
baseNote = LocalCache.checkGetOrCreateNote(badgeAwardEventHex)
|
||||
baseNote = LocalCache.checkGetOrCreateNote(badgeAwardEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ package com.vitorpamplona.quartz.blossom
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
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.nip31Alts.AltTagSerializer
|
||||
@ -36,9 +36,7 @@ class BlossomServersEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun servers(): List<String> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "server") {
|
||||
@ -50,12 +48,11 @@ class BlossomServersEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10063
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "File servers used by the author"
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun createTagArray(servers: List<String>): Array<Array<String>> =
|
||||
servers
|
||||
|
@ -24,7 +24,7 @@ import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
@ -43,15 +43,13 @@ class PrivateOutboxRelayListEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
@Transient private var privateTagsCache: Array<Array<String>>? = null
|
||||
|
||||
override fun countMemory(): Long =
|
||||
super.countMemory() +
|
||||
pointerSizeInBytes + (privateTagsCache?.sumOf { pointerSizeInBytes + it.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } } ?: 0)
|
||||
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
fun relays(): List<String>? =
|
||||
tags
|
||||
.mapNotNull {
|
||||
@ -102,12 +100,11 @@ class PrivateOutboxRelayListEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10013
|
||||
const val FIXED_D_TAG = ""
|
||||
val TAGS = arrayOf(AltTagSerializer.toTagArray("Relay list to store private content from this author"))
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun encryptTags(
|
||||
privateTags: Array<Array<String>>? = null,
|
||||
|
@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.hashtags.buildHashtagTags
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.buildUrlRefs
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parse
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
|
||||
|
@ -49,7 +49,7 @@ class InteractiveStoryPrologueEvent(
|
||||
fun createAddressTag(
|
||||
pubKey: HexKey,
|
||||
dtag: String,
|
||||
): String = ATag.assembleATag(KIND, pubKey, dtag)
|
||||
): String = ATag.assembleATagId(KIND, pubKey, dtag)
|
||||
|
||||
fun create(
|
||||
baseId: String,
|
||||
|
@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.firstTag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parse
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers
|
||||
@ -66,7 +65,7 @@ class InteractiveStoryReadingStateEvent(
|
||||
fun createAddressTag(
|
||||
pubKey: HexKey,
|
||||
dtag: String,
|
||||
): String = ATag.assembleATag(KIND, pubKey, dtag)
|
||||
): String = ATag.assembleATagId(KIND, pubKey, dtag)
|
||||
|
||||
fun update(
|
||||
base: InteractiveStoryReadingStateEvent,
|
||||
|
@ -49,7 +49,7 @@ class InteractiveStorySceneEvent(
|
||||
fun createAddressTag(
|
||||
pubKey: HexKey,
|
||||
dtag: String,
|
||||
): String = ATag.assembleATag(KIND, pubKey, dtag)
|
||||
): String = ATag.assembleATagId(KIND, pubKey, dtag)
|
||||
|
||||
fun create(
|
||||
baseId: String,
|
||||
|
@ -23,7 +23,7 @@ package com.vitorpamplona.quartz.nip01Core.core
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.dTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag
|
||||
|
||||
@Immutable
|
||||
open class BaseAddressableEvent(
|
||||
@ -43,5 +43,5 @@ open class BaseAddressableEvent(
|
||||
/**
|
||||
* Creates the tag in a memory efficient way (without creating the ATag class
|
||||
*/
|
||||
override fun addressTag() = ATag.assembleATag(kind, pubKey, dTag())
|
||||
override fun addressTag() = ATag.assembleATagId(kind, pubKey, dTag())
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.core
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
|
||||
@Immutable
|
||||
open class BaseReplaceableEvent(
|
||||
id: HexKey,
|
||||
pubKey: HexKey,
|
||||
createdAt: Long,
|
||||
kind: Int,
|
||||
tags: TagArray,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
override fun address(relayHint: String?) = ATag(kind, pubKey, FIXED_D_TAG, relayHint)
|
||||
|
||||
/**
|
||||
* Creates the tag in a memory efficient way (without creating the ATag class
|
||||
*/
|
||||
override fun addressTag() = ATag.assembleATagId(kind, pubKey, FIXED_D_TAG)
|
||||
|
||||
companion object {
|
||||
const val FIXED_D_TAG = ""
|
||||
}
|
||||
}
|
@ -20,7 +20,11 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.addressables
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers
|
||||
@ -35,7 +39,7 @@ data class ATag(
|
||||
|
||||
constructor(
|
||||
kind: Int,
|
||||
pubKeyHex: String,
|
||||
pubKeyHex: HexKey,
|
||||
dTag: String,
|
||||
relayHint: String?,
|
||||
) : this(kind, pubKeyHex, dTag) {
|
||||
@ -49,17 +53,56 @@ data class ATag(
|
||||
dTag.bytesUsedInMemory() +
|
||||
(relay?.bytesUsedInMemory() ?: 0)
|
||||
|
||||
fun toTag() = assembleATag(kind, pubKeyHex, dTag)
|
||||
fun toTag() = assembleATagId(kind, pubKeyHex, dTag)
|
||||
|
||||
fun toATagArray() = removeTrailingNullsAndEmptyOthers("a", toTag(), relay)
|
||||
fun toATagArray() = removeTrailingNullsAndEmptyOthers(TAG_NAME, toTag(), relay)
|
||||
|
||||
fun toQTagArray() = removeTrailingNullsAndEmptyOthers("q", toTag(), relay)
|
||||
|
||||
companion object {
|
||||
fun assembleATag(
|
||||
const val TAG_NAME = "a"
|
||||
|
||||
fun assembleATagId(
|
||||
kind: Int,
|
||||
pubKeyHex: HexKey,
|
||||
dTag: String,
|
||||
) = "$kind:$pubKeyHex:$dTag"
|
||||
|
||||
fun parse(
|
||||
aTagId: String,
|
||||
relay: String?,
|
||||
): ATag? =
|
||||
try {
|
||||
val parts = aTagId.split(":", limit = 3)
|
||||
if (Hex.isHex(parts[1])) {
|
||||
ATag(parts[0].toInt(), parts[1], parts[2], relay)
|
||||
} else {
|
||||
Log.w("ATag", "Error parsing A Tag. Pubkey is not hex: $aTagId")
|
||||
null
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
Log.w("ATag", "Error parsing A Tag: $aTagId: ${t.message}")
|
||||
null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): ATag? {
|
||||
require(tags[0] == TAG_NAME)
|
||||
return parse(tags[1], tags.getOrNull(2))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
aTagId: HexKey,
|
||||
relay: String?,
|
||||
) = arrayOfNotNull(TAG_NAME, aTagId, relay)
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
kind: Int,
|
||||
pubKeyHex: String,
|
||||
dTag: String,
|
||||
) = "$kind:$pubKeyHex:$dTag"
|
||||
relay: String?,
|
||||
) = arrayOfNotNull(TAG_NAME, assembleATagId(kind, pubKeyHex, dTag), relay)
|
||||
}
|
||||
}
|
||||
|
@ -28,35 +28,33 @@ import com.vitorpamplona.quartz.nip01Core.core.mapTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValueTagged
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parse
|
||||
|
||||
fun TagArray.dTag() = this.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: ""
|
||||
|
||||
fun <R> TagArray.mapTaggedAddress(map: (address: String) -> R) = this.mapValueTagged("a", map)
|
||||
fun <R> TagArray.mapTaggedAddress(map: (address: String) -> R) = this.mapValueTagged(ATag.TAG_NAME, map)
|
||||
|
||||
fun TagArray.firstIsTaggedAddressableNote(addressableNotes: Set<String>) =
|
||||
this
|
||||
.firstOrNull { it.size > 1 && it[0] == "a" && it[1] in addressableNotes }
|
||||
.firstOrNull { it.size > 1 && it[0] == ATag.TAG_NAME && it[1] in addressableNotes }
|
||||
?.getOrNull(1)
|
||||
|
||||
fun TagArray.isTaggedAddressableNote(idHex: String) = this.isTagged("a", idHex)
|
||||
fun TagArray.isTaggedAddressableNote(idHex: String) = this.isTagged(ATag.TAG_NAME, idHex)
|
||||
|
||||
fun TagArray.isTaggedAddressableNotes(idHexes: Set<String>) = this.isAnyTagged("a", idHexes)
|
||||
fun TagArray.isTaggedAddressableNotes(idHexes: Set<String>) = this.isAnyTagged(ATag.TAG_NAME, idHexes)
|
||||
|
||||
fun TagArray.isTaggedAddressableKind(kind: Int): Boolean {
|
||||
val kindStr = kind.toString()
|
||||
return this.any { it.size > 1 && it[0] == "a" && it[1].startsWith(kindStr) }
|
||||
return this.any { it.size > 1 && it[0] == ATag.TAG_NAME && it[1].startsWith(kindStr) }
|
||||
}
|
||||
|
||||
fun TagArray.getTagOfAddressableKind(kind: Int): ATag? {
|
||||
val kindStr = kind.toString()
|
||||
val aTag =
|
||||
this
|
||||
.firstOrNull { it.size > 1 && it[0] == "a" && it[1].startsWith(kindStr) }
|
||||
.firstOrNull { it.size > 1 && it[0] == ATag.TAG_NAME && it[1].startsWith(kindStr) }
|
||||
?.getOrNull(1)
|
||||
?: return null
|
||||
|
||||
return ATag.parse(aTag, null)
|
||||
}
|
||||
|
||||
fun TagArray.taggedAddresses() = this.mapTagged("a") { ATag.parse(it[1], it.getOrNull(2)) }
|
||||
fun TagArray.taggedAddresses() = this.mapTagged(ATag.TAG_NAME) { ATag.parse(it) }
|
||||
|
||||
fun TagArray.firstTaggedAddress() = this.firstMapTagged("a") { ATag.parse(it[1], it.getOrNull(2)) }
|
||||
fun TagArray.firstTaggedAddress() = this.firstMapTagged(ATag.TAG_NAME) { ATag.parse(it) }
|
||||
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.dTags
|
||||
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
|
||||
class DTag(
|
||||
val dId: String,
|
||||
) {
|
||||
fun countMemory(): Long = 1 * pointerSizeInBytes + dId.bytesUsedInMemory()
|
||||
|
||||
fun toTagArray() = assemble(dId)
|
||||
|
||||
companion object {
|
||||
const val TAG_NAME = "d"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): DTag {
|
||||
require(tags[0] == TAG_NAME)
|
||||
return DTag(tags[1])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(dId: String) = arrayOf(TAG_NAME, dId)
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.dTags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
|
||||
fun Event.dTag() = tags.dTag()
|
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.dTags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
|
||||
fun TagArrayBuilder.dTag(name: String) = add(DTag.assemble(name))
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.dTags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
|
||||
|
||||
fun TagArray.dTag() = this.firstTagValue(DTag.TAG_NAME) ?: ""
|
@ -18,14 +18,14 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip10Notes
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.events
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers
|
||||
|
||||
@Immutable
|
||||
data class ETag(
|
||||
@ -40,13 +40,31 @@ data class ETag(
|
||||
}
|
||||
|
||||
fun countMemory(): Long =
|
||||
2 * pointerSizeInBytes + // 2 fields, 4 bytes each reference (32bit)
|
||||
3 * pointerSizeInBytes + // 3 fields, 4 bytes each reference (32bit)
|
||||
eventId.bytesUsedInMemory() +
|
||||
(relay?.bytesUsedInMemory() ?: 0)
|
||||
(relay?.bytesUsedInMemory() ?: 0) +
|
||||
(authorPubKeyHex?.bytesUsedInMemory() ?: 0)
|
||||
|
||||
fun toNEvent(): String = NEvent.create(eventId, authorPubKeyHex, null, relay)
|
||||
|
||||
fun toETagArray() = removeTrailingNullsAndEmptyOthers("e", eventId, relay, authorPubKeyHex)
|
||||
fun toETagArray() = arrayOfNotNull(TAG_NAME, eventId, relay, authorPubKeyHex)
|
||||
|
||||
fun toQTagArray() = removeTrailingNullsAndEmptyOthers("q", eventId, relay, authorPubKeyHex)
|
||||
fun toQTagArray() = arrayOfNotNull("q", eventId, relay, authorPubKeyHex)
|
||||
|
||||
companion object {
|
||||
const val TAG_NAME = "e"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): ETag {
|
||||
require(tags[0] == TAG_NAME)
|
||||
return ETag(tags[1], tags.getOrNull(2), tags.getOrNull(3))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
eventId: HexKey,
|
||||
relay: String?,
|
||||
author: HexKey?,
|
||||
) = arrayOfNotNull(TAG_NAME, eventId, relay, author)
|
||||
}
|
||||
}
|
@ -23,12 +23,14 @@ package com.vitorpamplona.quartz.nip01Core.tags.events
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
|
||||
fun Event.forEachTaggedEvent(onEach: (eventId: HexKey) -> Unit) = tags.forEachTaggedEvent(onEach)
|
||||
fun Event.forEachTaggedEventId(onEach: (eventId: HexKey) -> Unit) = tags.forEachTaggedEventId(onEach)
|
||||
|
||||
fun <R> Event.mapTaggedEvent(map: (eventId: HexKey) -> R) = tags.mapTaggedEvent(map)
|
||||
fun <R> Event.mapTaggedEventId(map: (eventId: HexKey) -> R) = tags.mapTaggedEventId(map)
|
||||
|
||||
fun Event.taggedEvents() = tags.taggedEvents()
|
||||
|
||||
fun Event.taggedEventIds() = tags.taggedEventIds()
|
||||
|
||||
fun Event.firstTaggedEvent() = tags.firstTaggedEvent()
|
||||
|
||||
fun Event.isTaggedEvent(idHex: String) = tags.isTaggedEvent(idHex)
|
||||
|
@ -22,18 +22,22 @@ package com.vitorpamplona.quartz.nip01Core.tags.events
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstMapTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.forEachTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValueTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValues
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parse
|
||||
|
||||
fun TagArray.forEachTaggedEvent(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged("e", onEach)
|
||||
fun TagArray.forEachTaggedEventId(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged(ETag.TAG_NAME, onEach)
|
||||
|
||||
fun <R> TagArray.mapTaggedEvent(map: (eventId: HexKey) -> R) = this.mapValueTagged("e", map)
|
||||
fun <R> TagArray.mapTaggedEventId(map: (eventId: HexKey) -> R) = this.mapValueTagged(ETag.TAG_NAME, map)
|
||||
|
||||
fun TagArray.taggedEvents() = this.mapValues("e")
|
||||
fun TagArray.taggedEvents() = this.mapTagged(ETag.TAG_NAME) { ETag.parse(it) }
|
||||
|
||||
fun TagArray.firstTaggedEvent() = this.firstTagValue("e")
|
||||
fun TagArray.taggedEventIds() = this.mapValues(ETag.TAG_NAME)
|
||||
|
||||
fun TagArray.isTaggedEvent(idHex: String) = this.isTagged("e", idHex)
|
||||
fun TagArray.firstTaggedEvent() = this.firstMapTagged(ETag.TAG_NAME) { ETag.parse(it) }
|
||||
|
||||
fun TagArray.isTaggedEvent(idHex: String) = this.isTagged(ETag.TAG_NAME, idHex)
|
||||
|
@ -26,6 +26,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.taggedAddresses
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@ -41,6 +42,8 @@ class DeletionEvent(
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun deleteEvents() = taggedEvents()
|
||||
|
||||
fun deleteEventIds() = taggedEventIds()
|
||||
|
||||
fun deleteAddresses() = taggedAddresses()
|
||||
|
||||
fun deleteAddressTags() = tags.mapNotNull { if (it.size > 1 && it[0] == "a") it[1] else null }
|
||||
|
@ -33,7 +33,7 @@ class PoWTag(
|
||||
fun toTagArray() = assemble(nonce, commitment)
|
||||
|
||||
companion object {
|
||||
val TAG_NAME = "nonce"
|
||||
const val TAG_NAME = "nonce"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): PoWTag {
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip14Subject
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.dTags.DTag
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
|
||||
@ -31,12 +32,12 @@ class SubjectTag(
|
||||
fun toTagArray() = assemble(subject)
|
||||
|
||||
companion object {
|
||||
val TAG_NAME = "subject"
|
||||
const val TAG_NAME = "subject"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): SubjectTag {
|
||||
fun parse(tags: Array<String>): DTag {
|
||||
require(tags[0] == TAG_NAME)
|
||||
return SubjectTag(tags[1])
|
||||
return DTag(tags[1])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
@ -22,7 +22,7 @@ package com.vitorpamplona.quartz.nip17Dm
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
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
|
||||
@ -37,9 +37,7 @@ class ChatMessageRelayListEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun relays(): List<String> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "relay") {
|
||||
@ -51,11 +49,10 @@ class ChatMessageRelayListEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10050
|
||||
const val FIXED_D_TAG = ""
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun createTagArray(relays: List<String>): Array<Array<String>> =
|
||||
relays
|
||||
|
@ -40,7 +40,7 @@ data class NAddress(
|
||||
val dTag: String,
|
||||
val relay: List<String>,
|
||||
) : Entity {
|
||||
fun aTag(): String = ATag.assembleATag(kind, author, dTag)
|
||||
fun aTag(): String = ATag.assembleATagId(kind, author, dTag)
|
||||
|
||||
companion object {
|
||||
fun parse(naddr: String): NAddress? {
|
||||
|
@ -27,10 +27,10 @@ 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.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashMipMap
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.buildHashtagTags
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.ETag
|
||||
import com.vitorpamplona.quartz.nip10Notes.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.buildUrlRefs
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
|
||||
|
@ -25,7 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.dTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
|
||||
@ -45,7 +45,7 @@ class LongTextNoteEvent(
|
||||
|
||||
override fun address(relayHint: String?) = ATag(kind, pubKey, dTag(), relayHint)
|
||||
|
||||
override fun addressTag() = ATag.assembleATag(kind, pubKey, dTag())
|
||||
override fun addressTag() = ATag.assembleATagId(kind, pubKey, dTag())
|
||||
|
||||
fun topics() = hashtags()
|
||||
|
||||
|
@ -45,8 +45,6 @@ class ChannelListEvent(
|
||||
super.countMemory() +
|
||||
32 + (publicAndPrivateEventCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0L) // rough calculation
|
||||
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
fun publicAndPrivateEvents(
|
||||
signer: NostrSigner,
|
||||
onReady: (ImmutableSet<HexKey>) -> Unit,
|
||||
@ -67,7 +65,6 @@ class ChannelListEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10005
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Public Chat List"
|
||||
|
||||
fun blockListFor(pubKeyHex: HexKey): String = "$KIND:$pubKeyHex:"
|
||||
|
@ -22,11 +22,10 @@ package com.vitorpamplona.quartz.nip30CustomEmoji
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
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.nip31Alts.AltTagSerializer
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@Immutable
|
||||
@ -37,28 +36,14 @@ class EmojiPackSelectionEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
companion object {
|
||||
const val KIND = 10030
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Emoji selection"
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag =
|
||||
ATag(
|
||||
KIND,
|
||||
pubKey,
|
||||
AdvertisedRelayListEvent.FIXED_D_TAG,
|
||||
null,
|
||||
)
|
||||
fun createAddressATag(pubKey: HexKey) = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String =
|
||||
ATag.assembleATag(
|
||||
KIND,
|
||||
pubKey,
|
||||
AdvertisedRelayListEvent.FIXED_D_TAG,
|
||||
)
|
||||
fun createAddressTag(pubKey: HexKey) = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun create(
|
||||
listOfEmojiPacks: List<ATag>?,
|
||||
|
@ -125,7 +125,7 @@ class DraftEvent(
|
||||
fun createAddressTag(
|
||||
pubKey: HexKey,
|
||||
dTag: String,
|
||||
): String = ATag.assembleATag(KIND, pubKey, dTag)
|
||||
): String = ATag.assembleATagId(KIND, pubKey, dTag)
|
||||
|
||||
fun create(
|
||||
dTag: String,
|
||||
|
@ -22,7 +22,7 @@ package com.vitorpamplona.quartz.nip50Search
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
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
|
||||
@ -37,9 +37,7 @@ class SearchRelayListEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun relays(): List<String> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "relay") {
|
||||
@ -51,11 +49,10 @@ class SearchRelayListEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10007
|
||||
const val FIXED_D_TAG = ""
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun createTagArray(relays: List<String>): Array<Array<String>> =
|
||||
relays
|
||||
|
@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parse
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
|
||||
|
@ -22,6 +22,7 @@ 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.nip31Alts.AltTagSerializer
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@ -76,7 +77,6 @@ class MuteListEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10000
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Mute List"
|
||||
|
||||
fun blockListFor(pubKeyHex: HexKey): String = "10000:$pubKeyHex:"
|
||||
|
@ -44,7 +44,7 @@ class WikiNoteEvent(
|
||||
|
||||
override fun address(relayHint: String?) = ATag(kind, pubKey, dTag(), relayHint)
|
||||
|
||||
override fun addressTag() = ATag.assembleATag(kind, pubKey, dTag())
|
||||
override fun addressTag() = ATag.assembleATagId(kind, pubKey, dTag())
|
||||
|
||||
fun topics() = hashtags()
|
||||
|
||||
|
@ -22,7 +22,7 @@ package com.vitorpamplona.quartz.nip65RelayList
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
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
|
||||
@ -37,9 +37,7 @@ class AdvertisedRelayListEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun relays(): List<AdvertisedRelayInfo> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "r") {
|
||||
@ -85,12 +83,11 @@ class AdvertisedRelayListEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10002
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Relay list to discover the user's content"
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun updateRelayList(
|
||||
earlierVersion: AdvertisedRelayListEvent,
|
||||
|
@ -25,9 +25,9 @@ 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.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashMipMap
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.buildHashtagTags
|
||||
import com.vitorpamplona.quartz.nip10Notes.ETag
|
||||
import com.vitorpamplona.quartz.nip10Notes.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.buildUrlRefs
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
|
||||
|
@ -22,6 +22,7 @@ package com.vitorpamplona.quartz.nip72ModCommunities
|
||||
|
||||
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.ATag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.parseAtag
|
||||
@ -72,7 +73,6 @@ class CommunityListEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10004
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Community List"
|
||||
|
||||
fun blockListFor(pubKeyHex: HexKey): String = "$KIND:$pubKeyHex:"
|
||||
|
@ -25,7 +25,6 @@ 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.nip19Bech32.parse
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
|
@ -22,7 +22,7 @@ package com.vitorpamplona.quartz.nip96FileStorage
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
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.nip31Alts.AltTagSerializer
|
||||
@ -36,9 +36,7 @@ class FileServersEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun servers(): List<String> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "server") {
|
||||
@ -50,12 +48,11 @@ class FileServersEvent(
|
||||
|
||||
companion object {
|
||||
const val KIND = 10096
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "File servers used by the author"
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATagId(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun createTagArray(servers: List<String>): Array<Array<String>> =
|
||||
servers
|
||||
|
Loading…
x
Reference in New Issue
Block a user