From eb3d0ddfb6403d9cd948a58fc040288f59c9b60d Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:50:03 -0500 Subject: [PATCH] notification fixes the pubkey was not being returned if notifications was not enabled at the global level --- frigate/api/notification.py | 7 +- .../settings/NotificationsSettingsView.tsx | 94 ++++++++++--------- 2 files changed, 55 insertions(+), 46 deletions(-) diff --git a/frigate/api/notification.py b/frigate/api/notification.py index 7858ec1a7..96ba96fdc 100644 --- a/frigate/api/notification.py +++ b/frigate/api/notification.py @@ -21,7 +21,12 @@ router = APIRouter(tags=[Tags.notifications]) @router.get("/notifications/pubkey") def get_vapid_pub_key(request: Request): - if not request.app.frigate_config.notifications.enabled: + config = request.app.frigate_config + notifications_enabled = config.notifications.enabled + camera_notifications_enabled = [ + c for c in config.cameras.values() if c.enabled and c.notifications.enabled + ] + if not (notifications_enabled or camera_notifications_enabled): return JSONResponse( content=({"success": False, "message": "Notifications are not enabled."}), status_code=400, diff --git a/web/src/views/settings/NotificationsSettingsView.tsx b/web/src/views/settings/NotificationsSettingsView.tsx index 36213fc0e..52a02af5a 100644 --- a/web/src/views/settings/NotificationsSettingsView.tsx +++ b/web/src/views/settings/NotificationsSettingsView.tsx @@ -118,50 +118,6 @@ export default function NotificationView({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [changedValue]); - // notification key handling - - const { data: publicKey } = useSWR( - config?.notifications?.enabled ? "notifications/pubkey" : null, - { revalidateOnFocus: false }, - ); - - const subscribeToNotifications = useCallback( - (registration: ServiceWorkerRegistration) => { - if (registration) { - addMessage( - "notification_settings", - t("notification.unsavedRegistrations"), - undefined, - "registration", - ); - - registration.pushManager - .subscribe({ - userVisibleOnly: true, - applicationServerKey: publicKey, - }) - .then((pushSubscription) => { - axios - .post("notifications/register", { - sub: pushSubscription, - }) - .catch(() => { - toast.error(t("notification.toast.error.registerFailed"), { - position: "top-center", - }); - pushSubscription.unsubscribe(); - registration.unregister(); - setRegistration(null); - }); - toast.success(t("notification.toast.success.registered"), { - position: "top-center", - }); - }); - } - }, - [publicKey, addMessage, t], - ); - // notification state const [registration, setRegistration] = @@ -206,7 +162,55 @@ export default function NotificationView({ }, }); - const watchCameras = form.watch("cameras"); + const watchAllEnabled = form.watch("allEnabled"); + const watchCameras = useMemo(() => form.watch("cameras") || [], [form]); + + const { data: publicKey } = useSWR( + config && + (config.notifications?.enabled || + watchAllEnabled || + (Array.isArray(watchCameras) && watchCameras.length > 0)) + ? "notifications/pubkey" + : null, + { revalidateOnFocus: false }, + ); + + const subscribeToNotifications = useCallback( + (registration: ServiceWorkerRegistration) => { + if (registration) { + addMessage( + "notification_settings", + t("notification.unsavedRegistrations"), + undefined, + "registration", + ); + + registration.pushManager + .subscribe({ + userVisibleOnly: true, + applicationServerKey: publicKey, + }) + .then((pushSubscription) => { + axios + .post("notifications/register", { + sub: pushSubscription, + }) + .catch(() => { + toast.error(t("notification.toast.error.registerFailed"), { + position: "top-center", + }); + pushSubscription.unsubscribe(); + registration.unregister(); + setRegistration(null); + }); + toast.success(t("notification.toast.success.registered"), { + position: "top-center", + }); + }); + } + }, + [publicKey, addMessage, t], + ); useEffect(() => { if (watchCameras.length > 0) {