fix(chat): add p tags for people cited in kind 9/11/1111 messages

Extends the mention p-tag fix to the shared chat/thread composers, which
resolved `@`/`nostr:` mentions via NewMessageTagger but then dropped the
cited users from the signed event:

- kind 9 (ChatEvent, NIP-29 group chat): the reply path tagged only the
  parent author and the plain build path tagged no one. Emit `p` tags for
  every cited body user (reply path keeps the parent's relay-hinted tag and
  excludes it from the extra set to avoid a duplicate).
- kind 1111 (CommentEvent) minichat reply: replyBuilder auto-tags the
  parent/root author but body mentions were dropped. Notify the other
  cited users (parent excluded to avoid a duplicate).
- kind 11 (ThreadEvent, NIP-29 group thread): the ShortNote thread branch
  added no `p` tags at all; emit them from the cited body users, matching
  the sibling Poll/ZapPoll branches.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RcWSCNMTVcvKMXo7xA2hue
This commit is contained in:
Claude
2026-07-27 19:36:57 +00:00
parent 1d44563d37
commit 11147aac10
2 changed files with 23 additions and 0 deletions
@@ -94,6 +94,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.people.pTag
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
import com.vitorpamplona.quartz.nip01Core.tags.people.toPTag
import com.vitorpamplona.quartz.nip01Core.tags.references.references
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
@@ -102,6 +103,7 @@ import com.vitorpamplona.quartz.nip10Notes.content.findURLs
import com.vitorpamplona.quartz.nip13Pow.miner.PoWMiner
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
import com.vitorpamplona.quartz.nip22Comments.CommentEvent
import com.vitorpamplona.quartz.nip22Comments.notify
import com.vitorpamplona.quartz.nip28PublicChat.base.notify
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
import com.vitorpamplona.quartz.nip29RelayGroups.hTag
@@ -622,6 +624,14 @@ open class ChannelNewMessageViewModel :
hTag(channel.groupId.id)
previous(channel.previousEventRefs(account.userProfile().pubkeyHex))
}
// `p` mentions for everyone else cited in the body — replyBuilder already tags the
// parent/root author, so exclude the parent to avoid a duplicate `p`.
notify(
tagger.pTags
?.filter { it.pubkeyHex != minichatParent.pubKey }
?.map { it.toPTag() }
.orEmpty(),
)
hashtags(findHashtags(tagger.message))
references(findURLs(tagger.message))
quotes(findNostrUris(tagger.message))
@@ -843,6 +853,14 @@ open class ChannelNewMessageViewModel :
hTag(channel.groupId.id)
previous(channel.previousEventRefs(account.userProfile().pubkeyHex))
pTag(replyingToEvent.toPTag())
// `p` mentions for everyone else cited in the body (the parent author is
// already tagged above with its relay hint) so a named member is notified.
pTags(
tagger.pTags
?.filter { it.pubkeyHex != replyingToEvent.event.pubKey }
?.map { it.toPTag() }
.orEmpty(),
)
hashtags(findHashtags(tagger.message))
references(findURLs(tagger.message))
@@ -857,6 +875,8 @@ open class ChannelNewMessageViewModel :
ChatEvent.build(tagger.message) {
hTag(channel.groupId.id)
previous(channel.previousEventRefs(account.userProfile().pubkeyHex))
// `p` mentions for everyone cited in the body so a named member is notified.
pTags(tagger.pTags?.map { it.toPTag() }.orEmpty())
hashtags(findHashtags(tagger.message))
references(findURLs(tagger.message))
@@ -1265,6 +1265,9 @@ open class ShortNotePostViewModel :
// authorizes the write.
ThreadEvent.build(tagger.message, subjectValue) {
hTag(threadTarget.groupId)
// `p` mentions for everyone cited in the body, so a named member is notified and the
// `nostr:` reference resolves — matching the Poll/ZapPoll branches below.
pTags(tagger.directMentionsUsers.map { it.toPTag() })
hashtags(findHashtags(tagger.message))
references(findURLs(tagger.message))