From 1b24d0262424f6715ede37f72368efa5d141f279 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 24 Apr 2026 01:22:37 +0000 Subject: [PATCH] feat(notifications): route all content-event citations to Mentions Extend the Mentions channel beyond kind-1 text notes to cover every public content kind that can p-tag the user: - PictureEvent (20) - VideoNormalEvent (21), VideoShortEvent (22), VideoHorizontalEvent (34235), VideoVerticalEvent (34236) - ChannelMessageEvent (42) - PollEvent (1068) - GitPatchEvent (1617), GitIssueEvent (1621) - HighlightEvent (9802) - LongTextNoteEvent (30023) - WikiNoteEvent (30818) NotificationDispatcher observes these kinds so LocalCache insertions wake the consumer. dispatchForAccount routes all of them through a shared catch-all branch to notifyMention, which was generalized from TextNoteEvent to Event. The existing self-authored and 15-min filters now live inside notifyMention so the catch-all branch doesn't have to repeat them per kind. Replies (kind 1 to our own notes, kind 1111 comments with us as root or direct-reply author) still land on the Replies channel; all other p-tag citations fall to Mentions. https://claude.ai/code/session_01GQDJxiHPogdzCNhUBN7Pjc --- .../EventNotificationConsumer.kt | 42 ++++++++++++++++++- .../notifications/NotificationDispatcher.kt | 25 +++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt index bc3c42c84..a5ae6dfef 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt @@ -65,12 +65,24 @@ import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent import com.vitorpamplona.quartz.nip19Bech32.toNpub import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent +import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent 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.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 import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -177,13 +189,35 @@ class EventNotificationConsumer( when (event) { is PrivateDmEvent -> notify(event, account) + is LnZapEvent -> notify(event, account) + is ChatMessageEvent -> notify(event, account) + is ChatMessageEncryptedFileHeaderEvent -> notify(event, account) + is ReactionEvent -> notify(event, account) + is TextNoteEvent -> notify(event, account) + is CommentEvent -> notify(event, account) + + is PictureEvent, + is VideoNormalEvent, + is VideoShortEvent, + is VideoHorizontalEvent, + is VideoVerticalEvent, + is ChannelMessageEvent, + is PollEvent, + is GitPatchEvent, + is GitIssueEvent, + is HighlightEvent, + is LongTextNoteEvent, + is WikiNoteEvent, + -> notifyMention(event, account) + is LiveChessGameAcceptEvent -> notifyChessEvent(event, account, R.string.app_notification_chess_challenge_accepted) + is LiveChessMoveEvent -> notifyChessEvent(event, account, R.string.app_notification_chess_your_turn) // WelcomeEvent is dispatched directly from processMarmotWelcomeFlow // (no `p` tag, so tag-based matching doesn't work). @@ -774,9 +808,15 @@ class EventNotificationConsumer( } private suspend fun notifyMention( - event: TextNoteEvent, + event: Event, account: Account, ) { + // old event being re-broadcast + if (event.createdAt < TimeUtils.fifteenMinutesAgo()) return + + // don't notify for our own events + if (event.pubKey == account.signer.pubKey) return + val note = LocalCache.getNoteIfExists(event.id) ?: return val author = LocalCache.getOrCreateUser(event.pubKey) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt index 32900cc9f..95c662e21 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt @@ -32,10 +32,22 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent +import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent +import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent +import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent +import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent 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.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 import com.vitorpamplona.quartz.utils.Log import kotlinx.coroutines.CancellationException @@ -79,6 +91,19 @@ class NotificationDispatcher( ReactionEvent.KIND, TextNoteEvent.KIND, CommentEvent.KIND, + // Public content kinds — routed to the Mentions channel when p-tagged. + PictureEvent.KIND, + VideoNormalEvent.KIND, + VideoShortEvent.KIND, + VideoHorizontalEvent.KIND, + VideoVerticalEvent.KIND, + ChannelMessageEvent.KIND, + PollEvent.KIND, + GitPatchEvent.KIND, + GitIssueEvent.KIND, + HighlightEvent.KIND, + LongTextNoteEvent.KIND, + WikiNoteEvent.KIND, LiveChessGameAcceptEvent.KIND, LiveChessMoveEvent.KIND, WakeUpEvent.KIND,