forked from steipete/react-native-event-bridge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
148 lines (128 loc) · 4.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* EventBrige
* @flow
*/
// Native Event Bridge
// Wrapper around sending and receieving events that are related to components
// and view hierarchy of a root view
import React from 'react';
import {
findNodeHandle,
NativeModules,
NativeEventEmitter,
} from 'react-native';
import invariant from 'invariant';
import type EmitterSubscription from 'EmitterSubscription';
import enhanceForEventsSupport, {
enhanceForEventsSupportDecorator,
enhanceForEventsSupportEnhanced,
} from './react-native-event-bridge-enhance';
const { MSREventBridge } = NativeModules;
export type MSREventBridgeCallback = (error: ?any, data: ?any) => void;
// The react tag of the component acts as identifier to native. The native
// side will figure out the root view and dispatches it either to
// view / view controller or activity
// Emit an event to the native side
const emitEvent = (
component: React.Component<any, any, any>,
eventName: string,
info: any
) => {
let reactTag;
try {
reactTag = findNodeHandle(component);
} catch (err) {
return;
}
MSREventBridge.onEvent(reactTag, eventName, info);
};
// Emit an event to the native side and expect a callback
const emitEventCallback = (
component: React.Component<any, any, any>,
eventName: string,
info: any,
callback: MSREventBridgeCallback
): void => {
let reactTag;
try {
reactTag = findNodeHandle(component);
} catch (err) {
return;
}
MSREventBridge.onEventCallback(reactTag, eventName, info, callback);
};
// Event emitter to be able to emit events from the JavaScript side to native
const MSREventBridgeEventEmitter = new NativeEventEmitter(MSREventBridge);
const addEventListener = (
component: React.Component<any, any, any>,
callback: (string, any) => void
): EmitterSubscription => {
// Every component that would like to receive an event to native needs to have
// a rootTag in it's context otherwise it would not be possible to identify
// to which callback the event should be dispatched
const componentReactTag = component.context.rootTag;
invariant(
componentReactTag != null,
'If you would like receive events you have to define the reactTag in your contexts. Component: %s',
component.constructor.name
);
return MSREventBridgeEventEmitter.addListener(
MSREventBridge.EventName,
(body: any) => {
// Check if this event was directed to this subscritpion
const eventReactTag = body[MSREventBridge.EventReactTagKey];
// Check for react tag the same as the react tag passed in and dispatched to
// this means it was from the root node
if (componentReactTag !== eventReactTag) {
return;
}
// Let callback know about the event
const eventName = body[MSREventBridge.EventNameKey];
const eventInfo = body[MSREventBridge.EventInfoKey];
callback(eventName, eventInfo);
}
);
};
// Main handler that combines add a listener or emitting events from and to the
// native side
const EventBridge = {
// Add a listener for events that are dispatched from the native side
// It returns a EmitterSubscription you should store in your component and
// remove the component will unmount
addEventListener: (
component: React.Component<any, any, any>,
callback: any => void
): EmitterSubscription => addEventListener(component, callback),
// Emit an event to the native side
emitEvent: (
component: React.Component<any, any, any>,
eventName: string,
info: any
): void => {
emitEvent(component, eventName, info);
},
// Emit an event to the native side and expect a callback
emitEventCallback: (
component: React.Component<any, any, any>,
eventName: string,
callback: MSREventBridgeCallback
): void => {
emitEventCallback(component, eventName, null, callback);
},
// Emit an event to the native side and expect a callback
emitEventInfoCallback: (
component: React.Component<any, any, any>,
eventName: string,
info: any,
callback: MSREventBridgeCallback
): void => {
emitEventCallback(component, eventName, info, callback);
},
};
// Exports
export default EventBridge;
export {
enhanceForEventsSupport,
enhanceForEventsSupportEnhanced,
enhanceForEventsSupportDecorator,
};