Skip to content

Commit

Permalink
[expo-notifications] Implement notifications handling in TS
Browse files Browse the repository at this point in the history
  • Loading branch information
sjchmiela committed Jan 24, 2020
1 parent fb78b50 commit 2b9d471
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 1 deletion.
18 changes: 18 additions & 0 deletions packages/expo-notifications/build/NotificationsHandler.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions packages/expo-notifications/build/NotificationsHandler.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions packages/expo-notifications/build/NotificationsHandlerModule.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/expo-notifications/build/index.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/expo-notifications/build/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/expo-notifications/build/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 69 additions & 0 deletions packages/expo-notifications/src/NotificationsHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { EventEmitter, Subscription, CodedError } from '@unimodules/core';
import NotificationsHandlerModule, { NotificationBehavior } from './NotificationsHandlerModule';

type Notification = any;

export class NotificationTimeoutError extends CodedError {
info: { notification: Notification; id: string };
constructor(notificationId: string, notification: Notification) {
super('ERR_NOTIFICATION_TIMEOUT', `Notification handling timed out for ID ${notificationId}.`);
this.info = { id: notificationId, notification };
}
}

export type NotificationHandlingError = NotificationTimeoutError | Error;

export interface NotificationDelegate {
handleNotification: (notification: Notification) => Promise<NotificationBehavior>;
handleSuccess?: (notificationId: string) => void;
handleError?: (error: NotificationHandlingError) => void;
}

type HandleNotificationEvent = {
id: string;
notification: Notification;
};

type HandleNotificationTimeoutEvent = HandleNotificationEvent;

// Web uses SyntheticEventEmitter
const notificationEmitter = new EventEmitter(NotificationsHandlerModule);

const handleNotificationEventName = 'onHandleNotification';
const handleNotificationTimeoutEventName = 'onHandleNotificationTimeout';

let handleSubscription: Subscription | null = null;
let handleTimeoutSubscription: Subscription | null = null;

export function setNotificationDelegate(delegate: NotificationDelegate): void {
if (handleSubscription) {
handleSubscription.remove();
handleSubscription = null;
}
if (handleTimeoutSubscription) {
handleTimeoutSubscription.remove();
handleTimeoutSubscription = null;
}

handleSubscription = notificationEmitter.addListener<HandleNotificationEvent>(
handleNotificationEventName,
async ({ id, notification }) => {
try {
const requestedBehavior = await delegate.handleNotification(notification);
await NotificationsHandlerModule.handleNotificationAsync(id, requestedBehavior);
// TODO: Remove eslint-disable once we upgrade to a version that supports ?. notation.
// eslint-disable-next-line
delegate.handleSuccess?.(id);
} catch (error) {
// TODO: Remove eslint-disable once we upgrade to a version that supports ?. notation.
// eslint-disable-next-line
delegate.handleError?.(error);
}
}
);

handleTimeoutSubscription = notificationEmitter.addListener<HandleNotificationTimeoutEvent>(
handleNotificationTimeoutEventName,
({ id, notification }) => delegate.handleError?.(new NotificationTimeoutError(id, notification))
);
}
16 changes: 16 additions & 0 deletions packages/expo-notifications/src/NotificationsHandlerModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NativeModulesProxy, ProxyNativeModule } from '@unimodules/core';

export interface NotificationBehavior {
shouldShowAlert: boolean;
shouldPlaySound: boolean;
shouldSetBadge: boolean;
}

export interface NotificationsHandlerModule extends ProxyNativeModule {
handleNotificationAsync: (
notificationId: string,
notificationBehavior: NotificationBehavior
) => Promise<void>;
}

export default (NativeModulesProxy.ExpoNotificationsHandlerModule as any) as NotificationsHandlerModule;
1 change: 1 addition & 0 deletions packages/expo-notifications/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as getDevicePushTokenAsync } from './getDevicePushTokenAsync';
export * from './TokenEmitter';
export * from './NotificationsEmitter';
export * from './NotificationsHandler';

0 comments on commit 2b9d471

Please sign in to comment.