react-native-insider 8.1.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -660
- package/RNInsider.podspec +33 -12
- package/android/build.gradle +16 -2
- package/android/src/main/java/com/useinsider/react/RNInsiderAppFrameViewManager.java +253 -0
- package/android/src/main/java/com/useinsider/react/RNInsiderModule.java +238 -174
- package/android/src/main/java/com/useinsider/react/RNInsiderPackage.java +5 -1
- package/android/src/main/java/com/useinsider/react/RNUtils.java +111 -0
- package/babel.config.js +4 -1
- package/index.d.ts +196 -161
- package/index.js +60 -11
- package/ios/RNInsider/RNInsider.m +245 -341
- package/ios/RNInsider/RNInsiderAppFrameView.h +33 -0
- package/ios/RNInsider/RNInsiderAppFrameView.mm +315 -0
- package/ios/RNInsider/RNNotificationHandler.h +4 -1
- package/ios/RNInsider/RNNotificationHandler.m +16 -18
- package/ios/RNInsider/RNUtils.h +2 -0
- package/ios/RNInsider/RNUtils.m +79 -0
- package/package.json +43 -12
- package/src/EventHandler.js +17 -0
- package/src/InsiderAppFrame.d.ts +45 -0
- package/src/InsiderAppFrame.js +265 -0
- package/src/InsiderAppFrameLogic.d.ts +35 -0
- package/src/InsiderAppFrameLogic.js +192 -0
- package/src/InsiderAppFrameStatus.d.ts +22 -0
- package/src/InsiderAppFrameStatus.js +35 -0
- package/src/InsiderAppFramesError.d.ts +25 -0
- package/src/InsiderAppFramesError.js +77 -0
- package/src/InsiderEvent.js +1 -0
- package/src/InsiderEvents.d.ts +93 -0
- package/src/InsiderEvents.js +124 -0
- package/src/InsiderIdentifier.js +1 -1
- package/src/InsiderUser.d.ts +3 -2
- package/src/InsiderUser.js +27 -0
- package/src/Util.js +2 -1
- package/src/specs/InsiderAppFrameNativeComponent.ts +54 -0
- package/.orbit-output/config/MASTER.md +0 -129
- package/.orbit-output/config/architecture/API_DOCS.md +0 -342
- package/.orbit-output/config/architecture/ARCHITECTURE.md +0 -209
- package/.orbit-output/config/architecture/CODE-CATALOG.md +0 -172
- package/.orbit-output/config/architecture/project.yaml +0 -138
- package/.orbit-output/config/automation/AUTOMATION-SETUP.md +0 -50
- package/.orbit-output/config/enforcement/ENFORCEMENT-RULES.md +0 -41
- package/.orbit-output/config/enforcement/validate.sh +0 -49
- package/.orbit-output/skills/custom/academy-doc-generator.md +0 -598
- package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
- package/android/src/test/java/com/useinsider/react/RNInsiderModuleTest.java +0 -169
- package/docs/app-cards/app-cards_new.md +0 -569
- package/ios/RNInsiderTests/RNInsiderTriggerPushProcessTests.m +0 -91
package/RNInsider.podspec
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
require 'json'
|
|
2
|
+
require 'shellwords'
|
|
2
3
|
package_json = JSON.parse(File.read('package.json'))
|
|
3
4
|
|
|
5
|
+
react_native_search_root = defined?(Pod::Config) ? Pod::Config.instance.installation_root.to_s : __dir__
|
|
6
|
+
|
|
7
|
+
# A standard React Native Podfile has already required react_native_pods by the time this runs,
|
|
8
|
+
# so a failure here is only fatal when nothing else defined install_modules_dependencies.
|
|
9
|
+
react_native_pods_load_error = nil
|
|
10
|
+
begin
|
|
11
|
+
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json', {paths: [process.argv[1]]})" #{Shellwords.escape(react_native_search_root)}`), "scripts/react_native_pods")
|
|
12
|
+
rescue LoadError, Errno::ENOENT => e
|
|
13
|
+
react_native_pods_load_error = e
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
unless defined?(install_modules_dependencies)
|
|
17
|
+
raise Pod::Informative, "[RNInsider] Could not load react-native/scripts/react_native_pods.rb " \
|
|
18
|
+
"resolving react-native from #{react_native_search_root}: " \
|
|
19
|
+
"#{react_native_pods_load_error&.message || 'install_modules_dependencies is undefined'}. " \
|
|
20
|
+
"Make sure node is on PATH and react-native is installed for this app"
|
|
21
|
+
end
|
|
22
|
+
|
|
4
23
|
Pod::Spec.new do |s|
|
|
5
24
|
s.name = 'RNInsider'
|
|
6
25
|
s.version = package_json['version']
|
|
@@ -9,19 +28,21 @@ Pod::Spec.new do |s|
|
|
|
9
28
|
s.authors = package_json['author']
|
|
10
29
|
s.license = 'MIT'
|
|
11
30
|
s.platform = :ios, '12.0'
|
|
12
|
-
s.source = {:http => 'https://mobilesdk.useinsider.com/iOS/
|
|
13
|
-
s.source_files = 'ios/RNInsider/*.{h,m}'
|
|
31
|
+
s.source = {:http => 'https://mobilesdk.useinsider.com/iOS/16.2.1/InsiderMobileIOSFramework.zip'}
|
|
32
|
+
s.source_files = 'ios/RNInsider/*.{h,m,mm}'
|
|
14
33
|
s.requires_arc = true
|
|
34
|
+
s.compiler_flags = '-fobjc-arc-exceptions'
|
|
15
35
|
s.static_framework = true
|
|
16
|
-
s
|
|
17
|
-
s.dependency 'InsiderMobile', '
|
|
18
|
-
s.dependency 'InsiderGeofence', '1.
|
|
19
|
-
s.dependency 'InsiderHybrid', '1.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
install_modules_dependencies(s)
|
|
37
|
+
s.dependency 'InsiderMobile', '16.2.1'
|
|
38
|
+
s.dependency 'InsiderGeofence', '1.3.0'
|
|
39
|
+
s.dependency 'InsiderHybrid', '1.8.0'
|
|
40
|
+
if Dir.exist?(File.join(__dir__, 'ios', 'RNInsiderTests'))
|
|
41
|
+
s.test_spec 'Tests' do |test_spec|
|
|
42
|
+
test_spec.source_files = 'ios/RNInsiderTests/**/*.{h,m,mm}'
|
|
43
|
+
test_spec.frameworks = 'XCTest'
|
|
44
|
+
test_spec.requires_app_host = false
|
|
45
|
+
test_spec.dependency 'OCMock', '~> 3.9'
|
|
46
|
+
end
|
|
26
47
|
end
|
|
27
48
|
end
|
package/android/build.gradle
CHANGED
|
@@ -7,10 +7,20 @@ buildscript {
|
|
|
7
7
|
|
|
8
8
|
dependencies {
|
|
9
9
|
classpath 'com.android.tools.build:gradle:8.4.2'
|
|
10
|
+
classpath 'com.facebook.react:react-native-gradle-plugin'
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
apply plugin: 'com.android.library'
|
|
15
|
+
apply plugin: 'com.facebook.react'
|
|
16
|
+
|
|
17
|
+
// Codegen runs on this package's own specs: RNInsiderAppFrameViewManager implements the generated
|
|
18
|
+
// interface, so it must exist when the library compiles. libraryName must match codegenConfig.name.
|
|
19
|
+
react {
|
|
20
|
+
jsRootDir = file("../src/specs")
|
|
21
|
+
libraryName = "RNInsiderSpec"
|
|
22
|
+
codegenJavaPackageName = "com.useinsider.react"
|
|
23
|
+
}
|
|
14
24
|
|
|
15
25
|
def getVersionFromPartner(config, fallback) {
|
|
16
26
|
rootProject.ext.has(config) ? rootProject.ext.get(config) : fallback
|
|
@@ -47,14 +57,18 @@ repositories {
|
|
|
47
57
|
|
|
48
58
|
dependencies {
|
|
49
59
|
implementation "com.facebook.react:react-native:${getVersionFromPartner('reactNativeVersion', '+')}"
|
|
50
|
-
implementation 'com.useinsider:insider:
|
|
51
|
-
implementation 'com.useinsider:insiderhybrid:1.
|
|
60
|
+
implementation 'com.useinsider:insider:17.3.1'
|
|
61
|
+
implementation 'com.useinsider:insiderhybrid:1.4.0'
|
|
52
62
|
|
|
53
63
|
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
|
|
54
64
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
|
55
65
|
implementation 'androidx.lifecycle:lifecycle-process:2.8.3'
|
|
56
66
|
implementation "androidx.work:work-runtime:2.9.1"
|
|
57
67
|
|
|
68
|
+
// App Frames needs webkit at runtime (compileOnly in the native SDK); without it template actions
|
|
69
|
+
// never arrive. Held below 1.16.0, whose kotlin-stdlib 2.1 breaks older-Kotlin hosts (RN 0.76).
|
|
70
|
+
implementation 'androidx.webkit:webkit:1.15.0'
|
|
71
|
+
|
|
58
72
|
implementation 'com.google.firebase:firebase-messaging:24.0.0'
|
|
59
73
|
implementation 'com.google.android.gms:play-services-location:21.3.0'
|
|
60
74
|
implementation 'com.google.android.play:review:2.0.1'
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
package com.useinsider.react;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import androidx.annotation.Nullable;
|
|
5
|
+
|
|
6
|
+
import com.facebook.react.bridge.ReactContext;
|
|
7
|
+
import com.facebook.react.bridge.WritableMap;
|
|
8
|
+
import com.facebook.react.bridge.Arguments;
|
|
9
|
+
import com.facebook.react.module.annotations.ReactModule;
|
|
10
|
+
import com.facebook.react.uimanager.SimpleViewManager;
|
|
11
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
12
|
+
import com.facebook.react.uimanager.UIManagerHelper;
|
|
13
|
+
import com.facebook.react.uimanager.ViewManagerDelegate;
|
|
14
|
+
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
15
|
+
import com.facebook.react.uimanager.events.Event;
|
|
16
|
+
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
17
|
+
import com.facebook.react.viewmanagers.InsiderAppFrameViewManagerDelegate;
|
|
18
|
+
import com.facebook.react.viewmanagers.InsiderAppFrameViewManagerInterface;
|
|
19
|
+
|
|
20
|
+
import com.useinsider.insider.Insider;
|
|
21
|
+
import com.useinsider.insider.InsiderAppFramesError;
|
|
22
|
+
import com.useinsider.insider.InsiderAppFramesView;
|
|
23
|
+
import com.useinsider.insider.InsiderAppFramesViewListener;
|
|
24
|
+
import com.useinsider.insider.InsiderAppFramesViewStatus;
|
|
25
|
+
|
|
26
|
+
import org.json.JSONObject;
|
|
27
|
+
|
|
28
|
+
import java.util.HashMap;
|
|
29
|
+
import java.util.Map;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Fabric ViewManager for the {@code InsiderAppFrameView} component, backed by the native
|
|
33
|
+
* {@link InsiderAppFramesView}.
|
|
34
|
+
*
|
|
35
|
+
* <p>Status and error codes are forwarded as enum {@code name()}s, which must match the values in
|
|
36
|
+
* {@code src/InsiderAppFrameStatus.js} and {@code src/InsiderAppFramesError.js}. There is no
|
|
37
|
+
* compile-time link: a rename on one side shows up only as an unrecognized value at runtime.</p>
|
|
38
|
+
*/
|
|
39
|
+
@ReactModule(name = RNInsiderAppFrameViewManager.NAME)
|
|
40
|
+
public class RNInsiderAppFrameViewManager
|
|
41
|
+
extends SimpleViewManager<InsiderAppFramesView>
|
|
42
|
+
implements InsiderAppFrameViewManagerInterface<InsiderAppFramesView> {
|
|
43
|
+
|
|
44
|
+
public static final String NAME = "InsiderAppFrameView";
|
|
45
|
+
|
|
46
|
+
private final ViewManagerDelegate<InsiderAppFramesView> delegate =
|
|
47
|
+
new InsiderAppFrameViewManagerDelegate<>(this);
|
|
48
|
+
|
|
49
|
+
// Event names and payload keys must match src/specs/InsiderAppFrameNativeComponent.ts;
|
|
50
|
+
// a mismatch fails silently at runtime.
|
|
51
|
+
private static final String EVENT_ON_STATUS_CHANGE = "onStatusChange";
|
|
52
|
+
private static final String EVENT_ON_LOAD_ERROR = "onLoadError";
|
|
53
|
+
private static final String EVENT_ON_HEIGHT_CHANGE = "onHeightChange";
|
|
54
|
+
private static final String EVENT_ON_DISMISS_REQUEST = "onDismissRequest";
|
|
55
|
+
private static final String EVENT_ON_ACTION = "onAction";
|
|
56
|
+
|
|
57
|
+
private static final String KEY_PLACEMENT_ID = "placementId";
|
|
58
|
+
private static final String KEY_STATUS = "status";
|
|
59
|
+
private static final String KEY_PREVIOUS_STATUS = "previousStatus";
|
|
60
|
+
private static final String KEY_CODE = "code";
|
|
61
|
+
private static final String KEY_MESSAGE = "message";
|
|
62
|
+
private static final String KEY_CAUSE = "cause";
|
|
63
|
+
private static final String KEY_DISMISS_CODE = "dismissCode";
|
|
64
|
+
private static final String KEY_HEIGHT = "height";
|
|
65
|
+
private static final String KEY_DATA = "data";
|
|
66
|
+
|
|
67
|
+
private static final String ERROR_CODE_UNKNOWN = "UNKNOWN";
|
|
68
|
+
private static final String EMPTY_ACTION_DATA = "{}";
|
|
69
|
+
|
|
70
|
+
@NonNull
|
|
71
|
+
@Override
|
|
72
|
+
public String getName() {
|
|
73
|
+
return NAME;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@Nullable
|
|
77
|
+
@Override
|
|
78
|
+
protected ViewManagerDelegate<InsiderAppFramesView> getDelegate() {
|
|
79
|
+
return delegate;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@NonNull
|
|
83
|
+
@Override
|
|
84
|
+
protected InsiderAppFramesView createViewInstance(@NonNull ThemedReactContext context) {
|
|
85
|
+
InsiderAppFramesView view = new InsiderAppFramesView(context);
|
|
86
|
+
view.setAppFramesListener(new FrameListener());
|
|
87
|
+
return view;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@Override
|
|
91
|
+
public void onDropViewInstance(@NonNull InsiderAppFramesView view) {
|
|
92
|
+
view.setAppFramesListener(null);
|
|
93
|
+
super.onDropViewInstance(view);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@Override
|
|
97
|
+
@ReactProp(name = "placementId")
|
|
98
|
+
public void setPlacementId(InsiderAppFramesView view, @Nullable String placementId) {
|
|
99
|
+
view.setPlacementId(placementId);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@Override
|
|
103
|
+
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
104
|
+
// Extend super's map: it registers onAccessibilityAction, which NativeProps inherits
|
|
105
|
+
// from ViewProps. ViewManager's base implementation returns null.
|
|
106
|
+
Map<String, Object> events = super.getExportedCustomDirectEventTypeConstants();
|
|
107
|
+
if (events == null) {
|
|
108
|
+
events = new HashMap<>();
|
|
109
|
+
}
|
|
110
|
+
for (String name : new String[]{
|
|
111
|
+
EVENT_ON_STATUS_CHANGE, EVENT_ON_LOAD_ERROR,
|
|
112
|
+
EVENT_ON_HEIGHT_CHANGE, EVENT_ON_DISMISS_REQUEST, EVENT_ON_ACTION}) {
|
|
113
|
+
events.put(name, mapBuilderOf("registrationName", name));
|
|
114
|
+
}
|
|
115
|
+
return events;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private static Map<String, String> mapBuilderOf(String key, String value) {
|
|
119
|
+
Map<String, String> map = new HashMap<>();
|
|
120
|
+
map.put(key, value);
|
|
121
|
+
return map;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private void emit(InsiderAppFramesView view, String eventName, WritableMap payload) {
|
|
125
|
+
ReactContext reactContext = UIManagerHelper.getReactContext(view);
|
|
126
|
+
EventDispatcher dispatcher =
|
|
127
|
+
UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.getId());
|
|
128
|
+
if (dispatcher == null) {
|
|
129
|
+
// Not expected: Fabric records the event emitter before creating the view. Reported
|
|
130
|
+
// because JS mirrors status and error from these events, so a drop would desync it.
|
|
131
|
+
reportDroppedEvent(eventName, view.getId());
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
dispatcher.dispatchEvent(new FrameEvent(
|
|
135
|
+
UIManagerHelper.getSurfaceId(view), view.getId(), eventName, payload));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Reports through the SDK's error channel, like the rest of this bridge, rather than logcat.
|
|
140
|
+
* Package-private as a test seam: {@code Insider.Instance} cannot be stubbed.
|
|
141
|
+
*/
|
|
142
|
+
void reportDroppedEvent(String eventName, int viewId) {
|
|
143
|
+
Insider.Instance.putException(new IllegalStateException(
|
|
144
|
+
"Dropped " + eventName + ": no EventDispatcher for view " + viewId + " yet."));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Reports an action payload that could not be serialized and reaches JS as {@code {}}.
|
|
149
|
+
* Package-private as a test seam, like {@link #reportDroppedEvent}.
|
|
150
|
+
*/
|
|
151
|
+
void reportUnserializableAction(int viewId) {
|
|
152
|
+
Insider.Instance.putException(new IllegalStateException(
|
|
153
|
+
"Action data for view " + viewId + " could not be serialized; forwarding {}."));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private static WritableMap basePayload(InsiderAppFramesView view) {
|
|
157
|
+
WritableMap payload = Arguments.createMap();
|
|
158
|
+
String placementId = view.getPlacementId();
|
|
159
|
+
payload.putString(KEY_PLACEMENT_ID, placementId == null ? "" : placementId);
|
|
160
|
+
return payload;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private static class FrameEvent extends Event<FrameEvent> {
|
|
164
|
+
private final String eventName;
|
|
165
|
+
private final WritableMap payload;
|
|
166
|
+
|
|
167
|
+
FrameEvent(int surfaceId, int viewTag, String eventName, WritableMap payload) {
|
|
168
|
+
super(surfaceId, viewTag);
|
|
169
|
+
this.eventName = eventName;
|
|
170
|
+
this.payload = payload;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@Override
|
|
174
|
+
public String getEventName() {
|
|
175
|
+
return eventName;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@Override
|
|
179
|
+
protected WritableMap getEventData() {
|
|
180
|
+
return payload;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@Override
|
|
184
|
+
public boolean canCoalesce() {
|
|
185
|
+
// Event coalesces same-name events by default, which would drop status transitions
|
|
186
|
+
// and heights; both native SDKs deliver every event, so none of the five coalesce.
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private class FrameListener implements InsiderAppFramesViewListener {
|
|
192
|
+
@Override
|
|
193
|
+
public void onStatusChanged(@NonNull InsiderAppFramesView view,
|
|
194
|
+
@NonNull InsiderAppFramesViewStatus status,
|
|
195
|
+
@NonNull InsiderAppFramesViewStatus previousStatus) {
|
|
196
|
+
WritableMap payload = basePayload(view);
|
|
197
|
+
payload.putString(KEY_STATUS, status.name());
|
|
198
|
+
payload.putString(KEY_PREVIOUS_STATUS, previousStatus.name());
|
|
199
|
+
emit(view, EVENT_ON_STATUS_CHANGE, payload);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@Override
|
|
203
|
+
public void onLoadFailed(@NonNull InsiderAppFramesView view,
|
|
204
|
+
@NonNull InsiderAppFramesError error) {
|
|
205
|
+
WritableMap payload = basePayload(view);
|
|
206
|
+
payload.putString(KEY_CODE, error.getCode() == null
|
|
207
|
+
? ERROR_CODE_UNKNOWN : error.getCode().name());
|
|
208
|
+
// The canonical per-code text, the same text iOS sends as localizedDescription.
|
|
209
|
+
payload.putString(KEY_MESSAGE, error.getMessage() == null ? "" : error.getMessage());
|
|
210
|
+
// Only the message crosses the bridge; empty rather than null because the codegen
|
|
211
|
+
// payload is non-nullable.
|
|
212
|
+
Throwable cause = error.getCause();
|
|
213
|
+
payload.putString(KEY_CAUSE,
|
|
214
|
+
cause == null || cause.getMessage() == null ? "" : cause.getMessage());
|
|
215
|
+
// NO_DISMISS_CODE (-1) unless a template reported a dismissal.
|
|
216
|
+
payload.putInt(KEY_DISMISS_CODE, error.getDismissCode());
|
|
217
|
+
emit(view, EVENT_ON_LOAD_ERROR, payload);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
@Override
|
|
221
|
+
public void onHeightChangeRequested(@NonNull InsiderAppFramesView view, int optimalHeight) {
|
|
222
|
+
// The SDK reports px; React Native layout uses dp, as iOS already reports.
|
|
223
|
+
double heightDp = optimalHeight / view.getResources().getDisplayMetrics().density;
|
|
224
|
+
|
|
225
|
+
WritableMap payload = basePayload(view);
|
|
226
|
+
payload.putDouble(KEY_HEIGHT, heightDp);
|
|
227
|
+
// JS applies the height: Fabric always passes an EXACTLY measure spec, so the native
|
|
228
|
+
// view cannot size itself.
|
|
229
|
+
emit(view, EVENT_ON_HEIGHT_CHANGE, payload);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@Override
|
|
233
|
+
public void onDismissRequested(@NonNull InsiderAppFramesView view) {
|
|
234
|
+
// Event only: collapsing the slot is the host app's decision, as on native.
|
|
235
|
+
emit(view, EVENT_ON_DISMISS_REQUEST, basePayload(view));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
@Override
|
|
239
|
+
public void onActionTriggered(@NonNull InsiderAppFramesView view,
|
|
240
|
+
@NonNull JSONObject actionData) {
|
|
241
|
+
WritableMap payload = basePayload(view);
|
|
242
|
+
// toString() returns null when serialization fails (e.g. NaN), but the codegen
|
|
243
|
+
// payload is non-nullable.
|
|
244
|
+
String json = actionData.toString();
|
|
245
|
+
if (json == null) {
|
|
246
|
+
reportUnserializableAction(view.getId());
|
|
247
|
+
json = EMPTY_ACTION_DATA;
|
|
248
|
+
}
|
|
249
|
+
payload.putString(KEY_DATA, json);
|
|
250
|
+
emit(view, EVENT_ON_ACTION, payload);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|