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

yogevbd's avatar
yogevbd committed
11 12 13 14 15 16
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = 'remoteNotificationsRegistered';
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT = 'remoteNotificationsRegistrationFailed';
export const DEVICE_PUSH_KIT_REGISTERED_EVENT = 'pushKitRegistered';
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
17

yogevbd's avatar
yogevbd committed
18
const DEVICE_NOTIFICATION_ACTION_RECEIVED = 'notificationActionReceived';
19 20 21

const _exportedEvents = [
  DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
22
  DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT,
23 24 25 26 27
  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
28 29
const _notificationHandlers = new Map();
const _actionHandlers = new Map();
30
let _actionListener;
Lidan Hifi's avatar
Lidan Hifi committed
31

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

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

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

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

50
export default class NotificationsIOS {
Lidan Hifi's avatar
Lidan Hifi committed
51 52 53 54 55 56
  /**
   * Attaches a listener to remote notification events while the app is running
   * in the foreground or the background.
   *
   * Valid events are:
   *
57
   * - `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
58 59 60 61 62
   * - `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) {
63 64 65 66
    if (_exportedEvents.indexOf(type) !== -1) {
      let listener;

      if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT) {
67
        listener = DeviceEventEmitter.addListener(
68 69 70
          DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
          registration => handler(registration.deviceToken)
        );
71
      } else if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT) {
72
        listener = DeviceEventEmitter.addListener(
73 74 75
          DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT,
          error => handler(error)
        );
76
      } else if (type === DEVICE_PUSH_KIT_REGISTERED_EVENT) {
77
        listener = DeviceEventEmitter.addListener(
78 79 80 81
          DEVICE_PUSH_KIT_REGISTERED_EVENT,
          registration => handler(registration.pushKitToken)
        );
      } else {
82
        listener = DeviceEventEmitter.addListener(
83
          type,
yogevbd's avatar
WIP  
yogevbd committed
84 85 86
          ({payload, identifier}) => handler(new IOSNotification(payload), (presentingOptions) => {
            NativeRNNotifications.finishPresentingNotification(identifier, presentingOptions);
          })
87 88
        );
      }
Lidan Hifi's avatar
Lidan Hifi committed
89

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

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

    }
  }
108

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

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

115
      actionHandler(action, () => {
yogevbd's avatar
WIP  
yogevbd committed
116
        NativeRNNotifications.finishHandlingAction(action.identifier);
117
      });
118
    }
119 120 121 122 123
  }

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

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

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

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

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

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

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

    _actionHandlers.clear();
  }
164

165
  static getBadgesCount(callback: Function) {
166
    NativeRNNotifications.getBadgesCount(callback);
167 168
  }

169
  static setBadgesCount(count: number) {
170
    NativeRNNotifications.setBadgesCount(count);
171 172
  }

173
  static registerPushKit() {
174
    NativeRNNotifications.registerPushKit();
175 176 177
  }

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

181
  static consumeBackgroundQueue() {
yogevbd's avatar
WIP  
yogevbd committed
182
    // NativeRNNotifications.consumeBackgroundQueue();
183 184
  }

185
  static log(message: string) {
186
    NativeRNNotifications.log(message);
187
  }
188

189
  static async getInitialNotification() {
190
    const notification = await NativeRNNotifications.getInitialNotification();
191 192 193 194 195 196 197
    if (notification) {
      return new IOSNotification(notification);
    } else {
      return undefined;
    }
  }

198 199 200 201 202 203 204
  /**
   * Presenting local notification
   *
   * notification is an object containing:
   *
   * - `alertBody` : The message displayed in the notification alert.
   * - `alertTitle` : The message title displayed in the notification.
yogevbd's avatar
yogevbd committed
205
   * - `alertAction` : The 'action' displayed beneath an actionable notification. Defaults to 'view';
206
   * - `soundName` : The sound played when the notification is fired (optional).
207
   * - `silent`    : If true, the notification sound will be suppressed (optional).
208 209 210 211 212
   * - `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
213
    const notificationId = uuid.v4();
214
    NativeRNNotifications.localNotification(notification, notificationId);
215 216 217 218 219

    return notificationId;
  }

  static cancelLocalNotification(notificationId: String) {
220
    NativeRNNotifications.cancelLocalNotification(notificationId);
221 222 223
  }

  static cancelAllLocalNotifications() {
224
    NativeRNNotifications.cancelAllLocalNotifications();
225
  }
226

Ran Greenberg's avatar
Ran Greenberg committed
227
  static isRegisteredForRemoteNotifications() {
228
    return NativeRNNotifications.isRegisteredForRemoteNotifications();
229
  }
Ryan Eberhardt's avatar
Ryan Eberhardt committed
230 231

  static checkPermissions() {
232
    return NativeRNNotifications.checkPermissions();
Ryan Eberhardt's avatar
Ryan Eberhardt committed
233
  }
234

235 236 237 238
  /**
   * Remove all delivered notifications from Notification Center
   */
  static removeAllDeliveredNotifications() {
239
    return NativeRNNotifications.removeAllDeliveredNotifications();
240 241 242 243 244 245 246
  }

  /**
   * Removes the specified notifications from Notification Center
   *
   * @param identifiers Array of notification identifiers
   */
247
  static removeDeliveredNotifications(identifiers: Array<String>) {
248
    return NativeRNNotifications.removeDeliveredNotifications(identifiers);
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
  }

  /**
   * 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.
   */
266
  static getDeliveredNotifications(callback: (notifications: Array<Object>) => void) {
267
    return NativeRNNotifications.getDeliveredNotifications(callback);
268
  }
Lidan Hifi's avatar
Lidan Hifi committed
269
}