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 4b74716121..2d78756a15 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 @@ -505,18 +505,17 @@ class EventNotificationConsumer( * decrypted the outer ChaCha20-Poly1305 layer and verified the inner * MLS-signed payload. * - * Only kind:9 chat messages produce a notification — reactions, control - * messages, and deletions stay silent, mirroring how NIP-17 (kind:14) - * is the only DM kind we notify. + * Typed to [ChatEvent] so the caller has to narrow first — reactions, + * control messages, and deletions stay silent at the type level, + * mirroring how NIP-17 (kind:14) is the only DM kind we notify. */ suspend fun notifyGroupMessage( - innerEvent: Event, + innerEvent: ChatEvent, nostrGroupId: String, account: Account, ) = withWakeLock { Log.d(TAG, "New Marmot Group Message to Notify") - if (innerEvent.kind != ChatEvent.KIND) return@withWakeLock if (!notificationManager().areNotificationsEnabled()) return@withWakeLock if (MainActivity.isResumed) return@withWakeLock @@ -530,8 +529,9 @@ class EventNotificationConsumer( val sender = LocalCache.getOrCreateUser(innerEvent.pubKey) val senderName = sender.toBestDisplayName() val senderPicture = sender.profilePicture() - // Show the message body when present; reactions/empty payloads fall - // back to a generic prompt so the popup is still actionable. + // Defensive fallback for the rare empty-content ChatEvent so the + // popup is still actionable. Non-chat inner kinds were filtered + // out at the call site by the ChatEvent type narrowing. val body = innerEvent.content.takeIf { it.isNotBlank() } ?: "New message" val accountNpub = 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 02edd09763..df17bfe015 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 @@ -51,6 +51,7 @@ 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.nipC7Chats.ChatEvent import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CancellationException @@ -231,7 +232,7 @@ class NotificationDispatcher( * once the MLS-decrypted inner event has been parsed and indexed. */ suspend fun notifyGroupMessage( - innerEvent: Event, + innerEvent: ChatEvent, nostrGroupId: String, account: Account, ) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt index 91afd97845..b9538f08c5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt @@ -49,6 +49,7 @@ import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallIceCandidateEvent import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallOfferEvent import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRejectEvent import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRenegotiateEvent +import com.vitorpamplona.quartz.nipC7Chats.ChatEvent import com.vitorpamplona.quartz.utils.Log import kotlinx.coroutines.CancellationException import kotlinx.coroutines.sync.Mutex @@ -665,13 +666,16 @@ class GroupEventHandler( // notification path can't route them. Fire the popup // directly here — only on first-time decryption, so // a relay re-broadcast or persist-replay doesn't - // double-notify. The notifier itself filters by - // inner kind (chat only) and freshness. - Amethyst.instance.notificationDispatcher.notifyGroupMessage( - innerEvent, - result.groupId, - account, - ) + // double-notify. Restrict to ChatEvent (kind:9) so + // reactions, deletions, and control messages stay + // silent. + if (innerEvent is ChatEvent) { + Amethyst.instance.notificationDispatcher.notifyGroupMessage( + innerEvent, + result.groupId, + account, + ) + } } }