mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-11 08:47:33 +00:00
refactor(notifications): type notifyGroupMessage as ChatEvent
The previous signature took Event and runtime-checked kind == 9 inside the notifier. That left the contract implicit: any caller could pass a reaction or control message and the call would silently no-op. Type the parameter as ChatEvent so the kind:9 restriction is structural, and move the narrowing (`is ChatEvent`) to the GroupEventHandler call site where the inner event is parsed. Reactions, deletions, and other inner kinds now can't reach the notifier in the first place. Drops the runtime kind check and the now-stale comment about reactions.
This commit is contained in:
+7
-7
@@ -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 =
|
||||
|
||||
+2
-1
@@ -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,
|
||||
) {
|
||||
|
||||
+11
-7
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user