Skip to content

merge: promote staging to v3 (F9 notif spam fix)#83

Merged
epicexcelsior merged 2 commits into
v3from
staging
May 20, 2026
Merged

merge: promote staging to v3 (F9 notif spam fix)#83
epicexcelsior merged 2 commits into
v3from
staging

Conversation

@epicexcelsior
Copy link
Copy Markdown
Collaborator

@epicexcelsior epicexcelsior commented May 19, 2026

Summary

Promotes staging to v3. Brings the F9 notification spam fix to users.

This is a release-branch promotion PR. New convention going forward (per team-lead directive 2026-05-19):

  • Feature PRs target staging → review → merge.
  • Periodic staging → v3 promotion PRs roll integration tip to release.

What lands in v3

What v3 already has that this PR preserves

Verification

  • tsc clean on the F9 change (touched file).
  • Build verified yesterday on Solana Seeker — APK installs, app launches without notification-related errors in logcat.
  • Pattern parity: dumpsys notification confirms identifier-collapse mechanism is live for usePeerCountNotification on this device.

Gated test (deferrable, low-risk)

Behavioral 2-device smoke (5-step checklist):

  • Same peer 2 msgs → ONE tray entry (replaces, not stacks)
  • Different peers → TWO distinct entries
  • Dismiss + new msg from same peer → fresh banner
  • Foreground in-app banner path unchanged
  • Active-thread suppression unchanged

iOS verification deferred to TF window. Worst case if iOS quirk → identical to today's spam behavior, zero new failure mode.

Heads-up flagged in v3 (not introduced by this PR)

…ing (#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 epicexcelsior requested a review from Copilot May 19, 2026 06:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Promotes the current staging integration tip to v3, primarily to deliver the F9 background notification spam fix by making per-sender message notifications update/replace instead of stacking.

Changes:

  • Add a per-peer identifier to message background notifications so subsequent messages from the same sender replace the existing tray entry.
  • Add inline documentation explaining the per-peer notification identifier behavior across iOS/Android.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 89 to 92
Notifications.scheduleNotificationAsync({
identifier: `anonmesh-msg-${srcHash}`,
content: { title: sender, body: 'new message', sound: true },
trigger: null,
// on Android the channel already groups under 'messages'.
Notifications.scheduleNotificationAsync({
identifier: `anonmesh-msg-${srcHash}`,
content: { title: sender, body: 'new message', sound: true },
…rruption (#84)

Message notifications (useMessageNotifications.ts):
  Lock screen / Notification Center now show generic content only —
  `title: 'anonmesh'`, `body: 'New message'`. No sender hash, no preview.
  In-app banner (when the app is foregrounded) still surfaces the sender,
  since the user is already inside the app. Combined with the per-peer
  identifier from #78 and `interruptionLevel: 'passive'`, follow-up
  messages collapse silently into the existing tray entry instead of
  re-presenting the banner.

Peer-count notification (usePeerCountNotification.ts):
  Split by platform.
  - iOS: schedule ONCE on 0↔peers transition; body is generic 'Mesh active'.
    Notification Center has no silent persistent surface, so every
    reschedule resurfaces the entry. The in-app indicator carries live
    counts; the tray entry just signals "mesh is on".
  - Android: live counts on the LOW-importance 'peer-status' channel. The
    channel handles silence, so updates flow without re-presenting.

No native module changes, no permission changes — JS-only, ships via Metro
hot-reload or any existing dev build.
@epicexcelsior epicexcelsior merged commit 8f739f9 into v3 May 20, 2026
1 check passed
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.

2 participants