Add filtering options for announce notifications#426
Conversation
…ations Add two new notification sub-options under "Heard Announce" that allow users to filter announce notifications by interface type and hop count: - "Direct Only" (default: on) - Only notify for 1-hop announces from direct neighbors, filtering out multi-hop announces that were relayed through transport nodes - "Exclude TCP" (default: on) - Skip announces received via TCP interfaces, which arrive frequently and are less noteworthy than BLE or RNode announces Both options default to enabled, so existing users who have announce notifications turned on will immediately benefit from reduced noise without needing to change settings. Closes #339 https://claude.ai/code/session_01JjXTJtNGs16FH8NwmbkFBi
Greptile SummaryThis PR adds two notification filters for announce events to reduce noise: direct-only mode (only notify for 1-hop neighbors) and TCP exclusion (skip announces received via TCP interfaces). Both default to enabled, which provides a sensible out-of-the-box experience for reducing notification spam from distant peers and TCP connections.
Confidence Score: 5/5
Important Files Changed
Flowchartflowchart TD
A[MessageCollector receives announce] --> B[notifyAnnounceHeard\nhops, interfaceType]
B --> C{shouldNotifyAnnounce}
C --> D{Master notifications\nenabled?}
D -- No --> Z[Return: no notification]
D -- Yes --> E{Announce notifications\nenabled?}
E -- No --> Z
E -- Yes --> F{Direct-only filter\nenabled?}
F -- Yes --> G{hops == 1?}
G -- No --> Z
G -- Yes --> H{Exclude TCP\nenabled?}
F -- No --> H
H -- Yes --> I{interfaceType ==\nTCP_CLIENT?}
I -- Yes --> Z
I -- No --> J{Has notification\npermission?}
H -- No --> J
J -- No --> Z
J -- Yes --> K[Post notification]
Last reviewed commit: 3204916 |
app/src/main/java/com/lxmf/messenger/notifications/NotificationHelper.kt
Outdated
Show resolved
Hide resolved
hops==0 means unknown (Python fallback when hops_to() returns None), not direct. Change condition from `hops > 1` to `hops != 1` so that only confirmed direct-neighbor announces (exactly 1 hop) pass the direct-only filter. https://claude.ai/code/session_01JjXTJtNGs16FH8NwmbkFBi
|
@greptileai review |
Additional Comments (1)
combine(
combine(
settingsRepository.notificationsEnabledFlow,
settingsRepository.notificationReceivedMessageFlow,
settingsRepository.notificationReceivedMessageFavoriteFlow,
settingsRepository.notificationHeardAnnounceFlow,
) { enabled, msg, fav, announce -> Quadruple(enabled, msg, fav, announce) },
combine(
settingsRepository.notificationAnnounceDirectOnlyFlow,
settingsRepository.notificationAnnounceExcludeTcpFlow,
) { directOnly, excludeTcp -> Pair(directOnly, excludeTcp) },
// ...etc
) { ... }This makes it impossible to accidentally shift indices when adding new settings. Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: app/src/main/java/com/lxmf/messenger/viewmodel/NotificationSettingsViewModel.kt
Line: 51:73
Comment:
**Fragile index-based flow combine**
The `combine` call now merges 9 flows, accessed via `values[0]` through `values[8]`. Every time a new preference is added, all subsequent indices must be manually renumbered — which is error-prone and has already required a full re-index in this PR. Consider using a pattern that's resilient to insertion, for example combining sub-groups of flows or using named intermediate variables:
```kotlin
combine(
combine(
settingsRepository.notificationsEnabledFlow,
settingsRepository.notificationReceivedMessageFlow,
settingsRepository.notificationReceivedMessageFavoriteFlow,
settingsRepository.notificationHeardAnnounceFlow,
) { enabled, msg, fav, announce -> Quadruple(enabled, msg, fav, announce) },
combine(
settingsRepository.notificationAnnounceDirectOnlyFlow,
settingsRepository.notificationAnnounceExcludeTcpFlow,
) { directOnly, excludeTcp -> Pair(directOnly, excludeTcp) },
// ...etc
) { ... }
```
This makes it impossible to accidentally shift indices when adding new settings.
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise. |
… NotificationSettingsViewModel The 9-flow combine() used fragile values[0]..values[8] array indexing, requiring manual renumbering whenever a preference was added or reordered. Refactored to use nested combine() sub-groups with named lambda parameters and destructuring, making the mapping self-documenting and resilient to insertion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The notifyAnnounceHeard function had 5 early returns for guard checks (master toggle, per-type toggle, direct-only filter, TCP exclusion, permission), exceeding detekt's ReturnCount limit of 3. Extracted a shouldNotifyAnnounce helper that consolidates these checks into a single boolean expression, leaving notifyAnnounceHeard with just one guard return. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@greptileai review |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|
@greptileai review |
… icon Announce push notifications now display the receiving interface name (e.g. "via Backbone · 1 hop") instead of generic "Announce received". All notifications use the Columba launcher icon instead of Android system icons. Also adds root-level installDebug task defaulting to noSentry variant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
app/src/main/java/com/lxmf/messenger/notifications/NotificationHelper.kt
Show resolved
Hide resolved
…values Use concrete string sentinels for Link.ACTIVE/CLOSED instead of auto-created MagicMock attributes (Mock == Mock comparison is nondeterministic across Python versions). Also provide extra time.time() side_effect values and set Transport.active_links = [] to prevent StopIteration on unexpected calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Add two new filtering options for announce notifications to reduce notification noise: direct-only mode (only notify for 1-hop neighbors) and TCP exclusion (skip announces from TCP interfaces).
Key Changes
notifyAnnounceHeard()to accepthopsandinterfaceTypeparameters, with logic to filter notifications based on new settingsnotificationAnnounceDirectOnlyFlow: Only notify for direct (1-hop) announces (defaults to true)notificationAnnounceExcludeTcpFlow: Exclude TCP interface announces from notifications (defaults to true)hopsandinterfaceTypewhen callingnotifyAnnounceHeard()Implementation Details
true(enabled), providing sensible defaults that reduce notification spam from distant peers and TCP connectionsInterfaceType.fromInterfaceName()to classify the receiving interfacehttps://claude.ai/code/session_01JjXTJtNGs16FH8NwmbkFBi