rampkit-expo-dev 0.0.6 → 0.0.8

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.
@@ -4,6 +4,7 @@ export declare class RampKitCore {
4
4
  private onboardingData;
5
5
  private userId;
6
6
  private onOnboardingFinished?;
7
+ private onShowPaywall?;
7
8
  private static readonly ONBOARDING_URL;
8
9
  static get instance(): RampKitCore;
9
10
  init(config: {
@@ -11,8 +12,11 @@ export declare class RampKitCore {
11
12
  environment?: string;
12
13
  autoShowOnboarding?: boolean;
13
14
  onOnboardingFinished?: (payload?: any) => void;
15
+ showPaywall?: () => void;
14
16
  }): Promise<void>;
15
17
  getOnboardingData(): any;
16
18
  getUserId(): string | null;
17
- showOnboarding(): void;
19
+ showOnboarding(opts?: {
20
+ showPaywall?: () => void;
21
+ }): void;
18
22
  }
package/build/RampKit.js CHANGED
@@ -17,6 +17,7 @@ class RampKitCore {
17
17
  async init(config) {
18
18
  this.config = config;
19
19
  this.onOnboardingFinished = config.onOnboardingFinished;
20
+ this.onShowPaywall = config.showPaywall;
20
21
  try {
21
22
  // Ensure a stable, encrypted user id exists on first init
22
23
  this.userId = await (0, userId_1.getRampKitUserId)();
@@ -56,7 +57,7 @@ class RampKitCore {
56
57
  getUserId() {
57
58
  return this.userId;
58
59
  }
59
- showOnboarding() {
60
+ showOnboarding(opts) {
60
61
  const data = this.onboardingData;
61
62
  if (!data || !Array.isArray(data.screens) || data.screens.length === 0) {
62
63
  console.log("[RampKit] ShowOnboarding: no onboarding data available");
@@ -109,6 +110,7 @@ class RampKitCore {
109
110
  }
110
111
  catch (_) { }
111
112
  },
113
+ onShowPaywall: (opts === null || opts === void 0 ? void 0 : opts.showPaywall) || this.onShowPaywall,
112
114
  });
113
115
  }
114
116
  catch (e) {
@@ -13,6 +13,7 @@ export declare function showRampkitOverlay(opts: {
13
13
  requiredScripts?: string[];
14
14
  onClose?: () => void;
15
15
  onOnboardingFinished?: (payload?: any) => void;
16
+ onShowPaywall?: () => void;
16
17
  }): void;
17
18
  export declare function hideRampkitOverlay(): void;
18
19
  export declare function preloadRampkitOverlay(opts: {
@@ -29,5 +30,6 @@ declare function Overlay(props: {
29
30
  prebuiltDocs?: string[];
30
31
  onRequestClose: () => void;
31
32
  onOnboardingFinished?: (payload?: any) => void;
33
+ onShowPaywall?: () => void;
32
34
  }): any;
33
35
  export default Overlay;
@@ -138,7 +138,7 @@ function showRampkitOverlay(opts) {
138
138
  var _a;
139
139
  hideRampkitOverlay();
140
140
  (_a = opts.onClose) === null || _a === void 0 ? void 0 : _a.call(opts);
141
- }, onOnboardingFinished: opts.onOnboardingFinished })));
141
+ }, onOnboardingFinished: opts.onOnboardingFinished, onShowPaywall: opts.onShowPaywall })));
142
142
  // Once shown, we can safely discard the preloader sibling if present
143
143
  if (preloadSibling) {
144
144
  preloadSibling.destroy();
@@ -235,6 +235,8 @@ function Overlay(props) {
235
235
  const [firstPageLoaded, setFirstPageLoaded] = (0, react_1.useState)(false);
236
236
  const [visible, setVisible] = (0, react_1.useState)(false);
237
237
  const [isTransitioning, setIsTransitioning] = (0, react_1.useState)(false);
238
+ const [isClosing, setIsClosing] = (0, react_1.useState)(false);
239
+ const overlayOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
238
240
  const fadeOpacity = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
239
241
  const allLoaded = loadedCount >= props.screens.length;
240
242
  // shared vars across all webviews
@@ -243,6 +245,30 @@ function Overlay(props) {
243
245
  const webviewsRef = (0, react_1.useRef)([]);
244
246
  // track when we last initialized a given page with host vars (to filter stale defaults)
245
247
  const lastInitSendRef = (0, react_1.useRef)([]);
248
+ // Fade-in when overlay becomes visible
249
+ react_1.default.useEffect(() => {
250
+ if (visible && !isClosing) {
251
+ react_native_1.Animated.timing(overlayOpacity, {
252
+ toValue: 1,
253
+ duration: 220,
254
+ easing: react_native_1.Easing.out(react_native_1.Easing.cubic),
255
+ useNativeDriver: true,
256
+ }).start();
257
+ }
258
+ }, [visible, isClosing, overlayOpacity]);
259
+ const handleRequestClose = react_1.default.useCallback(() => {
260
+ if (isClosing)
261
+ return;
262
+ setIsClosing(true);
263
+ react_native_1.Animated.timing(overlayOpacity, {
264
+ toValue: 0,
265
+ duration: 220,
266
+ easing: react_native_1.Easing.out(react_native_1.Easing.cubic),
267
+ useNativeDriver: true,
268
+ }).start(() => {
269
+ props.onRequestClose();
270
+ });
271
+ }, [isClosing, overlayOpacity, props.onRequestClose]);
246
272
  // Android hardware back goes to previous page, then closes
247
273
  const navigateToIndex = (nextIndex) => {
248
274
  if (nextIndex === index ||
@@ -312,11 +338,11 @@ function Overlay(props) {
312
338
  navigateToIndex(index - 1);
313
339
  return true;
314
340
  }
315
- props.onRequestClose();
341
+ handleRequestClose();
316
342
  return true;
317
343
  });
318
344
  return () => sub.remove();
319
- }, [index, props.onRequestClose]);
345
+ }, [index, handleRequestClose]);
320
346
  const docs = (0, react_1.useMemo)(() => props.prebuiltDocs ||
321
347
  props.screens.map((s) => buildHtmlDocument(s, props.variables, props.requiredScripts)), [props.prebuiltDocs, props.screens, props.variables, props.requiredScripts]);
322
348
  react_1.default.useEffect(() => {
@@ -364,7 +390,7 @@ function Overlay(props) {
364
390
  else {
365
391
  // finish
366
392
  Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success).catch(() => { });
367
- props.onRequestClose();
393
+ handleRequestClose();
368
394
  }
369
395
  };
370
396
  async function handleNotificationPermissionRequest(payload) {
@@ -451,7 +477,11 @@ function Overlay(props) {
451
477
  }
452
478
  catch (_) { }
453
479
  }
454
- return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [styles.root, !visible && styles.invisible], pointerEvents: visible ? "auto" : "none", children: [(0, jsx_runtime_1.jsx)(react_native_pager_view_1.default, { ref: pagerRef, style: react_native_1.StyleSheet.absoluteFill, scrollEnabled: false, initialPage: 0, onPageSelected: onPageSelected, offscreenPageLimit: props.screens.length, overScrollMode: "never", children: docs.map((doc, i) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.page, renderToHardwareTextureAndroid: true, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { ref: (r) => (webviewsRef.current[i] = r), style: styles.webview, originWhitelist: ["*"], source: { html: doc }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, onLoadEnd: () => {
480
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
481
+ styles.root,
482
+ !visible && styles.invisible,
483
+ visible && { opacity: overlayOpacity },
484
+ ], pointerEvents: visible && !isClosing ? "auto" : "none", children: [(0, jsx_runtime_1.jsx)(react_native_pager_view_1.default, { ref: pagerRef, style: react_native_1.StyleSheet.absoluteFill, scrollEnabled: false, initialPage: 0, onPageSelected: onPageSelected, offscreenPageLimit: props.screens.length, overScrollMode: "never", children: docs.map((doc, i) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.page, renderToHardwareTextureAndroid: true, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { ref: (r) => (webviewsRef.current[i] = r), style: styles.webview, originWhitelist: ["*"], source: { html: doc }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, onLoadEnd: () => {
455
485
  setLoadedCount((c) => c + 1);
456
486
  if (i === 0)
457
487
  setFirstPageLoaded(true);
@@ -460,7 +490,7 @@ function Overlay(props) {
460
490
  console.log("[Rampkit] onLoadEnd init send vars", i);
461
491
  sendVarsToWebView(i);
462
492
  }, onMessage: (ev) => {
463
- var _a, _b;
493
+ var _a, _b, _c, _d;
464
494
  const raw = ev.nativeEvent.data;
465
495
  console.log("raw", raw);
466
496
  // Accept either raw strings or JSON payloads from your editor
@@ -543,7 +573,15 @@ function Overlay(props) {
543
573
  (_a = props.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(props, data === null || data === void 0 ? void 0 : data.payload);
544
574
  }
545
575
  catch (_) { }
546
- props.onRequestClose();
576
+ handleRequestClose();
577
+ return;
578
+ }
579
+ // 6) Request to show paywall
580
+ if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:show-paywall") {
581
+ try {
582
+ (_b = props.onShowPaywall) === null || _b === void 0 ? void 0 : _b.call(props);
583
+ }
584
+ catch (_) { }
547
585
  return;
548
586
  }
549
587
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
@@ -558,7 +596,7 @@ function Overlay(props) {
558
596
  navigateToIndex(i - 1);
559
597
  }
560
598
  else {
561
- props.onRequestClose();
599
+ handleRequestClose();
562
600
  }
563
601
  return;
564
602
  }
@@ -580,12 +618,12 @@ function Overlay(props) {
580
618
  navigateToIndex(i - 1);
581
619
  }
582
620
  else {
583
- props.onRequestClose();
621
+ handleRequestClose();
584
622
  }
585
623
  return;
586
624
  }
587
625
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
588
- props.onRequestClose();
626
+ handleRequestClose();
589
627
  return;
590
628
  }
591
629
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:haptic") {
@@ -593,7 +631,7 @@ function Overlay(props) {
593
631
  return;
594
632
  }
595
633
  }
596
- catch (_c) {
634
+ catch (_e) {
597
635
  // String path
598
636
  if (raw === "rampkit:tap" ||
599
637
  raw === "next" ||
@@ -627,10 +665,17 @@ function Overlay(props) {
627
665
  }
628
666
  if (raw === "rampkit:onboarding-finished") {
629
667
  try {
630
- (_b = props.onOnboardingFinished) === null || _b === void 0 ? void 0 : _b.call(props, undefined);
668
+ (_c = props.onOnboardingFinished) === null || _c === void 0 ? void 0 : _c.call(props, undefined);
669
+ }
670
+ catch (_) { }
671
+ handleRequestClose();
672
+ return;
673
+ }
674
+ if (raw === "rampkit:show-paywall") {
675
+ try {
676
+ (_d = props.onShowPaywall) === null || _d === void 0 ? void 0 : _d.call(props);
631
677
  }
632
678
  catch (_) { }
633
- props.onRequestClose();
634
679
  return;
635
680
  }
636
681
  if (raw === "rampkit:goBack") {
@@ -638,7 +683,7 @@ function Overlay(props) {
638
683
  navigateToIndex(i - 1);
639
684
  }
640
685
  else {
641
- props.onRequestClose();
686
+ handleRequestClose();
642
687
  }
643
688
  return;
644
689
  }
@@ -649,7 +694,7 @@ function Overlay(props) {
649
694
  navigateToIndex(i - 1);
650
695
  }
651
696
  else {
652
- props.onRequestClose();
697
+ handleRequestClose();
653
698
  }
654
699
  return;
655
700
  }
@@ -667,7 +712,7 @@ function Overlay(props) {
667
712
  return;
668
713
  }
669
714
  if (raw === "rampkit:close") {
670
- props.onRequestClose();
715
+ handleRequestClose();
671
716
  return;
672
717
  }
673
718
  if (raw.startsWith("haptic:")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rampkit-expo-dev",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "The Expo SDK for RampKit. Build, test, and personalize app onboardings with instant updates.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",