Mirrors the activity the app already computes (bell, crews, DMs, newsletter)
to the OS notification shade, with no new relay traffic and no new network
destination.
- src/lib/osNotify.ts: one delivery API. Web uses the Notification API; native
uses @capacitor/local-notifications (lazily imported, so the web bundle never
pays for it). Tap-through navigates in-app.
- src/components/OsNotificationBridge.tsx: mounted once in Layout, inert until
opted in. Per-source silent priming + a seen-id set means history is never
replayed as a flood, and it stays quiet while the app is visible (the bell
already covers that).
- DMs notify from the gift-wrap ENVELOPE only (src/hooks/useDmEnvelopes.ts,
no decryption) — so Amber is never prompted just to be told you have a
message. Preview is honestly generic.
- src/lib/notificationPrefs.ts + useNotificationPrefs: device-local, opt-in,
default off, per-category toggles. Settings -> Notifications UI.
Deliberately local-only: a fully closed app needs a server push, which is not
built (Phase 2 = on-device background runner; Phase 3 = content-free FCM).
Admins (the two pubkeys in src/lib/admins.ts) can now moderate any event:
- Post authoritative Event Updates (incl. cancel/reschedule) on events they don't own,
clearly labelled "Admin" and marked with an ["admin","true"] tag
- Take down any event (already wired via DeleteEntityDialog + isAdminPubkey)
SECURITY FIX: kind-7103 Event Updates are now only trusted from the event's host
(pubkey in the `a` coordinate) or a SkateSpots admin. Previously ANY npub could
publish a fake "CANCELLED" update — spoofing the detail-page banner and spamming
RSVPers' notification bells. Enforced in both parseEventUpdate() and
useActivityNotifications.
Note: admins intentionally CANNOT open the edit form on others' events — an
addressable event (31923) can only be replaced by the key that signed it; editing
under a different key would fork it, not edit it. Moderation is done via
authoritative updates + takedown instead.
Docs: NIP.md updated with the host/admin trust rule and the admin marker tag.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- AttendeeList: tabbed Going/Interested with faces + names + a "who you trust"
signal (reuses batch trust scores); replaces the plain avatar stack
- Event Updates (kind 7103): usePostEventUpdate + useEventUpdates; host-only
composer with update/reschedule/relocation/cancelled categories that p-tags
every RSVPer so they get notified; public feed on the event page
- EditEventPage: auto-post a reschedule/relocation update to notify attendees
when the host changes time or location
- Activity bell: new 'event-update' notification type for RSVPers
- EventsPage: "Hosting" tab (logged-in) with a HostingDashboard listing the
user's upcoming/past events, live RSVP counts, and quick edit/update actions
- Document Event Update kind 7103 in NIP.md
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
- New useActivityNotifications: single combined #p query classifies reactions,
reposts, zaps, mentions and replies referencing the user; parses zap sats
- New useNotificationsRead: per-account last-read timestamp for unread badge
- New ActivityNotificationCard: actor avatar + type badge, verb, snippet, links
to the actor's profile
- Rewrite NotificationBell into a tabbed activity center (All / Social / Crews)
with unread tracking, mark-all-read, and the existing crew invites/requests
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>