mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 11:18:24 +00:00
refactor(quartz): rename event classes to match their NIP names
Old class names drifted from the NIP wording (or described the wrong kind). Every old name stays available as a @Deprecated typealias with a ReplaceWith, so external Quartz users get an IDE quick-fix instead of a break. Wire format is unchanged: parsing goes by kind. Renames: - FollowListEvent (39089) -> StarterPackEvent - LnZapPaymentRequestEvent/ResponseEvent (NIP-47) -> NwcRequestEvent/NwcResponseEvent - VideoHorizontalEvent/VideoVerticalEvent -> AddressableNormalVideoEvent/AddressableShortVideoEvent - CalendarEvent (31924) -> CalendarCollectionEvent - HashtagListEvent -> InterestListEvent - ContactCardEvent (30382) -> UserAssertionEvent - LnZapEvent/LnZapRequestEvent/LnZapEventInterface -> ZapReceiptEvent/ZapRequestEvent/ZapReceiptEventInterface - PrivateDmEvent -> EncryptedDmEvent, DeletionEvent -> DeletionRequestEvent - LongTextNoteEvent -> LongFormContentEvent, WikiNoteEvent -> WikiArticleEvent - PeopleListEvent -> FollowSetEvent, LabeledBookmarkListEvent -> BookmarkSetEvent - RelayFeedsListEvent -> FavoriteRelayListEvent, EmojiPackSelectionEvent -> EmojiListEvent - ChannelListEvent -> PublicChatListEvent, ChatMessageRelayListEvent -> DmRelayListEvent - SealedRumorEvent -> SealEvent, FileHeaderEvent -> FileMetadataEvent - GoalEvent -> ZapGoalEvent, StatusEvent -> UserStatusEvent - NIP90*Event -> Dvm*Event (all NIP-90 events) - NIP-29 group events get the Group prefix to separate them from NIP-43: PutUser, RemoveUser, EditMetadata, DeleteEvent, CreateInvite, UpdatePinList, JoinRequest, LeaveRequest; SupportedRolesEvent -> GroupRolesEvent Merged duplicate classes for the same kind: - nip61 TokenEvent (7375) was unreachable in EventFactory; now an alias of CashuTokenEvent. - nip61 NutzapRedemptionEvent (7376) was unreachable; CashuSpendingHistoryEvent now carries its hint providers and redeemedNutzaps(), plus CashuSpendingHistoryEvent.buildNutzapRedemption. - NIP-82 SoftwareReleaseEvent (30063) was never built by EventFactory; ReleaseArtifactSetEvent now exposes appId/version/channel/assets/releaseNotes and buildSoftwareRelease, and the app no longer re-parses the event. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015VvJ8XpeYqBe8bYT3bJ7UD
This commit is contained in:
@@ -29,7 +29,7 @@ abstract class NostrSigner(val pubKey: HexKey) {
|
||||
abstract fun nip04Decrypt(ciphertext: String, fromPubKey: HexKey, onReady: (String) -> Unit)
|
||||
abstract fun nip44Encrypt(...)
|
||||
abstract fun nip44Decrypt(...)
|
||||
abstract fun decryptZapEvent(event: LnZapRequestEvent, onReady: (LnZapRequestEvent) -> Unit)
|
||||
abstract fun decryptZapEvent(event: ZapRequestEvent, onReady: (ZapRequestEvent) -> Unit)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -26,16 +26,16 @@ event signatures; the 10040→assertion link is **consumer-side convention** (se
|
||||
| Kind | Class | Kind class | d-tag = the subject | Content |
|
||||
|---|---|---|---|---|
|
||||
| 10040 | `list/TrustProviderListEvent` | replaceable | *(none — always `""`)* | NIP-44 private provider entries (optional) |
|
||||
| 30382 | `users/ContactCardEvent` | addressable | **target user's pubkey** (hex) | NIP-44 private tags (petname/summary/emoji) |
|
||||
| 30382 | `users/UserAssertionEvent` | addressable | **target user's pubkey** (hex) | NIP-44 private tags (petname/summary/emoji) |
|
||||
| 30383 | `events/EventAssertionEvent` | addressable | **target event id** (hex) | `""` |
|
||||
| 30384 | `addressables/AddressableAssertionEvent` | addressable | **target coordinate** `kind:pubkey:dtag` | `""` |
|
||||
| 30385 | `externalIds/ExternalIdAssertionEvent` | addressable | **external identifier** (e.g. `isbn:978-0-13-468599-1`) | `""` |
|
||||
|
||||
Addresses: `ContactCardEvent.createAddress(owner, target)` → `Address(30382, owner, target)`
|
||||
Addresses: `UserAssertionEvent.createAddress(owner, target)` → `Address(30382, owner, target)`
|
||||
(owner = signer, target = subject). `TrustProviderListEvent.createAddress(pubKey)` uses
|
||||
`FIXED_D_TAG = ""`. `AssertionEventTest.eventKindsAreCorrect` pins all five numbers.
|
||||
|
||||
`ContactCardEvent` is also a `SearchableEvent` — it indexes only the **public** petname/summary
|
||||
`UserAssertionEvent` is also a `SearchableEvent` — it indexes only the **public** petname/summary
|
||||
tags plus topics; the encrypted card content is intentionally never indexed.
|
||||
|
||||
## The 10040 provider entry (`ServiceProviderTag` / `ServiceType`)
|
||||
@@ -91,7 +91,7 @@ The same kind serves two roles, distinguished **by author**:
|
||||
`followers`, `hops`, …); this is what 10040 discovery points at.
|
||||
2. **The account's own contact cards (nicknames, NIP-81-style)** — signed by the account,
|
||||
one per target user. The petname, summary, and their NIP-30 emoji mappings **always live in
|
||||
the NIP-44 encrypted content, never in public tags** (`ContactCardEvent.build`/
|
||||
the NIP-44 encrypted content, never in public tags** (`UserAssertionEvent.build`/
|
||||
`updatePetNameAndSummary` strip stray public copies; asserted by `ContactCardPetNameTest`).
|
||||
`commons/.../ContactCardsState.kt` keys everything on `author == account` and ignores
|
||||
provider cards.
|
||||
@@ -104,7 +104,7 @@ value — a bad tag is *dropped*, never an error) + `assemble(value)` → `[name
|
||||
validation (rank isn't clamped, hours aren't checked against 0–23, counts may be negative) —
|
||||
consumers must defend.
|
||||
|
||||
**On 30382** (`users/tags/`, accessors on `ContactCardEvent` and as `TagArray` extensions in
|
||||
**On 30382** (`users/tags/`, accessors on `UserAssertionEvent` and as `TagArray` extensions in
|
||||
`users/TagArrayExt.kt` so they also work on decrypted private arrays):
|
||||
|
||||
| Tag name | Accessor | Type | Semantics |
|
||||
@@ -138,7 +138,7 @@ val providers: List<ServiceProviderTag> = updated.serviceProviders() //
|
||||
val private = updated.privateTags(signer)?.serviceProviders() // private side
|
||||
|
||||
// Provider-style contact card (public metrics) — the GrapeRankPublisher pattern:
|
||||
val card = ContactCardEvent.create(
|
||||
val card = UserAssertionEvent.create(
|
||||
targetUser = subjectPubkey,
|
||||
signer = providerSigner,
|
||||
publicInitializer = {
|
||||
|
||||
@@ -79,28 +79,28 @@ companion object {
|
||||
|
||||
### Zap Request/Receipt (kinds 9734, 9735)
|
||||
```kotlin
|
||||
class LnZapRequestEvent(...) : Event(...)
|
||||
class ZapRequestEvent(...) : Event(...)
|
||||
// Created by client, sent to Lightning Address
|
||||
|
||||
class LnZapEvent(...) : Event(...)
|
||||
class ZapReceiptEvent(...) : Event(...)
|
||||
// Receipt from LSP, contains bolt11 + embedded zap request
|
||||
val zapRequest: LnZapRequestEvent? by lazy { containedPost() }
|
||||
val zapRequest: ZapRequestEvent? by lazy { containedPost() }
|
||||
val amount: BigDecimal? by lazy { /* parse from bolt11 */ }
|
||||
```
|
||||
|
||||
### Long-Form Content (kind 30023)
|
||||
```kotlin
|
||||
class LongTextNoteEvent(...) : BaseAddressableEvent(...)
|
||||
class LongFormContentEvent(...) : BaseAddressableEvent(...)
|
||||
// Blog posts, articles
|
||||
// Addressable via kind:pubkey:d-tag
|
||||
```
|
||||
|
||||
### Lists (kinds 10000-30004)
|
||||
```kotlin
|
||||
sealed class PeopleListEvent : BaseAddressableEvent {
|
||||
object MuteList : PeopleListEvent(10000)
|
||||
object PinList : PeopleListEvent(10001)
|
||||
object BookmarkList : PeopleListEvent(10003)
|
||||
sealed class FollowSetEvent : BaseAddressableEvent {
|
||||
object MuteList : FollowSetEvent(10000)
|
||||
object PinList : FollowSetEvent(10001)
|
||||
object BookmarkList : FollowSetEvent(10003)
|
||||
// ... 18 list types total
|
||||
}
|
||||
```
|
||||
@@ -279,7 +279,7 @@ val metadata2 = MetadataEvent.createNew(name = "Alice Updated", picture = "url2"
|
||||
### Event Deletion
|
||||
```kotlin
|
||||
// Delete events
|
||||
val deletion = DeletionEvent.create(
|
||||
val deletion = DeletionRequestEvent.create(
|
||||
deleteEvents = listOf(eventId1, eventId2),
|
||||
reason = "Spam",
|
||||
signer = signer
|
||||
|
||||
@@ -15,7 +15,7 @@ under `experimental/`**. The categorized list below may lag behind —
|
||||
| 04 | `nip04Dm/` | EncryptedDmEvent.kt | Legacy encrypted DMs (deprecated for NIP-17) |
|
||||
| 05 | `nip05DnsIdentifiers/` | UserHexResolver.kt, Nip05Client.kt | Internet identifiers; `resolveUserHexOrNull` resolves hex/npub/nprofile/`name@domain` → pubkey (see references/nip05-identifiers.md) |
|
||||
| 06 | `nip06KeyDerivation/` | Mnemonic-related | BIP-39 key derivation |
|
||||
| 09 | `nip09Deletions/` | DeletionEvent.kt | Event deletion requests (kind 5) |
|
||||
| 09 | `nip09Deletions/` | DeletionRequestEvent.kt | Event deletion requests (kind 5) |
|
||||
| 11 | `nip11RelayInfo/` | RelayInformation.kt | Relay metadata |
|
||||
| 13 | `nip13Pow/` | ProofOfWork.kt | Proof of work |
|
||||
| 14 | `nip14Subject/` | Subject tags | Subject tags for text notes |
|
||||
@@ -33,7 +33,7 @@ ent for NIP-04) |
|
||||
| 10 | `nip10Notes/` | TextNoteEvent.kt | Text notes with threading (kind 1) |
|
||||
| 18 | `nip18Reposts/` | RepostEvent.kt, GenericRepostEvent.kt | Reposts (kind 6, 16) |
|
||||
| 22 | `nip22Comments/` | CommentEvent.kt | Comments (kind 1111) |
|
||||
| 23 | `nip23LongContent/` | LongTextNoteEvent.kt | Long-form content (kind 30023) |
|
||||
| 23 | `nip23LongContent/` | LongFormContentEvent.kt | Long-form content (kind 30023) |
|
||||
| 25 | `nip25Reactions/` | ReactionEvent.kt | Reactions (kind 7) |
|
||||
| 31 | `nip31Alts/` | Alt tags | Alt description tags |
|
||||
| 36 | `nip36SensitiveContent/` | Content warnings | Content warning tags |
|
||||
@@ -62,7 +62,7 @@ ent for NIP-04) |
|
||||
| 46 | `nip46RemoteSigner/` | NostrConnectEvent.kt | Remote signer protocol (bunker) |
|
||||
| 47 | `nip47WalletConnect/` | Nostr Wallet Connect | Wallet connection protocol |
|
||||
| 56 | `nip56Reports/` | ReportEvent.kt | Reports (kind 1984) |
|
||||
| 57 | `nip57Zaps/` | LnZapEvent.kt, LnZapRequestEvent.kt | Lightning zaps (kinds 9734, 9735) |
|
||||
| 57 | `nip57Zaps/` | ZapReceiptEvent.kt, ZapRequestEvent.kt | Lightning zaps (kinds 9734, 9735) |
|
||||
| 58 | `nip58Badges/` | Badge events | Badge definitions & awards (kinds 30009, 8) |
|
||||
| 59 | `nip59Giftwrap/` | GiftWrapEvent.kt | Gift-wrapped events for privacy |
|
||||
| 75 | `nip75ZapGoals/` | ZapGoalEvent.kt | Zap goals (kind 9041) |
|
||||
@@ -76,7 +76,7 @@ ent for NIP-04) |
|
||||
| 35 | `nip35Torrents/` | Torrent events | Torrent tracking |
|
||||
| 52 | `nip52Calendar/` | Calendar events | Calendar time-based/date-based (kinds 31922-31925) |
|
||||
| 53 | `nip53LiveActivities/` | LiveActivitiesEvent.kt | Live events/streaming (kind 30311) |
|
||||
| 54 | `nip54Wiki/` | WikiNoteEvent.kt | Wiki pages (kind 30818) |
|
||||
| 54 | `nip54Wiki/` | WikiArticleEvent.kt | Wiki pages (kind 30818) |
|
||||
| 68 | `nip68Picture/` | Picture metadata | Picture metadata |
|
||||
| 71 | `nip71Video/` | 7 video event types | Video events (kinds 34235, 35235, 1234, 1235) |
|
||||
| 72 | `nip72ModCommunities/` | Community events | Moderated communities (kinds 34550, 34551, 9041) |
|
||||
@@ -84,7 +84,7 @@ ent for NIP-04) |
|
||||
| 89 | `nip89AppHandlers/` | AppDefinitionEvent.kt | App recommendations (kinds 31990, 31989) |
|
||||
| 90 | `nip90Dvms/` | DVM job events | Data Vending Machines (DVMs) (kinds 5000-7000) |
|
||||
| 92 | `nip92IMeta/` | IMeta tags | Image metadata tags |
|
||||
| 94 | `nip94FileMetadata/` | FileHeaderEvent.kt, FileStorageEvent.kt | File metadata (kind 1063) |
|
||||
| 94 | `nip94FileMetadata/` | FileMetadataEvent.kt, FileStorageEvent.kt | File metadata (kind 1063) |
|
||||
| 96 | `nip96FileStorage/` | HTTP file storage | HTTP-based file storage |
|
||||
| 99 | `nip99Classifieds/` | ClassifiedsEvent.kt | Classifieds/marketplace (kind 30402) |
|
||||
| A0 | `nipA0VoiceMessages/` | Voice messages | Voice message events |
|
||||
@@ -93,7 +93,7 @@ ent for NIP-04) |
|
||||
### Web/Storage/Other
|
||||
| NIP | Directory | Key Files | Description |
|
||||
|-----|-----------|-----------|-------------|
|
||||
| 38 | `nip38UserStatus/` | StatusEvent.kt | User status (kind 30315) |
|
||||
| 38 | `nip38UserStatus/` | UserStatusEvent.kt | User status (kind 30315) |
|
||||
| 60 | `nip60Payment/` | Wallet events | Wallet info (kind 13194) |
|
||||
| 61 | `nip61PaymentRequest/` | Nut zaps | Cashu payment requests |
|
||||
| 64 | `nip64Chess/` | Chess moves | Chess move events |
|
||||
|
||||
@@ -650,15 +650,15 @@ val custom = ReactionEvent.build("🤙", targetEvent)
|
||||
### NIP-57 — Zap request (kind 9734)
|
||||
|
||||
```kotlin
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
|
||||
val template = LnZapRequestEvent.build(
|
||||
val template = ZapRequestEvent.build(
|
||||
message = "Great post!",
|
||||
relays = listOf("wss://relay.damus.io"),
|
||||
target = targetEvent,
|
||||
zapType = LnZapRequestEvent.ZapType.PUBLIC
|
||||
zapType = ZapRequestEvent.ZapType.PUBLIC
|
||||
)
|
||||
val zapRequest: LnZapRequestEvent = signer.sign(template)
|
||||
val zapRequest: ZapRequestEvent = signer.sign(template)
|
||||
```
|
||||
|
||||
### NIP-59 — Gift wrap / sealed DM (kind 1059 + 14)
|
||||
@@ -678,9 +678,9 @@ val (dmEvent, giftWrap) = NIP17Factory.create(
|
||||
### NIP-23 — Long-form article (kind 30023)
|
||||
|
||||
```kotlin
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
|
||||
val template = LongTextNoteEvent.build(
|
||||
val template = LongFormContentEvent.build(
|
||||
body = markdownContent,
|
||||
title = "My Article",
|
||||
image = "https://example.com/cover.jpg",
|
||||
@@ -882,16 +882,16 @@ use `Nip11RelayInformation.fromJson(json)`.
|
||||
| 0 | User metadata | 01 | `MetadataEvent` |
|
||||
| 1 | Text note | 10 | `TextNoteEvent` |
|
||||
| 3 | Follow list | 02 | `ContactListEvent` |
|
||||
| 4 | Legacy DM | 04 | `PrivateDmEvent` |
|
||||
| 5 | Deletion | 09 | `DeletionEvent` |
|
||||
| 4 | Legacy DM | 04 | `EncryptedDmEvent` |
|
||||
| 5 | Deletion | 09 | `DeletionRequestEvent` |
|
||||
| 6 | Repost | 18 | `RepostEvent` |
|
||||
| 7 | Reaction | 25 | `ReactionEvent` |
|
||||
| 14 | Chat message (sealed) | 17 | `NIP17GroupMessage` |
|
||||
| 1059 | Gift wrap | 59 | `GiftWrapEvent` |
|
||||
| 9734 | Zap request | 57 | `LnZapRequestEvent` |
|
||||
| 9735 | Zap receipt | 57 | `LnZapEvent` |
|
||||
| 9734 | Zap request | 57 | `ZapRequestEvent` |
|
||||
| 9735 | Zap receipt | 57 | `ZapReceiptEvent` |
|
||||
| 10002 | Relay list | 65 | `AdvertisedRelayListEvent` |
|
||||
| 30023 | Long-form content | 23 | `LongTextNoteEvent` |
|
||||
| 30023 | Long-form content | 23 | `LongFormContentEvent` |
|
||||
|
||||
## Related Skills
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 42 | ChannelMessageEvent | nip28PublicChat/message | `content` |
|
||||
| 54 | PodcastEpisodeEvent | nipF4Podcasts/episode | `listOfNotNull(title(), description(), content)` NL |
|
||||
| 1010 | TextNoteModificationEvent | experimental/edits | `listOfNotNull(content, summary())` NL (content first) |
|
||||
| 1063 | FileHeaderEvent | nip94FileMetadata | `listOfNotNull(summary(), content)` NL |
|
||||
| 1063 | FileMetadataEvent | nip94FileMetadata | `listOfNotNull(summary(), content)` NL |
|
||||
| 1065 | FileStorageHeaderEvent | experimental/nip95/header | `listOfNotNull(summary())` NL |
|
||||
| 1068 | PollEvent | nip88Polls/poll | `buildString { append(content); options().forEach { append('\n').append(it.label) } }` |
|
||||
| 1111 | CommentEvent | nip22Comments | `(listOf(content) + tags.hashtags())` NL |
|
||||
@@ -48,20 +48,20 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 2004 | TorrentCommentEvent | nip35Torrents | `content` |
|
||||
| 2473 | BirdDetectionEvent | experimental/birdstar | `listOfNotNull(summary(), speciesName())` NL |
|
||||
| 3302 | ConcordChatEditEvent | concord/cord03Channels | `content` |
|
||||
| 5050 | NIP90TextGenerationRequestEvent | nip90Dvms/textGeneration | `inputs().filter { it.type == "prompt" \|\| it.type == "text" }.joinToString(" ") { it.value }` (SP) |
|
||||
| 5100 | NIP90ImageGenerationRequestEvent | nip90Dvms/imageGeneration | `listOfNotNull(prompt(), negativePrompt()).joinToString(" ")` (SP) |
|
||||
| 5050 | DvmTextGenerationRequestEvent | nip90Dvms/textGeneration | `inputs().filter { it.type == "prompt" \|\| it.type == "text" }.joinToString(" ") { it.value }` (SP) |
|
||||
| 5100 | DvmImageGenerationRequestEvent | nip90Dvms/imageGeneration | `listOfNotNull(prompt(), negativePrompt()).joinToString(" ")` (SP) |
|
||||
| 5129 | NappletSnapshotEvent | nip5dNapplets | `listOfNotNull(title(), description())` NL |
|
||||
| 5250 | NIP90TextToSpeechRequestEvent | nip90Dvms/textToSpeech | `text() ?: ""` |
|
||||
| 5302 | NIP90ContentSearchRequestEvent | nip90Dvms/contentSearch | `searchQuery() ?: ""` |
|
||||
| 5303 | NIP90PeopleSearchRequestEvent | nip90Dvms/peopleSearch | `searchQuery() ?: ""` |
|
||||
| 5250 | DvmTextToSpeechRequestEvent | nip90Dvms/textToSpeech | `text() ?: ""` |
|
||||
| 5302 | DvmContentSearchRequestEvent | nip90Dvms/contentSearch | `searchQuery() ?: ""` |
|
||||
| 5303 | DvmPeopleSearchRequestEvent | nip90Dvms/peopleSearch | `searchQuery() ?: ""` |
|
||||
| 6969 | ZapPollEvent | experimental/zapPolls | `buildString { append(content); pollOptionsArray().forEach { append('\n').append(it.descriptor) } }` |
|
||||
| 7516 | GeocacheFoundLogEvent | nipCCGeocaching/foundLog | `content` |
|
||||
| 8333 | OnchainZapEvent | nipBCOnchainZaps/zap | `content` |
|
||||
| 9002 | EditMetadataEvent | nip29RelayGroups/moderation | `(listOfNotNull(name(), about()) + hashtags())` NL |
|
||||
| 9041 | GoalEvent | nip75ZapGoals | `listOfNotNull(summary(), content)` NL |
|
||||
| 9002 | GroupEditMetadataEvent | nip29RelayGroups/moderation | `(listOfNotNull(name(), about()) + hashtags())` NL |
|
||||
| 9041 | ZapGoalEvent | nip75ZapGoals | `listOfNotNull(summary(), content)` NL |
|
||||
| 9321 | NutzapEvent | nip61Nutzaps/nutzap | `content` |
|
||||
| 9734 | LnZapRequestEvent | nip57Zaps | `content` |
|
||||
| 9735 | LnZapEvent | nip57Zaps | `zapRequest?.content.orEmpty()` — indexes the **embedded 9734's** content |
|
||||
| 9734 | ZapRequestEvent | nip57Zaps | `content` |
|
||||
| 9735 | ZapReceiptEvent | nip57Zaps | `zapRequest?.content.orEmpty()` — indexes the **embedded 9734's** content |
|
||||
| 9736 | Bolt12ZapEvent | nipB1Bolt12Zaps/zap | `content` |
|
||||
| 9737 | Bolt12ZapIntentEvent | nipB1Bolt12Zaps/intent | `content` |
|
||||
| 9802 | HighlightEvent | nip84Highlights | `listOfNotNull(comment(), context(), content)` NL |
|
||||
@@ -74,10 +74,10 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 12473 | BirdexEvent | experimental/birdstar | `(listOfNotNull(summary()) + speciesNames())` NL |
|
||||
| 15128 | RootSiteEvent | nip5aStaticWebsites | `listOfNotNull(title(), description())` NL |
|
||||
| 15129 | RootNappletEvent | nip5dNapplets | `listOfNotNull(title(), description())` NL |
|
||||
| 30000 | PeopleListEvent | nip51Lists/peopleList | `listOfNotNull(titleOrName(), description())` NL |
|
||||
| 30000 | FollowSetEvent | nip51Lists/peopleList | `listOfNotNull(titleOrName(), description())` NL |
|
||||
| 30001 | OldBookmarkListEvent | nip51Lists/bookmarkList | `listOfNotNull(title())` NL |
|
||||
| 30002 | RelaySetEvent | nip51Lists/relaySets | `listOfNotNull(title(), description())` NL |
|
||||
| 30003 | LabeledBookmarkListEvent | nip51Lists/labeledBookmarkList | `listOfNotNull(titleOrName(), description())` NL |
|
||||
| 30003 | BookmarkSetEvent | nip51Lists/labeledBookmarkList | `listOfNotNull(titleOrName(), description())` NL |
|
||||
| 30004 | ArticleCurationSetEvent | nip51Lists/articleCurationSet | `listOfNotNull(title(), description())` NL |
|
||||
| 30005 | VideoCurationSetEvent | nip51Lists/videoCurationSet | `listOfNotNull(title(), description())` NL |
|
||||
| 30006 | PictureCurationSetEvent | nip51Lists/pictureCurationSet | `listOfNotNull(title(), description())` NL |
|
||||
@@ -87,7 +87,7 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 30018 | ProductEvent | nip15Marketplace/product | `productData()?.let { (listOfNotNull(it.name, it.description) + categories()).joinToString("\n") } ?: ""` |
|
||||
| 30019 | MarketplaceEvent | nip15Marketplace/marketplace | `marketplaceData()?.let { listOfNotNull(it.name, it.about).joinToString("\n") } ?: ""` |
|
||||
| 30020 | AuctionEvent | nip15Marketplace/auction | `auctionData()?.let { (listOfNotNull(it.name, it.description) + tags.hashtags()).joinToString("\n") } ?: ""` |
|
||||
| 30023 | LongTextNoteEvent | nip23LongContent | `listOfNotNull(title(), summary(), content)` NL |
|
||||
| 30023 | LongFormContentEvent | nip23LongContent | `listOfNotNull(title(), summary(), content)` NL |
|
||||
| 30030 | EmojiPackEvent | nip30CustomEmoji/pack | `listOfNotNull(titleOrName(), description(), content)` NL |
|
||||
| 30054 | Podcasting20EpisodeEvent | nipXXPodcasting20/episode | `(listOfNotNull(title(), description(), content) + topics())` NL |
|
||||
| 30055 | Podcasting20TrailerEvent | nipXXPodcasting20/trailer | `listOfNotNull(title(), content)` NL |
|
||||
@@ -101,8 +101,8 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 30311 | LiveActivitiesEvent | nip53LiveActivities/streaming | `listOfNotNull(title(), summary(), content)` NL |
|
||||
| 30312 | MeetingSpaceEvent | nip53LiveActivities/meetingSpaces | `listOfNotNull(room(), summary(), content)` NL |
|
||||
| 30313 | MeetingRoomEvent | nip53LiveActivities/meetingSpaces | `listOfNotNull(title(), summary())` NL |
|
||||
| 30315 | StatusEvent | nip38UserStatus | `content` |
|
||||
| 30382 | ContactCardEvent | nip85TrustedAssertions/users | `(listOfNotNull(petName(), summary()) + topics())` NL — public tags only, never the NIP-44 content |
|
||||
| 30315 | UserStatusEvent | nip38UserStatus | `content` |
|
||||
| 30382 | UserAssertionEvent | nip85TrustedAssertions/users | `(listOfNotNull(petName(), summary()) + topics())` NL — public tags only, never the NIP-44 content |
|
||||
| 30392 | UserTrustedListEvent | experimental/trustedLists/users | inherited `TrustedListEvent`: `title() ?: ""` — the label only; `metric`/`d` are machine ids and `content` is a JSON echo of the membership |
|
||||
| 30393 | EventTrustedListEvent | experimental/trustedLists/events | inherited `TrustedListEvent`: `title() ?: ""` |
|
||||
| 30394 | AddressableTrustedListEvent | experimental/trustedLists/addressables | inherited `TrustedListEvent`: `title() ?: ""` |
|
||||
@@ -111,7 +111,7 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 30617 | GitRepositoryEvent | nip34Git/repository | `listOfNotNull(name(), description(), content)` NL |
|
||||
| 30620 | WorkflowDefEvent | buzz/workflow | `listOfNotNull(name(), content)` NL |
|
||||
| 30817 | NipTextEvent | experimental/nipsOnNostr | `listOfNotNull(title(), content)` NL |
|
||||
| 30818 | WikiNoteEvent | nip54Wiki | `listOfNotNull(title(), summary(), content)` NL |
|
||||
| 30818 | WikiArticleEvent | nip54Wiki | `listOfNotNull(title(), summary(), content)` NL |
|
||||
| 31337 | AudioTrackEvent | experimental/audio/track | `listOfNotNull(subject())` NL |
|
||||
| 31871 | AttestationEvent | experimental/attestations/attestation | `content` |
|
||||
| 31872 | AttestationRequestEvent | experimental/attestations/request | `content` |
|
||||
@@ -119,15 +119,15 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 31890 | FeedDefinitionEvent | feedDefinition | `title().orEmpty()` |
|
||||
| 31922 | CalendarDateSlotEvent | nip52Calendar/appt/day | `listOfNotNull(title(), summary(), content)` NL |
|
||||
| 31923 | CalendarTimeSlotEvent | nip52Calendar/appt/time | `listOfNotNull(title(), summary(), content)` NL |
|
||||
| 31924 | CalendarEvent | nip52Calendar/calendar | `listOfNotNull(title(), content)` NL |
|
||||
| 31924 | CalendarCollectionEvent | nip52Calendar/calendar | `listOfNotNull(title(), content)` NL |
|
||||
| 31925 | CalendarRSVPEvent | nip52Calendar/rsvp | `content` |
|
||||
| 31990 | AppDefinitionEvent | nip89AppHandlers/definition | `appMetaData()?.let { listOfNotNull(it.name, it.username, it.displayName, it.about, it.nip05, it.lud06, it.lud16, it.website, it.picture, it.banner, it.image).joinToString(" ") } ?: ""` (SP) |
|
||||
| 32267 | SoftwareApplicationEvent | experimental/nip82SoftwareApps/application | `listOfNotNull(name(), summary(), content)` NL |
|
||||
| 33401 | ExerciseTemplateEvent | experimental/fitness/workout | `listOfNotNull(title(), content)` NL |
|
||||
| 33863 | FundraiserEvent | experimental/agora | `listOfNotNull(title(), content)` NL |
|
||||
| 34139 | MusicPlaylistEvent | experimental/music/playlist | `listOfNotNull(title(), description(), content)` NL |
|
||||
| 34235 | VideoHorizontalEvent | nip71Video | inherited `AddressableVideoEvent`: `listOfNotNull(title(), content)` NL |
|
||||
| 34236 | VideoVerticalEvent | nip71Video | inherited `AddressableVideoEvent`: `listOfNotNull(title(), content)` NL |
|
||||
| 34235 | AddressableNormalVideoEvent | nip71Video | inherited `AddressableVideoEvent`: `listOfNotNull(title(), content)` NL |
|
||||
| 34236 | AddressableShortVideoEvent | nip71Video | inherited `AddressableVideoEvent`: `listOfNotNull(title(), content)` NL |
|
||||
| 34550 | CommunityDefinitionEvent | nip72ModCommunities/definition | `listOfNotNull(name(), description(), rules(), content)` NL |
|
||||
| 35128 | NamedSiteEvent | nip5aStaticWebsites | `listOfNotNull(title(), description())` NL |
|
||||
| 35129 | NamedNappletEvent | nip5dNapplets | `listOfNotNull(title(), description())` NL |
|
||||
@@ -138,7 +138,7 @@ Separator legend: **NL** = `joinToString("\n")`, **SP** = `joinToString(" ")`.
|
||||
| 38192 | Ps1SaveEvent | experimental/ps1saves | `listOfNotNull(summary(), saveTitle(), region(), filename())` NL |
|
||||
| 38383 | P2POrderEvent | nip69P2pOrderEvents | `(listOfNotNull(makerName(), currency()) + paymentMethods().orEmpty()).joinToString(" ")` (SP) |
|
||||
| 39000 | GroupMetadataEvent | nip29RelayGroups/metadata | `listOfNotNull(name(), about())` NL |
|
||||
| 39089 | FollowListEvent | nip51Lists/followList | `listOfNotNull(title(), description())` NL |
|
||||
| 39089 | StarterPackEvent | nip51Lists/followList | `listOfNotNull(title(), description())` NL |
|
||||
| 39092 | MediaStarterPackEvent | nip51Lists/mediaStarterPack | `listOfNotNull(title(), description())` NL |
|
||||
| 39307 | TextTrackEvent | nip71Video/textTrack | `content` (the WebVTT cue text) |
|
||||
| 39701 | WebBookmarkEvent | nipB0WebBookmarks | `listOfNotNull(title(), description())` NL |
|
||||
|
||||
@@ -54,19 +54,19 @@ import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.PublicChatListEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.privateOutbox.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.FavoriteRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.simpleGroupList.SimpleGroupListEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
@@ -887,19 +887,19 @@ object LocalPreferences {
|
||||
val pendingAttestations = async { parseOrNull<Map<HexKey, String>>(pendingAttestationsStr) ?: mapOf() }
|
||||
val latestUserMetadata = async { parseEventOrNull<MetadataEvent>(latestUserMetadataStr) }
|
||||
val latestContactList = async { parseEventOrNull<ContactListEvent>(latestContactListStr) }
|
||||
val latestDmRelayList = async { parseEventOrNull<ChatMessageRelayListEvent>(latestDmRelayListStr) }
|
||||
val latestDmRelayList = async { parseEventOrNull<DmRelayListEvent>(latestDmRelayListStr) }
|
||||
val latestNip65RelayList = async { parseEventOrNull<AdvertisedRelayListEvent>(latestNip65RelayListStr) }
|
||||
val latestSearchRelayList = async { parseEventOrNull<SearchRelayListEvent>(latestSearchRelayListStr) }
|
||||
val latestIndexRelayList = async { parseEventOrNull<IndexerRelayListEvent>(latestIndexRelayListStr) }
|
||||
val latestRelayFeedsList = async { parseEventOrNull<RelayFeedsListEvent>(latestRelayFeedsListStr) }
|
||||
val latestRelayFeedsList = async { parseEventOrNull<FavoriteRelayListEvent>(latestRelayFeedsListStr) }
|
||||
val latestBlockedRelayList = async { parseEventOrNull<BlockedRelayListEvent>(latestBlockedRelayListStr) }
|
||||
val latestTrustedRelayList = async { parseEventOrNull<TrustedRelayListEvent>(latestTrustedRelayListStr) }
|
||||
val latestMuteList = async { parseEventOrNull<MuteListEvent>(latestMuteListStr) }
|
||||
val latestPrivateHomeRelayList = async { parseEventOrNull<PrivateOutboxRelayListEvent>(latestPrivateHomeRelayListStr) }
|
||||
val latestAppSpecificData = async { parseEventOrNull<AppSpecificDataEvent>(latestAppSpecificDataStr) }
|
||||
val latestChannelList = async { parseEventOrNull<ChannelListEvent>(latestChannelListStr) }
|
||||
val latestChannelList = async { parseEventOrNull<PublicChatListEvent>(latestChannelListStr) }
|
||||
val latestCommunityList = async { parseEventOrNull<CommunityListEvent>(latestCommunityListStr) }
|
||||
val latestHashtagList = async { parseEventOrNull<HashtagListEvent>(latestHashtagListStr) }
|
||||
val latestHashtagList = async { parseEventOrNull<InterestListEvent>(latestHashtagListStr) }
|
||||
val latestGeohashList = async { parseEventOrNull<GeohashListEvent>(latestGeohashListStr) }
|
||||
val latestEphemeralList = async { parseEventOrNull<EphemeralChatListEvent>(latestEphemeralListStr) }
|
||||
val latestRelayGroupList = async { parseEventOrNull<SimpleGroupListEvent>(latestRelayGroupListStr) }
|
||||
|
||||
@@ -238,8 +238,8 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.references.references
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsResolver
|
||||
import com.vitorpamplona.quartz.nip04Dm.PrivateDMCache
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findNostrUris
|
||||
@@ -281,10 +281,10 @@ import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.PrivateZapCache
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.zapSplits
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiser
|
||||
@@ -320,10 +320,10 @@ import com.vitorpamplona.quartz.nip88Polls.poll.tags.PollType
|
||||
import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.NostrSignerWithClientTag
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.withoutClientTag
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.NIP90ContentDiscoveryRequestEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.DvmContentDiscoveryRequestEvent
|
||||
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
|
||||
import com.vitorpamplona.quartz.nip92IMeta.imetas
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.blurhash
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.dimension
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.fileSize
|
||||
@@ -1283,7 +1283,7 @@ class Account(
|
||||
|
||||
suspend fun updateZapAmounts(
|
||||
amountSet: List<Long>,
|
||||
selectedZapType: LnZapEvent.ZapType,
|
||||
selectedZapType: ZapReceiptEvent.ZapType,
|
||||
nip47Update: Nip47WalletConnect.Nip47URINorm?,
|
||||
) {
|
||||
var changed = false
|
||||
@@ -1707,7 +1707,7 @@ class Account(
|
||||
if (myNotes.isNotEmpty()) {
|
||||
// chunks in 200 elements to avoid going over the 65KB limit for events.
|
||||
myNotes.chunked(200).forEach { chunkedList ->
|
||||
val template = DeletionEvent.build(chunkedList.mapNotNull { it.event })
|
||||
val template = DeletionRequestEvent.build(chunkedList.mapNotNull { it.event })
|
||||
val deletionEvent = signer.sign(template)
|
||||
val myRelayList = outboxRelays.flow.value.toMutableSet()
|
||||
chunkedList.forEach {
|
||||
@@ -1738,7 +1738,7 @@ class Account(
|
||||
|
||||
val recipients = (targetEvent.taggedUserIds() + targetEvent.pubKey).distinct().minus(signer.pubKey)
|
||||
broadcastPrivately(
|
||||
NIP17Factory().createDeletionNIP17(DeletionEvent.build(myRumors), recipients, signer),
|
||||
NIP17Factory().createDeletionNIP17(DeletionRequestEvent.build(myRumors), recipients, signer),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1749,7 +1749,7 @@ class Account(
|
||||
if (!isWriteable()) return
|
||||
if (event.pubKey != signer.pubKey) return
|
||||
|
||||
val deletionEvent = signer.sign(DeletionEvent.build(listOf(event)))
|
||||
val deletionEvent = signer.sign(DeletionRequestEvent.build(listOf(event)))
|
||||
client.publish(deletionEvent, outboxRelays.flow.value + additionalRelays)
|
||||
cache.justConsumeMyOwnEvent(deletionEvent)
|
||||
}
|
||||
@@ -2176,7 +2176,7 @@ class Account(
|
||||
suspend fun deleteWebBookmark(event: WebBookmarkEvent) {
|
||||
if (!isWriteable()) return
|
||||
|
||||
val template = DeletionEvent.build(listOf(event))
|
||||
val template = DeletionRequestEvent.build(listOf(event))
|
||||
val signedEvent = signer.sign(template)
|
||||
|
||||
cache.justConsumeMyOwnEvent(signedEvent)
|
||||
@@ -2212,7 +2212,7 @@ class Account(
|
||||
if (!isWriteable()) return
|
||||
if (event.pubKey != signer.pubKey) return
|
||||
|
||||
val template = DeletionEvent.build(listOf(event))
|
||||
val template = DeletionRequestEvent.build(listOf(event))
|
||||
val signedEvent = signer.sign(template)
|
||||
|
||||
cache.justConsumeMyOwnEvent(signedEvent)
|
||||
@@ -2597,7 +2597,7 @@ class Account(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FileHeaderEvent.build(url, alt) {
|
||||
FileMetadataEvent.build(url, alt) {
|
||||
hash(headerInfo.hash)
|
||||
fileSize(headerInfo.size)
|
||||
|
||||
@@ -2711,7 +2711,7 @@ class Account(
|
||||
val extraRelays = draftNote.relays
|
||||
|
||||
val deletedDraft = DraftWrapEvent.createDeletedEvent(draftTag, signer)
|
||||
val deletionEvent = signer.sign(DeletionEvent.build(listOf(deletedDraft)))
|
||||
val deletionEvent = signer.sign(DeletionRequestEvent.build(listOf(deletedDraft)))
|
||||
|
||||
val relayList = (privateStorageRelayList.flow.value + localRelayList.flow.value + extraRelays).toSet()
|
||||
|
||||
@@ -2937,7 +2937,7 @@ class Account(
|
||||
broadcast.forEach { client.publish(it, relayList) }
|
||||
}
|
||||
|
||||
override suspend fun sendNip04PrivateMessage(eventTemplate: EventTemplate<PrivateDmEvent>) {
|
||||
override suspend fun sendNip04PrivateMessage(eventTemplate: EventTemplate<EncryptedDmEvent>) {
|
||||
if (!isWriteable()) return
|
||||
|
||||
val newEvent = signer.sign(eventTemplate)
|
||||
@@ -3481,10 +3481,10 @@ class Account(
|
||||
|
||||
suspend fun requestDVMContentDiscovery(
|
||||
dvmPublicKey: User,
|
||||
onReady: (event: NIP90ContentDiscoveryRequestEvent, relays: Set<NormalizedRelayUrl>) -> Unit,
|
||||
onReady: (event: DvmContentDiscoveryRequestEvent, relays: Set<NormalizedRelayUrl>) -> Unit,
|
||||
) {
|
||||
val relays = nip65RelayList.inboxFlow.value.toSet()
|
||||
val request = signer.sign<NIP90ContentDiscoveryRequestEvent>(NIP90ContentDiscoveryRequestEvent.build(dvmPublicKey.pubkeyHex, signer.pubKey, relays))
|
||||
val request = signer.sign<DvmContentDiscoveryRequestEvent>(DvmContentDiscoveryRequestEvent.build(dvmPublicKey.pubkeyHex, signer.pubKey, relays))
|
||||
|
||||
val relayList =
|
||||
dvmPublicKey.inboxRelays()?.toSet()?.ifEmpty { null }
|
||||
@@ -3503,8 +3503,8 @@ class Account(
|
||||
|
||||
return if (isWriteable()) {
|
||||
when {
|
||||
event is PrivateDmEvent -> privateDMDecryptionCache.cachedDM(event)
|
||||
event is LnZapRequestEvent && event.isPrivateZap() -> privateZapsDecryptionCache.cachedPrivateZap(event)?.content
|
||||
event is EncryptedDmEvent -> privateDMDecryptionCache.cachedDM(event)
|
||||
event is ZapRequestEvent && event.isPrivateZap() -> privateZapsDecryptionCache.cachedPrivateZap(event)?.content
|
||||
event is DraftWrapEvent -> draftsDecryptionCache.preCachedDraft(event)?.content
|
||||
else -> event.content
|
||||
}
|
||||
@@ -3519,11 +3519,11 @@ class Account(
|
||||
suspend fun decryptContent(note: Note): String? {
|
||||
val event = note.event
|
||||
return when {
|
||||
event is PrivateDmEvent && isWriteable() -> {
|
||||
event is EncryptedDmEvent && isWriteable() -> {
|
||||
privateDMDecryptionCache.decryptDM(event)
|
||||
}
|
||||
|
||||
event is LnZapRequestEvent && isWriteable() -> {
|
||||
event is ZapRequestEvent && isWriteable() -> {
|
||||
if (event.isPrivateZap()) {
|
||||
if (isWriteable()) {
|
||||
privateZapsDecryptionCache.decryptPrivateZap(event)?.content
|
||||
@@ -3550,7 +3550,7 @@ class Account(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun decryptZapOrNull(event: LnZapRequestEvent): LnZapPrivateEvent? = if (event.isPrivateZap() && isWriteable()) privateZapsDecryptionCache.decryptPrivateZap(event) else null
|
||||
suspend fun decryptZapOrNull(event: ZapRequestEvent): LnZapPrivateEvent? = if (event.isPrivateZap() && isWriteable()) privateZapsDecryptionCache.decryptPrivateZap(event) else null
|
||||
|
||||
fun isAllHidden(users: Set<HexKey>): Boolean = users.all { isHidden(it) }
|
||||
|
||||
@@ -3602,7 +3602,7 @@ class Account(
|
||||
note.countReportAuthorsBy(followingKeySet()) < reportWarningThreshold
|
||||
}
|
||||
|
||||
fun isDecryptedContentHidden(noteEvent: PrivateDmEvent): Boolean =
|
||||
fun isDecryptedContentHidden(noteEvent: EncryptedDmEvent): Boolean =
|
||||
if (hiddenUsers.flow.value.hiddenWordsCase
|
||||
.isNotEmpty()
|
||||
) {
|
||||
|
||||
+16
-16
@@ -58,15 +58,15 @@ import com.vitorpamplona.quartz.nip29RelayGroups.GroupId
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.hTag
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.metadata.GroupMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.CreateGroupEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.CreateInviteEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.DeleteGroupEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.EditMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.PutUserEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.RemoveUserEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.UpdatePinListEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.GroupCreateInviteEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.GroupEditMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.GroupPutUserEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.GroupRemoveUserEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.GroupUpdatePinListEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.moderation.previous
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.request.JoinRequestEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.request.LeaveRequestEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.request.GroupJoinRequestEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.request.GroupLeaveRequestEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.tags.GroupIdTag
|
||||
import com.vitorpamplona.quartz.nip7DThreads.ThreadEvent
|
||||
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||
@@ -92,7 +92,7 @@ class AccountRelayGroupActions(
|
||||
channel: RelayGroupChannel,
|
||||
code: String? = null,
|
||||
) {
|
||||
val template = JoinRequestEvent.build(channel.groupId.id, inviteCode = code)
|
||||
val template = GroupJoinRequestEvent.build(channel.groupId.id, inviteCode = code)
|
||||
account.broadcaster.signAndSendPrivatelyOrBroadcast(template) { channel.relays().toList() }
|
||||
account.follow(channel)
|
||||
}
|
||||
@@ -295,7 +295,7 @@ class AccountRelayGroupActions(
|
||||
|
||||
/** Send a kind 9022 leave request to the host relay and drop it from our list. */
|
||||
suspend fun leaveRelayGroup(channel: RelayGroupChannel) {
|
||||
val template = LeaveRequestEvent.build(channel.groupId.id)
|
||||
val template = GroupLeaveRequestEvent.build(channel.groupId.id)
|
||||
account.broadcaster.signAndSendPrivatelyOrBroadcast(template) { channel.relays().toList() }
|
||||
account.unfollow(channel)
|
||||
}
|
||||
@@ -351,7 +351,7 @@ class AccountRelayGroupActions(
|
||||
) { listOf(relay) }
|
||||
|
||||
val edit =
|
||||
EditMetadataEvent.build(
|
||||
GroupEditMetadataEvent.build(
|
||||
groupId,
|
||||
name = name,
|
||||
about = about,
|
||||
@@ -405,7 +405,7 @@ class AccountRelayGroupActions(
|
||||
channel: RelayGroupChannel,
|
||||
code: String,
|
||||
) {
|
||||
val template = CreateInviteEvent.build(channel.groupId.id, code)
|
||||
val template = GroupCreateInviteEvent.build(channel.groupId.id, code)
|
||||
account.broadcaster.signAndSendPrivatelyOrBroadcast(template) { channel.relays().toList() }
|
||||
}
|
||||
|
||||
@@ -418,7 +418,7 @@ class AccountRelayGroupActions(
|
||||
channel: RelayGroupChannel,
|
||||
pinnedEventIds: List<HexKey>,
|
||||
) {
|
||||
val template = UpdatePinListEvent.build(channel.groupId.id, pinnedEventIds)
|
||||
val template = GroupUpdatePinListEvent.build(channel.groupId.id, pinnedEventIds)
|
||||
account.broadcaster.signAndSendPrivatelyOrBroadcast(template) { channel.relays().toList() }
|
||||
}
|
||||
|
||||
@@ -445,7 +445,7 @@ class AccountRelayGroupActions(
|
||||
channel: RelayGroupChannel,
|
||||
pubkey: HexKey,
|
||||
) {
|
||||
val template = RemoveUserEvent.build(channel.groupId.id, listOf(pubkey))
|
||||
val template = GroupRemoveUserEvent.build(channel.groupId.id, listOf(pubkey))
|
||||
account.broadcaster.signAndSendPrivatelyOrBroadcast(template) { channel.relays().toList() }
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ class AccountRelayGroupActions(
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val template = PutUserEvent.build(channel.groupId.id, listOf(pubkey to roles), buzzRole = buzzRole)
|
||||
val template = GroupPutUserEvent.build(channel.groupId.id, listOf(pubkey to roles), buzzRole = buzzRole)
|
||||
account.broadcaster.signAndSendPrivatelyOrBroadcast(template) { channel.relays().toList() }
|
||||
}
|
||||
|
||||
@@ -525,7 +525,7 @@ class AccountRelayGroupActions(
|
||||
// edit when we send that tag. A plain NIP-29 relay ignores it and honours the status flag.
|
||||
val isBuzz = BuzzRelayDialect.isBuzz(channel.groupId.relayUrl)
|
||||
val template =
|
||||
EditMetadataEvent.build(
|
||||
GroupEditMetadataEvent.build(
|
||||
channel.groupId.id,
|
||||
name = name,
|
||||
about = about,
|
||||
@@ -549,7 +549,7 @@ class AccountRelayGroupActions(
|
||||
channel: RelayGroupChannel,
|
||||
archived: Boolean,
|
||||
) {
|
||||
val template = EditMetadataEvent.build(channel.groupId.id, archived = archived)
|
||||
val template = GroupEditMetadataEvent.build(channel.groupId.id, archived = archived)
|
||||
account.broadcaster.signAndSendPrivatelyOrBroadcast(template) { channel.relays().toList() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.PublicChatListEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.privateOutbox.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent
|
||||
@@ -68,16 +68,16 @@ import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.FavoriteRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.simpleGroupList.SimpleGroupListEvent
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.CommandType
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.permission.Permission
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip60Cashu.wallet.CashuWalletEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.info.NutzapInfoEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
@@ -203,20 +203,20 @@ class AccountSettings(
|
||||
val showMessagesInNotifications: MutableStateFlow<Boolean> = MutableStateFlow(true),
|
||||
var backupUserMetadata: MetadataEvent? = null,
|
||||
var backupContactList: ContactListEvent? = null,
|
||||
var backupDMRelayList: ChatMessageRelayListEvent? = null,
|
||||
var backupDMRelayList: DmRelayListEvent? = null,
|
||||
var backupKeyPackageRelayList: KeyPackageRelayListEvent? = null,
|
||||
var backupNIP65RelayList: AdvertisedRelayListEvent? = null,
|
||||
var backupSearchRelayList: SearchRelayListEvent? = null,
|
||||
var backupIndexRelayList: IndexerRelayListEvent? = null,
|
||||
var backupRelayFeedsList: RelayFeedsListEvent? = null,
|
||||
var backupRelayFeedsList: FavoriteRelayListEvent? = null,
|
||||
var backupBlockedRelayList: BlockedRelayListEvent? = null,
|
||||
var backupTrustedRelayList: TrustedRelayListEvent? = null,
|
||||
var backupMuteList: MuteListEvent? = null,
|
||||
var backupPrivateHomeRelayList: PrivateOutboxRelayListEvent? = null,
|
||||
var backupAppSpecificData: AppSpecificDataEvent? = null,
|
||||
var backupChannelList: ChannelListEvent? = null,
|
||||
var backupChannelList: PublicChatListEvent? = null,
|
||||
var backupCommunityList: CommunityListEvent? = null,
|
||||
var backupHashtagList: HashtagListEvent? = null,
|
||||
var backupHashtagList: InterestListEvent? = null,
|
||||
var backupFavoriteAlgoFeedsList: FavoriteAlgoFeedsListEvent? = null,
|
||||
var backupGeohashList: GeohashListEvent? = null,
|
||||
var backupEphemeralChatList: EphemeralChatListEvent? = null,
|
||||
@@ -375,7 +375,7 @@ class AccountSettings(
|
||||
// Zaps and Reactions
|
||||
// ---
|
||||
|
||||
fun changeDefaultZapType(zapType: LnZapEvent.ZapType): Boolean {
|
||||
fun changeDefaultZapType(zapType: ZapReceiptEvent.ZapType): Boolean {
|
||||
if (syncedSettings.zaps.defaultZapType.value != zapType) {
|
||||
syncedSettings.zaps.defaultZapType.tryEmit(zapType)
|
||||
saveAccountSettings()
|
||||
@@ -1075,7 +1075,7 @@ class AccountSettings(
|
||||
when (incoming) {
|
||||
is MetadataEvent -> updateUserMetadata(incoming)
|
||||
is ContactListEvent -> updateContactListTo(incoming)
|
||||
is ChatMessageRelayListEvent -> updateDMRelayList(incoming)
|
||||
is DmRelayListEvent -> updateDMRelayList(incoming)
|
||||
is KeyPackageRelayListEvent -> updateKeyPackageRelayList(incoming)
|
||||
is AdvertisedRelayListEvent -> updateNIP65RelayList(incoming)
|
||||
is CashuWalletEvent -> updateCashuWallet(incoming)
|
||||
@@ -1084,13 +1084,13 @@ class AccountSettings(
|
||||
is Bolt12OfferListEvent -> updateBolt12Offers(incoming)
|
||||
is SearchRelayListEvent -> updateSearchRelayList(incoming)
|
||||
is IndexerRelayListEvent -> updateIndexRelayList(incoming)
|
||||
is RelayFeedsListEvent -> updateRelayFeedList(incoming)
|
||||
is FavoriteRelayListEvent -> updateRelayFeedList(incoming)
|
||||
is BlockedRelayListEvent -> updateBlockedRelayList(incoming)
|
||||
is TrustedRelayListEvent -> updateTrustedRelayList(incoming)
|
||||
is PrivateOutboxRelayListEvent -> updatePrivateHomeRelayList(incoming)
|
||||
is ChannelListEvent -> updateChannelListTo(incoming)
|
||||
is PublicChatListEvent -> updateChannelListTo(incoming)
|
||||
is GeohashListEvent -> updateGeohashListTo(incoming)
|
||||
is HashtagListEvent -> updateHashtagListTo(incoming)
|
||||
is InterestListEvent -> updateHashtagListTo(incoming)
|
||||
is FavoriteAlgoFeedsListEvent -> updateFavoriteAlgoFeedsListTo(incoming)
|
||||
is CommunityListEvent -> updateCommunityListTo(incoming)
|
||||
is EphemeralChatListEvent -> updateEphemeralChatListTo(incoming)
|
||||
@@ -1140,7 +1140,7 @@ class AccountSettings(
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDMRelayList(newDMRelayList: ChatMessageRelayListEvent?) {
|
||||
fun updateDMRelayList(newDMRelayList: DmRelayListEvent?) {
|
||||
if (newDMRelayList == null) return
|
||||
|
||||
if (backupGuard.accept(backupDMRelayList, newDMRelayList, isEmpty = newDMRelayList.tags.isEmpty()) { updateDMRelayList(newDMRelayList) }) {
|
||||
@@ -1284,7 +1284,7 @@ class AccountSettings(
|
||||
}
|
||||
}
|
||||
|
||||
fun updateRelayFeedList(newRelayFeedList: RelayFeedsListEvent?) {
|
||||
fun updateRelayFeedList(newRelayFeedList: FavoriteRelayListEvent?) {
|
||||
if (newRelayFeedList == null) return
|
||||
|
||||
if (backupGuard.accept(backupRelayFeedsList, newRelayFeedList, isEmpty = newRelayFeedList.tags.isEmpty()) { updateRelayFeedList(newRelayFeedList) }) {
|
||||
@@ -1322,7 +1322,7 @@ class AccountSettings(
|
||||
|
||||
override fun channelList() = backupChannelList
|
||||
|
||||
override fun updateChannelListTo(newChannelList: ChannelListEvent?) {
|
||||
override fun updateChannelListTo(newChannelList: PublicChatListEvent?) {
|
||||
if (newChannelList == null) return
|
||||
|
||||
if (backupGuard.accept(backupChannelList, newChannelList, isEmpty = newChannelList.tags.isEmpty()) { updateChannelListTo(newChannelList) }) {
|
||||
@@ -1340,7 +1340,7 @@ class AccountSettings(
|
||||
}
|
||||
}
|
||||
|
||||
fun updateHashtagListTo(newHashtagList: HashtagListEvent?) {
|
||||
fun updateHashtagListTo(newHashtagList: InterestListEvent?) {
|
||||
if (newHashtagList == null) return
|
||||
|
||||
if (backupGuard.accept(backupHashtagList, newHashtagList, isEmpty = newHashtagList.tags.isEmpty()) { updateHashtagListTo(newHashtagList) }) {
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.vitorpamplona.amethyst.commons.service.pow.PoWCategory
|
||||
import com.vitorpamplona.amethyst.commons.service.pow.PoWPolicy
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.equalImmutableLists
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -265,7 +265,7 @@ class AccountVideoPlayerPreferences(
|
||||
@Stable
|
||||
class AccountZapPreferences(
|
||||
var zapAmountChoices: MutableStateFlow<ImmutableList<Long>>,
|
||||
val defaultZapType: MutableStateFlow<LnZapEvent.ZapType>,
|
||||
val defaultZapType: MutableStateFlow<ZapReceiptEvent.ZapType>,
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ import androidx.core.os.ConfigurationCompat
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.BottomBarEntry
|
||||
import com.vitorpamplona.amethyst.commons.service.pow.PoWCategory
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.DefaultBottomBarEntries
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.Locale
|
||||
|
||||
@@ -207,7 +207,7 @@ class AccountZapPreferencesInternal(
|
||||
// and so the on-chain-eligible subset round-trips back for them; on load it
|
||||
// is unioned into [zapAmountChoices]. See AccountSyncedSettings.
|
||||
var onchainZapAmountChoices: List<Long> = DefaultOnchainZapAmounts,
|
||||
val defaultZapType: LnZapEvent.ZapType = LnZapEvent.ZapType.PUBLIC,
|
||||
val defaultZapType: ZapReceiptEvent.ZapType = ZapReceiptEvent.ZapType.PUBLIC,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -48,8 +48,8 @@ import com.vitorpamplona.quartz.nip47WalletConnect.rpc.PayMethod
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.PaySuccessResponse
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Request
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Response
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.builder.Bolt12ZapBuilder
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
@@ -74,12 +74,12 @@ class AccountZapActions(
|
||||
event: Event,
|
||||
pollOption: Int?,
|
||||
message: String = "",
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
toUser: User?,
|
||||
additionalRelays: Set<NormalizedRelayUrl>? = null,
|
||||
amountMillisats: Long? = null,
|
||||
lnurl: String? = null,
|
||||
) = LnZapRequestEvent.create(
|
||||
) = ZapRequestEvent.create(
|
||||
zappedEvent = event,
|
||||
// Where the provider should publish the receipt. Zapping group content pins that to the room's
|
||||
// host relay: the receipt belongs where the message it pays for lives, so the room can show it
|
||||
@@ -205,7 +205,7 @@ class AccountZapActions(
|
||||
offer: String,
|
||||
amountMillisats: Long,
|
||||
message: String,
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
// (messageResId, detail) — the caller localizes; detail carries a wallet error, if any.
|
||||
onError: (StringResource, String?) -> Unit,
|
||||
// (code, detail) — the wallet refused or failed the payment; no funds moved.
|
||||
@@ -215,7 +215,7 @@ class AccountZapActions(
|
||||
) {
|
||||
// NONZAP means "pay, but publish no receipt" — settle the offer without binding
|
||||
// a zap intent or emitting a 9736, matching the privacy of a bolt11 NONZAP.
|
||||
if (zapType == LnZapEvent.ZapType.NONZAP) {
|
||||
if (zapType == ZapReceiptEvent.ZapType.NONZAP) {
|
||||
sendNwcRequest(PayMethod.create("bitcoin:?lno=$offer", amountMillisats), onTimeout) { response ->
|
||||
account.scope.launch {
|
||||
try {
|
||||
@@ -228,7 +228,7 @@ class AccountZapActions(
|
||||
return
|
||||
}
|
||||
|
||||
val anonymous = zapType == LnZapEvent.ZapType.ANONYMOUS
|
||||
val anonymous = zapType == ZapReceiptEvent.ZapType.ANONYMOUS
|
||||
// The 9737 intent and the 9736 zap MUST be signed by the same key. An anonymous
|
||||
// zap uses a fresh ephemeral key so it carries no `P` tag and isn't traceable.
|
||||
val zapSigner = if (anonymous) NostrSignerInternal(KeyPair()) else account.signer
|
||||
@@ -284,12 +284,12 @@ class AccountZapActions(
|
||||
suspend fun createZapRequestFor(
|
||||
user: User,
|
||||
message: String = "",
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
amountMillisats: Long? = null,
|
||||
lnurl: String? = null,
|
||||
): LnZapRequestEvent {
|
||||
): ZapRequestEvent {
|
||||
val zapRequest =
|
||||
LnZapRequestEvent.create(
|
||||
ZapRequestEvent.create(
|
||||
userHex = user.pubkeyHex,
|
||||
relays = account.nip65RelayList.inboxFlow.value + (user.inboxRelays() ?: emptyList()),
|
||||
signer = account.signer,
|
||||
|
||||
@@ -40,16 +40,16 @@ 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.nip17Dm.base.BaseDMGroupEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.isGroupScoped
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.OldBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.LabeledBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.BookmarkSetEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip60Cashu.wallet.CashuWalletEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.info.NutzapInfoEvent
|
||||
@@ -121,7 +121,7 @@ class EventBroadcaster(
|
||||
event is AppSpecificDataEvent ||
|
||||
event is BookmarkListEvent ||
|
||||
event is OldBookmarkListEvent ||
|
||||
event is LabeledBookmarkListEvent
|
||||
event is BookmarkSetEvent
|
||||
) {
|
||||
return false
|
||||
}
|
||||
@@ -166,7 +166,7 @@ class EventBroadcaster(
|
||||
}
|
||||
// Seals, inner DM messages, and unsigned rumors never get broadcast
|
||||
// relays: they only travel inside gift wraps.
|
||||
if (event is SealedRumorEvent || event is BaseDMGroupEvent || event.sig.isEmpty()) {
|
||||
if (event is SealEvent || event is BaseDMGroupEvent || event.sig.isEmpty()) {
|
||||
return emptySet()
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ class EventBroadcaster(
|
||||
.toList()
|
||||
}
|
||||
val filter =
|
||||
if (host.kind == SealedRumorEvent.KIND) {
|
||||
if (host.kind == SealEvent.KIND) {
|
||||
Filter(
|
||||
kinds = listOf(host.kind),
|
||||
ids = listOf(host.id),
|
||||
@@ -383,7 +383,7 @@ class EventBroadcaster(
|
||||
fun sendRestoredVersion(event: Event) {
|
||||
when (event) {
|
||||
is AdvertisedRelayListEvent -> sendEverywhereAnd(event, event.relays().mapTo(mutableSetOf()) { it.relayUrl })
|
||||
is ChatMessageRelayListEvent -> sendEverywhereAnd(event, event.relays().toSet())
|
||||
is DmRelayListEvent -> sendEverywhereAnd(event, event.relays().toSet())
|
||||
is KeyPackageRelayListEvent -> sendEverywhereAnd(event, event.relays().toSet())
|
||||
is CashuWalletEvent -> sendLiterallyEverywhere(event)
|
||||
// Profiles and nutzap info are normally saved everywhere so others can find them;
|
||||
|
||||
+7
-7
@@ -25,8 +25,8 @@ import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.DvmContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.status.DvmStatusEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -60,7 +60,7 @@ data class FavoriteAlgoFeedsSnapshot(
|
||||
val responseRelays: Set<NormalizedRelayUrl> = emptySet(),
|
||||
val ids: Set<HexKey> = emptySet(),
|
||||
val addresses: Set<String> = emptySet(),
|
||||
val latestStatus: NIP90StatusEvent? = null,
|
||||
val latestStatus: DvmStatusEvent? = null,
|
||||
val errorMessage: String? = null,
|
||||
)
|
||||
|
||||
@@ -139,9 +139,9 @@ class FavoriteAlgoFeedsOrchestrator(
|
||||
|
||||
launch {
|
||||
account.cache
|
||||
.observeLatestEvent<NIP90ContentDiscoveryResponseEvent>(
|
||||
.observeLatestEvent<DvmContentDiscoveryResponseEvent>(
|
||||
Filter(
|
||||
kinds = listOf(NIP90ContentDiscoveryResponseEvent.KIND),
|
||||
kinds = listOf(DvmContentDiscoveryResponseEvent.KIND),
|
||||
tags = mapOf("e" to listOf(requestId)),
|
||||
limit = 1,
|
||||
),
|
||||
@@ -159,9 +159,9 @@ class FavoriteAlgoFeedsOrchestrator(
|
||||
|
||||
launch {
|
||||
account.cache
|
||||
.observeLatestEvent<NIP90StatusEvent>(
|
||||
.observeLatestEvent<DvmStatusEvent>(
|
||||
Filter(
|
||||
kinds = listOf(NIP90StatusEvent.KIND),
|
||||
kinds = listOf(DvmStatusEvent.KIND),
|
||||
tags = mapOf("e" to listOf(requestId)),
|
||||
limit = 1,
|
||||
),
|
||||
|
||||
+8
-8
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.commons.model.cache.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@@ -48,14 +48,14 @@ class DmRelayListState(
|
||||
// Creates a long-term reference for this note so that the GC doesn't collect the note it self
|
||||
val dmListNote = cache.getOrCreateAddressableNote(getDMRelayListAddress())
|
||||
|
||||
fun getDMRelayListAddress() = ChatMessageRelayListEvent.createAddress(signer.pubKey)
|
||||
fun getDMRelayListAddress() = DmRelayListEvent.createAddress(signer.pubKey)
|
||||
|
||||
fun getDMRelayListFlow(): StateFlow<NoteState> = dmListNote.flow().metadata.stateFlow
|
||||
|
||||
fun getDMRelayList(): ChatMessageRelayListEvent? = dmListNote.event as? ChatMessageRelayListEvent
|
||||
fun getDMRelayList(): DmRelayListEvent? = dmListNote.event as? DmRelayListEvent
|
||||
|
||||
fun normalizeDMRelayListWithBackup(note: Note): Set<NormalizedRelayUrl> {
|
||||
val event = note.event as? ChatMessageRelayListEvent ?: settings.backupDMRelayList
|
||||
val event = note.event as? DmRelayListEvent ?: settings.backupDMRelayList
|
||||
return event?.relays()?.toSet() ?: emptySet()
|
||||
}
|
||||
|
||||
@@ -70,16 +70,16 @@ class DmRelayListState(
|
||||
emptySet(),
|
||||
)
|
||||
|
||||
suspend fun saveRelayList(dmRelays: List<NormalizedRelayUrl>): ChatMessageRelayListEvent {
|
||||
suspend fun saveRelayList(dmRelays: List<NormalizedRelayUrl>): DmRelayListEvent {
|
||||
val relayListForDMs = getDMRelayList()
|
||||
return if (relayListForDMs != null && relayListForDMs.tags.isNotEmpty()) {
|
||||
ChatMessageRelayListEvent.updateRelayList(
|
||||
DmRelayListEvent.updateRelayList(
|
||||
earlierVersion = relayListForDMs,
|
||||
relays = dmRelays,
|
||||
signer = signer,
|
||||
)
|
||||
} else {
|
||||
ChatMessageRelayListEvent.create(
|
||||
DmRelayListEvent.create(
|
||||
relays = dmRelays,
|
||||
signer = signer,
|
||||
)
|
||||
@@ -99,7 +99,7 @@ class DmRelayListState(
|
||||
Log.d("AccountRegisterObservers", "NIP-17 Relay List Collector Start")
|
||||
getDMRelayListFlow().collect {
|
||||
Log.d("AccountRegisterObservers") { "Updating DM Relay List for ${signer.pubKey}" }
|
||||
(it.note.event as? ChatMessageRelayListEvent)?.let {
|
||||
(it.note.event as? DmRelayListEvent)?.let {
|
||||
settings.updateDMRelayList(it)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -33,7 +33,7 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.update
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.emoji
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
|
||||
@@ -129,12 +129,12 @@ class OwnedEmojiPacksState(
|
||||
.onStart { emit(listFeedFlow.value.getPack(dTag)) }
|
||||
.flowOn(Dispatchers.IO)
|
||||
|
||||
fun DeletionEvent.hasAnyDeletedOwnedEmojiPacks() = deleteAddressesWithKind(EmojiPackEvent.KIND) || deletesAnyEventIn(ownedEmojiPackEventIds.value)
|
||||
fun DeletionRequestEvent.hasAnyDeletedOwnedEmojiPacks() = deleteAddressesWithKind(EmojiPackEvent.KIND) || deletesAnyEventIn(ownedEmojiPackEventIds.value)
|
||||
|
||||
fun hasItemInNoteList(notes: Set<Note>): Boolean =
|
||||
notes.anyNotNullEvent { event ->
|
||||
if (event.pubKey == signer.pubKey) {
|
||||
event is EmojiPackEvent || (event is DeletionEvent && event.hasAnyDeletedOwnedEmojiPacks())
|
||||
event is EmojiPackEvent || (event is DeletionRequestEvent && event.hasAnyDeletedOwnedEmojiPacks())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -269,7 +269,7 @@ class OwnedEmojiPacksState(
|
||||
account: Account,
|
||||
) {
|
||||
val packEvent = getOwnedEmojiPackEvent(dTag) ?: return
|
||||
val deletionEventTemplate = DeletionEvent.build(listOf(packEvent))
|
||||
val deletionEventTemplate = DeletionRequestEvent.build(listOf(packEvent))
|
||||
val deletionEvent = signer.sign(deletionEventTemplate)
|
||||
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
||||
}
|
||||
|
||||
+9
-9
@@ -36,10 +36,10 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.cache.NostrWalletConnectRequestCache
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.cache.NostrWalletConnectResponseCache
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.LnZapPaymentRequestEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.LnZapPaymentResponseEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.NwcInfoEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.NwcNotificationEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.NwcRequestEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.NwcResponseEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.NwcTransaction
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.PayInvoiceMethod
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.PaymentReceivedNotification
|
||||
@@ -199,12 +199,12 @@ class NwcSignerState(
|
||||
|
||||
override fun isNIP47Author(pubKey: HexKey?): Boolean = nip47Signer.value.pubKey == pubKey
|
||||
|
||||
override suspend fun decryptRequest(event: LnZapPaymentRequestEvent): Request? {
|
||||
override suspend fun decryptRequest(event: NwcRequestEvent): Request? {
|
||||
if (!hasWalletConnectSetup()) return null
|
||||
return zapPaymentRequestDecryptionCache.value.decryptRequest(event)
|
||||
}
|
||||
|
||||
override suspend fun decryptResponse(event: LnZapPaymentResponseEvent): Response? {
|
||||
override suspend fun decryptResponse(event: NwcResponseEvent): Response? {
|
||||
if (!hasWalletConnectSetup()) return null
|
||||
return zapPaymentResponseDecryptionCache.value.decryptResponse(event)
|
||||
}
|
||||
@@ -252,7 +252,7 @@ class NwcSignerState(
|
||||
request: Request,
|
||||
onTimeout: () -> Unit = {},
|
||||
onResponse: (Response?) -> Unit,
|
||||
): Pair<LnZapPaymentRequestEvent, NormalizedRelayUrl> = sendNwcRequestToWallet(defaultWalletUri.value, request, onTimeout, onResponse)
|
||||
): Pair<NwcRequestEvent, NormalizedRelayUrl> = sendNwcRequestToWallet(defaultWalletUri.value, request, onTimeout, onResponse)
|
||||
|
||||
/**
|
||||
* Sends a generic NIP-47 request to a specific wallet.
|
||||
@@ -266,14 +266,14 @@ class NwcSignerState(
|
||||
request: Request,
|
||||
onTimeout: () -> Unit = {},
|
||||
onResponse: (Response?) -> Unit,
|
||||
): Pair<LnZapPaymentRequestEvent, NormalizedRelayUrl> {
|
||||
): Pair<NwcRequestEvent, NormalizedRelayUrl> {
|
||||
val walletService = walletUri ?: throw IllegalArgumentException("No NIP47 setup")
|
||||
val walletSigner = buildSigner(walletService) ?: signer
|
||||
|
||||
val info = walletInfo(walletService)
|
||||
request.dropMetadataIfUnsupported(info)
|
||||
|
||||
val event = LnZapPaymentRequestEvent.createRequest(request, walletService.pubKeyHex, walletSigner, useNip44 = prefersNip44(info))
|
||||
val event = NwcRequestEvent.createRequest(request, walletService.pubKeyHex, walletSigner, useNip44 = prefersNip44(info))
|
||||
|
||||
val filter =
|
||||
NWCPaymentQueryState(
|
||||
@@ -314,7 +314,7 @@ class NwcSignerState(
|
||||
onTimeout: () -> Unit = {},
|
||||
metadata: Map<String, Any?>? = null,
|
||||
onResponse: (Response?) -> Unit,
|
||||
): Pair<LnZapPaymentRequestEvent, NormalizedRelayUrl> {
|
||||
): Pair<NwcRequestEvent, NormalizedRelayUrl> {
|
||||
val walletService = defaultWalletUri.value ?: throw IllegalArgumentException("No NIP47 setup")
|
||||
|
||||
val info = walletInfo(walletService)
|
||||
@@ -322,7 +322,7 @@ class NwcSignerState(
|
||||
request.dropMetadataIfUnsupported(info)
|
||||
|
||||
val event =
|
||||
LnZapPaymentRequestEvent.createRequest(
|
||||
NwcRequestEvent.createRequest(
|
||||
request,
|
||||
walletService.pubKeyHex,
|
||||
nip47Signer.value,
|
||||
|
||||
+13
-13
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.commons.model.cache.LocalCache
|
||||
import com.vitorpamplona.amethyst.commons.model.nip51Lists.hashtagLists.HashtagListDecryptionCache
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@@ -50,14 +50,14 @@ class HashtagListState(
|
||||
// Creates a long-term reference for this note so that the GC doesn't collect the note it self
|
||||
val hashtagListNote = cache.getOrCreateAddressableNote(getHashtagListAddress())
|
||||
|
||||
fun getHashtagListAddress() = HashtagListEvent.createAddress(signer.pubKey)
|
||||
fun getHashtagListAddress() = InterestListEvent.createAddress(signer.pubKey)
|
||||
|
||||
fun getHashtagListFlow(): StateFlow<NoteState> = hashtagListNote.flow().metadata.stateFlow
|
||||
|
||||
fun getHashtagList(): HashtagListEvent? = hashtagListNote.event as? HashtagListEvent
|
||||
fun getHashtagList(): InterestListEvent? = hashtagListNote.event as? InterestListEvent
|
||||
|
||||
suspend fun hashtagListWithBackup(note: Note): Set<String> {
|
||||
val event = note.event as? HashtagListEvent ?: settings.backupHashtagList
|
||||
val event = note.event as? InterestListEvent ?: settings.backupHashtagList
|
||||
return event?.let { decryptionCache.hashtags(it).mapTo(mutableSetOf()) { it.lowercase() } } ?: emptySet()
|
||||
}
|
||||
|
||||
@@ -75,31 +75,31 @@ class HashtagListState(
|
||||
emptySet(),
|
||||
)
|
||||
|
||||
suspend fun follow(hashtags: List<String>): HashtagListEvent {
|
||||
suspend fun follow(hashtags: List<String>): InterestListEvent {
|
||||
val hashtagList = getHashtagList()
|
||||
|
||||
return if (hashtagList == null) {
|
||||
HashtagListEvent.create(hashtags, true, signer)
|
||||
InterestListEvent.create(hashtags, true, signer)
|
||||
} else {
|
||||
HashtagListEvent.add(hashtagList, hashtags, true, signer)
|
||||
InterestListEvent.add(hashtagList, hashtags, true, signer)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun follow(hashtag: String): HashtagListEvent {
|
||||
suspend fun follow(hashtag: String): InterestListEvent {
|
||||
val hashtagList = getHashtagList()
|
||||
|
||||
return if (hashtagList == null) {
|
||||
HashtagListEvent.create(hashtag.lowercase(), true, signer)
|
||||
InterestListEvent.create(hashtag.lowercase(), true, signer)
|
||||
} else {
|
||||
HashtagListEvent.add(hashtagList, hashtag.lowercase(), true, signer)
|
||||
InterestListEvent.add(hashtagList, hashtag.lowercase(), true, signer)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun unfollow(hashtag: String): HashtagListEvent? {
|
||||
suspend fun unfollow(hashtag: String): InterestListEvent? {
|
||||
val hashtagList = getHashtagList()
|
||||
|
||||
return if (hashtagList != null) {
|
||||
HashtagListEvent.remove(hashtagList, hashtag, signer)
|
||||
InterestListEvent.remove(hashtagList, hashtag, signer)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -118,7 +118,7 @@ class HashtagListState(
|
||||
Log.d("AccountRegisterObservers", "Hashtag List Collector Start")
|
||||
getHashtagListFlow().collect {
|
||||
Log.d("AccountRegisterObservers") { "Hashtag List for ${signer.pubKey}" }
|
||||
(it.note.event as? HashtagListEvent)?.let {
|
||||
(it.note.event as? InterestListEvent)?.let {
|
||||
settings.updateHashtagListTo(it)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -31,7 +31,7 @@ import com.vitorpamplona.amethyst.commons.model.nip51Lists.interestSets.Interest
|
||||
import com.vitorpamplona.amethyst.commons.model.updateFlow
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.interestSet.InterestSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.tags.TitleTag
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -106,12 +106,12 @@ class InterestSetsState(
|
||||
|
||||
fun getInterestSet(dTag: String) = listFeedFlow.value.getSet(dTag)
|
||||
|
||||
fun DeletionEvent.hasAnyDeletedInterestSets() = deleteAddressesWithKind(InterestSetEvent.KIND) || deletesAnyEventIn(interestSetEventIds.value)
|
||||
fun DeletionRequestEvent.hasAnyDeletedInterestSets() = deleteAddressesWithKind(InterestSetEvent.KIND) || deletesAnyEventIn(interestSetEventIds.value)
|
||||
|
||||
fun hasItemInNoteList(notes: Set<Note>): Boolean =
|
||||
notes.anyNotNullEvent { event ->
|
||||
if (event.pubKey == signer.pubKey) {
|
||||
event is InterestSetEvent || (event is DeletionEvent && event.hasAnyDeletedInterestSets())
|
||||
event is InterestSetEvent || (event is DeletionRequestEvent && event.hasAnyDeletedInterestSets())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -178,7 +178,7 @@ class InterestSetsState(
|
||||
account: Account,
|
||||
) {
|
||||
val event = getInterestSetEvent(identifier)
|
||||
val template = DeletionEvent.build(listOf(event))
|
||||
val template = DeletionRequestEvent.build(listOf(event))
|
||||
val deletionEvent = account.signer.sign(template)
|
||||
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
||||
}
|
||||
|
||||
+21
-21
@@ -33,11 +33,11 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.update
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.LabeledBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.BookmarkSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.description
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.image
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.title
|
||||
@@ -62,7 +62,7 @@ class LabeledBookmarkListsState(
|
||||
) {
|
||||
val user = cache.getOrCreateUser(signer.pubKey)
|
||||
|
||||
fun existingLabeledBookmarkNotes() = cache.addressables.filter(LabeledBookmarkListEvent.KIND, user.pubkeyHex)
|
||||
fun existingLabeledBookmarkNotes() = cache.addressables.filter(BookmarkSetEvent.KIND, user.pubkeyHex)
|
||||
|
||||
val labeledBookmarkListVersions = MutableStateFlow(0)
|
||||
|
||||
@@ -81,14 +81,14 @@ class LabeledBookmarkListsState(
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptySet())
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val latestBookmarkLists: StateFlow<List<LabeledBookmarkListEvent>> =
|
||||
val latestBookmarkLists: StateFlow<List<BookmarkSetEvent>> =
|
||||
labeledBookmarkListNotes
|
||||
.transformLatest { emitAll(it.updateFlow<LabeledBookmarkListEvent>()) }
|
||||
.transformLatest { emitAll(it.updateFlow<BookmarkSetEvent>()) }
|
||||
.onStart { emit(labeledBookmarkListNotes.value.events()) }
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
suspend fun LabeledBookmarkListEvent.toLabeledBookmarkList() =
|
||||
suspend fun BookmarkSetEvent.toLabeledBookmarkList() =
|
||||
LabeledBookmarkList(
|
||||
identifier = dTag(),
|
||||
title = titleOrName() ?: dTag(),
|
||||
@@ -98,7 +98,7 @@ class LabeledBookmarkListsState(
|
||||
publicBookmarks = publicBookmarks().toSet(),
|
||||
)
|
||||
|
||||
suspend fun List<LabeledBookmarkListEvent>.toLabeledBookmarkListsFeed() = map { it.toLabeledBookmarkList() }.sortedBy { it.title }
|
||||
suspend fun List<BookmarkSetEvent>.toLabeledBookmarkListsFeed() = map { it.toLabeledBookmarkList() }.sortedBy { it.title }
|
||||
|
||||
val listFeedFlow =
|
||||
latestBookmarkLists
|
||||
@@ -114,12 +114,12 @@ class LabeledBookmarkListsState(
|
||||
|
||||
fun getBookmarkList(dTag: String) = listFeedFlow.value.getList(bookmarkListId = dTag)
|
||||
|
||||
fun DeletionEvent.hasAnyDeletedBookmarkLists() = deleteAddressesWithKind(LabeledBookmarkListEvent.KIND) || deletesAnyEventIn(labeledBookmarkListEventIds.value)
|
||||
fun DeletionRequestEvent.hasAnyDeletedBookmarkLists() = deleteAddressesWithKind(BookmarkSetEvent.KIND) || deletesAnyEventIn(labeledBookmarkListEventIds.value)
|
||||
|
||||
fun hasItemInNoteList(notes: Set<Note>): Boolean =
|
||||
notes.anyNotNullEvent { event ->
|
||||
if (event.pubKey == signer.pubKey) {
|
||||
event is LabeledBookmarkListEvent || (event is DeletionEvent && event.hasAnyDeletedBookmarkLists())
|
||||
event is BookmarkSetEvent || (event is DeletionRequestEvent && event.hasAnyDeletedBookmarkLists())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -143,7 +143,7 @@ class LabeledBookmarkListsState(
|
||||
|
||||
fun getLabeledBookmarkListNote(bookmarkIdentifier: String): AddressableNote? = existingLabeledBookmarkNotes().find { it.dTag() == bookmarkIdentifier }
|
||||
|
||||
fun getLabeledBookmarkListEvent(bookmarkIdentifier: String): LabeledBookmarkListEvent = getLabeledBookmarkListNote(bookmarkIdentifier)?.event as LabeledBookmarkListEvent
|
||||
fun getLabeledBookmarkListEvent(bookmarkIdentifier: String): BookmarkSetEvent = getLabeledBookmarkListNote(bookmarkIdentifier)?.event as BookmarkSetEvent
|
||||
|
||||
fun getLabeledBookmarkListFlow(bookmarkIdentifier: String) =
|
||||
listFeedFlow
|
||||
@@ -163,7 +163,7 @@ class LabeledBookmarkListsState(
|
||||
account: Account,
|
||||
) {
|
||||
val newList =
|
||||
LabeledBookmarkListEvent.create(
|
||||
BookmarkSetEvent.create(
|
||||
title = listName,
|
||||
description = listDescription,
|
||||
image = listImage,
|
||||
@@ -202,7 +202,7 @@ class LabeledBookmarkListsState(
|
||||
) {
|
||||
val listEvent = getLabeledBookmarkListEvent(bookmarkList.identifier)
|
||||
val renamedList =
|
||||
LabeledBookmarkListEvent.modifyName(
|
||||
BookmarkSetEvent.modifyName(
|
||||
earlierVersion = listEvent,
|
||||
newTitle = newName,
|
||||
signer = account.signer,
|
||||
@@ -217,7 +217,7 @@ class LabeledBookmarkListsState(
|
||||
) {
|
||||
val listEvent = getLabeledBookmarkListEvent(bookmarkList.identifier)
|
||||
val modifiedList =
|
||||
LabeledBookmarkListEvent.modifyDescription(
|
||||
BookmarkSetEvent.modifyDescription(
|
||||
earlierVersion = listEvent,
|
||||
newDescription = newDescription,
|
||||
signer = account.signer,
|
||||
@@ -232,7 +232,7 @@ class LabeledBookmarkListsState(
|
||||
account: Account,
|
||||
) {
|
||||
val clonedList =
|
||||
LabeledBookmarkListEvent.create(
|
||||
BookmarkSetEvent.create(
|
||||
title = customCloneName ?: currentBookmarkList.title,
|
||||
description = customCloneDescription ?: currentBookmarkList.description,
|
||||
publicBookmarks = currentBookmarkList.publicBookmarks.toList(),
|
||||
@@ -247,7 +247,7 @@ class LabeledBookmarkListsState(
|
||||
account: Account,
|
||||
) {
|
||||
val listEvent = getLabeledBookmarkListEvent(bookmarkListIdentifier)
|
||||
val deletionEventTemplate = DeletionEvent.build(listOf(listEvent))
|
||||
val deletionEventTemplate = DeletionRequestEvent.build(listOf(listEvent))
|
||||
val deletionEvent = account.signer.sign(deletionEventTemplate)
|
||||
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
||||
}
|
||||
@@ -260,7 +260,7 @@ class LabeledBookmarkListsState(
|
||||
) {
|
||||
val currentBookmarkList = getLabeledBookmarkListEvent(bookmarkListIdentifier)
|
||||
val updatedList =
|
||||
LabeledBookmarkListEvent.addBookmark(
|
||||
BookmarkSetEvent.addBookmark(
|
||||
earlierVersion = currentBookmarkList,
|
||||
bookmarkIdTag = bookmark,
|
||||
isPrivate = isBookmarkPrivate,
|
||||
@@ -277,7 +277,7 @@ class LabeledBookmarkListsState(
|
||||
) {
|
||||
val bookmarkList = getLabeledBookmarkListEvent(bookmarkListIdentifier)
|
||||
val updatedList =
|
||||
LabeledBookmarkListEvent.moveBookmark(
|
||||
BookmarkSetEvent.moveBookmark(
|
||||
earlierVersion = bookmarkList,
|
||||
bookmarkIdTag = bookmark,
|
||||
isCurrentlyPrivate = isBookmarkCurrentlyPrivate,
|
||||
@@ -294,7 +294,7 @@ class LabeledBookmarkListsState(
|
||||
) {
|
||||
val currentBookmarkList = getLabeledBookmarkListEvent(bookmarkListIdentifier)
|
||||
val updatedList =
|
||||
LabeledBookmarkListEvent.removeBookmark(
|
||||
BookmarkSetEvent.removeBookmark(
|
||||
earlierVersion = currentBookmarkList,
|
||||
bookmarkIdTag = bookmark,
|
||||
isPrivate = isBookmarkPrivate,
|
||||
@@ -311,7 +311,7 @@ class LabeledBookmarkListsState(
|
||||
) {
|
||||
if (deletedEventIds.isEmpty() && deletedAddresses.isEmpty()) return
|
||||
|
||||
val currentList = getLabeledBookmarkListNote(bookmarkListIdentifier)?.event as? LabeledBookmarkListEvent ?: return
|
||||
val currentList = getLabeledBookmarkListNote(bookmarkListIdentifier)?.event as? BookmarkSetEvent ?: return
|
||||
|
||||
val newPublicTags =
|
||||
currentList.tags
|
||||
@@ -328,7 +328,7 @@ class LabeledBookmarkListsState(
|
||||
val updatedList =
|
||||
if (oldPrivateTags == null) {
|
||||
if (newPublicTags.size == currentList.tags.size) return
|
||||
LabeledBookmarkListEvent.resign(
|
||||
BookmarkSetEvent.resign(
|
||||
content = currentList.content,
|
||||
tags = newPublicTags,
|
||||
signer = account.signer,
|
||||
@@ -344,7 +344,7 @@ class LabeledBookmarkListsState(
|
||||
}
|
||||
}.toTypedArray()
|
||||
if (newPublicTags.size == currentList.tags.size && newPrivateTags.size == oldPrivateTags.size) return
|
||||
LabeledBookmarkListEvent.resign(
|
||||
BookmarkSetEvent.resign(
|
||||
tags = newPublicTags,
|
||||
privateTags = newPrivateTags,
|
||||
signer = account.signer,
|
||||
|
||||
+13
-13
@@ -35,8 +35,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.update
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.StarterPackEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.description
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.image
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.person
|
||||
@@ -79,7 +79,7 @@ class FollowListsState(
|
||||
// them from relays.
|
||||
fun existingPeopleListNotes() =
|
||||
cache.addressables
|
||||
.filter(FollowListEvent.KIND, user.pubkeyHex)
|
||||
.filter(StarterPackEvent.KIND, user.pubkeyHex)
|
||||
.filter { it.event != null || !cache.hasBeenDeleted(it.address) }
|
||||
|
||||
val followListVersions = MutableStateFlow(0)
|
||||
@@ -99,14 +99,14 @@ class FollowListsState(
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptySet())
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val latestLists: StateFlow<List<FollowListEvent>> =
|
||||
val latestLists: StateFlow<List<StarterPackEvent>> =
|
||||
followListNotes
|
||||
.transformLatest { emitAll(it.updateFlow<FollowListEvent>()) }
|
||||
.transformLatest { emitAll(it.updateFlow<StarterPackEvent>()) }
|
||||
.onStart { emit(followListNotes.value.events()) }
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
fun List<FollowListEvent>.mapToUserIdSet() = this.map { it.followIdSet() }.flattenToSet()
|
||||
fun List<StarterPackEvent>.mapToUserIdSet() = this.map { it.followIdSet() }.flattenToSet()
|
||||
|
||||
val allPeopleListProfiles: StateFlow<Set<HexKey>> =
|
||||
latestLists
|
||||
@@ -115,7 +115,7 @@ class FollowListsState(
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptySet())
|
||||
|
||||
fun FollowListEvent.toUI() =
|
||||
fun StarterPackEvent.toUI() =
|
||||
PeopleList(
|
||||
identifierTag = this.dTag(),
|
||||
title = this.title() ?: this.dTag(),
|
||||
@@ -125,7 +125,7 @@ class FollowListsState(
|
||||
publicMembers = cache.load(this.followIdSet()),
|
||||
)
|
||||
|
||||
fun List<FollowListEvent>.toUI() = this.map { it.toUI() }
|
||||
fun List<StarterPackEvent>.toUI() = this.map { it.toUI() }
|
||||
|
||||
val uiListFlow =
|
||||
latestLists
|
||||
@@ -148,12 +148,12 @@ class FollowListsState(
|
||||
|
||||
fun isUserInFollowSets(user: User): Boolean = allPeopleListProfiles.value.contains(user.pubkeyHex)
|
||||
|
||||
fun DeletionEvent.hasDeletedAnyFollowList() = deleteAddressesWithKind(FollowListEvent.KIND) || deletesAnyEventIn(followListsEventIds.value)
|
||||
fun DeletionRequestEvent.hasDeletedAnyFollowList() = deleteAddressesWithKind(StarterPackEvent.KIND) || deletesAnyEventIn(followListsEventIds.value)
|
||||
|
||||
fun hasItemInNoteList(notes: Set<Note>): Boolean =
|
||||
notes.anyNotNullEvent { event ->
|
||||
if (event.pubKey == signer.pubKey) {
|
||||
event is FollowListEvent || (event is DeletionEvent && event.hasDeletedAnyFollowList())
|
||||
event is StarterPackEvent || (event is DeletionRequestEvent && event.hasDeletedAnyFollowList())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -181,7 +181,7 @@ class FollowListsState(
|
||||
|
||||
fun getPeopleListNote(noteIdentifier: String): AddressableNote? = existingPeopleListNotes().find { it.dTag() == noteIdentifier }
|
||||
|
||||
fun getPeopleList(noteIdentifier: String): FollowListEvent = getPeopleListNote(noteIdentifier)?.event as FollowListEvent
|
||||
fun getPeopleList(noteIdentifier: String): StarterPackEvent = getPeopleListNote(noteIdentifier)?.event as StarterPackEvent
|
||||
|
||||
fun User.toUserTag() = UserTag(this.pubkeyHex, this.bestRelayHint())
|
||||
|
||||
@@ -198,7 +198,7 @@ class FollowListsState(
|
||||
val dTag = UUID.randomUUID().toString()
|
||||
|
||||
val newListTemplate =
|
||||
FollowListEvent.build(
|
||||
StarterPackEvent.build(
|
||||
name = name,
|
||||
people = if (!isPrivate && member != null) listOf(member.toUserTag()) else emptyList(),
|
||||
dTag = dTag,
|
||||
@@ -262,7 +262,7 @@ class FollowListsState(
|
||||
account: Account,
|
||||
) {
|
||||
val followListEvent = getPeopleList(identifierTag)
|
||||
val deletionEvent = account.signer.sign(DeletionEvent.build(listOf(followListEvent)))
|
||||
val deletionEvent = account.signer.sign(DeletionRequestEvent.build(listOf(followListEvent)))
|
||||
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
||||
// Any screen whose persisted feed filter still points at this follow pack would
|
||||
// keep re-creating an empty shell for its address (and render the dTag/UUID in
|
||||
|
||||
+21
-21
@@ -35,9 +35,9 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.update
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.FollowSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.description
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.image
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.title
|
||||
@@ -78,8 +78,8 @@ class PeopleListsState(
|
||||
// can subscribe and fetch them from relays.
|
||||
fun existingPeopleListNotes() =
|
||||
cache.addressables
|
||||
.filter(PeopleListEvent.KIND, user.pubkeyHex)
|
||||
.filter { it.dTag() != PeopleListEvent.BLOCK_LIST_D_TAG || it.event != null }
|
||||
.filter(FollowSetEvent.KIND, user.pubkeyHex)
|
||||
.filter { it.dTag() != FollowSetEvent.BLOCK_LIST_D_TAG || it.event != null }
|
||||
.filter { it.event != null || !cache.hasBeenDeleted(it.address) }
|
||||
|
||||
val peopleListVersions = MutableStateFlow(0)
|
||||
@@ -99,21 +99,21 @@ class PeopleListsState(
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptySet())
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val latestLists: StateFlow<List<PeopleListEvent>> =
|
||||
val latestLists: StateFlow<List<FollowSetEvent>> =
|
||||
peopleListNotes
|
||||
.transformLatest { emitAll(it.updateFlow<PeopleListEvent>()) }
|
||||
.transformLatest { emitAll(it.updateFlow<FollowSetEvent>()) }
|
||||
.onStart { emit(peopleListNotes.value.events()) }
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
suspend fun PeopleListEvent.userIdSet() = decryptionCache.userIdSet(this)
|
||||
suspend fun FollowSetEvent.userIdSet() = decryptionCache.userIdSet(this)
|
||||
|
||||
suspend fun List<PeopleListEvent>.mapToUserIdSet() = this.map { it.userIdSet() }.flattenToSet()
|
||||
suspend fun List<FollowSetEvent>.mapToUserIdSet() = this.map { it.userIdSet() }.flattenToSet()
|
||||
|
||||
suspend fun List<PeopleListEvent>.mapGoodUsersToIdSet() =
|
||||
suspend fun List<FollowSetEvent>.mapGoodUsersToIdSet() =
|
||||
this
|
||||
.mapNotNull {
|
||||
if (it.dTag() != PeopleListEvent.BLOCK_LIST_D_TAG) {
|
||||
if (it.dTag() != FollowSetEvent.BLOCK_LIST_D_TAG) {
|
||||
it.userIdSet()
|
||||
} else {
|
||||
null
|
||||
@@ -127,7 +127,7 @@ class PeopleListsState(
|
||||
.flowOn(Dispatchers.IO)
|
||||
.stateIn(scope, SharingStarted.Eagerly, emptySet())
|
||||
|
||||
suspend fun PeopleListEvent.toUI() =
|
||||
suspend fun FollowSetEvent.toUI() =
|
||||
PeopleList(
|
||||
identifierTag = this.dTag(),
|
||||
title = this.titleOrName() ?: this.dTag(),
|
||||
@@ -137,7 +137,7 @@ class PeopleListsState(
|
||||
publicMembers = cache.load(this.publicUsersIdSet()),
|
||||
)
|
||||
|
||||
suspend fun List<PeopleListEvent>.toUI() = this.map { it.toUI() }.sortedBy { it.title }
|
||||
suspend fun List<FollowSetEvent>.toUI() = this.map { it.toUI() }.sortedBy { it.title }
|
||||
|
||||
val uiListFlow =
|
||||
latestLists
|
||||
@@ -158,12 +158,12 @@ class PeopleListsState(
|
||||
.map { it.select(dTag) }
|
||||
.onStart { emit(selectList(dTag)) }
|
||||
|
||||
fun DeletionEvent.hasDeletedAnyPeopleList() = deleteAddressesWithKind(PeopleListEvent.KIND) || deletesAnyEventIn(peopleListsEventIds.value)
|
||||
fun DeletionRequestEvent.hasDeletedAnyPeopleList() = deleteAddressesWithKind(FollowSetEvent.KIND) || deletesAnyEventIn(peopleListsEventIds.value)
|
||||
|
||||
fun hasItemInNoteList(notes: Set<Note>): Boolean =
|
||||
notes.anyNotNullEvent { event ->
|
||||
if (event.pubKey == signer.pubKey) {
|
||||
event is PeopleListEvent || (event is DeletionEvent && event.hasDeletedAnyPeopleList())
|
||||
event is FollowSetEvent || (event is DeletionRequestEvent && event.hasDeletedAnyPeopleList())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -191,7 +191,7 @@ class PeopleListsState(
|
||||
|
||||
fun getPeopleListNote(noteIdentifier: String): AddressableNote? = existingPeopleListNotes().find { it.dTag() == noteIdentifier }
|
||||
|
||||
fun getPeopleList(noteIdentifier: String): PeopleListEvent = getPeopleListNote(noteIdentifier)?.event as PeopleListEvent
|
||||
fun getPeopleList(noteIdentifier: String): FollowSetEvent = getPeopleListNote(noteIdentifier)?.event as FollowSetEvent
|
||||
|
||||
fun User.toUserTag() = UserTag(this.pubkeyHex, this.bestRelayHint())
|
||||
|
||||
@@ -207,7 +207,7 @@ class PeopleListsState(
|
||||
): String {
|
||||
val dTag = UUID.randomUUID().toString()
|
||||
val newListTemplate =
|
||||
PeopleListEvent.build(
|
||||
FollowSetEvent.build(
|
||||
dTag = dTag,
|
||||
title = listName,
|
||||
publicMembers = if (!isPrivate && member != null) listOf(member.toUserTag()) else emptyList(),
|
||||
@@ -252,7 +252,7 @@ class PeopleListsState(
|
||||
account: Account,
|
||||
) {
|
||||
val newList =
|
||||
PeopleListEvent.createListWithDescription(
|
||||
FollowSetEvent.createListWithDescription(
|
||||
dTag = UUID.randomUUID().toString(),
|
||||
title = customCloneName ?: currentPeopleList.title,
|
||||
description = customCloneDescription ?: currentPeopleList.description,
|
||||
@@ -268,7 +268,7 @@ class PeopleListsState(
|
||||
account: Account,
|
||||
) {
|
||||
val followListEvent = getPeopleList(identifierTag)
|
||||
val deletionEvent = account.signer.sign(DeletionEvent.build(listOf(followListEvent)))
|
||||
val deletionEvent = account.signer.sign(DeletionRequestEvent.build(listOf(followListEvent)))
|
||||
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
||||
// Any screen whose persisted feed filter still points at this list would keep
|
||||
// re-creating an empty shell for its address (and render the dTag/UUID in the
|
||||
@@ -284,7 +284,7 @@ class PeopleListsState(
|
||||
) {
|
||||
val followListEvent = getPeopleList(identifierTag)
|
||||
val newList =
|
||||
PeopleListEvent.addUser(
|
||||
FollowSetEvent.addUser(
|
||||
earlierVersion = followListEvent,
|
||||
pubKeyHex = user.pubkeyHex,
|
||||
relayHint = user.bestRelayHint(),
|
||||
@@ -302,7 +302,7 @@ class PeopleListsState(
|
||||
) {
|
||||
val followListEvent = getPeopleList(identifierTag)
|
||||
val newList =
|
||||
PeopleListEvent.addUserFirst(
|
||||
FollowSetEvent.addUserFirst(
|
||||
earlierVersion = followListEvent,
|
||||
pubKeyHex = user.pubkeyHex,
|
||||
relayHint = user.bestRelayHint(),
|
||||
@@ -320,7 +320,7 @@ class PeopleListsState(
|
||||
) {
|
||||
val followListEvent = getPeopleList(identifierTag)
|
||||
val newList =
|
||||
PeopleListEvent.removeUser(
|
||||
FollowSetEvent.removeUser(
|
||||
earlierVersion = followListEvent,
|
||||
pubKeyHex = user.pubkeyHex,
|
||||
isUserPrivate = isPrivate,
|
||||
|
||||
+10
-10
@@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.commons.model.nip51Lists.relayFeeds.RelayFeeds
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.FavoriteRelayListEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@@ -50,13 +50,13 @@ class RelayFeedListState(
|
||||
// Creates a long-term reference for this note so that the GC doesn't collect the note it self
|
||||
val relayFeedListNote = cache.getOrCreateAddressableNote(getRelayFeedsListAddress())
|
||||
|
||||
fun getRelayFeedsListAddress() = RelayFeedsListEvent.createAddress(signer.pubKey)
|
||||
fun getRelayFeedsListAddress() = FavoriteRelayListEvent.createAddress(signer.pubKey)
|
||||
|
||||
fun getRelayFeedsListFlow(): StateFlow<NoteState> = relayFeedListNote.flow().metadata.stateFlow
|
||||
|
||||
fun getRelayFeedsList(): RelayFeedsListEvent? = relayFeedListNote.event as? RelayFeedsListEvent
|
||||
fun getRelayFeedsList(): FavoriteRelayListEvent? = relayFeedListNote.event as? FavoriteRelayListEvent
|
||||
|
||||
fun relayFeedsListEvent(note: Note) = note.event as? RelayFeedsListEvent ?: settings.backupRelayFeedsList
|
||||
fun relayFeedsListEvent(note: Note) = note.event as? FavoriteRelayListEvent ?: settings.backupRelayFeedsList
|
||||
|
||||
suspend fun normalizeRelayFeedsListWithBackup(note: Note): Set<NormalizedRelayUrl> = relayFeedsListEvent(note)?.let { decryptionCache.relays(it) }?.ifEmpty { null } ?: emptySet()
|
||||
|
||||
@@ -84,30 +84,30 @@ class RelayFeedListState(
|
||||
emptySet(),
|
||||
)
|
||||
|
||||
suspend fun addRelay(relay: NormalizedRelayUrl): RelayFeedsListEvent {
|
||||
suspend fun addRelay(relay: NormalizedRelayUrl): FavoriteRelayListEvent {
|
||||
val current = normalizeRelayFeedsListWithBackupNoDefaults(relayFeedListNote).toMutableList()
|
||||
if (relay !in current) current.add(relay)
|
||||
return saveRelayList(current)
|
||||
}
|
||||
|
||||
suspend fun removeRelay(relay: NormalizedRelayUrl): RelayFeedsListEvent? {
|
||||
suspend fun removeRelay(relay: NormalizedRelayUrl): FavoriteRelayListEvent? {
|
||||
val current = normalizeRelayFeedsListWithBackupNoDefaults(relayFeedListNote).toMutableList()
|
||||
if (relay !in current) return null
|
||||
current.remove(relay)
|
||||
return saveRelayList(current)
|
||||
}
|
||||
|
||||
suspend fun saveRelayList(relayFeeds: List<NormalizedRelayUrl>): RelayFeedsListEvent {
|
||||
suspend fun saveRelayList(relayFeeds: List<NormalizedRelayUrl>): FavoriteRelayListEvent {
|
||||
val relayFeedsList = getRelayFeedsList()
|
||||
|
||||
return if (relayFeedsList != null && relayFeedsList.tags.isNotEmpty()) {
|
||||
RelayFeedsListEvent.updateRelayList(
|
||||
FavoriteRelayListEvent.updateRelayList(
|
||||
earlierVersion = relayFeedsList,
|
||||
relays = relayFeeds,
|
||||
signer = signer,
|
||||
)
|
||||
} else {
|
||||
RelayFeedsListEvent.create(
|
||||
FavoriteRelayListEvent.create(
|
||||
relays = relayFeeds,
|
||||
signer = signer,
|
||||
)
|
||||
@@ -125,7 +125,7 @@ class RelayFeedListState(
|
||||
Log.d("AccountRegisterObservers", "Relay feeds list Collector Start")
|
||||
getRelayFeedsListFlow().collect {
|
||||
Log.d("AccountRegisterObservers") { "Updating Relay feeds list for ${signer.pubKey}" }
|
||||
(it.note.event as? RelayFeedsListEvent)?.let {
|
||||
(it.note.event as? FavoriteRelayListEvent)?.let {
|
||||
settings.updateRelayFeedList(it)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -41,7 +41,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchAllPages
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip60Cashu.history.CashuSpendingHistoryEvent
|
||||
import com.vitorpamplona.quartz.nip60Cashu.mintApi.DeterministicSecretFactory
|
||||
import com.vitorpamplona.quartz.nip60Cashu.mintApi.MeltQuoteBolt11ResponseDto
|
||||
@@ -486,7 +486,7 @@ class CashuWalletState(
|
||||
|
||||
// Process our own NIP-09 deletions inline rather than
|
||||
// relying on LocalCache's `deletedEventBundles`. That
|
||||
// path only fires when `consume(DeletionEvent)` finds
|
||||
// path only fires when `consume(DeletionRequestEvent)` finds
|
||||
// the target Note still resident in `notes` — a
|
||||
// LargeSoftCache backed by WeakReferences, which can
|
||||
// be cleared on any GC cycle. When the weak ref is
|
||||
@@ -503,7 +503,7 @@ class CashuWalletState(
|
||||
val ourDeleteIds =
|
||||
all
|
||||
.asSequence()
|
||||
.filterIsInstance<DeletionEvent>()
|
||||
.filterIsInstance<DeletionRequestEvent>()
|
||||
.filter { it.pubKey == pubKey }
|
||||
.flatMap { it.deleteEventIds().asSequence() }
|
||||
.toSet()
|
||||
@@ -1447,7 +1447,7 @@ class CashuWalletState(
|
||||
}
|
||||
val redundantIds = redundant.map { it.event.id }.toSet()
|
||||
runCatching {
|
||||
val template = DeletionEvent.build(redundant.map { it.event })
|
||||
val template = DeletionRequestEvent.build(redundant.map { it.event })
|
||||
val signed = signer.sign(template)
|
||||
publishEvent(signed)
|
||||
}.onFailure {
|
||||
|
||||
@@ -67,7 +67,7 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.lightning.LnInvoiceUtil
|
||||
import com.vitorpamplona.quartz.nip01Core.core.fastForEach
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import org.jetbrains.compose.resources.PluralStringResource
|
||||
@@ -199,7 +199,7 @@ class NappletConsentSummary(
|
||||
oneRemoved = Res.string.napplet_consent_diff_unmute_one,
|
||||
)
|
||||
// Deletions have no prior version to compare against — the tags are the whole request.
|
||||
DeletionEvent.KIND ->
|
||||
DeletionRequestEvent.KIND ->
|
||||
pluralFor(Res.plurals.napplet_consent_effect_deletes, countTag(tags, "e") + countTag(tags, "a"))
|
||||
?.let { Consequence(it) }
|
||||
// Any other kind: at least tell the user tags exist and can be inspected, so an empty
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.napplet.gateways
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.award.BadgeAwardEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.definition.BadgeDefinitionEvent
|
||||
import kotlinx.serialization.json.add
|
||||
@@ -137,7 +137,7 @@ class AccountIdentityReader(
|
||||
val receipts =
|
||||
cache
|
||||
.filter(Filter(kinds = listOf(9735), tags = mapOf("p" to listOf(pubkey))))
|
||||
.mapNotNull { it.event as? LnZapEvent }
|
||||
.mapNotNull { it.event as? ZapReceiptEvent }
|
||||
return buildJsonArray {
|
||||
receipts.forEach { zap ->
|
||||
addJsonObject {
|
||||
|
||||
@@ -40,7 +40,7 @@ import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.PayKeysendMethod
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Response
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.TlvRecord
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.validate.LnurlForm
|
||||
import com.vitorpamplona.quartz.podcasts.PodcastBoostagram
|
||||
import com.vitorpamplona.quartz.podcasts.PodcastValue
|
||||
@@ -91,7 +91,7 @@ class V4VPaymentHandler(
|
||||
onProgress: (percent: Float) -> Unit,
|
||||
onPayInvoicesViaIntent: (invoices: List<String>) -> Unit,
|
||||
asZap: Boolean = false,
|
||||
zapType: LnZapEvent.ZapType = LnZapEvent.ZapType.PUBLIC,
|
||||
zapType: ZapReceiptEvent.ZapType = ZapReceiptEvent.ZapType.PUBLIC,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
val shares = value.computeShares(totalMilliSats)
|
||||
if (shares.isEmpty()) {
|
||||
@@ -190,7 +190,7 @@ class V4VPaymentHandler(
|
||||
shares: List<PodcastValueShare>,
|
||||
message: String,
|
||||
asZap: Boolean,
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
zappedNote: Note?,
|
||||
okHttpClient: (String) -> OkHttpClient,
|
||||
context: Context,
|
||||
|
||||
@@ -48,8 +48,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.NwcErrorCode
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.NwcTransactionMetadata
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupLnAddress
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.zapSplitSetup
|
||||
@@ -79,7 +79,7 @@ class ZapPaymentHandler(
|
||||
// The signed kind 9734 this invoice was fetched with, and the message on it.
|
||||
// Carried so the NWC payment can name the payee (NWC-06 `metadata`); null for
|
||||
// a NONZAP split, which has no zap request to send.
|
||||
val zapRequest: LnZapRequestEvent? = null,
|
||||
val zapRequest: ZapRequestEvent? = null,
|
||||
val message: String = "",
|
||||
)
|
||||
|
||||
@@ -122,7 +122,7 @@ class ZapPaymentHandler(
|
||||
onError: (String, String, User?) -> Unit,
|
||||
onProgress: (percent: Float) -> Unit,
|
||||
onPayViaIntent: (ImmutableList<Payable>) -> Unit,
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
val noteEvent = note.event
|
||||
val zapSplitSetup = noteEvent?.zapSplitSetup()
|
||||
@@ -297,7 +297,7 @@ class ZapPaymentHandler(
|
||||
note: Note,
|
||||
pollOption: Int?,
|
||||
message: String,
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
totalAmountMilliSats: Long,
|
||||
totalWeight: Double,
|
||||
okHttpClient: (String) -> OkHttpClient,
|
||||
@@ -360,14 +360,14 @@ class ZapPaymentHandler(
|
||||
|
||||
class ZapRequestReady(
|
||||
val inputSetup: MyZapSplitSetup,
|
||||
val zapRequest: LnZapRequestEvent?,
|
||||
val zapRequest: ZapRequestEvent?,
|
||||
)
|
||||
|
||||
suspend fun signAllZapRequests(
|
||||
note: Note,
|
||||
pollOption: Int?,
|
||||
message: String,
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
zapsToSend: List<MyZapSplitSetup>,
|
||||
totalAmountMilliSats: Long,
|
||||
// Shared across the lightning + BOLT12 lanes so a mixed split stays proportional.
|
||||
@@ -389,7 +389,7 @@ class ZapPaymentHandler(
|
||||
val splitLnurl = LnurlForm.toUrl(next.lnAddress)?.let(LnurlForm::urlToBech32)
|
||||
|
||||
val zapRequest =
|
||||
if (zapType != LnZapEvent.ZapType.NONZAP && noteEvent != null) {
|
||||
if (zapType != ZapReceiptEvent.ZapType.NONZAP && noteEvent != null) {
|
||||
account.zaps.createZapRequestFor(
|
||||
event = noteEvent,
|
||||
pollOption = pollOption,
|
||||
@@ -535,7 +535,7 @@ class ZapPaymentHandler(
|
||||
totalAmountMilliSats: Long,
|
||||
totalWeight: Double,
|
||||
message: String,
|
||||
zapType: LnZapEvent.ZapType,
|
||||
zapType: ZapReceiptEvent.ZapType,
|
||||
okHttpClient: (String) -> OkHttpClient,
|
||||
onError: (String, String, User?) -> Unit,
|
||||
onProgress: (percent: Float) -> Unit,
|
||||
@@ -672,7 +672,7 @@ class ZapPaymentHandler(
|
||||
private suspend fun assembleInvoice(
|
||||
lud16: String,
|
||||
splitSetup: MyZapSplitSetup,
|
||||
nostrZapRequest: LnZapRequestEvent?,
|
||||
nostrZapRequest: ZapRequestEvent?,
|
||||
zapValue: Long,
|
||||
message: String,
|
||||
okHttpClient: (String) -> OkHttpClient,
|
||||
@@ -683,7 +683,7 @@ class ZapPaymentHandler(
|
||||
|
||||
// Only the request the provider actually accepted may be claimed as bound to
|
||||
// this invoice; see lnAddressInvoice's onZapRequestSent.
|
||||
var sentZapRequest: LnZapRequestEvent? = null
|
||||
var sentZapRequest: ZapRequestEvent? = null
|
||||
|
||||
val invoice =
|
||||
LightningAddressResolver().lnAddressInvoice(
|
||||
|
||||
+4
-4
@@ -38,7 +38,7 @@ import com.vitorpamplona.amethyst.commons.ui.loadStringRes
|
||||
import com.vitorpamplona.amethyst.service.HttpStatusMessages
|
||||
import com.vitorpamplona.quartz.lightning.LnInvoiceUtil
|
||||
import com.vitorpamplona.quartz.lightning.Lud06
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.validate.LnurlEndpointCache
|
||||
import com.vitorpamplona.quartz.nip57Zaps.validate.LnurlEndpointInfo
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
@@ -128,7 +128,7 @@ class LightningAddressResolver {
|
||||
lnCallback: String,
|
||||
milliSats: Long,
|
||||
message: String,
|
||||
nostrRequest: LnZapRequestEvent? = null,
|
||||
nostrRequest: ZapRequestEvent? = null,
|
||||
okHttpClient: (String) -> OkHttpClient,
|
||||
context: Context,
|
||||
): String {
|
||||
@@ -219,11 +219,11 @@ class LightningAddressResolver {
|
||||
lnAddress: String,
|
||||
milliSats: Long,
|
||||
message: String,
|
||||
nostrRequest: LnZapRequestEvent? = null,
|
||||
nostrRequest: ZapRequestEvent? = null,
|
||||
okHttpClient: (String) -> OkHttpClient,
|
||||
onProgress: (percent: Float) -> Unit,
|
||||
context: Context,
|
||||
onZapRequestSent: (LnZapRequestEvent?) -> Unit = {},
|
||||
onZapRequestSent: (ZapRequestEvent?) -> Unit = {},
|
||||
): String {
|
||||
val mapper = ObjectMapper()
|
||||
|
||||
|
||||
+13
-13
@@ -64,7 +64,7 @@ import com.vitorpamplona.quartz.marmot.mip02Welcome.WelcomeEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
@@ -72,7 +72,7 @@ import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.bech32.bechToBytes
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
@@ -84,17 +84,17 @@ import com.vitorpamplona.quartz.nip34Git.status.GitStatusAppliedEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusClosedEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusDraftEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusOpenEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiArticleEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.award.BadgeAwardEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.nutzap.NutzapEvent
|
||||
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.LiveChessGameAcceptEvent
|
||||
import com.vitorpamplona.quartz.nip64Chess.move.LiveChessMoveEvent
|
||||
import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.AddressableNormalVideoEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.AddressableShortVideoEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoNormalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoShortEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallOfferEvent
|
||||
@@ -234,7 +234,7 @@ class EventNotificationConsumer(
|
||||
// public chat the user has silenced (matches the in-app feed, which mutes all four).
|
||||
// Without the second check, muting a channel still let a like on your own message
|
||||
// there notify you — the row's glyph promises silence, so it has to mean it.
|
||||
if (event is ReactionEvent || event is LnZapEvent || event is RepostEvent || event is GenericRepostEvent) {
|
||||
if (event is ReactionEvent || event is ZapReceiptEvent || event is RepostEvent || event is GenericRepostEvent) {
|
||||
val target = LocalCache.getNoteIfExists(event)?.replyTo?.lastOrNull()
|
||||
if (target != null &&
|
||||
(
|
||||
@@ -247,7 +247,7 @@ class EventNotificationConsumer(
|
||||
}
|
||||
|
||||
when (event) {
|
||||
is PrivateDmEvent -> DirectMessageNotification.notify(applicationContext, account, event)
|
||||
is EncryptedDmEvent -> DirectMessageNotification.notify(applicationContext, account, event)
|
||||
is ChatMessageEvent -> DirectMessageNotification.notify(applicationContext, account, event)
|
||||
is ChatMessageEncryptedFileHeaderEvent -> DirectMessageNotification.notify(applicationContext, account, event)
|
||||
|
||||
@@ -256,7 +256,7 @@ class EventNotificationConsumer(
|
||||
is StreamMessageV2Event -> BuzzDmNotification.notify(applicationContext, account, event)
|
||||
is ChatEvent -> BuzzDmNotification.notify(applicationContext, account, event)
|
||||
|
||||
is LnZapEvent -> ZapNotification.notify(applicationContext, account, event)
|
||||
is ZapReceiptEvent -> ZapNotification.notify(applicationContext, account, event)
|
||||
is NutzapEvent -> ZapNotification.notify(applicationContext, account, event)
|
||||
is OnchainZapEvent -> ZapNotification.notify(applicationContext, account, event)
|
||||
|
||||
@@ -274,15 +274,15 @@ class EventNotificationConsumer(
|
||||
is PictureEvent,
|
||||
is VideoNormalEvent,
|
||||
is VideoShortEvent,
|
||||
is VideoHorizontalEvent,
|
||||
is VideoVerticalEvent,
|
||||
is AddressableNormalVideoEvent,
|
||||
is AddressableShortVideoEvent,
|
||||
-> MediaNotification.notify(applicationContext, account, event)
|
||||
|
||||
is PollEvent -> MentionNotification.notify(applicationContext, account, event, titleRes = Res.string.app_notification_poll_channel_message)
|
||||
|
||||
is HighlightEvent,
|
||||
is LongTextNoteEvent,
|
||||
is WikiNoteEvent,
|
||||
is LongFormContentEvent,
|
||||
is WikiArticleEvent,
|
||||
-> ArticleNotification.notify(applicationContext, account, event)
|
||||
|
||||
is GitIssueEvent -> CodeNotification.notify(applicationContext, account, event)
|
||||
|
||||
+5
-5
@@ -27,11 +27,11 @@ import com.vitorpamplona.amethyst.commons.model.nip71Video.selectVideoTrack
|
||||
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoEvent
|
||||
|
||||
@@ -177,7 +177,7 @@ object NotificationContent {
|
||||
}
|
||||
|
||||
suspend fun decryptZapContentAuthor(
|
||||
event: LnZapRequestEvent,
|
||||
event: ZapRequestEvent,
|
||||
signer: NostrSigner,
|
||||
): Event? =
|
||||
if (event.isPrivateZap() && event.zappedAuthor().contains(event.pubKey)) {
|
||||
@@ -191,8 +191,8 @@ object NotificationContent {
|
||||
signer: NostrSigner,
|
||||
): String? =
|
||||
when (val event = note.event) {
|
||||
is PrivateDmEvent -> event.decryptContent(signer)
|
||||
is LnZapRequestEvent -> decryptZapContentAuthor(event, signer)?.content
|
||||
is EncryptedDmEvent -> event.decryptContent(signer)
|
||||
is ZapRequestEvent -> decryptZapContentAuthor(event, signer)?.content
|
||||
else -> event?.content
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -32,7 +32,7 @@ import com.vitorpamplona.quartz.marmot.mip02Welcome.WelcomeEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
@@ -40,7 +40,7 @@ import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.bech32.bechToBytes
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
@@ -52,17 +52,17 @@ import com.vitorpamplona.quartz.nip34Git.status.GitStatusAppliedEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusClosedEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusDraftEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusOpenEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiArticleEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.award.BadgeAwardEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.nutzap.NutzapEvent
|
||||
import com.vitorpamplona.quartz.nip64Chess.challenge.accept.LiveChessGameAcceptEvent
|
||||
import com.vitorpamplona.quartz.nip64Chess.move.LiveChessMoveEvent
|
||||
import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.AddressableNormalVideoEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.AddressableShortVideoEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoNormalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoShortEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallOfferEvent
|
||||
@@ -118,8 +118,8 @@ class NotificationDispatcher(
|
||||
internal val NOTIFICATION_KINDS: Set<Int> =
|
||||
setOf(
|
||||
// Direct-arrival
|
||||
PrivateDmEvent.KIND,
|
||||
LnZapEvent.KIND,
|
||||
EncryptedDmEvent.KIND,
|
||||
ZapReceiptEvent.KIND,
|
||||
NutzapEvent.KIND,
|
||||
OnchainZapEvent.KIND,
|
||||
Bolt12ZapEvent.KIND,
|
||||
@@ -133,8 +133,8 @@ class NotificationDispatcher(
|
||||
PictureEvent.KIND,
|
||||
VideoNormalEvent.KIND,
|
||||
VideoShortEvent.KIND,
|
||||
VideoHorizontalEvent.KIND,
|
||||
VideoVerticalEvent.KIND,
|
||||
AddressableNormalVideoEvent.KIND,
|
||||
AddressableShortVideoEvent.KIND,
|
||||
ChannelMessageEvent.KIND,
|
||||
PollEvent.KIND,
|
||||
GitPatchEvent.KIND,
|
||||
@@ -150,8 +150,8 @@ class NotificationDispatcher(
|
||||
GitStatusClosedEvent.KIND,
|
||||
GitStatusDraftEvent.KIND,
|
||||
HighlightEvent.KIND,
|
||||
LongTextNoteEvent.KIND,
|
||||
WikiNoteEvent.KIND,
|
||||
LongFormContentEvent.KIND,
|
||||
WikiArticleEvent.KIND,
|
||||
LiveChessGameAcceptEvent.KIND,
|
||||
LiveChessMoveEvent.KIND,
|
||||
WakeUpEvent.KIND,
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.Conver
|
||||
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.ReplyAction
|
||||
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.postConversation
|
||||
import com.vitorpamplona.amethyst.service.notifications.notificationManager
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
@@ -64,7 +64,7 @@ object DirectMessageNotification {
|
||||
suspend fun notify(
|
||||
context: Context,
|
||||
account: Account,
|
||||
event: PrivateDmEvent,
|
||||
event: EncryptedDmEvent,
|
||||
) {
|
||||
if (account.signer.pubKey != event.verifiedRecipientPubKey()) return
|
||||
notifyRoom(context, account, event.id, event.createdAt, event.chatroomKey(account.signer.pubKey), decrypt = true)
|
||||
|
||||
+4
-4
@@ -39,8 +39,8 @@ import com.vitorpamplona.amethyst.service.notifications.NotificationRoutes
|
||||
import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.postStandard
|
||||
import com.vitorpamplona.amethyst.service.notifications.notificationManager
|
||||
import com.vitorpamplona.amethyst.ui.note.showAmount
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.nutzap.NutzapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
@@ -59,7 +59,7 @@ object ZapNotification {
|
||||
suspend fun notify(
|
||||
context: Context,
|
||||
account: Account,
|
||||
event: LnZapEvent,
|
||||
event: ZapReceiptEvent,
|
||||
) {
|
||||
LocalCache.getNoteIfExists(event.id) ?: return
|
||||
val zapRequestNote = event.zapRequest?.id?.let { LocalCache.checkGetOrCreateNote(it) } ?: return
|
||||
@@ -67,7 +67,7 @@ object ZapNotification {
|
||||
if (!account.isAcceptable(zappedNote)) return
|
||||
if ((event.amount ?: BigDecimal.ZERO) < MIN_ZAP_AMOUNT) return
|
||||
|
||||
val zapRequestEvent = zapRequestNote.event as? LnZapRequestEvent ?: return
|
||||
val zapRequestEvent = zapRequestNote.event as? ZapRequestEvent ?: return
|
||||
// Resolve the (possibly private) zapper once — never re-decrypt per tick.
|
||||
val decrypted = NotificationContent.decryptZapContentAuthor(zapRequestEvent, account.signer) ?: return
|
||||
val sender = LocalCache.getOrCreateUser(decrypted.pubKey)
|
||||
|
||||
+8
-8
@@ -32,18 +32,18 @@ import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.privateOutbox.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent
|
||||
import com.vitorpamplona.quartz.nip38UserStatus.UserStatusEvent
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.interestSet.InterestSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BroadcastRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.FavoriteRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.ProxyRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.simpleGroupList.SimpleGroupListEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.nestsServers.NestsServersEvent
|
||||
@@ -60,9 +60,9 @@ val AccountInfoAndListsFromKeyKinds =
|
||||
listOf(
|
||||
MetadataEvent.KIND,
|
||||
ContactListEvent.KIND,
|
||||
StatusEvent.KIND,
|
||||
UserStatusEvent.KIND,
|
||||
AdvertisedRelayListEvent.KIND,
|
||||
ChatMessageRelayListEvent.KIND,
|
||||
DmRelayListEvent.KIND,
|
||||
KeyPackageRelayListEvent.KIND,
|
||||
SearchRelayListEvent.KIND,
|
||||
FileServersEvent.KIND,
|
||||
@@ -78,12 +78,12 @@ val AccountInfoAndListsFromKeyKinds2 =
|
||||
BroadcastRelayListEvent.KIND,
|
||||
IndexerRelayListEvent.KIND,
|
||||
ProxyRelayListEvent.KIND,
|
||||
HashtagListEvent.KIND,
|
||||
InterestListEvent.KIND,
|
||||
GeohashListEvent.KIND,
|
||||
TrustProviderListEvent.KIND,
|
||||
PaymentTargetsEvent.KIND,
|
||||
Bolt12OfferListEvent.KIND,
|
||||
RelayFeedsListEvent.KIND,
|
||||
FavoriteRelayListEvent.KIND,
|
||||
InterestSetEvent.KIND,
|
||||
// NIP-51 "simple groups" list (kind 10009): the user's joined NIP-29 groups + servers.
|
||||
// Loaded up-front so "My Groups" and group memberships resolve immediately at login,
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.nip47WalletConnect.NWCPaym
|
||||
import com.vitorpamplona.amethyst.commons.relayClient.nip47WalletConnect.NWCPaymentQueryState
|
||||
import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.KeyDataSourceSubscription
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.LnZapPaymentRequestEvent
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.events.NwcRequestEvent
|
||||
|
||||
@SuppressLint("StateFlowValueCalledInComposition")
|
||||
@Composable
|
||||
@@ -50,7 +50,7 @@ fun NWCFinderFilterAssemblerSubscription(
|
||||
val states =
|
||||
remember(note) {
|
||||
val zapPaymentRequestNote = note
|
||||
(zapPaymentRequestNote.event as? LnZapPaymentRequestEvent)?.let { noteEvent ->
|
||||
(zapPaymentRequestNote.event as? NwcRequestEvent)?.let { noteEvent ->
|
||||
noteEvent.walletServicePubKey()?.let {
|
||||
zapPaymentRequestNote.relays.map {
|
||||
NWCPaymentQueryState(
|
||||
|
||||
+5
-5
@@ -39,7 +39,7 @@ import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.PinListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.OldBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -132,9 +132,9 @@ fun observeUserTagFollowCount(
|
||||
.metadata.stateFlow
|
||||
.sample(1000)
|
||||
.mapLatest { noteState ->
|
||||
(noteState.note.event as? HashtagListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.size ?: 0
|
||||
(noteState.note.event as? InterestListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.size ?: 0
|
||||
}.onStart {
|
||||
emit((accountViewModel.hashtagFollows(user).event as? HashtagListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.size ?: 0)
|
||||
emit((accountViewModel.hashtagFollows(user).event as? InterestListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.size ?: 0)
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
@@ -160,9 +160,9 @@ fun observeUserTagFollows(
|
||||
.metadata.stateFlow
|
||||
.sample(200)
|
||||
.mapLatest { noteState ->
|
||||
(noteState.note.event as? HashtagListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.sorted() ?: emptyList()
|
||||
(noteState.note.event as? InterestListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.sorted() ?: emptyList()
|
||||
}.onStart {
|
||||
emit((accountViewModel.hashtagFollows(user).event as? HashtagListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.sorted() ?: emptyList())
|
||||
emit((accountViewModel.hashtagFollows(user).event as? InterestListEvent)?.let { accountViewModel.account.hashtagListDecryptionCache.hashtags(it) }?.sorted() ?: emptyList())
|
||||
}.distinctUntilChanged()
|
||||
.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.signer.NostrSignerRemote
|
||||
import com.vitorpamplona.quartz.nip55AndroidSigner.client.NostrSignerExternal
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.NostrSignerWithClientTag
|
||||
|
||||
/**
|
||||
@@ -89,7 +89,7 @@ class MeteringNostrSigner(
|
||||
fromPublicKey: HexKey,
|
||||
): String = metered(UsageKeys.DECRYPT_COUNT, UsageKeys.DECRYPT_US) { inner.nip44Decrypt(ciphertext, fromPublicKey) }
|
||||
|
||||
override suspend fun decryptZapEvent(event: LnZapRequestEvent): LnZapPrivateEvent = metered(UsageKeys.DECRYPT_COUNT, UsageKeys.DECRYPT_US) { inner.decryptZapEvent(event) }
|
||||
override suspend fun decryptZapEvent(event: ZapRequestEvent): LnZapPrivateEvent = metered(UsageKeys.DECRYPT_COUNT, UsageKeys.DECRYPT_US) { inner.decryptZapEvent(event) }
|
||||
|
||||
override suspend fun deriveKey(nonce: HexKey): HexKey = inner.deriveKey(nonce)
|
||||
|
||||
|
||||
+7
-7
@@ -26,9 +26,9 @@ import com.davotoula.lightcompressor.hls.HlsUploaded
|
||||
import com.vitorpamplona.amethyst.service.uploads.MediaUploadResult
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.contentWarning
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.AddressableNormalVideoEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.AddressableShortVideoEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoMeta
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.duration
|
||||
import com.vitorpamplona.quartz.nip71Video.title
|
||||
import com.vitorpamplona.quartz.nip71Video.videoIMetas
|
||||
@@ -61,11 +61,11 @@ data class HlsVideoPublishInput(
|
||||
|
||||
sealed class HlsVideoEventTemplate {
|
||||
data class Horizontal(
|
||||
val template: EventTemplate<VideoHorizontalEvent>,
|
||||
val template: EventTemplate<AddressableNormalVideoEvent>,
|
||||
) : HlsVideoEventTemplate()
|
||||
|
||||
data class Vertical(
|
||||
val template: EventTemplate<VideoVerticalEvent>,
|
||||
val template: EventTemplate<AddressableShortVideoEvent>,
|
||||
) : HlsVideoEventTemplate()
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ data class HlsBuiltTemplate(
|
||||
)
|
||||
|
||||
/**
|
||||
* Assembles a NIP-71 VideoHorizontalEvent / VideoVerticalEvent template from an HLS upload
|
||||
* Assembles a NIP-71 AddressableNormalVideoEvent / AddressableShortVideoEvent template from an HLS upload
|
||||
* result. Orientation is decided from the first rendition's width/height: portrait
|
||||
* (height > width) selects kind 34236, otherwise 34235.
|
||||
*
|
||||
@@ -142,7 +142,7 @@ object HlsVideoEventBuilder {
|
||||
val template =
|
||||
if (isVertical) {
|
||||
HlsVideoEventTemplate.Vertical(
|
||||
VideoVerticalEvent.build(input.description, dTag, createdAt) {
|
||||
AddressableShortVideoEvent.build(input.description, dTag, createdAt) {
|
||||
videoIMetas(videoMetas)
|
||||
title(input.title)
|
||||
input.durationSeconds?.let { duration(it) }
|
||||
@@ -151,7 +151,7 @@ object HlsVideoEventBuilder {
|
||||
)
|
||||
} else {
|
||||
HlsVideoEventTemplate.Horizontal(
|
||||
VideoHorizontalEvent.build(input.description, dTag, createdAt) {
|
||||
AddressableNormalVideoEvent.build(input.description, dTag, createdAt) {
|
||||
videoIMetas(videoMetas)
|
||||
title(input.title)
|
||||
input.durationSeconds?.let { duration(it) }
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.uriToRoute
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip92IMeta.imetasByUrl
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@@ -425,7 +425,7 @@ fun RenderContentAsMarkdownNotePreview() {
|
||||
runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
val blogPost =
|
||||
LongTextNoteEvent(
|
||||
LongFormContentEvent(
|
||||
id = "e69fa72a221d0b7362f8e63fd6ab84cc6b5e7b505fe49cefe6823a47a6a4b583",
|
||||
pubKey = "88cc134b1a65f54ef48acc1df3665063d3ea45f04eab8af4646e561c5ae99079",
|
||||
createdAt = 1718785725,
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasMoreHashtagsThan
|
||||
import com.vitorpamplona.quartz.nip10Notes.threadRootIdOrSelf
|
||||
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.FollowSetEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
class FilterByListParams(
|
||||
@@ -105,7 +105,7 @@ class FilterByListParams(
|
||||
fun showHiddenKey(
|
||||
selectedListName: String,
|
||||
userHex: String,
|
||||
) = selectedListName == PeopleListEvent.blockListFor(userHex) || selectedListName == MuteListEvent.blockListFor(userHex)
|
||||
) = selectedListName == FollowSetEvent.blockListFor(userHex) || selectedListName == MuteListEvent.blockListFor(userHex)
|
||||
|
||||
fun create(
|
||||
followLists: IFeedTopNavFilter?,
|
||||
|
||||
@@ -298,7 +298,7 @@ private class WarmTargets {
|
||||
|
||||
/**
|
||||
* Adds NIP-94 file-header media: blobs declared as top-level `url` tags (not
|
||||
* imeta), as used by FileHeaderEvent and the gallery/file kinds. Only image
|
||||
* imeta), as used by FileMetadataEvent and the gallery/file kinds. Only image
|
||||
* files are prefetched — detected by the URL extension or the event's top-level
|
||||
* `m` mime type (a hashed URL may carry no extension). The decode listener
|
||||
* records their dims like any other image.
|
||||
@@ -333,7 +333,7 @@ private fun Note.collectWarmTargets(): WarmTargets? {
|
||||
}
|
||||
|
||||
// NIP-94 file-header convention: the blob is a top-level `url` tag with sibling
|
||||
// `m`/`dim`, not imeta (FileHeaderEvent and the gallery/file kinds). The generic
|
||||
// `m`/`dim`, not imeta (FileMetadataEvent and the gallery/file kinds). The generic
|
||||
// imetas() above misses these entirely.
|
||||
targets.addFileHeaderMedia(ev)
|
||||
|
||||
|
||||
+9
-9
@@ -44,7 +44,7 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.IsInPublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
@@ -57,12 +57,12 @@ import com.vitorpamplona.quartz.nip34Git.pr.GitPullRequestEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.pr.GitPullRequestUpdateEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.StarterPackEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.HasInnerEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
||||
import com.vitorpamplona.quartz.nip71Video.VideoNormalEvent
|
||||
@@ -247,7 +247,7 @@ fun routeForInner(
|
||||
}
|
||||
}
|
||||
|
||||
is FollowListEvent -> {
|
||||
is StarterPackEvent -> {
|
||||
Route.FollowPack(noteEvent.address())
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ fun routeForInner(
|
||||
Route.GeocacheHunt(noteEvent.kind, noteEvent.pubKey, noteEvent.dTag())
|
||||
}
|
||||
|
||||
is GiftWrapEvent, is SealedRumorEvent -> {
|
||||
is GiftWrapEvent, is SealEvent -> {
|
||||
val wrap = noteEvent as HasInnerEvent
|
||||
wrap.innerEventId?.let {
|
||||
routeFor(LocalCache.getOrCreateNote(it), loggedIn)
|
||||
@@ -456,7 +456,7 @@ fun routeReplyTo(
|
||||
}
|
||||
|
||||
is ChatroomKeyable -> {
|
||||
// Covers PrivateDmEvent (NIP-04) and BaseDMGroupEvent (NIP-17) — both
|
||||
// Covers EncryptedDmEvent (NIP-04) and BaseDMGroupEvent (NIP-17) — both
|
||||
// implement ChatroomKeyable with identical routing semantics here.
|
||||
routeToMessage(
|
||||
room = noteEvent.chatroomKey(account.userProfile().pubkeyHex),
|
||||
@@ -477,7 +477,7 @@ fun routeReplyTo(
|
||||
}
|
||||
}
|
||||
|
||||
is LnZapEvent -> {
|
||||
is ZapReceiptEvent -> {
|
||||
// A public reply can't tag a private zapper without exposing them.
|
||||
// When we hold the decrypted sender (we are the zap recipient), reply
|
||||
// in their DM room instead of the public comment composer.
|
||||
@@ -532,7 +532,7 @@ suspend fun routeEditDraftTo(
|
||||
Route.NewShortNote(draft = note.idHex)
|
||||
}
|
||||
|
||||
is LongTextNoteEvent -> {
|
||||
is LongFormContentEvent -> {
|
||||
Route.NewLongFormPost(draft = note.idHex)
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -84,7 +84,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.firstTaggedUserId
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.taggedEmojis
|
||||
import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent
|
||||
import com.vitorpamplona.quartz.nip38UserStatus.UserStatusEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
@@ -219,14 +219,14 @@ fun DisplayStatus(
|
||||
nav: INav,
|
||||
) {
|
||||
val noteState by observeNote(addressableNote, accountViewModel)
|
||||
val noteEvent = noteState.note.event as? StatusEvent ?: return
|
||||
val noteEvent = noteState.note.event as? UserStatusEvent ?: return
|
||||
|
||||
DisplayStatus(noteEvent, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DisplayStatus(
|
||||
event: StatusEvent,
|
||||
event: UserStatusEvent,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@@ -266,7 +266,7 @@ fun DisplayStatusInner(
|
||||
nav: INav,
|
||||
) {
|
||||
when (type) {
|
||||
StatusEvent.MUSIC -> {
|
||||
UserStatusEvent.MUSIC -> {
|
||||
Icon(
|
||||
imageVector = CustomHashTagIcons.Tunestr,
|
||||
null,
|
||||
|
||||
@@ -331,16 +331,16 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geoHashOrScope
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip13Pow.strongPoWOrNull
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ExternalReactionEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
@@ -368,26 +368,26 @@ import com.vitorpamplona.quartz.nip51Lists.articleCurationSet.ArticleCurationSet
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.OldBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.StarterPackEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.gitAuthorList.GitAuthorListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.gitRepositoryList.GitRepositoryListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.goodWikiAuthorList.GoodWikiAuthorListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.goodWikiRelayList.GoodWikiRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.interestSet.InterestSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.kindMuteSet.KindMuteSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.LabeledBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.BookmarkSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.mediaFollowList.MediaFollowListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.mediaStarterPack.MediaStarterPackEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.FollowSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.pictureCurationSet.PictureCurationSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BroadcastRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.FavoriteRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.ProxyRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relaySets.RelaySetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.releaseArtifactSet.ReleaseArtifactSetEvent
|
||||
@@ -395,19 +395,19 @@ import com.vitorpamplona.quartz.nip51Lists.simpleGroupList.SimpleGroupListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.videoCurationSet.VideoCurationSetEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.day.CalendarDateSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.time.CalendarTimeSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.rsvp.CalendarRSVPEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.clip.LiveActivitiesClipEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiArticleEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiMergeAcceptanceEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiMergeRequestEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiRedirectEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.hasZapSplitSetupBesidesAuthor
|
||||
import com.vitorpamplona.quartz.nip58Badges.award.BadgeAwardEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.definition.BadgeDefinitionEvent
|
||||
@@ -427,7 +427,7 @@ import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprov
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.communityAddress
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.isACommunityPost
|
||||
import com.vitorpamplona.quartz.nip75ZapGoals.GoalEvent
|
||||
import com.vitorpamplona.quartz.nip75ZapGoals.ZapGoalEvent
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
|
||||
import com.vitorpamplona.quartz.nip7DThreads.ThreadEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
@@ -437,9 +437,9 @@ import com.vitorpamplona.quartz.nip87Ecash.recommendation.MintRecommendationEven
|
||||
import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.DvmContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.status.DvmStatusEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.BaseVoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent
|
||||
@@ -1145,7 +1145,7 @@ private fun RenderNoteRow(
|
||||
RenderReport(baseNote, quotesLeft, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is LongTextNoteEvent -> {
|
||||
is LongFormContentEvent -> {
|
||||
RenderLongFormContent(baseNote, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1171,7 +1171,7 @@ private fun RenderNoteRow(
|
||||
RenderCodeSnippetEvent(baseNote)
|
||||
}
|
||||
|
||||
is WikiNoteEvent -> {
|
||||
is WikiArticleEvent -> {
|
||||
RenderWikiContent(baseNote, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1191,7 +1191,7 @@ private fun RenderNoteRow(
|
||||
BadgeDisplay(baseNote = baseNote, accountViewModel = accountViewModel, nav = nav)
|
||||
}
|
||||
|
||||
is LnZapEvent -> {
|
||||
is ZapReceiptEvent -> {
|
||||
RenderLnZap(baseNote, quotesLeft, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1215,11 +1215,11 @@ private fun RenderNoteRow(
|
||||
RenderFhirResource(baseNote, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is PeopleListEvent -> {
|
||||
is FollowSetEvent -> {
|
||||
DisplayPeopleList(baseNote, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is FollowListEvent -> {
|
||||
is StarterPackEvent -> {
|
||||
DisplayFollowList(baseNote, true, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1231,7 +1231,7 @@ private fun RenderNoteRow(
|
||||
DisplayRelaySet(baseNote, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is ChatMessageRelayListEvent -> {
|
||||
is DmRelayListEvent -> {
|
||||
DisplayDMRelayList(baseNote, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1251,7 +1251,7 @@ private fun RenderNoteRow(
|
||||
DisplayTrustedRelayList(baseNote, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is RelayFeedsListEvent -> {
|
||||
is FavoriteRelayListEvent -> {
|
||||
DisplayRelayFeedsList(baseNote, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1384,7 +1384,7 @@ private fun RenderNoteRow(
|
||||
)
|
||||
}
|
||||
|
||||
is PrivateDmEvent -> {
|
||||
is EncryptedDmEvent -> {
|
||||
RenderPrivateMessage(
|
||||
baseNote,
|
||||
makeItShort,
|
||||
@@ -1494,7 +1494,7 @@ private fun RenderNoteRow(
|
||||
RenderCalendarDateSlotEvent(baseNote, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is CalendarEvent -> {
|
||||
is CalendarCollectionEvent -> {
|
||||
RenderCalendarCollectionEvent(baseNote, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1502,7 +1502,7 @@ private fun RenderNoteRow(
|
||||
RenderCalendarRSVPEvent(baseNote, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is GoalEvent -> {
|
||||
is ZapGoalEvent -> {
|
||||
RenderGoal(baseNote, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1550,7 +1550,7 @@ private fun RenderNoteRow(
|
||||
)
|
||||
}
|
||||
|
||||
is NIP90ContentDiscoveryResponseEvent -> {
|
||||
is DvmContentDiscoveryResponseEvent -> {
|
||||
RenderNIP90ContentDiscoveryResponse(
|
||||
baseNote,
|
||||
makeItShort,
|
||||
@@ -1562,7 +1562,7 @@ private fun RenderNoteRow(
|
||||
)
|
||||
}
|
||||
|
||||
is NIP90StatusEvent -> {
|
||||
is DvmStatusEvent -> {
|
||||
RenderNIP90Status(
|
||||
baseNote,
|
||||
accountViewModel,
|
||||
@@ -1640,7 +1640,7 @@ private fun RenderNoteRow(
|
||||
)
|
||||
}
|
||||
|
||||
is FileHeaderEvent -> {
|
||||
is FileMetadataEvent -> {
|
||||
FileHeaderDisplay(baseNote, true, ContentScale.FillWidth, accountViewModel)
|
||||
}
|
||||
|
||||
@@ -1879,7 +1879,7 @@ private fun RenderNoteRow(
|
||||
RenderOldBookmarkList(baseNote, quotesLeft, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is LabeledBookmarkListEvent -> {
|
||||
is BookmarkSetEvent -> {
|
||||
RenderLabeledBookmarkList(baseNote, quotesLeft, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -1923,7 +1923,7 @@ private fun RenderNoteRow(
|
||||
RenderMediaStarterPack(baseNote, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is HashtagListEvent -> {
|
||||
is InterestListEvent -> {
|
||||
RenderHashtagList(baseNote, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@@ -2172,7 +2172,7 @@ fun FirstUserInfoRow(
|
||||
// Zap receipts are signed by the recipient's lightning provider; show the
|
||||
// sender from the embedded zap request instead of the service key.
|
||||
val zapSender =
|
||||
if (baseNote.event is LnZapEvent) {
|
||||
if (baseNote.event is ZapReceiptEvent) {
|
||||
observeZapSender(baseNote, accountViewModel).value
|
||||
} else {
|
||||
null
|
||||
@@ -2411,7 +2411,7 @@ fun RenderAuthorImages(
|
||||
} else {
|
||||
NoteAuthorPicture(baseNote, Size55dp, accountViewModel = accountViewModel, nav = nav)
|
||||
}
|
||||
} else if (noteEvent is LnZapEvent) {
|
||||
} else if (noteEvent is ZapReceiptEvent) {
|
||||
// Zap receipts are signed by the recipient's lightning provider; show the
|
||||
// sender from the embedded zap request instead of the service key, matching
|
||||
// how the thread's master note resolves the author.
|
||||
|
||||
@@ -116,8 +116,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.report.ReportNoteDialog
|
||||
import com.vitorpamplona.quartz.experimental.bounties.bountyBaseReward
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.StarterPackEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.FollowSetEvent
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
|
||||
@@ -149,8 +149,8 @@ val externalLinkForNote = { note: Note ->
|
||||
if (note is AddressableNote) {
|
||||
when {
|
||||
note.event?.bountyBaseReward() != null -> "https://nostrbounties.com/b/${note.toNAddr()}"
|
||||
note.event is PeopleListEvent -> "https://listr.lol/a/${note.toNAddr()}"
|
||||
note.event is FollowListEvent -> "https://following.space/d/${note.address.dTag}?p=${note.address.pubKeyHex}"
|
||||
note.event is FollowSetEvent -> "https://listr.lol/a/${note.toNAddr()}"
|
||||
note.event is StarterPackEvent -> "https://following.space/d/${note.address.dTag}?p=${note.address.pubKeyHex}"
|
||||
else -> njumpLink(note.toNAddr())
|
||||
}
|
||||
} else {
|
||||
|
||||
+2
-2
@@ -95,7 +95,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiListEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -361,7 +361,7 @@ private fun EmojiSelector(
|
||||
accountViewModel.account.emoji.getEmojiPackSelectionAddress(),
|
||||
) { emptyNote ->
|
||||
emptyNote?.let { usersEmojiList ->
|
||||
val collections by observeNoteEventAndMapNotNull(usersEmojiList, accountViewModel) { event: EmojiPackSelectionEvent ->
|
||||
val collections by observeNoteEventAndMapNotNull(usersEmojiList, accountViewModel) { event: EmojiListEvent ->
|
||||
event.emojiPacks().toImmutableList()
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.getFragmentActivity
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -153,22 +153,22 @@ fun UpdateZapAmountContent(
|
||||
val zapTypes =
|
||||
listOf(
|
||||
Triple(
|
||||
LnZapEvent.ZapType.PUBLIC,
|
||||
ZapReceiptEvent.ZapType.PUBLIC,
|
||||
stringRes(id = Res.string.zap_type_public),
|
||||
stringRes(id = Res.string.zap_type_public_explainer),
|
||||
),
|
||||
Triple(
|
||||
LnZapEvent.ZapType.PRIVATE,
|
||||
ZapReceiptEvent.ZapType.PRIVATE,
|
||||
stringRes(id = Res.string.zap_type_private),
|
||||
stringRes(id = Res.string.zap_type_private_explainer),
|
||||
),
|
||||
Triple(
|
||||
LnZapEvent.ZapType.ANONYMOUS,
|
||||
ZapReceiptEvent.ZapType.ANONYMOUS,
|
||||
stringRes(id = Res.string.zap_type_anonymous),
|
||||
stringRes(id = Res.string.zap_type_anonymous_explainer),
|
||||
),
|
||||
Triple(
|
||||
LnZapEvent.ZapType.NONZAP,
|
||||
ZapReceiptEvent.ZapType.NONZAP,
|
||||
stringRes(id = Res.string.zap_type_nonzap),
|
||||
stringRes(id = Res.string.zap_type_nonzap_explainer),
|
||||
),
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodePrivateKeyAsHexOrNull
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodePublicKey
|
||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlinx.coroutines.CancellationException
|
||||
|
||||
@Stable
|
||||
@@ -44,7 +44,7 @@ class UpdateZapAmountViewModel : ViewModel() {
|
||||
var walletConnectRelay by mutableStateOf(TextFieldValue(""))
|
||||
var walletConnectPubkey by mutableStateOf(TextFieldValue(""))
|
||||
var walletConnectSecret by mutableStateOf(TextFieldValue(""))
|
||||
var selectedZapType by mutableStateOf(LnZapEvent.ZapType.PRIVATE)
|
||||
var selectedZapType by mutableStateOf(ZapReceiptEvent.ZapType.PRIVATE)
|
||||
|
||||
// A local UI preference rather than synced account state, but it is edited on
|
||||
// this screen, so it follows this screen's Save/Cancel contract instead of
|
||||
|
||||
@@ -117,7 +117,7 @@ import com.vitorpamplona.amethyst.service.ZapPaymentHandler
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.wallet.OnchainZapSendDialog
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.CancellationException
|
||||
|
||||
@@ -163,35 +163,35 @@ fun ZapCustomDialog(
|
||||
val zapTypes =
|
||||
listOf(
|
||||
Triple(
|
||||
LnZapEvent.ZapType.PUBLIC,
|
||||
ZapReceiptEvent.ZapType.PUBLIC,
|
||||
stringRes(id = Res.string.zap_type_public),
|
||||
stringRes(id = Res.string.zap_type_public_explainer),
|
||||
),
|
||||
Triple(
|
||||
LnZapEvent.ZapType.PRIVATE,
|
||||
ZapReceiptEvent.ZapType.PRIVATE,
|
||||
stringRes(id = Res.string.zap_type_private),
|
||||
stringRes(id = Res.string.zap_type_private_explainer),
|
||||
),
|
||||
Triple(
|
||||
LnZapEvent.ZapType.ANONYMOUS,
|
||||
ZapReceiptEvent.ZapType.ANONYMOUS,
|
||||
stringRes(id = Res.string.zap_type_anonymous),
|
||||
stringRes(id = Res.string.zap_type_anonymous_explainer),
|
||||
),
|
||||
Triple(
|
||||
LnZapEvent.ZapType.NONZAP,
|
||||
ZapReceiptEvent.ZapType.NONZAP,
|
||||
stringRes(id = Res.string.zap_type_nonzap),
|
||||
stringRes(id = Res.string.zap_type_nonzap_explainer),
|
||||
),
|
||||
).filter {
|
||||
!isPrivateTarget || it.first == LnZapEvent.ZapType.PRIVATE || it.first == LnZapEvent.ZapType.NONZAP
|
||||
!isPrivateTarget || it.first == ZapReceiptEvent.ZapType.PRIVATE || it.first == ZapReceiptEvent.ZapType.NONZAP
|
||||
}
|
||||
|
||||
var selectedZapType by
|
||||
remember(accountViewModel, baseNote) {
|
||||
val default = accountViewModel.defaultZapType()
|
||||
mutableStateOf(
|
||||
if (isPrivateTarget && default != LnZapEvent.ZapType.NONZAP) {
|
||||
LnZapEvent.ZapType.PRIVATE
|
||||
if (isPrivateTarget && default != ZapReceiptEvent.ZapType.NONZAP) {
|
||||
ZapReceiptEvent.ZapType.PRIVATE
|
||||
} else {
|
||||
default
|
||||
},
|
||||
@@ -327,15 +327,15 @@ fun ZapCustomDialog(
|
||||
OutlinedTextField(
|
||||
label = {
|
||||
when (selectedZapType) {
|
||||
LnZapEvent.ZapType.PUBLIC, LnZapEvent.ZapType.ANONYMOUS -> {
|
||||
ZapReceiptEvent.ZapType.PUBLIC, ZapReceiptEvent.ZapType.ANONYMOUS -> {
|
||||
Text(text = stringRes(id = Res.string.custom_zaps_add_a_message))
|
||||
}
|
||||
|
||||
LnZapEvent.ZapType.PRIVATE -> {
|
||||
ZapReceiptEvent.ZapType.PRIVATE -> {
|
||||
Text(text = stringRes(id = Res.string.custom_zaps_add_a_message_private))
|
||||
}
|
||||
|
||||
LnZapEvent.ZapType.NONZAP -> {
|
||||
ZapReceiptEvent.ZapType.NONZAP -> {
|
||||
Text(text = stringRes(id = Res.string.custom_zaps_add_a_message_nonzap))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockVitorAccountViewModel
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.ZapPollEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -145,7 +145,7 @@ fun ZapZapPollNotePreview() {
|
||||
)
|
||||
|
||||
val zapVote =
|
||||
LnZapEvent(
|
||||
ZapReceiptEvent(
|
||||
id = "2a17fdcd0e387d1623c7313d7aa2848e18dde8a942cfe8a2d6b686ea5f68f01a",
|
||||
pubKey = "79f00d3f5a19ec806189fcab03c1be4ff81d18ee4f653c88fac41fe03570f432",
|
||||
createdAt = 1729186293,
|
||||
|
||||
@@ -30,8 +30,8 @@ import com.vitorpamplona.amethyst.commons.model.Note
|
||||
import com.vitorpamplona.amethyst.commons.model.User
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.experimental.zapPolls.ZapPollEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -233,9 +233,9 @@ class PollNoteViewModel : ViewModel() {
|
||||
user: User,
|
||||
): Boolean =
|
||||
pollNote!!.zaps.any {
|
||||
val zapEvent = it.value?.event as? LnZapEvent
|
||||
val zapEvent = it.value?.event as? ZapReceiptEvent
|
||||
val privateZapAuthor =
|
||||
(it.key.event as? LnZapRequestEvent)?.let {
|
||||
(it.key.event as? ZapRequestEvent)?.let {
|
||||
account.privateZapsDecryptionCache.cachedPrivateZap(it)
|
||||
}
|
||||
zapEvent?.zappedPollOption() == option &&
|
||||
@@ -244,7 +244,7 @@ class PollNoteViewModel : ViewModel() {
|
||||
|
||||
private fun zappedPollOptionAmount(option: Int): BigDecimal =
|
||||
pollNote?.zaps?.values?.sumOf {
|
||||
val event = it?.event as? LnZapEvent
|
||||
val event = it?.event as? ZapReceiptEvent
|
||||
val zapAmount = event?.amount ?: BigDecimal.ZERO
|
||||
val isValidAmount = isValidInputVoteAmount(event?.amount)
|
||||
|
||||
@@ -258,7 +258,7 @@ class PollNoteViewModel : ViewModel() {
|
||||
|
||||
private fun totalZapped(): BigDecimal =
|
||||
pollNote?.zaps?.values?.sumOf {
|
||||
val zapEvent = (it?.event as? LnZapEvent)
|
||||
val zapEvent = (it?.event as? ZapReceiptEvent)
|
||||
val zapAmount = zapEvent?.amount ?: BigDecimal.ZERO
|
||||
val isValidAmount = isValidInputVoteAmount(zapEvent?.amount)
|
||||
|
||||
|
||||
+3
-3
@@ -27,16 +27,16 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNo
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.aTag.taggedAddresses
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiPackSelectionEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.selection.EmojiListEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@Composable
|
||||
fun WatchAndLoadMyEmojiList(accountViewModel: AccountViewModel) {
|
||||
LoadAddressableNote(
|
||||
EmojiPackSelectionEvent.createAddress(accountViewModel.userProfile().pubkeyHex),
|
||||
EmojiListEvent.createAddress(accountViewModel.userProfile().pubkeyHex),
|
||||
) { emptyNote ->
|
||||
emptyNote?.let { usersEmojiList ->
|
||||
val collections by observeNoteEventAndMapNotNull(usersEmojiList, accountViewModel) { event: EmojiPackSelectionEvent ->
|
||||
val collections by observeNoteEventAndMapNotNull(usersEmojiList, accountViewModel) { event: EmojiListEvent ->
|
||||
event.taggedAddresses().toImmutableList()
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -55,7 +55,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm.AddDMRelayListDialog
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
@@ -88,7 +88,7 @@ fun ObserveRelayListForDMsAndDisplayIfNotFound(
|
||||
@Composable
|
||||
fun ObserveRelayListForDMs(
|
||||
accountViewModel: AccountViewModel,
|
||||
inner: @Composable (relayListEvent: ChatMessageRelayListEvent?) -> Unit,
|
||||
inner: @Composable (relayListEvent: DmRelayListEvent?) -> Unit,
|
||||
) {
|
||||
ObserveRelayListForDMs(
|
||||
pubkey = accountViewModel.account.userProfile().pubkeyHex,
|
||||
@@ -102,13 +102,13 @@ fun ObserveRelayListForDMs(
|
||||
fun ObserveRelayListForDMs(
|
||||
pubkey: HexKey,
|
||||
accountViewModel: AccountViewModel,
|
||||
inner: @Composable (relayListEvent: ChatMessageRelayListEvent?) -> Unit,
|
||||
inner: @Composable (relayListEvent: DmRelayListEvent?) -> Unit,
|
||||
) {
|
||||
LoadAddressableNote(
|
||||
ChatMessageRelayListEvent.createAddress(pubkey),
|
||||
DmRelayListEvent.createAddress(pubkey),
|
||||
) { relayList ->
|
||||
if (relayList != null) {
|
||||
val relayListEvent by observeNoteEvent<ChatMessageRelayListEvent>(relayList, accountViewModel)
|
||||
val relayListEvent by observeNoteEvent<DmRelayListEvent>(relayList, accountViewModel)
|
||||
|
||||
inner(relayListEvent)
|
||||
}
|
||||
|
||||
+5
-5
@@ -80,7 +80,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.experimental.music.track.MusicTrackEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -222,7 +222,7 @@ fun noteActionSections(
|
||||
// nostr source pre-tagged (`a` for an addressable article, else `e`) plus the author,
|
||||
// and the passage left for the user to type or paste. Prose kinds only, and never a
|
||||
// private rumor (a public highlight would e-tag the unsigned rumor onto relays).
|
||||
if (!isPrivateRumor && (note.event is TextNoteEvent || note.event is LongTextNoteEvent)) {
|
||||
if (!isPrivateRumor && (note.event is TextNoteEvent || note.event is LongFormContentEvent)) {
|
||||
add(
|
||||
NoteAction(MaterialSymbols.FormatQuote, stringRes(Res.string.highlight_action)) {
|
||||
val author = note.author?.pubkeyHex
|
||||
@@ -256,7 +256,7 @@ fun noteActionSections(
|
||||
onClick = handlers.onEditPost,
|
||||
),
|
||||
)
|
||||
} else if (note.event is LongTextNoteEvent && state.isLoggedUser) {
|
||||
} else if (note.event is LongFormContentEvent && state.isLoggedUser) {
|
||||
add(
|
||||
NoteAction(MaterialSymbols.Edit, stringRes(Res.string.edit_article)) {
|
||||
nav.nav { Route.NewLongFormPost(version = note.idHex) }
|
||||
@@ -343,10 +343,10 @@ fun noteActionSections(
|
||||
}
|
||||
|
||||
else -> {
|
||||
val noteBookmarkType = if (note.event is LongTextNoteEvent) stringRes(Res.string.article) else stringRes(Res.string.post)
|
||||
val noteBookmarkType = if (note.event is LongFormContentEvent) stringRes(Res.string.article) else stringRes(Res.string.post)
|
||||
add(
|
||||
NoteAction(MaterialSymbols.BookmarkAdd, stringRes(Res.string.manage_bookmark_label, noteBookmarkType)) {
|
||||
if (note.event is LongTextNoteEvent) {
|
||||
if (note.event is LongFormContentEvent) {
|
||||
nav.nav(Route.ArticleBookmarkManagement((note as AddressableNote).address))
|
||||
} else {
|
||||
nav.nav(Route.PostBookmarkManagement(note.idHex))
|
||||
|
||||
+5
-5
@@ -109,7 +109,7 @@ import com.vitorpamplona.quartz.nip36SensitiveContent.contentWarningReason
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitive
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip40Expiration.expiration
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.zapSplits
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiser
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount
|
||||
@@ -352,7 +352,7 @@ open class CommentPostViewModel :
|
||||
this.externalIdentity = (post.event as? CommentEvent)?.scope()
|
||||
mutedNotifies = emptySet()
|
||||
notifyProvenance = emptyMap()
|
||||
(post.event as? LnZapEvent)?.let { zap ->
|
||||
(post.event as? ZapReceiptEvent)?.let { zap ->
|
||||
notifying = listOfNotNull(zapSenderToNotify(zap))
|
||||
}
|
||||
observeCommunityRules(post)
|
||||
@@ -366,7 +366,7 @@ open class CommentPostViewModel :
|
||||
* by an ephemeral key: skip those — tagging the throwaway key is useless, and
|
||||
* tagging the decrypted sender would publicly expose a private zapper.
|
||||
*/
|
||||
private fun zapSenderToNotify(zapEvent: LnZapEvent): User? {
|
||||
private fun zapSenderToNotify(zapEvent: ZapReceiptEvent): User? {
|
||||
val request = zapEvent.zapRequest ?: return null
|
||||
if (request.hasAnonTag()) return null
|
||||
if (request.pubKey == account.signer.pubKey) return null
|
||||
@@ -554,7 +554,7 @@ open class CommentPostViewModel :
|
||||
// Replies to zaps notify the zap sender through a plain p tag (the receipt's
|
||||
// author keys above are the lightning provider). The sender chip always comes
|
||||
// back; a missing p tag in the draft means the user muted their bell.
|
||||
(replyingTo?.event as? LnZapEvent)?.let { zap ->
|
||||
(replyingTo?.event as? ZapReceiptEvent)?.let { zap ->
|
||||
zapSenderToNotify(zap)?.let { sender ->
|
||||
notifying = ((notifying ?: emptyList()) + sender).distinct()
|
||||
if (!draftEvent.tags.mapNotNull(PTag::parseKey).contains(sender.pubkeyHex)) {
|
||||
@@ -726,7 +726,7 @@ open class CommentPostViewModel :
|
||||
null
|
||||
}
|
||||
}
|
||||
} else if (replyingToEvent is LnZapEvent) {
|
||||
} else if (replyingToEvent is ZapReceiptEvent) {
|
||||
val sender = zapSenderToNotify(replyingToEvent)
|
||||
// The sender's chip stays in the list; a muted bell means
|
||||
// the user doesn't want to ping them, so don't tag them.
|
||||
|
||||
@@ -63,7 +63,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.gallery.GalleryThum
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.gallery.UrlImageView
|
||||
import com.vitorpamplona.quartz.experimental.profileGallery.ProfileGalleryEntryEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningTag
|
||||
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.clip.LiveActivitiesClipEvent
|
||||
@@ -278,7 +278,7 @@ private fun secondaryLineFor(
|
||||
return when {
|
||||
event is PictureEvent -> stringRes(Res.string.share_as_qr_kind_picture)
|
||||
event is VideoEvent -> stringRes(Res.string.kind_video)
|
||||
event is LongTextNoteEvent -> stringRes(Res.string.article)
|
||||
event is LongFormContentEvent -> stringRes(Res.string.article)
|
||||
hasContentImage -> stringRes(Res.string.share_as_qr_kind_picture)
|
||||
else -> ""
|
||||
}
|
||||
@@ -293,7 +293,7 @@ internal fun secondaryBodyTextFor(
|
||||
// Gated: never surface the note's own title, content or alt text, only the kind label above.
|
||||
if (isGated) return null
|
||||
|
||||
if (event is LongTextNoteEvent) {
|
||||
if (event is LongFormContentEvent) {
|
||||
val title = event.title()
|
||||
if (!title.isNullOrBlank()) return title
|
||||
}
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.commons.model.Note
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.CalendarCollectionCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
|
||||
/**
|
||||
* Entry for a NIP-52 calendar collection: decodes the [Note] and renders the shared commons
|
||||
@@ -38,7 +38,7 @@ fun RenderCalendarCollectionEvent(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val event = note.event as? CalendarEvent ?: return
|
||||
val event = note.event as? CalendarCollectionEvent ?: return
|
||||
|
||||
CalendarCollectionCard(event)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.FileMetadataEvent
|
||||
|
||||
@Composable
|
||||
fun FileHeaderDisplay(
|
||||
@@ -44,7 +44,7 @@ fun FileHeaderDisplay(
|
||||
contentScale: ContentScale,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
val event = (note.event as? FileHeaderEvent) ?: return
|
||||
val event = (note.event as? FileMetadataEvent) ?: return
|
||||
val fullUrl = event.url() ?: return
|
||||
val mimeType = remember(note) { event.mimeType() }
|
||||
val content = remember(note) { event.toMediaContent(note, fullUrl, mimeType) }
|
||||
@@ -72,7 +72,7 @@ fun FileHeaderDisplay(
|
||||
* video event the kind itself asserts nothing about how to render the payload. A null here means
|
||||
* the file belongs in [FileHeaderAttachmentCard] rather than being pushed into the video player.
|
||||
*/
|
||||
internal fun FileHeaderEvent.toMediaContent(
|
||||
internal fun FileMetadataEvent.toMediaContent(
|
||||
note: Note,
|
||||
url: String,
|
||||
mimeType: String?,
|
||||
@@ -129,7 +129,7 @@ internal fun FileHeaderEvent.toMediaContent(
|
||||
/** The link card a kind-1063 header falls back to when [toMediaContent] returns null. */
|
||||
@Composable
|
||||
internal fun FileHeaderAttachmentCard(
|
||||
event: FileHeaderEvent,
|
||||
event: FileMetadataEvent,
|
||||
url: String,
|
||||
mimeType: String?,
|
||||
) {
|
||||
@@ -145,4 +145,4 @@ internal fun FileHeaderAttachmentCard(
|
||||
}
|
||||
|
||||
/** The human-facing name of the file: NIP-94 `content` when present, else the `alt` tag. */
|
||||
private fun FileHeaderEvent.fileDescription(): String? = content.ifEmpty { null } ?: alt()
|
||||
private fun FileMetadataEvent.fileDescription(): String? = content.ifEmpty { null } ?: alt()
|
||||
|
||||
@@ -66,7 +66,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip51FollowSets.FollowSetCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.StarterPackEvent
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@@ -79,7 +79,7 @@ fun DisplayFollowList(
|
||||
nav: INav,
|
||||
) {
|
||||
val card =
|
||||
observeNoteEventAndMap(baseNote, accountViewModel) { event: FollowListEvent? ->
|
||||
observeNoteEventAndMap(baseNote, accountViewModel) { event: StarterPackEvent? ->
|
||||
if (event == null) {
|
||||
FollowSetCard(
|
||||
name = "",
|
||||
@@ -190,7 +190,7 @@ fun RenderFollowSetThumbPreview() {
|
||||
val accountViewModel = mockAccountViewModel()
|
||||
|
||||
val followCard =
|
||||
FollowListEvent(
|
||||
StarterPackEvent(
|
||||
id = "eca31634fce7c9068b56fa8db9f387da70bdcceb3986a77ca1a9844f3128eb5f",
|
||||
pubKey = "3c39a7b53dec9ac85acf08b267637a9841e6df7b7b0f5e2ac56a8cf107de37da",
|
||||
createdAt = 1761736286,
|
||||
|
||||
@@ -60,7 +60,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground
|
||||
import com.vitorpamplona.amethyst.ui.note.showAmount
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip75ZapGoals.GoalEvent
|
||||
import com.vitorpamplona.quartz.nip75ZapGoals.ZapGoalEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import java.math.BigDecimal
|
||||
import kotlin.math.roundToInt
|
||||
@@ -71,14 +71,14 @@ fun RenderGoal(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? GoalEvent ?: return
|
||||
val noteEvent = note.event as? ZapGoalEvent ?: return
|
||||
|
||||
GoalHeader(noteEvent, note, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GoalHeader(
|
||||
noteEvent: GoalEvent,
|
||||
noteEvent: ZapGoalEvent,
|
||||
note: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
|
||||
@@ -65,7 +65,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.TimeAgo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
private const val WORDS_PER_MINUTE = 225
|
||||
@@ -77,7 +77,7 @@ fun RenderLongFormContent(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? LongTextNoteEvent ?: return
|
||||
val noteEvent = note.event as? LongFormContentEvent ?: return
|
||||
|
||||
LongFormHeader(noteEvent, note, accountViewModel)
|
||||
}
|
||||
@@ -85,7 +85,7 @@ fun RenderLongFormContent(
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun LongFormHeader(
|
||||
noteEvent: LongTextNoteEvent,
|
||||
noteEvent: LongFormContentEvent,
|
||||
note: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.DvmContentDiscoveryResponseEvent
|
||||
|
||||
@Composable
|
||||
fun RenderNIP90ContentDiscoveryResponse(
|
||||
@@ -47,7 +47,7 @@ fun RenderNIP90ContentDiscoveryResponse(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? NIP90ContentDiscoveryResponseEvent ?: return
|
||||
val noteEvent = note.event as? DvmContentDiscoveryResponseEvent ?: return
|
||||
val callbackUri = remember(note) { note.toNostrUri() }
|
||||
|
||||
SensitivityWarning(
|
||||
|
||||
@@ -25,7 +25,7 @@ import androidx.compose.runtime.Composable
|
||||
import com.vitorpamplona.amethyst.commons.model.Note
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.status.DvmStatusEvent
|
||||
|
||||
@Composable
|
||||
fun RenderNIP90Status(
|
||||
@@ -33,7 +33,7 @@ fun RenderNIP90Status(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? NIP90StatusEvent ?: return
|
||||
val noteEvent = note.event as? DvmStatusEvent ?: return
|
||||
|
||||
Text(text = noteEvent.content)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.getGradient
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.FollowSetEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@@ -68,7 +68,7 @@ fun DisplayPeopleList(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = baseNote.event as? PeopleListEvent ?: return
|
||||
val noteEvent = baseNote.event as? FollowSetEvent ?: return
|
||||
|
||||
var members by remember { mutableStateOf<ImmutableList<User>>(persistentListOf()) }
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.header.ChatroomHeader
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
|
||||
@@ -67,7 +67,7 @@ fun RenderPrivateMessage(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? PrivateDmEvent ?: return
|
||||
val noteEvent = note.event as? EncryptedDmEvent ?: return
|
||||
|
||||
val userRoom by
|
||||
remember(note) {
|
||||
|
||||
@@ -80,8 +80,8 @@ import com.vitorpamplona.quartz.experimental.publications.PublicationContentEven
|
||||
import com.vitorpamplona.quartz.experimental.publications.PublicationIndexEvent
|
||||
import com.vitorpamplona.quartz.experimental.publications.PublicationSectionRef
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiArticleEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
// A 2:3 portrait cover — a book jacket, which is what NKBIP-01's default `book` type is. The
|
||||
@@ -355,8 +355,8 @@ private fun ObservedSectionRow(
|
||||
// list long-form, wiki and spec events as sections too.
|
||||
is PublicationIndexEvent -> event.titleOrIdentifier()
|
||||
is PublicationContentEvent -> event.titleOrIdentifier()
|
||||
is LongTextNoteEvent -> event.title()
|
||||
is WikiNoteEvent -> event.title()
|
||||
is LongFormContentEvent -> event.title()
|
||||
is WikiArticleEvent -> event.title()
|
||||
// A bookshelf directory lists whatever it likes, including another directory, so the
|
||||
// row has to name the library kinds too -- otherwise a nested entry falls through to
|
||||
// the section placeholder and reads "Untitled section", which it is not.
|
||||
|
||||
+3
-3
@@ -67,7 +67,7 @@ import com.vitorpamplona.quartz.experimental.publications.PublicationIndexEvent
|
||||
import com.vitorpamplona.quartz.experimental.publications.PublicationSectionRef
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiArticleEvent
|
||||
|
||||
/**
|
||||
* Renders a kind-30041 NKBIP-01 publication section — a chapter, zettel or episode.
|
||||
@@ -331,12 +331,12 @@ private fun wikilinkResolver(event: PublicationContentEvent): (String) -> String
|
||||
link == null -> null
|
||||
|
||||
link.eventId != null ->
|
||||
"nostr:" + NEvent.create(link.eventId!!, link.pubKey, WikiNoteEvent.KIND, link.relay)
|
||||
"nostr:" + NEvent.create(link.eventId!!, link.pubKey, WikiArticleEvent.KIND, link.relay)
|
||||
|
||||
link.pubKey != null ->
|
||||
"nostr:" +
|
||||
NAddress.create(
|
||||
WikiNoteEvent.KIND,
|
||||
WikiArticleEvent.KIND,
|
||||
link.pubKey!!,
|
||||
PublicationContentEvent.normalizeWikilink(link.target),
|
||||
link.relay,
|
||||
|
||||
@@ -70,7 +70,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstTagValueFor
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relaySets.RelaySetEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -158,7 +158,7 @@ fun DisplayDMRelayList(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = baseNote.event as? ChatMessageRelayListEvent ?: return
|
||||
val noteEvent = baseNote.event as? DmRelayListEvent ?: return
|
||||
|
||||
val relays =
|
||||
remember(noteEvent) {
|
||||
|
||||
@@ -96,12 +96,11 @@ import com.vitorpamplona.amethyst.ui.note.elements.MoreOptionsButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.application.SoftwareApplicationEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.asset.SoftwareAssetEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.SoftwareReleaseEvent
|
||||
import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.asSoftwareRelease
|
||||
import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.isNip82SoftwareRelease
|
||||
import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.tags.AppIdTag
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag
|
||||
import com.vitorpamplona.quartz.nip51Lists.releaseArtifactSet.ReleaseArtifactSetEvent
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -209,7 +208,7 @@ fun RenderSoftwareApplication(
|
||||
}
|
||||
|
||||
/**
|
||||
* Latest NIP-82 [SoftwareReleaseEvent] version for [app], kept live.
|
||||
* Latest NIP-82 [ReleaseArtifactSetEvent] version for [app], kept live.
|
||||
*
|
||||
* Releases (kind 30063) are separate events that point back to the app via an
|
||||
* `i` tag rather than an `a` tag, so they are never indexed as replies to the
|
||||
@@ -230,7 +229,7 @@ fun produceLatestReleaseVersion(app: SoftwareApplicationEvent): State<String?> {
|
||||
remember(app.pubKey, app.id) {
|
||||
val filter =
|
||||
Filter(
|
||||
kinds = listOf(SoftwareReleaseEvent.KIND),
|
||||
kinds = listOf(ReleaseArtifactSetEvent.KIND),
|
||||
authors = listOf(app.pubKey),
|
||||
tags = mapOf(AppIdTag.TAG_NAME to listOf(app.appId())),
|
||||
)
|
||||
@@ -243,13 +242,13 @@ fun produceLatestReleaseVersion(app: SoftwareApplicationEvent): State<String?> {
|
||||
return flow.collectAsStateWithLifecycle(initialValue = null)
|
||||
}
|
||||
|
||||
fun findLatestNip82Release(app: SoftwareApplicationEvent): SoftwareReleaseEvent? = latestNip82Release(nip82ReleaseNotesFor(app), app)
|
||||
fun findLatestNip82Release(app: SoftwareApplicationEvent): ReleaseArtifactSetEvent? = latestNip82Release(nip82ReleaseNotesFor(app), app)
|
||||
|
||||
/** Picks the newest NIP-82 release for [app] out of an already-narrowed [notes] collection. */
|
||||
private fun latestNip82Release(
|
||||
notes: Collection<Note>,
|
||||
app: SoftwareApplicationEvent,
|
||||
): SoftwareReleaseEvent? {
|
||||
): ReleaseArtifactSetEvent? {
|
||||
val prefix = "${app.dTag()}@"
|
||||
return notes
|
||||
.mapNotNull { it.asNip82ReleaseFor(prefix) }
|
||||
@@ -259,25 +258,22 @@ private fun latestNip82Release(
|
||||
/** kind-30063 addressables authored by [app] whose `d` tag is `<app-id>@<version>`. */
|
||||
private fun nip82ReleaseNotesFor(app: SoftwareApplicationEvent): Set<Note> {
|
||||
val prefix = "${app.dTag()}@"
|
||||
return LocalCache.addressables.filterIntoSet(SoftwareReleaseEvent.KIND, app.pubKey) { _, addr ->
|
||||
return LocalCache.addressables.filterIntoSet(ReleaseArtifactSetEvent.KIND, app.pubKey) { _, addr ->
|
||||
val ev = addr.event ?: return@filterIntoSet false
|
||||
ev.isNip82SoftwareRelease() && ev.dTag().startsWith(prefix)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-reads this note as the NIP-82 release for [prefix] (`<app-id>@`). kind 30063
|
||||
* collides with NIP-51 `ReleaseArtifactSetEvent`, which is what `EventFactory`
|
||||
* builds, so we re-parse matching tag arrays as the NIP-82 form.
|
||||
* This note as the NIP-82 release for [prefix] (`<app-id>@`). kind 30063 is shared
|
||||
* with NIP-51 release artifact sets, so only events carrying the NIP-82 tags qualify.
|
||||
*/
|
||||
private fun Note.asNip82ReleaseFor(prefix: String): SoftwareReleaseEvent? =
|
||||
when (val ev = event) {
|
||||
null -> null
|
||||
is SoftwareReleaseEvent -> ev.takeIf { it.dTag().startsWith(prefix) }
|
||||
else -> if (ev.isNip82SoftwareRelease() && ev.dTag().startsWith(prefix)) ev.asSoftwareRelease() else null
|
||||
}
|
||||
private fun Note.asNip82ReleaseFor(prefix: String): ReleaseArtifactSetEvent? {
|
||||
val ev = event as? ReleaseArtifactSetEvent ?: return null
|
||||
return ev.takeIf { it.isNip82SoftwareRelease() && it.dTag().startsWith(prefix) }
|
||||
}
|
||||
|
||||
fun findAllNip82Releases(app: SoftwareApplicationEvent): List<SoftwareReleaseEvent> {
|
||||
fun findAllNip82Releases(app: SoftwareApplicationEvent): List<ReleaseArtifactSetEvent> {
|
||||
val prefix = "${app.dTag()}@"
|
||||
return nip82ReleaseNotesFor(app)
|
||||
.mapNotNull { it.asNip82ReleaseFor(prefix) }
|
||||
@@ -486,25 +482,17 @@ fun RenderSoftwareRelease(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
// kind 30063 is shared between NIP-51 ReleaseArtifactSetEvent and NIP-82 SoftwareReleaseEvent;
|
||||
// EventFactory always returns the NIP-51 class, so we re-parse the same tag array as the
|
||||
// NIP-82 form when the tag signature matches.
|
||||
val rawEvent = note.event ?: return
|
||||
val event: SoftwareReleaseEvent =
|
||||
if (rawEvent is SoftwareReleaseEvent) {
|
||||
rawEvent
|
||||
} else if (rawEvent.isNip82SoftwareRelease()) {
|
||||
rawEvent.asSoftwareRelease()
|
||||
} else {
|
||||
return
|
||||
}
|
||||
// kind 30063 is shared between NIP-51 release artifact sets and NIP-82 software
|
||||
// releases; only render the NIP-82 form here.
|
||||
val event = note.event as? ReleaseArtifactSetEvent ?: return
|
||||
if (!event.isNip82SoftwareRelease()) return
|
||||
|
||||
RenderSoftwareReleaseBody(event = event, accountViewModel = accountViewModel, nav = nav)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RenderSoftwareReleaseBody(
|
||||
event: SoftwareReleaseEvent,
|
||||
event: ReleaseArtifactSetEvent,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
showAppId: Boolean = true,
|
||||
|
||||
@@ -60,7 +60,7 @@ import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip14Subject.subject
|
||||
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
|
||||
enum class ReplyRenderType {
|
||||
FULL,
|
||||
@@ -129,7 +129,7 @@ fun RenderTextEvent(
|
||||
// Zap receipts are signed by the recipient's lightning provider;
|
||||
// label the reply with the zap sender instead of the service key.
|
||||
val zapSender =
|
||||
if (parentNote.event is LnZapEvent) {
|
||||
if (parentNote.event is ZapReceiptEvent) {
|
||||
observeZapSender(parentNote, accountViewModel).value
|
||||
} else {
|
||||
null
|
||||
|
||||
@@ -50,7 +50,7 @@ import com.vitorpamplona.amethyst.ui.components.MyAsyncImage
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiArticleEvent
|
||||
|
||||
@Composable
|
||||
fun RenderWikiContent(
|
||||
@@ -58,14 +58,14 @@ fun RenderWikiContent(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = note.event as? WikiNoteEvent ?: return
|
||||
val noteEvent = note.event as? WikiArticleEvent ?: return
|
||||
|
||||
WikiNoteHeader(noteEvent, note, accountViewModel, nav)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WikiNoteHeader(
|
||||
noteEvent: WikiNoteEvent,
|
||||
noteEvent: WikiArticleEvent,
|
||||
note: Note,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
|
||||
+3
-3
@@ -55,9 +55,9 @@ import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiArticleEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiMergeAcceptanceEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiMergeRequestEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent
|
||||
import com.vitorpamplona.quartz.nip54Wiki.WikiRedirectEvent
|
||||
|
||||
/**
|
||||
@@ -215,7 +215,7 @@ private fun WikiArticleRow(
|
||||
) {
|
||||
LoadAddressableNote(address) { articleNote ->
|
||||
if (articleNote != null) {
|
||||
val article by observeNoteEvent<WikiNoteEvent>(articleNote, accountViewModel)
|
||||
val article by observeNoteEvent<WikiArticleEvent>(articleNote, accountViewModel)
|
||||
|
||||
WikiRow(
|
||||
// The coordinate's own identifier is a readable slug, so it stands in until the
|
||||
@@ -240,7 +240,7 @@ private fun WikiVersionRow(
|
||||
) {
|
||||
LoadNote(eventId) { versionNote ->
|
||||
if (versionNote != null) {
|
||||
val article by observeNoteEvent<WikiNoteEvent>(versionNote, accountViewModel)
|
||||
val article by observeNoteEvent<WikiArticleEvent>(versionNote, accountViewModel)
|
||||
|
||||
WikiRow(
|
||||
title = article?.title() ?: eventId.take(8),
|
||||
|
||||
@@ -64,7 +64,7 @@ import com.vitorpamplona.amethyst.ui.note.UserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.ZapAmountCommentNotification
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -104,7 +104,7 @@ fun RenderLnZap(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val zapEvent = note.event as? LnZapEvent ?: return
|
||||
val zapEvent = note.event as? ZapReceiptEvent ?: return
|
||||
|
||||
val card by parseAuthorCommentAndAmount(note, accountViewModel)
|
||||
|
||||
|
||||
+2
-2
@@ -38,7 +38,7 @@ import com.vitorpamplona.quartz.nip51Lists.articleCurationSet.ArticleCurationSet
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.OldBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.LabeledBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.labeledBookmarkList.BookmarkSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.pictureCurationSet.PictureCurationSetEvent
|
||||
|
||||
/** NIP-51 kind 10003: the user's bookmarks — notes, articles, hashtags and links. */
|
||||
@@ -108,7 +108,7 @@ fun RenderLabeledBookmarkList(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = baseNote.event as? LabeledBookmarkListEvent ?: return
|
||||
val noteEvent = baseNote.event as? BookmarkSetEvent ?: return
|
||||
|
||||
val public = remember(noteEvent) { noteEvent.publicBookmarks() }
|
||||
val private by loadPrivateItems(noteEvent, accountViewModel) { noteEvent.privateBookmarks(it) }
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag
|
||||
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.interestSet.InterestSetEvent
|
||||
|
||||
/** NIP-51 kind 10015: the hashtags this user follows. */
|
||||
@@ -47,10 +47,10 @@ fun RenderHashtagList(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val noteEvent = baseNote.event as? HashtagListEvent ?: return
|
||||
val noteEvent = baseNote.event as? InterestListEvent ?: return
|
||||
|
||||
val public = remember(noteEvent) { noteEvent.publicHashtags() }
|
||||
// HashtagListEvent exposes no private accessor of its own, but it is a PrivateTagArrayEvent
|
||||
// InterestListEvent exposes no private accessor of its own, but it is a PrivateTagArrayEvent
|
||||
// like the rest, so its private half is read the same way InterestSetEvent reads its own.
|
||||
val private by loadPrivateItems(noteEvent, accountViewModel) { signer ->
|
||||
noteEvent.privateTags(signer)?.mapNotNull(HashtagTag::parse)
|
||||
|
||||
@@ -43,9 +43,9 @@ import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.followList.StarterPackEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.interestSet.InterestSetEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.FollowSetEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
@@ -594,9 +594,9 @@ class PeopleListName(
|
||||
NoteBackedName {
|
||||
override fun name(): String {
|
||||
val noteEvent = note.event
|
||||
return if (noteEvent is PeopleListEvent) {
|
||||
return if (noteEvent is FollowSetEvent) {
|
||||
noteEvent.titleOrName() ?: note.dTag()
|
||||
} else if (noteEvent is FollowListEvent) {
|
||||
} else if (noteEvent is StarterPackEvent) {
|
||||
noteEvent.title() ?: note.dTag()
|
||||
} else {
|
||||
note.dTag()
|
||||
|
||||
+34
-34
@@ -172,7 +172,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.PubKeyReferenceTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.EmptyOtsResolverBuilder
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip05DnsIdentifiers.EmptyNip05Client
|
||||
import com.vitorpamplona.quartz.nip05DnsIdentifiers.INip05Client
|
||||
import com.vitorpamplona.quartz.nip05DnsIdentifiers.Nip05Client
|
||||
@@ -202,16 +202,16 @@ import com.vitorpamplona.quartz.nip51Lists.PinListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.OldBookmarkListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.validate.LnurlForm
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip60Cashu.token.CashuToken
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.DvmContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip92IMeta.imeta
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.podcasts.PodcastBoostagram
|
||||
@@ -725,7 +725,7 @@ class AccountViewModel(
|
||||
val isHiddenAuthor = note.author?.let { account.isHidden(it) } == true
|
||||
|
||||
val noteEvent = note.event
|
||||
val isDecryptedPostHidden = if (noteEvent is PrivateDmEvent) account.isDecryptedContentHidden(noteEvent) else false
|
||||
val isDecryptedPostHidden = if (noteEvent is EncryptedDmEvent) account.isDecryptedContentHidden(noteEvent) else false
|
||||
|
||||
return if (isPostHidden || isDecryptedPostHidden) {
|
||||
// Spam + Blocked Users + Hidden Words + Sensitive Content
|
||||
@@ -924,14 +924,14 @@ class AccountViewModel(
|
||||
it.request.event
|
||||
?.content
|
||||
?.ifBlank { null },
|
||||
showAmountInteger((it.response.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.response.event as? ZapReceiptEvent)?.amount),
|
||||
it.response,
|
||||
)
|
||||
}.toMutableMap()
|
||||
|
||||
val results =
|
||||
mapNotNullAsync(
|
||||
zaps.filter { (it.request.event as? LnZapRequestEvent)?.isPrivateZap() == true },
|
||||
zaps.filter { (it.request.event as? ZapRequestEvent)?.isPrivateZap() == true },
|
||||
) { next ->
|
||||
val info = innerDecryptAmountMessage(next.request, next.response)
|
||||
if (info != null) {
|
||||
@@ -950,14 +950,14 @@ class AccountViewModel(
|
||||
fun cachedDecryptAmountMessageInGroup(zapNotes: List<CombinedZap>): ImmutableList<ZapAmountCommentNotification> =
|
||||
zapNotes
|
||||
.map {
|
||||
val request = it.request.event as? LnZapRequestEvent
|
||||
val request = it.request.event as? ZapRequestEvent
|
||||
if (request?.isPrivateZap() == true) {
|
||||
val cachedPrivateRequest = account.privateZapsDecryptionCache.cachedPrivateZap(request)
|
||||
if (cachedPrivateRequest != null) {
|
||||
ZapAmountCommentNotification(
|
||||
LocalCache.getUserIfExists(cachedPrivateRequest.pubKey) ?: it.request.author,
|
||||
cachedPrivateRequest.content.ifBlank { null },
|
||||
showAmountInteger((it.response.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.response.event as? ZapReceiptEvent)?.amount),
|
||||
it.response,
|
||||
)
|
||||
} else {
|
||||
@@ -966,7 +966,7 @@ class AccountViewModel(
|
||||
it.request.event
|
||||
?.content
|
||||
?.ifBlank { null },
|
||||
showAmountInteger((it.response.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.response.event as? ZapReceiptEvent)?.amount),
|
||||
it.response,
|
||||
)
|
||||
}
|
||||
@@ -976,7 +976,7 @@ class AccountViewModel(
|
||||
it.request.event
|
||||
?.content
|
||||
?.ifBlank { null },
|
||||
showAmountInteger((it.response.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.response.event as? ZapReceiptEvent)?.amount),
|
||||
it.response,
|
||||
)
|
||||
}
|
||||
@@ -987,14 +987,14 @@ class AccountViewModel(
|
||||
|
||||
return myList
|
||||
.map {
|
||||
val request = it.first.event as? LnZapRequestEvent
|
||||
val request = it.first.event as? ZapRequestEvent
|
||||
if (request?.isPrivateZap() == true) {
|
||||
val cachedPrivateRequest = account.privateZapsDecryptionCache.cachedPrivateZap(request)
|
||||
if (cachedPrivateRequest != null) {
|
||||
ZapAmountCommentNotification(
|
||||
LocalCache.getUserIfExists(cachedPrivateRequest.pubKey) ?: it.first.author,
|
||||
cachedPrivateRequest.content.ifBlank { null },
|
||||
showAmountInteger((it.second?.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.second?.event as? ZapReceiptEvent)?.amount),
|
||||
it.second,
|
||||
)
|
||||
} else {
|
||||
@@ -1003,7 +1003,7 @@ class AccountViewModel(
|
||||
it.first.event
|
||||
?.content
|
||||
?.ifBlank { null },
|
||||
showAmountInteger((it.second?.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.second?.event as? ZapReceiptEvent)?.amount),
|
||||
it.second,
|
||||
)
|
||||
}
|
||||
@@ -1013,7 +1013,7 @@ class AccountViewModel(
|
||||
it.first.event
|
||||
?.content
|
||||
?.ifBlank { null },
|
||||
showAmountInteger((it.second?.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.second?.event as? ZapReceiptEvent)?.amount),
|
||||
it.second,
|
||||
)
|
||||
}
|
||||
@@ -1036,7 +1036,7 @@ class AccountViewModel(
|
||||
it.first.event
|
||||
?.content
|
||||
?.ifBlank { null },
|
||||
showAmountInteger((it.second?.event as? LnZapEvent)?.amount),
|
||||
showAmountInteger((it.second?.event as? ZapReceiptEvent)?.amount),
|
||||
it.second,
|
||||
)
|
||||
}.toMutableMap()
|
||||
@@ -1073,7 +1073,7 @@ class AccountViewModel(
|
||||
}
|
||||
|
||||
suspend fun innerDecryptAmountMessage(zapNote: Note): ZapAmountCommentNotification? {
|
||||
val zapEvent = zapNote.event as? LnZapEvent ?: return null
|
||||
val zapEvent = zapNote.event as? ZapReceiptEvent ?: return null
|
||||
val zapRequest = zapEvent.zapRequest ?: return null
|
||||
|
||||
return innerDecryptAmountMessage(zapRequest, zapEvent)?.copy(zapNote = zapNote)
|
||||
@@ -1083,14 +1083,14 @@ class AccountViewModel(
|
||||
zapRequest: Note,
|
||||
zapEvent: Note,
|
||||
): ZapAmountCommentNotification? {
|
||||
val zapEvent = zapEvent.event as? LnZapEvent ?: return null
|
||||
val zapRequest = zapRequest.event as? LnZapRequestEvent ?: return null
|
||||
val zapEvent = zapEvent.event as? ZapReceiptEvent ?: return null
|
||||
val zapRequest = zapRequest.event as? ZapRequestEvent ?: return null
|
||||
return innerDecryptAmountMessage(zapRequest, zapEvent)
|
||||
}
|
||||
|
||||
suspend fun innerDecryptAmountMessage(
|
||||
zapRequestEvent: LnZapRequestEvent,
|
||||
zapEvent: LnZapEvent,
|
||||
zapRequestEvent: ZapRequestEvent,
|
||||
zapEvent: ZapReceiptEvent,
|
||||
): ZapAmountCommentNotification? {
|
||||
val amount = showAmountInteger(zapEvent.amount)
|
||||
return if (zapRequestEvent.isPrivateZap()) {
|
||||
@@ -1148,7 +1148,7 @@ class AccountViewModel(
|
||||
onError: (String, String, User?) -> Unit,
|
||||
onProgress: (percent: Float) -> Unit,
|
||||
onPayViaIntent: (ImmutableList<ZapPaymentHandler.Payable>) -> Unit,
|
||||
zapType: LnZapEvent.ZapType? = null,
|
||||
zapType: ZapReceiptEvent.ZapType? = null,
|
||||
) = launchSigner {
|
||||
// A podcast note (episode or show) can carry a Podcasting-2.0 value-for-value block. When it
|
||||
// does, "zapping" it means paying that split — lnaddress recipients go out as real zaps (with
|
||||
@@ -1177,8 +1177,8 @@ class AccountViewModel(
|
||||
// comment stay encrypted. NONZAP is kept: paying without a zap
|
||||
// request produces no receipt at all, which is even more private.
|
||||
val effectiveType =
|
||||
if (note.isPrivateRumor() && requestedType != LnZapEvent.ZapType.NONZAP) {
|
||||
LnZapEvent.ZapType.PRIVATE
|
||||
if (note.isPrivateRumor() && requestedType != ZapReceiptEvent.ZapType.NONZAP) {
|
||||
ZapReceiptEvent.ZapType.PRIVATE
|
||||
} else {
|
||||
requestedType
|
||||
}
|
||||
@@ -1299,7 +1299,7 @@ class AccountViewModel(
|
||||
zappedNote = zappedNote,
|
||||
context = context,
|
||||
asZap = !streaming,
|
||||
zapType = LnZapEvent.ZapType.PUBLIC,
|
||||
zapType = ZapReceiptEvent.ZapType.PUBLIC,
|
||||
okHttpClient = httpClientBuilder::okHttpClientForMoney,
|
||||
onError = { title, message ->
|
||||
if (!streaming) toastManager.toast(title, message)
|
||||
@@ -1463,7 +1463,7 @@ class AccountViewModel(
|
||||
|
||||
fun follows(user: User): Note = LocalCache.getOrCreateAddressableNote(ContactListEvent.createAddress(user.pubkeyHex))
|
||||
|
||||
fun hashtagFollows(user: User): Note = LocalCache.getOrCreateAddressableNote(HashtagListEvent.createAddress(user.pubkeyHex))
|
||||
fun hashtagFollows(user: User): Note = LocalCache.getOrCreateAddressableNote(InterestListEvent.createAddress(user.pubkeyHex))
|
||||
|
||||
fun bookmarks(user: User): Note = LocalCache.getOrCreateAddressableNote(BookmarkListEvent.createBookmarkAddress(user.pubkeyHex))
|
||||
|
||||
@@ -2122,7 +2122,7 @@ class AccountViewModel(
|
||||
|
||||
fun updateZapAmounts(
|
||||
amountSet: List<Long>,
|
||||
selectedZapType: LnZapEvent.ZapType,
|
||||
selectedZapType: ZapReceiptEvent.ZapType,
|
||||
nip47Update: Nip47WalletConnect.Nip47URINorm?,
|
||||
) = launchSigner { account.updateZapAmounts(amountSet, selectedZapType, nip47Update) }
|
||||
|
||||
@@ -2848,7 +2848,7 @@ class AccountViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun unwrapSeal(event: SealedRumorEvent): Note? {
|
||||
private suspend fun unwrapSeal(event: SealEvent): Note? {
|
||||
val cacheInnerEventId = event.innerEventId
|
||||
return if (cacheInnerEventId != null) {
|
||||
val existingNoteEvent = LocalCache.getNoteIfExists(cacheInnerEventId)?.event
|
||||
@@ -2882,7 +2882,7 @@ class AccountViewModel(
|
||||
private suspend fun unwrapIfNeeded(event: Event): Note? =
|
||||
when (event) {
|
||||
is GiftWrapEvent -> unwrapGiftWrap(event)
|
||||
is SealedRumorEvent -> unwrapSeal(event)
|
||||
is SealEvent -> unwrapSeal(event)
|
||||
else -> LocalCache.getNoteIfExists(event.id)
|
||||
}
|
||||
|
||||
@@ -2936,7 +2936,7 @@ class AccountViewModel(
|
||||
LocalCache.notes.maxOrNullOf(
|
||||
filter = { _, note ->
|
||||
val noteEvent = note.event
|
||||
noteEvent is NIP90ContentDiscoveryResponseEvent &&
|
||||
noteEvent is DvmContentDiscoveryResponseEvent &&
|
||||
noteEvent.pubKey == pubkeyHex &&
|
||||
noteEvent.isTaggedUser(account.signer.pubKey) &&
|
||||
noteEvent.createdAt > fifteenMinsAgo
|
||||
@@ -3005,13 +3005,13 @@ class AccountViewModel(
|
||||
onError: (String, String) -> Unit,
|
||||
onProgress: (percent: Float) -> Unit,
|
||||
context: Context,
|
||||
zapType: LnZapEvent.ZapType? = null,
|
||||
zapType: ZapReceiptEvent.ZapType? = null,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val effectiveZapType = zapType ?: defaultZapType()
|
||||
val zapRequest =
|
||||
if (effectiveZapType != LnZapEvent.ZapType.NONZAP) {
|
||||
if (effectiveZapType != ZapReceiptEvent.ZapType.NONZAP) {
|
||||
// NIP-57 Appendix F: include amount + lnurl so the receipt can be validated.
|
||||
val splitLnurl = LnurlForm.toUrl(lnAddress)?.let(LnurlForm::urlToBech32)
|
||||
account.zaps.createZapRequestFor(
|
||||
|
||||
+17
-17
@@ -42,10 +42,10 @@ import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.PrivateZapCache
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.EphemeralGiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallAnswerEvent
|
||||
@@ -112,9 +112,9 @@ class EventProcessor(
|
||||
|
||||
is GiftWrapEvent -> giftWrapHandler.add(event, eventNote, publicNote)
|
||||
|
||||
is SealedRumorEvent -> sealHandler.add(event, eventNote, publicNote)
|
||||
is SealEvent -> sealHandler.add(event, eventNote, publicNote)
|
||||
|
||||
is LnZapRequestEvent -> zapRequest.add(event, eventNote, publicNote)
|
||||
is ZapRequestEvent -> zapRequest.add(event, eventNote, publicNote)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,9 +153,9 @@ class EventProcessor(
|
||||
is ChatroomKeyable -> chatHandler.delete(event, note)
|
||||
is DraftWrapEvent -> draftHandler.delete(event, note)
|
||||
is GiftWrapEvent -> giftWrapHandler.delete(event, note)
|
||||
is SealedRumorEvent -> sealHandler.delete(event, note)
|
||||
is LnZapRequestEvent -> zapRequest.delete(event, note)
|
||||
is LnZapEvent -> zapEvent.delete(event, note)
|
||||
is SealEvent -> sealHandler.delete(event, note)
|
||||
is ZapRequestEvent -> zapRequest.delete(event, note)
|
||||
is ZapReceiptEvent -> zapEvent.delete(event, note)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,9 +457,9 @@ class SealedRumorEventHandler(
|
||||
private val account: Account,
|
||||
private val cache: LocalCache,
|
||||
private val eventProcessor: EventProcessor,
|
||||
) : EventHandler<SealedRumorEvent> {
|
||||
) : EventHandler<SealEvent> {
|
||||
override suspend fun add(
|
||||
event: SealedRumorEvent,
|
||||
event: SealEvent,
|
||||
eventNote: Note,
|
||||
publicNote: Note,
|
||||
) {
|
||||
@@ -477,7 +477,7 @@ class SealedRumorEventHandler(
|
||||
}
|
||||
|
||||
override suspend fun delete(
|
||||
event: SealedRumorEvent,
|
||||
event: SealEvent,
|
||||
eventNote: Note,
|
||||
) {
|
||||
event.innerEventId?.let { rumorId ->
|
||||
@@ -489,7 +489,7 @@ class SealedRumorEventHandler(
|
||||
}
|
||||
|
||||
private suspend fun processNewSealedRumor(
|
||||
event: SealedRumorEvent,
|
||||
event: SealEvent,
|
||||
eventNote: Note,
|
||||
publicNote: Note,
|
||||
) {
|
||||
@@ -538,9 +538,9 @@ class SealedRumorEventHandler(
|
||||
|
||||
class LnZapRequestEventHandler(
|
||||
val decryptionCache: PrivateZapCache,
|
||||
) : EventHandler<LnZapRequestEvent> {
|
||||
) : EventHandler<ZapRequestEvent> {
|
||||
override suspend fun add(
|
||||
event: LnZapRequestEvent,
|
||||
event: ZapRequestEvent,
|
||||
eventNote: Note,
|
||||
publicNote: Note,
|
||||
) {
|
||||
@@ -550,7 +550,7 @@ class LnZapRequestEventHandler(
|
||||
}
|
||||
|
||||
override suspend fun delete(
|
||||
event: LnZapRequestEvent,
|
||||
event: ZapRequestEvent,
|
||||
eventNote: Note,
|
||||
) {
|
||||
if (event.isPrivateZap()) {
|
||||
@@ -561,9 +561,9 @@ class LnZapRequestEventHandler(
|
||||
|
||||
class LnZapEventHandler(
|
||||
val decryptionCache: PrivateZapCache,
|
||||
) : EventHandler<LnZapEvent> {
|
||||
) : EventHandler<ZapReceiptEvent> {
|
||||
override suspend fun delete(
|
||||
event: LnZapEvent,
|
||||
event: ZapReceiptEvent,
|
||||
eventNote: Note,
|
||||
) {
|
||||
event.zapRequest?.let { req ->
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.ChannelCardCompose
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
|
||||
@Composable
|
||||
fun ArticlesFeedLoaded(
|
||||
@@ -61,7 +61,7 @@ fun ArticlesFeedLoaded(
|
||||
ChannelCardCompose(
|
||||
baseNote = item,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
forceEventKind = LongTextNoteEvent.KIND,
|
||||
forceEventKind = LongFormContentEvent.KIND,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar
|
||||
import com.vitorpamplona.amethyst.ui.screen.FeedDefinition
|
||||
import com.vitorpamplona.amethyst.ui.screen.TopNavFilterState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
|
||||
@Composable
|
||||
fun ArticlesTopBar(
|
||||
@@ -49,7 +49,7 @@ fun ArticlesTopBar(
|
||||
// The feed's own kind window, plus whatever the list spinner narrowed it to — a hashtag or a
|
||||
// geohash says itself as a token; a follow set does not, and seeds nothing (see asSearchQuery).
|
||||
val me = accountViewModel.userProfile().pubkeyHex
|
||||
val seed = remember(list, me) { SearchSeed.merge(SearchSeed.ofKinds(LongTextNoteEvent.KIND), list.asSearchQuery(me)) }
|
||||
val seed = remember(list, me) { SearchSeed.merge(SearchSeed.ofKinds(LongFormContentEvent.KIND), list.asSearchQuery(me)) }
|
||||
|
||||
UserDrawerSearchTopBar(accountViewModel, nav, seed) {
|
||||
ArticlesTopNavFilterBar(
|
||||
|
||||
+4
-4
@@ -28,7 +28,7 @@ import com.vitorpamplona.amethyst.commons.model.topNavFeeds.TopFilter
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.ui.dal.FilterByListParams
|
||||
import com.vitorpamplona.amethyst.ui.dal.sortedByDefaultFeedOrder
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
|
||||
class ArticlesFeedFilter(
|
||||
val account: Account,
|
||||
@@ -50,9 +50,9 @@ class ArticlesFeedFilter(
|
||||
override fun feed(): List<Note> {
|
||||
val params = buildFilterParams(account)
|
||||
val notes =
|
||||
LocalCache.addressables.filterIntoSet(LongTextNoteEvent.KIND) { _, it ->
|
||||
LocalCache.addressables.filterIntoSet(LongFormContentEvent.KIND) { _, it ->
|
||||
val noteEvent = it.event
|
||||
noteEvent is LongTextNoteEvent && params.match(noteEvent, it.relays)
|
||||
noteEvent is LongFormContentEvent && params.match(noteEvent, it.relays)
|
||||
}
|
||||
return sort(notes)
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class ArticlesFeedFilter(
|
||||
|
||||
return collection.filterTo(HashSet()) {
|
||||
val noteEvent = it.event
|
||||
noteEvent is LongTextNoteEvent && params.match(noteEvent, it.relays)
|
||||
noteEvent is LongFormContentEvent && params.match(noteEvent, it.relays)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -92,9 +92,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.diff.ContentChange
|
||||
import com.vitorpamplona.quartz.nip01Core.diff.ListDiff
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListDiff
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.PublicChatListEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.channels
|
||||
import com.vitorpamplona.quartz.nip37Drafts.privateOutbox.PrivateOutboxRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
@@ -103,10 +103,10 @@ import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFee
|
||||
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListDiff
|
||||
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListDiff
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.InterestListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.FavoriteRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayListDiff
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip60Cashu.wallet.CashuWalletDiff
|
||||
@@ -137,7 +137,7 @@ internal fun LazyListScope.listDiffItems(
|
||||
is CommunityListDiff -> communityItems(diff, conflict, accountViewModel, nav)
|
||||
is EphemeralChatListDiff -> ephemeralRoomItems(diff, conflict, nav)
|
||||
is FavoriteAlgoFeedsListDiff -> favoriteFeedItems(diff, conflict, accountViewModel, nav)
|
||||
is HashtagListDiff -> topicItems(diff.hashtags, (conflict.saved as? HashtagListEvent)?.publicHashtags().orEmpty(), diff.privateItems, isPlace = false, nav)
|
||||
is HashtagListDiff -> topicItems(diff.hashtags, (conflict.saved as? InterestListEvent)?.publicHashtags().orEmpty(), diff.privateItems, isPlace = false, nav)
|
||||
is GeohashListDiff -> topicItems(diff.geohashes, (conflict.saved as? GeohashListEvent)?.publicGeohashes().orEmpty(), diff.privateItems, isPlace = true, nav)
|
||||
is TrustProviderListDiff -> trustProviderItems(diff, conflict, accountViewModel, nav)
|
||||
is PaymentTargetsDiff -> paymentTargetItems(diff, conflict)
|
||||
@@ -236,11 +236,11 @@ private fun framingOf(type: BackupEventType): RelayFraming =
|
||||
|
||||
private fun savedRelaysOf(event: Event): List<NormalizedRelayUrl> =
|
||||
when (event) {
|
||||
is ChatMessageRelayListEvent -> event.relays()
|
||||
is DmRelayListEvent -> event.relays()
|
||||
is KeyPackageRelayListEvent -> event.relays()
|
||||
is SearchRelayListEvent -> event.publicRelays()
|
||||
is IndexerRelayListEvent -> event.publicRelays()
|
||||
is RelayFeedsListEvent -> event.publicRelays()
|
||||
is FavoriteRelayListEvent -> event.publicRelays()
|
||||
is BlockedRelayListEvent -> event.publicRelays()
|
||||
is TrustedRelayListEvent -> event.publicRelays()
|
||||
is PrivateOutboxRelayListEvent -> event.publicRelays()
|
||||
@@ -451,7 +451,7 @@ private fun LazyListScope.publicChatItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val saved = (conflict.saved as? ChannelListEvent)?.tags?.channels().orEmpty()
|
||||
val saved = (conflict.saved as? PublicChatListEvent)?.tags?.channels().orEmpty()
|
||||
spaceGrid("chat-", fates(saved, diff.channels) { it.eventId }, { it.eventId }) { tag, fate, modifier ->
|
||||
LoadPublicChatChannel(tag.eventId) { channel ->
|
||||
// Subscribes to the channel's metadata on relays and recomposes when it arrives.
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ import com.vitorpamplona.amethyst.ui.note.types.EditState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.report.ReportNoteDialog
|
||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
||||
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -281,7 +281,7 @@ fun BookmarkGroupItemOptionsMenu(
|
||||
wantsToEditPost.value = true
|
||||
}
|
||||
}
|
||||
} else if (note.event is LongTextNoteEvent && state.isLoggedUser) {
|
||||
} else if (note.event is LongFormContentEvent && state.isLoggedUser) {
|
||||
M3ActionRow(icon = MaterialSymbols.Edit, text = stringRes(Res.string.edit_article)) {
|
||||
nav.nav { Route.NewLongFormPost(version = note.idHex) }
|
||||
}
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar
|
||||
import com.vitorpamplona.amethyst.ui.screen.FeedDefinition
|
||||
import com.vitorpamplona.amethyst.ui.screen.TopNavFilterState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
|
||||
@Composable
|
||||
fun CalendarCollectionsTopBar(
|
||||
@@ -49,7 +49,7 @@ fun CalendarCollectionsTopBar(
|
||||
// The feed's own kind window, plus whatever the list spinner narrowed it to — a hashtag
|
||||
// or a geohash says itself as a token; a follow set does not, and seeds nothing.
|
||||
val me = accountViewModel.userProfile().pubkeyHex
|
||||
val seed = remember(list, me) { SearchSeed.merge(SearchSeed.ofKinds(CalendarEvent.KIND), list.asSearchQuery(me)) }
|
||||
val seed = remember(list, me) { SearchSeed.merge(SearchSeed.ofKinds(CalendarCollectionEvent.KIND), list.asSearchQuery(me)) }
|
||||
|
||||
UserDrawerSearchTopBar(accountViewModel, nav, seed) {
|
||||
CalendarCollectionsTopNavFilterBar(
|
||||
|
||||
+3
-3
@@ -76,7 +76,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.UserCardHeader
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.day.CalendarDateSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.time.CalendarTimeSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@Composable
|
||||
@@ -153,7 +153,7 @@ fun CalendarCollectionCard(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val event = note.event as? CalendarEvent ?: return
|
||||
val event = note.event as? CalendarCollectionEvent ?: return
|
||||
val title = remember(note.idHex) { event.title() }
|
||||
val description = remember(note.idHex) { event.content.take(180) }
|
||||
val count = remember(note.idHex) { event.calendarEventAddresses().size }
|
||||
@@ -241,7 +241,7 @@ fun CalendarCollectionCard(
|
||||
* arrived from relays yet or aren't appointments. Returns a list compatible with
|
||||
* [IcsExport.calendarToIcs].
|
||||
*/
|
||||
private fun collectMembers(calendar: CalendarEvent): List<Pair<Address, Any>> =
|
||||
private fun collectMembers(calendar: CalendarCollectionEvent): List<Pair<Address, Any>> =
|
||||
calendar
|
||||
.calendarEventAddresses()
|
||||
.mapNotNull { addr ->
|
||||
|
||||
+4
-4
@@ -39,7 +39,7 @@ import com.vitorpamplona.amethyst.commons.model.nip52Calendar.groupByDayKeyExpan
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -162,13 +162,13 @@ class CalendarsViewModel : ViewModel() {
|
||||
* changes about once a week.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val ownCalendars: StateFlow<List<CalendarEvent>> =
|
||||
val ownCalendars: StateFlow<List<CalendarCollectionEvent>> =
|
||||
inputs
|
||||
.filterNotNull()
|
||||
.flatMapLatest { (myPubKey, _) ->
|
||||
LocalCache
|
||||
.observeEvents<CalendarEvent>(
|
||||
Filter(kinds = listOf(CalendarEvent.KIND), authors = listOf(myPubKey)),
|
||||
.observeEvents<CalendarCollectionEvent>(
|
||||
Filter(kinds = listOf(CalendarCollectionEvent.KIND), authors = listOf(myPubKey)),
|
||||
).map { calendars -> calendars.sortedBy { it.title()?.lowercase() ?: "" } }
|
||||
}
|
||||
// The seed scan inside observeEvents walks the whole notes cache (LocalCache.filter
|
||||
|
||||
+6
-6
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTags
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.day.CalendarDateSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.time.CalendarTimeSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -62,7 +62,7 @@ class NewCalendarCollectionViewModel : ViewModel() {
|
||||
private var dTag: String? = null
|
||||
|
||||
/** The full original event in edit mode; needed to publish a NIP-09 deletion. */
|
||||
private var loadedEvent: com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent? = null
|
||||
private var loadedEvent: com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent? = null
|
||||
|
||||
val selectedAddresses = mutableStateListOf<Address>()
|
||||
val availableAppointments = mutableStateOf<List<OwnedAppointmentSummary>>(emptyList())
|
||||
@@ -81,9 +81,9 @@ class NewCalendarCollectionViewModel : ViewModel() {
|
||||
dTag = editDTag
|
||||
|
||||
editDTag?.let { existingDTag ->
|
||||
val existingAddress = Address(CalendarEvent.KIND, account.userProfile().pubkeyHex, existingDTag)
|
||||
val existingAddress = Address(CalendarCollectionEvent.KIND, account.userProfile().pubkeyHex, existingDTag)
|
||||
val existingNote = LocalCache.addressables.get(existingAddress)
|
||||
(existingNote?.event as? CalendarEvent)?.let { existing ->
|
||||
(existingNote?.event as? CalendarCollectionEvent)?.let { existing ->
|
||||
loadedEvent = existing
|
||||
title.value = existing.title().orEmpty()
|
||||
description.value = existing.content
|
||||
@@ -140,7 +140,7 @@ class NewCalendarCollectionViewModel : ViewModel() {
|
||||
|
||||
account.signAndComputeBroadcast(
|
||||
if (effectiveDTag != null) {
|
||||
CalendarEvent.build(
|
||||
CalendarCollectionEvent.build(
|
||||
title = parsedTitle,
|
||||
content = parsedDescription,
|
||||
dTag = effectiveDTag,
|
||||
@@ -148,7 +148,7 @@ class NewCalendarCollectionViewModel : ViewModel() {
|
||||
if (selected.isNotEmpty()) aTags(selected.map { ATag(it) })
|
||||
}
|
||||
} else {
|
||||
CalendarEvent.build(
|
||||
CalendarCollectionEvent.build(
|
||||
title = parsedTitle,
|
||||
content = parsedDescription,
|
||||
) {
|
||||
|
||||
+3
-3
@@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.commons.model.topNavFeeds.TopFilter
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.ui.dal.FilterByListParams
|
||||
import com.vitorpamplona.amethyst.ui.dal.sortedByDefaultFeedOrder
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
|
||||
class CalendarCollectionsFeedFilter(
|
||||
val account: Account,
|
||||
@@ -49,7 +49,7 @@ class CalendarCollectionsFeedFilter(
|
||||
val notes =
|
||||
LocalCache.addressables.filterIntoSet { _, it ->
|
||||
val e = it.event
|
||||
e is CalendarEvent && params.match(e, it.relays)
|
||||
e is CalendarCollectionEvent && params.match(e, it.relays)
|
||||
}
|
||||
return sort(notes)
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class CalendarCollectionsFeedFilter(
|
||||
val params = buildFilterParams(account)
|
||||
return collection.filterTo(HashSet()) {
|
||||
val e = it.event
|
||||
e is CalendarEvent && params.match(e, it.relays)
|
||||
e is CalendarCollectionEvent && params.match(e, it.relays)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -53,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTags
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
|
||||
/**
|
||||
* Bottom sheet that lists the current user's own kind-31924 calendars with a checkbox per
|
||||
@@ -74,7 +74,7 @@ fun AddToCalendarSheet(
|
||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val myPubKey = accountViewModel.userProfile().pubkeyHex
|
||||
|
||||
val ownCalendars by produceState<List<CalendarEvent>>(initialValue = ownCalendars(myPubKey), myPubKey) {
|
||||
val ownCalendars by produceState<List<CalendarCollectionEvent>>(initialValue = ownCalendars(myPubKey), myPubKey) {
|
||||
LocalCache.live.newEventBundles.collect {
|
||||
value = ownCalendars(myPubKey)
|
||||
}
|
||||
@@ -152,17 +152,17 @@ private fun CalendarPickerRow(
|
||||
}
|
||||
}
|
||||
|
||||
private fun ownCalendars(myPubKey: String): List<CalendarEvent> =
|
||||
private fun ownCalendars(myPubKey: String): List<CalendarCollectionEvent> =
|
||||
LocalCache.addressables
|
||||
.filterIntoSet { _, note ->
|
||||
val e = note.event
|
||||
e is CalendarEvent && e.pubKey == myPubKey
|
||||
}.mapNotNull { it.event as? CalendarEvent }
|
||||
e is CalendarCollectionEvent && e.pubKey == myPubKey
|
||||
}.mapNotNull { it.event as? CalendarCollectionEvent }
|
||||
.sortedBy { it.title()?.lowercase() ?: "" }
|
||||
|
||||
private fun toggleMembership(
|
||||
accountViewModel: AccountViewModel,
|
||||
calendar: CalendarEvent,
|
||||
calendar: CalendarCollectionEvent,
|
||||
targetAddress: Address,
|
||||
isCurrentlyMember: Boolean,
|
||||
) {
|
||||
@@ -177,7 +177,7 @@ private fun toggleMembership(
|
||||
}
|
||||
accountViewModel.launchSigner {
|
||||
accountViewModel.account.signAndComputeBroadcast(
|
||||
CalendarEvent.build(
|
||||
CalendarCollectionEvent.build(
|
||||
title = calendar.title().orEmpty(),
|
||||
content = calendar.content,
|
||||
dTag = calendar.dTag(),
|
||||
|
||||
+6
-6
@@ -116,7 +116,7 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.day.CalendarDateSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.tags.RSVPStatusTag
|
||||
import com.vitorpamplona.quartz.nip52Calendar.appt.time.CalendarTimeSlotEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarCollectionEvent
|
||||
import com.vitorpamplona.quartz.nip52Calendar.rsvp.CalendarRSVPEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -287,7 +287,7 @@ fun CalendarEventDetailScreen(
|
||||
targetAddress = targetAddress,
|
||||
)
|
||||
|
||||
is CalendarEvent ->
|
||||
is CalendarCollectionEvent ->
|
||||
CollectionBody(
|
||||
note = targetNote,
|
||||
accountViewModel = accountViewModel,
|
||||
@@ -432,7 +432,7 @@ private fun CollectionBody(
|
||||
nav: INav,
|
||||
targetAddress: Address,
|
||||
) {
|
||||
val event = note.event as? CalendarEvent ?: return
|
||||
val event = note.event as? CalendarCollectionEvent ?: return
|
||||
val title = remember(note.idHex) { event.title() }
|
||||
val memberAddresses = remember(note.idHex) { event.calendarEventAddresses() }
|
||||
|
||||
@@ -736,7 +736,7 @@ private fun InCalendarsSection(
|
||||
.clickable {
|
||||
nav.nav(
|
||||
Route.CalendarEventDetail(
|
||||
kind = CalendarEvent.KIND,
|
||||
kind = CalendarCollectionEvent.KIND,
|
||||
pubKeyHex = calendar.pubKey,
|
||||
dTag = calendar.dTag(),
|
||||
),
|
||||
@@ -889,11 +889,11 @@ private fun rememberRsvpsFor(targetAddress: Address): State<List<CalendarRSVPEve
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberCalendarsContaining(targetAddress: Address): State<List<CalendarEvent>> {
|
||||
private fun rememberCalendarsContaining(targetAddress: Address): State<List<CalendarCollectionEvent>> {
|
||||
val calendars =
|
||||
remember(targetAddress) {
|
||||
LocalCache
|
||||
.observeEvents<CalendarEvent>(Filter(kinds = listOf(CalendarEvent.KIND)))
|
||||
.observeEvents<CalendarCollectionEvent>(Filter(kinds = listOf(CalendarCollectionEvent.KIND)))
|
||||
.map { all ->
|
||||
all
|
||||
.filter { it.calendarEventAddresses().contains(targetAddress) }
|
||||
|
||||
+6
-6
@@ -87,7 +87,7 @@ import com.vitorpamplona.quartz.buzz.stream.SystemMessageEvent
|
||||
import com.vitorpamplona.quartz.concord.cord03Channels.ConcordChatEditEvent
|
||||
import com.vitorpamplona.quartz.marmot.foundation.appEvents.MarmotAppEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseNoteEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
@@ -97,7 +97,7 @@ import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.clip.LiveActivitiesClipEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.raid.LiveActivitiesRaidEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.splits.hasZapSplitSetup
|
||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount
|
||||
|
||||
@@ -156,7 +156,7 @@ fun ChatroomMessageCompose(
|
||||
}
|
||||
|
||||
val event = baseNote.event
|
||||
if (event is LnZapEvent) {
|
||||
if (event is ZapReceiptEvent) {
|
||||
RenderChatZap(baseNote, accountViewModel, nav)
|
||||
} else if (event is LiveActivitiesRaidEvent) {
|
||||
RenderChatRaid(baseNote, accountViewModel, nav)
|
||||
@@ -248,10 +248,10 @@ fun NormalChatNote(
|
||||
when {
|
||||
// Own messages: normally no name; in a multi-identity chat, show it (unless a DM,
|
||||
// which never draws the user's own author info).
|
||||
isLoggedInUser -> showSelfAuthorName && noteEvent !is PrivateDmEvent
|
||||
isLoggedInUser -> showSelfAuthorName && noteEvent !is EncryptedDmEvent
|
||||
|
||||
// never shows the user's pictures
|
||||
noteEvent is PrivateDmEvent -> false
|
||||
noteEvent is EncryptedDmEvent -> false
|
||||
|
||||
// one-on-one, never shows it.
|
||||
// only shows in a group chat.
|
||||
@@ -588,7 +588,7 @@ private fun RenderReply(
|
||||
is ChatMessageEvent, is ChatMessageEncryptedFileHeaderEvent -> {
|
||||
{ LoadingReplyNote(DmReplyProtocol.NIP17, accountViewModel) }
|
||||
}
|
||||
is PrivateDmEvent -> {
|
||||
is EncryptedDmEvent -> {
|
||||
{ LoadingReplyNote(DmReplyProtocol.NIP04, accountViewModel) }
|
||||
}
|
||||
else -> null
|
||||
|
||||
+3
-3
@@ -51,7 +51,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.ToggleableTimeAgoText
|
||||
import com.vitorpamplona.amethyst.ui.note.timeAheadNoDot
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geoHashOrScope
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip13Pow.strongPoWOrNull
|
||||
import com.vitorpamplona.quartz.nip40Expiration.expiration
|
||||
|
||||
@@ -84,7 +84,7 @@ fun chatFooterHasMeta(
|
||||
): Boolean {
|
||||
val event = note.event ?: return false
|
||||
val geo = event.geoHashOrScope()
|
||||
return event is PrivateDmEvent ||
|
||||
return event is EncryptedDmEvent ||
|
||||
event.expiration() != null ||
|
||||
(geo != null && geo != suppressGeohash) ||
|
||||
event.strongPoWOrNull() != null ||
|
||||
@@ -132,7 +132,7 @@ fun ChatMessageFooter(
|
||||
}
|
||||
|
||||
if (showTime) {
|
||||
val hasGlyph = note.isPinnedInRelayGroup() || event is PrivateDmEvent || event?.expiration() != null || geo != null || pow != null
|
||||
val hasGlyph = note.isPinnedInRelayGroup() || event is EncryptedDmEvent || event?.expiration() != null || geo != null || pow != null
|
||||
if (hasGlyph) Spacer(StdHorzSpacer)
|
||||
|
||||
// Drafts aren't published, so no relay/delivery detail; everything else gets
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.clip.LiveActivitiesClipEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.raid.LiveActivitiesRaidEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
@@ -96,7 +96,7 @@ internal const val CHAT_GROUP_WINDOW_SECONDS = 10 * 60L
|
||||
*/
|
||||
private fun isGroupableEvent(event: Event?): Boolean =
|
||||
event != null &&
|
||||
event !is LnZapEvent &&
|
||||
event !is ZapReceiptEvent &&
|
||||
event !is LiveActivitiesRaidEvent &&
|
||||
event !is LiveActivitiesClipEvent &&
|
||||
event !is ChannelCreateEvent &&
|
||||
|
||||
+2
-2
@@ -55,7 +55,7 @@ import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.note.ZapAmountCommentNotification
|
||||
import com.vitorpamplona.amethyst.ui.note.showAmountInteger
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.ZapReceiptEvent
|
||||
|
||||
private const val BIG_ZAP_THRESHOLD_SATS = 50_000L
|
||||
|
||||
@@ -65,7 +65,7 @@ fun RenderChatZap(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val zapEvent = baseNote.event as? LnZapEvent ?: return
|
||||
val zapEvent = baseNote.event as? ZapReceiptEvent ?: return
|
||||
|
||||
val card by produceState(
|
||||
ZapAmountCommentNotification(user = null, comment = null, amount = null),
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionRequestEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -122,7 +122,7 @@ class GeohashChatViewModel : ViewModel() {
|
||||
val signer = NostrSignerInternal(keyPair)
|
||||
val template =
|
||||
if (mine.isNotEmpty()) {
|
||||
DeletionEvent.build(mine)
|
||||
DeletionRequestEvent.build(mine)
|
||||
} else {
|
||||
val hint = note.toEventHint<Event>() ?: return@launch
|
||||
ReactionEvent.build(reaction, hint)
|
||||
|
||||
+2
-2
@@ -71,7 +71,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.paging.RelayPagingProgress
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -130,7 +130,7 @@ fun ChatroomView(
|
||||
// Reactively check if recipients have DM relays for NIP-17 delivery
|
||||
for (userHex in room.users) {
|
||||
LoadAddressableNote(
|
||||
ChatMessageRelayListEvent.createAddress(userHex),
|
||||
DmRelayListEvent.createAddress(userHex),
|
||||
) { note ->
|
||||
if (note != null) {
|
||||
EventFinderFilterAssemblerSubscription(note, accountViewModel)
|
||||
|
||||
+3
-3
@@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
|
||||
/**
|
||||
@@ -114,7 +114,7 @@ private fun toMeFilter(
|
||||
filter =
|
||||
ExplainedFilter(
|
||||
purpose = SubPurpose.DIRECT_MESSAGES,
|
||||
kinds = listOf(PrivateDmEvent.KIND),
|
||||
kinds = listOf(EncryptedDmEvent.KIND),
|
||||
authors = authors.toList(),
|
||||
tags = mapOf("p" to listOf(account.userProfile().pubkeyHex)),
|
||||
since = since,
|
||||
@@ -135,7 +135,7 @@ private fun fromMeFilter(
|
||||
filter =
|
||||
ExplainedFilter(
|
||||
purpose = SubPurpose.DIRECT_MESSAGES,
|
||||
kinds = listOf(PrivateDmEvent.KIND),
|
||||
kinds = listOf(EncryptedDmEvent.KIND),
|
||||
authors = listOf(account.userProfile().pubkeyHex),
|
||||
tags = mapOf("p" to pTags.toList()),
|
||||
since = since,
|
||||
|
||||
+5
-5
@@ -68,7 +68,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.getGeoHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.references.references
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.EncryptedDmEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findNostrEventUris
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
|
||||
@@ -78,7 +78,7 @@ import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.NIP17Group
|
||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.DmRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.emojis
|
||||
@@ -184,7 +184,7 @@ class ChatNewMessageViewModel :
|
||||
combine(dmRelayListNoteFlows) { dmRelayListNotes ->
|
||||
dmRelayListNotes
|
||||
.mapNotNull { noteState ->
|
||||
val noteEvent = noteState.note.event as? ChatMessageRelayListEvent
|
||||
val noteEvent = noteState.note.event as? DmRelayListEvent
|
||||
if (noteEvent == null || noteEvent.relays().isEmpty()) {
|
||||
noteState.note.author
|
||||
} else {
|
||||
@@ -409,7 +409,7 @@ class ChatNewMessageViewModel :
|
||||
if (replyId != null) {
|
||||
replyTo.value = LocalCache.checkGetOrCreateNote(replyId)
|
||||
}
|
||||
} else if (draftEvent is PrivateDmEvent) {
|
||||
} else if (draftEvent is EncryptedDmEvent) {
|
||||
val recipientNPub = draftEvent.verifiedRecipientPubKey()?.let { Hex.decode(it).toNpub() }
|
||||
toUsers.setTextAndPlaceCursorAtEnd("@$recipientNPub")
|
||||
|
||||
@@ -420,7 +420,7 @@ class ChatNewMessageViewModel :
|
||||
}
|
||||
|
||||
val draftText =
|
||||
if (draftEvent is PrivateDmEvent) {
|
||||
if (draftEvent is EncryptedDmEvent) {
|
||||
accountViewModel.account.privateDMDecryptionCache.cachedDM(draftEvent) ?: ""
|
||||
} else {
|
||||
draftEvent.content
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user