Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 43 additions & 25 deletions src/libs/Notification/LocalNotification/BrowserNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import EXPENSIFY_ICON_URL from '@assets/images/expensify-logo-round-clearspace.p

import * as AppUpdate from '@libs/actions/AppUpdate';
import {translateLocal} from '@libs/Localize';
import Log from '@libs/Log';
import {getForReportAction} from '@libs/ModifiedExpenseMessage';
import NotificationPermission from '@libs/Notification/notificationPermission';
import {getTextFromHtml} from '@libs/ReportActionsUtils';
Expand Down Expand Up @@ -52,33 +53,50 @@ function push(
silent = false,
tag = '',
) {
canUseBrowserNotifications().then((canUseNotifications) => {
if (!canUseNotifications) {
return;
}
canUseBrowserNotifications()
.then((canUseNotifications) => {
if (!canUseNotifications) {
return;
}

// We cache these notifications so that we can clear them later
const notificationID = Str.guid();
notificationCache[notificationID] = new Notification(title, {
body,
icon: SafeString(icon),
data,
silent: true,
tag,
// Some browsers (e.g. Samsung Internet, Chrome on Android) forbid constructing a Notification in the page
// context and throw a "TypeError: Illegal constructor". Guard the construction so an unsupported browser
// degrades to "no local notification" instead of surfacing an unhandled promise rejection.
let notification: Notification;
try {
notification = new Notification(title, {
body,
icon: SafeString(icon),
data,
silent: true,
tag,
});
} catch (error) {
Log.hmmm('[BrowserNotifications] Failed to construct a Notification', {error});
return;
}

// We cache these notifications so that we can clear them later
const notificationID = Str.guid();
notificationCache[notificationID] = notification;
if (!silent) {
playSound(SOUNDS.RECEIVE);
}
notification.onclick = () => {
onClick();
window.parent.focus();
window.focus();
notification.close();
};
notification.onclose = () => {
delete notificationCache[notificationID];
};
})
.catch((error) => {
// Swallow any unexpected errors from the permission check or notification setup so they don't surface as
// unhandled promise rejections (the root cause of the reported crash).
Log.hmmm('[BrowserNotifications] Failed to push a local notification', {error});
});
if (!silent) {
playSound(SOUNDS.RECEIVE);
}
notificationCache[notificationID].onclick = () => {
onClick();
window.parent.focus();
window.focus();
notificationCache[notificationID].close();
};
notificationCache[notificationID].onclose = () => {
delete notificationCache[notificationID];
};
});
}

/**
Expand Down
Loading