index.ios.js 7.06 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
  }
Lidan Hifi's avatar
Lidan Hifi committed
215
}