Spaces:
Sleeping
Sleeping
| import { useEffect, useRef } from "react"; | |
| import { useChatStore } from "@/store/chatStore"; | |
| /** | |
| * useStreamingNotification — S-NOTIF | |
| * Browser Notification when streaming ends and tab is hidden. | |
| * No server/VAPID needed. Works: Android Chrome, iOS 16.4+ PWA, Desktop. | |
| */ | |
| export function useStreamingNotification(): void { | |
| const isStreaming = useChatStore(s => s.isStreaming); | |
| const prevRef = useRef(false); | |
| useEffect(() => { | |
| if (prevRef.current && !isStreaming) { | |
| if ( | |
| typeof Notification !== "undefined" && | |
| Notification.permission === "granted" && | |
| document.visibilityState !== "visible" | |
| ) { | |
| try { | |
| new Notification("Agente AI · Risposta pronta ✓", { | |
| body: "Tocca per leggere la risposta dell'agente.", | |
| icon: "/favicon.svg", | |
| tag: "agent-done", | |
| // @ts-expect-error renotify is non-standard but supported | |
| renotify: true, | |
| }); | |
| } catch { /* Safari older */ } | |
| } | |
| } | |
| prevRef.current = isStreaming; | |
| }, [isStreaming]); | |
| } | |
| export async function requestNotificationPermission(): Promise<NotificationPermission> { | |
| if (typeof Notification === "undefined") return "denied"; | |
| if (Notification.permission !== "default") return Notification.permission; | |
| return Notification.requestPermission(); | |
| } | |