fix notification crash on ios (#2192)

* fix notification crash for ios

* access notification from window variable

* fix Notification check

* catch notification variable error

* fix missing check for Notification
This commit is contained in:
Ajay Bura 2025-02-10 21:02:33 +11:00 committed by GitHub
parent 5460e4922b
commit b12228ee95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 31 additions and 14 deletions

View file

@ -6,17 +6,14 @@ import { SequenceCardStyle } from '../styles.css';
import { SettingTile } from '../../../components/setting-tile'; import { SettingTile } from '../../../components/setting-tile';
import { useSetting } from '../../../state/hooks/settings'; import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings'; import { settingsAtom } from '../../../state/settings';
import { usePermissionState } from '../../../hooks/usePermission'; import { getNotificationState, usePermissionState } from '../../../hooks/usePermission';
import { AllMessagesNotifications } from './AllMessages'; import { AllMessagesNotifications } from './AllMessages';
import { SpecialMessagesNotifications } from './SpecialMessages'; import { SpecialMessagesNotifications } from './SpecialMessages';
import { KeywordMessagesNotifications } from './KeywordMessages'; import { KeywordMessagesNotifications } from './KeywordMessages';
import { IgnoredUserList } from './IgnoredUserList'; import { IgnoredUserList } from './IgnoredUserList';
function SystemNotification() { function SystemNotification() {
const notifPermission = usePermissionState( const notifPermission = usePermissionState('notifications', getNotificationState());
'notifications',
window.Notification.permission === 'default' ? 'prompt' : window.Notification.permission
);
const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications'); const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications');
const [isNotificationSounds, setIsNotificationSounds] = useSetting( const [isNotificationSounds, setIsNotificationSounds] = useSetting(
settingsAtom, settingsAtom,
@ -41,8 +38,9 @@ function SystemNotification() {
description={ description={
notifPermission === 'denied' ? ( notifPermission === 'denied' ? (
<Text as="span" style={{ color: color.Critical.Main }} size="T200"> <Text as="span" style={{ color: color.Critical.Main }} size="T200">
Notification permission is blocked. Please allow notification permission from {'Notification' in window
browser address bar. ? 'Notification permission is blocked. Please allow notification permission from browser address bar.'
: 'Notifications are not supported by the system.'}
</Text> </Text>
) : ( ) : (
<span>Show desktop notifications when message arrive.</span> <span>Show desktop notifications when message arrive.</span>

View file

@ -1,4 +1,16 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from 'react';
export const getNotificationState = (): PermissionState => {
if ('Notification' in window) {
if (window.Notification.permission === 'default') {
return 'prompt';
}
return window.Notification.permission;
}
return 'denied';
};
export function usePermissionState(name: PermissionName, initialValue: PermissionState = 'prompt') { export function usePermissionState(name: PermissionName, initialValue: PermissionState = 'prompt') {
const [permissionState, setPermissionState] = useState<PermissionState>(initialValue); const [permissionState, setPermissionState] = useState<PermissionState>(initialValue);
@ -15,14 +27,14 @@ export function usePermissionState(name: PermissionName, initialValue: Permissio
.then((permStatus: PermissionStatus) => { .then((permStatus: PermissionStatus) => {
permissionStatus = permStatus; permissionStatus = permStatus;
handlePermissionChange.apply(permStatus); handlePermissionChange.apply(permStatus);
permStatus.addEventListener("change", handlePermissionChange); permStatus.addEventListener('change', handlePermissionChange);
}) })
.catch(() => { .catch(() => {
// Silence error since FF doesn't support microphone permission // Silence error since FF doesn't support microphone permission
}); });
return () => { return () => {
permissionStatus?.removeEventListener("change", handlePermissionChange); permissionStatus?.removeEventListener('change', handlePermissionChange);
}; };
}, [name]); }, [name]);

View file

@ -8,7 +8,7 @@ import LogoUnreadSVG from '../../../../public/res/svg/cinny-unread.svg';
import LogoHighlightSVG from '../../../../public/res/svg/cinny-highlight.svg'; import LogoHighlightSVG from '../../../../public/res/svg/cinny-highlight.svg';
import NotificationSound from '../../../../public/sound/notification.ogg'; import NotificationSound from '../../../../public/sound/notification.ogg';
import InviteSound from '../../../../public/sound/invite.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 { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings'; import { settingsAtom } from '../../state/settings';
import { allInvitesAtom } from '../../state/room-list/inviteList'; import { allInvitesAtom } from '../../state/room-list/inviteList';
@ -110,7 +110,7 @@ function InviteNotifications() {
useEffect(() => { useEffect(() => {
if (invites.length > perviousInviteLen && mx.getSyncState() === 'SYNCING') { if (invites.length > perviousInviteLen && mx.getSyncState() === 'SYNCING') {
if (showNotifications && Notification.permission === 'granted') { if (showNotifications && notificationPermission('granted')) {
notify(invites.length - perviousInviteLen); notify(invites.length - perviousInviteLen);
} }
@ -212,7 +212,7 @@ function MessageNotifications() {
return; return;
} }
if (showNotifications && Notification.permission === 'granted') { if (showNotifications && notificationPermission('granted')) {
const avatarMxc = const avatarMxc =
room.getAvatarFallbackMember()?.getMxcAvatarUrl() ?? room.getMxcAvatarUrl(); room.getAvatarFallbackMember()?.getMxcAvatarUrl() ?? room.getMxcAvatarUrl();
notify({ notify({

View file

@ -217,3 +217,10 @@ export const syntaxErrorPosition = (error: SyntaxError): number | undefined => {
if (Number.isNaN(position)) return undefined; if (Number.isNaN(position)) return undefined;
return position; return position;
}; };
export const notificationPermission = (permission: NotificationPermission) => {
if ('Notification' in window) {
return window.Notification.permission === permission;
}
return false;
};