@kontextso/sdk-react-native 3.0.7-rc.3 → 3.0.7
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 +318 -149
- package/dist/index.mjs +321 -149
- package/package.json +2 -2
- package/src/formats/Format.tsx +329 -149
- package/src/frame-webview.tsx +3 -0
package/src/formats/Format.tsx
CHANGED
|
@@ -7,12 +7,17 @@ import {
|
|
|
7
7
|
} from '@kontextso/sdk-common'
|
|
8
8
|
import {
|
|
9
9
|
AdsContext,
|
|
10
|
+
type ContextType,
|
|
11
|
+
convertParamsToString,
|
|
12
|
+
ErrorBoundary,
|
|
10
13
|
type FormatProps,
|
|
11
14
|
useBid,
|
|
15
|
+
useIframeUrl,
|
|
12
16
|
} from '@kontextso/sdk-react'
|
|
13
|
-
import { useContext, useRef } from 'react'
|
|
14
|
-
import { View } from 'react-native'
|
|
15
|
-
import { WebView,
|
|
17
|
+
import { useContext, useEffect, useRef, useState } from 'react'
|
|
18
|
+
import { Keyboard, Linking, Modal, useWindowDimensions, View } from 'react-native'
|
|
19
|
+
import type { WebView, WebViewMessageEvent } from 'react-native-webview'
|
|
20
|
+
import FrameWebView from '../frame-webview'
|
|
16
21
|
|
|
17
22
|
const sendMessage = (
|
|
18
23
|
webViewRef: React.RefObject<WebView>,
|
|
@@ -32,30 +37,68 @@ const sendMessage = (
|
|
|
32
37
|
`)
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
if (!context || !bidId) {
|
|
40
|
+
const getCachedContent = (context: ContextType, bidId?: string) => {
|
|
41
|
+
if (!bidId) {
|
|
38
42
|
return null
|
|
39
43
|
}
|
|
40
|
-
|
|
41
|
-
const adServerUrl = context?.adServerUrl
|
|
42
|
-
|
|
43
|
-
const params = new URLSearchParams({
|
|
44
|
-
code,
|
|
45
|
-
messageId,
|
|
46
|
-
sdk: 'sdk-react-native',
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
return `${adServerUrl}/api/frame/${bidId}?${params}`
|
|
44
|
+
return context?.cachedContentRef?.current?.get(bidId) ?? null
|
|
50
45
|
}
|
|
51
46
|
|
|
52
47
|
const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatProps) => {
|
|
53
48
|
const context = useContext(AdsContext)
|
|
54
49
|
|
|
55
50
|
const bid = useBid({ code, messageId })
|
|
56
|
-
const
|
|
51
|
+
const [height, setHeight] = useState<number>(0)
|
|
52
|
+
|
|
53
|
+
const cachedContent = getCachedContent(context, bid?.bidId)
|
|
54
|
+
|
|
55
|
+
const iframeUrl = useIframeUrl(bid, code, messageId, 'sdk-react-native', otherParams.theme, cachedContent)
|
|
56
|
+
const modalUrl = iframeUrl.replace('/api/frame/', '/api/modal/')
|
|
57
|
+
|
|
58
|
+
const [showIframe, setShowIframe] = useState<boolean>(false)
|
|
59
|
+
const [iframeLoaded, setIframeLoaded] = useState<boolean>(false)
|
|
57
60
|
|
|
61
|
+
const [modalOpen, setModalOpen] = useState<boolean>(false)
|
|
62
|
+
const [modalShown, setModalShown] = useState<boolean>(false)
|
|
63
|
+
const [modalLoaded, setModalLoaded] = useState<boolean>(false)
|
|
64
|
+
|
|
65
|
+
const [containerStyles, setContainerStyles] = useState<any>({})
|
|
66
|
+
const [iframeStyles, setIframeStyles] = useState<any>({})
|
|
67
|
+
|
|
68
|
+
const containerRef = useRef<View>(null)
|
|
58
69
|
const webViewRef = useRef<WebView>(null)
|
|
70
|
+
const modalWebViewRef = useRef<WebView>(null)
|
|
71
|
+
const modalInitTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
72
|
+
const isModalInitRef = useRef<boolean>(false)
|
|
73
|
+
|
|
74
|
+
const { height: windowHeight, width: windowWidth } = useWindowDimensions()
|
|
75
|
+
|
|
76
|
+
const keyboardHeightRef = useRef(0)
|
|
77
|
+
|
|
78
|
+
const isAdViewVisible = showIframe && iframeLoaded
|
|
79
|
+
|
|
80
|
+
const reset = () => {
|
|
81
|
+
setHeight(0)
|
|
82
|
+
setShowIframe(false)
|
|
83
|
+
setContainerStyles({})
|
|
84
|
+
setIframeStyles({})
|
|
85
|
+
setIframeLoaded(false)
|
|
86
|
+
resetModal()
|
|
87
|
+
context?.resetAll()
|
|
88
|
+
context?.captureError(new Error('Processing iframe error'))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const resetModal = () => {
|
|
92
|
+
if (modalInitTimeoutRef.current) {
|
|
93
|
+
clearTimeout(modalInitTimeoutRef.current)
|
|
94
|
+
modalInitTimeoutRef.current = null
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
isModalInitRef.current = false
|
|
98
|
+
setModalOpen(false)
|
|
99
|
+
setModalLoaded(false)
|
|
100
|
+
setModalShown(false)
|
|
101
|
+
}
|
|
59
102
|
|
|
60
103
|
const debug = (name: string, data: any = {}) => {
|
|
61
104
|
context?.onDebugEventInternal?.(name, {
|
|
@@ -64,40 +107,45 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
|
|
|
64
107
|
otherParams,
|
|
65
108
|
bid,
|
|
66
109
|
iframeUrl,
|
|
110
|
+
iframeLoaded,
|
|
111
|
+
showIframe,
|
|
112
|
+
height,
|
|
113
|
+
containerStyles,
|
|
114
|
+
iframeStyles,
|
|
67
115
|
...data,
|
|
68
116
|
})
|
|
69
117
|
}
|
|
70
118
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
messageId,
|
|
119
|
+
const debugModal = (name: string, data: any = {}) => {
|
|
120
|
+
context?.onDebugEventInternal?.(name, {
|
|
74
121
|
code,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
122
|
+
messageId,
|
|
123
|
+
otherParams,
|
|
124
|
+
bid,
|
|
125
|
+
modalUrl,
|
|
126
|
+
modalOpen,
|
|
127
|
+
modalShown,
|
|
128
|
+
modalLoaded,
|
|
129
|
+
...data,
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
debug('format-update-state')
|
|
78
134
|
|
|
79
135
|
const onMessage = (event: WebViewMessageEvent) => {
|
|
80
136
|
try {
|
|
81
137
|
const data = JSON.parse(event.nativeEvent.data) as IframeMessage
|
|
82
138
|
|
|
83
|
-
debug('
|
|
139
|
+
debug('iframe-message', {
|
|
84
140
|
message: data,
|
|
85
|
-
params: { data, messageId, code, otherParams }
|
|
86
141
|
})
|
|
87
142
|
|
|
88
143
|
const messageHandler = handleIframeMessage(
|
|
89
144
|
(message) => {
|
|
90
145
|
switch (message.type) {
|
|
91
146
|
case 'init-iframe':
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
code,
|
|
95
|
-
messages: context?.messages,
|
|
96
|
-
sdk: 'sdk-react-native',
|
|
97
|
-
otherParams,
|
|
98
|
-
messageId,
|
|
99
|
-
}
|
|
100
|
-
})
|
|
147
|
+
setIframeLoaded(true)
|
|
148
|
+
debug('iframe-post-message')
|
|
101
149
|
sendMessage(webViewRef, 'update-iframe', code, {
|
|
102
150
|
messages: context?.messages,
|
|
103
151
|
sdk: 'sdk-react-native',
|
|
@@ -106,6 +154,56 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
|
|
|
106
154
|
})
|
|
107
155
|
break
|
|
108
156
|
|
|
157
|
+
case 'error-iframe':
|
|
158
|
+
reset()
|
|
159
|
+
break
|
|
160
|
+
|
|
161
|
+
case 'resize-iframe':
|
|
162
|
+
setHeight(message.data.height)
|
|
163
|
+
break
|
|
164
|
+
|
|
165
|
+
case 'click-iframe':
|
|
166
|
+
if (message.data.url) {
|
|
167
|
+
Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch((err) =>
|
|
168
|
+
console.error('error opening url', err)
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
context?.onAdClickInternal(message.data)
|
|
172
|
+
break
|
|
173
|
+
|
|
174
|
+
case 'view-iframe':
|
|
175
|
+
context?.onAdViewInternal(message.data)
|
|
176
|
+
break
|
|
177
|
+
|
|
178
|
+
case 'ad-done-iframe':
|
|
179
|
+
if (bid?.bidId && message.data.cachedContent) {
|
|
180
|
+
context?.cachedContentRef?.current?.set(bid.bidId, message.data.cachedContent)
|
|
181
|
+
}
|
|
182
|
+
break
|
|
183
|
+
|
|
184
|
+
case 'show-iframe':
|
|
185
|
+
setShowIframe(true)
|
|
186
|
+
break
|
|
187
|
+
|
|
188
|
+
case 'hide-iframe':
|
|
189
|
+
setShowIframe(false)
|
|
190
|
+
break
|
|
191
|
+
|
|
192
|
+
case 'set-styles-iframe':
|
|
193
|
+
setContainerStyles(message.data.containerStyles)
|
|
194
|
+
setIframeStyles(message.data.iframeStyles)
|
|
195
|
+
break
|
|
196
|
+
|
|
197
|
+
case 'open-component-iframe':
|
|
198
|
+
setModalOpen(true)
|
|
199
|
+
|
|
200
|
+
modalInitTimeoutRef.current = setTimeout(() => {
|
|
201
|
+
if (!isModalInitRef.current) {
|
|
202
|
+
resetModal()
|
|
203
|
+
}
|
|
204
|
+
}, message.data.timeout ?? 5000)
|
|
205
|
+
break
|
|
206
|
+
|
|
109
207
|
case 'event-iframe':
|
|
110
208
|
onEvent?.(message.data)
|
|
111
209
|
context?.onAdEventInternal(message.data)
|
|
@@ -118,139 +216,221 @@ const Format = ({ code, messageId, wrapper, onEvent, ...otherParams }: FormatPro
|
|
|
118
216
|
)
|
|
119
217
|
messageHandler({ data } as IframeMessageEvent)
|
|
120
218
|
} catch (e) {
|
|
121
|
-
debug('
|
|
122
|
-
params: { error: e, messageId, code, otherParams },
|
|
219
|
+
debug('iframe-message-error', {
|
|
123
220
|
error: e,
|
|
124
221
|
})
|
|
125
222
|
console.error('error parsing message from webview', e)
|
|
223
|
+
reset()
|
|
126
224
|
}
|
|
127
225
|
}
|
|
128
226
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
227
|
+
const onModalMessage = (event: WebViewMessageEvent) => {
|
|
228
|
+
try {
|
|
229
|
+
const data = JSON.parse(event.nativeEvent.data) as IframeMessage
|
|
230
|
+
|
|
231
|
+
debugModal('modal-iframe-message', {
|
|
232
|
+
message: data,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
const messageHandler = handleIframeMessage(
|
|
236
|
+
(message) => {
|
|
237
|
+
switch (message.type) {
|
|
238
|
+
case 'close-component-iframe':
|
|
239
|
+
resetModal()
|
|
240
|
+
break
|
|
241
|
+
|
|
242
|
+
case 'init-component-iframe':
|
|
243
|
+
// Just clearing the timeoutRef didn't work in Android, so we need to set a flag and check it in the timeout callback
|
|
244
|
+
isModalInitRef.current = true
|
|
245
|
+
|
|
246
|
+
if (modalInitTimeoutRef.current) {
|
|
247
|
+
clearTimeout(modalInitTimeoutRef.current)
|
|
248
|
+
modalInitTimeoutRef.current = null
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
setModalShown(true)
|
|
252
|
+
break
|
|
253
|
+
|
|
254
|
+
case 'error-component-iframe':
|
|
255
|
+
case 'error-iframe':
|
|
256
|
+
resetModal()
|
|
257
|
+
context?.captureError(new Error('Processing modal iframe error'))
|
|
258
|
+
break
|
|
259
|
+
|
|
260
|
+
case 'click-iframe':
|
|
261
|
+
if (message.data.url) {
|
|
262
|
+
Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch((err) =>
|
|
263
|
+
console.error('error opening url', err)
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
context?.onAdClickInternal(message.data)
|
|
267
|
+
break
|
|
268
|
+
|
|
269
|
+
case 'event-iframe':
|
|
270
|
+
onEvent?.(message.data)
|
|
271
|
+
context?.onAdEventInternal(message.data)
|
|
272
|
+
break
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
code,
|
|
277
|
+
component: 'modal',
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
messageHandler({ data } as IframeMessageEvent)
|
|
281
|
+
} catch (e) {
|
|
282
|
+
debugModal('modal-iframe-message-error', {
|
|
283
|
+
error: e,
|
|
284
|
+
})
|
|
285
|
+
console.error('error parsing message from webview', e)
|
|
286
|
+
resetModal()
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const paramsString = convertParamsToString(otherParams)
|
|
291
|
+
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
|
|
294
|
+
return
|
|
295
|
+
}
|
|
296
|
+
debug('iframe-post-message')
|
|
297
|
+
sendMessage(webViewRef, 'update-iframe', code, {
|
|
298
|
+
data: { otherParams },
|
|
299
|
+
code,
|
|
300
|
+
})
|
|
301
|
+
// because we use the rest params, the object is alaways new and useEffect would be called on every render
|
|
302
|
+
}, [paramsString, iframeLoaded, context?.adServerUrl, bid, code])
|
|
303
|
+
|
|
304
|
+
const checkIfInViewport = () => {
|
|
305
|
+
if (!containerRef.current) return
|
|
306
|
+
|
|
307
|
+
containerRef.current.measureInWindow((containerX, containerY, containerWidth, containerHeight) => {
|
|
308
|
+
sendMessage(webViewRef, 'update-dimensions-iframe', code, {
|
|
309
|
+
windowWidth,
|
|
310
|
+
windowHeight,
|
|
311
|
+
containerWidth,
|
|
312
|
+
containerHeight,
|
|
313
|
+
containerX,
|
|
314
|
+
containerY,
|
|
315
|
+
keyboardHeight: keyboardHeightRef.current,
|
|
316
|
+
})
|
|
139
317
|
})
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
useEffect(() => {
|
|
321
|
+
if (!isAdViewVisible) return
|
|
322
|
+
|
|
323
|
+
const interval = setInterval(() => {
|
|
324
|
+
checkIfInViewport()
|
|
325
|
+
}, 250)
|
|
326
|
+
|
|
327
|
+
return () => clearInterval(interval)
|
|
328
|
+
}, [isAdViewVisible])
|
|
329
|
+
|
|
330
|
+
useEffect(() => {
|
|
331
|
+
const showSubscription = Keyboard.addListener('keyboardDidShow', (e) => {
|
|
332
|
+
keyboardHeightRef.current = e?.endCoordinates?.height ?? 0
|
|
333
|
+
})
|
|
334
|
+
const hideSubscription = Keyboard.addListener('keyboardDidHide', () => {
|
|
335
|
+
keyboardHeightRef.current = 0
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
return () => {
|
|
339
|
+
showSubscription.remove()
|
|
340
|
+
hideSubscription.remove()
|
|
341
|
+
keyboardHeightRef.current = 0
|
|
342
|
+
}
|
|
343
|
+
}, [])
|
|
344
|
+
|
|
345
|
+
if (!context || !bid || !iframeUrl) {
|
|
140
346
|
return null
|
|
141
347
|
}
|
|
142
348
|
|
|
143
|
-
|
|
144
|
-
<
|
|
349
|
+
const inlineContent = (
|
|
350
|
+
<FrameWebView
|
|
351
|
+
ref={webViewRef}
|
|
352
|
+
iframeUrl={iframeUrl}
|
|
353
|
+
onMessage={onMessage}
|
|
145
354
|
style={{
|
|
146
|
-
height
|
|
355
|
+
height,
|
|
147
356
|
width: '100%',
|
|
148
357
|
backgroundColor: 'transparent',
|
|
149
358
|
borderWidth: 0,
|
|
359
|
+
...iframeStyles,
|
|
150
360
|
}}
|
|
151
|
-
|
|
361
|
+
onError={() => {
|
|
362
|
+
debug('iframe-error')
|
|
363
|
+
reset()
|
|
364
|
+
}}
|
|
365
|
+
onLoad={() => {
|
|
366
|
+
debug('iframe-load')
|
|
367
|
+
}}
|
|
368
|
+
/>
|
|
369
|
+
)
|
|
152
370
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
371
|
+
const interstitialContent = (
|
|
372
|
+
<Modal
|
|
373
|
+
visible={modalOpen}
|
|
374
|
+
transparent={true}
|
|
375
|
+
onRequestClose={resetModal}
|
|
376
|
+
animationType="slide"
|
|
377
|
+
statusBarTranslucent={true}
|
|
378
|
+
>
|
|
379
|
+
<View
|
|
159
380
|
style={{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
borderWidth: 0,
|
|
164
|
-
}}
|
|
165
|
-
allowsInlineMediaPlayback={true}
|
|
166
|
-
mediaPlaybackRequiresUserAction={false}
|
|
167
|
-
javaScriptEnabled={true}
|
|
168
|
-
domStorageEnabled={true}
|
|
169
|
-
allowsFullscreenVideo={false}
|
|
170
|
-
injectedJavaScript={`
|
|
171
|
-
window.addEventListener("message", function(event) {
|
|
172
|
-
if (window.ReactNativeWebView && event.data) {
|
|
173
|
-
// ReactNativeWebView.postMessage only supports string data
|
|
174
|
-
window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
|
|
175
|
-
}
|
|
176
|
-
}, false);
|
|
177
|
-
`}
|
|
178
|
-
onLoadStart={() => {
|
|
179
|
-
debug('Format:iframeLoadStart', {
|
|
180
|
-
params: {
|
|
181
|
-
messageId,
|
|
182
|
-
code,
|
|
183
|
-
otherParams,
|
|
184
|
-
}
|
|
185
|
-
})
|
|
186
|
-
}}
|
|
187
|
-
onError={() => {
|
|
188
|
-
debug('Format:iframeError', {
|
|
189
|
-
params: {
|
|
190
|
-
messageId,
|
|
191
|
-
code,
|
|
192
|
-
otherParams,
|
|
193
|
-
}
|
|
194
|
-
})
|
|
195
|
-
}}
|
|
196
|
-
onLoad={() => {
|
|
197
|
-
debug('Format:iframeLoad', {
|
|
198
|
-
params: {
|
|
199
|
-
messageId,
|
|
200
|
-
code,
|
|
201
|
-
otherParams,
|
|
202
|
-
}
|
|
203
|
-
})
|
|
204
|
-
}}
|
|
205
|
-
onLoadProgress={() => {
|
|
206
|
-
debug('Format:iframeLoadProgress', {
|
|
207
|
-
params: {
|
|
208
|
-
messageId,
|
|
209
|
-
code,
|
|
210
|
-
otherParams,
|
|
211
|
-
}
|
|
212
|
-
})
|
|
213
|
-
}}
|
|
214
|
-
onHttpError={() => {
|
|
215
|
-
debug('Format:iframeHttpError', {
|
|
216
|
-
params: {
|
|
217
|
-
messageId,
|
|
218
|
-
code,
|
|
219
|
-
otherParams,
|
|
220
|
-
}
|
|
221
|
-
})
|
|
222
|
-
}}
|
|
223
|
-
onRenderProcessGone={() => {
|
|
224
|
-
debug('Format:iframeRenderProcessGone', {
|
|
225
|
-
params: {
|
|
226
|
-
messageId,
|
|
227
|
-
code,
|
|
228
|
-
otherParams,
|
|
229
|
-
}
|
|
230
|
-
})
|
|
381
|
+
flex: 1,
|
|
382
|
+
// Don't show the modal until the modal page is loaded and sends 'init-component-iframe' message back to SDK
|
|
383
|
+
...(modalShown ? { opacity: 1, pointerEvents: 'auto' } : { opacity: 0, pointerEvents: 'none' }),
|
|
231
384
|
}}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
385
|
+
>
|
|
386
|
+
<FrameWebView
|
|
387
|
+
ref={modalWebViewRef}
|
|
388
|
+
iframeUrl={modalUrl}
|
|
389
|
+
onMessage={onModalMessage}
|
|
390
|
+
style={{
|
|
391
|
+
backgroundColor: 'transparent',
|
|
392
|
+
height: '100%',
|
|
393
|
+
width: '100%',
|
|
394
|
+
borderWidth: 0,
|
|
395
|
+
}}
|
|
396
|
+
onError={() => {
|
|
397
|
+
debug('modal-error')
|
|
398
|
+
resetModal()
|
|
399
|
+
}}
|
|
400
|
+
onLoad={() => {
|
|
401
|
+
debug('modal-load')
|
|
402
|
+
setModalLoaded(true)
|
|
403
|
+
}}
|
|
404
|
+
/>
|
|
405
|
+
</View>
|
|
406
|
+
</Modal>
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
return (
|
|
410
|
+
<>
|
|
411
|
+
<View
|
|
412
|
+
style={
|
|
413
|
+
isAdViewVisible
|
|
414
|
+
? containerStyles
|
|
415
|
+
: {
|
|
416
|
+
height: 0,
|
|
417
|
+
overflow: 'hidden',
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
ref={containerRef}
|
|
421
|
+
>
|
|
422
|
+
{wrapper ? wrapper(inlineContent) : inlineContent}
|
|
423
|
+
</View>
|
|
424
|
+
|
|
425
|
+
{interstitialContent}
|
|
426
|
+
</>
|
|
253
427
|
)
|
|
254
428
|
}
|
|
255
429
|
|
|
256
|
-
|
|
430
|
+
const FormatWithErrorBoundary = (props: FormatProps) => (
|
|
431
|
+
<ErrorBoundary>
|
|
432
|
+
<Format {...props} />
|
|
433
|
+
</ErrorBoundary>
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
export default FormatWithErrorBoundary
|
package/src/frame-webview.tsx
CHANGED
|
@@ -25,6 +25,9 @@ const FrameWebView = forwardRef<WebView, FrameWebViewProps>(
|
|
|
25
25
|
javaScriptEnabled={true}
|
|
26
26
|
domStorageEnabled={true}
|
|
27
27
|
allowsFullscreenVideo={false}
|
|
28
|
+
originWhitelist={['*']}
|
|
29
|
+
sharedCookiesEnabled={true}
|
|
30
|
+
thirdPartyCookiesEnabled={true}
|
|
28
31
|
injectedJavaScript={`
|
|
29
32
|
window.addEventListener("message", function(event) {
|
|
30
33
|
if (window.ReactNativeWebView && event.data) {
|