10 Commits

Author SHA1 Message Date
Lemon 9d8a30f678 Add badge awards push notification template and pref key mapping 2026-03-28 00:13:21 -07:00
Lemon 2b0b99d598 Fix letters push toggle not propagating to nostr-push server 2026-03-28 00:07:28 -07:00
Lemon 7ade0eaeb1 Clean up notification follow-filter code: remove dead ref, fix filter typing 2026-03-27 23:58:31 -07:00
Lemon debdbf770b Respect 'only from people I follow' in web push notifications
Send authors: ['$contacts'] in the nostr-push subscription filter
when onlyFollowing is enabled. The nostr-push server resolves this
macro to the user's kind 3 follow list. Toggling the setting off
removes the authors filter so all notifications are delivered again.
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
Chad Curtis 230b4820bf fix: pre-fetch VAPID key on mount to avoid insecure-operation error
Browsers (especially Safari/Firefox) require pushManager.subscribe() to be
synchronously reachable from a user gesture. The previous code awaited a
getVapidKey() network call inside enable(), which broke the activation chain
and threw 'DOMException: The operation is insecure'.

Fix: fetch and cache the VAPID key during SW registration on mount so it is
ready in vapidKeyRef before the user ever clicks Enable, making
pushManager.subscribe() the first async call after the user gesture.
2026-03-17 08:48:45 -05:00
Lemon 547fcd91fe Refactor: clean up notification code for clarity
- useNativeNotifications: remove web push concerns entirely, this hook
  is now Capacitor-only. Web push lifecycle is fully managed by
  usePushNotifications + NotificationSettings.
- usePushNotifications: strip debug logging, tighten doc comments.
- nostrPush: strip debug logging.
- notificationTemplates: trim verbose block comment.
- NotificationSettings: reduce comment noise.
2026-03-16 19:05:45 -07:00
Lemon 587f0ff442 Fix enable() double-requesting permission and add push debug logging
- Remove redundant Notification.requestPermission() from enable() since
  the caller (NotificationSettings) already handles it from the user gesture.
  On iOS this second call could behave unexpectedly.
- Add console.debug logging throughout the enable flow and RPC send for
  diagnosing push registration issues in production.
2026-03-16 17:17:56 -07:00
Lemon 023f440054 Fix web push notifications: derive toggle from browser state, not NIP-78
- NotificationSettings: on web, drive the push toggle from the hook's
  enabled state (actual browser subscription) instead of the NIP-78
  notificationsEnabled setting which can be stale across devices.
  NIP-78 is still used for the Capacitor/Android path.

- useNativeNotifications: remove the web push auto-disable effect that
  raced against encrypted settings loading, causing disablePush() on
  every page load before settings resolved.

- usePushNotifications: remove REGISTERED_KEY localStorage check from
  the mount restore logic; derive enabled purely from
  pushManager.getSubscription() like the working Ghastly reference.
  Remove dead REGISTERED_KEY code entirely.
2026-03-16 16:57:31 -07:00
Lemon 8e8aed69c0 Add Web Push notifications via nostr-push
Replace the browser Notification constructor (tab-must-be-open) with nostr-push
Web Push notifications that work even when the browser is closed.

- Add service worker (public/sw.js) for receiving and displaying push events
- Add nostr-push RPC client (src/lib/nostrPush.ts) using an ephemeral device
  keypair for signing — the user's Nostr signer is never prompted
- Add usePushNotifications hook managing the full lifecycle: SW registration,
  VAPID key fetch, pushManager.subscribe, and nostr-push registration
- Replace the web path in useNativeNotifications with push registration that
  auto-enables/disables based on the notificationsEnabled encrypted setting
- Android native Capacitor path is unchanged
- Requires VITE_NOSTR_PUSH_PUBKEY env var (hex pubkey of the nostr-push server)
2026-03-16 00:17:05 -07:00