index.ios.js 8.6 KB
Newer Older
Lidan Hifi's avatar
Lidan Hifi committed
1
/**
Lidan Hifi's avatar
Lidan Hifi committed
2
 * @providesModule RNNotifications
Lidan Hifi's avatar
Lidan Hifi committed
3 4
 * @flow
 */
Lidan Hifi's avatar
Lidan Hifi committed
5
"use strict";
6
import { NativeModules, DeviceEventEmitter, NativeAppEventEmitter } from "react-native";
Lidan Hifi's avatar
Lidan Hifi committed
7
import Map from "core-js/library/es6/map";
8
import uuid from "uuid";
9
const NativeRNNotifications = NativeModules.RNNotifications; // eslint-disable-line no-unused-vars
10
import IOSNotification from "./notification.ios";
Lidan Hifi's avatar
Lidan Hifi committed
11

12
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = "remoteNotificationsRegistered";
13
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT = "remoteNotificationsRegistrationFailed";
14
export const DEVICE_PUSH_KIT_REGISTERED_EVENT = "pushKitRegistered";
15 16 17
export const DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT = "notificationReceivedForeground";
export const DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT = "notificationReceivedBackground";
export const DEVICE_NOTIFICATION_OPENED_EVENT = "notificationOpened";
Lidan Hifi's avatar
Lidan Hifi committed
18

19 20 21 22
const DEVICE_NOTIFICATION_ACTION_RECEIVED = "notificationActionReceived";

const _exportedEvents = [
  DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
23
  DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT,
24 25 26 27 28
  DEVICE_PUSH_KIT_REGISTERED_EVENT,
  DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT,
  DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT,
  DEVICE_NOTIFICATION_OPENED_EVENT
];
Leon Mok's avatar
Leon Mok committed
29 30
const _notificationHandlers = new Map();
const _actionHandlers = new Map();
31
let _actionListener;
Lidan Hifi's avatar
Lidan Hifi committed
32

33
export class NotificationAction {
mlanter's avatar
mlanter committed
34 35 36
  options: Object;
  handler: Function;

37 38 39 40 41 42 43
  constructor(options: Object, handler: Function) {
    this.options = options;
    this.handler = handler;
  }
}

export class NotificationCategory {
mlanter's avatar
mlanter committed
44 45
  options: Object;

46 47 48 49 50
  constructor(options: Object) {
    this.options = options;
  }
}

51
export default class NotificationsIOS {
Lidan Hifi's avatar
Lidan Hifi committed
52 53 54 55 56 57
  /**
   * Attaches a listener to remote notification events while the app is running
   * in the foreground or the background.
   *
   * Valid events are:
   *
58
   * - `remoteNotificationsRegistered` : Fired when the user registers for remote notifications. The handler will be invoked with a hex string representing the deviceToken.
Lidan Hifi's avatar
Lidan Hifi committed
59 60 61 62 63
   * - `notificationReceivedForeground` : Fired when a notification (local / remote) is received when app is on foreground state.
   * - `notificationReceivedBackground`: Fired when a background notification is received.
   * - `notificationOpened`: Fired when a notification (local / remote) is opened.
   */
  static addEventListener(type: string, handler: Function) {
64 65 66 67 68 69 70 71
    if (_exportedEvents.indexOf(type) !== -1) {
      let listener;

      if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT) {
        listener = DeviceEventEmitter.addListener(
          DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
          registration => handler(registration.deviceToken)
        );
72 73 74 75 76
      } else if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT) {
        listener = DeviceEventEmitter.addListener(
          DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT,
          error => handler(error)
        );
77 78 79 80 81 82 83 84 85 86 87
      } else if (type === DEVICE_PUSH_KIT_REGISTERED_EVENT) {
        listener = DeviceEventEmitter.addListener(
          DEVICE_PUSH_KIT_REGISTERED_EVENT,
          registration => handler(registration.pushKitToken)
        );
      } else {
        listener = DeviceEventEmitter.addListener(
          type,
          notification => handler(new IOSNotification(notification))
        );
      }
Lidan Hifi's avatar
Lidan Hifi committed
88

Lidan Hifi's avatar
Lidan Hifi committed
89
      _notificationHandlers.set(handler, listener);
Lidan Hifi's avatar
Lidan Hifi committed
90 91 92 93 94 95 96 97
    }
  }

  /**
   * Removes the event listener. Do this in `componentWillUnmount` to prevent
   * memory leaks
   */
  static removeEventListener(type: string, handler: Function) {
98
    if (_exportedEvents.indexOf(type) !== -1) {
Leon Mok's avatar
Leon Mok committed
99 100 101 102
      const listener = _notificationHandlers.get(handler);
      if (listener) {
        listener.remove();
        _notificationHandlers.delete(handler);
Lidan Hifi's avatar
Lidan Hifi committed
103
      }
Lidan Hifi's avatar
Lidan Hifi committed
104 105 106

    }
  }
107

108
  static _actionHandlerDispatcher(action: Object) {
Leon Mok's avatar
Leon Mok committed
109
    const actionHandler = _actionHandlers.get(action.identifier);
110 111

    if (actionHandler) {
112 113
      action.notification = new IOSNotification(action.notification);

114 115 116
      actionHandler(action, () => {
        NativeRNNotifications.completionHandler(action.completionKey);
      });
117
    }
118 119 120 121 122
  }

  /**
   * Sets the notification categories
   */
123
  static requestPermissions(categories: Array<NotificationCategory>) {
124 125 126
    let notificationCategories = [];

    if (categories) {
127
      // subscribe once for all actions
128
      _actionListener = NativeAppEventEmitter.addListener(DEVICE_NOTIFICATION_ACTION_RECEIVED, this._actionHandlerDispatcher.bind(this));
129

130 131 132 133
      notificationCategories = categories.map(category => {
        return Object.assign({}, category.options, {
          actions: category.options.actions.map(action => {
            // subscribe to action event
134
            _actionHandlers.set(action.options.identifier, action.handler);
135 136 137 138 139 140 141

            return action.options;
          })
        });
      });
    }

142 143 144 145 146 147 148 149
    NativeRNNotifications.requestPermissionsWithCategories(notificationCategories);
  }

  /**
   * Unregister for all remote notifications received via Apple Push Notification service.
   */
  static abandonPermissions() {
    NativeRNNotifications.abandonPermissions();
150
  }
151 152 153 154 155 156 157 158 159 160 161 162

  /**
   * Removes the event listener. Do this in `componentWillUnmount` to prevent
   * memory leaks
   */
  static resetCategories() {
    if (_actionListener) {
      _actionListener.remove();
    }

    _actionHandlers.clear();
  }
163

164 165 166 167
  static setBadgesCount(count: number) {
    NativeRNNotifications.setBadgesCount(count);
  }

168 169 170 171 172 173 174 175
  static registerPushKit() {
    NativeRNNotifications.registerPushKit();
  }

  static backgroundTimeRemaining(callback: Function) {
    NativeRNNotifications.backgroundTimeRemaining(callback);
  }

176 177 178 179
  static consumeBackgroundQueue() {
    NativeRNNotifications.consumeBackgroundQueue();
  }

180
  static log(message: string) {
181 182
    NativeRNNotifications.log(message);
  }
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

  /**
   * Presenting local notification
   *
   * notification is an object containing:
   *
   * - `alertBody` : The message displayed in the notification alert.
   * - `alertTitle` : The message title displayed in the notification.
   * - `alertAction` : The "action" displayed beneath an actionable notification. Defaults to "view";
   * - `soundName` : The sound played when the notification is fired (optional).
   * - `category`  : The category of this notification, required for actionable notifications (optional).
   * - `userInfo`  : An optional object containing additional notification data.
   * - `fireDate` : The date and time when the system should deliver the notification. if not specified, the notification will be dispatched immediately.
   */
  static localNotification(notification: Object) {
Leon Mok's avatar
Leon Mok committed
198
    const notificationId = uuid.v4();
199 200 201 202 203 204 205 206 207 208 209
    NativeRNNotifications.localNotification(notification, notificationId);

    return notificationId;
  }

  static cancelLocalNotification(notificationId: String) {
    NativeRNNotifications.cancelLocalNotification(notificationId);
  }

  static cancelAllLocalNotifications() {
    NativeRNNotifications.cancelAllLocalNotifications();
210
  }
211

Ran Greenberg's avatar
Ran Greenberg committed
212 213
  static isRegisteredForRemoteNotifications() {
    return NativeRNNotifications.isRegisteredForRemoteNotifications();
214
  }
Ryan Eberhardt's avatar
Ryan Eberhardt committed
215 216 217 218

  static checkPermissions() {
    return NativeRNNotifications.checkPermissions();
  }
219

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
  /**
   * Remove all delivered notifications from Notification Center
   */
  static removeAllDeliveredNotifications() {
    return NativeRNNotifications.removeAllDeliveredNotifications();
  }

  /**
   * Removes the specified notifications from Notification Center
   *
   * @param identifiers Array of notification identifiers
   */
  static removeDeliveredNotifications(identifiers: [string]) {
    return NativeRNNotifications.removeDeliveredNotifications(identifiers);
  }

  /**
   * Provides you with a list of the app’s notifications that are still displayed in Notification Center
   *
   * @param callback Function which receive an array of delivered notifications
   *
   *  A delivered notification is an object containing:
   *
   * - `identifier`  : The identifier of this notification.
   * - `alertBody` : The message displayed in the notification alert.
   * - `alertTitle` : The message title displayed in the notification.
   * - `category`  : The category of this notification, if has one.
   * - `userInfo`  : An optional object containing additional notification data.
   * - `thread-id`  : The thread identifier of this notification, if has one.
   * - `fireDate` : The date and time when the system should deliver the notification. if not specified, the notification will be dispatched immediately.
   */
  static getDeliveredNotifications(callback: (notifications: [Object]) => void) {
    return NativeRNNotifications.getDeliveredNotifications(callback);
  }
Lidan Hifi's avatar
Lidan Hifi committed
254
}