Merge branch 'IDTEAM-1.26.0' into 'main'
[ProtonMail-WebClient.git] / packages / shared / lib / helpers / desktopNotification.ts
blob868093e1028e0a85c54a5ba14a455285b7e5d47b
1 import noop from '@proton/utils/noop';
3 import type { ElectronNotification } from '../desktop/desktopTypes';
4 import { invokeInboxDesktopIPC } from '../desktop/ipcHelpers';
6 export enum Status {
7     DENIED = 'denied',
8     DEFAULT = 'default',
9     GRANTED = 'granted',
12 let notifications: Notification[] = [];
14 export const hasNotificationSupport = (): boolean => 'Notification' in window;
15 export const hasPermission = (): boolean => Notification.permission === Status.GRANTED;
16 export const hasDenied = (): boolean => Notification.permission === Status.DENIED;
18 const addNotification = (notification: Notification) => {
19     notifications.push(notification);
22 const removeNotification = (notification: Notification) => {
23     notifications = notifications.filter((n) => n !== notification);
26 const setupNotificationHandlers = (notification: Notification, onClick?: () => void) => {
27     notification.onclose = () => removeNotification(notification);
28     notification.onclick = () => {
29         onClick?.();
30         notification.close();
31     };
34 export const getStatus = (): Status => {
35     if (!hasNotificationSupport()) {
36         return Status.DEFAULT;
37     }
39     if (hasPermission()) {
40         return Status.GRANTED;
41     }
43     if (hasDenied()) {
44         return Status.DENIED;
45     }
47     return Status.DEFAULT;
50 export const isEnabled = (): boolean => {
51     if (hasNotificationSupport()) {
52         return hasPermission();
53     }
54     return false;
57 export const clear = () => {
58     notifications.forEach((notification) => notification.close());
59     notifications = [];
62 export const request = async (onGranted: () => void = noop, onDenied: () => void = noop) => {
63     if (!hasNotificationSupport() || hasDenied()) {
64         onDenied();
65         return;
66     }
68     if (hasPermission()) {
69         onGranted();
70         return;
71     }
73     const permission = await Notification.requestPermission();
75     if (permission === Status.GRANTED) {
76         onGranted();
77     } else {
78         onDenied();
79     }
82 const createWebNotification = (title: string, options?: NotificationOptions, onClick?: () => void) => {
83     if (!isEnabled()) {
84         return;
85     }
87     const notification = new Notification(title, options);
89     addNotification(notification);
91     setupNotificationHandlers(notification, onClick);
93     return notification;
96 export const createElectronNotification = (payload: ElectronNotification) => {
97     return invokeInboxDesktopIPC({ type: 'showNotification', payload });
100 interface NotificationParams extends NotificationOptions {
101     onClick?: () => void;
104 export const create = async (title = '', params: NotificationParams = {}) => {
105     await request();
106     if (!isEnabled()) {
107         return; // Exit if permission wasn't granted
108     }
110     return createWebNotification(title, params, params.onClick);