| 1 | "use client"; |
| 2 | |
| 3 | import { useEffect } from "react"; |
| 4 | import { useQueryClient } from "@tanstack/react-query"; |
| 5 | import { toast } from "sonner"; |
| 6 | import { openDropStream } from "@/lib/sse"; |
| 7 | import { useUiStore } from "@/stores/ui"; |
| 8 | import { queryKeys } from "@/lib/query"; |
| 9 | |
| 10 | |
| 11 | export function useDropsStream() { |
| 12 | const pushDrop = useUiStore((s) => s.pushDrop); |
| 13 | const setStreamStatus = useUiStore((s) => s.setStreamStatus); |
| 14 | const qc = useQueryClient(); |
| 15 | |
| 16 | useEffect(() => { |
| 17 | if (typeof window !== "undefined" && "Notification" in window && Notification.permission === "default") { |
| 18 | void Notification.requestPermission().catch(() => undefined); |
| 19 | } |
| 20 | |
| 21 | const close = openDropStream({ |
| 22 | onStatus: (status) => setStreamStatus(status), |
| 23 | onDrop: (drop, name) => { |
| 24 | pushDrop(drop); |
| 25 | qc.invalidateQueries({ queryKey: queryKeys.stats }); |
| 26 | |
| 27 | if (name === "drop.new" || name === "drop.status") { |
| 28 | const title = drop.event.title; |
| 29 | toast(name === "drop.status" ? "On sale now" : "New drop", { |
| 30 | description: title, |
| 31 | }); |
| 32 | if (typeof window !== "undefined" && "Notification" in window && Notification.permission === "granted") { |
| 33 | try { |
| 34 | new Notification("DropHawk - " + (name === "drop.status" ? "On sale" : "New drop"), { |
| 35 | body: title, |
| 36 | tag: `drop-${drop.id}`, |
| 37 | }); |
| 38 | } catch { |
| 39 | } |
| 40 | } |
| 41 | } |
| 42 | }, |
| 43 | }); |
| 44 | |
| 45 | return close; |
| 46 | }, [pushDrop, setStreamStatus, qc]); |
| 47 | } |