feat: add webpush and sadhna tracker
This commit is contained in:
@@ -27,6 +27,7 @@ import {
|
||||
import { toast } from "sonner";
|
||||
import { useAuth } from "@/components/auth/auth-provider";
|
||||
import { notifications } from "@/lib/social";
|
||||
import { sadhna } from "@/lib/sadhna";
|
||||
|
||||
type NotificationsContextValue = {
|
||||
/** Live unread count for the header bell. */
|
||||
@@ -86,13 +87,26 @@ export function NotificationsProvider({
|
||||
// Seed the count whenever the signed-in user changes (async — no
|
||||
// synchronous setState in the effect body).
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
if (!user?.id) return;
|
||||
refreshUnread();
|
||||
}, [user?.id, refreshUnread]);
|
||||
|
||||
// Open the realtime connection while signed in.
|
||||
// Report the browser's timezone (once per signed-in session) so sādhana
|
||||
// reminders fire at the user's local clock time. Best-effort.
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
if (!user?.id) return;
|
||||
try {
|
||||
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
if (tz) void sadhna.setTimezone(tz).catch(() => {});
|
||||
} catch {
|
||||
/* Intl unavailable — leave the server default (UTC) */
|
||||
}
|
||||
}, [user?.id]);
|
||||
|
||||
// Open the realtime connection while signed in.
|
||||
const userId = user?.id;
|
||||
useEffect(() => {
|
||||
if (!userId) return;
|
||||
const key = process.env.NEXT_PUBLIC_SOKETI_KEY;
|
||||
const host = process.env.NEXT_PUBLIC_SOKETI_HOST;
|
||||
if (!key || !host) return; // realtime not configured
|
||||
@@ -100,7 +114,7 @@ export function NotificationsProvider({
|
||||
const port = Number(process.env.NEXT_PUBLIC_SOKETI_PORT || "443");
|
||||
const forceTLS =
|
||||
(process.env.NEXT_PUBLIC_SOKETI_FORCE_TLS ?? "true") !== "false";
|
||||
const channelName = `notifications.${user.id}`;
|
||||
const channelName = `notifications.${userId}`;
|
||||
|
||||
let cancelled = false;
|
||||
// Dynamic import keeps pusher-js out of SSR (it touches window) and the
|
||||
@@ -124,6 +138,16 @@ export function NotificationsProvider({
|
||||
setLastEventAt(Date.now());
|
||||
toast(messageFor(data ?? {}), { duration: 4000 });
|
||||
});
|
||||
// Sādhana reminders are ephemeral nudges — toast only, no unread bump
|
||||
// (they aren't persisted to the notification center).
|
||||
channel.bind(
|
||||
"reminder",
|
||||
(data: { title?: string; body?: string }) => {
|
||||
toast(data?.body || data?.title || "A gentle reminder", {
|
||||
duration: 6000,
|
||||
});
|
||||
},
|
||||
);
|
||||
cleanup = () => {
|
||||
channel.unbind_all();
|
||||
pusher.unsubscribe(channelName);
|
||||
@@ -135,7 +159,7 @@ export function NotificationsProvider({
|
||||
cancelled = true;
|
||||
cleanup?.();
|
||||
};
|
||||
}, [user?.id]);
|
||||
}, [userId]);
|
||||
|
||||
return (
|
||||
<NotificationsContext.Provider
|
||||
|
||||
Reference in New Issue
Block a user