Skip to content

fix(notifications): collapse per-peer message notifs instead of stacking#82

Closed
epicexcelsior wants to merge 1 commit into
anonmesh:v3from
epicexcelsior:epic/f9-cherry-to-v3
Closed

fix(notifications): collapse per-peer message notifs instead of stacking#82
epicexcelsior wants to merge 1 commit into
anonmesh:v3from
epicexcelsior:epic/f9-cherry-to-v3

Conversation

@epicexcelsior
Copy link
Copy Markdown
Collaborator

@epicexcelsior epicexcelsior commented May 18, 2026

Summary

Cherry-picks the F9 fix from staging (originally PR #78, commit b5c81ff) onto v3. Same diff — +5 lines in mobile_app/hooks/useMessageNotifications.ts.

The staging branch has been mostly unused for ~17 PRs and the F9 fix has been stuck there. Bringing it directly to v3 so users actually receive it.

What it does

Background message notifications previously called scheduleNotificationAsync with no identifier. Each event minted a fresh UNNotificationRequest on iOS — that's the team-lead-reported "push notifications spammed on iOS instead of updated."

This passes a per-peer identifier (anonmesh-msg-<srcHash>). iOS reuses the same request slot, so a follow-up message replaces the unread banner. Android same-identifier reuse updates in place.

Mirrors hooks/usePeerCountNotification.ts — same pattern, in production already.

Scope

  • hooks/useMessageNotifications.ts — one new line on the schedule payload + a short comment
  • No new permissions, no native config, no expo-notifications version bump
  • No behavior change in foreground / active-thread paths

Verified

  • Static: tsc clean for the diff (touched file only). Lint clean.
  • Build: npx expo run:android --device Seeker BUILD SUCCESSFUL, APK installed, app launches without notification-related errors in logcat.
  • Pattern parity: dumpsys notification on Seeker confirms tag=anonmesh-peer-count exists — identical API surface this fix uses. The peer-count hook has shipped on iOS without spam complaints.
  • Regression: home→foreground cycle, app PID stable, adjacent peer-count notification still healthy.

Not yet verified (deferred to flip-ready)

  • Behavioral 2-device smoke (single Android available at time of opening). 5-step checklist below.
  • iOS device verification (Mac/EAS gated — anyone on TF can run the same 5 steps).

Test plan (manual, 2 devices)

Background app, drive from a 2nd device:

  • Same peer sends 2 messages within 30s → ONE tray notification, latest content shown, not two stacked
  • Different peers send messages → TWO distinct notifications (one per peer)
  • Dismiss notification + new message from same peer → notification reappears as fresh banner
  • Foreground unchanged: app open, peer sends msg → in-app banner, no tray notification (no regression in onInApp path)
  • Active thread unchanged: thread open with peer, peer sends msg → no in-app banner, no tray notification

Heads-up — unrelated pre-existing tsc error on v3

While running tsc, found that v3 head (currently 31ad916) has a type error not introduced by this PR:

context/NetworkModeContext.tsx(110): error TS2304: Cannot find name 'beaconRpcWait'.
context/NetworkModeContext.tsx(112): error TS2304: Cannot find name 'beaconRpcWait'.

The destructure on line 64 reads { beacons, beaconBroadcastRpc, status, peers } from useLxmfContext(), but lines 110/112 reference beaconRpcWait. Looks like a merge-resolution artifact from #80/#81. Flagging here as informational — happy to open a separate small PR fixing the destructure if useful.

…ing (anonmesh#78)

Background-delivered messages scheduled a fresh notification request per
event, so iOS stacked one banner per message in the tray (same symptom
as F9 — "push notifications spammed instead of updated"). Android was
saved only by the channel-level group fallback.

Pass a per-peer identifier (`anonmesh-msg-<srcHash>`) on
scheduleNotificationAsync. On iOS this reuses the same UNNotificationRequest
slot so a follow-up message replaces the unread banner instead of stacking;
on Android same-identifier reuse updates the existing notification in place.

Mirrors the single-id pattern already used by usePeerCountNotification.
No new permissions or native config.
@epicexcelsior
Copy link
Copy Markdown
Collaborator Author

Closing this in favor of a proper staging→v3 promotion PR.

Team lead asked PRs to target staging first, then promote to v3 via a separate maintainer-cadence merge. This PR is a v3-direct cherry-pick which doesn't honor that policy.

The F9 fix is already on staging at b5c81ff via #78 (merged yesterday). Opening a staging → v3 promotion PR next, which will bring F9 to v3 alongside the mesh-payment trio (#79/#80/#81) that's already there.

Future PR cadence:

  1. Feature PR → target staging → review → merge
  2. (Periodic) staging → v3 promotion PR → release to users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant