rampkit-expo-dev 0.0.5 → 0.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/README.md +33 -9
- package/build/RampKit.d.ts +5 -1
- package/build/RampKit.js +3 -1
- package/build/RampkitOverlay.d.ts +2 -0
- package/build/RampkitOverlay.js +70 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
2
|
+
<br />
|
|
3
|
+
<img src="https://dqplcvw3fzili.cloudfront.net/rampkitlogo.png" height="110" />
|
|
3
4
|
</p>
|
|
4
5
|
|
|
5
6
|
<h1 align="center">RampKit Expo SDK</h1>
|
|
@@ -37,15 +38,20 @@ npx expo install rampkit-expo-dev
|
|
|
37
38
|
```ts
|
|
38
39
|
import { RampKit } from "rampkit-expo-dev";
|
|
39
40
|
|
|
40
|
-
RampKit.
|
|
41
|
-
|
|
41
|
+
await RampKit.init({
|
|
42
|
+
apiKey: "YOUR_API_KEY",
|
|
43
|
+
environment: "production", // optional
|
|
44
|
+
autoShowOnboarding: false, // optional
|
|
45
|
+
onOnboardingFinished: (payload) => {
|
|
46
|
+
// optional callback fired when the flow finishes
|
|
47
|
+
},
|
|
42
48
|
});
|
|
43
49
|
```
|
|
44
50
|
|
|
45
51
|
Show an onboarding:
|
|
46
52
|
|
|
47
53
|
```ts
|
|
48
|
-
|
|
54
|
+
RampKit.showOnboarding();
|
|
49
55
|
```
|
|
50
56
|
|
|
51
57
|
---
|
|
@@ -53,11 +59,21 @@ await RampKit.present();
|
|
|
53
59
|
## Configuration Options
|
|
54
60
|
|
|
55
61
|
```ts
|
|
56
|
-
RampKit.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
await RampKit.init({
|
|
63
|
+
apiKey: "abc123",
|
|
64
|
+
environment: "staging", // optional
|
|
65
|
+
autoShowOnboarding: true, // optional (auto-present after init if data is available)
|
|
66
|
+
onOnboardingFinished: (payload) => {
|
|
67
|
+
// optional
|
|
68
|
+
},
|
|
60
69
|
});
|
|
70
|
+
|
|
71
|
+
// Access the generated stable user id (stored securely)
|
|
72
|
+
const idFromInit = RampKit.getUserId(); // string | null (available after init)
|
|
73
|
+
|
|
74
|
+
// Or fetch/generate it directly (always returns a string)
|
|
75
|
+
import { getRampKitUserId } from "rampkit-expo-dev";
|
|
76
|
+
const userId = await getRampKitUserId();
|
|
61
77
|
```
|
|
62
78
|
|
|
63
79
|
More examples are in the docs:
|
|
@@ -68,11 +84,19 @@ https://rampkit.com/docs
|
|
|
68
84
|
## Example
|
|
69
85
|
|
|
70
86
|
```ts
|
|
87
|
+
import { useEffect } from "react";
|
|
71
88
|
import { RampKit } from "rampkit-expo-dev";
|
|
72
89
|
import { Button } from "react-native";
|
|
73
90
|
|
|
74
91
|
export default function App() {
|
|
75
|
-
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
// Initialize once in your app
|
|
94
|
+
RampKit.init({ apiKey: "YOUR_API_KEY" });
|
|
95
|
+
}, []);
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<Button title="Show Onboarding" onPress={() => RampKit.showOnboarding()} />
|
|
99
|
+
);
|
|
76
100
|
}
|
|
77
101
|
```
|
|
78
102
|
|
package/build/RampKit.d.ts
CHANGED
|
@@ -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(
|
|
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;
|
package/build/RampkitOverlay.js
CHANGED
|
@@ -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,39 @@ 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
|
+
try {
|
|
252
|
+
overlayOpacity.stopAnimation();
|
|
253
|
+
}
|
|
254
|
+
catch (_) { }
|
|
255
|
+
overlayOpacity.setValue(0);
|
|
256
|
+
react_native_1.Animated.timing(overlayOpacity, {
|
|
257
|
+
toValue: 1,
|
|
258
|
+
duration: 220,
|
|
259
|
+
easing: react_native_1.Easing.out(react_native_1.Easing.cubic),
|
|
260
|
+
useNativeDriver: true,
|
|
261
|
+
}).start();
|
|
262
|
+
}
|
|
263
|
+
}, [visible, isClosing, overlayOpacity]);
|
|
264
|
+
const handleRequestClose = react_1.default.useCallback(() => {
|
|
265
|
+
if (isClosing)
|
|
266
|
+
return;
|
|
267
|
+
setIsClosing(true);
|
|
268
|
+
try {
|
|
269
|
+
overlayOpacity.stopAnimation();
|
|
270
|
+
}
|
|
271
|
+
catch (_) { }
|
|
272
|
+
react_native_1.Animated.timing(overlayOpacity, {
|
|
273
|
+
toValue: 0,
|
|
274
|
+
duration: 220,
|
|
275
|
+
easing: react_native_1.Easing.out(react_native_1.Easing.cubic),
|
|
276
|
+
useNativeDriver: true,
|
|
277
|
+
}).start(() => {
|
|
278
|
+
props.onRequestClose();
|
|
279
|
+
});
|
|
280
|
+
}, [isClosing, overlayOpacity, props.onRequestClose]);
|
|
246
281
|
// Android hardware back goes to previous page, then closes
|
|
247
282
|
const navigateToIndex = (nextIndex) => {
|
|
248
283
|
if (nextIndex === index ||
|
|
@@ -312,11 +347,11 @@ function Overlay(props) {
|
|
|
312
347
|
navigateToIndex(index - 1);
|
|
313
348
|
return true;
|
|
314
349
|
}
|
|
315
|
-
|
|
350
|
+
handleRequestClose();
|
|
316
351
|
return true;
|
|
317
352
|
});
|
|
318
353
|
return () => sub.remove();
|
|
319
|
-
}, [index,
|
|
354
|
+
}, [index, handleRequestClose]);
|
|
320
355
|
const docs = (0, react_1.useMemo)(() => props.prebuiltDocs ||
|
|
321
356
|
props.screens.map((s) => buildHtmlDocument(s, props.variables, props.requiredScripts)), [props.prebuiltDocs, props.screens, props.variables, props.requiredScripts]);
|
|
322
357
|
react_1.default.useEffect(() => {
|
|
@@ -364,7 +399,7 @@ function Overlay(props) {
|
|
|
364
399
|
else {
|
|
365
400
|
// finish
|
|
366
401
|
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success).catch(() => { });
|
|
367
|
-
|
|
402
|
+
handleRequestClose();
|
|
368
403
|
}
|
|
369
404
|
};
|
|
370
405
|
async function handleNotificationPermissionRequest(payload) {
|
|
@@ -451,7 +486,11 @@ function Overlay(props) {
|
|
|
451
486
|
}
|
|
452
487
|
catch (_) { }
|
|
453
488
|
}
|
|
454
|
-
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
|
|
489
|
+
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
|
|
490
|
+
styles.root,
|
|
491
|
+
!visible && styles.invisible,
|
|
492
|
+
visible && { opacity: overlayOpacity },
|
|
493
|
+
], 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
494
|
setLoadedCount((c) => c + 1);
|
|
456
495
|
if (i === 0)
|
|
457
496
|
setFirstPageLoaded(true);
|
|
@@ -460,7 +499,7 @@ function Overlay(props) {
|
|
|
460
499
|
console.log("[Rampkit] onLoadEnd init send vars", i);
|
|
461
500
|
sendVarsToWebView(i);
|
|
462
501
|
}, onMessage: (ev) => {
|
|
463
|
-
var _a, _b;
|
|
502
|
+
var _a, _b, _c, _d;
|
|
464
503
|
const raw = ev.nativeEvent.data;
|
|
465
504
|
console.log("raw", raw);
|
|
466
505
|
// Accept either raw strings or JSON payloads from your editor
|
|
@@ -543,7 +582,15 @@ function Overlay(props) {
|
|
|
543
582
|
(_a = props.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(props, data === null || data === void 0 ? void 0 : data.payload);
|
|
544
583
|
}
|
|
545
584
|
catch (_) { }
|
|
546
|
-
|
|
585
|
+
handleRequestClose();
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
// 6) Request to show paywall
|
|
589
|
+
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:show-paywall") {
|
|
590
|
+
try {
|
|
591
|
+
(_b = props.onShowPaywall) === null || _b === void 0 ? void 0 : _b.call(props);
|
|
592
|
+
}
|
|
593
|
+
catch (_) { }
|
|
547
594
|
return;
|
|
548
595
|
}
|
|
549
596
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
|
|
@@ -558,7 +605,7 @@ function Overlay(props) {
|
|
|
558
605
|
navigateToIndex(i - 1);
|
|
559
606
|
}
|
|
560
607
|
else {
|
|
561
|
-
|
|
608
|
+
handleRequestClose();
|
|
562
609
|
}
|
|
563
610
|
return;
|
|
564
611
|
}
|
|
@@ -580,12 +627,12 @@ function Overlay(props) {
|
|
|
580
627
|
navigateToIndex(i - 1);
|
|
581
628
|
}
|
|
582
629
|
else {
|
|
583
|
-
|
|
630
|
+
handleRequestClose();
|
|
584
631
|
}
|
|
585
632
|
return;
|
|
586
633
|
}
|
|
587
634
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
|
|
588
|
-
|
|
635
|
+
handleRequestClose();
|
|
589
636
|
return;
|
|
590
637
|
}
|
|
591
638
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:haptic") {
|
|
@@ -593,7 +640,7 @@ function Overlay(props) {
|
|
|
593
640
|
return;
|
|
594
641
|
}
|
|
595
642
|
}
|
|
596
|
-
catch (
|
|
643
|
+
catch (_e) {
|
|
597
644
|
// String path
|
|
598
645
|
if (raw === "rampkit:tap" ||
|
|
599
646
|
raw === "next" ||
|
|
@@ -627,10 +674,17 @@ function Overlay(props) {
|
|
|
627
674
|
}
|
|
628
675
|
if (raw === "rampkit:onboarding-finished") {
|
|
629
676
|
try {
|
|
630
|
-
(
|
|
677
|
+
(_c = props.onOnboardingFinished) === null || _c === void 0 ? void 0 : _c.call(props, undefined);
|
|
678
|
+
}
|
|
679
|
+
catch (_) { }
|
|
680
|
+
handleRequestClose();
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
if (raw === "rampkit:show-paywall") {
|
|
684
|
+
try {
|
|
685
|
+
(_d = props.onShowPaywall) === null || _d === void 0 ? void 0 : _d.call(props);
|
|
631
686
|
}
|
|
632
687
|
catch (_) { }
|
|
633
|
-
props.onRequestClose();
|
|
634
688
|
return;
|
|
635
689
|
}
|
|
636
690
|
if (raw === "rampkit:goBack") {
|
|
@@ -638,7 +692,7 @@ function Overlay(props) {
|
|
|
638
692
|
navigateToIndex(i - 1);
|
|
639
693
|
}
|
|
640
694
|
else {
|
|
641
|
-
|
|
695
|
+
handleRequestClose();
|
|
642
696
|
}
|
|
643
697
|
return;
|
|
644
698
|
}
|
|
@@ -649,7 +703,7 @@ function Overlay(props) {
|
|
|
649
703
|
navigateToIndex(i - 1);
|
|
650
704
|
}
|
|
651
705
|
else {
|
|
652
|
-
|
|
706
|
+
handleRequestClose();
|
|
653
707
|
}
|
|
654
708
|
return;
|
|
655
709
|
}
|
|
@@ -667,7 +721,7 @@ function Overlay(props) {
|
|
|
667
721
|
return;
|
|
668
722
|
}
|
|
669
723
|
if (raw === "rampkit:close") {
|
|
670
|
-
|
|
724
|
+
handleRequestClose();
|
|
671
725
|
return;
|
|
672
726
|
}
|
|
673
727
|
if (raw.startsWith("haptic:")) {
|
package/package.json
CHANGED