diff --git a/src/app/features/settings/notifications/Notifications.tsx b/src/app/features/settings/notifications/Notifications.tsx index 230d60a32..b7af48545 100644 --- a/src/app/features/settings/notifications/Notifications.tsx +++ b/src/app/features/settings/notifications/Notifications.tsx @@ -6,17 +6,14 @@ import { SequenceCardStyle } from '../styles.css'; import { SettingTile } from '../../../components/setting-tile'; import { useSetting } from '../../../state/hooks/settings'; import { settingsAtom } from '../../../state/settings'; -import { usePermissionState } from '../../../hooks/usePermission'; +import { getNotificationState, usePermissionState } from '../../../hooks/usePermission'; import { AllMessagesNotifications } from './AllMessages'; import { SpecialMessagesNotifications } from './SpecialMessages'; import { KeywordMessagesNotifications } from './KeywordMessages'; import { IgnoredUserList } from './IgnoredUserList'; function SystemNotification() { - const notifPermission = usePermissionState( - 'notifications', - window.Notification.permission === 'default' ? 'prompt' : window.Notification.permission - ); + const notifPermission = usePermissionState('notifications', getNotificationState()); const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications'); const [isNotificationSounds, setIsNotificationSounds] = useSetting( settingsAtom, @@ -41,8 +38,9 @@ function SystemNotification() { description={ notifPermission === 'denied' ? ( - Notification permission is blocked. Please allow notification permission from - browser address bar. + {!Notification + ? 'Notifications are not supported by the system.' + : 'Notification permission is blocked. Please allow notification permission from browser address bar.'} ) : ( Show desktop notifications when message arrive. diff --git a/src/app/hooks/usePermission.ts b/src/app/hooks/usePermission.ts index 5a3ec9f6b..cc063966b 100644 --- a/src/app/hooks/usePermission.ts +++ b/src/app/hooks/usePermission.ts @@ -1,4 +1,16 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState } from 'react'; + +export const getNotificationState = (): PermissionState => { + if (!Notification) { + return 'denied'; + } + + if (Notification.permission === 'default') { + return 'prompt'; + } + + return Notification.permission; +}; export function usePermissionState(name: PermissionName, initialValue: PermissionState = 'prompt') { const [permissionState, setPermissionState] = useState(initialValue); @@ -15,16 +27,16 @@ export function usePermissionState(name: PermissionName, initialValue: Permissio .then((permStatus: PermissionStatus) => { permissionStatus = permStatus; handlePermissionChange.apply(permStatus); - permStatus.addEventListener("change", handlePermissionChange); + permStatus.addEventListener('change', handlePermissionChange); }) .catch(() => { // Silence error since FF doesn't support microphone permission }); return () => { - permissionStatus?.removeEventListener("change", handlePermissionChange); + permissionStatus?.removeEventListener('change', handlePermissionChange); }; }, [name]); return permissionState; -} \ No newline at end of file +} diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 8678e6194..ce952bfc6 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -8,7 +8,7 @@ import LogoUnreadSVG from '../../../../public/res/svg/cinny-unread.svg'; import LogoHighlightSVG from '../../../../public/res/svg/cinny-highlight.svg'; import NotificationSound from '../../../../public/sound/notification.ogg'; import InviteSound from '../../../../public/sound/invite.ogg'; -import { setFavicon } from '../../utils/dom'; +import { notificationPermission, setFavicon } from '../../utils/dom'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; import { allInvitesAtom } from '../../state/room-list/inviteList'; @@ -110,7 +110,7 @@ function InviteNotifications() { useEffect(() => { if (invites.length > perviousInviteLen && mx.getSyncState() === 'SYNCING') { - if (showNotifications && Notification.permission === 'granted') { + if (showNotifications && notificationPermission('granted')) { notify(invites.length - perviousInviteLen); } @@ -212,7 +212,7 @@ function MessageNotifications() { return; } - if (showNotifications && Notification.permission === 'granted') { + if (showNotifications && notificationPermission('granted')) { const avatarMxc = room.getAvatarFallbackMember()?.getMxcAvatarUrl() ?? room.getMxcAvatarUrl(); notify({ diff --git a/src/app/utils/dom.ts b/src/app/utils/dom.ts index f931ac453..416cd1d8d 100644 --- a/src/app/utils/dom.ts +++ b/src/app/utils/dom.ts @@ -217,3 +217,10 @@ export const syntaxErrorPosition = (error: SyntaxError): number | undefined => { if (Number.isNaN(position)) return undefined; return position; }; + +export const notificationPermission = (permission: NotificationPermission) => { + if (Notification) { + return Notification.permission === permission; + } + return false; +};