Commit Graph

17 Commits

Author SHA1 Message Date
Alex Gleason dc81585f9a Pre-fetch all nsite blobs on Android before WebView navigates
Android's shouldInterceptRequest blocks a pool of ~6 IO threads, each
waiting for JS to respond via the Capacitor bridge. With 200+ files
each requiring a network round-trip to Blossom, loading is painfully
slow. iOS doesn't have this problem — WKURLSchemeHandler is async.

Split the native plugin lifecycle into create() and navigate():
- create() adds the WebView container with spinner overlay (visible)
- navigate() loads the entry URL (triggers fetch interception)

On Android, onReady downloads all manifest blobs in parallel (12
concurrent fetches) into an in-memory cache while the native
ProgressBar spinner animates. Once navigate() fires, every resolveFile
call is an instant cache hit.

On iOS/web, onReady is a no-op and navigate() fires immediately.
2026-04-11 17:20:21 -05:00
Alex Gleason dceda199c3 Add loading spinners to native sandbox WebViews
iOS: load inline spinner HTML (centered spinning ring on dark background)
before navigating to the real content URL. Supports light/dark mode via
prefers-color-scheme. The spinner is replaced when the real page loads.

Android: use a native ProgressBar overlay instead of HTML — the HTML
spinner froze because constant Capacitor bridge calls saturated the
main thread, starving the WebView compositor. The native ProgressBar
animates on the render thread independently. Wrapped in a FrameLayout
with a dark overlay behind the spinner.

Both platforms: set WebView background to #14161f (app dark theme)
instead of white. Increased Android shouldInterceptRequest timeout
from 10s to 60s to prevent premature timeouts on large nsites.
2026-04-11 17:20:01 -05:00
Alex Gleason e482afbd3f Fix sandbox origin isolation and Android build issues 2026-04-08 20:47:42 -05:00
Alex Gleason f25139103c Add native SandboxPlugin for iOS and Android 2026-04-08 20:47:28 -05:00
Chad Curtis 3ee491a63b Add push vs persistent notification delivery option for Android
Default to push mode (no foreground service). Persistent mode with
the always-on background polling service is opt-in via the new
Delivery Method section in notification settings.

- Add notificationStyle ('push' | 'persistent') to EncryptedSettings
- Show radio group in NotificationSettings on native platforms
- Pass notificationStyle through Capacitor plugin to SharedPreferences
- DittoNotificationPlugin starts/stops foreground service on style change
- MainActivity only starts service on launch when style is persistent
- Re-enable unread polling on native when push mode is active
2026-04-07 10:54:30 -05:00
Lemon a1ef06510e Remove stale DEFAULT_KINDS fallback, skip polling until JS configures kinds 2026-03-28 00:20:21 -07:00
Lemon bac5d71480 Respect 'only from people I follow' in native Android notifications
Pass followed pubkeys through the Capacitor plugin to the native
polling service. When onlyFollowing is enabled, the relay query
includes an authors filter so only events from followed accounts
trigger native Android notifications.
2026-03-27 23:58:31 -07:00
Lemon 0ad655d1cf Fix notification preferences not filtering push notifications or unread dot
Disabled notification types (e.g. reactions) still triggered push
notifications and showed the unread dot indicator, even though the
notification tab correctly filtered them out.

Three root causes fixed:
- useHasUnreadNotifications now uses getEnabledNotificationKinds to
  only query for enabled types, preventing phantom unread dots
- NotificationSettings now syncs type preference changes to the
  nostr-push server via updateSubscription (is_active toggle)
- Native Android poller now receives enabled kinds from the JS layer
  and uses them in the relay filter instead of hardcoded kinds
2026-03-27 23:58:31 -07:00
Mary Kate Fain f82adab05d Fix: add letter (kind 8211) notifications
Letters were completely absent from the notification pipeline — users had
to visit the Letters page to discover incoming letters. This integrates
kind 8211 into every layer of the notification system:

- useNotifications: query, grouping, and referenced-event exclusion
- useHasUnreadNotifications: unread dot indicator
- NotificationsPage: LetterNotification component with link to /letters
- NotificationSettings: toggleable Letters row
- notificationTemplates: web push template
- Android NotificationRelayService + NostrPoller: native push support
- EncryptedSettings + schema: letters preference field

Closes #188
2026-03-27 14:15:50 -05:00
Chad Curtis 39fee6aa5d Filter notifications for reactions/reposts/zaps on posts user didn't author 2026-03-18 05:36:10 -05:00
Chad Curtis 67fc5f3fb2 Fix NPE crash in NotificationRelayService.onDestroy when httpClient is null
When onCreate() catches ForegroundServiceStartNotAllowedException and calls
stopSelf() early, httpClient is never initialized. onDestroy() still runs and
was crashing with a NullPointerException on httpClient.dispatcher().
2026-03-18 05:17:36 -05:00
Chad Curtis 341d9764b4 Fix crash: catch ForegroundServiceStartNotAllowedException in notification service
Android 16 (targetSdk 36) enforces strict time limits on dataSync
foreground services. When the limit is exhausted, calling startForeground()
or startForegroundService() throws ForegroundServiceStartNotAllowedException
and kills the app. Catch the exception in both NotificationRelayService.onCreate()
and MainActivity.onCreate() so the app continues running; the AlarmManager
will reschedule the next fetch cycle at the normal interval.
2026-03-16 01:42:50 -05:00
Chad Curtis 53eb0f37e9 Add kind 1111 to Android native notification service
- Add kind 1111 to the Nostr REQ filter in NotificationRelayService
- Add case 1111 to kindToAction() in NostrPoller with the same context-aware
  label logic: 'replied to your comment' when k=1111, 'commented on your post' otherwise
2026-03-07 02:01:59 -06:00
Chad Curtis fb9064cb0e Add pull-to-refresh to notifications; simplify Android notifications to use 'Someone' instead of fetching kind 0 metadata 2026-02-26 18:06:53 -06:00
Chad Curtis c8e92644d8 Fix spurious JSONException catch in EOSE handler 2026-02-24 01:49:26 -06:00
Chad Curtis 49d6166b99 Rewrite notification service: connect-fetch-disconnect per cycle, limit 5 events, adaptive interval 2026-02-24 01:18:11 -06:00
Alex Gleason 1f035f4a6e Rename Mew to Ditto across entire codebase
- Update all branding: titles, meta tags, OG tags, manifest
- Rename MewLogo component to DittoLogo
- Update Capacitor config: appId to pub.ditto.app, hostname to ditto.pub
- Migrate Android Java package from com.mew.app to pub.ditto.app
- Rename MewNotificationPlugin to DittoNotificationPlugin
- Update all localStorage keys from mew: to ditto: prefix
- Update Nostr encrypted settings d-tag from mew-metadata to ditto-metadata
- Update all page titles, zap comments, and UI strings
- Rename ic_stat_mew.xml drawable to ic_stat_ditto.xml
- Update build script references (mew.apk -> ditto.apk)
- Update all domain references (mew.shakespeare.wtf -> ditto.pub)
2026-02-23 11:50:00 -06:00