diff --git a/src/app/features/settings/notifications/PushNotifications.tsx b/src/app/features/settings/notifications/PushNotifications.tsx index 7f510b444..6246cd92f 100644 --- a/src/app/features/settings/notifications/PushNotifications.tsx +++ b/src/app/features/settings/notifications/PushNotifications.tsx @@ -4,6 +4,10 @@ import type { ClientConfig } from '../../../hooks/useClientConfig'; const debugLog = createDebugLogger('PushNotifications'); +export function isPushSupported(): boolean { + return 'serviceWorker' in navigator && 'PushManager' in window; +} + type PushSubscriptionState = [ PushSubscriptionJSON | null, (subscription: PushSubscription | null) => void, @@ -32,12 +36,12 @@ export async function enablePushNotifications( clientConfig: ClientConfig, pushSubscriptionAtom: PushSubscriptionState ): Promise { - if (!('serviceWorker' in navigator) || !('PushManager' in window)) { + if (!isPushSupported()) { debugLog.error( 'notification', 'Push messaging not supported - missing serviceWorker or PushManager' ); - throw new Error('Push messaging is not supported in this browser.'); + return; } debugLog.info('notification', 'Enabling push notifications'); const [pushSubAtom, setPushSubscription] = pushSubscriptionAtom; @@ -178,6 +182,7 @@ export async function togglePusher( keepEnabledWhenVisible = false ): Promise { if (usePushNotifications) { + if (!isPushSupported()) return; if (visible && !keepEnabledWhenVisible) { await disablePushNotifications(mx, clientConfig, pushSubscriptionAtom); } else { diff --git a/src/app/features/settings/notifications/SystemNotification.tsx b/src/app/features/settings/notifications/SystemNotification.tsx index fafe0a793..5a785fd92 100644 --- a/src/app/features/settings/notifications/SystemNotification.tsx +++ b/src/app/features/settings/notifications/SystemNotification.tsx @@ -18,6 +18,7 @@ import { requestBrowserNotificationPermission, enablePushNotifications, disablePushNotifications, + isPushSupported, } from './PushNotifications'; import { DeregisterAllPushersSetting } from './DeregisterPushNotifications'; @@ -106,6 +107,8 @@ function WebPushNotificationSetting() { const pushSubAtom = useAtom(pushSubscriptionAtom); const browserPermission = usePermissionState('notifications', getNotificationState()); + + if (!isPushSupported()) return null; useEffect(() => { setIsLoading(false); }, []); diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 5efe57552..e8e372df3 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -251,7 +251,7 @@ export const defaultSettings: Settings = { // Push notifications (SW/Sygnal): default on for mobile, opt-in on desktop. // In-app pill banner: default on for mobile (primary foreground alert), opt-in on desktop. // System (OS) notifications: desktop-only; hidden and disabled on mobile. - usePushNotifications: mobileOrTablet(), + usePushNotifications: mobileOrTablet() && 'serviceWorker' in navigator && 'PushManager' in window, useInAppNotifications: mobileOrTablet(), useSystemNotifications: !mobileOrTablet(), isNotificationSounds: true,