diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt index 124e578ad0..8f4cdc9eb2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt @@ -81,6 +81,7 @@ import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceEvent import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceReplyEvent import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent +import com.vitorpamplona.quartz.nipC7Chats.ChatEvent import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent import kotlinx.coroutines.flow.MutableStateFlow @@ -136,6 +137,12 @@ class NotificationFeedFilter( setOf( BadgeAwardEvent.KIND, ChannelMessageEvent.KIND, + // NIP-29 group chat (kind 9). A reply to my group message is a + // kind-9 that p-tags me (see ChannelNewMessageViewModel), fetched + // at startup by filterGroupNotificationsToPubkey. Without kind 9 + // here the acceptableEvent kind gate drops it before the p-tag + // check, so those replies never render on the Notifications tab. + ChatEvent.KIND, ChatMessageEvent.KIND, ChatMessageEncryptedFileHeaderEvent.KIND, CommentEvent.KIND, diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationKindsContractTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationKindsContractTest.kt index 0e49022cf9..886bf711b9 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationKindsContractTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationKindsContractTest.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.dal import com.vitorpamplona.amethyst.commons.moderation.notifications.NotificationKinds import com.vitorpamplona.quartz.nip59Giftwrap.wraps.EphemeralGiftWrapEvent import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent +import com.vitorpamplona.quartz.nipC7Chats.ChatEvent import org.junit.Assert.assertTrue import org.junit.Test @@ -73,4 +74,23 @@ class NotificationKindsContractTest { unaccounted.isEmpty(), ) } + + /** + * A reply to my message inside a NIP-29 relay group is a kind-9 [ChatEvent] + * that p-tags me. It is fetched at startup by `filterGroupNotificationsToPubkey` + * (scoped `#p`=me + `#h`=my groups on the group's host relay), but the + * `acceptableEvent` gate first checks `kind in NOTIFICATION_KINDS`, so without + * kind 9 in the set the reply is dropped before the p-tag check and never + * surfaces on the Notifications tab. Pin its presence so it can't silently + * regress. + */ + @Test + fun `nip-29 group chat replies render on the Android notifications tab`() { + assertTrue( + "ChatEvent.KIND (9) is missing from NOTIFICATION_KINDS. NIP-29 group " + + "replies that p-tag the user would be dropped by the acceptableEvent " + + "kind gate before the p-tag check and never notify.", + ChatEvent.KIND in NotificationFeedFilter.NOTIFICATION_KINDS, + ) + } }