@kontextso/sdk-react-native 3.0.7-rc.2 → 3.0.7-rc.3

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.mjs CHANGED
@@ -20,52 +20,12 @@ function handleIframeMessage(handler, opts) {
20
20
  // src/formats/Format.tsx
21
21
  import {
22
22
  AdsContext,
23
- convertParamsToString,
24
- ErrorBoundary,
25
- useBid,
26
- useIframeUrl
23
+ useBid
27
24
  } from "@kontextso/sdk-react";
28
- import { useContext, useEffect, useRef, useState } from "react";
29
- import { Keyboard, Linking, Modal, useWindowDimensions, View } from "react-native";
30
-
31
- // src/frame-webview.tsx
32
- import { forwardRef } from "react";
25
+ import { useContext, useRef } from "react";
26
+ import { View } from "react-native";
33
27
  import { WebView } from "react-native-webview";
34
28
  import { jsx } from "react/jsx-runtime";
35
- var FrameWebView = forwardRef(
36
- ({ iframeUrl, onMessage, style, onError, onLoad }, forwardedRef) => {
37
- return /* @__PURE__ */ jsx(
38
- WebView,
39
- {
40
- ref: forwardedRef,
41
- source: {
42
- uri: iframeUrl
43
- },
44
- onMessage,
45
- style,
46
- allowsInlineMediaPlayback: true,
47
- mediaPlaybackRequiresUserAction: false,
48
- javaScriptEnabled: true,
49
- domStorageEnabled: true,
50
- allowsFullscreenVideo: false,
51
- injectedJavaScript: `
52
- window.addEventListener("message", function(event) {
53
- if (window.ReactNativeWebView && event.data) {
54
- // ReactNativeWebView.postMessage only supports string data
55
- window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
56
- }
57
- }, false);
58
- `,
59
- onError,
60
- onLoad
61
- }
62
- );
63
- }
64
- );
65
- var frame_webview_default = FrameWebView;
66
-
67
- // src/formats/Format.tsx
68
- import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
69
29
  var sendMessage = (webViewRef, type, code, data) => {
70
30
  const message = makeIframeMessage(type, {
71
31
  data,
@@ -77,68 +37,24 @@ var sendMessage = (webViewRef, type, code, data) => {
77
37
  }));
78
38
  `);
79
39
  };
80
- var getCachedContent = (context, bidId) => {
81
- if (!bidId) {
40
+ var getUrl = (code, messageId, bidId) => {
41
+ const context = useContext(AdsContext);
42
+ if (!context || !bidId) {
82
43
  return null;
83
44
  }
84
- return context?.cachedContentRef?.current?.get(bidId) ?? null;
45
+ const adServerUrl = context?.adServerUrl;
46
+ const params = new URLSearchParams({
47
+ code,
48
+ messageId,
49
+ sdk: "sdk-react-native"
50
+ });
51
+ return `${adServerUrl}/api/frame/${bidId}?${params}`;
85
52
  };
86
53
  var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
87
54
  const context = useContext(AdsContext);
88
55
  const bid = useBid({ code, messageId });
89
- const [height, setHeight] = useState(0);
90
- const cachedContent = getCachedContent(context, bid?.bidId);
91
- const iframeUrl = useIframeUrl(bid, code, messageId, "sdk-react-native", otherParams.theme, cachedContent);
92
- const modalUrl = iframeUrl.replace("/api/frame/", "/api/modal/");
93
- const [showIframe, setShowIframe] = useState(false);
94
- const [iframeLoaded, setIframeLoaded] = useState(false);
95
- const [modalOpen, setModalOpen] = useState(false);
96
- const [modalShown, setModalShown] = useState(false);
97
- const [modalLoaded, setModalLoaded] = useState(false);
98
- const [containerStyles, setContainerStyles] = useState({});
99
- const [iframeStyles, setIframeStyles] = useState({});
100
- const containerRef = useRef(null);
56
+ const iframeUrl = getUrl(code, messageId, bid?.bidId);
101
57
  const webViewRef = useRef(null);
102
- const modalWebViewRef = useRef(null);
103
- const modalInitTimeoutRef = useRef(null);
104
- const isModalInitRef = useRef(false);
105
- const { height: windowHeight, width: windowWidth } = useWindowDimensions();
106
- const keyboardHeightRef = useRef(0);
107
- const isAdViewVisible = showIframe && iframeLoaded;
108
- const reset = () => {
109
- setHeight(0);
110
- setShowIframe(false);
111
- setContainerStyles({});
112
- setIframeStyles({});
113
- setIframeLoaded(false);
114
- resetModal();
115
- context?.resetAll();
116
- context?.captureError(new Error("Processing iframe error"));
117
- };
118
- const resetModal = () => {
119
- debugModal("Format:resetModal", {
120
- params: {
121
- messageId,
122
- code,
123
- otherParams
124
- }
125
- });
126
- if (modalInitTimeoutRef.current) {
127
- debugModal("Format:resetModalTimeout", {
128
- params: {
129
- messageId,
130
- code,
131
- otherParams
132
- }
133
- });
134
- clearTimeout(modalInitTimeoutRef.current);
135
- modalInitTimeoutRef.current = null;
136
- }
137
- isModalInitRef.current = false;
138
- setModalOpen(false);
139
- setModalLoaded(false);
140
- setModalShown(false);
141
- };
142
58
  const debug = (name, data = {}) => {
143
59
  context?.onDebugEventInternal?.(name, {
144
60
  code,
@@ -146,24 +62,6 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
146
62
  otherParams,
147
63
  bid,
148
64
  iframeUrl,
149
- iframeLoaded,
150
- showIframe,
151
- height,
152
- containerStyles,
153
- iframeStyles,
154
- ...data
155
- });
156
- };
157
- const debugModal = (name, data = {}) => {
158
- context?.onDebugEventInternal?.(name, {
159
- code,
160
- messageId,
161
- otherParams,
162
- bid,
163
- modalUrl,
164
- modalOpen,
165
- modalShown,
166
- modalLoaded,
167
65
  ...data
168
66
  });
169
67
  };
@@ -185,7 +83,6 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
185
83
  (message) => {
186
84
  switch (message.type) {
187
85
  case "init-iframe":
188
- setIframeLoaded(true);
189
86
  debug("Format:iframePostMessage", {
190
87
  params: {
191
88
  code,
@@ -202,46 +99,6 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
202
99
  messageId
203
100
  });
204
101
  break;
205
- case "error-iframe":
206
- reset();
207
- break;
208
- case "resize-iframe":
209
- setHeight(message.data.height);
210
- break;
211
- case "click-iframe":
212
- if (message.data.url) {
213
- Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch(
214
- (err) => console.error("error opening url", err)
215
- );
216
- }
217
- context?.onAdClickInternal(message.data);
218
- break;
219
- case "view-iframe":
220
- context?.onAdViewInternal(message.data);
221
- break;
222
- case "ad-done-iframe":
223
- if (bid?.bidId && message.data.cachedContent) {
224
- context?.cachedContentRef?.current?.set(bid.bidId, message.data.cachedContent);
225
- }
226
- break;
227
- case "show-iframe":
228
- setShowIframe(true);
229
- break;
230
- case "hide-iframe":
231
- setShowIframe(false);
232
- break;
233
- case "set-styles-iframe":
234
- setContainerStyles(message.data.containerStyles);
235
- setIframeStyles(message.data.iframeStyles);
236
- break;
237
- case "open-component-iframe":
238
- setModalOpen(true);
239
- modalInitTimeoutRef.current = setTimeout(() => {
240
- if (!isModalInitRef.current) {
241
- resetModal();
242
- }
243
- }, message.data.timeout ?? 5e3);
244
- break;
245
102
  case "event-iframe":
246
103
  onEvent?.(message.data);
247
104
  context?.onAdEventInternal(message.data);
@@ -259,197 +116,8 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
259
116
  error: e
260
117
  });
261
118
  console.error("error parsing message from webview", e);
262
- reset();
263
- }
264
- };
265
- const onModalMessage = (event) => {
266
- try {
267
- const data = JSON.parse(event.nativeEvent.data);
268
- debugModal("Format:modalIframeMessage", {
269
- params: { data, messageId, code, otherParams },
270
- message: data
271
- });
272
- const messageHandler = handleIframeMessage(
273
- (message) => {
274
- switch (message.type) {
275
- case "close-component-iframe":
276
- resetModal();
277
- break;
278
- case "init-component-iframe":
279
- isModalInitRef.current = true;
280
- if (modalInitTimeoutRef.current) {
281
- clearTimeout(modalInitTimeoutRef.current);
282
- modalInitTimeoutRef.current = null;
283
- }
284
- setModalShown(true);
285
- break;
286
- case "error-component-iframe":
287
- case "error-iframe":
288
- resetModal();
289
- context?.captureError(new Error("Processing modal iframe error"));
290
- break;
291
- case "click-iframe":
292
- if (message.data.url) {
293
- Linking.openURL(`${context?.adServerUrl}${message.data.url}`).catch(
294
- (err) => console.error("error opening url", err)
295
- );
296
- }
297
- context?.onAdClickInternal(message.data);
298
- break;
299
- case "event-iframe":
300
- onEvent?.(message.data);
301
- context?.onAdEventInternal(message.data);
302
- break;
303
- }
304
- },
305
- {
306
- code,
307
- component: "modal"
308
- }
309
- );
310
- messageHandler({ data });
311
- } catch (e) {
312
- debugModal("Format:modalIframeMessageError", {
313
- params: { error: e, messageId, code, otherParams },
314
- error: e
315
- });
316
- console.error("error parsing message from webview", e);
317
- resetModal();
318
119
  }
319
120
  };
320
- const paramsString = convertParamsToString(otherParams);
321
- useEffect(() => {
322
- if (!iframeLoaded || !context?.adServerUrl || !bid || !webViewRef.current) {
323
- debug("Format:iframePostMessageNotLoaded", {
324
- params: {
325
- messageId,
326
- iframeLoaded,
327
- contextAdServerUrl: context?.adServerUrl,
328
- bid,
329
- code,
330
- otherParams
331
- }
332
- });
333
- return;
334
- }
335
- debug("Format:iframePostMessage", {
336
- params: {
337
- messageId,
338
- otherParams,
339
- code
340
- }
341
- });
342
- sendMessage(webViewRef, "update-iframe", code, {
343
- data: { otherParams },
344
- code
345
- });
346
- }, [paramsString, iframeLoaded, context?.adServerUrl, bid, code]);
347
- const checkIfInViewport = () => {
348
- if (!containerRef.current) {
349
- debug("Format:checkIfInViewportNoContainer", {
350
- params: {
351
- messageId,
352
- code,
353
- otherParams
354
- }
355
- });
356
- return;
357
- }
358
- debug("Format:checkIfInViewportMeasure", {
359
- params: {
360
- windowWidth,
361
- windowHeight,
362
- messageId,
363
- code,
364
- otherParams
365
- }
366
- });
367
- containerRef.current.measureInWindow((containerX, containerY, containerWidth, containerHeight) => {
368
- sendMessage(webViewRef, "update-dimensions-iframe", code, {
369
- windowWidth,
370
- windowHeight,
371
- containerWidth,
372
- containerHeight,
373
- containerX,
374
- containerY,
375
- keyboardHeight: keyboardHeightRef.current
376
- });
377
- debug("Format:checkIfInViewportMeasureSend", {
378
- params: {
379
- messageId,
380
- code,
381
- otherParams,
382
- windowWidth,
383
- windowHeight,
384
- containerWidth,
385
- containerHeight,
386
- containerX,
387
- containerY,
388
- keyboardHeight: keyboardHeightRef.current
389
- }
390
- });
391
- });
392
- };
393
- useEffect(() => {
394
- if (!isAdViewVisible) {
395
- debug("Format:checkIfInViewportNotVisible", {
396
- params: {
397
- messageId,
398
- code,
399
- otherParams
400
- }
401
- });
402
- return;
403
- }
404
- const interval = setInterval(() => {
405
- checkIfInViewport();
406
- }, 250);
407
- return () => {
408
- clearInterval(interval);
409
- debug("Format:checkIfInViewportCleanup", {
410
- params: {
411
- messageId,
412
- code,
413
- otherParams
414
- }
415
- });
416
- };
417
- }, [isAdViewVisible]);
418
- useEffect(() => {
419
- const showSubscription = Keyboard.addListener("keyboardDidShow", (e) => {
420
- debug("Format:keyboardDidShow", {
421
- params: {
422
- keyboardHeight: e?.endCoordinates?.height ?? 0,
423
- messageId,
424
- code,
425
- otherParams
426
- }
427
- });
428
- keyboardHeightRef.current = e?.endCoordinates?.height ?? 0;
429
- });
430
- const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
431
- debug("Format:keyboardDidHide", {
432
- params: {
433
- messageId,
434
- code,
435
- otherParams
436
- }
437
- });
438
- keyboardHeightRef.current = 0;
439
- });
440
- return () => {
441
- showSubscription.remove();
442
- hideSubscription.remove();
443
- keyboardHeightRef.current = 0;
444
- debug("Format:keyboardEffectCleanup", {
445
- params: {
446
- messageId,
447
- code,
448
- otherParams
449
- }
450
- });
451
- };
452
- }, []);
453
121
  if (!context || !bid || !iframeUrl) {
454
122
  debug("Format:noContextOrBidOrIframeUrl", {
455
123
  params: {
@@ -463,116 +131,125 @@ var Format = ({ code, messageId, wrapper, onEvent, ...otherParams }) => {
463
131
  });
464
132
  return null;
465
133
  }
466
- const inlineContent = /* @__PURE__ */ jsx2(
467
- frame_webview_default,
134
+ return /* @__PURE__ */ jsx(
135
+ View,
468
136
  {
469
- ref: webViewRef,
470
- iframeUrl,
471
- onMessage,
472
137
  style: {
473
- height,
138
+ height: 300,
474
139
  width: "100%",
475
140
  backgroundColor: "transparent",
476
- borderWidth: 0,
477
- ...iframeStyles
141
+ borderWidth: 0
478
142
  },
479
- onError: () => {
480
- debug("Format:iframeError", {
481
- params: {
482
- messageId,
483
- code,
484
- otherParams
485
- }
486
- });
487
- reset();
488
- },
489
- onLoad: () => {
490
- debug("Format:iframeLoad", {
491
- params: {
492
- messageId,
493
- code,
494
- otherParams
495
- }
496
- });
497
- }
498
- }
499
- );
500
- const interstitialContent = /* @__PURE__ */ jsx2(
501
- Modal,
502
- {
503
- visible: modalOpen,
504
- transparent: true,
505
- onRequestClose: resetModal,
506
- animationType: "slide",
507
- statusBarTranslucent: true,
508
- children: /* @__PURE__ */ jsx2(
509
- View,
143
+ children: /* @__PURE__ */ jsx(
144
+ WebView,
510
145
  {
146
+ ref: webViewRef,
147
+ source: {
148
+ uri: iframeUrl
149
+ },
150
+ onMessage,
511
151
  style: {
512
- flex: 1,
513
- // Don't show the modal until the modal page is loaded and sends 'init-component-iframe' message back to SDK
514
- ...modalShown ? { opacity: 1, pointerEvents: "auto" } : { opacity: 0, pointerEvents: "none" }
152
+ height: 300,
153
+ width: "100%",
154
+ backgroundColor: "transparent",
155
+ borderWidth: 0
515
156
  },
516
- children: /* @__PURE__ */ jsx2(
517
- frame_webview_default,
518
- {
519
- ref: modalWebViewRef,
520
- iframeUrl: modalUrl,
521
- onMessage: onModalMessage,
522
- style: {
523
- backgroundColor: "transparent",
524
- height: "100%",
525
- width: "100%",
526
- borderWidth: 0
527
- },
528
- onError: () => {
529
- debug("Format:modalError", {
530
- params: {
531
- messageId,
532
- code,
533
- otherParams
534
- }
535
- });
536
- resetModal();
537
- },
538
- onLoad: () => {
539
- debug("Format:modalLoad", {
540
- params: {
541
- messageId,
542
- code,
543
- otherParams
544
- }
545
- });
546
- setModalLoaded(true);
547
- }
157
+ allowsInlineMediaPlayback: true,
158
+ mediaPlaybackRequiresUserAction: false,
159
+ javaScriptEnabled: true,
160
+ domStorageEnabled: true,
161
+ allowsFullscreenVideo: false,
162
+ injectedJavaScript: `
163
+ window.addEventListener("message", function(event) {
164
+ if (window.ReactNativeWebView && event.data) {
165
+ // ReactNativeWebView.postMessage only supports string data
166
+ window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
548
167
  }
549
- )
168
+ }, false);
169
+ `,
170
+ onLoadStart: () => {
171
+ debug("Format:iframeLoadStart", {
172
+ params: {
173
+ messageId,
174
+ code,
175
+ otherParams
176
+ }
177
+ });
178
+ },
179
+ onError: () => {
180
+ debug("Format:iframeError", {
181
+ params: {
182
+ messageId,
183
+ code,
184
+ otherParams
185
+ }
186
+ });
187
+ },
188
+ onLoad: () => {
189
+ debug("Format:iframeLoad", {
190
+ params: {
191
+ messageId,
192
+ code,
193
+ otherParams
194
+ }
195
+ });
196
+ },
197
+ onLoadProgress: () => {
198
+ debug("Format:iframeLoadProgress", {
199
+ params: {
200
+ messageId,
201
+ code,
202
+ otherParams
203
+ }
204
+ });
205
+ },
206
+ onHttpError: () => {
207
+ debug("Format:iframeHttpError", {
208
+ params: {
209
+ messageId,
210
+ code,
211
+ otherParams
212
+ }
213
+ });
214
+ },
215
+ onRenderProcessGone: () => {
216
+ debug("Format:iframeRenderProcessGone", {
217
+ params: {
218
+ messageId,
219
+ code,
220
+ otherParams
221
+ }
222
+ });
223
+ },
224
+ onNavigationStateChange: () => {
225
+ debug("Format:iframeNavigationStateChange", {
226
+ params: {
227
+ messageId,
228
+ code,
229
+ otherParams
230
+ }
231
+ });
232
+ },
233
+ onContentProcessDidTerminate: () => {
234
+ debug("Format:iframeContentProcessDidTerminate", {
235
+ params: {
236
+ messageId,
237
+ code,
238
+ otherParams
239
+ }
240
+ });
241
+ }
550
242
  }
551
243
  )
552
244
  }
553
245
  );
554
- return /* @__PURE__ */ jsxs(Fragment, { children: [
555
- /* @__PURE__ */ jsx2(
556
- View,
557
- {
558
- style: isAdViewVisible ? containerStyles : {
559
- height: 0,
560
- overflow: "hidden"
561
- },
562
- ref: containerRef,
563
- children: wrapper ? wrapper(inlineContent) : inlineContent
564
- }
565
- ),
566
- interstitialContent
567
- ] });
568
246
  };
569
- var FormatWithErrorBoundary = (props) => /* @__PURE__ */ jsx2(ErrorBoundary, { children: /* @__PURE__ */ jsx2(Format, { ...props }) });
570
- var Format_default = FormatWithErrorBoundary;
247
+ var Format_default = Format;
571
248
 
572
249
  // src/formats/InlineAd.tsx
573
- import { jsx as jsx3 } from "react/jsx-runtime";
250
+ import { jsx as jsx2 } from "react/jsx-runtime";
574
251
  var InlineAd = ({ code, messageId, wrapper, ...props }) => {
575
- return /* @__PURE__ */ jsx3(Format_default, { code, messageId, wrapper, ...props });
252
+ return /* @__PURE__ */ jsx2(Format_default, { code, messageId, wrapper, ...props });
576
253
  };
577
254
  var InlineAd_default = InlineAd;
578
255
 
@@ -586,14 +263,14 @@ import { Appearance, Dimensions, PixelRatio, Platform } from "react-native";
586
263
  import DeviceInfo from "react-native-device-info";
587
264
 
588
265
  // package.json
589
- var version = "3.0.7-rc.2";
266
+ var version = "3.0.7-rc.3";
590
267
 
591
268
  // src/NativeRNKontext.ts
592
269
  import { TurboModuleRegistry } from "react-native";
593
270
  var NativeRNKontext_default = TurboModuleRegistry.getEnforcing("RNKontext");
594
271
 
595
272
  // src/context/AdsProvider.tsx
596
- import { jsx as jsx4 } from "react/jsx-runtime";
273
+ import { jsx as jsx3 } from "react/jsx-runtime";
597
274
  ErrorUtils.setGlobalHandler((error, isFatal) => {
598
275
  if (!isFatal) {
599
276
  log.warn(error);
@@ -687,7 +364,7 @@ var getSdk = async () => ({
687
364
  version
688
365
  });
689
366
  var AdsProvider = (props) => {
690
- return /* @__PURE__ */ jsx4(AdsProviderInternal, { ...props, getDevice, getSdk, getApp });
367
+ return /* @__PURE__ */ jsx3(AdsProviderInternal, { ...props, getDevice, getSdk, getApp });
691
368
  };
692
369
  export {
693
370
  AdsProvider,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextso/sdk-react-native",
3
- "version": "3.0.7-rc.2",
3
+ "version": "3.0.7-rc.3",
4
4
  "description": "Kontext SDK for React Native",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",