1import { EventEmitter, Subscription, UnavailabilityError } from 'expo-modules-core';
2
3import { Notification, NotificationResponse } from './Notifications.types';
4import NotificationsEmitterModule from './NotificationsEmitterModule';
5
6// Web uses SyntheticEventEmitter
7const emitter = new EventEmitter(NotificationsEmitterModule);
8
9const didReceiveNotificationEventName = 'onDidReceiveNotification';
10const didDropNotificationsEventName = 'onNotificationsDeleted';
11const didReceiveNotificationResponseEventName = 'onDidReceiveNotificationResponse';
12
13// @docsMissing
14export const DEFAULT_ACTION_IDENTIFIER = 'expo.modules.notifications.actions.DEFAULT';
15
16/**
17 * Listeners registered by this method will be called whenever a notification is received while the app is running.
18 * @param listener A function accepting a notification ([`Notification`](#notification)) as an argument.
19 * @return A [`Subscription`](#subscription) object represents the subscription of the provided listener.
20 * @example Registering a notification listener using a React hook:
21 * ```jsx
22 * import React from 'react';
23 * import * as Notifications from 'expo-notifications';
24 *
25 * export default function App() {
26 *   React.useEffect(() => {
27 *     const subscription = Notifications.addNotificationReceivedListener(notification => {
28 *       console.log(notification);
29 *     });
30 *     return () => subscription.remove();
31 *   }, []);
32 *
33 *   return (
34 *     // Your app content
35 *   );
36 * }
37 * ```
38 * @header listen
39 */
40export function addNotificationReceivedListener(
41  listener: (event: Notification) => void
42): Subscription {
43  return emitter.addListener<Notification>(didReceiveNotificationEventName, listener);
44}
45
46/**
47 * Listeners registered by this method will be called whenever some notifications have been dropped by the server.
48 * Applicable only to Firebase Cloud Messaging which we use as a notifications service on Android. It corresponds to `onDeletedMessages()` callback.
49 * More information can be found in [Firebase docs](https://firebase.google.com/docs/cloud-messaging/android/receive#override-ondeletedmessages).
50 * @param listener A callback function.
51 * @return A [`Subscription`](#subscription) object represents the subscription of the provided listener.
52 * @header listen
53 */
54export function addNotificationsDroppedListener(listener: () => void): Subscription {
55  return emitter.addListener<void>(didDropNotificationsEventName, listener);
56}
57
58/**
59 * Listeners registered by this method will be called whenever a user interacts with a notification (for example, taps on it).
60 * @param listener A function accepting notification response ([`NotificationResponse`](#notificationresponse)) as an argument.
61 * @return A [`Subscription`](#subscription) object represents the subscription of the provided listener.
62 * @example Register a notification responder listener:
63 * ```jsx
64 * import React from 'react';
65 * import { Linking } from 'react-native';
66 * import * as Notifications from 'expo-notifications';
67 *
68 * export default function Container() {
69 *   React.useEffect(() => {
70 *     const subscription = Notifications.addNotificationResponseReceivedListener(response => {
71 *       const url = response.notification.request.content.data.url;
72 *       Linking.openURL(url);
73 *     });
74 *     return () => subscription.remove();
75 *   }, []);
76 *
77 *   return (
78 *     // Your app content
79 *   );
80 * }
81 * ```
82 * @header listen
83 */
84export function addNotificationResponseReceivedListener(
85  listener: (event: NotificationResponse) => void
86): Subscription {
87  return emitter.addListener<NotificationResponse>(
88    didReceiveNotificationResponseEventName,
89    listener
90  );
91}
92
93/**
94 * Removes a notification subscription returned by an `addNotificationListener` call.
95 * @param subscription A subscription returned by `addNotificationListener` method.
96 * @header listen
97 */
98export function removeNotificationSubscription(subscription: Subscription) {
99  emitter.removeSubscription(subscription);
100}
101
102// @docsMissing
103/**
104 * @header listen
105 */
106export async function getLastNotificationResponseAsync(): Promise<NotificationResponse | null> {
107  if (!NotificationsEmitterModule.getLastNotificationResponseAsync) {
108    throw new UnavailabilityError('ExpoNotifications', 'getLastNotificationResponseAsync');
109  }
110  return await NotificationsEmitterModule.getLastNotificationResponseAsync();
111}
112