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