- Extract zap amount from kind 9735 events in NostrPoller.java (checks
amount tag then falls back to description tag's zap request)
- Format amounts compactly (e.g. 1.5K sats, 2M sats)
- Set data URI on notification PendingIntent so tapping opens /notifications
- Handle deep link intent in MainActivity (both onCreate and onNewIntent)
- Remove dead localNotificationActionPerformed listener from TypeScript
(only fired for Capacitor-API notifications, not natively posted ones)
The notification service was holding a PARTIAL_WAKE_LOCK indefinitely,
preventing the CPU from ever sleeping. Combined with OkHttp's 30-second
ping interval, this caused continuous CPU wake-ups — worse than the
previous polling approach.
Changes:
- Remove permanent WakeLock that kept CPU running 24/7
- Disable OkHttp's 30s ping interval (useless without WakeLock in Doze)
- Add AlarmManager keepalive using setAndAllowWhileIdle() every ~8 min
- Acquire brief WakeLock (15s timeout) only during keepalive checks
- Track connection liveness via relay message timestamps
- Reconnect automatically when Doze kills the TCP connection
- Missed events are recovered via the existing 'since' timestamp
Expected improvement: ~3 brief wake-ups/hour vs continuous CPU usage.
Notifications may be delayed up to ~8 min in deep sleep.
Android 12+ crashes the app if startForeground() isn't called within 5
seconds of startForegroundService(). Moved it from onStartCommand() to
the top of onCreate() to ensure the foreground notification is posted
before any other initialization.
Replaces the AlarmManager-based polling (wake every 60s, open/close WebSocket
connections) with a persistent WebSocket subscription to a Nostr relay. Events
are delivered in real-time via the open connection. A partial WakeLock keeps
the connection alive through Doze mode (same approach as Signal without FCM).
- Add NotificationRelayService: foreground service with persistent WebSocket,
exponential backoff reconnection, network-aware reconnect, relay rotation
on failure, and SharedPreferences config listener
- Refactor NostrPoller into notification dispatcher with metadata caching
(SharedPreferences-based, avoids redundant WebSocket connections for
repeat authors)
- Remove NotificationService (AlarmManager scheduler) and PollAlarmReceiver
(WakeLock-based polling)
- Remove SCHEDULE_EXACT_ALARM permission (no longer needed)
- Disable web-layer background refetch on native (persistent connection
handles it)
Replace JS WebView-based polling with pure native implementation:
- NostrPoller: Java WebSocket client that queries Nostr relays directly via OkHttp
- PollAlarmReceiver: AlarmManager fires every 60s, acquires WakeLock, runs native poll
- NotificationService: foreground service keeps process alive, schedules alarms
- MewNotificationPlugin: Capacitor plugin passes pubkey/relays from JS to SharedPreferences
- Remove notificationService.ts (all polling logic now in Java)
- Simplify useNativeNotifications to only configure native service + handle permissions
- Implement Signal-like local-only notifications via direct WebSocket relay polling
- Poll every 60s foreground, 15min background, no external push server
- Resolve NIP-05 display names for notification body (e.g. 'alice@nostr.com reacted to your post')
- Add Capacitor LocalNotifications plugin with POST_NOTIFICATIONS permission
- Replace default Capacitor splash with Mew logo PNG on dark background using Android 12 Theme.SplashScreen
- Add ic_stat_mew vector drawable for notification small icon
- Regenerate splash PNGs with #14161f background
- Change STICKY_HEADER_CLASS to use 'top-mobile-bar sidebar:top-0'
- Matches the pattern used in Feed and NotificationsPage
- On mobile: sticky tabs position below the MobileTopBar (accounting for safe area)
- On desktop: sticky tabs position at top-0 (no top bar on desktop)
- Fixes issue where safe-area-top created unwanted space above tabs
- Update STICKY_HEADER_CLASS constant to include safe-area-top
- Fixes sticky tabs in Search and Settings pages on mobile
- Ensures sticky headers respect device notches and status bars
- Feed and NotificationsPage already use top-mobile-bar which includes safe area
- Created QuickReactMenu component with horizontal emoji bar
- Quick access to 6 common emojis (❤️, 😂, 💯, 🔥, 👍, 📌)
- "..." button opens full EmojiPicker for more options
- Updated ReactionButton to use QuickReactMenu instead of full picker
- Matches Ditto UX: click shows quick react menu, ... reveals full picker
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- Change icon background from white (#ffffff) to dark theme (#14161f)
- Update capacitor.config.ts backgroundColor to match
- Update generate-icons.sh to use dark theme color
- Regenerate all Android icons with new background
- Prevents white-on-white icon appearance