@kontextso/sdk-react-native 2.1.1-rc.1 → 2.2.0-rc.1
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/dist/index.js +188 -59
- package/dist/index.mjs +178 -49
- package/package.json +2 -2
- package/src/context/AdsProvider.tsx +0 -2
- package/src/formats/Format.tsx +153 -46
- package/src/frame-webview.tsx +43 -0
package/dist/index.js
CHANGED
|
@@ -36,9 +36,8 @@ __export(index_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
37
|
|
|
38
38
|
// src/formats/Format.tsx
|
|
39
|
-
var
|
|
39
|
+
var import_react2 = require("react");
|
|
40
40
|
var import_sdk_react = require("@kontextso/sdk-react");
|
|
41
|
-
var import_react_native_webview = require("react-native-webview");
|
|
42
41
|
var import_react_native = require("react-native");
|
|
43
42
|
|
|
44
43
|
// ../sdk-common/dist/index.mjs
|
|
@@ -59,8 +58,44 @@ function handleIframeMessage(handler, opts) {
|
|
|
59
58
|
};
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
// src/
|
|
61
|
+
// src/frame-webview.tsx
|
|
62
|
+
var import_react = require("react");
|
|
63
|
+
var import_react_native_webview = require("react-native-webview");
|
|
63
64
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
65
|
+
var FrameWebView = (0, import_react.forwardRef)(
|
|
66
|
+
({ iframeUrl, onMessage, style, onError, onLoad }, forwardedRef) => {
|
|
67
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
68
|
+
import_react_native_webview.WebView,
|
|
69
|
+
{
|
|
70
|
+
ref: forwardedRef,
|
|
71
|
+
source: {
|
|
72
|
+
uri: iframeUrl
|
|
73
|
+
},
|
|
74
|
+
onMessage,
|
|
75
|
+
style,
|
|
76
|
+
allowsInlineMediaPlayback: true,
|
|
77
|
+
mediaPlaybackRequiresUserAction: false,
|
|
78
|
+
javaScriptEnabled: true,
|
|
79
|
+
domStorageEnabled: true,
|
|
80
|
+
allowsFullscreenVideo: false,
|
|
81
|
+
injectedJavaScript: `
|
|
82
|
+
window.addEventListener("message", function(event) {
|
|
83
|
+
if (window.ReactNativeWebView && event.data) {
|
|
84
|
+
// ReactNativeWebView.postMessage only supports string data
|
|
85
|
+
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
|
|
86
|
+
}
|
|
87
|
+
}, false);
|
|
88
|
+
`,
|
|
89
|
+
onError,
|
|
90
|
+
onLoad
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
var frame_webview_default = FrameWebView;
|
|
96
|
+
|
|
97
|
+
// src/formats/Format.tsx
|
|
98
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
64
99
|
var sendMessage = (webViewRef, type, code, data) => {
|
|
65
100
|
const message = makeIframeMessage(type, {
|
|
66
101
|
data,
|
|
@@ -73,16 +108,22 @@ var sendMessage = (webViewRef, type, code, data) => {
|
|
|
73
108
|
`);
|
|
74
109
|
};
|
|
75
110
|
var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
76
|
-
const context = (0,
|
|
111
|
+
const context = (0, import_react2.useContext)(import_sdk_react.AdsContext);
|
|
77
112
|
const bid = (0, import_sdk_react.useBid)({ code, messageId });
|
|
78
|
-
const [height, setHeight] = (0,
|
|
79
|
-
const iframeUrl = (0, import_sdk_react.useIframeUrl)(context, bid, code, messageId);
|
|
80
|
-
const
|
|
81
|
-
const [
|
|
82
|
-
const [
|
|
83
|
-
const [
|
|
84
|
-
const
|
|
85
|
-
const
|
|
113
|
+
const [height, setHeight] = (0, import_react2.useState)(0);
|
|
114
|
+
const iframeUrl = (0, import_sdk_react.useIframeUrl)(context, bid, code, messageId, "sdk-react-native", otherParams.theme);
|
|
115
|
+
const modalUrl = iframeUrl.replace("/api/frame/", "/api/modal/");
|
|
116
|
+
const [showIframe, setShowIframe] = (0, import_react2.useState)(false);
|
|
117
|
+
const [iframeLoaded, setIframeLoaded] = (0, import_react2.useState)(false);
|
|
118
|
+
const [modalOpen, setModalOpen] = (0, import_react2.useState)(false);
|
|
119
|
+
const [modalShown, setModalShown] = (0, import_react2.useState)(false);
|
|
120
|
+
const [modalLoaded, setModalLoaded] = (0, import_react2.useState)(false);
|
|
121
|
+
const [containerStyles, setContainerStyles] = (0, import_react2.useState)({});
|
|
122
|
+
const [iframeStyles, setIframeStyles] = (0, import_react2.useState)({});
|
|
123
|
+
const containerRef = (0, import_react2.useRef)(null);
|
|
124
|
+
const webViewRef = (0, import_react2.useRef)(null);
|
|
125
|
+
const modalWebViewRef = (0, import_react2.useRef)(null);
|
|
126
|
+
const modalInitTimeoutRef = (0, import_react2.useRef)(null);
|
|
86
127
|
const { height: windowHeight, width: windowWidth } = (0, import_react_native.useWindowDimensions)();
|
|
87
128
|
const reset = () => {
|
|
88
129
|
setHeight(0);
|
|
@@ -90,9 +131,19 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
90
131
|
setContainerStyles({});
|
|
91
132
|
setIframeStyles({});
|
|
92
133
|
setIframeLoaded(false);
|
|
134
|
+
resetModal();
|
|
93
135
|
context?.resetAll();
|
|
94
136
|
context?.captureError(new Error("Processing iframe error"));
|
|
95
137
|
};
|
|
138
|
+
const resetModal = () => {
|
|
139
|
+
if (modalInitTimeoutRef.current) {
|
|
140
|
+
clearTimeout(modalInitTimeoutRef.current);
|
|
141
|
+
modalInitTimeoutRef.current = null;
|
|
142
|
+
}
|
|
143
|
+
setModalOpen(false);
|
|
144
|
+
setModalLoaded(false);
|
|
145
|
+
setModalShown(false);
|
|
146
|
+
};
|
|
96
147
|
const debug = (name, data = {}) => {
|
|
97
148
|
context?.onDebugEventInternal?.(name, {
|
|
98
149
|
code,
|
|
@@ -108,6 +159,19 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
108
159
|
...data
|
|
109
160
|
});
|
|
110
161
|
};
|
|
162
|
+
const debugModal = (name, data = {}) => {
|
|
163
|
+
context?.onDebugEventInternal?.(name, {
|
|
164
|
+
code,
|
|
165
|
+
messageId,
|
|
166
|
+
otherParams,
|
|
167
|
+
bid,
|
|
168
|
+
modalUrl,
|
|
169
|
+
modalOpen,
|
|
170
|
+
modalShown,
|
|
171
|
+
modalLoaded,
|
|
172
|
+
...data
|
|
173
|
+
});
|
|
174
|
+
};
|
|
111
175
|
debug("format-update-state");
|
|
112
176
|
const onMessage = (event) => {
|
|
113
177
|
try {
|
|
@@ -155,6 +219,10 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
155
219
|
setContainerStyles(message.data.containerStyles);
|
|
156
220
|
setIframeStyles(message.data.iframeStyles);
|
|
157
221
|
break;
|
|
222
|
+
case "open-component-iframe":
|
|
223
|
+
setModalOpen(true);
|
|
224
|
+
modalInitTimeoutRef.current = setTimeout(resetModal, message.data.timeout ?? 5e3);
|
|
225
|
+
break;
|
|
158
226
|
}
|
|
159
227
|
},
|
|
160
228
|
{
|
|
@@ -170,8 +238,55 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
170
238
|
reset();
|
|
171
239
|
}
|
|
172
240
|
};
|
|
241
|
+
const onModalMessage = (event) => {
|
|
242
|
+
try {
|
|
243
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
244
|
+
debugModal("modal-iframe-message", {
|
|
245
|
+
message: data
|
|
246
|
+
});
|
|
247
|
+
const messageHandler = handleIframeMessage(
|
|
248
|
+
(message) => {
|
|
249
|
+
switch (message.type) {
|
|
250
|
+
case "close-component-iframe":
|
|
251
|
+
resetModal();
|
|
252
|
+
break;
|
|
253
|
+
case "init-component-iframe":
|
|
254
|
+
if (modalInitTimeoutRef.current) {
|
|
255
|
+
clearTimeout(modalInitTimeoutRef.current);
|
|
256
|
+
modalInitTimeoutRef.current = null;
|
|
257
|
+
}
|
|
258
|
+
setModalShown(true);
|
|
259
|
+
break;
|
|
260
|
+
case "error-component-iframe":
|
|
261
|
+
case "error-iframe":
|
|
262
|
+
resetModal();
|
|
263
|
+
break;
|
|
264
|
+
case "click-iframe":
|
|
265
|
+
if (message.data.url) {
|
|
266
|
+
import_react_native.Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch(
|
|
267
|
+
(err) => console.error("error opening url", err)
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
context?.onAdClickInternal(message.data);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
code,
|
|
276
|
+
component: "modal"
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
messageHandler({ data });
|
|
280
|
+
} catch (e) {
|
|
281
|
+
debugModal("modal-iframe-message-error", {
|
|
282
|
+
error: e
|
|
283
|
+
});
|
|
284
|
+
console.error("error parsing message from webview", e);
|
|
285
|
+
resetModal();
|
|
286
|
+
}
|
|
287
|
+
};
|
|
173
288
|
const paramsString = (0, import_sdk_react.convertParamsToString)(otherParams);
|
|
174
|
-
(0,
|
|
289
|
+
(0, import_react2.useEffect)(() => {
|
|
175
290
|
if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
|
|
176
291
|
return;
|
|
177
292
|
}
|
|
@@ -194,7 +309,7 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
194
309
|
});
|
|
195
310
|
});
|
|
196
311
|
};
|
|
197
|
-
(0,
|
|
312
|
+
(0, import_react2.useEffect)(() => {
|
|
198
313
|
const interval = setInterval(() => {
|
|
199
314
|
checkIfInViewport();
|
|
200
315
|
}, 250);
|
|
@@ -215,57 +330,71 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
215
330
|
}
|
|
216
331
|
return 0;
|
|
217
332
|
};
|
|
218
|
-
const content = /* @__PURE__ */ (0,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
// ReactNativeWebView.postMessage only supports string data
|
|
247
|
-
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
|
|
333
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
334
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native.Modal, { visible: modalOpen, transparent: true, onRequestClose: resetModal, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
335
|
+
import_react_native.View,
|
|
336
|
+
{
|
|
337
|
+
style: {
|
|
338
|
+
flex: 1,
|
|
339
|
+
// Don't show the modal until the modal page is loaded and sends 'init-component-iframe' message back to SDK
|
|
340
|
+
...modalShown ? { opacity: 1, pointerEvents: "auto" } : { opacity: 0, pointerEvents: "none" }
|
|
341
|
+
},
|
|
342
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
343
|
+
frame_webview_default,
|
|
344
|
+
{
|
|
345
|
+
ref: modalWebViewRef,
|
|
346
|
+
iframeUrl: modalUrl,
|
|
347
|
+
onMessage: onModalMessage,
|
|
348
|
+
style: {
|
|
349
|
+
backgroundColor: "transparent",
|
|
350
|
+
height: "100%",
|
|
351
|
+
width: "100%",
|
|
352
|
+
borderWidth: 0
|
|
353
|
+
},
|
|
354
|
+
onError: () => {
|
|
355
|
+
debug("modal-error");
|
|
356
|
+
resetModal();
|
|
357
|
+
},
|
|
358
|
+
onLoad: () => {
|
|
359
|
+
debug("modal-load");
|
|
360
|
+
setModalLoaded(true);
|
|
248
361
|
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
onError: () => {
|
|
252
|
-
debug("iframe-error");
|
|
253
|
-
reset();
|
|
254
|
-
},
|
|
255
|
-
onLoad: () => {
|
|
256
|
-
debug("iframe-load");
|
|
362
|
+
}
|
|
363
|
+
)
|
|
257
364
|
}
|
|
258
|
-
}
|
|
259
|
-
|
|
365
|
+
) }),
|
|
366
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native.View, { style: containerStyles, ref: containerRef, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
367
|
+
frame_webview_default,
|
|
368
|
+
{
|
|
369
|
+
ref: webViewRef,
|
|
370
|
+
iframeUrl,
|
|
371
|
+
onMessage,
|
|
372
|
+
style: {
|
|
373
|
+
height: getHeight(),
|
|
374
|
+
width: getWidth(),
|
|
375
|
+
background: "transparent",
|
|
376
|
+
borderWidth: 0,
|
|
377
|
+
...iframeStyles
|
|
378
|
+
},
|
|
379
|
+
onError: () => {
|
|
380
|
+
debug("iframe-error");
|
|
381
|
+
reset();
|
|
382
|
+
},
|
|
383
|
+
onLoad: () => {
|
|
384
|
+
debug("iframe-load");
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
) })
|
|
388
|
+
] });
|
|
260
389
|
return wrapper ? wrapper(content) : content;
|
|
261
390
|
};
|
|
262
|
-
var FormatWithErrorBoundary = (props) => /* @__PURE__ */ (0,
|
|
391
|
+
var FormatWithErrorBoundary = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sdk_react.ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Format, { ...props }) });
|
|
263
392
|
var Format_default = FormatWithErrorBoundary;
|
|
264
393
|
|
|
265
394
|
// src/formats/InlineAd.tsx
|
|
266
|
-
var
|
|
395
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
267
396
|
var InlineAd = ({ code, messageId, wrapper, ...props }) => {
|
|
268
|
-
return /* @__PURE__ */ (0,
|
|
397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Format_default, { code, messageId, wrapper, ...props });
|
|
269
398
|
};
|
|
270
399
|
var InlineAd_default = InlineAd;
|
|
271
400
|
|
|
@@ -279,7 +408,7 @@ var import_react_native2 = require("react-native");
|
|
|
279
408
|
var NativeRNKontext_default = import_react_native2.TurboModuleRegistry.getEnforcing("RNKontext");
|
|
280
409
|
|
|
281
410
|
// src/context/AdsProvider.tsx
|
|
282
|
-
var
|
|
411
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
283
412
|
ErrorUtils.setGlobalHandler((error, isFatal) => {
|
|
284
413
|
if (!isFatal) {
|
|
285
414
|
import_sdk_react2.log.warn(error);
|
|
@@ -323,7 +452,7 @@ var getDevice = async () => {
|
|
|
323
452
|
return {};
|
|
324
453
|
};
|
|
325
454
|
var AdsProvider = (props) => {
|
|
326
|
-
return /* @__PURE__ */ (0,
|
|
455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_sdk_react2.AdsProviderInternal, { ...props, getDevice });
|
|
327
456
|
};
|
|
328
457
|
// Annotate the CommonJS export names for ESM import in node:
|
|
329
458
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -7,8 +7,7 @@ import {
|
|
|
7
7
|
useBid,
|
|
8
8
|
useIframeUrl
|
|
9
9
|
} from "@kontextso/sdk-react";
|
|
10
|
-
import {
|
|
11
|
-
import { Linking, View, useWindowDimensions } from "react-native";
|
|
10
|
+
import { Linking, Modal, View, useWindowDimensions } from "react-native";
|
|
12
11
|
|
|
13
12
|
// ../sdk-common/dist/index.mjs
|
|
14
13
|
function makeIframeMessage(type, opts) {
|
|
@@ -28,8 +27,44 @@ function handleIframeMessage(handler, opts) {
|
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
// src/
|
|
30
|
+
// src/frame-webview.tsx
|
|
31
|
+
import { forwardRef } from "react";
|
|
32
|
+
import { WebView } from "react-native-webview";
|
|
32
33
|
import { jsx } from "react/jsx-runtime";
|
|
34
|
+
var FrameWebView = forwardRef(
|
|
35
|
+
({ iframeUrl, onMessage, style, onError, onLoad }, forwardedRef) => {
|
|
36
|
+
return /* @__PURE__ */ jsx(
|
|
37
|
+
WebView,
|
|
38
|
+
{
|
|
39
|
+
ref: forwardedRef,
|
|
40
|
+
source: {
|
|
41
|
+
uri: iframeUrl
|
|
42
|
+
},
|
|
43
|
+
onMessage,
|
|
44
|
+
style,
|
|
45
|
+
allowsInlineMediaPlayback: true,
|
|
46
|
+
mediaPlaybackRequiresUserAction: false,
|
|
47
|
+
javaScriptEnabled: true,
|
|
48
|
+
domStorageEnabled: true,
|
|
49
|
+
allowsFullscreenVideo: false,
|
|
50
|
+
injectedJavaScript: `
|
|
51
|
+
window.addEventListener("message", function(event) {
|
|
52
|
+
if (window.ReactNativeWebView && event.data) {
|
|
53
|
+
// ReactNativeWebView.postMessage only supports string data
|
|
54
|
+
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
|
|
55
|
+
}
|
|
56
|
+
}, false);
|
|
57
|
+
`,
|
|
58
|
+
onError,
|
|
59
|
+
onLoad
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
var frame_webview_default = FrameWebView;
|
|
65
|
+
|
|
66
|
+
// src/formats/Format.tsx
|
|
67
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
33
68
|
var sendMessage = (webViewRef, type, code, data) => {
|
|
34
69
|
const message = makeIframeMessage(type, {
|
|
35
70
|
data,
|
|
@@ -45,13 +80,19 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
45
80
|
const context = useContext(AdsContext);
|
|
46
81
|
const bid = useBid({ code, messageId });
|
|
47
82
|
const [height, setHeight] = useState(0);
|
|
48
|
-
const iframeUrl = useIframeUrl(context, bid, code, messageId);
|
|
83
|
+
const iframeUrl = useIframeUrl(context, bid, code, messageId, "sdk-react-native", otherParams.theme);
|
|
84
|
+
const modalUrl = iframeUrl.replace("/api/frame/", "/api/modal/");
|
|
49
85
|
const [showIframe, setShowIframe] = useState(false);
|
|
50
86
|
const [iframeLoaded, setIframeLoaded] = useState(false);
|
|
87
|
+
const [modalOpen, setModalOpen] = useState(false);
|
|
88
|
+
const [modalShown, setModalShown] = useState(false);
|
|
89
|
+
const [modalLoaded, setModalLoaded] = useState(false);
|
|
51
90
|
const [containerStyles, setContainerStyles] = useState({});
|
|
52
91
|
const [iframeStyles, setIframeStyles] = useState({});
|
|
53
92
|
const containerRef = useRef(null);
|
|
54
93
|
const webViewRef = useRef(null);
|
|
94
|
+
const modalWebViewRef = useRef(null);
|
|
95
|
+
const modalInitTimeoutRef = useRef(null);
|
|
55
96
|
const { height: windowHeight, width: windowWidth } = useWindowDimensions();
|
|
56
97
|
const reset = () => {
|
|
57
98
|
setHeight(0);
|
|
@@ -59,9 +100,19 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
59
100
|
setContainerStyles({});
|
|
60
101
|
setIframeStyles({});
|
|
61
102
|
setIframeLoaded(false);
|
|
103
|
+
resetModal();
|
|
62
104
|
context?.resetAll();
|
|
63
105
|
context?.captureError(new Error("Processing iframe error"));
|
|
64
106
|
};
|
|
107
|
+
const resetModal = () => {
|
|
108
|
+
if (modalInitTimeoutRef.current) {
|
|
109
|
+
clearTimeout(modalInitTimeoutRef.current);
|
|
110
|
+
modalInitTimeoutRef.current = null;
|
|
111
|
+
}
|
|
112
|
+
setModalOpen(false);
|
|
113
|
+
setModalLoaded(false);
|
|
114
|
+
setModalShown(false);
|
|
115
|
+
};
|
|
65
116
|
const debug = (name, data = {}) => {
|
|
66
117
|
context?.onDebugEventInternal?.(name, {
|
|
67
118
|
code,
|
|
@@ -77,6 +128,19 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
77
128
|
...data
|
|
78
129
|
});
|
|
79
130
|
};
|
|
131
|
+
const debugModal = (name, data = {}) => {
|
|
132
|
+
context?.onDebugEventInternal?.(name, {
|
|
133
|
+
code,
|
|
134
|
+
messageId,
|
|
135
|
+
otherParams,
|
|
136
|
+
bid,
|
|
137
|
+
modalUrl,
|
|
138
|
+
modalOpen,
|
|
139
|
+
modalShown,
|
|
140
|
+
modalLoaded,
|
|
141
|
+
...data
|
|
142
|
+
});
|
|
143
|
+
};
|
|
80
144
|
debug("format-update-state");
|
|
81
145
|
const onMessage = (event) => {
|
|
82
146
|
try {
|
|
@@ -124,6 +188,10 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
124
188
|
setContainerStyles(message.data.containerStyles);
|
|
125
189
|
setIframeStyles(message.data.iframeStyles);
|
|
126
190
|
break;
|
|
191
|
+
case "open-component-iframe":
|
|
192
|
+
setModalOpen(true);
|
|
193
|
+
modalInitTimeoutRef.current = setTimeout(resetModal, message.data.timeout ?? 5e3);
|
|
194
|
+
break;
|
|
127
195
|
}
|
|
128
196
|
},
|
|
129
197
|
{
|
|
@@ -139,6 +207,53 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
139
207
|
reset();
|
|
140
208
|
}
|
|
141
209
|
};
|
|
210
|
+
const onModalMessage = (event) => {
|
|
211
|
+
try {
|
|
212
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
213
|
+
debugModal("modal-iframe-message", {
|
|
214
|
+
message: data
|
|
215
|
+
});
|
|
216
|
+
const messageHandler = handleIframeMessage(
|
|
217
|
+
(message) => {
|
|
218
|
+
switch (message.type) {
|
|
219
|
+
case "close-component-iframe":
|
|
220
|
+
resetModal();
|
|
221
|
+
break;
|
|
222
|
+
case "init-component-iframe":
|
|
223
|
+
if (modalInitTimeoutRef.current) {
|
|
224
|
+
clearTimeout(modalInitTimeoutRef.current);
|
|
225
|
+
modalInitTimeoutRef.current = null;
|
|
226
|
+
}
|
|
227
|
+
setModalShown(true);
|
|
228
|
+
break;
|
|
229
|
+
case "error-component-iframe":
|
|
230
|
+
case "error-iframe":
|
|
231
|
+
resetModal();
|
|
232
|
+
break;
|
|
233
|
+
case "click-iframe":
|
|
234
|
+
if (message.data.url) {
|
|
235
|
+
Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch(
|
|
236
|
+
(err) => console.error("error opening url", err)
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
context?.onAdClickInternal(message.data);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
code,
|
|
245
|
+
component: "modal"
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
messageHandler({ data });
|
|
249
|
+
} catch (e) {
|
|
250
|
+
debugModal("modal-iframe-message-error", {
|
|
251
|
+
error: e
|
|
252
|
+
});
|
|
253
|
+
console.error("error parsing message from webview", e);
|
|
254
|
+
resetModal();
|
|
255
|
+
}
|
|
256
|
+
};
|
|
142
257
|
const paramsString = convertParamsToString(otherParams);
|
|
143
258
|
useEffect(() => {
|
|
144
259
|
if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
|
|
@@ -184,57 +299,71 @@ var Format = ({ code, messageId, wrapper, ...otherParams }) => {
|
|
|
184
299
|
}
|
|
185
300
|
return 0;
|
|
186
301
|
};
|
|
187
|
-
const content = /* @__PURE__ */
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
// ReactNativeWebView.postMessage only supports string data
|
|
216
|
-
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
|
|
302
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
303
|
+
/* @__PURE__ */ jsx2(Modal, { visible: modalOpen, transparent: true, onRequestClose: resetModal, children: /* @__PURE__ */ jsx2(
|
|
304
|
+
View,
|
|
305
|
+
{
|
|
306
|
+
style: {
|
|
307
|
+
flex: 1,
|
|
308
|
+
// Don't show the modal until the modal page is loaded and sends 'init-component-iframe' message back to SDK
|
|
309
|
+
...modalShown ? { opacity: 1, pointerEvents: "auto" } : { opacity: 0, pointerEvents: "none" }
|
|
310
|
+
},
|
|
311
|
+
children: /* @__PURE__ */ jsx2(
|
|
312
|
+
frame_webview_default,
|
|
313
|
+
{
|
|
314
|
+
ref: modalWebViewRef,
|
|
315
|
+
iframeUrl: modalUrl,
|
|
316
|
+
onMessage: onModalMessage,
|
|
317
|
+
style: {
|
|
318
|
+
backgroundColor: "transparent",
|
|
319
|
+
height: "100%",
|
|
320
|
+
width: "100%",
|
|
321
|
+
borderWidth: 0
|
|
322
|
+
},
|
|
323
|
+
onError: () => {
|
|
324
|
+
debug("modal-error");
|
|
325
|
+
resetModal();
|
|
326
|
+
},
|
|
327
|
+
onLoad: () => {
|
|
328
|
+
debug("modal-load");
|
|
329
|
+
setModalLoaded(true);
|
|
217
330
|
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
onError: () => {
|
|
221
|
-
debug("iframe-error");
|
|
222
|
-
reset();
|
|
223
|
-
},
|
|
224
|
-
onLoad: () => {
|
|
225
|
-
debug("iframe-load");
|
|
331
|
+
}
|
|
332
|
+
)
|
|
226
333
|
}
|
|
227
|
-
}
|
|
228
|
-
|
|
334
|
+
) }),
|
|
335
|
+
/* @__PURE__ */ jsx2(View, { style: containerStyles, ref: containerRef, children: /* @__PURE__ */ jsx2(
|
|
336
|
+
frame_webview_default,
|
|
337
|
+
{
|
|
338
|
+
ref: webViewRef,
|
|
339
|
+
iframeUrl,
|
|
340
|
+
onMessage,
|
|
341
|
+
style: {
|
|
342
|
+
height: getHeight(),
|
|
343
|
+
width: getWidth(),
|
|
344
|
+
background: "transparent",
|
|
345
|
+
borderWidth: 0,
|
|
346
|
+
...iframeStyles
|
|
347
|
+
},
|
|
348
|
+
onError: () => {
|
|
349
|
+
debug("iframe-error");
|
|
350
|
+
reset();
|
|
351
|
+
},
|
|
352
|
+
onLoad: () => {
|
|
353
|
+
debug("iframe-load");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
) })
|
|
357
|
+
] });
|
|
229
358
|
return wrapper ? wrapper(content) : content;
|
|
230
359
|
};
|
|
231
|
-
var FormatWithErrorBoundary = (props) => /* @__PURE__ */
|
|
360
|
+
var FormatWithErrorBoundary = (props) => /* @__PURE__ */ jsx2(ErrorBoundary, { children: /* @__PURE__ */ jsx2(Format, { ...props }) });
|
|
232
361
|
var Format_default = FormatWithErrorBoundary;
|
|
233
362
|
|
|
234
363
|
// src/formats/InlineAd.tsx
|
|
235
|
-
import { jsx as
|
|
364
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
236
365
|
var InlineAd = ({ code, messageId, wrapper, ...props }) => {
|
|
237
|
-
return /* @__PURE__ */
|
|
366
|
+
return /* @__PURE__ */ jsx3(Format_default, { code, messageId, wrapper, ...props });
|
|
238
367
|
};
|
|
239
368
|
var InlineAd_default = InlineAd;
|
|
240
369
|
|
|
@@ -248,7 +377,7 @@ import { TurboModuleRegistry } from "react-native";
|
|
|
248
377
|
var NativeRNKontext_default = TurboModuleRegistry.getEnforcing("RNKontext");
|
|
249
378
|
|
|
250
379
|
// src/context/AdsProvider.tsx
|
|
251
|
-
import { jsx as
|
|
380
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
252
381
|
ErrorUtils.setGlobalHandler((error, isFatal) => {
|
|
253
382
|
if (!isFatal) {
|
|
254
383
|
log.warn(error);
|
|
@@ -292,7 +421,7 @@ var getDevice = async () => {
|
|
|
292
421
|
return {};
|
|
293
422
|
};
|
|
294
423
|
var AdsProvider = (props) => {
|
|
295
|
-
return /* @__PURE__ */
|
|
424
|
+
return /* @__PURE__ */ jsx4(AdsProviderInternal, { ...props, getDevice });
|
|
296
425
|
};
|
|
297
426
|
export {
|
|
298
427
|
AdsProvider,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontextso/sdk-react-native",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0-rc.1",
|
|
4
4
|
"description": "Kontext SDK for React Native",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"react-native-webview": "^13.15.0"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@kontextso/sdk-react": "^1.2.
|
|
58
|
+
"@kontextso/sdk-react": "^1.2.4"
|
|
59
59
|
},
|
|
60
60
|
"files": [
|
|
61
61
|
"dist/*",
|
|
@@ -32,8 +32,6 @@ const getDevice = async (): Promise<Device> => {
|
|
|
32
32
|
log.warn('Failed to read output volume', error)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
console.log('soundOn', soundOn)
|
|
36
|
-
|
|
37
35
|
const rnv = Platform.constants.reactNativeVersion
|
|
38
36
|
const reactNativeVersion = `${rnv.major}.${rnv.minor}.${rnv.patch}`
|
|
39
37
|
|
package/src/formats/Format.tsx
CHANGED
|
@@ -7,15 +7,16 @@ import {
|
|
|
7
7
|
useIframeUrl,
|
|
8
8
|
type FormatProps,
|
|
9
9
|
} from '@kontextso/sdk-react'
|
|
10
|
-
import { WebView,
|
|
11
|
-
import { Linking, View, useWindowDimensions } from 'react-native'
|
|
10
|
+
import type { WebView, WebViewMessageEvent } from 'react-native-webview'
|
|
11
|
+
import { Linking, Modal, View, useWindowDimensions } from 'react-native'
|
|
12
12
|
import {
|
|
13
13
|
handleIframeMessage,
|
|
14
|
-
IframeMessageEvent,
|
|
15
|
-
IframeMessageType,
|
|
14
|
+
type IframeMessageEvent,
|
|
15
|
+
type IframeMessageType,
|
|
16
16
|
makeIframeMessage,
|
|
17
17
|
type IframeMessage,
|
|
18
18
|
} from '@kontextso/sdk-common'
|
|
19
|
+
import FrameWebView from '../frame-webview'
|
|
19
20
|
|
|
20
21
|
const sendMessage = (
|
|
21
22
|
webViewRef: React.RefObject<WebView>,
|
|
@@ -40,16 +41,24 @@ const Format = ({ code, messageId, wrapper, ...otherParams }: FormatProps) => {
|
|
|
40
41
|
|
|
41
42
|
const bid = useBid({ code, messageId })
|
|
42
43
|
const [height, setHeight] = useState<number>(0)
|
|
43
|
-
|
|
44
|
+
|
|
45
|
+
const iframeUrl = useIframeUrl(context, bid, code, messageId, 'sdk-react-native', otherParams.theme)
|
|
46
|
+
const modalUrl = iframeUrl.replace('/api/frame/', '/api/modal/')
|
|
44
47
|
|
|
45
48
|
const [showIframe, setShowIframe] = useState<boolean>(false)
|
|
46
49
|
const [iframeLoaded, setIframeLoaded] = useState<boolean>(false)
|
|
47
50
|
|
|
51
|
+
const [modalOpen, setModalOpen] = useState<boolean>(false)
|
|
52
|
+
const [modalShown, setModalShown] = useState<boolean>(false)
|
|
53
|
+
const [modalLoaded, setModalLoaded] = useState<boolean>(false)
|
|
54
|
+
|
|
48
55
|
const [containerStyles, setContainerStyles] = useState<any>({})
|
|
49
56
|
const [iframeStyles, setIframeStyles] = useState<any>({})
|
|
50
57
|
|
|
51
58
|
const containerRef = useRef<View>(null)
|
|
52
59
|
const webViewRef = useRef<WebView>(null)
|
|
60
|
+
const modalWebViewRef = useRef<WebView>(null)
|
|
61
|
+
const modalInitTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
53
62
|
|
|
54
63
|
const { height: windowHeight, width: windowWidth } = useWindowDimensions()
|
|
55
64
|
|
|
@@ -59,10 +68,22 @@ const Format = ({ code, messageId, wrapper, ...otherParams }: FormatProps) => {
|
|
|
59
68
|
setContainerStyles({})
|
|
60
69
|
setIframeStyles({})
|
|
61
70
|
setIframeLoaded(false)
|
|
71
|
+
resetModal()
|
|
62
72
|
context?.resetAll()
|
|
63
73
|
context?.captureError(new Error('Processing iframe error'))
|
|
64
74
|
}
|
|
65
75
|
|
|
76
|
+
const resetModal = () => {
|
|
77
|
+
if (modalInitTimeoutRef.current) {
|
|
78
|
+
clearTimeout(modalInitTimeoutRef.current)
|
|
79
|
+
modalInitTimeoutRef.current = null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
setModalOpen(false)
|
|
83
|
+
setModalLoaded(false)
|
|
84
|
+
setModalShown(false)
|
|
85
|
+
}
|
|
86
|
+
|
|
66
87
|
const debug = (name: string, data: any = {}) => {
|
|
67
88
|
context?.onDebugEventInternal?.(name, {
|
|
68
89
|
code,
|
|
@@ -79,6 +100,20 @@ const Format = ({ code, messageId, wrapper, ...otherParams }: FormatProps) => {
|
|
|
79
100
|
})
|
|
80
101
|
}
|
|
81
102
|
|
|
103
|
+
const debugModal = (name: string, data: any = {}) => {
|
|
104
|
+
context?.onDebugEventInternal?.(name, {
|
|
105
|
+
code,
|
|
106
|
+
messageId,
|
|
107
|
+
otherParams,
|
|
108
|
+
bid,
|
|
109
|
+
modalUrl,
|
|
110
|
+
modalOpen,
|
|
111
|
+
modalShown,
|
|
112
|
+
modalLoaded,
|
|
113
|
+
...data,
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
82
117
|
debug('format-update-state')
|
|
83
118
|
|
|
84
119
|
const onMessage = (event: WebViewMessageEvent) => {
|
|
@@ -136,6 +171,12 @@ const Format = ({ code, messageId, wrapper, ...otherParams }: FormatProps) => {
|
|
|
136
171
|
setContainerStyles(message.data.containerStyles)
|
|
137
172
|
setIframeStyles(message.data.iframeStyles)
|
|
138
173
|
break
|
|
174
|
+
|
|
175
|
+
case 'open-component-iframe':
|
|
176
|
+
setModalOpen(true)
|
|
177
|
+
|
|
178
|
+
modalInitTimeoutRef.current = setTimeout(resetModal, message.data.timeout ?? 5000)
|
|
179
|
+
break
|
|
139
180
|
}
|
|
140
181
|
},
|
|
141
182
|
{
|
|
@@ -152,6 +193,60 @@ const Format = ({ code, messageId, wrapper, ...otherParams }: FormatProps) => {
|
|
|
152
193
|
}
|
|
153
194
|
}
|
|
154
195
|
|
|
196
|
+
const onModalMessage = (event: WebViewMessageEvent) => {
|
|
197
|
+
try {
|
|
198
|
+
const data = JSON.parse(event.nativeEvent.data) as IframeMessage
|
|
199
|
+
|
|
200
|
+
debugModal('modal-iframe-message', {
|
|
201
|
+
message: data,
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
const messageHandler = handleIframeMessage(
|
|
205
|
+
(message) => {
|
|
206
|
+
switch (message.type) {
|
|
207
|
+
case 'close-component-iframe':
|
|
208
|
+
resetModal()
|
|
209
|
+
break
|
|
210
|
+
|
|
211
|
+
case 'init-component-iframe':
|
|
212
|
+
if (modalInitTimeoutRef.current) {
|
|
213
|
+
clearTimeout(modalInitTimeoutRef.current)
|
|
214
|
+
modalInitTimeoutRef.current = null
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
setModalShown(true)
|
|
218
|
+
break
|
|
219
|
+
|
|
220
|
+
case 'error-component-iframe':
|
|
221
|
+
case 'error-iframe':
|
|
222
|
+
resetModal()
|
|
223
|
+
break
|
|
224
|
+
|
|
225
|
+
case 'click-iframe':
|
|
226
|
+
if (message.data.url) {
|
|
227
|
+
Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch((err) =>
|
|
228
|
+
console.error('error opening url', err)
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
context?.onAdClickInternal(message.data)
|
|
232
|
+
break
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
code,
|
|
237
|
+
component: 'modal',
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
messageHandler({ data } as IframeMessageEvent)
|
|
241
|
+
} catch (e) {
|
|
242
|
+
debugModal('modal-iframe-message-error', {
|
|
243
|
+
error: e,
|
|
244
|
+
})
|
|
245
|
+
console.error('error parsing message from webview', e)
|
|
246
|
+
resetModal()
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
155
250
|
const paramsString = convertParamsToString(otherParams)
|
|
156
251
|
|
|
157
252
|
useEffect(() => {
|
|
@@ -208,47 +303,59 @@ const Format = ({ code, messageId, wrapper, ...otherParams }: FormatProps) => {
|
|
|
208
303
|
}
|
|
209
304
|
|
|
210
305
|
const content = (
|
|
211
|
-
|
|
212
|
-
<
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
306
|
+
<>
|
|
307
|
+
<Modal visible={modalOpen} transparent={true} onRequestClose={resetModal}>
|
|
308
|
+
<View
|
|
309
|
+
style={{
|
|
310
|
+
flex: 1,
|
|
311
|
+
// Don't show the modal until the modal page is loaded and sends 'init-component-iframe' message back to SDK
|
|
312
|
+
...(modalShown ? { opacity: 1, pointerEvents: 'auto' } : { opacity: 0, pointerEvents: 'none' }),
|
|
313
|
+
}}
|
|
314
|
+
>
|
|
315
|
+
<FrameWebView
|
|
316
|
+
ref={modalWebViewRef}
|
|
317
|
+
iframeUrl={modalUrl}
|
|
318
|
+
onMessage={onModalMessage}
|
|
319
|
+
style={{
|
|
320
|
+
backgroundColor: 'transparent',
|
|
321
|
+
height: '100%',
|
|
322
|
+
width: '100%',
|
|
323
|
+
borderWidth: 0,
|
|
324
|
+
}}
|
|
325
|
+
onError={() => {
|
|
326
|
+
debug('modal-error')
|
|
327
|
+
resetModal()
|
|
328
|
+
}}
|
|
329
|
+
onLoad={() => {
|
|
330
|
+
debug('modal-load')
|
|
331
|
+
setModalLoaded(true)
|
|
332
|
+
}}
|
|
333
|
+
/>
|
|
334
|
+
</View>
|
|
335
|
+
</Modal>
|
|
336
|
+
|
|
337
|
+
<View style={containerStyles} ref={containerRef}>
|
|
338
|
+
<FrameWebView
|
|
339
|
+
ref={webViewRef}
|
|
340
|
+
iframeUrl={iframeUrl}
|
|
341
|
+
onMessage={onMessage}
|
|
342
|
+
style={{
|
|
343
|
+
height: getHeight(),
|
|
344
|
+
width: getWidth(),
|
|
345
|
+
background: 'transparent',
|
|
346
|
+
borderWidth: 0,
|
|
347
|
+
...iframeStyles,
|
|
348
|
+
}}
|
|
349
|
+
onError={() => {
|
|
350
|
+
debug('iframe-error')
|
|
351
|
+
reset()
|
|
352
|
+
}}
|
|
353
|
+
onLoad={() => {
|
|
354
|
+
debug('iframe-load')
|
|
355
|
+
}}
|
|
356
|
+
/>
|
|
357
|
+
</View>
|
|
358
|
+
</>
|
|
252
359
|
)
|
|
253
360
|
|
|
254
361
|
return wrapper ? wrapper(content) : content
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { forwardRef } from 'react'
|
|
2
|
+
import type { StyleProp, ViewStyle } from 'react-native'
|
|
3
|
+
import { WebView, type WebViewMessageEvent } from 'react-native-webview'
|
|
4
|
+
|
|
5
|
+
interface FrameWebViewProps {
|
|
6
|
+
iframeUrl: string
|
|
7
|
+
onMessage: (event: WebViewMessageEvent) => void
|
|
8
|
+
style: StyleProp<ViewStyle>
|
|
9
|
+
onError: () => void
|
|
10
|
+
onLoad: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const FrameWebView = forwardRef<WebView, FrameWebViewProps>(
|
|
14
|
+
({ iframeUrl, onMessage, style, onError, onLoad }, forwardedRef) => {
|
|
15
|
+
return (
|
|
16
|
+
<WebView
|
|
17
|
+
ref={forwardedRef}
|
|
18
|
+
source={{
|
|
19
|
+
uri: iframeUrl,
|
|
20
|
+
}}
|
|
21
|
+
onMessage={onMessage}
|
|
22
|
+
style={style}
|
|
23
|
+
allowsInlineMediaPlayback={true}
|
|
24
|
+
mediaPlaybackRequiresUserAction={false}
|
|
25
|
+
javaScriptEnabled={true}
|
|
26
|
+
domStorageEnabled={true}
|
|
27
|
+
allowsFullscreenVideo={false}
|
|
28
|
+
injectedJavaScript={`
|
|
29
|
+
window.addEventListener("message", function(event) {
|
|
30
|
+
if (window.ReactNativeWebView && event.data) {
|
|
31
|
+
// ReactNativeWebView.postMessage only supports string data
|
|
32
|
+
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
|
|
33
|
+
}
|
|
34
|
+
}, false);
|
|
35
|
+
`}
|
|
36
|
+
onError={onError}
|
|
37
|
+
onLoad={onLoad}
|
|
38
|
+
/>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
export default FrameWebView
|