Files
cinny/docs/handoff/features/background-notifications/HANDOFF.md
litruv b52926f7d8 Fix system notifications ignoring mention-only and default room settings.
Skip non-highlight events for Mentions/Default non-DM rooms so public chats stay quiet unless they should ping.
2026-07-24 00:30:25 +10:00

3.4 KiB

Background notifications — handoff

Summary

Paarrot keeps users notified of Matrix activity when the app is in the background: desktop tray/favicon badges, system notifications (Electron/Tauri/Android), and Android UnifiedPush for reliable mobile push without Google FCM dependency.

User-facing behavior

  • Unread counts update favicon (Paarrot / unread / highlight variants)
  • System notifications for mentions/DMs per notification settings
  • Android: requires UnifiedPush distributor (e.g. ntfy); user prompted if missing
  • Foreground/background state affects sync strategy

Architecture

ClientNonUIFeatures.tsx
  → FaviconUpdater (roomToUnread atom)
  → notification listeners (tauri.ts sendNotification)
  → initPaarrotAPI + background sync lifecycle
backgroundSync.ts
  → UnifiedPush registration, pusher setup
  → setAppForegroundState / startBackgroundSync / stopBackgroundSync
tauri.ts / electron main
  → OS notification APIs, Android small icon ic_stat_paarrot

Key files

Path Role
cinny/src/app/pages/client/ClientNonUIFeatures.tsx Favicon, notifications, API init, background sync hooks
cinny/src/app/utils/backgroundSync.ts Pushers, UnifiedPush, foreground state
cinny/src/app/utils/tauri.ts Tauri/Capacitor notification helpers
cinny/src/app/features/settings/notifications/SystemNotification.tsx Permission UX
electron/main.js Tray, notification IPC (if applicable)
src-tauri/src/main.rs Tauri Android shell

Data model

Key Storage Purpose
paarrot.unifiedpush.* localStorage prefix UP endpoint state
com.paarrot.app.android Pusher app id base Android pushers
Matrix pusher Homeserver HTTP push gateway

Dependencies

  • UnifiedPush distributor app on Android
  • Notification permission (browser/OS)
  • Homeserver pusher support
  • matrix-js-sdk sync

Integration points

  • Settings → Notifications: rules + system permission
  • DirectTab / sidebar: custom Paarrot SVG favicon states
  • Deep links: notification tap → setupNotificationTapListener

Testing

Manual

  1. Desktop: background app; send mention; verify system notification.
  2. Verify favicon switches unread/highlight with counts.
  3. Android: install ntfy; verify push when app killed.
  4. Toggle notification settings; verify respect mute rules.

Automated

  • None

Known issues & gotchas

  • UnifiedPush user education string in backgroundSync.ts if no distributor
  • Multiple runtimes: isTauri, isElectron, isCapacitorNative branch logic
  • Pusher registration races on fast login/logout
  • Android small icon: ic_stat_paarrot must exist in Android resources
  • Background wake (MatrixSyncService) must filter by push rules / unread_notifications; a push for one room used to notify for every new message in the sync batch

Future work

  • iOS push strategy
  • Notification action buttons (reply, mark read)
  • Per-room notification channels on Android
  • Matrix push gateway docs (upstream)

Add your extra things here

  • Constants: PUSHER_APP_ID_BASE, PUSHER_STORAGE_PREFIX in backgroundSync.ts
  • Logo assets: paarrot.svg, paarrot-unread.svg, paarrot-highlight.svg in public/res/svg/
  • Android notify filter: mute / mentions / default-room behavior lives in MatrixSyncService.resolveRoomNotifyMode