mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 01:07:46 +00:00
fix(concord): notify on reactions to my Concord messages
NotificationFeedFilter derived `isConcord` from the note's own gatherers (is it in a joined ConcordChannel), but LocalCache.consumeConcordRumor only attaches kind-9 messages and kind-1111 replies to the channel — never a kind-7 reaction. So a reaction's `isConcord` was always false, it didn't bypass the follow filter, and since a fellow member usually isn't a follow it was dropped in Curated/Selected mode. Recognize a reaction/repost as Concord through its TARGET instead: if `replyTo.lastOrNull()` is a message in a community I've joined, it bypasses the follow filter exactly like a reply. Relevance is still the existing p-tag gate, so only reactions that actually tag me notify (a well-formed NIP-25 kind-7 p-tags the reacted author, which is what our own ChannelChat.reaction writes). The "Messages in notifications" toggle now gates only Concord messages, not reactions — a like isn't a message, so it follows the same rule as any other reaction. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
08c1d1d539
commit
5b54eb88a5
+21
-5
@@ -449,14 +449,30 @@ class NotificationFeedFilter(
|
||||
// gatherer reference from every account/community that ever touched them, so require the
|
||||
// community to be one THIS account has currently joined (mirrors the Marmot check above) —
|
||||
// otherwise a note from a prior account or a left community would leak onto Notifications.
|
||||
val isConcord =
|
||||
it.inGatherers?.any { g ->
|
||||
fun Note?.inJoinedConcordCommunity() =
|
||||
this?.inGatherers?.any { g ->
|
||||
g is ConcordChannel && account.concordSessions.sessionFor(g.channelId.communityId) != null
|
||||
} == true
|
||||
|
||||
// Concord is a messaging feature, so honor the same "Messages in notifications" toggle that
|
||||
// silences DMs and Marmot groups above.
|
||||
if (isConcord && !showMessages) return false
|
||||
val isConcordMessage = it.inJoinedConcordCommunity()
|
||||
|
||||
// A like/repost is NOT itself attached to the channel gatherer — only chat messages/replies are
|
||||
// (see LocalCache.consumeConcordRumor) — so `inGatherers` never flags it as Concord, and its
|
||||
// author (a fellow member) usually isn't a follow, so it falls through the follow filter and is
|
||||
// dropped. Recognize it through its TARGET: a reaction/repost pointing at a message in a
|
||||
// community I've joined is a Concord reaction, and bypasses the follow filter like a reply does.
|
||||
// Relevance (does it target ME) is still enforced below by the p-tag gate — a well-formed kind-7
|
||||
// p-tags the reacted author (NIP-25), which is exactly what our own ChannelChat.reaction writes.
|
||||
val isConcordReaction =
|
||||
(noteEvent is ReactionEvent || noteEvent is RepostEvent || noteEvent is GenericRepostEvent) &&
|
||||
it.replyTo?.lastOrNull().inJoinedConcordCommunity()
|
||||
|
||||
val isConcord = isConcordMessage || isConcordReaction
|
||||
|
||||
// Concord CHAT (a message/reply) honors the "Messages in notifications" toggle that silences DMs
|
||||
// and Marmot groups above. A reaction isn't a message — regular reactions ignore that toggle, so
|
||||
// Concord reactions do too (only isConcordMessage is gated).
|
||||
if (isConcordMessage && !showMessages) return false
|
||||
|
||||
// Global keeps every event that p-tags the user; Selected (and the
|
||||
// follow/list modes) also applies the per-kind relevance heuristics.
|
||||
|
||||
Reference in New Issue
Block a user