Add browser notification support for new videos

- Settings: Notifications section with toggle that requests browser permission
  and stores preference in localStorage
- Layout: fires a Notification when new_count increases and user isn't on /following
- Works whenever the tab is open (foreground or background)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 23:56:22 +02:00
parent 8029b2517f
commit 65bc199366
2 changed files with 79 additions and 0 deletions

View File

@@ -600,6 +600,62 @@ function OAuth2Section({ s, qc }) {
);
}
function NotificationsSection() {
const [permission, setPermission] = useState(() =>
"Notification" in window ? Notification.permission : "unsupported"
);
const [enabled, setEnabled] = useState(() => localStorage.getItem("notifications_enabled") === "true");
const requestPermission = async () => {
if (!("Notification" in window)) return;
const result = await Notification.requestPermission();
setPermission(result);
if (result === "granted") {
setEnabled(true);
localStorage.setItem("notifications_enabled", "true");
new Notification("YTContinue notifications on", {
body: "You'll be notified when new videos arrive from channels you follow.",
});
}
};
const toggle = () => {
if (permission !== "granted") {
requestPermission();
return;
}
const next = !enabled;
setEnabled(next);
localStorage.setItem("notifications_enabled", next ? "true" : "false");
};
if (permission === "unsupported") return null;
return (
<Section title="Notifications">
<Row
label="New video alerts"
hint={
permission === "denied"
? "Blocked by browser allow notifications for this site in browser settings"
: "Get a browser notification when followed channels upload new videos"
}
>
{permission === "denied" ? (
<span className="text-xs text-zinc-600">Blocked</span>
) : (
<button
onClick={toggle}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${enabled && permission === "granted" ? "bg-accent" : "bg-zinc-700"}`}
>
<span className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${enabled && permission === "granted" ? "translate-x-6" : "translate-x-1"}`} />
</button>
)}
</Row>
</Section>
);
}
export default function SettingsPage() {
const { user } = useAuth();
const qc = useQueryClient();
@@ -823,6 +879,9 @@ export default function SettingsPage() {
</Row>
</Section>
{/* Notifications */}
<NotificationsSection />
{/* Data */}
<Section title="Data">
<div className="px-5 py-4 flex items-center justify-between">