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).
30 lines
996 B
TypeScript
30 lines
996 B
TypeScript
import { useMemo } from 'react';
|
|
import { useLocalStorage } from '@/hooks/useLocalStorage';
|
|
import {
|
|
DEFAULT_NOTIFICATION_PREFS,
|
|
NOTIFICATION_PREFS_KEY,
|
|
type NotificationPrefs,
|
|
} from '@/lib/notificationPrefs';
|
|
|
|
/**
|
|
* Read/write the device-local notification preferences.
|
|
*
|
|
* Returns a memoized object (stable identity until the stored value changes) so
|
|
* callers can safely put it in effect dependency arrays — an object literal that
|
|
* is fresh every render would otherwise re-run those effects on every render.
|
|
* Missing keys fall back to the defaults, so adding a new category later does
|
|
* not leave existing users with `undefined`.
|
|
*/
|
|
export function useNotificationPrefs() {
|
|
const [stored, setPrefs] = useLocalStorage<NotificationPrefs>(
|
|
NOTIFICATION_PREFS_KEY,
|
|
DEFAULT_NOTIFICATION_PREFS,
|
|
);
|
|
|
|
const prefs = useMemo<NotificationPrefs>(
|
|
() => ({ ...DEFAULT_NOTIFICATION_PREFS, ...(stored ?? {}) }),
|
|
[stored],
|
|
);
|
|
|
|
return [prefs, setPrefs] as const;
|
|
}
|