74 lines
2.2 KiB
JavaScript
74 lines
2.2 KiB
JavaScript
|
/**
|
||
|
* @flow
|
||
|
*/
|
||
|
import { NativeEventEmitter, NativeModules } from 'react-native';
|
||
|
import EventEmitter from './emitter/EventEmitter';
|
||
|
|
||
|
import type ModuleBase from './ModuleBase';
|
||
|
import type { FirebaseModuleConfig, FirebaseModuleName } from '../types';
|
||
|
|
||
|
const NATIVE_EMITTERS: { [string]: NativeEventEmitter } = {};
|
||
|
const NATIVE_SUBSCRIPTIONS: { [string]: boolean } = {};
|
||
|
|
||
|
export const SharedEventEmitter = new EventEmitter();
|
||
|
|
||
|
export const getAppEventName = (
|
||
|
module: ModuleBase,
|
||
|
eventName: string
|
||
|
): string => `${module.app.name}-${eventName}`;
|
||
|
|
||
|
const getNativeEmitter = (
|
||
|
moduleName: FirebaseModuleName,
|
||
|
module: ModuleBase
|
||
|
): NativeEventEmitter => {
|
||
|
const name = `${module.app.name}-${moduleName}`;
|
||
|
const nativeModule = NativeModules[moduleName];
|
||
|
if (!NATIVE_EMITTERS[name]) {
|
||
|
NATIVE_EMITTERS[name] = new NativeEventEmitter(nativeModule);
|
||
|
}
|
||
|
return NATIVE_EMITTERS[name];
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Subscribe to a native event for js side distribution by appName
|
||
|
* React Native events are hard set at compile - cant do dynamic event names
|
||
|
* so we use a single event send it to js and js then internally can prefix it
|
||
|
* and distribute dynamically.
|
||
|
*
|
||
|
* @param module
|
||
|
* @param eventName
|
||
|
* @private
|
||
|
*/
|
||
|
const subscribeToNativeModuleEvents = (
|
||
|
moduleName: FirebaseModuleName,
|
||
|
module: ModuleBase,
|
||
|
eventName: string
|
||
|
): void => {
|
||
|
if (!NATIVE_SUBSCRIPTIONS[eventName]) {
|
||
|
const nativeEmitter = getNativeEmitter(moduleName, module);
|
||
|
nativeEmitter.addListener(eventName, event => {
|
||
|
if (event.appName) {
|
||
|
// native event has an appName property - auto prefix and internally emit
|
||
|
SharedEventEmitter.emit(`${event.appName}-${eventName}`, event);
|
||
|
} else {
|
||
|
// standard event - no need to prefix
|
||
|
SharedEventEmitter.emit(eventName, event);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
NATIVE_SUBSCRIPTIONS[eventName] = true;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
export const initialiseNativeModuleEventEmitter = (
|
||
|
module: ModuleBase,
|
||
|
config: FirebaseModuleConfig
|
||
|
): void => {
|
||
|
const { events, moduleName } = config;
|
||
|
if (events && events.length) {
|
||
|
for (let i = 0, len = events.length; i < len; i++) {
|
||
|
subscribeToNativeModuleEvents(moduleName, module, events[i]);
|
||
|
}
|
||
|
}
|
||
|
};
|