diff --git a/frontend/src/components/Layout.jsx b/frontend/src/components/Layout.jsx index 8dbe916..6a7fdd9 100644 --- a/frontend/src/components/Layout.jsx +++ b/frontend/src/components/Layout.jsx @@ -1,5 +1,6 @@ import { Outlet, NavLink, Link, useLocation } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; +import { useRef, useEffect } from "react"; import { useAuth } from "../hooks/useAuth"; import SearchBar from "./SearchBar"; import { getDownloads, getChannels, getActiveTasks, getMe } from "../api"; @@ -259,6 +260,24 @@ function useNewVideosCount() { return channels.reduce((sum, c) => sum + (c.new_count ?? 0), 0); } +function useNewVideoNotifications(newCount) { + const location = useLocation(); + const prevCount = useRef(newCount); + + useEffect(() => { + const enabled = localStorage.getItem("notifications_enabled") === "true"; + if (!enabled) return; + if (Notification.permission !== "granted") return; + if (location.pathname === "/following") return; + if (newCount > 0 && newCount > prevCount.current) { + new Notification("New videos", { + body: `${newCount} new video${newCount !== 1 ? "s" : ""} from channels you follow`, + }); + } + prevCount.current = newCount; + }, [newCount, location.pathname]); +} + function useOffline() { const { isError, error } = useQuery({ queryKey: ["health"], @@ -274,6 +293,7 @@ export default function Layout() { const { user, logout } = useAuth(); const newCount = useNewVideosCount(); const offline = useOffline(); + useNewVideoNotifications(newCount); return (