diff --git a/lib/src/DTO/Notification.test.ts b/lib/src/DTO/Notification.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..2c4a4fe1ff1528b95af299a91a5c9df11920d0bf --- /dev/null +++ b/lib/src/DTO/Notification.test.ts @@ -0,0 +1,50 @@ +import { Notification } from './Notification'; +describe('Notification', () => { + it('Should create notification with payload', () => { + const payload = { p: 'p' }; + const notification = new Notification(payload); + expect(notification.data).toEqual(payload); + }); + + it('Should create notification with identifier', () => { + const payload = { identifier: 'identifier' }; + const notification = new Notification(payload); + expect(notification.identifier).toEqual(payload.identifier); + }); + + it('Should return title from payload', () => { + const payload = { title: 'title' }; + const notification = new Notification(payload); + expect(notification.title).toEqual(payload.title); + }); + + it('Should return body from payload', () => { + const payload = { body: 'body' }; + const notification = new Notification(payload); + expect(notification.body).toEqual(payload.body); + }); + + it('Should return sound from payload', () => { + const payload = { sound: 'sound.mp4' }; + const notification = new Notification(payload); + expect(notification.sound).toEqual(payload.sound); + }); + + it('Should return badge from payload', () => { + const payload = { badge: 1 }; + const notification = new Notification(payload); + expect(notification.badge).toEqual(payload.badge); + }); + + it('Should return type from payload', () => { + const payload = { type: 'type' }; + const notification = new Notification(payload); + expect(notification.type).toEqual(payload.type); + }); + + it('Should return thread from payload', () => { + const payload = { thread: 'thread' }; + const notification = new Notification(payload); + expect(notification.thread).toEqual(payload.thread); + }); +}); diff --git a/lib/src/interfaces/Notification.ts b/lib/src/DTO/Notification.ts similarity index 60% rename from lib/src/interfaces/Notification.ts rename to lib/src/DTO/Notification.ts index 05a4599def4f84868e143dac4ee14bdb8ed8638c..20d6eafa39d102a9adcdd1a8ae7c4136fd862e9a 100644 --- a/lib/src/interfaces/Notification.ts +++ b/lib/src/DTO/Notification.ts @@ -2,11 +2,6 @@ export class Notification { identifier: string; private _data?: any; - sound?: string; - badge?: number; - type?: string; - thread?: string; - constructor(payload: object) { this._data = payload; this.identifier = this._data.identifier; @@ -23,4 +18,20 @@ export class Notification { get body(): string { return this._data.body; } + + get sound(): string { + return this._data.sound; + } + + get badge(): number { + return this._data.badge; + } + + get type(): string { + return this._data.type; + } + + get thread(): string { + return this._data.thread; + } } diff --git a/lib/src/Notifications.ts b/lib/src/Notifications.ts index 8019c6af1b4dc2b5e38ec87dadc1a329271db3fd..dc6e56a984e140bc586e67d9f209440f9e04ae42 100644 --- a/lib/src/Notifications.ts +++ b/lib/src/Notifications.ts @@ -2,7 +2,7 @@ import { NativeCommandsSender } from './adapters/NativeCommandsSender'; import { NativeEventsReceiver } from './adapters/NativeEventsReceiver'; import { Commands } from './commands/Commands'; import { EventsRegistry } from './events/EventsRegistry'; -import { Notification } from './interfaces/Notification'; +import { Notification } from './DTO/Notification'; import { UniqueIdProvider } from './adapters/UniqueIdProvider'; import { CompletionCallbackWrapper } from './adapters/CompletionCallbackWrapper'; import { NotificationCategory } from './interfaces/NotificationCategory'; diff --git a/lib/src/adapters/CompletionCallbackWrapper.ts b/lib/src/adapters/CompletionCallbackWrapper.ts index 8530682714e1dceecc1165cedcee57c22b7c257c..50fd4c4552234f1280aca3eab722106ab192b31a 100644 --- a/lib/src/adapters/CompletionCallbackWrapper.ts +++ b/lib/src/adapters/CompletionCallbackWrapper.ts @@ -1,5 +1,5 @@ import { NativeCommandsSender } from './NativeCommandsSender'; -import { Notification } from '../interfaces/Notification'; +import { Notification } from '../DTO/Notification'; import { NotificationCompletion } from '../interfaces/NotificationCompletion'; import { Platform } from 'react-native'; diff --git a/lib/src/adapters/NativeCommandsSender.ts b/lib/src/adapters/NativeCommandsSender.ts index f36b688e70b82fa1942f33d727f0e609c2ce6311..f094b33edfe227af3e5f9c75f624c86ecd11b032 100644 --- a/lib/src/adapters/NativeCommandsSender.ts +++ b/lib/src/adapters/NativeCommandsSender.ts @@ -1,5 +1,5 @@ import { NativeModules } from 'react-native'; -import { Notification } from '../interfaces/Notification'; +import { Notification } from '../DTO/Notification'; import { NotificationCompletion } from '../interfaces/NotificationCompletion'; import { NotificationPermissions } from '../interfaces/NotificationPermissions'; import { NotificationCategory } from '../interfaces/NotificationCategory'; diff --git a/lib/src/adapters/NativeEventsReceiver.ts b/lib/src/adapters/NativeEventsReceiver.ts index f84071db00a86f4584a18d698ac4858cb66d2223..de54bb46732f43599f18e40110f028f4dffbdbd2 100644 --- a/lib/src/adapters/NativeEventsReceiver.ts +++ b/lib/src/adapters/NativeEventsReceiver.ts @@ -2,7 +2,7 @@ import { NativeModules, NativeEventEmitter, EventEmitter, EmitterSubscription } import { Registered, RegistrationError, RegisteredPushKit } from '../interfaces/NotificationEvents'; -import { Notification } from '../interfaces/Notification'; +import { Notification } from '../DTO/Notification'; export class NativeEventsReceiver { private emitter: EventEmitter; diff --git a/lib/src/commands/Commands.test.ts b/lib/src/commands/Commands.test.ts index 127570d384bc42d175947a3d92ce77321ffa855b..2bb82e628a90842486c3b587a3d122f55d673d7c 100644 --- a/lib/src/commands/Commands.test.ts +++ b/lib/src/commands/Commands.test.ts @@ -3,7 +3,7 @@ import { mock, verify, instance, when, anyNumber } from 'ts-mockito'; import { Commands } from './Commands'; import { NativeCommandsSender } from '../adapters/NativeCommandsSender'; -import { Notification } from '../interfaces/Notification'; +import { Notification } from '../DTO/Notification'; import { UniqueIdProvider } from '../adapters/UniqueIdProvider'; import { NotificationCategory } from '../interfaces/NotificationCategory'; import { NotificationPermissions } from '../interfaces/NotificationPermissions'; diff --git a/lib/src/commands/Commands.ts b/lib/src/commands/Commands.ts index 99a11ba4583ca5085e6b58ef588c4ea7c2240e46..6d1be116cb1e60f3b2de37e695fa72fb5134fb79 100644 --- a/lib/src/commands/Commands.ts +++ b/lib/src/commands/Commands.ts @@ -1,6 +1,6 @@ import * as _ from 'lodash'; import { NativeCommandsSender } from '../adapters/NativeCommandsSender'; -import { Notification } from '../interfaces/Notification'; +import { Notification } from '../DTO/Notification'; import { NotificationCategory } from '../interfaces/NotificationCategory'; import { NotificationPermissions } from '../interfaces/NotificationPermissions'; import { UniqueIdProvider } from '../adapters/UniqueIdProvider'; diff --git a/lib/src/events/EventsRegistry.test.ts b/lib/src/events/EventsRegistry.test.ts index b8af1c83044c694c967b5ab8003df80af1b0eb47..3b864a4971ecc55b461e8478191f3402c93102bc 100644 --- a/lib/src/events/EventsRegistry.test.ts +++ b/lib/src/events/EventsRegistry.test.ts @@ -1,6 +1,6 @@ import { EventsRegistry } from './EventsRegistry'; import { NativeEventsReceiver } from '../adapters/NativeEventsReceiver.mock'; -import { Notification } from '../interfaces/Notification'; +import { Notification } from '../DTO/Notification'; import { CompletionCallbackWrapper } from '../adapters/CompletionCallbackWrapper'; import { NativeCommandsSender } from '../adapters/NativeCommandsSender.mock'; import { NotificationResponse } from '../interfaces/NotificationEvents'; diff --git a/lib/src/events/EventsRegistry.ts b/lib/src/events/EventsRegistry.ts index 97bd3509a23512d924751ab3489623c7adb7454c..8fc076cd938c505f3a654b3d18b53681941b8787 100644 --- a/lib/src/events/EventsRegistry.ts +++ b/lib/src/events/EventsRegistry.ts @@ -7,7 +7,7 @@ import { NotificationResponse } from '../interfaces/NotificationEvents'; import { CompletionCallbackWrapper } from '../adapters/CompletionCallbackWrapper'; -import { Notification } from '../interfaces/Notification'; +import { Notification } from '../DTO/Notification'; import { NotificationCompletion } from '../interfaces/NotificationCompletion'; export class EventsRegistry { diff --git a/lib/src/index.android.js b/lib/src/index.android.js deleted file mode 100644 index 51376bf839ee06fea285d2d5ff1ad12dc32ce49b..0000000000000000000000000000000000000000 --- a/lib/src/index.android.js +++ /dev/null @@ -1,82 +0,0 @@ -import {NativeModules, DeviceEventEmitter} from 'react-native'; -import NotificationAndroid from './notification'; - -const RNNotifications = NativeModules.WixRNNotifications; - -let notificationReceivedListener; -let notificationReceivedInForegroundListener; -let notificationOpenedListener; -let registrationTokenUpdateListener; - -export class NotificationsAndroid { - static setNotificationOpenedListener(listener) { - notificationOpenedListener = DeviceEventEmitter.addListener('notificationOpened', (notification) => listener(new NotificationAndroid(notification))); - } - - static clearNotificationOpenedListener() { - if (notificationOpenedListener) { - notificationOpenedListener.remove(); - notificationOpenedListener = null; - } - } - - static setNotificationReceivedListener(listener) { - notificationReceivedListener = DeviceEventEmitter.addListener('notificationReceived', (notification) => listener(new NotificationAndroid(notification))); - } - - static setNotificationReceivedInForegroundListener(listener) { - notificationReceivedInForegroundListener = DeviceEventEmitter.addListener('notificationReceivedInForeground', (notification) => listener(new NotificationAndroid(notification))); - } - - static clearNotificationReceivedListener() { - if (notificationReceivedListener) { - notificationReceivedListener.remove(); - notificationReceivedListener = null; - } - } - - static clearNotificationReceivedInForegroundListener() { - if (notificationReceivedInForegroundListener) { - notificationReceivedInForegroundListener.remove(); - notificationReceivedInForegroundListener = null; - } - } - - static setRegistrationTokenUpdateListener(listener) { - registrationTokenUpdateListener = DeviceEventEmitter.addListener('remoteNotificationsRegistered', listener); - } - - static clearRegistrationTokenUpdateListener() { - if (registrationTokenUpdateListener) { - registrationTokenUpdateListener.remove(); - registrationTokenUpdateListener = null; - } - } - - static async isRegisteredForRemoteNotifications() { - return await RNNotifications.isRegisteredForRemoteNotifications(); - } - - static refreshToken() { - RNNotifications.refreshToken(); - } - - static localNotification(notification: Object) { - const id = Math.random() * 100000000 | 0; // Bitwise-OR forces value onto a 32bit limit - RNNotifications.postLocalNotification(notification, id); - return id; - } - - static cancelLocalNotification(id) { - RNNotifications.cancelLocalNotification(id); - } -} - -export class PendingNotifications { - static getInitialNotification() { - return RNNotifications.getInitialNotification() - .then((rawNotification) => { - return rawNotification ? new NotificationAndroid(rawNotification) : undefined; - }); - } -} diff --git a/lib/src/index.ios.js b/lib/src/index.ios.js deleted file mode 100644 index 2182588b8ebec918bd244459bd70b5f8a205f5d3..0000000000000000000000000000000000000000 --- a/lib/src/index.ios.js +++ /dev/null @@ -1,254 +0,0 @@ -/** - * @flow - */ -'use strict'; -import { NativeModules, DeviceEventEmitter } from 'react-native'; -import Map from 'core-js/library/es6/map'; -import uuid from 'uuid'; -const NativeRNNotifications = NativeModules.RNBridgeModule; // eslint-disable-line no-unused-vars -import IOSNotification from './notification.ios'; - -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_OPENED_EVENT = 'notificationOpened'; -export const DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT = 'pushKitNotificationReceived'; - - -const _exportedEvents = [ - DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT, - DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT, - DEVICE_PUSH_KIT_REGISTERED_EVENT, - DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT, - DEVICE_NOTIFICATION_OPENED_EVENT, - DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT -]; -const _notificationHandlers = new Map(); -const _actionHandlers = new Map(); - -export class NotificationAction { - options: Object; - - constructor(options: Object) { - this.options = options; - } -} - -export class NotificationCategory { - options: Object; - - constructor(options: Object) { - this.options = options; - } -} - -export default class NotificationsIOS { - /** - * Attaches a listener to remote notification events while the app is running - * in the foreground or the background. - * - * Valid events are: - * - * - `remoteNotificationsRegistered` : Fired when the user registers for remote notifications. The handler will be invoked with a hex string representing the deviceToken. - * - `notificationReceivedForeground` : Fired when a notification (local / remote) is received when app is on foreground state. - * - `notificationOpened`: Fired when a notification (local / remote) is opened. - * - `pushKitNotificationReceived` : Fired when a pushKit notification received when app is both on foreground and background state. - */ - static addEventListener(type: string, handler: Function) { - 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) - ); - } else if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT) { - listener = DeviceEventEmitter.addListener( - DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT, - error => handler(error) - ); - } else if (type === DEVICE_PUSH_KIT_REGISTERED_EVENT) { - listener = DeviceEventEmitter.addListener( - DEVICE_PUSH_KIT_REGISTERED_EVENT, - registration => handler(registration.pushKitToken) - ); - } else if (type === DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT) { - listener = DeviceEventEmitter.addListener( - type, - ({payload, identifier}) => handler(new IOSNotification(payload), (presentingOptions) => { - NativeRNNotifications.finishPresentingNotification(identifier, presentingOptions); - }) - ); - } else if (type === DEVICE_NOTIFICATION_OPENED_EVENT) { - listener = DeviceEventEmitter.addListener( - type, - ({payload, identifier, action}) => handler(new IOSNotification(payload), () => { - NativeRNNotifications.finishHandlingAction(identifier); - }, action) - ); - } else if (type === DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT) { - listener = DeviceEventEmitter.addListener( - type, - (payload) => handler(new IOSNotification(payload)) - ); - } - - _notificationHandlers.set(handler, listener); - } - } - - /** - * Removes the event listener. Do this in `componentWillUnmount` to prevent - * memory leaks - */ - static removeEventListener(type: string, handler: Function) { - if (_exportedEvents.indexOf(type) !== -1) { - const listener = _notificationHandlers.get(handler); - if (listener) { - listener.remove(); - _notificationHandlers.delete(handler); - } - - } - } - - /** - * Sets the notification categories - */ - static requestPermissions(categories: Array) { - let notificationCategories = []; - - if (categories) { - notificationCategories = categories.map(category => { - return Object.assign({}, category.options, { - actions: category.options.actions.map(action => { - // subscribe to action event - _actionHandlers.set(action.options.identifier, action.handler); - - return action.options; - }) - }); - }); - } - - NativeRNNotifications.requestPermissionsWithCategories(notificationCategories); - } - - /** - * Unregister for all remote notifications received via Apple Push Notification service. - */ - static abandonPermissions() { - NativeRNNotifications.abandonPermissions(); - } - - /** - * Removes the event listener. Do this in `componentWillUnmount` to prevent - * memory leaks - */ - static resetCategories() { - _actionHandlers.clear(); - } - - static getBadgesCount(callback: Function) { - NativeRNNotifications.getBadgesCount(callback); - } - - static setBadgesCount(count: number) { - NativeRNNotifications.setBadgesCount(count); - } - - static registerPushKit() { - NativeRNNotifications.registerPushKit(); - } - - static backgroundTimeRemaining(callback: Function) { - NativeRNNotifications.backgroundTimeRemaining(callback); - } - - static log(message: string) { - NativeRNNotifications.log(message); - } - - static async getInitialNotification() { - const notification = await NativeRNNotifications.getInitialNotification(); - if (notification) { - return new IOSNotification(notification); - } else { - return undefined; - } - } - - /** - * Presenting local notification - * - * notification is an object containing: - * - * - `body` : The message displayed in the notification alert. - * - `title` : The message title displayed in the notification. - * - `alertAction` : The 'action' displayed beneath an actionable notification. Defaults to 'view'; - * - `sound` : The sound played when the notification is fired (optional). - * - `silent` : If true, the notification sound will be suppressed (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) { - const notificationId = uuid.v4(); - NativeRNNotifications.localNotification(notification, notificationId); - - return notificationId; - } - - static cancelLocalNotification(notificationId: String) { - NativeRNNotifications.cancelLocalNotification(notificationId); - } - - static cancelAllLocalNotifications() { - NativeRNNotifications.cancelAllLocalNotifications(); - } - - static isRegisteredForRemoteNotifications() { - return NativeRNNotifications.isRegisteredForRemoteNotifications(); - } - - static checkPermissions() { - return NativeRNNotifications.checkPermissions(); - } - - /** - * 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: Array) { - 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. - * - `body` : The message displayed in the notification alert. - * - `title` : 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: Array) => void) { - return NativeRNNotifications.getDeliveredNotifications(callback); - } -} diff --git a/lib/src/index.ts b/lib/src/index.ts index 0826f6b25c526b6f4485eef3fc3c3bf4792ec02c..c6964f5fea451142ea2a6ff9b2a878e3f06c9667 100644 --- a/lib/src/index.ts +++ b/lib/src/index.ts @@ -4,5 +4,5 @@ const notificationsSingleton = new NotificationsRoot(); export const Notifications = notificationsSingleton; export * from './interfaces/EventSubscription'; -export * from './interfaces/Notification'; +export * from './DTO/Notification'; export * from './interfaces/NotificationEvents'; diff --git a/lib/src/interfaces/NotificationEvents.ts b/lib/src/interfaces/NotificationEvents.ts index dcd90eb3c5713b8aa744c6b04c193c14ad779b69..2fc1bf39bf73a109be5d3d1efee5d5781957a11f 100644 --- a/lib/src/interfaces/NotificationEvents.ts +++ b/lib/src/interfaces/NotificationEvents.ts @@ -1,4 +1,4 @@ -import { Notification } from './Notification'; +import { Notification } from '../DTO/Notification'; import { NotificationActionResponse } from './NotificationActionResponse'; export interface Registered { diff --git a/lib/src/notification.android.js b/lib/src/notification.android.js deleted file mode 100644 index bb2ace85e1dfa5656311edf703250dd2fdd352ec..0000000000000000000000000000000000000000 --- a/lib/src/notification.android.js +++ /dev/null @@ -1,20 +0,0 @@ -/** A wrapper to align Android with iOS in terms on notification structure. */ -export default class NotificationAndroid { - - constructor(notification) { - this.data = notification; - } - - getData() { - return this.data; - } - - getTitle() { - return this.data.title; - } - - getMessage() { - return this.data.body; - } -} - diff --git a/lib/src/notification.ios.js b/lib/src/notification.ios.js deleted file mode 100644 index 0d9b58a35a583e1bdf1e1da02690d667cddc97e0..0000000000000000000000000000000000000000 --- a/lib/src/notification.ios.js +++ /dev/null @@ -1,69 +0,0 @@ -export default class IOSNotification { - _data: Object; - _alert: string | Object; - _sound: string; - _badge: number; - _category: string; - _type: string; // regular / managed - _thread: string; - - constructor(notification: Object) { - this._data = {}; - - if (notification.aps && - notification.aps['content-available'] && - notification.aps['content-available'] === 1 && - !notification.aps.alert && - !notification.aps.sound && - notification.managedAps) { - // managed notification - this._alert = notification.managedAps.alert; - this._sound = notification.managedAps.sound; - this._badge = notification.aps.badge; - this._category = notification.managedAps.category; - this._type = 'managed'; - this._thread = notification.aps.thread; - } else if ( - notification.aps) { - // regular notification - this._alert = notification.aps.alert; - this._sound = notification.aps.sound; - this._badge = notification.aps.badge; - this._category = notification.aps.category; - this._type = 'regular'; - this._thread = notification.aps.thread; - } - - Object.keys(notification).filter(key => key !== 'aps').forEach(key => { - this._data[key] = notification[key]; - }); - } - - getMessage(): ?string | ?Object { - return this._alert; - } - - getSound(): ?string { - return this._sound; - } - - getBadgeCount(): ?number { - return this._badge; - } - - getCategory(): ?string { - return this._category; - } - - getData(): ?Object { - return this._data; - } - - getType(): ?string { - return this._type; - } - - getThread(): ?string { - return this._thread; - } -}