Files
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

96 lines
3.4 KiB
Markdown

# 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
## Related docs
- 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`