2
0
mirror of synced 2025-03-01 06:20:33 +00:00

Add auto call to done which awaits the listener before doing so

The idea is to catch any cases where the API user is not calling done manually.
This has the issue that we've modified pre-existing function to take a
Promisified callback instead of just a callback. Any user upgrading to a
version that contains this that does not read the upgrade guide and make
appropriate changes will:
- be passing a plain callback (not promisified)
- not be calling done
- may be performing async (something that triggers a later callback) in their
onNotificationDisplayed handler.

This all means that we will be auto calling `done` prior to them performing
any background work. This is exactly how things worked prior to these changes
so perhaps the user is no worse off.
This commit is contained in:
Ryan Grey 2018-08-07 14:26:16 +01:00
parent 0291605934
commit ab42108234

@ -33,7 +33,17 @@ import type {
Schedule, Schedule,
} from './types'; } from './types';
type OnNotification = Notification => any; type BackgroundFetchResultValue = string;
type BackgroundFetchResult = {
noData: BackgroundFetchResultValue,
newData: BackgroundFetchResultValue,
failure: BackgroundFetchResultValue,
};
type CompletionHandler = BackgroundFetchResultValue => void;
type OnNotification = (Notification, CompletionHandler) => Promise<any>;
type OnNotificationObserver = { type OnNotificationObserver = {
next: OnNotification, next: OnNotification,
@ -45,12 +55,6 @@ type OnNotificationOpenedObserver = {
next: NotificationOpen, next: NotificationOpen,
}; };
type BackgroundFetchResult = {
noData: string,
newData: string,
failure: string,
};
const NATIVE_EVENTS = [ const NATIVE_EVENTS = [
'notifications_notification_displayed', 'notifications_notification_displayed',
'notifications_notification_opened', 'notifications_notification_opened',
@ -266,32 +270,36 @@ export default class Notifications extends ModuleBase {
onNotificationDisplayed( onNotificationDisplayed(
nextOrObserver: OnNotification | OnNotificationObserver nextOrObserver: OnNotification | OnNotificationObserver
): () => any { ): () => any {
let listener; const isNext = isFunction(nextOrObserver);
if (isFunction(nextOrObserver)) { const isObserver = isObject(nextOrObserver) && isFunction(nextOrObserver.next);
listener = nextOrObserver; if (!isNext && !isObserver) {
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
listener = nextOrObserver.next;
} else {
throw new Error( throw new Error(
'Notifications.onNotificationDisplayed failed: First argument must be a function or observer object with a `next` function.' 'Notifications.onNotificationDisplayed failed: First argument must be a function or observer object with a `next` function.'
); );
} }
let listener: OnNotification;
if (nextOrObserver.next) {
listener = nextOrObserver.next;
} else {
listener = nextOrObserver;
}
const autoCompletingListener: OnNotification = async (notification, done) => {
const listenerResult = await listener(notification, done);
done(this.backgroundFetchResult.noData);
return listenerResult;
};
getLogger(this).info('Creating onNotificationDisplayed listener'); getLogger(this).info('Creating onNotificationDisplayed listener');
SharedEventEmitter.addListener( SharedEventEmitter.addListener('onNotificationDisplayed', autoCompletingListener);
'onNotificationDisplayed',
listener
);
if (hasListeners('onNotificationDisplayed')) { if (hasListeners('onNotificationDisplayed')) {
getNativeModule(this).startHandlingNotificationDisplayed(); getNativeModule(this).startHandlingNotificationDisplayed();
} }
return () => { return () => {
getLogger(this).info('Removing onNotificationDisplayed listener'); getLogger(this).info('Removing onNotificationDisplayed listener');
SharedEventEmitter.removeListener( SharedEventEmitter.removeListener('onNotificationDisplayed', autoCompletingListener);
'onNotificationDisplayed',
listener
);
if (!hasListeners('onNotificationDisplayed')) { if (!hasListeners('onNotificationDisplayed')) {
getNativeModule(this).stopHandlingNotificationDisplayed(); getNativeModule(this).stopHandlingNotificationDisplayed();
} }