@virex-tech/paywallo-sdk 2.2.6 → 2.2.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.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +834 -508
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +726 -400
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2386,8 +2386,8 @@ var init_NotificationHandlerSetup = __esm({
|
|
|
2386
2386
|
// src/core/version.ts
|
|
2387
2387
|
function resolveVersion() {
|
|
2388
2388
|
try {
|
|
2389
|
-
if ("2.2.
|
|
2390
|
-
return "2.2.
|
|
2389
|
+
if ("2.2.7") {
|
|
2390
|
+
return "2.2.7";
|
|
2391
2391
|
}
|
|
2392
2392
|
} catch {
|
|
2393
2393
|
}
|
|
@@ -3057,6 +3057,41 @@ var init_emitPaywallClosed = __esm({
|
|
|
3057
3057
|
}
|
|
3058
3058
|
});
|
|
3059
3059
|
|
|
3060
|
+
// src/domains/paywall/extractFirstPageBackground.ts
|
|
3061
|
+
function extractFirstPageBackground(craftData) {
|
|
3062
|
+
if (!craftData) return DEFAULT_BACKGROUND;
|
|
3063
|
+
try {
|
|
3064
|
+
const data = JSON.parse(craftData);
|
|
3065
|
+
const nodes = { ...data.nodes, ...data.sharedNodes };
|
|
3066
|
+
const rootId = data.rootId;
|
|
3067
|
+
if (!rootId || !nodes[rootId]) return DEFAULT_BACKGROUND;
|
|
3068
|
+
const firstPageId = nodes[rootId].children?.[0];
|
|
3069
|
+
if (!firstPageId) return DEFAULT_BACKGROUND;
|
|
3070
|
+
const bg = nodes[firstPageId]?.props?.backgroundColor;
|
|
3071
|
+
return typeof bg === "string" && bg.length > 0 && bg !== "transparent" ? bg : DEFAULT_BACKGROUND;
|
|
3072
|
+
} catch {
|
|
3073
|
+
return DEFAULT_BACKGROUND;
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
function isColorDark(color) {
|
|
3077
|
+
const hex = color.replace("#", "").trim();
|
|
3078
|
+
const normalized = hex.length === 3 ? hex.split("").map((c) => c + c).join("") : hex;
|
|
3079
|
+
if (normalized.length !== 6) return false;
|
|
3080
|
+
const r = parseInt(normalized.slice(0, 2), 16);
|
|
3081
|
+
const g = parseInt(normalized.slice(2, 4), 16);
|
|
3082
|
+
const b = parseInt(normalized.slice(4, 6), 16);
|
|
3083
|
+
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return false;
|
|
3084
|
+
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
3085
|
+
return luminance < 0.5;
|
|
3086
|
+
}
|
|
3087
|
+
var DEFAULT_BACKGROUND;
|
|
3088
|
+
var init_extractFirstPageBackground = __esm({
|
|
3089
|
+
"src/domains/paywall/extractFirstPageBackground.ts"() {
|
|
3090
|
+
"use strict";
|
|
3091
|
+
DEFAULT_BACKGROUND = "#FFFFFF";
|
|
3092
|
+
}
|
|
3093
|
+
});
|
|
3094
|
+
|
|
3060
3095
|
// src/domains/paywall/parseWebViewMessage.ts
|
|
3061
3096
|
function deriveMessageId(message) {
|
|
3062
3097
|
if (message.id) return message.id;
|
|
@@ -3299,6 +3334,66 @@ var init_localization = __esm({
|
|
|
3299
3334
|
}
|
|
3300
3335
|
});
|
|
3301
3336
|
|
|
3337
|
+
// src/domains/paywall/PaywallSkeleton.tsx
|
|
3338
|
+
function SkeletonBlock({ style, color, opacity }) {
|
|
3339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native14.Animated.View, { style: [style, { backgroundColor: color, opacity }] });
|
|
3340
|
+
}
|
|
3341
|
+
function PaywallSkeleton({ backgroundColor = "#FFFFFF" }) {
|
|
3342
|
+
const pulse = (0, import_react3.useRef)(new import_react_native14.Animated.Value(0.4)).current;
|
|
3343
|
+
(0, import_react3.useEffect)(() => {
|
|
3344
|
+
const loop = import_react_native14.Animated.loop(
|
|
3345
|
+
import_react_native14.Animated.sequence([
|
|
3346
|
+
import_react_native14.Animated.timing(pulse, { toValue: 1, duration: 700, useNativeDriver: true }),
|
|
3347
|
+
import_react_native14.Animated.timing(pulse, { toValue: 0.4, duration: 700, useNativeDriver: true })
|
|
3348
|
+
])
|
|
3349
|
+
);
|
|
3350
|
+
loop.start();
|
|
3351
|
+
return () => loop.stop();
|
|
3352
|
+
}, [pulse]);
|
|
3353
|
+
const placeholder = isColorDark(backgroundColor) ? "rgba(255,255,255,0.13)" : "rgba(0,0,0,0.07)";
|
|
3354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: [styles.container, { backgroundColor }], pointerEvents: "none", children: [
|
|
3355
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native14.View, { style: styles.header, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.logo, color: placeholder, opacity: pulse }) }),
|
|
3356
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.hero, color: placeholder, opacity: pulse }),
|
|
3357
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: styles.titleGroup, children: [
|
|
3358
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.titleLine, color: placeholder, opacity: pulse }),
|
|
3359
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.titleLineShort, color: placeholder, opacity: pulse })
|
|
3360
|
+
] }),
|
|
3361
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: styles.cardsRow, children: [
|
|
3362
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.card, color: placeholder, opacity: pulse }),
|
|
3363
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.card, color: placeholder, opacity: pulse })
|
|
3364
|
+
] }),
|
|
3365
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: styles.footerGroup, children: [
|
|
3366
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.cta, color: placeholder, opacity: pulse }),
|
|
3367
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.footer, color: placeholder, opacity: pulse })
|
|
3368
|
+
] })
|
|
3369
|
+
] });
|
|
3370
|
+
}
|
|
3371
|
+
var import_react3, import_react_native14, import_jsx_runtime, RADIUS, styles;
|
|
3372
|
+
var init_PaywallSkeleton = __esm({
|
|
3373
|
+
"src/domains/paywall/PaywallSkeleton.tsx"() {
|
|
3374
|
+
"use strict";
|
|
3375
|
+
import_react3 = require("react");
|
|
3376
|
+
import_react_native14 = require("react-native");
|
|
3377
|
+
init_extractFirstPageBackground();
|
|
3378
|
+
import_jsx_runtime = require("react/jsx-runtime");
|
|
3379
|
+
RADIUS = 14;
|
|
3380
|
+
styles = import_react_native14.StyleSheet.create({
|
|
3381
|
+
card: { borderRadius: RADIUS, flex: 1, height: 120 },
|
|
3382
|
+
cardsRow: { flexDirection: "row", gap: 12, marginTop: "auto", paddingHorizontal: 24 },
|
|
3383
|
+
container: { flex: 1, paddingBottom: 40, paddingTop: 64 },
|
|
3384
|
+
cta: { borderRadius: 30, height: 58, marginHorizontal: 24 },
|
|
3385
|
+
footer: { alignSelf: "center", borderRadius: 6, height: 12, marginTop: 20, width: 180 },
|
|
3386
|
+
footerGroup: { marginTop: 28 },
|
|
3387
|
+
header: { alignItems: "center", paddingVertical: 12 },
|
|
3388
|
+
hero: { alignSelf: "center", borderRadius: 20, height: 220, marginTop: 16, width: "70%" },
|
|
3389
|
+
logo: { borderRadius: 6, height: 22, width: 110 },
|
|
3390
|
+
titleGroup: { alignItems: "center", gap: 12, marginTop: 28, paddingHorizontal: 24 },
|
|
3391
|
+
titleLine: { borderRadius: 8, height: 26, width: "85%" },
|
|
3392
|
+
titleLineShort: { borderRadius: 8, height: 26, width: "60%" }
|
|
3393
|
+
});
|
|
3394
|
+
}
|
|
3395
|
+
});
|
|
3396
|
+
|
|
3302
3397
|
// src/domains/paywall/paywallScripts.ts
|
|
3303
3398
|
function buildPaywallInjectionScript(data) {
|
|
3304
3399
|
const paywallData = {
|
|
@@ -3347,7 +3442,7 @@ function getNativeWebView() {
|
|
|
3347
3442
|
if (NativeWebViewComponent) return NativeWebViewComponent;
|
|
3348
3443
|
if (nativeWebViewLookupFailed) return null;
|
|
3349
3444
|
try {
|
|
3350
|
-
NativeWebViewComponent = (0,
|
|
3445
|
+
NativeWebViewComponent = (0, import_react_native15.requireNativeComponent)("PaywalloWebView");
|
|
3351
3446
|
return NativeWebViewComponent;
|
|
3352
3447
|
} catch {
|
|
3353
3448
|
nativeWebViewLookupFailed = true;
|
|
@@ -3356,9 +3451,9 @@ function getNativeWebView() {
|
|
|
3356
3451
|
}
|
|
3357
3452
|
function getWebViewEmitter() {
|
|
3358
3453
|
if (webViewEmitter) return webViewEmitter;
|
|
3359
|
-
const mod =
|
|
3454
|
+
const mod = import_react_native15.NativeModules.PaywalloWebViewModule;
|
|
3360
3455
|
if (!mod) return null;
|
|
3361
|
-
webViewEmitter = new
|
|
3456
|
+
webViewEmitter = new import_react_native15.NativeEventEmitter(mod);
|
|
3362
3457
|
return webViewEmitter;
|
|
3363
3458
|
}
|
|
3364
3459
|
async function triggerNativeHaptic(style) {
|
|
@@ -3400,16 +3495,16 @@ function PaywallWebView({
|
|
|
3400
3495
|
onReady,
|
|
3401
3496
|
onError
|
|
3402
3497
|
}) {
|
|
3403
|
-
const paywallDataSent = (0,
|
|
3404
|
-
const loadEndReceived = (0,
|
|
3405
|
-
const [scriptToInject, setScriptToInject] = (0,
|
|
3406
|
-
const webViewRef = (0,
|
|
3407
|
-
const onErrorRef = (0,
|
|
3498
|
+
const paywallDataSent = (0, import_react4.useRef)(false);
|
|
3499
|
+
const loadEndReceived = (0, import_react4.useRef)(false);
|
|
3500
|
+
const [scriptToInject, setScriptToInject] = (0, import_react4.useState)(void 0);
|
|
3501
|
+
const webViewRef = (0, import_react4.useRef)(null);
|
|
3502
|
+
const onErrorRef = (0, import_react4.useRef)(onError);
|
|
3408
3503
|
onErrorRef.current = onError;
|
|
3409
|
-
const onReadyRef = (0,
|
|
3504
|
+
const onReadyRef = (0, import_react4.useRef)(onReady);
|
|
3410
3505
|
onReadyRef.current = onReady;
|
|
3411
|
-
const NativeWebView = (0,
|
|
3412
|
-
(0,
|
|
3506
|
+
const NativeWebView = (0, import_react4.useMemo)(() => getNativeWebView(), []);
|
|
3507
|
+
(0, import_react4.useEffect)(() => {
|
|
3413
3508
|
if (!NativeWebView) {
|
|
3414
3509
|
onErrorRef.current?.({
|
|
3415
3510
|
code: -1,
|
|
@@ -3417,10 +3512,10 @@ function PaywallWebView({
|
|
|
3417
3512
|
});
|
|
3418
3513
|
}
|
|
3419
3514
|
}, [NativeWebView]);
|
|
3420
|
-
const [resolvedWebUrl, setResolvedWebUrl] = (0,
|
|
3515
|
+
const [resolvedWebUrl, setResolvedWebUrl] = (0, import_react4.useState)(
|
|
3421
3516
|
() => webUrlProp ?? PaywalloClient.getWebUrl()
|
|
3422
3517
|
);
|
|
3423
|
-
(0,
|
|
3518
|
+
(0, import_react4.useEffect)(() => {
|
|
3424
3519
|
if (webUrlProp !== void 0) {
|
|
3425
3520
|
setResolvedWebUrl(webUrlProp ?? null);
|
|
3426
3521
|
return;
|
|
@@ -3439,7 +3534,7 @@ function PaywallWebView({
|
|
|
3439
3534
|
}, 200);
|
|
3440
3535
|
return () => clearInterval(interval);
|
|
3441
3536
|
}, [webUrlProp]);
|
|
3442
|
-
(0,
|
|
3537
|
+
(0, import_react4.useEffect)(() => {
|
|
3443
3538
|
if (!resolvedWebUrl) {
|
|
3444
3539
|
onErrorRef.current?.({
|
|
3445
3540
|
code: -1,
|
|
@@ -3447,16 +3542,16 @@ function PaywallWebView({
|
|
|
3447
3542
|
});
|
|
3448
3543
|
}
|
|
3449
3544
|
}, []);
|
|
3450
|
-
const injectScript = (0,
|
|
3451
|
-
if (
|
|
3452
|
-
const handle = (0,
|
|
3545
|
+
const injectScript = (0, import_react4.useCallback)((script) => {
|
|
3546
|
+
if (import_react_native15.Platform.OS === "android") {
|
|
3547
|
+
const handle = (0, import_react_native15.findNodeHandle)(webViewRef.current);
|
|
3453
3548
|
if (handle == null) return;
|
|
3454
|
-
|
|
3549
|
+
import_react_native15.UIManager.dispatchViewManagerCommand(handle, "injectJavaScript", [script]);
|
|
3455
3550
|
return;
|
|
3456
3551
|
}
|
|
3457
3552
|
setScriptToInject(script);
|
|
3458
3553
|
}, []);
|
|
3459
|
-
const buildAndSetInjectionScript = (0,
|
|
3554
|
+
const buildAndSetInjectionScript = (0, import_react4.useCallback)(() => {
|
|
3460
3555
|
if (!craftData || paywallDataSent.current) return;
|
|
3461
3556
|
paywallDataSent.current = true;
|
|
3462
3557
|
const script = buildPaywallInjectionScript({
|
|
@@ -3467,16 +3562,16 @@ function PaywallWebView({
|
|
|
3467
3562
|
});
|
|
3468
3563
|
injectScript(script);
|
|
3469
3564
|
}, [craftData, products, primaryProductId, secondaryProductId, injectScript]);
|
|
3470
|
-
const processedIdsRef = (0,
|
|
3471
|
-
const dedupeTimersRef = (0,
|
|
3472
|
-
(0,
|
|
3565
|
+
const processedIdsRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
|
|
3566
|
+
const dedupeTimersRef = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
|
|
3567
|
+
(0, import_react4.useEffect)(() => {
|
|
3473
3568
|
return () => {
|
|
3474
3569
|
for (const timerId of dedupeTimersRef.current.values()) clearTimeout(timerId);
|
|
3475
3570
|
dedupeTimersRef.current.clear();
|
|
3476
3571
|
processedIdsRef.current.clear();
|
|
3477
3572
|
};
|
|
3478
3573
|
}, []);
|
|
3479
|
-
const handleParsedMessage = (0,
|
|
3574
|
+
const handleParsedMessage = (0, import_react4.useCallback)(
|
|
3480
3575
|
(message) => {
|
|
3481
3576
|
const msgId = deriveMessageId(message);
|
|
3482
3577
|
if (processedIdsRef.current.has(msgId)) return;
|
|
@@ -3510,7 +3605,7 @@ function PaywallWebView({
|
|
|
3510
3605
|
if (message.payload?.url) {
|
|
3511
3606
|
const url = message.payload.url;
|
|
3512
3607
|
if (/^https?:\/\//i.test(url) || /^mailto:/i.test(url) || /^itms-apps:/i.test(url) || /^market:/i.test(url)) {
|
|
3513
|
-
void
|
|
3608
|
+
void import_react_native15.Linking.openURL(url);
|
|
3514
3609
|
}
|
|
3515
3610
|
}
|
|
3516
3611
|
break;
|
|
@@ -3521,7 +3616,7 @@ function PaywallWebView({
|
|
|
3521
3616
|
},
|
|
3522
3617
|
[buildAndSetInjectionScript, onPurchase, onClose, onRestore]
|
|
3523
3618
|
);
|
|
3524
|
-
(0,
|
|
3619
|
+
(0, import_react4.useEffect)(() => {
|
|
3525
3620
|
const emitter = getWebViewEmitter();
|
|
3526
3621
|
if (!emitter) return;
|
|
3527
3622
|
const loadEndSub = emitter.addListener("PaywalloWebViewLoadEnd", () => {
|
|
@@ -3546,7 +3641,7 @@ function PaywallWebView({
|
|
|
3546
3641
|
errorSub.remove();
|
|
3547
3642
|
};
|
|
3548
3643
|
}, [buildAndSetInjectionScript, handleParsedMessage]);
|
|
3549
|
-
(0,
|
|
3644
|
+
(0, import_react4.useEffect)(() => {
|
|
3550
3645
|
const timer = setTimeout(() => {
|
|
3551
3646
|
if (!paywallDataSent.current) {
|
|
3552
3647
|
onErrorRef.current?.({
|
|
@@ -3557,13 +3652,13 @@ function PaywallWebView({
|
|
|
3557
3652
|
}, 1e4);
|
|
3558
3653
|
return () => clearTimeout(timer);
|
|
3559
3654
|
}, []);
|
|
3560
|
-
const handleLoadEnd = (0,
|
|
3655
|
+
const handleLoadEnd = (0, import_react4.useCallback)(() => {
|
|
3561
3656
|
if (!loadEndReceived.current) {
|
|
3562
3657
|
loadEndReceived.current = true;
|
|
3563
3658
|
buildAndSetInjectionScript();
|
|
3564
3659
|
}
|
|
3565
3660
|
}, [buildAndSetInjectionScript]);
|
|
3566
|
-
const handleNativeError = (0,
|
|
3661
|
+
const handleNativeError = (0, import_react4.useCallback)((event) => {
|
|
3567
3662
|
const ne = event.nativeEvent;
|
|
3568
3663
|
let errorData;
|
|
3569
3664
|
if (ne["payload"] && typeof ne["payload"] === "object") {
|
|
@@ -3579,30 +3674,30 @@ function PaywallWebView({
|
|
|
3579
3674
|
}
|
|
3580
3675
|
onErrorRef.current?.(parseErrorEvent(errorData));
|
|
3581
3676
|
}, []);
|
|
3582
|
-
const handleMessage = (0,
|
|
3677
|
+
const handleMessage = (0, import_react4.useCallback)(
|
|
3583
3678
|
(event) => {
|
|
3584
3679
|
const message = parseWebViewMessage(event.nativeEvent.data);
|
|
3585
3680
|
if (message) handleParsedMessage(message);
|
|
3586
3681
|
},
|
|
3587
3682
|
[handleParsedMessage]
|
|
3588
3683
|
);
|
|
3589
|
-
(0,
|
|
3684
|
+
(0, import_react4.useEffect)(() => {
|
|
3590
3685
|
if (!paywallDataSent.current) return;
|
|
3591
3686
|
injectScript(buildPurchaseStateScript(isPurchasing));
|
|
3592
3687
|
}, [isPurchasing, injectScript]);
|
|
3593
|
-
(0,
|
|
3594
|
-
if (
|
|
3688
|
+
(0, import_react4.useEffect)(() => {
|
|
3689
|
+
if (import_react_native15.Platform.OS !== "android") return;
|
|
3595
3690
|
const onBackPress = () => {
|
|
3596
3691
|
if (!paywallDataSent.current) return false;
|
|
3597
3692
|
injectScript(buildBackButtonScript());
|
|
3598
3693
|
return true;
|
|
3599
3694
|
};
|
|
3600
|
-
const subscription =
|
|
3695
|
+
const subscription = import_react_native15.BackHandler.addEventListener("hardwareBackPress", onBackPress);
|
|
3601
3696
|
return () => subscription.remove();
|
|
3602
3697
|
}, [injectScript]);
|
|
3603
3698
|
if (!resolvedWebUrl || !NativeWebView) return null;
|
|
3604
3699
|
const paywallUrl = `${resolvedWebUrl}/paywall/${paywallId}`;
|
|
3605
|
-
return /* @__PURE__ */ (0,
|
|
3700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native15.View, { style: styles2.container, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3606
3701
|
NativeWebView,
|
|
3607
3702
|
{
|
|
3608
3703
|
ref: webViewRef,
|
|
@@ -3611,24 +3706,24 @@ function PaywallWebView({
|
|
|
3611
3706
|
onMessage: handleMessage,
|
|
3612
3707
|
onLoadEnd: handleLoadEnd,
|
|
3613
3708
|
onError: handleNativeError,
|
|
3614
|
-
style:
|
|
3709
|
+
style: styles2.webview
|
|
3615
3710
|
}
|
|
3616
3711
|
) });
|
|
3617
3712
|
}
|
|
3618
|
-
var
|
|
3713
|
+
var import_react4, import_react_native15, import_jsx_runtime2, NativeWebViewComponent, nativeWebViewLookupFailed, webViewEmitter, styles2;
|
|
3619
3714
|
var init_PaywallWebView = __esm({
|
|
3620
3715
|
"src/domains/paywall/PaywallWebView.tsx"() {
|
|
3621
3716
|
"use strict";
|
|
3622
|
-
|
|
3623
|
-
|
|
3717
|
+
import_react4 = require("react");
|
|
3718
|
+
import_react_native15 = require("react-native");
|
|
3624
3719
|
init_PaywalloClient();
|
|
3625
3720
|
init_parseWebViewMessage();
|
|
3626
3721
|
init_paywallScripts();
|
|
3627
|
-
|
|
3722
|
+
import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3628
3723
|
NativeWebViewComponent = null;
|
|
3629
3724
|
nativeWebViewLookupFailed = false;
|
|
3630
3725
|
webViewEmitter = null;
|
|
3631
|
-
|
|
3726
|
+
styles2 = import_react_native15.StyleSheet.create({
|
|
3632
3727
|
container: { flex: 1 },
|
|
3633
3728
|
webview: { flex: 1, backgroundColor: "transparent" }
|
|
3634
3729
|
});
|
|
@@ -3763,7 +3858,7 @@ function mapNativePurchase(native) {
|
|
|
3763
3858
|
transactionId: native.transactionId,
|
|
3764
3859
|
transactionDate: native.transactionDate,
|
|
3765
3860
|
receipt: native.receipt,
|
|
3766
|
-
platform:
|
|
3861
|
+
platform: import_react_native16.Platform.OS
|
|
3767
3862
|
};
|
|
3768
3863
|
}
|
|
3769
3864
|
function normalizeTransactionUpdate(raw) {
|
|
@@ -3783,17 +3878,17 @@ function normalizeTransactionUpdate(raw) {
|
|
|
3783
3878
|
if (typeof r.currency === "string") update.currency = r.currency;
|
|
3784
3879
|
return update;
|
|
3785
3880
|
}
|
|
3786
|
-
var
|
|
3881
|
+
var import_react_native16, TRANSACTION_UPDATE_EVENT, PaywalloStoreKitNative, nativeStoreKit, NativeStoreKit;
|
|
3787
3882
|
var init_NativeStoreKit = __esm({
|
|
3788
3883
|
"src/domains/iap/NativeStoreKit.ts"() {
|
|
3789
3884
|
"use strict";
|
|
3790
|
-
|
|
3885
|
+
import_react_native16 = require("react-native");
|
|
3791
3886
|
init_PaywalloClient();
|
|
3792
3887
|
init_uuid();
|
|
3793
3888
|
init_IdentityManager();
|
|
3794
3889
|
init_PurchaseError();
|
|
3795
3890
|
TRANSACTION_UPDATE_EVENT = "PaywalloTransactionUpdate";
|
|
3796
|
-
PaywalloStoreKitNative =
|
|
3891
|
+
PaywalloStoreKitNative = import_react_native16.NativeModules.PaywalloStoreKit ?? null;
|
|
3797
3892
|
nativeStoreKit = {
|
|
3798
3893
|
isAvailable: isAvailable3,
|
|
3799
3894
|
async getProducts(productIds) {
|
|
@@ -3862,7 +3957,7 @@ var init_NativeStoreKit = __esm({
|
|
|
3862
3957
|
subscribeToTransactionUpdates(listener) {
|
|
3863
3958
|
if (!PaywalloStoreKitNative) return null;
|
|
3864
3959
|
try {
|
|
3865
|
-
const EmitterCtor =
|
|
3960
|
+
const EmitterCtor = import_react_native16.NativeEventEmitter;
|
|
3866
3961
|
const emitter = new EmitterCtor(PaywalloStoreKitNative);
|
|
3867
3962
|
const sub = emitter.addListener(TRANSACTION_UPDATE_EVENT, (payload) => {
|
|
3868
3963
|
const update = normalizeTransactionUpdate(payload);
|
|
@@ -4518,11 +4613,11 @@ var init_types2 = __esm({
|
|
|
4518
4613
|
});
|
|
4519
4614
|
|
|
4520
4615
|
// src/core/network/NetworkMonitor.ts
|
|
4521
|
-
var
|
|
4616
|
+
var import_react_native17, NetworkMonitorClass, networkMonitor;
|
|
4522
4617
|
var init_NetworkMonitor = __esm({
|
|
4523
4618
|
"src/core/network/NetworkMonitor.ts"() {
|
|
4524
4619
|
"use strict";
|
|
4525
|
-
|
|
4620
|
+
import_react_native17 = require("react-native");
|
|
4526
4621
|
init_types2();
|
|
4527
4622
|
NetworkMonitorClass = class {
|
|
4528
4623
|
constructor() {
|
|
@@ -4551,7 +4646,7 @@ var init_NetworkMonitor = __esm({
|
|
|
4551
4646
|
}, this.config.checkInterval);
|
|
4552
4647
|
}
|
|
4553
4648
|
setupAppStateListener() {
|
|
4554
|
-
this.appStateSubscription =
|
|
4649
|
+
this.appStateSubscription = import_react_native17.AppState.addEventListener("change", (state) => {
|
|
4555
4650
|
if (state === "active") {
|
|
4556
4651
|
if (!this.checkIntervalId) {
|
|
4557
4652
|
this.checkIntervalId = setInterval(() => {
|
|
@@ -4920,11 +5015,11 @@ var init_queue = __esm({
|
|
|
4920
5015
|
});
|
|
4921
5016
|
|
|
4922
5017
|
// src/domains/iap/IAPValidator.ts
|
|
4923
|
-
var
|
|
5018
|
+
var import_react_native18, IAPValidator;
|
|
4924
5019
|
var init_IAPValidator = __esm({
|
|
4925
5020
|
"src/domains/iap/IAPValidator.ts"() {
|
|
4926
5021
|
"use strict";
|
|
4927
|
-
|
|
5022
|
+
import_react_native18 = require("react-native");
|
|
4928
5023
|
init_PaywalloClient();
|
|
4929
5024
|
init_queue();
|
|
4930
5025
|
init_PurchaseError();
|
|
@@ -4950,7 +5045,7 @@ var init_IAPValidator = __esm({
|
|
|
4950
5045
|
async validateWithServer(purchase, productId, options) {
|
|
4951
5046
|
const apiClient = this.getApiClientFn();
|
|
4952
5047
|
const product = this.getProductFromCache(productId);
|
|
4953
|
-
const platform =
|
|
5048
|
+
const platform = import_react_native18.Platform.OS;
|
|
4954
5049
|
const distinctId = PaywalloClient.getDistinctId();
|
|
4955
5050
|
return this.validateWithRetry(
|
|
4956
5051
|
() => apiClient.validatePurchase(
|
|
@@ -4985,7 +5080,7 @@ var init_IAPValidator = __esm({
|
|
|
4985
5080
|
try {
|
|
4986
5081
|
const apiClient = this.getApiClientFn();
|
|
4987
5082
|
const product = this.getProductFromCache(productId);
|
|
4988
|
-
const platform =
|
|
5083
|
+
const platform = import_react_native18.Platform.OS;
|
|
4989
5084
|
const distinctId = PaywalloClient.getDistinctId();
|
|
4990
5085
|
const appKey = apiClient.getAppKey();
|
|
4991
5086
|
const body = {
|
|
@@ -5025,11 +5120,11 @@ function getIAPService() {
|
|
|
5025
5120
|
}
|
|
5026
5121
|
return _instance;
|
|
5027
5122
|
}
|
|
5028
|
-
var
|
|
5123
|
+
var import_react_native19, IAPService, _instance;
|
|
5029
5124
|
var init_IAPService = __esm({
|
|
5030
5125
|
"src/domains/iap/IAPService.ts"() {
|
|
5031
5126
|
"use strict";
|
|
5032
|
-
|
|
5127
|
+
import_react_native19 = require("react-native");
|
|
5033
5128
|
init_PaywalloClient();
|
|
5034
5129
|
init_IAPTransactionEmitter();
|
|
5035
5130
|
init_IAPValidator();
|
|
@@ -5179,7 +5274,7 @@ var init_IAPService = __esm({
|
|
|
5179
5274
|
const transactions = await nativeStoreKit.getActiveTransactions();
|
|
5180
5275
|
const apiClient = this.getApiClient();
|
|
5181
5276
|
const distinctId = PaywalloClient.getDistinctId();
|
|
5182
|
-
const platform =
|
|
5277
|
+
const platform = import_react_native19.Platform.OS;
|
|
5183
5278
|
const results = await Promise.allSettled(
|
|
5184
5279
|
transactions.map((tx) => {
|
|
5185
5280
|
const product = this.productsCache.get(tx.productId);
|
|
@@ -5237,11 +5332,11 @@ var init_IAPService = __esm({
|
|
|
5237
5332
|
|
|
5238
5333
|
// src/domains/paywall/usePaywallTracking.ts
|
|
5239
5334
|
function usePaywallTracking() {
|
|
5240
|
-
const trackClosed = (0,
|
|
5335
|
+
const trackClosed = (0, import_react5.useCallback)(async (opts) => {
|
|
5241
5336
|
await emitPaywallClosed(opts);
|
|
5242
5337
|
await stopHeartbeat();
|
|
5243
5338
|
}, []);
|
|
5244
|
-
const trackDismissed = (0,
|
|
5339
|
+
const trackDismissed = (0, import_react5.useCallback)(async (opts) => {
|
|
5245
5340
|
const presentedAt = Date.now() - Math.max(0, opts.duration_ms);
|
|
5246
5341
|
await trackClosed({
|
|
5247
5342
|
placement: opts.placement,
|
|
@@ -5253,17 +5348,17 @@ function usePaywallTracking() {
|
|
|
5253
5348
|
...opts.variantId && { variantId: opts.variantId }
|
|
5254
5349
|
});
|
|
5255
5350
|
}, [trackClosed]);
|
|
5256
|
-
const trackProductSelected = (0,
|
|
5351
|
+
const trackProductSelected = (0, import_react5.useCallback)((_opts) => {
|
|
5257
5352
|
}, []);
|
|
5258
|
-
const trackPurchased = (0,
|
|
5353
|
+
const trackPurchased = (0, import_react5.useCallback)(async (_opts) => {
|
|
5259
5354
|
}, []);
|
|
5260
5355
|
return { trackClosed, trackDismissed, trackProductSelected, trackPurchased };
|
|
5261
5356
|
}
|
|
5262
|
-
var
|
|
5357
|
+
var import_react5;
|
|
5263
5358
|
var init_usePaywallTracking = __esm({
|
|
5264
5359
|
"src/domains/paywall/usePaywallTracking.ts"() {
|
|
5265
5360
|
"use strict";
|
|
5266
|
-
|
|
5361
|
+
import_react5 = require("react");
|
|
5267
5362
|
init_emitPaywallClosed();
|
|
5268
5363
|
init_paywallHeartbeat();
|
|
5269
5364
|
}
|
|
@@ -5271,19 +5366,19 @@ var init_usePaywallTracking = __esm({
|
|
|
5271
5366
|
|
|
5272
5367
|
// src/domains/paywall/usePaywallActions.ts
|
|
5273
5368
|
function usePaywallActions(placement, paywallConfig, onResult, variantKey, campaignId, openAnim, variantId) {
|
|
5274
|
-
const [isPurchasing, setIsPurchasing] = (0,
|
|
5275
|
-
const isPurchasingRef = (0,
|
|
5276
|
-
const [isClosing, setIsClosing] = (0,
|
|
5277
|
-
const slideAnim = (0,
|
|
5278
|
-
const presentedAtRef = (0,
|
|
5279
|
-
const closedRef = (0,
|
|
5369
|
+
const [isPurchasing, setIsPurchasing] = (0, import_react6.useState)(false);
|
|
5370
|
+
const isPurchasingRef = (0, import_react6.useRef)(false);
|
|
5371
|
+
const [isClosing, setIsClosing] = (0, import_react6.useState)(false);
|
|
5372
|
+
const slideAnim = (0, import_react6.useRef)(new import_react_native20.Animated.Value(0)).current;
|
|
5373
|
+
const presentedAtRef = (0, import_react6.useRef)(Date.now());
|
|
5374
|
+
const closedRef = (0, import_react6.useRef)(false);
|
|
5280
5375
|
const { trackDismissed, trackProductSelected, trackPurchased } = usePaywallTracking();
|
|
5281
|
-
const closeWithReason = (0,
|
|
5376
|
+
const closeWithReason = (0, import_react6.useCallback)((reason, resultOverride) => {
|
|
5282
5377
|
if (closedRef.current) return;
|
|
5283
5378
|
closedRef.current = true;
|
|
5284
5379
|
const animTarget = openAnim ?? slideAnim;
|
|
5285
|
-
|
|
5286
|
-
toValue:
|
|
5380
|
+
import_react_native20.Animated.timing(animTarget, {
|
|
5381
|
+
toValue: import_react_native20.Dimensions.get("window").height,
|
|
5287
5382
|
duration: 350,
|
|
5288
5383
|
useNativeDriver: true
|
|
5289
5384
|
}).start(() => {
|
|
@@ -5297,13 +5392,13 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5297
5392
|
onResult(resultOverride ?? { presented: true, purchased: false, cancelled: true, restored: false });
|
|
5298
5393
|
});
|
|
5299
5394
|
}, [openAnim, slideAnim, paywallConfig, placement, trackDismissed, variantKey, campaignId, variantId, onResult]);
|
|
5300
|
-
const handleClose = (0,
|
|
5395
|
+
const handleClose = (0, import_react6.useCallback)(() => {
|
|
5301
5396
|
if (isClosing) return;
|
|
5302
5397
|
setIsClosing(true);
|
|
5303
5398
|
closeWithReason("dismissed");
|
|
5304
5399
|
}, [isClosing, closeWithReason]);
|
|
5305
|
-
(0,
|
|
5306
|
-
const sub =
|
|
5400
|
+
(0, import_react6.useEffect)(() => {
|
|
5401
|
+
const sub = import_react_native20.AppState.addEventListener("change", (nextState) => {
|
|
5307
5402
|
if (isPurchasingRef.current) return;
|
|
5308
5403
|
if (nextState === "background" || nextState === "inactive") {
|
|
5309
5404
|
closeWithReason("backgrounded");
|
|
@@ -5311,13 +5406,13 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5311
5406
|
});
|
|
5312
5407
|
return () => sub.remove();
|
|
5313
5408
|
}, [closeWithReason]);
|
|
5314
|
-
(0,
|
|
5409
|
+
(0, import_react6.useEffect)(() => {
|
|
5315
5410
|
const timer = setTimeout(() => {
|
|
5316
5411
|
closeWithReason("timeout");
|
|
5317
5412
|
}, PAYWALL_TIMEOUT_MS);
|
|
5318
5413
|
return () => clearTimeout(timer);
|
|
5319
5414
|
}, [closeWithReason]);
|
|
5320
|
-
const handlePurchase = (0,
|
|
5415
|
+
const handlePurchase = (0, import_react6.useCallback)(async (productId) => {
|
|
5321
5416
|
if (isPurchasing) return;
|
|
5322
5417
|
setIsPurchasing(true);
|
|
5323
5418
|
isPurchasingRef.current = true;
|
|
@@ -5347,7 +5442,7 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5347
5442
|
setIsPurchasing(false);
|
|
5348
5443
|
}
|
|
5349
5444
|
}, [isPurchasing, onResult, paywallConfig, placement, trackDismissed, trackProductSelected, trackPurchased, variantKey, campaignId, variantId]);
|
|
5350
|
-
const handleRestore = (0,
|
|
5445
|
+
const handleRestore = (0, import_react6.useCallback)(async () => {
|
|
5351
5446
|
if (isPurchasing) return;
|
|
5352
5447
|
setIsPurchasing(true);
|
|
5353
5448
|
isPurchasingRef.current = true;
|
|
@@ -5371,12 +5466,12 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5371
5466
|
}, [isPurchasing, onResult, paywallConfig, placement, trackDismissed, variantKey, campaignId, variantId]);
|
|
5372
5467
|
return { isPurchasing, slideAnim, handleClose, handlePurchase, handleRestore };
|
|
5373
5468
|
}
|
|
5374
|
-
var
|
|
5469
|
+
var import_react6, import_react_native20, PAYWALL_TIMEOUT_MS;
|
|
5375
5470
|
var init_usePaywallActions = __esm({
|
|
5376
5471
|
"src/domains/paywall/usePaywallActions.ts"() {
|
|
5377
5472
|
"use strict";
|
|
5378
|
-
|
|
5379
|
-
|
|
5473
|
+
import_react6 = require("react");
|
|
5474
|
+
import_react_native20 = require("react-native");
|
|
5380
5475
|
init_IAPService();
|
|
5381
5476
|
init_usePaywallTracking();
|
|
5382
5477
|
PAYWALL_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
@@ -5385,15 +5480,15 @@ var init_usePaywallActions = __esm({
|
|
|
5385
5480
|
|
|
5386
5481
|
// src/domains/paywall/usePaywallLoader.ts
|
|
5387
5482
|
function usePaywallLoader(placement, visible, preloadedConfig, preloadedProducts, variantKey, campaignId, variantId) {
|
|
5388
|
-
const [error, setError] = (0,
|
|
5389
|
-
const [paywallConfig, setPaywallConfig] = (0,
|
|
5390
|
-
const [products, setProducts] = (0,
|
|
5391
|
-
const preloadedConfigRef = (0,
|
|
5483
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
5484
|
+
const [paywallConfig, setPaywallConfig] = (0, import_react7.useState)(null);
|
|
5485
|
+
const [products, setProducts] = (0, import_react7.useState)(/* @__PURE__ */ new Map());
|
|
5486
|
+
const preloadedConfigRef = (0, import_react7.useRef)(preloadedConfig);
|
|
5392
5487
|
preloadedConfigRef.current = preloadedConfig;
|
|
5393
|
-
const preloadedProductsRef = (0,
|
|
5488
|
+
const preloadedProductsRef = (0, import_react7.useRef)(preloadedProducts);
|
|
5394
5489
|
preloadedProductsRef.current = preloadedProducts;
|
|
5395
|
-
const trackingDoneRef = (0,
|
|
5396
|
-
(0,
|
|
5490
|
+
const trackingDoneRef = (0, import_react7.useRef)(false);
|
|
5491
|
+
(0, import_react7.useEffect)(() => {
|
|
5397
5492
|
if (!visible) {
|
|
5398
5493
|
trackingDoneRef.current = false;
|
|
5399
5494
|
return;
|
|
@@ -5478,11 +5573,11 @@ function usePaywallLoader(placement, visible, preloadedConfig, preloadedProducts
|
|
|
5478
5573
|
}, [placement, visible, variantKey, campaignId, variantId]);
|
|
5479
5574
|
return { paywallConfig, products, error };
|
|
5480
5575
|
}
|
|
5481
|
-
var
|
|
5576
|
+
var import_react7;
|
|
5482
5577
|
var init_usePaywallLoader = __esm({
|
|
5483
5578
|
"src/domains/paywall/usePaywallLoader.ts"() {
|
|
5484
5579
|
"use strict";
|
|
5485
|
-
|
|
5580
|
+
import_react7 = require("react");
|
|
5486
5581
|
init_PaywalloClient();
|
|
5487
5582
|
init_IAPService();
|
|
5488
5583
|
init_PaywallError();
|
|
@@ -5495,11 +5590,11 @@ function ErrorFallback({ description, onRetry, onClose }) {
|
|
|
5495
5590
|
const title = overrides?.title ?? getSdkString("paywallErrorTitle");
|
|
5496
5591
|
const retryLabel = overrides?.retry ?? getSdkString("paywallRetryButton");
|
|
5497
5592
|
const closeLabel = overrides?.close ?? getSdkString("paywallCloseButton");
|
|
5498
|
-
return /* @__PURE__ */ (0,
|
|
5499
|
-
/* @__PURE__ */ (0,
|
|
5500
|
-
/* @__PURE__ */ (0,
|
|
5501
|
-
/* @__PURE__ */ (0,
|
|
5502
|
-
/* @__PURE__ */ (0,
|
|
5593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.View, { style: styles3.fallbackContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native21.View, { style: styles3.fallbackCard, children: [
|
|
5594
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.fallbackTitle, children: title }),
|
|
5595
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.fallbackDescription, children: description }),
|
|
5596
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Pressable, { style: styles3.retryButton, onPress: onRetry, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.retryButtonText, children: retryLabel }) }),
|
|
5597
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Pressable, { style: styles3.closeButton, onPress: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.closeButtonText, children: closeLabel }) })
|
|
5503
5598
|
] }) });
|
|
5504
5599
|
}
|
|
5505
5600
|
function PaywallModal({
|
|
@@ -5521,18 +5616,20 @@ function PaywallModal({
|
|
|
5521
5616
|
campaignId,
|
|
5522
5617
|
variantId
|
|
5523
5618
|
);
|
|
5524
|
-
const screenHeight =
|
|
5525
|
-
const openAnim = (0,
|
|
5526
|
-
const [modalVisible, setModalVisible] = (0,
|
|
5527
|
-
const handleResult = (0,
|
|
5619
|
+
const screenHeight = import_react_native21.Dimensions.get("window").height;
|
|
5620
|
+
const openAnim = (0, import_react8.useRef)(new import_react_native21.Animated.Value(screenHeight)).current;
|
|
5621
|
+
const [modalVisible, setModalVisible] = (0, import_react8.useState)(false);
|
|
5622
|
+
const handleResult = (0, import_react8.useCallback)((result) => {
|
|
5528
5623
|
setModalVisible(false);
|
|
5529
5624
|
onResult(result);
|
|
5530
5625
|
}, [onResult]);
|
|
5531
5626
|
const { isPurchasing, slideAnim, handleClose, handlePurchase, handleRestore } = usePaywallActions(placement, paywallConfig, handleResult, variantKey, campaignId, openAnim, variantId);
|
|
5532
|
-
const [webViewError, setWebViewError] = (0,
|
|
5533
|
-
const [retryCount, setRetryCount] = (0,
|
|
5534
|
-
const
|
|
5535
|
-
const
|
|
5627
|
+
const [webViewError, setWebViewError] = (0, import_react8.useState)(null);
|
|
5628
|
+
const [retryCount, setRetryCount] = (0, import_react8.useState)(0);
|
|
5629
|
+
const [showSkeleton, setShowSkeleton] = (0, import_react8.useState)(true);
|
|
5630
|
+
const skeletonOpacity = (0, import_react8.useRef)(new import_react_native21.Animated.Value(1)).current;
|
|
5631
|
+
const retryCountRef = (0, import_react8.useRef)(0);
|
|
5632
|
+
const handleWebViewError = (0, import_react8.useCallback)(
|
|
5536
5633
|
(err) => {
|
|
5537
5634
|
if (retryCountRef.current >= 1) {
|
|
5538
5635
|
setWebViewError({ code: err.code, description: err.description });
|
|
@@ -5543,26 +5640,44 @@ function PaywallModal({
|
|
|
5543
5640
|
},
|
|
5544
5641
|
[]
|
|
5545
5642
|
);
|
|
5546
|
-
const handleRetry = (0,
|
|
5643
|
+
const handleRetry = (0, import_react8.useCallback)(() => {
|
|
5547
5644
|
retryCountRef.current = 0;
|
|
5548
5645
|
setWebViewError(null);
|
|
5549
5646
|
setRetryCount(0);
|
|
5550
|
-
|
|
5551
|
-
|
|
5647
|
+
setShowSkeleton(true);
|
|
5648
|
+
skeletonOpacity.setValue(1);
|
|
5649
|
+
}, [skeletonOpacity]);
|
|
5650
|
+
const handleWebViewReady = (0, import_react8.useCallback)(() => {
|
|
5651
|
+
import_react_native21.Animated.timing(skeletonOpacity, {
|
|
5652
|
+
toValue: 0,
|
|
5653
|
+
duration: 250,
|
|
5654
|
+
easing: import_react_native21.Easing.out(import_react_native21.Easing.cubic),
|
|
5655
|
+
useNativeDriver: true
|
|
5656
|
+
}).start(() => setShowSkeleton(false));
|
|
5657
|
+
}, [skeletonOpacity]);
|
|
5658
|
+
(0, import_react8.useEffect)(() => {
|
|
5659
|
+
if (!visible || !showSkeleton) return;
|
|
5660
|
+
const timer = setTimeout(handleWebViewReady, 8e3);
|
|
5661
|
+
return () => clearTimeout(timer);
|
|
5662
|
+
}, [visible, showSkeleton, handleWebViewReady]);
|
|
5663
|
+
(0, import_react8.useEffect)(() => {
|
|
5552
5664
|
if (visible) {
|
|
5553
5665
|
setModalVisible(true);
|
|
5554
|
-
|
|
5555
|
-
|
|
5666
|
+
setShowSkeleton(true);
|
|
5667
|
+
skeletonOpacity.setValue(1);
|
|
5668
|
+
openAnim.setValue(import_react_native21.Dimensions.get("window").height);
|
|
5669
|
+
import_react_native21.Animated.timing(openAnim, {
|
|
5556
5670
|
toValue: 0,
|
|
5557
5671
|
duration: 550,
|
|
5558
|
-
easing:
|
|
5672
|
+
easing: import_react_native21.Easing.out(import_react_native21.Easing.cubic),
|
|
5559
5673
|
useNativeDriver: true
|
|
5560
5674
|
}).start();
|
|
5561
5675
|
}
|
|
5562
|
-
}, [visible, openAnim]);
|
|
5676
|
+
}, [visible, openAnim, skeletonOpacity]);
|
|
5563
5677
|
if (!modalVisible && !visible) return null;
|
|
5564
|
-
|
|
5565
|
-
|
|
5678
|
+
const skeletonBackground = paywallConfig && "craftData" in paywallConfig.config ? extractFirstPageBackground(paywallConfig.config.craftData) : "#FFFFFF";
|
|
5679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5680
|
+
import_react_native21.Modal,
|
|
5566
5681
|
{
|
|
5567
5682
|
visible: modalVisible,
|
|
5568
5683
|
animationType: "none",
|
|
@@ -5570,16 +5685,16 @@ function PaywallModal({
|
|
|
5570
5685
|
onRequestClose: handleClose,
|
|
5571
5686
|
transparent: true,
|
|
5572
5687
|
statusBarTranslucent: true,
|
|
5573
|
-
children: /* @__PURE__ */ (0,
|
|
5574
|
-
error && /* @__PURE__ */ (0,
|
|
5575
|
-
!error && paywallConfig && "craftData" in paywallConfig.config && /* @__PURE__ */ (0,
|
|
5688
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.View, { style: styles3.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Animated.View, { style: [styles3.animatedContainer, { transform: [{ translateY: openAnim }] }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native21.View, { style: styles3.container, children: [
|
|
5689
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.View, { style: styles3.errorContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.errorText, children: error.message }) }),
|
|
5690
|
+
!error && paywallConfig && "craftData" in paywallConfig.config && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: webViewError ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5576
5691
|
ErrorFallback,
|
|
5577
5692
|
{
|
|
5578
5693
|
description: webViewError.description,
|
|
5579
5694
|
onRetry: handleRetry,
|
|
5580
5695
|
onClose: handleClose
|
|
5581
5696
|
}
|
|
5582
|
-
) : /* @__PURE__ */ (0,
|
|
5697
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5583
5698
|
PaywallWebView,
|
|
5584
5699
|
{
|
|
5585
5700
|
paywallId: paywallConfig.id,
|
|
@@ -5588,30 +5703,41 @@ function PaywallModal({
|
|
|
5588
5703
|
primaryProductId: paywallConfig.primaryProductId,
|
|
5589
5704
|
secondaryProductId: paywallConfig.secondaryProductId,
|
|
5590
5705
|
isPurchasing,
|
|
5706
|
+
onReady: handleWebViewReady,
|
|
5591
5707
|
onClose: handleClose,
|
|
5592
5708
|
onPurchase: handlePurchase,
|
|
5593
5709
|
onRestore: handleRestore,
|
|
5594
5710
|
onError: handleWebViewError
|
|
5595
5711
|
},
|
|
5596
5712
|
retryCount
|
|
5597
|
-
) })
|
|
5713
|
+
) }),
|
|
5714
|
+
showSkeleton && !error && !webViewError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5715
|
+
import_react_native21.Animated.View,
|
|
5716
|
+
{
|
|
5717
|
+
style: [import_react_native21.StyleSheet.absoluteFill, { opacity: skeletonOpacity }],
|
|
5718
|
+
pointerEvents: "none",
|
|
5719
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaywallSkeleton, { backgroundColor: skeletonBackground })
|
|
5720
|
+
}
|
|
5721
|
+
)
|
|
5598
5722
|
] }) }) })
|
|
5599
5723
|
}
|
|
5600
5724
|
);
|
|
5601
5725
|
}
|
|
5602
|
-
var
|
|
5726
|
+
var import_react8, import_react_native21, import_jsx_runtime3, styles3;
|
|
5603
5727
|
var init_PaywallModal = __esm({
|
|
5604
5728
|
"src/domains/paywall/PaywallModal.tsx"() {
|
|
5605
5729
|
"use strict";
|
|
5606
|
-
|
|
5607
|
-
|
|
5730
|
+
import_react8 = require("react");
|
|
5731
|
+
import_react_native21 = require("react-native");
|
|
5608
5732
|
init_PaywalloClient();
|
|
5609
5733
|
init_localization();
|
|
5734
|
+
init_extractFirstPageBackground();
|
|
5735
|
+
init_PaywallSkeleton();
|
|
5610
5736
|
init_PaywallWebView();
|
|
5611
5737
|
init_usePaywallActions();
|
|
5612
5738
|
init_usePaywallLoader();
|
|
5613
|
-
|
|
5614
|
-
|
|
5739
|
+
import_jsx_runtime3 = require("react/jsx-runtime");
|
|
5740
|
+
styles3 = import_react_native21.StyleSheet.create({
|
|
5615
5741
|
overlay: { flex: 1, backgroundColor: "rgba(0,0,0,0.3)" },
|
|
5616
5742
|
animatedContainer: { flex: 1, backgroundColor: "#fff" },
|
|
5617
5743
|
container: { flex: 1, backgroundColor: "#fff" },
|
|
@@ -5667,12 +5793,175 @@ var init_PaywallModal = __esm({
|
|
|
5667
5793
|
}
|
|
5668
5794
|
});
|
|
5669
5795
|
|
|
5796
|
+
// src/domains/paywall/PaywallPreloadService.ts
|
|
5797
|
+
var PRELOAD_TTL_MS, STALE_THRESHOLD, PaywallPreloadService, paywallPreloadService;
|
|
5798
|
+
var init_PaywallPreloadService = __esm({
|
|
5799
|
+
"src/domains/paywall/PaywallPreloadService.ts"() {
|
|
5800
|
+
"use strict";
|
|
5801
|
+
init_PaywalloClient();
|
|
5802
|
+
init_IAPService();
|
|
5803
|
+
init_PaywallError();
|
|
5804
|
+
PRELOAD_TTL_MS = 5 * 60 * 1e3;
|
|
5805
|
+
STALE_THRESHOLD = 0.75;
|
|
5806
|
+
PaywallPreloadService = class {
|
|
5807
|
+
constructor() {
|
|
5808
|
+
this.preloaded = /* @__PURE__ */ new Map();
|
|
5809
|
+
this.activePreloads = /* @__PURE__ */ new Map();
|
|
5810
|
+
this.apiClientRef = null;
|
|
5811
|
+
}
|
|
5812
|
+
async preload(apiClient, placement) {
|
|
5813
|
+
this.apiClientRef = apiClient;
|
|
5814
|
+
const existing = this.activePreloads.get(placement);
|
|
5815
|
+
if (existing) return existing;
|
|
5816
|
+
const promise = this.doPreload(apiClient, placement);
|
|
5817
|
+
this.activePreloads.set(placement, promise);
|
|
5818
|
+
try {
|
|
5819
|
+
return await promise;
|
|
5820
|
+
} finally {
|
|
5821
|
+
this.activePreloads.delete(placement);
|
|
5822
|
+
}
|
|
5823
|
+
}
|
|
5824
|
+
async preloadMany(apiClient, placements) {
|
|
5825
|
+
this.apiClientRef = apiClient;
|
|
5826
|
+
if (placements.length === 0) return;
|
|
5827
|
+
const debug = PaywalloClient.getConfig()?.debug;
|
|
5828
|
+
if (debug) console.log(`[Paywallo PRELOAD] paywalls: ${placements.length} placements`);
|
|
5829
|
+
for (let i = 0; i < placements.length; i++) {
|
|
5830
|
+
if (i > 0) await new Promise((r) => setTimeout(r, 200));
|
|
5831
|
+
void this.preload(apiClient, placements[i]).catch((err) => {
|
|
5832
|
+
if (debug) console.log(`[Paywallo PRELOAD] paywall failed ${placements[i]}:`, err);
|
|
5833
|
+
});
|
|
5834
|
+
}
|
|
5835
|
+
}
|
|
5836
|
+
getPreloaded(placement) {
|
|
5837
|
+
const cached2 = this.preloaded.get(placement);
|
|
5838
|
+
if (!cached2) return null;
|
|
5839
|
+
const age = Date.now() - cached2.preloadedAt;
|
|
5840
|
+
if (age >= PRELOAD_TTL_MS) {
|
|
5841
|
+
this.preloaded.delete(placement);
|
|
5842
|
+
return null;
|
|
5843
|
+
}
|
|
5844
|
+
if (age >= PRELOAD_TTL_MS * STALE_THRESHOLD && this.apiClientRef) {
|
|
5845
|
+
void this.preload(this.apiClientRef, placement).catch(() => {
|
|
5846
|
+
});
|
|
5847
|
+
}
|
|
5848
|
+
return { config: cached2.config, products: new Map(cached2.products) };
|
|
5849
|
+
}
|
|
5850
|
+
isPreloaded(placement) {
|
|
5851
|
+
return this.getPreloaded(placement) !== null;
|
|
5852
|
+
}
|
|
5853
|
+
clear() {
|
|
5854
|
+
this.preloaded.clear();
|
|
5855
|
+
this.activePreloads.clear();
|
|
5856
|
+
}
|
|
5857
|
+
async doPreload(apiClient, placement) {
|
|
5858
|
+
try {
|
|
5859
|
+
const config = await apiClient.getPaywall(placement);
|
|
5860
|
+
if (!config) {
|
|
5861
|
+
return {
|
|
5862
|
+
success: false,
|
|
5863
|
+
error: new PaywallError(
|
|
5864
|
+
PAYWALL_ERROR_CODES.NOT_FOUND,
|
|
5865
|
+
`Paywall not found for placement: ${placement}`
|
|
5866
|
+
)
|
|
5867
|
+
};
|
|
5868
|
+
}
|
|
5869
|
+
const products = await this.loadProductsFor(config);
|
|
5870
|
+
this.preloaded.set(placement, { config, products, preloadedAt: Date.now() });
|
|
5871
|
+
if (PaywalloClient.getConfig()?.debug) {
|
|
5872
|
+
console.log(`[Paywallo PRELOAD] paywall cached \u2014 placement: ${placement}`);
|
|
5873
|
+
}
|
|
5874
|
+
return { success: true };
|
|
5875
|
+
} catch (error) {
|
|
5876
|
+
return {
|
|
5877
|
+
success: false,
|
|
5878
|
+
error: error instanceof Error ? error : new PaywallError(PAYWALL_ERROR_CODES.LOAD_FAILED, String(error))
|
|
5879
|
+
};
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5882
|
+
async loadProductsFor(config) {
|
|
5883
|
+
const productIds = [];
|
|
5884
|
+
if (config.primaryProductId) productIds.push(config.primaryProductId);
|
|
5885
|
+
if (config.secondaryProductId) productIds.push(config.secondaryProductId);
|
|
5886
|
+
if (productIds.length === 0) return /* @__PURE__ */ new Map();
|
|
5887
|
+
try {
|
|
5888
|
+
const loaded = await getIAPService().loadProducts(productIds);
|
|
5889
|
+
const map = /* @__PURE__ */ new Map();
|
|
5890
|
+
for (const p of loaded) map.set(p.productId, p);
|
|
5891
|
+
return map;
|
|
5892
|
+
} catch (err) {
|
|
5893
|
+
if (PaywalloClient.getConfig()?.debug) {
|
|
5894
|
+
console.log("[Paywallo PRELOAD] products failed, caching config only:", err);
|
|
5895
|
+
}
|
|
5896
|
+
return /* @__PURE__ */ new Map();
|
|
5897
|
+
}
|
|
5898
|
+
}
|
|
5899
|
+
};
|
|
5900
|
+
paywallPreloadService = new PaywallPreloadService();
|
|
5901
|
+
}
|
|
5902
|
+
});
|
|
5903
|
+
|
|
5904
|
+
// src/domains/paywall/PaywallWebViewPrewarmer.tsx
|
|
5905
|
+
function getNativeWebView2() {
|
|
5906
|
+
if (NativeWebViewComponent2) return NativeWebViewComponent2;
|
|
5907
|
+
if (nativeLookupFailed) return null;
|
|
5908
|
+
try {
|
|
5909
|
+
NativeWebViewComponent2 = (0, import_react_native22.requireNativeComponent)("PaywalloWebView");
|
|
5910
|
+
return NativeWebViewComponent2;
|
|
5911
|
+
} catch {
|
|
5912
|
+
nativeLookupFailed = true;
|
|
5913
|
+
return null;
|
|
5914
|
+
}
|
|
5915
|
+
}
|
|
5916
|
+
function PaywallWebViewPrewarmer({
|
|
5917
|
+
webUrl,
|
|
5918
|
+
durationMs = DEFAULT_DURATION_MS
|
|
5919
|
+
}) {
|
|
5920
|
+
const NativeWebView = (0, import_react9.useMemo)(() => getNativeWebView2(), []);
|
|
5921
|
+
const [mounted, setMounted] = (0, import_react9.useState)(true);
|
|
5922
|
+
(0, import_react9.useEffect)(() => {
|
|
5923
|
+
if (!NativeWebView) return;
|
|
5924
|
+
const timer = setTimeout(() => setMounted(false), durationMs);
|
|
5925
|
+
return () => clearTimeout(timer);
|
|
5926
|
+
}, [NativeWebView, durationMs]);
|
|
5927
|
+
if (!NativeWebView || !mounted) return null;
|
|
5928
|
+
const preheatUrl = `${webUrl}/paywall/preheat`;
|
|
5929
|
+
if (PaywalloClient.getConfig()?.debug) {
|
|
5930
|
+
console.log(`[Paywallo PREWARM] mounting hidden WebView: ${preheatUrl}`);
|
|
5931
|
+
}
|
|
5932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native22.View, { pointerEvents: "none", style: styles4.hidden, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NativeWebView, { sourceUrl: preheatUrl, style: styles4.fill }) });
|
|
5933
|
+
}
|
|
5934
|
+
var import_react9, import_react_native22, import_jsx_runtime4, NativeWebViewComponent2, nativeLookupFailed, DEFAULT_DURATION_MS, styles4;
|
|
5935
|
+
var init_PaywallWebViewPrewarmer = __esm({
|
|
5936
|
+
"src/domains/paywall/PaywallWebViewPrewarmer.tsx"() {
|
|
5937
|
+
"use strict";
|
|
5938
|
+
import_react9 = require("react");
|
|
5939
|
+
import_react_native22 = require("react-native");
|
|
5940
|
+
init_PaywalloClient();
|
|
5941
|
+
import_jsx_runtime4 = require("react/jsx-runtime");
|
|
5942
|
+
NativeWebViewComponent2 = null;
|
|
5943
|
+
nativeLookupFailed = false;
|
|
5944
|
+
DEFAULT_DURATION_MS = 60 * 1e3;
|
|
5945
|
+
styles4 = import_react_native22.StyleSheet.create({
|
|
5946
|
+
hidden: {
|
|
5947
|
+
height: 1,
|
|
5948
|
+
left: -9999,
|
|
5949
|
+
opacity: 0,
|
|
5950
|
+
position: "absolute",
|
|
5951
|
+
top: -9999,
|
|
5952
|
+
width: 1
|
|
5953
|
+
},
|
|
5954
|
+
fill: { flex: 1 }
|
|
5955
|
+
});
|
|
5956
|
+
}
|
|
5957
|
+
});
|
|
5958
|
+
|
|
5670
5959
|
// src/domains/paywall/usePaywallSession.ts
|
|
5671
5960
|
function usePaywallSession(options) {
|
|
5672
|
-
const closedRef = (0,
|
|
5673
|
-
const optsRef = (0,
|
|
5961
|
+
const closedRef = (0, import_react10.useRef)(false);
|
|
5962
|
+
const optsRef = (0, import_react10.useRef)(options);
|
|
5674
5963
|
optsRef.current = options;
|
|
5675
|
-
(0,
|
|
5964
|
+
(0, import_react10.useEffect)(() => {
|
|
5676
5965
|
if (!options) return;
|
|
5677
5966
|
closedRef.current = false;
|
|
5678
5967
|
startHeartbeat({
|
|
@@ -5702,16 +5991,16 @@ function usePaywallSession(options) {
|
|
|
5702
5991
|
});
|
|
5703
5992
|
};
|
|
5704
5993
|
}, [options?.paywallId, options?.placement]);
|
|
5705
|
-
const markClosed = (0,
|
|
5994
|
+
const markClosed = (0, import_react10.useCallback)(() => {
|
|
5706
5995
|
closedRef.current = true;
|
|
5707
5996
|
}, []);
|
|
5708
5997
|
return { markClosed };
|
|
5709
5998
|
}
|
|
5710
|
-
var
|
|
5999
|
+
var import_react10;
|
|
5711
6000
|
var init_usePaywallSession = __esm({
|
|
5712
6001
|
"src/domains/paywall/usePaywallSession.ts"() {
|
|
5713
6002
|
"use strict";
|
|
5714
|
-
|
|
6003
|
+
import_react10 = require("react");
|
|
5715
6004
|
init_emitPaywallClosed();
|
|
5716
6005
|
init_paywallHeartbeat();
|
|
5717
6006
|
}
|
|
@@ -5719,9 +6008,9 @@ var init_usePaywallSession = __esm({
|
|
|
5719
6008
|
|
|
5720
6009
|
// src/domains/paywall/usePaywallPresenter.ts
|
|
5721
6010
|
function usePaywallPresenter(preloadedWebView, setPreloadedWebView) {
|
|
5722
|
-
const [showingPreloadedWebView, setShowingPreloadedWebView] = (0,
|
|
5723
|
-
const resolverRef = (0,
|
|
5724
|
-
const presentedAtRef = (0,
|
|
6011
|
+
const [showingPreloadedWebView, setShowingPreloadedWebView] = (0, import_react11.useState)(false);
|
|
6012
|
+
const resolverRef = (0, import_react11.useRef)(null);
|
|
6013
|
+
const presentedAtRef = (0, import_react11.useRef)(Date.now());
|
|
5725
6014
|
const sessionOpts = showingPreloadedWebView && preloadedWebView ? {
|
|
5726
6015
|
placement: preloadedWebView.placement,
|
|
5727
6016
|
paywallId: preloadedWebView.paywallId,
|
|
@@ -5731,7 +6020,7 @@ function usePaywallPresenter(preloadedWebView, setPreloadedWebView) {
|
|
|
5731
6020
|
...preloadedWebView.campaignId && { campaignId: preloadedWebView.campaignId }
|
|
5732
6021
|
} : null;
|
|
5733
6022
|
const { markClosed } = usePaywallSession(sessionOpts);
|
|
5734
|
-
(0,
|
|
6023
|
+
(0, import_react11.useEffect)(() => {
|
|
5735
6024
|
return () => {
|
|
5736
6025
|
if (resolverRef.current) {
|
|
5737
6026
|
resolverRef.current({ presented: false, purchased: false, cancelled: true, restored: false });
|
|
@@ -5740,7 +6029,7 @@ function usePaywallPresenter(preloadedWebView, setPreloadedWebView) {
|
|
|
5740
6029
|
setShowingPreloadedWebView(false);
|
|
5741
6030
|
};
|
|
5742
6031
|
}, []);
|
|
5743
|
-
const presentPreloadedWebView = (0,
|
|
6032
|
+
const presentPreloadedWebView = (0, import_react11.useCallback)(() => {
|
|
5744
6033
|
return new Promise((resolve) => {
|
|
5745
6034
|
resolverRef.current = resolve;
|
|
5746
6035
|
presentedAtRef.current = Date.now();
|
|
@@ -5774,16 +6063,16 @@ function usePaywallPresenter(preloadedWebView, setPreloadedWebView) {
|
|
|
5774
6063
|
}
|
|
5775
6064
|
});
|
|
5776
6065
|
}, [preloadedWebView]);
|
|
5777
|
-
const resolvePreloadedPaywall = (0,
|
|
6066
|
+
const resolvePreloadedPaywall = (0, import_react11.useCallback)((result) => {
|
|
5778
6067
|
if (resolverRef.current) {
|
|
5779
6068
|
resolverRef.current(result);
|
|
5780
6069
|
resolverRef.current = null;
|
|
5781
6070
|
}
|
|
5782
6071
|
}, []);
|
|
5783
|
-
const handlePreloadedWebViewReady = (0,
|
|
6072
|
+
const handlePreloadedWebViewReady = (0, import_react11.useCallback)(() => {
|
|
5784
6073
|
setPreloadedWebView((prev) => prev ? { ...prev, loaded: true } : null);
|
|
5785
6074
|
}, [setPreloadedWebView]);
|
|
5786
|
-
const handlePreloadedClose = (0,
|
|
6075
|
+
const handlePreloadedClose = (0, import_react11.useCallback)(() => {
|
|
5787
6076
|
if (preloadedWebView) {
|
|
5788
6077
|
markClosed();
|
|
5789
6078
|
void emitPaywallClosed({
|
|
@@ -5801,11 +6090,11 @@ function usePaywallPresenter(preloadedWebView, setPreloadedWebView) {
|
|
|
5801
6090
|
}, [preloadedWebView, markClosed, resolvePreloadedPaywall]);
|
|
5802
6091
|
return { showingPreloadedWebView, presentPreloadedWebView, resolvePreloadedPaywall, handlePreloadedWebViewReady, handlePreloadedClose, setShowingPreloadedWebView, presentedAtRef };
|
|
5803
6092
|
}
|
|
5804
|
-
var
|
|
6093
|
+
var import_react11;
|
|
5805
6094
|
var init_usePaywallPresenter = __esm({
|
|
5806
6095
|
"src/domains/paywall/usePaywallPresenter.ts"() {
|
|
5807
6096
|
"use strict";
|
|
5808
|
-
|
|
6097
|
+
import_react11 = require("react");
|
|
5809
6098
|
init_PaywalloClient();
|
|
5810
6099
|
init_emitPaywallClosed();
|
|
5811
6100
|
init_usePaywallSession();
|
|
@@ -5820,7 +6109,9 @@ var init_paywall = __esm({
|
|
|
5820
6109
|
init_PaywallError();
|
|
5821
6110
|
init_PaywallErrorBoundary();
|
|
5822
6111
|
init_PaywallModal();
|
|
6112
|
+
init_PaywallPreloadService();
|
|
5823
6113
|
init_PaywallWebView();
|
|
6114
|
+
init_PaywallWebViewPrewarmer();
|
|
5824
6115
|
init_usePaywallPresenter();
|
|
5825
6116
|
init_usePaywallTracking();
|
|
5826
6117
|
}
|
|
@@ -7146,7 +7437,7 @@ function buildV2Envelope(events, providerContext) {
|
|
|
7146
7437
|
};
|
|
7147
7438
|
});
|
|
7148
7439
|
if (context.sdk_version === void 0) context.sdk_version = SDK_VERSION;
|
|
7149
|
-
if (context.platform === void 0) context.platform =
|
|
7440
|
+
if (context.platform === void 0) context.platform = import_react_native23.Platform.OS;
|
|
7150
7441
|
if (context.distinct_id === void 0 && events.length > 0) {
|
|
7151
7442
|
context.distinct_id = events[0].distinctId;
|
|
7152
7443
|
}
|
|
@@ -7186,11 +7477,11 @@ function splitPayloadAndContext(properties) {
|
|
|
7186
7477
|
}
|
|
7187
7478
|
return { payload, promoted };
|
|
7188
7479
|
}
|
|
7189
|
-
var
|
|
7480
|
+
var import_react_native23, import_zod2, v2EventSchema, v2ContextSchema, v2EnvelopeSchema, CONTEXT_KEY_ALIASES;
|
|
7190
7481
|
var init_eventEnvelopeV2 = __esm({
|
|
7191
7482
|
"src/core/eventEnvelopeV2.ts"() {
|
|
7192
7483
|
"use strict";
|
|
7193
|
-
|
|
7484
|
+
import_react_native23 = require("react-native");
|
|
7194
7485
|
import_zod2 = require("zod");
|
|
7195
7486
|
init_uuid();
|
|
7196
7487
|
init_eventFamilies();
|
|
@@ -7260,11 +7551,11 @@ var init_events = __esm({
|
|
|
7260
7551
|
});
|
|
7261
7552
|
|
|
7262
7553
|
// src/core/EventBatcher.ts
|
|
7263
|
-
var
|
|
7554
|
+
var import_react_native24, BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT, EventBatcher;
|
|
7264
7555
|
var init_EventBatcher = __esm({
|
|
7265
7556
|
"src/core/EventBatcher.ts"() {
|
|
7266
7557
|
"use strict";
|
|
7267
|
-
|
|
7558
|
+
import_react_native24 = require("react-native");
|
|
7268
7559
|
init_eventEnvelopeV2();
|
|
7269
7560
|
init_events();
|
|
7270
7561
|
BATCH_MAX_SIZE = 25;
|
|
@@ -7313,7 +7604,7 @@ var init_EventBatcher = __esm({
|
|
|
7313
7604
|
const event = {
|
|
7314
7605
|
eventName,
|
|
7315
7606
|
distinctId,
|
|
7316
|
-
properties: { ...properties, platform:
|
|
7607
|
+
properties: { ...properties, platform: import_react_native24.Platform.OS },
|
|
7317
7608
|
timestamp: timestamp ?? Date.now(),
|
|
7318
7609
|
environment: environment.toLowerCase()
|
|
7319
7610
|
};
|
|
@@ -7639,11 +7930,11 @@ var init_http = __esm({
|
|
|
7639
7930
|
});
|
|
7640
7931
|
|
|
7641
7932
|
// src/core/ApiClient.ts
|
|
7642
|
-
var
|
|
7933
|
+
var import_react_native25, ApiClient;
|
|
7643
7934
|
var init_ApiClient = __esm({
|
|
7644
7935
|
"src/core/ApiClient.ts"() {
|
|
7645
7936
|
"use strict";
|
|
7646
|
-
|
|
7937
|
+
import_react_native25 = require("react-native");
|
|
7647
7938
|
init_apiPurchaseMethods();
|
|
7648
7939
|
init_ApiCache();
|
|
7649
7940
|
init_ApiClientFlags();
|
|
@@ -7745,7 +8036,7 @@ var init_ApiClient = __esm({
|
|
|
7745
8036
|
buildSdkHeaders() {
|
|
7746
8037
|
return {
|
|
7747
8038
|
"x-sdk-version": SDK_VERSION,
|
|
7748
|
-
"x-sdk-platform":
|
|
8039
|
+
"x-sdk-platform": import_react_native25.Platform.OS,
|
|
7749
8040
|
"x-sdk-environment": this.environment
|
|
7750
8041
|
};
|
|
7751
8042
|
}
|
|
@@ -7775,7 +8066,7 @@ var init_ApiClient = __esm({
|
|
|
7775
8066
|
message,
|
|
7776
8067
|
context,
|
|
7777
8068
|
sdkVersion: SDK_VERSION,
|
|
7778
|
-
platform:
|
|
8069
|
+
platform: import_react_native25.Platform.OS
|
|
7779
8070
|
}, true);
|
|
7780
8071
|
} catch (err) {
|
|
7781
8072
|
if (this.debug) console.log("[Paywallo:ApiClient] reportError failed", err);
|
|
@@ -7793,7 +8084,7 @@ var init_ApiClient = __esm({
|
|
|
7793
8084
|
async identify(distinctId, properties, email, deviceId, pii) {
|
|
7794
8085
|
const rawTraits = {
|
|
7795
8086
|
email: email || void 0,
|
|
7796
|
-
platform:
|
|
8087
|
+
platform: import_react_native25.Platform.OS,
|
|
7797
8088
|
name: properties?.name,
|
|
7798
8089
|
country: properties?.country,
|
|
7799
8090
|
locale: properties?.locale,
|
|
@@ -8089,12 +8380,12 @@ async function detectEnvironment() {
|
|
|
8089
8380
|
return cached;
|
|
8090
8381
|
}
|
|
8091
8382
|
}
|
|
8092
|
-
var
|
|
8383
|
+
var import_react_native26, nativeModule, cached;
|
|
8093
8384
|
var init_detectEnvironment = __esm({
|
|
8094
8385
|
"src/utils/detectEnvironment.ts"() {
|
|
8095
8386
|
"use strict";
|
|
8096
|
-
|
|
8097
|
-
nativeModule =
|
|
8387
|
+
import_react_native26 = require("react-native");
|
|
8388
|
+
nativeModule = import_react_native26.NativeModules.PaywalloEnv ?? null;
|
|
8098
8389
|
cached = null;
|
|
8099
8390
|
}
|
|
8100
8391
|
});
|
|
@@ -8276,10 +8567,10 @@ async function doInit(state, config) {
|
|
|
8276
8567
|
let screenHeight;
|
|
8277
8568
|
let screenDensity;
|
|
8278
8569
|
try {
|
|
8279
|
-
const screen =
|
|
8570
|
+
const screen = import_react_native27.Dimensions.get("screen");
|
|
8280
8571
|
screenWidth = Math.round(screen.width) || void 0;
|
|
8281
8572
|
screenHeight = Math.round(screen.height) || void 0;
|
|
8282
|
-
screenDensity =
|
|
8573
|
+
screenDensity = import_react_native27.PixelRatio.get() || void 0;
|
|
8283
8574
|
} catch {
|
|
8284
8575
|
}
|
|
8285
8576
|
return {
|
|
@@ -8346,11 +8637,11 @@ async function doInit(state, config) {
|
|
|
8346
8637
|
setupAutoPreload(state, apiClient, config, distinctId);
|
|
8347
8638
|
startBatchPreload(apiClient, config.debug);
|
|
8348
8639
|
}
|
|
8349
|
-
var
|
|
8640
|
+
var import_react_native27;
|
|
8350
8641
|
var init_PaywalloInitializer = __esm({
|
|
8351
8642
|
"src/core/PaywalloInitializer.ts"() {
|
|
8352
8643
|
"use strict";
|
|
8353
|
-
|
|
8644
|
+
import_react_native27 = require("react-native");
|
|
8354
8645
|
init_identity();
|
|
8355
8646
|
init_AdvertisingIdManager();
|
|
8356
8647
|
init_DeepLinkAttributionCapture();
|
|
@@ -8393,6 +8684,7 @@ async function doFullReset(state) {
|
|
|
8393
8684
|
offlineQueue.dispose();
|
|
8394
8685
|
networkMonitor.dispose();
|
|
8395
8686
|
campaignGateService.clearPreloaded();
|
|
8687
|
+
paywallPreloadService.clear();
|
|
8396
8688
|
await notificationsManager.invalidateLocalToken().catch(() => void 0);
|
|
8397
8689
|
notificationsManager.destroy();
|
|
8398
8690
|
deepLinkAttributionCapture.stop();
|
|
@@ -8427,6 +8719,7 @@ var init_PaywalloLifecycle = __esm({
|
|
|
8427
8719
|
init_identity();
|
|
8428
8720
|
init_DeepLinkAttributionCapture();
|
|
8429
8721
|
init_notifications();
|
|
8722
|
+
init_paywall();
|
|
8430
8723
|
init_session();
|
|
8431
8724
|
init_SubscriptionCache();
|
|
8432
8725
|
init_network();
|
|
@@ -8730,6 +9023,15 @@ var init_PaywalloClient = __esm({
|
|
|
8730
9023
|
isPreloaded(placement) {
|
|
8731
9024
|
return campaignGateService.getPreloadedCampaign(placement) !== null;
|
|
8732
9025
|
}
|
|
9026
|
+
async preloadPaywall(placement) {
|
|
9027
|
+
return paywallPreloadService.preload(this.getApiClientOrThrow(), placement);
|
|
9028
|
+
}
|
|
9029
|
+
async preloadPaywalls(placements) {
|
|
9030
|
+
return paywallPreloadService.preloadMany(this.getApiClientOrThrow(), placements);
|
|
9031
|
+
}
|
|
9032
|
+
isPaywallPreloaded(placement) {
|
|
9033
|
+
return paywallPreloadService.isPreloaded(placement);
|
|
9034
|
+
}
|
|
8733
9035
|
getAutoPreloadedPlacement() {
|
|
8734
9036
|
return this.state.autoPreloadedPlacement;
|
|
8735
9037
|
}
|
|
@@ -8775,7 +9077,7 @@ __export(OfferingService_exports, {
|
|
|
8775
9077
|
offeringService: () => offeringService
|
|
8776
9078
|
});
|
|
8777
9079
|
function resolveProductId(raw) {
|
|
8778
|
-
const isIos =
|
|
9080
|
+
const isIos = import_react_native28.Platform.OS === "ios";
|
|
8779
9081
|
const productId = isIos ? raw.apple_product_id : raw.google_product_id;
|
|
8780
9082
|
return productId ?? "";
|
|
8781
9083
|
}
|
|
@@ -8794,7 +9096,7 @@ function mapProduct2(raw) {
|
|
|
8794
9096
|
};
|
|
8795
9097
|
}
|
|
8796
9098
|
function pickPlatformProduct(products) {
|
|
8797
|
-
const isIos =
|
|
9099
|
+
const isIos = import_react_native28.Platform.OS === "ios";
|
|
8798
9100
|
const match = products.find((p) => isIos ? p.apple_product_id : p.google_product_id);
|
|
8799
9101
|
return match ?? products[0] ?? null;
|
|
8800
9102
|
}
|
|
@@ -8810,11 +9112,11 @@ function mapOffering(raw) {
|
|
|
8810
9112
|
product: mapProduct2(rawProduct)
|
|
8811
9113
|
};
|
|
8812
9114
|
}
|
|
8813
|
-
var
|
|
9115
|
+
var import_react_native28, OFFERINGS_CACHE_KEY, DEFAULT_TTL3, OfferingService, offeringService;
|
|
8814
9116
|
var init_OfferingService = __esm({
|
|
8815
9117
|
"src/domains/offering/OfferingService.ts"() {
|
|
8816
9118
|
"use strict";
|
|
8817
|
-
|
|
9119
|
+
import_react_native28 = require("react-native");
|
|
8818
9120
|
init_SecureStorage();
|
|
8819
9121
|
OFFERINGS_CACHE_KEY = "@paywallo:offerings_cache";
|
|
8820
9122
|
DEFAULT_TTL3 = 5 * 60 * 1e3;
|
|
@@ -8975,8 +9277,8 @@ module.exports = __toCommonJS(index_exports);
|
|
|
8975
9277
|
init_PaywalloClient();
|
|
8976
9278
|
|
|
8977
9279
|
// src/context/PaywalloContext.ts
|
|
8978
|
-
var
|
|
8979
|
-
var PaywalloContext = (0,
|
|
9280
|
+
var import_react12 = require("react");
|
|
9281
|
+
var PaywalloContext = (0, import_react12.createContext)(null);
|
|
8980
9282
|
|
|
8981
9283
|
// src/index.ts
|
|
8982
9284
|
init_ApiClient();
|
|
@@ -9021,7 +9323,7 @@ init_session();
|
|
|
9021
9323
|
init_PaywalloError();
|
|
9022
9324
|
|
|
9023
9325
|
// src/hooks/useOfferingPurchase.ts
|
|
9024
|
-
var
|
|
9326
|
+
var import_react13 = require("react");
|
|
9025
9327
|
|
|
9026
9328
|
// src/domains/plan/invalidateCache.ts
|
|
9027
9329
|
async function invalidatePlanCache() {
|
|
@@ -9034,8 +9336,8 @@ async function invalidatePlanCache() {
|
|
|
9034
9336
|
|
|
9035
9337
|
// src/hooks/useOfferingPurchase.ts
|
|
9036
9338
|
function useOfferingPurchase() {
|
|
9037
|
-
const [state, setState] = (0,
|
|
9038
|
-
const purchase = (0,
|
|
9339
|
+
const [state, setState] = (0, import_react13.useState)("idle");
|
|
9340
|
+
const purchase = (0, import_react13.useCallback)(async (productId) => {
|
|
9039
9341
|
setState("purchasing");
|
|
9040
9342
|
try {
|
|
9041
9343
|
const iapService = getIAPService();
|
|
@@ -9059,7 +9361,7 @@ function useOfferingPurchase() {
|
|
|
9059
9361
|
}
|
|
9060
9362
|
|
|
9061
9363
|
// src/hooks/useOfferings.ts
|
|
9062
|
-
var
|
|
9364
|
+
var import_react14 = require("react");
|
|
9063
9365
|
async function getOfferingService() {
|
|
9064
9366
|
try {
|
|
9065
9367
|
const mod = await Promise.resolve().then(() => (init_OfferingService(), OfferingService_exports));
|
|
@@ -9069,10 +9371,10 @@ async function getOfferingService() {
|
|
|
9069
9371
|
}
|
|
9070
9372
|
}
|
|
9071
9373
|
function useOfferings(ids) {
|
|
9072
|
-
const [offerings, setOfferings] = (0,
|
|
9073
|
-
const [isLoading, setIsLoading] = (0,
|
|
9374
|
+
const [offerings, setOfferings] = (0, import_react14.useState)([]);
|
|
9375
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
9074
9376
|
const idsKey = ids?.join(",") ?? "";
|
|
9075
|
-
const fetchOfferings = (0,
|
|
9377
|
+
const fetchOfferings = (0, import_react14.useCallback)(async () => {
|
|
9076
9378
|
setIsLoading(true);
|
|
9077
9379
|
try {
|
|
9078
9380
|
const service = await getOfferingService();
|
|
@@ -9088,25 +9390,25 @@ function useOfferings(ids) {
|
|
|
9088
9390
|
setIsLoading(false);
|
|
9089
9391
|
}
|
|
9090
9392
|
}, [idsKey]);
|
|
9091
|
-
(0,
|
|
9393
|
+
(0, import_react14.useEffect)(() => {
|
|
9092
9394
|
void fetchOfferings();
|
|
9093
9395
|
}, [fetchOfferings]);
|
|
9094
9396
|
return { offerings, isLoading };
|
|
9095
9397
|
}
|
|
9096
9398
|
|
|
9097
9399
|
// src/hooks/useOnboarding.ts
|
|
9098
|
-
var
|
|
9400
|
+
var import_react15 = require("react");
|
|
9099
9401
|
init_onboarding();
|
|
9100
9402
|
function useOnboarding() {
|
|
9101
|
-
const step = (0,
|
|
9403
|
+
const step = (0, import_react15.useCallback)(
|
|
9102
9404
|
(stepName) => onboardingManager.step(stepName),
|
|
9103
9405
|
[]
|
|
9104
9406
|
);
|
|
9105
|
-
const complete = (0,
|
|
9407
|
+
const complete = (0, import_react15.useCallback)(
|
|
9106
9408
|
() => onboardingManager.complete(),
|
|
9107
9409
|
[]
|
|
9108
9410
|
);
|
|
9109
|
-
const drop = (0,
|
|
9411
|
+
const drop = (0, import_react15.useCallback)(
|
|
9110
9412
|
(stepName) => onboardingManager.drop(stepName),
|
|
9111
9413
|
[]
|
|
9112
9414
|
);
|
|
@@ -9114,10 +9416,10 @@ function useOnboarding() {
|
|
|
9114
9416
|
}
|
|
9115
9417
|
|
|
9116
9418
|
// src/hooks/usePaywallo.ts
|
|
9117
|
-
var
|
|
9419
|
+
var import_react16 = require("react");
|
|
9118
9420
|
init_ClientError();
|
|
9119
9421
|
function usePaywallo() {
|
|
9120
|
-
const context = (0,
|
|
9422
|
+
const context = (0, import_react16.useContext)(PaywalloContext);
|
|
9121
9423
|
if (!context) {
|
|
9122
9424
|
throw new ClientError(CLIENT_ERROR_CODES.PROVIDER_MISSING, "usePaywallo must be used within a PaywalloProvider");
|
|
9123
9425
|
}
|
|
@@ -9125,11 +9427,11 @@ function usePaywallo() {
|
|
|
9125
9427
|
}
|
|
9126
9428
|
|
|
9127
9429
|
// src/hooks/usePlanPurchase.ts
|
|
9128
|
-
var
|
|
9430
|
+
var import_react17 = require("react");
|
|
9129
9431
|
function usePlanPurchase() {
|
|
9130
|
-
const [state, setState] = (0,
|
|
9131
|
-
const [error, setError] = (0,
|
|
9132
|
-
const purchase = (0,
|
|
9432
|
+
const [state, setState] = (0, import_react17.useState)("idle");
|
|
9433
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
9434
|
+
const purchase = (0, import_react17.useCallback)(async (productId) => {
|
|
9133
9435
|
setState("purchasing");
|
|
9134
9436
|
setError(null);
|
|
9135
9437
|
try {
|
|
@@ -9152,7 +9454,7 @@ function usePlanPurchase() {
|
|
|
9152
9454
|
return { success: false, error: purchaseError };
|
|
9153
9455
|
}
|
|
9154
9456
|
}, []);
|
|
9155
|
-
const restore = (0,
|
|
9457
|
+
const restore = (0, import_react17.useCallback)(async () => {
|
|
9156
9458
|
setState("restoring");
|
|
9157
9459
|
setError(null);
|
|
9158
9460
|
try {
|
|
@@ -9181,7 +9483,7 @@ function usePlanPurchase() {
|
|
|
9181
9483
|
}
|
|
9182
9484
|
|
|
9183
9485
|
// src/hooks/usePlans.ts
|
|
9184
|
-
var
|
|
9486
|
+
var import_react18 = require("react");
|
|
9185
9487
|
async function getPlanService() {
|
|
9186
9488
|
try {
|
|
9187
9489
|
const mod = await Promise.resolve().then(() => (init_PlanService(), PlanService_exports));
|
|
@@ -9191,11 +9493,11 @@ async function getPlanService() {
|
|
|
9191
9493
|
}
|
|
9192
9494
|
}
|
|
9193
9495
|
function usePlans() {
|
|
9194
|
-
const [allPlans, setAllPlans] = (0,
|
|
9195
|
-
const [currentPlan, setCurrentPlan] = (0,
|
|
9196
|
-
const [isLoading, setIsLoading] = (0,
|
|
9197
|
-
const [error, setError] = (0,
|
|
9198
|
-
const fetchPlans = (0,
|
|
9496
|
+
const [allPlans, setAllPlans] = (0, import_react18.useState)([]);
|
|
9497
|
+
const [currentPlan, setCurrentPlan] = (0, import_react18.useState)(null);
|
|
9498
|
+
const [isLoading, setIsLoading] = (0, import_react18.useState)(true);
|
|
9499
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
9500
|
+
const fetchPlans = (0, import_react18.useCallback)(async (forceRefresh = false) => {
|
|
9199
9501
|
setIsLoading(true);
|
|
9200
9502
|
setError(null);
|
|
9201
9503
|
try {
|
|
@@ -9216,17 +9518,17 @@ function usePlans() {
|
|
|
9216
9518
|
setIsLoading(false);
|
|
9217
9519
|
}
|
|
9218
9520
|
}, []);
|
|
9219
|
-
const refresh = (0,
|
|
9521
|
+
const refresh = (0, import_react18.useCallback)(() => {
|
|
9220
9522
|
return fetchPlans(true);
|
|
9221
9523
|
}, [fetchPlans]);
|
|
9222
|
-
(0,
|
|
9524
|
+
(0, import_react18.useEffect)(() => {
|
|
9223
9525
|
void fetchPlans(false);
|
|
9224
9526
|
}, [fetchPlans]);
|
|
9225
9527
|
return { currentPlan, allPlans, isLoading, error, refresh };
|
|
9226
9528
|
}
|
|
9227
9529
|
|
|
9228
9530
|
// src/hooks/useProducts.ts
|
|
9229
|
-
var
|
|
9531
|
+
var import_react19 = require("react");
|
|
9230
9532
|
|
|
9231
9533
|
// src/utils/productMappers.ts
|
|
9232
9534
|
function mapToIAPProduct(product) {
|
|
@@ -9265,11 +9567,11 @@ function mapToFormattedProduct(product) {
|
|
|
9265
9567
|
|
|
9266
9568
|
// src/hooks/useProducts.ts
|
|
9267
9569
|
function useProducts(initialProductIds) {
|
|
9268
|
-
const [products, setProducts] = (0,
|
|
9269
|
-
const [formattedProducts, setFormattedProducts] = (0,
|
|
9270
|
-
const [isLoading, setIsLoading] = (0,
|
|
9271
|
-
const [error, setError] = (0,
|
|
9272
|
-
const loadProducts = (0,
|
|
9570
|
+
const [products, setProducts] = (0, import_react19.useState)([]);
|
|
9571
|
+
const [formattedProducts, setFormattedProducts] = (0, import_react19.useState)([]);
|
|
9572
|
+
const [isLoading, setIsLoading] = (0, import_react19.useState)(false);
|
|
9573
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
9574
|
+
const loadProducts = (0, import_react19.useCallback)(async (productIds) => {
|
|
9273
9575
|
setIsLoading(true);
|
|
9274
9576
|
setError(null);
|
|
9275
9577
|
try {
|
|
@@ -9283,24 +9585,24 @@ function useProducts(initialProductIds) {
|
|
|
9283
9585
|
setIsLoading(false);
|
|
9284
9586
|
}
|
|
9285
9587
|
}, []);
|
|
9286
|
-
(0,
|
|
9588
|
+
(0, import_react19.useEffect)(() => {
|
|
9287
9589
|
if (initialProductIds && initialProductIds.length > 0) {
|
|
9288
9590
|
void loadProducts(initialProductIds);
|
|
9289
9591
|
}
|
|
9290
9592
|
}, []);
|
|
9291
|
-
const getProduct = (0,
|
|
9593
|
+
const getProduct = (0, import_react19.useCallback)(
|
|
9292
9594
|
(productId) => {
|
|
9293
9595
|
return products.find((p) => p.productId === productId);
|
|
9294
9596
|
},
|
|
9295
9597
|
[products]
|
|
9296
9598
|
);
|
|
9297
|
-
const getFormattedProduct = (0,
|
|
9599
|
+
const getFormattedProduct = (0, import_react19.useCallback)(
|
|
9298
9600
|
(productId) => {
|
|
9299
9601
|
return formattedProducts.find((p) => p.productId === productId);
|
|
9300
9602
|
},
|
|
9301
9603
|
[formattedProducts]
|
|
9302
9604
|
);
|
|
9303
|
-
const getPriceInfo = (0,
|
|
9605
|
+
const getPriceInfo = (0, import_react19.useCallback)(
|
|
9304
9606
|
(productId) => {
|
|
9305
9607
|
const p = formattedProducts.find((fp) => fp.productId === productId);
|
|
9306
9608
|
if (!p) return void 0;
|
|
@@ -9329,14 +9631,14 @@ function useProducts(initialProductIds) {
|
|
|
9329
9631
|
}
|
|
9330
9632
|
|
|
9331
9633
|
// src/hooks/usePurchase.ts
|
|
9332
|
-
var
|
|
9634
|
+
var import_react20 = require("react");
|
|
9333
9635
|
function toIAPPurchase(p) {
|
|
9334
9636
|
return { productId: p.productId, transactionId: p.transactionId, transactionDate: p.transactionDate, transactionReceipt: p.receipt };
|
|
9335
9637
|
}
|
|
9336
9638
|
function usePurchase() {
|
|
9337
|
-
const [state, setState] = (0,
|
|
9338
|
-
const [error, setError] = (0,
|
|
9339
|
-
const purchase = (0,
|
|
9639
|
+
const [state, setState] = (0, import_react20.useState)("idle");
|
|
9640
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
9641
|
+
const purchase = (0, import_react20.useCallback)(async (productId) => {
|
|
9340
9642
|
setState("purchasing");
|
|
9341
9643
|
setError(null);
|
|
9342
9644
|
try {
|
|
@@ -9364,7 +9666,7 @@ function usePurchase() {
|
|
|
9364
9666
|
return { status: "failed", error: purchaseError };
|
|
9365
9667
|
}
|
|
9366
9668
|
}, []);
|
|
9367
|
-
const restore = (0,
|
|
9669
|
+
const restore = (0, import_react20.useCallback)(async () => {
|
|
9368
9670
|
setState("restoring");
|
|
9369
9671
|
setError(null);
|
|
9370
9672
|
try {
|
|
@@ -9383,14 +9685,14 @@ function usePurchase() {
|
|
|
9383
9685
|
}
|
|
9384
9686
|
|
|
9385
9687
|
// src/hooks/useSubscription.ts
|
|
9386
|
-
var
|
|
9688
|
+
var import_react21 = require("react");
|
|
9387
9689
|
init_SubscriptionManager();
|
|
9388
9690
|
var EMPTY_ENTITLEMENTS = [];
|
|
9389
9691
|
function useSubscription() {
|
|
9390
|
-
const [status, setStatus] = (0,
|
|
9391
|
-
const [isLoading, setIsLoading] = (0,
|
|
9392
|
-
const [error, setError] = (0,
|
|
9393
|
-
const refresh = (0,
|
|
9692
|
+
const [status, setStatus] = (0, import_react21.useState)(null);
|
|
9693
|
+
const [isLoading, setIsLoading] = (0, import_react21.useState)(true);
|
|
9694
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
9695
|
+
const refresh = (0, import_react21.useCallback)(async () => {
|
|
9394
9696
|
setIsLoading(true);
|
|
9395
9697
|
setError(null);
|
|
9396
9698
|
try {
|
|
@@ -9403,7 +9705,7 @@ function useSubscription() {
|
|
|
9403
9705
|
setIsLoading(false);
|
|
9404
9706
|
}
|
|
9405
9707
|
}, []);
|
|
9406
|
-
const restore = (0,
|
|
9708
|
+
const restore = (0, import_react21.useCallback)(async () => {
|
|
9407
9709
|
setIsLoading(true);
|
|
9408
9710
|
setError(null);
|
|
9409
9711
|
try {
|
|
@@ -9416,7 +9718,7 @@ function useSubscription() {
|
|
|
9416
9718
|
setIsLoading(false);
|
|
9417
9719
|
}
|
|
9418
9720
|
}, []);
|
|
9419
|
-
(0,
|
|
9721
|
+
(0, import_react21.useEffect)(() => {
|
|
9420
9722
|
void subscriptionManager.getSubscriptionStatus().then((s) => {
|
|
9421
9723
|
setStatus(s);
|
|
9422
9724
|
setIsLoading(false);
|
|
@@ -9444,63 +9746,257 @@ function useSubscription() {
|
|
|
9444
9746
|
}
|
|
9445
9747
|
|
|
9446
9748
|
// src/PaywalloProvider.tsx
|
|
9447
|
-
var
|
|
9448
|
-
var
|
|
9749
|
+
var import_react27 = require("react");
|
|
9750
|
+
var import_react_native29 = require("react-native");
|
|
9449
9751
|
init_PaywalloClient();
|
|
9450
|
-
init_SecureStorage();
|
|
9451
9752
|
init_NativeStorage();
|
|
9753
|
+
init_SecureStorage();
|
|
9452
9754
|
init_campaign();
|
|
9453
9755
|
init_paywall();
|
|
9454
9756
|
init_paywall();
|
|
9455
9757
|
init_paywall();
|
|
9456
9758
|
init_paywall();
|
|
9457
|
-
|
|
9458
|
-
|
|
9759
|
+
init_paywall();
|
|
9760
|
+
init_paywall();
|
|
9459
9761
|
|
|
9460
|
-
// src/
|
|
9461
|
-
|
|
9762
|
+
// src/domains/paywall/SuperwallAutoBridge.ts
|
|
9763
|
+
init_PaywalloClient();
|
|
9462
9764
|
|
|
9463
|
-
// src/utils/
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9765
|
+
// src/core/utils/eventId.ts
|
|
9766
|
+
function hashString(input) {
|
|
9767
|
+
let h1 = 3735928559;
|
|
9768
|
+
let h2 = 1103547991;
|
|
9769
|
+
for (let i = 0; i < input.length; i++) {
|
|
9770
|
+
const ch = input.charCodeAt(i);
|
|
9771
|
+
h1 = Math.imul(h1 ^ ch, 2654435769);
|
|
9772
|
+
h2 = Math.imul(h2 ^ ch, 1598716949);
|
|
9470
9773
|
}
|
|
9774
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 73244475);
|
|
9775
|
+
h1 ^= Math.imul(h2 ^ h2 >>> 13, 351452291);
|
|
9776
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 73244475);
|
|
9777
|
+
h2 ^= Math.imul(h1 ^ h1 >>> 13, 351452291);
|
|
9778
|
+
const toHex = (n) => (n >>> 0).toString(16).padStart(8, "0");
|
|
9779
|
+
return toHex(h1) + toHex(h2);
|
|
9471
9780
|
}
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
}
|
|
9781
|
+
function buildDeterministicEventId(parts) {
|
|
9782
|
+
const raw = hashString(parts.join("|"));
|
|
9783
|
+
const p1 = raw.slice(0, 8);
|
|
9784
|
+
const p2 = raw.slice(8, 12);
|
|
9785
|
+
const p3 = "4" + raw.slice(13, 16);
|
|
9786
|
+
const p4 = (parseInt(raw[16], 16) & 3 | 8).toString(16) + raw.slice(17, 20);
|
|
9787
|
+
const p5 = raw.padEnd(32, "0").slice(20, 32);
|
|
9788
|
+
return `${p1}-${p2}-${p3}-${p4}-${p5}`;
|
|
9480
9789
|
}
|
|
9481
9790
|
|
|
9482
|
-
// src/
|
|
9483
|
-
var
|
|
9484
|
-
var
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
|
|
9488
|
-
(0
|
|
9489
|
-
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9791
|
+
// src/domains/paywall/SuperwallAutoBridge.ts
|
|
9792
|
+
var bridgeStarted = false;
|
|
9793
|
+
var unsubscribe = null;
|
|
9794
|
+
var debugEnabled = false;
|
|
9795
|
+
function log(msg, data) {
|
|
9796
|
+
if (!debugEnabled) return;
|
|
9797
|
+
if (data !== void 0) {
|
|
9798
|
+
console.log(`[Paywallo:SuperwallBridge] ${msg}`, data);
|
|
9799
|
+
} else {
|
|
9800
|
+
console.log(`[Paywallo:SuperwallBridge] ${msg}`);
|
|
9801
|
+
}
|
|
9802
|
+
}
|
|
9803
|
+
function minuteBucket(ts) {
|
|
9804
|
+
return String(Math.floor(ts / 6e4));
|
|
9805
|
+
}
|
|
9806
|
+
function buildEventId(type, identifier, ts) {
|
|
9807
|
+
return buildDeterministicEventId(["sw", type, identifier, minuteBucket(ts)]);
|
|
9808
|
+
}
|
|
9809
|
+
async function trackPaywallEvent(type, identifier, ts, extra) {
|
|
9810
|
+
const _eventId = buildEventId(type, identifier, ts);
|
|
9811
|
+
try {
|
|
9812
|
+
const cleanExtra = {};
|
|
9813
|
+
if (extra) {
|
|
9814
|
+
for (const [k, v] of Object.entries(extra)) if (v !== void 0) cleanExtra[k] = v;
|
|
9815
|
+
}
|
|
9816
|
+
await PaywalloClient.track("paywall", {
|
|
9817
|
+
priority: "critical",
|
|
9818
|
+
properties: {
|
|
9819
|
+
type,
|
|
9820
|
+
paywall_id: identifier,
|
|
9821
|
+
...cleanExtra
|
|
9822
|
+
}
|
|
9823
|
+
});
|
|
9824
|
+
} catch (err) {
|
|
9825
|
+
log("track error", { type, identifier, eventId: _eventId, err: String(err) });
|
|
9826
|
+
}
|
|
9827
|
+
}
|
|
9828
|
+
function mapDismissToCloseReason(resultType) {
|
|
9829
|
+
switch (resultType) {
|
|
9830
|
+
case "purchased":
|
|
9831
|
+
return "purchased";
|
|
9832
|
+
case "restored":
|
|
9833
|
+
return "purchased";
|
|
9834
|
+
// restore counts as a purchase outcome for funnel
|
|
9835
|
+
case "declined":
|
|
9836
|
+
return "dismissed";
|
|
9837
|
+
default:
|
|
9838
|
+
return void 0;
|
|
9839
|
+
}
|
|
9840
|
+
}
|
|
9841
|
+
function buildCallbacks() {
|
|
9842
|
+
return {
|
|
9843
|
+
onPaywallPresent: (info) => {
|
|
9844
|
+
const ts = Date.now();
|
|
9845
|
+
log("onPaywallPresent", { identifier: info.identifier });
|
|
9846
|
+
void trackPaywallEvent("viewed", info.identifier, ts, {
|
|
9847
|
+
placement: info.presentedByEventWithName,
|
|
9848
|
+
variant_id: info.experiment?.variant?.id,
|
|
9849
|
+
campaign_id: info.experiment?.id
|
|
9850
|
+
});
|
|
9851
|
+
},
|
|
9852
|
+
onPaywallDismiss: (info, result) => {
|
|
9853
|
+
const ts = Date.now();
|
|
9854
|
+
log("onPaywallDismiss", { identifier: info.identifier, result: result.type });
|
|
9855
|
+
void trackPaywallEvent("closed", info.identifier, ts, {
|
|
9856
|
+
placement: info.presentedByEventWithName,
|
|
9857
|
+
variant_id: info.experiment?.variant?.id,
|
|
9858
|
+
campaign_id: info.experiment?.id,
|
|
9859
|
+
close_reason: mapDismissToCloseReason(result.type),
|
|
9860
|
+
closed_at: new Date(ts).toISOString()
|
|
9861
|
+
});
|
|
9862
|
+
},
|
|
9863
|
+
onPurchase: (params) => {
|
|
9864
|
+
const ts = Date.now();
|
|
9865
|
+
const safe = params !== null && typeof params === "object" ? params : {};
|
|
9866
|
+
const productId = "productId" in safe && typeof safe.productId === "string" ? safe.productId : "unknown";
|
|
9867
|
+
const identifier = "paywallIdentifier" in safe && typeof safe.paywallIdentifier === "string" ? safe.paywallIdentifier : productId;
|
|
9868
|
+
log("onPurchase", { productId, identifier });
|
|
9869
|
+
void trackPaywallEvent("purchased", identifier, ts, { product_id: productId });
|
|
9870
|
+
},
|
|
9871
|
+
// Global Superwall event listener — used specifically for `transactionComplete`
|
|
9872
|
+
// which is the only event that exposes the full product (currency/price) +
|
|
9873
|
+
// transaction (storeTransactionId) shape needed to create a server-side
|
|
9874
|
+
// `transactions` row. Other events are skipped (paywallOpen/Dismiss already
|
|
9875
|
+
// handled above with their typed callbacks).
|
|
9876
|
+
onSuperwallEvent: (info) => {
|
|
9877
|
+
const ev = info?.event;
|
|
9878
|
+
if (!ev || ev.event !== "transactionComplete") return;
|
|
9879
|
+
const ts = Date.now();
|
|
9880
|
+
const product = ev.product;
|
|
9881
|
+
const transaction = ev.transaction;
|
|
9882
|
+
if (!product) {
|
|
9883
|
+
log("transactionComplete missing product \u2014 skipping transaction track");
|
|
9884
|
+
return;
|
|
9885
|
+
}
|
|
9886
|
+
const productId = product.productIdentifier ?? product.id ?? "unknown";
|
|
9887
|
+
const currency = product.currencyCode ?? "USD";
|
|
9888
|
+
const price = product.price ?? 0;
|
|
9889
|
+
const transactionId = transaction?.storeTransactionId ?? transaction?.originalTransactionIdentifier ?? `${productId}_${String(ts)}`;
|
|
9890
|
+
const isTrial = product.hasFreeTrial === true || (product.trialPeriodPrice ?? 0) > 0;
|
|
9891
|
+
const paywallIdentifier = ev.paywallInfo?.identifier;
|
|
9892
|
+
log("onSuperwallEvent: transactionComplete", { productId, currency, price, transactionId, isTrial });
|
|
9893
|
+
void (async () => {
|
|
9894
|
+
try {
|
|
9895
|
+
await PaywalloClient.track("transaction", {
|
|
9896
|
+
priority: "critical",
|
|
9897
|
+
properties: {
|
|
9898
|
+
type: isTrial ? "trial_started" : "completed",
|
|
9899
|
+
// Server's IngestTranslator looks for `transaction_id`/`product_id`
|
|
9900
|
+
// /`amount`/`currency`/`paywall_id` keys (not `tx_id`). PurchaseHandler
|
|
9901
|
+
// then resolves type=trial/new/renewal based on amount being 0 vs >0.
|
|
9902
|
+
transaction_id: transactionId,
|
|
9903
|
+
product_id: productId,
|
|
9904
|
+
amount: price,
|
|
9905
|
+
currency,
|
|
9906
|
+
...paywallIdentifier ? { paywall_id: paywallIdentifier } : {}
|
|
9907
|
+
}
|
|
9908
|
+
});
|
|
9909
|
+
} catch (err) {
|
|
9910
|
+
log("transactionComplete track error", { err: String(err) });
|
|
9911
|
+
}
|
|
9912
|
+
})();
|
|
9913
|
+
}
|
|
9914
|
+
};
|
|
9915
|
+
}
|
|
9916
|
+
function startSuperwallAutoBridge(debug = false) {
|
|
9917
|
+
debugEnabled = debug;
|
|
9918
|
+
if (bridgeStarted) {
|
|
9919
|
+
log("already started, skipping");
|
|
9920
|
+
return;
|
|
9921
|
+
}
|
|
9922
|
+
void detectAndStart();
|
|
9923
|
+
}
|
|
9924
|
+
async function detectAndStart() {
|
|
9925
|
+
let subscribeFn;
|
|
9926
|
+
try {
|
|
9927
|
+
const mod = await import("expo-superwall");
|
|
9928
|
+
if (!mod || typeof mod.subscribeToSuperwallEvents !== "function") {
|
|
9929
|
+
const internal = await import("expo-superwall/build/src/internal/superwallEventBridge");
|
|
9930
|
+
if (typeof internal.subscribeToSuperwallEvents !== "function") {
|
|
9931
|
+
log("expo-superwall subscribeToSuperwallEvents not found \u2014 bridge inactive");
|
|
9932
|
+
return;
|
|
9933
|
+
}
|
|
9934
|
+
subscribeFn = internal.subscribeToSuperwallEvents;
|
|
9935
|
+
} else {
|
|
9936
|
+
subscribeFn = mod.subscribeToSuperwallEvents;
|
|
9937
|
+
}
|
|
9938
|
+
} catch {
|
|
9939
|
+
log("expo-superwall not installed \u2014 bridge inactive");
|
|
9940
|
+
return;
|
|
9941
|
+
}
|
|
9942
|
+
try {
|
|
9943
|
+
const callbacks = buildCallbacks();
|
|
9944
|
+
unsubscribe = subscribeFn(void 0, () => callbacks);
|
|
9945
|
+
bridgeStarted = true;
|
|
9946
|
+
log("bridge started");
|
|
9947
|
+
} catch (err) {
|
|
9948
|
+
log("subscribe failed", { err: String(err) });
|
|
9949
|
+
}
|
|
9950
|
+
}
|
|
9951
|
+
|
|
9952
|
+
// src/PaywalloProvider.tsx
|
|
9953
|
+
init_session();
|
|
9954
|
+
init_ClientError();
|
|
9955
|
+
|
|
9956
|
+
// src/hooks/useAppAutoEvents.ts
|
|
9957
|
+
var import_react22 = require("react");
|
|
9958
|
+
|
|
9959
|
+
// src/utils/platformDetection.ts
|
|
9960
|
+
async function detectPlatform3() {
|
|
9961
|
+
try {
|
|
9962
|
+
const rn = await import("react-native");
|
|
9963
|
+
return rn.Platform?.OS === "ios" ? "ios" : "android";
|
|
9964
|
+
} catch {
|
|
9965
|
+
return "android";
|
|
9966
|
+
}
|
|
9967
|
+
}
|
|
9968
|
+
async function detectOsVersion() {
|
|
9969
|
+
try {
|
|
9970
|
+
const rn = await import("react-native");
|
|
9971
|
+
const version = rn.Platform?.Version;
|
|
9972
|
+
return version != null ? String(version) : "unknown";
|
|
9973
|
+
} catch {
|
|
9974
|
+
return "unknown";
|
|
9975
|
+
}
|
|
9976
|
+
}
|
|
9977
|
+
|
|
9978
|
+
// src/hooks/useAppAutoEvents.ts
|
|
9979
|
+
var FIRST_SEEN_KEY = "@paywallo:firstSeen_v226";
|
|
9980
|
+
var DEBOUNCE_MS = 1e3;
|
|
9981
|
+
function useAppAutoEvents(config) {
|
|
9982
|
+
const { isInitialized, getAppVersion: getAppVersion2, getSessionId, emitLifecycle, storageGet, storageSet, debug } = config;
|
|
9983
|
+
const didRunRef = (0, import_react22.useRef)(false);
|
|
9984
|
+
(0, import_react22.useEffect)(() => {
|
|
9985
|
+
if (debug) console.log("[Paywallo EVENTS] useEffect fired", { isInitialized, didRunRefCurrent: didRunRef.current });
|
|
9986
|
+
if (!isInitialized || didRunRef.current) return;
|
|
9987
|
+
const timer = setTimeout(() => {
|
|
9988
|
+
if (didRunRef.current) return;
|
|
9989
|
+
didRunRef.current = true;
|
|
9990
|
+
void (async () => {
|
|
9991
|
+
const sessionId = getSessionId();
|
|
9992
|
+
const appVersion = getAppVersion2();
|
|
9993
|
+
const deviceType = await detectPlatform3();
|
|
9994
|
+
const osVersion = await detectOsVersion();
|
|
9995
|
+
if (debug) console.log("[Paywallo EVENTS] computed device context", { deviceType, osVersion, appVersion, sessionId, hasSessionId: !!sessionId });
|
|
9996
|
+
try {
|
|
9997
|
+
if (debug) console.log("[Paywallo EVENTS] checking install \u2014 about to read FIRST_SEEN_KEY");
|
|
9998
|
+
const firstSeen = await storageGet(FIRST_SEEN_KEY);
|
|
9999
|
+
if (!firstSeen) {
|
|
9504
10000
|
await emitLifecycle({ type: "install", device_type: deviceType, os_version: osVersion, app_version: appVersion, ...sessionId ? { session_id: sessionId } : {} }, "critical");
|
|
9505
10001
|
await storageSet(FIRST_SEEN_KEY, (/* @__PURE__ */ new Date()).toISOString());
|
|
9506
10002
|
if (debug) console.log("[Paywallo EVENTS] install event emitted (first time)");
|
|
@@ -9525,7 +10021,7 @@ function useAppAutoEvents(config) {
|
|
|
9525
10021
|
}
|
|
9526
10022
|
|
|
9527
10023
|
// src/hooks/useCampaignPreload.ts
|
|
9528
|
-
var
|
|
10024
|
+
var import_react23 = require("react");
|
|
9529
10025
|
init_PaywalloClient();
|
|
9530
10026
|
init_CampaignError();
|
|
9531
10027
|
|
|
@@ -9596,17 +10092,17 @@ function getCacheEntry(cache, placement) {
|
|
|
9596
10092
|
|
|
9597
10093
|
// src/hooks/useCampaignPreload.ts
|
|
9598
10094
|
function useCampaignPreload() {
|
|
9599
|
-
const [preloadedWebView, setPreloadedWebView] = (0,
|
|
9600
|
-
const preloadedCampaignsRef = (0,
|
|
9601
|
-
const isPreloadValid = (0,
|
|
10095
|
+
const [preloadedWebView, setPreloadedWebView] = (0, import_react23.useState)(null);
|
|
10096
|
+
const preloadedCampaignsRef = (0, import_react23.useRef)(/* @__PURE__ */ new Map());
|
|
10097
|
+
const isPreloadValid = (0, import_react23.useCallback)(
|
|
9602
10098
|
(placement) => isCacheEntryValid(preloadedCampaignsRef.current.get(placement)),
|
|
9603
10099
|
[]
|
|
9604
10100
|
);
|
|
9605
|
-
const consumePreloadedCampaign = (0,
|
|
10101
|
+
const consumePreloadedCampaign = (0, import_react23.useCallback)(
|
|
9606
10102
|
(placement) => getCacheEntry(preloadedCampaignsRef.current, placement),
|
|
9607
10103
|
[]
|
|
9608
10104
|
);
|
|
9609
|
-
const preloadCampaign = (0,
|
|
10105
|
+
const preloadCampaign = (0, import_react23.useCallback)(
|
|
9610
10106
|
async (placement, context) => {
|
|
9611
10107
|
try {
|
|
9612
10108
|
const campaign = await PaywalloClient.getCampaign(placement, context);
|
|
@@ -9675,11 +10171,11 @@ function useCampaignPreload() {
|
|
|
9675
10171
|
}
|
|
9676
10172
|
|
|
9677
10173
|
// src/hooks/useProductLoader.ts
|
|
9678
|
-
var
|
|
10174
|
+
var import_react24 = require("react");
|
|
9679
10175
|
function useProductLoader() {
|
|
9680
|
-
const [products, setProducts] = (0,
|
|
9681
|
-
const [isLoadingProducts, setIsLoadingProducts] = (0,
|
|
9682
|
-
const refreshProducts = (0,
|
|
10176
|
+
const [products, setProducts] = (0, import_react24.useState)(/* @__PURE__ */ new Map());
|
|
10177
|
+
const [isLoadingProducts, setIsLoadingProducts] = (0, import_react24.useState)(false);
|
|
10178
|
+
const refreshProducts = (0, import_react24.useCallback)(async (productIds) => {
|
|
9683
10179
|
setIsLoadingProducts(true);
|
|
9684
10180
|
try {
|
|
9685
10181
|
const iapService = getIAPService();
|
|
@@ -9697,11 +10193,11 @@ function useProductLoader() {
|
|
|
9697
10193
|
}
|
|
9698
10194
|
|
|
9699
10195
|
// src/hooks/usePurchaseOrchestrator.ts
|
|
9700
|
-
var
|
|
10196
|
+
var import_react25 = require("react");
|
|
9701
10197
|
init_paywall();
|
|
9702
10198
|
function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clearPreloadedWebView, setShowingPreloadedWebView, presentedAtRef, invalidateSubscriptionCache) {
|
|
9703
10199
|
const { trackDismissed, trackProductSelected, trackPurchased } = usePaywallTracking();
|
|
9704
|
-
const handlePreloadedPurchase = (0,
|
|
10200
|
+
const handlePreloadedPurchase = (0, import_react25.useCallback)(
|
|
9705
10201
|
async (productId) => {
|
|
9706
10202
|
try {
|
|
9707
10203
|
if (preloadedWebView) {
|
|
@@ -9739,7 +10235,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
9739
10235
|
},
|
|
9740
10236
|
[preloadedWebView, resolvePreloadedPaywall, clearPreloadedWebView, setShowingPreloadedWebView, presentedAtRef, trackDismissed, trackProductSelected, trackPurchased, invalidateSubscriptionCache]
|
|
9741
10237
|
);
|
|
9742
|
-
const handlePreloadedRestore = (0,
|
|
10238
|
+
const handlePreloadedRestore = (0, import_react25.useCallback)(async () => {
|
|
9743
10239
|
try {
|
|
9744
10240
|
const transactions = await getIAPService().restore();
|
|
9745
10241
|
if (transactions.length === 0) return;
|
|
@@ -9762,7 +10258,7 @@ function usePurchaseOrchestrator(preloadedWebView, resolvePreloadedPaywall, clea
|
|
|
9762
10258
|
}
|
|
9763
10259
|
|
|
9764
10260
|
// src/hooks/useSubscriptionSync.ts
|
|
9765
|
-
var
|
|
10261
|
+
var import_react26 = require("react");
|
|
9766
10262
|
init_PaywalloClient();
|
|
9767
10263
|
init_SubscriptionCache();
|
|
9768
10264
|
|
|
@@ -9872,18 +10368,18 @@ async function checkPersistedCache(distinctId, onHit) {
|
|
|
9872
10368
|
|
|
9873
10369
|
// src/hooks/useSubscriptionSync.ts
|
|
9874
10370
|
function useSubscriptionSync() {
|
|
9875
|
-
const [subscription, setSubscription] = (0,
|
|
9876
|
-
const cacheRef = (0,
|
|
9877
|
-
const setCacheAndState = (0,
|
|
10371
|
+
const [subscription, setSubscription] = (0, import_react26.useState)(null);
|
|
10372
|
+
const cacheRef = (0, import_react26.useRef)(null);
|
|
10373
|
+
const setCacheAndState = (0, import_react26.useCallback)((sub) => {
|
|
9878
10374
|
cacheRef.current = { data: sub, expiresAt: Date.now() + CACHE_TTL_MS2 };
|
|
9879
10375
|
setSubscription(sub);
|
|
9880
10376
|
}, []);
|
|
9881
|
-
const invalidateCache = (0,
|
|
10377
|
+
const invalidateCache = (0, import_react26.useCallback)(() => {
|
|
9882
10378
|
cacheRef.current = null;
|
|
9883
10379
|
const distinctId = PaywalloClient.getDistinctId();
|
|
9884
10380
|
if (distinctId) void subscriptionCache.invalidate(distinctId);
|
|
9885
10381
|
}, []);
|
|
9886
|
-
const fetchAndCache = (0,
|
|
10382
|
+
const fetchAndCache = (0, import_react26.useCallback)(async () => {
|
|
9887
10383
|
const apiClient = PaywalloClient.getApiClient();
|
|
9888
10384
|
const distinctId = PaywalloClient.getDistinctId();
|
|
9889
10385
|
if (!apiClient || !distinctId) return null;
|
|
@@ -9893,7 +10389,7 @@ function useSubscriptionSync() {
|
|
|
9893
10389
|
void subscriptionCache.set(distinctId, toDomainResponse(status));
|
|
9894
10390
|
return sub;
|
|
9895
10391
|
}, [setCacheAndState]);
|
|
9896
|
-
const hasActiveSubscription = (0,
|
|
10392
|
+
const hasActiveSubscription = (0, import_react26.useCallback)(async () => {
|
|
9897
10393
|
const apiClient = PaywalloClient.getApiClient();
|
|
9898
10394
|
const distinctId = PaywalloClient.getDistinctId();
|
|
9899
10395
|
if (!apiClient || !distinctId) return false;
|
|
@@ -9913,7 +10409,7 @@ function useSubscriptionSync() {
|
|
|
9913
10409
|
return resolveOfflineFromCache(distinctId);
|
|
9914
10410
|
}
|
|
9915
10411
|
}, [setCacheAndState]);
|
|
9916
|
-
const getSubscription = (0,
|
|
10412
|
+
const getSubscription = (0, import_react26.useCallback)(async () => {
|
|
9917
10413
|
const apiClient = PaywalloClient.getApiClient();
|
|
9918
10414
|
const distinctId = PaywalloClient.getDistinctId();
|
|
9919
10415
|
if (!apiClient || !distinctId) return null;
|
|
@@ -9934,214 +10430,24 @@ function useSubscriptionSync() {
|
|
|
9934
10430
|
return { subscription, hasActiveSubscription, getSubscription, invalidateCache };
|
|
9935
10431
|
}
|
|
9936
10432
|
|
|
9937
|
-
// src/domains/paywall/SuperwallAutoBridge.ts
|
|
9938
|
-
init_PaywalloClient();
|
|
9939
|
-
|
|
9940
|
-
// src/core/utils/eventId.ts
|
|
9941
|
-
function hashString(input) {
|
|
9942
|
-
let h1 = 3735928559;
|
|
9943
|
-
let h2 = 1103547991;
|
|
9944
|
-
for (let i = 0; i < input.length; i++) {
|
|
9945
|
-
const ch = input.charCodeAt(i);
|
|
9946
|
-
h1 = Math.imul(h1 ^ ch, 2654435769);
|
|
9947
|
-
h2 = Math.imul(h2 ^ ch, 1598716949);
|
|
9948
|
-
}
|
|
9949
|
-
h1 = Math.imul(h1 ^ h1 >>> 16, 73244475);
|
|
9950
|
-
h1 ^= Math.imul(h2 ^ h2 >>> 13, 351452291);
|
|
9951
|
-
h2 = Math.imul(h2 ^ h2 >>> 16, 73244475);
|
|
9952
|
-
h2 ^= Math.imul(h1 ^ h1 >>> 13, 351452291);
|
|
9953
|
-
const toHex = (n) => (n >>> 0).toString(16).padStart(8, "0");
|
|
9954
|
-
return toHex(h1) + toHex(h2);
|
|
9955
|
-
}
|
|
9956
|
-
function buildDeterministicEventId(parts) {
|
|
9957
|
-
const raw = hashString(parts.join("|"));
|
|
9958
|
-
const p1 = raw.slice(0, 8);
|
|
9959
|
-
const p2 = raw.slice(8, 12);
|
|
9960
|
-
const p3 = "4" + raw.slice(13, 16);
|
|
9961
|
-
const p4 = (parseInt(raw[16], 16) & 3 | 8).toString(16) + raw.slice(17, 20);
|
|
9962
|
-
const p5 = raw.padEnd(32, "0").slice(20, 32);
|
|
9963
|
-
return `${p1}-${p2}-${p3}-${p4}-${p5}`;
|
|
9964
|
-
}
|
|
9965
|
-
|
|
9966
|
-
// src/domains/paywall/SuperwallAutoBridge.ts
|
|
9967
|
-
var bridgeStarted = false;
|
|
9968
|
-
var unsubscribe = null;
|
|
9969
|
-
var debugEnabled = false;
|
|
9970
|
-
function log(msg, data) {
|
|
9971
|
-
if (!debugEnabled) return;
|
|
9972
|
-
if (data !== void 0) {
|
|
9973
|
-
console.log(`[Paywallo:SuperwallBridge] ${msg}`, data);
|
|
9974
|
-
} else {
|
|
9975
|
-
console.log(`[Paywallo:SuperwallBridge] ${msg}`);
|
|
9976
|
-
}
|
|
9977
|
-
}
|
|
9978
|
-
function minuteBucket(ts) {
|
|
9979
|
-
return String(Math.floor(ts / 6e4));
|
|
9980
|
-
}
|
|
9981
|
-
function buildEventId(type, identifier, ts) {
|
|
9982
|
-
return buildDeterministicEventId(["sw", type, identifier, minuteBucket(ts)]);
|
|
9983
|
-
}
|
|
9984
|
-
async function trackPaywallEvent(type, identifier, ts, extra) {
|
|
9985
|
-
const _eventId = buildEventId(type, identifier, ts);
|
|
9986
|
-
try {
|
|
9987
|
-
const cleanExtra = {};
|
|
9988
|
-
if (extra) {
|
|
9989
|
-
for (const [k, v] of Object.entries(extra)) if (v !== void 0) cleanExtra[k] = v;
|
|
9990
|
-
}
|
|
9991
|
-
await PaywalloClient.track("paywall", {
|
|
9992
|
-
priority: "critical",
|
|
9993
|
-
properties: {
|
|
9994
|
-
type,
|
|
9995
|
-
paywall_id: identifier,
|
|
9996
|
-
...cleanExtra
|
|
9997
|
-
}
|
|
9998
|
-
});
|
|
9999
|
-
} catch (err) {
|
|
10000
|
-
log("track error", { type, identifier, eventId: _eventId, err: String(err) });
|
|
10001
|
-
}
|
|
10002
|
-
}
|
|
10003
|
-
function mapDismissToCloseReason(resultType) {
|
|
10004
|
-
switch (resultType) {
|
|
10005
|
-
case "purchased":
|
|
10006
|
-
return "purchased";
|
|
10007
|
-
case "restored":
|
|
10008
|
-
return "purchased";
|
|
10009
|
-
// restore counts as a purchase outcome for funnel
|
|
10010
|
-
case "declined":
|
|
10011
|
-
return "dismissed";
|
|
10012
|
-
default:
|
|
10013
|
-
return void 0;
|
|
10014
|
-
}
|
|
10015
|
-
}
|
|
10016
|
-
function buildCallbacks() {
|
|
10017
|
-
return {
|
|
10018
|
-
onPaywallPresent: (info) => {
|
|
10019
|
-
const ts = Date.now();
|
|
10020
|
-
log("onPaywallPresent", { identifier: info.identifier });
|
|
10021
|
-
void trackPaywallEvent("viewed", info.identifier, ts, {
|
|
10022
|
-
placement: info.presentedByEventWithName,
|
|
10023
|
-
variant_id: info.experiment?.variant?.id,
|
|
10024
|
-
campaign_id: info.experiment?.id
|
|
10025
|
-
});
|
|
10026
|
-
},
|
|
10027
|
-
onPaywallDismiss: (info, result) => {
|
|
10028
|
-
const ts = Date.now();
|
|
10029
|
-
log("onPaywallDismiss", { identifier: info.identifier, result: result.type });
|
|
10030
|
-
void trackPaywallEvent("closed", info.identifier, ts, {
|
|
10031
|
-
placement: info.presentedByEventWithName,
|
|
10032
|
-
variant_id: info.experiment?.variant?.id,
|
|
10033
|
-
campaign_id: info.experiment?.id,
|
|
10034
|
-
close_reason: mapDismissToCloseReason(result.type),
|
|
10035
|
-
closed_at: new Date(ts).toISOString()
|
|
10036
|
-
});
|
|
10037
|
-
},
|
|
10038
|
-
onPurchase: (params) => {
|
|
10039
|
-
const ts = Date.now();
|
|
10040
|
-
const safe = params !== null && typeof params === "object" ? params : {};
|
|
10041
|
-
const productId = "productId" in safe && typeof safe.productId === "string" ? safe.productId : "unknown";
|
|
10042
|
-
const identifier = "paywallIdentifier" in safe && typeof safe.paywallIdentifier === "string" ? safe.paywallIdentifier : productId;
|
|
10043
|
-
log("onPurchase", { productId, identifier });
|
|
10044
|
-
void trackPaywallEvent("purchased", identifier, ts, { product_id: productId });
|
|
10045
|
-
},
|
|
10046
|
-
// Global Superwall event listener — used specifically for `transactionComplete`
|
|
10047
|
-
// which is the only event that exposes the full product (currency/price) +
|
|
10048
|
-
// transaction (storeTransactionId) shape needed to create a server-side
|
|
10049
|
-
// `transactions` row. Other events are skipped (paywallOpen/Dismiss already
|
|
10050
|
-
// handled above with their typed callbacks).
|
|
10051
|
-
onSuperwallEvent: (info) => {
|
|
10052
|
-
const ev = info?.event;
|
|
10053
|
-
if (!ev || ev.event !== "transactionComplete") return;
|
|
10054
|
-
const ts = Date.now();
|
|
10055
|
-
const product = ev.product;
|
|
10056
|
-
const transaction = ev.transaction;
|
|
10057
|
-
if (!product) {
|
|
10058
|
-
log("transactionComplete missing product \u2014 skipping transaction track");
|
|
10059
|
-
return;
|
|
10060
|
-
}
|
|
10061
|
-
const productId = product.productIdentifier ?? product.id ?? "unknown";
|
|
10062
|
-
const currency = product.currencyCode ?? "USD";
|
|
10063
|
-
const price = product.price ?? 0;
|
|
10064
|
-
const transactionId = transaction?.storeTransactionId ?? transaction?.originalTransactionIdentifier ?? `${productId}_${String(ts)}`;
|
|
10065
|
-
const isTrial = product.hasFreeTrial === true || (product.trialPeriodPrice ?? 0) > 0;
|
|
10066
|
-
const paywallIdentifier = ev.paywallInfo?.identifier;
|
|
10067
|
-
log("onSuperwallEvent: transactionComplete", { productId, currency, price, transactionId, isTrial });
|
|
10068
|
-
void (async () => {
|
|
10069
|
-
try {
|
|
10070
|
-
await PaywalloClient.track("transaction", {
|
|
10071
|
-
priority: "critical",
|
|
10072
|
-
properties: {
|
|
10073
|
-
type: isTrial ? "trial_started" : "completed",
|
|
10074
|
-
// Server's IngestTranslator looks for `transaction_id`/`product_id`
|
|
10075
|
-
// /`amount`/`currency`/`paywall_id` keys (not `tx_id`). PurchaseHandler
|
|
10076
|
-
// then resolves type=trial/new/renewal based on amount being 0 vs >0.
|
|
10077
|
-
transaction_id: transactionId,
|
|
10078
|
-
product_id: productId,
|
|
10079
|
-
amount: price,
|
|
10080
|
-
currency,
|
|
10081
|
-
...paywallIdentifier ? { paywall_id: paywallIdentifier } : {}
|
|
10082
|
-
}
|
|
10083
|
-
});
|
|
10084
|
-
} catch (err) {
|
|
10085
|
-
log("transactionComplete track error", { err: String(err) });
|
|
10086
|
-
}
|
|
10087
|
-
})();
|
|
10088
|
-
}
|
|
10089
|
-
};
|
|
10090
|
-
}
|
|
10091
|
-
function startSuperwallAutoBridge(debug = false) {
|
|
10092
|
-
debugEnabled = debug;
|
|
10093
|
-
if (bridgeStarted) {
|
|
10094
|
-
log("already started, skipping");
|
|
10095
|
-
return;
|
|
10096
|
-
}
|
|
10097
|
-
void detectAndStart();
|
|
10098
|
-
}
|
|
10099
|
-
async function detectAndStart() {
|
|
10100
|
-
let subscribeFn;
|
|
10101
|
-
try {
|
|
10102
|
-
const mod = await import("expo-superwall");
|
|
10103
|
-
if (!mod || typeof mod.subscribeToSuperwallEvents !== "function") {
|
|
10104
|
-
const internal = await import("expo-superwall/build/src/internal/superwallEventBridge");
|
|
10105
|
-
if (typeof internal.subscribeToSuperwallEvents !== "function") {
|
|
10106
|
-
log("expo-superwall subscribeToSuperwallEvents not found \u2014 bridge inactive");
|
|
10107
|
-
return;
|
|
10108
|
-
}
|
|
10109
|
-
subscribeFn = internal.subscribeToSuperwallEvents;
|
|
10110
|
-
} else {
|
|
10111
|
-
subscribeFn = mod.subscribeToSuperwallEvents;
|
|
10112
|
-
}
|
|
10113
|
-
} catch {
|
|
10114
|
-
log("expo-superwall not installed \u2014 bridge inactive");
|
|
10115
|
-
return;
|
|
10116
|
-
}
|
|
10117
|
-
try {
|
|
10118
|
-
const callbacks = buildCallbacks();
|
|
10119
|
-
unsubscribe = subscribeFn(void 0, () => callbacks);
|
|
10120
|
-
bridgeStarted = true;
|
|
10121
|
-
log("bridge started");
|
|
10122
|
-
} catch (err) {
|
|
10123
|
-
log("subscribe failed", { err: String(err) });
|
|
10124
|
-
}
|
|
10125
|
-
}
|
|
10126
|
-
|
|
10127
10433
|
// src/PaywalloProvider.tsx
|
|
10128
10434
|
init_localization();
|
|
10129
|
-
var
|
|
10435
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
10130
10436
|
function PaywalloProvider({ children, config }) {
|
|
10131
|
-
const [isInitialized, setIsInitialized] = (0,
|
|
10132
|
-
const [initError, setInitError] = (0,
|
|
10133
|
-
const [distinctId, setDistinctId] = (0,
|
|
10134
|
-
const [activePaywall, setActivePaywall] = (0,
|
|
10437
|
+
const [isInitialized, setIsInitialized] = (0, import_react27.useState)(false);
|
|
10438
|
+
const [initError, setInitError] = (0, import_react27.useState)(null);
|
|
10439
|
+
const [distinctId, setDistinctId] = (0, import_react27.useState)(null);
|
|
10440
|
+
const [activePaywall, setActivePaywall] = (0, import_react27.useState)(null);
|
|
10135
10441
|
const { products, isLoadingProducts, refreshProducts } = useProductLoader();
|
|
10136
10442
|
const { subscription, hasActiveSubscription, getSubscription, invalidateCache } = useSubscriptionSync();
|
|
10137
10443
|
const { preloadedWebView, setPreloadedWebView, preloadCampaign, consumePreloadedCampaign, isPreloadValid } = useCampaignPreload();
|
|
10138
|
-
const clearPreloadedWebView = (0,
|
|
10139
|
-
const autoPreloadTriggeredRef = (0,
|
|
10140
|
-
const preloadedWebViewRef = (0,
|
|
10141
|
-
const pollTimerRef = (0,
|
|
10142
|
-
const pollCancelledRef = (0,
|
|
10143
|
-
const secureStorageRef = (0,
|
|
10144
|
-
(0,
|
|
10444
|
+
const clearPreloadedWebView = (0, import_react27.useCallback)(() => setPreloadedWebView(null), [setPreloadedWebView]);
|
|
10445
|
+
const autoPreloadTriggeredRef = (0, import_react27.useRef)(false);
|
|
10446
|
+
const preloadedWebViewRef = (0, import_react27.useRef)(preloadedWebView);
|
|
10447
|
+
const pollTimerRef = (0, import_react27.useRef)(null);
|
|
10448
|
+
const pollCancelledRef = (0, import_react27.useRef)(false);
|
|
10449
|
+
const secureStorageRef = (0, import_react27.useRef)(new SecureStorage(config.debug));
|
|
10450
|
+
(0, import_react27.useEffect)(() => {
|
|
10145
10451
|
preloadedWebViewRef.current = preloadedWebView;
|
|
10146
10452
|
}, [preloadedWebView]);
|
|
10147
10453
|
useAppAutoEvents({
|
|
@@ -10167,22 +10473,22 @@ function PaywalloProvider({ children, config }) {
|
|
|
10167
10473
|
},
|
|
10168
10474
|
debug: config.debug
|
|
10169
10475
|
});
|
|
10170
|
-
const triggerRepreload = (0,
|
|
10476
|
+
const triggerRepreload = (0, import_react27.useCallback)((placement) => {
|
|
10171
10477
|
void PaywalloClient.preloadCampaign(placement).catch(() => {
|
|
10172
10478
|
});
|
|
10173
10479
|
}, []);
|
|
10174
10480
|
const { showingPreloadedWebView, presentPreloadedWebView, resolvePreloadedPaywall, handlePreloadedWebViewReady: baseHandlePreloadedWebViewReady, handlePreloadedClose: baseHandlePreloadedClose, setShowingPreloadedWebView, presentedAtRef } = usePaywallPresenter(preloadedWebView, setPreloadedWebView);
|
|
10175
|
-
const SCREEN_HEIGHT = (0,
|
|
10176
|
-
const slideAnim = (0,
|
|
10177
|
-
const handlePreloadedWebViewReady = (0,
|
|
10481
|
+
const SCREEN_HEIGHT = (0, import_react27.useMemo)(() => import_react_native29.Dimensions.get("window").height, []);
|
|
10482
|
+
const slideAnim = (0, import_react27.useRef)(new import_react_native29.Animated.Value(SCREEN_HEIGHT)).current;
|
|
10483
|
+
const handlePreloadedWebViewReady = (0, import_react27.useCallback)(() => {
|
|
10178
10484
|
if (PaywalloClient.getConfig()?.debug) {
|
|
10179
10485
|
console.log(`[Paywallo WEBVIEW] loaded \u2014 placement: ${preloadedWebView?.placement}`);
|
|
10180
10486
|
}
|
|
10181
10487
|
baseHandlePreloadedWebViewReady();
|
|
10182
10488
|
}, [preloadedWebView?.placement, baseHandlePreloadedWebViewReady]);
|
|
10183
|
-
const handlePreloadedClose = (0,
|
|
10489
|
+
const handlePreloadedClose = (0, import_react27.useCallback)(() => {
|
|
10184
10490
|
const placement = preloadedWebView?.placement;
|
|
10185
|
-
|
|
10491
|
+
import_react_native29.Animated.timing(slideAnim, { toValue: SCREEN_HEIGHT, duration: 200, easing: import_react_native29.Easing.in(import_react_native29.Easing.cubic), useNativeDriver: true }).start(() => {
|
|
10186
10492
|
baseHandlePreloadedClose();
|
|
10187
10493
|
if (placement) triggerRepreload(placement);
|
|
10188
10494
|
});
|
|
@@ -10195,8 +10501,8 @@ function PaywalloProvider({ children, config }) {
|
|
|
10195
10501
|
presentedAtRef,
|
|
10196
10502
|
invalidateCache
|
|
10197
10503
|
);
|
|
10198
|
-
const [isPreloadPurchasing, setIsPreloadPurchasing] = (0,
|
|
10199
|
-
const handlePreloadedPurchase = (0,
|
|
10504
|
+
const [isPreloadPurchasing, setIsPreloadPurchasing] = (0, import_react27.useState)(false);
|
|
10505
|
+
const handlePreloadedPurchase = (0, import_react27.useCallback)(async (productId) => {
|
|
10200
10506
|
setIsPreloadPurchasing(true);
|
|
10201
10507
|
try {
|
|
10202
10508
|
await rawPreloadedPurchase(productId);
|
|
@@ -10204,8 +10510,8 @@ function PaywalloProvider({ children, config }) {
|
|
|
10204
10510
|
setIsPreloadPurchasing(false);
|
|
10205
10511
|
}
|
|
10206
10512
|
}, [rawPreloadedPurchase]);
|
|
10207
|
-
const configRef = (0,
|
|
10208
|
-
(0,
|
|
10513
|
+
const configRef = (0, import_react27.useRef)(config);
|
|
10514
|
+
(0, import_react27.useEffect)(() => {
|
|
10209
10515
|
let mounted = true;
|
|
10210
10516
|
initLocalization({ detectDevice: true });
|
|
10211
10517
|
PaywalloClient.init(configRef.current).then(async () => {
|
|
@@ -10218,6 +10524,11 @@ function PaywalloProvider({ children, config }) {
|
|
|
10218
10524
|
const placement = await PaywalloClient.waitForAutoPreloadedPlacement();
|
|
10219
10525
|
if (mounted && placement) void preloadCampaign(placement).catch(() => {
|
|
10220
10526
|
});
|
|
10527
|
+
const preloadPlacements = configRef.current.preloadPaywalls;
|
|
10528
|
+
if (mounted && preloadPlacements && preloadPlacements.length > 0) {
|
|
10529
|
+
void PaywalloClient.preloadPaywalls(preloadPlacements).catch(() => {
|
|
10530
|
+
});
|
|
10531
|
+
}
|
|
10221
10532
|
}
|
|
10222
10533
|
}).catch((err) => {
|
|
10223
10534
|
if (!mounted) return;
|
|
@@ -10227,14 +10538,28 @@ function PaywalloProvider({ children, config }) {
|
|
|
10227
10538
|
mounted = false;
|
|
10228
10539
|
};
|
|
10229
10540
|
}, [preloadCampaign]);
|
|
10230
|
-
const getPaywallConfig = (0,
|
|
10541
|
+
const getPaywallConfig = (0, import_react27.useCallback)(async (p) => {
|
|
10231
10542
|
const api = PaywalloClient.getApiClient();
|
|
10232
10543
|
return api ? api.getPaywall(p) : null;
|
|
10233
10544
|
}, []);
|
|
10234
|
-
const presentPaywall = (0,
|
|
10235
|
-
|
|
10545
|
+
const presentPaywall = (0, import_react27.useCallback)((placement) => {
|
|
10546
|
+
const preloaded = paywallPreloadService.getPreloaded(placement);
|
|
10547
|
+
return new Promise((resolve) => setActivePaywall({
|
|
10548
|
+
placement,
|
|
10549
|
+
resolver: resolve,
|
|
10550
|
+
...preloaded && {
|
|
10551
|
+
paywallConfig: {
|
|
10552
|
+
id: preloaded.config.id,
|
|
10553
|
+
placement: preloaded.config.placement,
|
|
10554
|
+
config: preloaded.config.config,
|
|
10555
|
+
primaryProductId: preloaded.config.primaryProductId,
|
|
10556
|
+
secondaryProductId: preloaded.config.secondaryProductId
|
|
10557
|
+
},
|
|
10558
|
+
preloadedProducts: preloaded.products
|
|
10559
|
+
}
|
|
10560
|
+
}));
|
|
10236
10561
|
}, []);
|
|
10237
|
-
const trackCampaignImpression = (0,
|
|
10562
|
+
const trackCampaignImpression = (0, import_react27.useCallback)((placement, variantKey, campaignId) => {
|
|
10238
10563
|
const api = PaywalloClient.getApiClient();
|
|
10239
10564
|
if (!api) return;
|
|
10240
10565
|
const sessionId = PaywalloClient.getSessionId();
|
|
@@ -10248,7 +10573,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
10248
10573
|
}).catch(() => {
|
|
10249
10574
|
});
|
|
10250
10575
|
}, []);
|
|
10251
|
-
const presentCampaign = (0,
|
|
10576
|
+
const presentCampaign = (0, import_react27.useCallback)(
|
|
10252
10577
|
async (placement, context) => {
|
|
10253
10578
|
try {
|
|
10254
10579
|
if (preloadedWebView?.placement === placement && preloadedWebView.loaded && isPreloadValid(placement)) {
|
|
@@ -10322,7 +10647,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
10322
10647
|
},
|
|
10323
10648
|
[preloadedWebView, isPreloadValid, consumePreloadedCampaign, presentPreloadedWebView, trackCampaignImpression]
|
|
10324
10649
|
);
|
|
10325
|
-
const restorePurchases = (0,
|
|
10650
|
+
const restorePurchases = (0, import_react27.useCallback)(async () => {
|
|
10326
10651
|
invalidateCache();
|
|
10327
10652
|
try {
|
|
10328
10653
|
const txs = await getIAPService().restore();
|
|
@@ -10331,13 +10656,13 @@ function PaywalloProvider({ children, config }) {
|
|
|
10331
10656
|
return { success: false, restoredProducts: [], error: error instanceof Error ? error : new PurchaseError(PURCHASE_ERROR_CODES.RESTORE_FAILED, String(error)) };
|
|
10332
10657
|
}
|
|
10333
10658
|
}, [invalidateCache]);
|
|
10334
|
-
const handlePaywallResult = (0,
|
|
10659
|
+
const handlePaywallResult = (0, import_react27.useCallback)((result) => {
|
|
10335
10660
|
if (activePaywall) {
|
|
10336
10661
|
activePaywall.resolver(result);
|
|
10337
10662
|
setActivePaywall(null);
|
|
10338
10663
|
}
|
|
10339
10664
|
}, [activePaywall]);
|
|
10340
|
-
const bridgePaywallPresenter = (0,
|
|
10665
|
+
const bridgePaywallPresenter = (0, import_react27.useCallback)((placement) => {
|
|
10341
10666
|
if (PaywalloClient.getConfig()?.debug) {
|
|
10342
10667
|
console.log(`[Paywallo PRESENT] called \u2014 preloaded: ${preloadedWebViewRef.current?.loaded === true} placement: ${placement}`);
|
|
10343
10668
|
}
|
|
@@ -10366,7 +10691,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
10366
10691
|
}
|
|
10367
10692
|
return presentCampaign(placement);
|
|
10368
10693
|
}, [presentPreloadedWebView, presentCampaign]);
|
|
10369
|
-
(0,
|
|
10694
|
+
(0, import_react27.useEffect)(() => {
|
|
10370
10695
|
if (!isInitialized) return;
|
|
10371
10696
|
const onEmergency = async (id) => {
|
|
10372
10697
|
try {
|
|
@@ -10393,9 +10718,9 @@ function PaywalloProvider({ children, config }) {
|
|
|
10393
10718
|
};
|
|
10394
10719
|
}, [isInitialized, bridgePaywallPresenter, getSubscription, hasActiveSubscription, restorePurchases]);
|
|
10395
10720
|
const isReady = isInitialized && !isLoadingProducts;
|
|
10396
|
-
const noOp = (0,
|
|
10721
|
+
const noOp = (0, import_react27.useCallback)(() => {
|
|
10397
10722
|
}, []);
|
|
10398
|
-
const contextValue = (0,
|
|
10723
|
+
const contextValue = (0, import_react27.useMemo)(() => ({
|
|
10399
10724
|
config: PaywalloClient.getConfig(),
|
|
10400
10725
|
isInitialized,
|
|
10401
10726
|
isReady,
|
|
@@ -10429,20 +10754,20 @@ function PaywalloProvider({ children, config }) {
|
|
|
10429
10754
|
getPaywallConfig,
|
|
10430
10755
|
refreshProducts
|
|
10431
10756
|
]);
|
|
10432
|
-
(0,
|
|
10757
|
+
(0, import_react27.useLayoutEffect)(() => {
|
|
10433
10758
|
if (showingPreloadedWebView) {
|
|
10434
10759
|
slideAnim.setValue(SCREEN_HEIGHT);
|
|
10435
|
-
|
|
10760
|
+
import_react_native29.Animated.timing(slideAnim, { toValue: 0, duration: 200, easing: import_react_native29.Easing.out(import_react_native29.Easing.cubic), useNativeDriver: true }).start();
|
|
10436
10761
|
}
|
|
10437
10762
|
}, [showingPreloadedWebView, slideAnim, SCREEN_HEIGHT]);
|
|
10438
10763
|
const preloadStyle = [
|
|
10439
|
-
|
|
10440
|
-
showingPreloadedWebView ?
|
|
10764
|
+
styles5.preloadOverlay,
|
|
10765
|
+
showingPreloadedWebView ? styles5.visible : styles5.hidden,
|
|
10441
10766
|
showingPreloadedWebView ? { transform: [{ translateY: slideAnim }] } : void 0
|
|
10442
10767
|
];
|
|
10443
|
-
return /* @__PURE__ */ (0,
|
|
10768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(PaywalloContext.Provider, { value: contextValue, children: [
|
|
10444
10769
|
children,
|
|
10445
|
-
/* @__PURE__ */ (0,
|
|
10770
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallErrorBoundary, { children: !!preloadedWebView?.craftData && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native29.Animated.View, { style: preloadStyle, pointerEvents: showingPreloadedWebView ? "auto" : "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
10446
10771
|
PaywallWebView,
|
|
10447
10772
|
{
|
|
10448
10773
|
paywallId: preloadedWebView.paywallId,
|
|
@@ -10458,7 +10783,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
10458
10783
|
onRestore: showingPreloadedWebView ? handlePreloadedRestore : noOp
|
|
10459
10784
|
}
|
|
10460
10785
|
) }) }),
|
|
10461
|
-
/* @__PURE__ */ (0,
|
|
10786
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallErrorBoundary, { children: activePaywall && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
10462
10787
|
PaywallModal,
|
|
10463
10788
|
{
|
|
10464
10789
|
placement: activePaywall.placement,
|
|
@@ -10470,10 +10795,11 @@ function PaywalloProvider({ children, config }) {
|
|
|
10470
10795
|
campaignId: activePaywall.campaignId,
|
|
10471
10796
|
variantId: activePaywall.variantId
|
|
10472
10797
|
}
|
|
10473
|
-
) })
|
|
10798
|
+
) }),
|
|
10799
|
+
isInitialized && (config.preloadPaywalls?.length ?? 0) > 0 && PaywalloClient.getWebUrl() !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallWebViewPrewarmer, { webUrl: PaywalloClient.getWebUrl() })
|
|
10474
10800
|
] });
|
|
10475
10801
|
}
|
|
10476
|
-
var
|
|
10802
|
+
var styles5 = import_react_native29.StyleSheet.create({
|
|
10477
10803
|
preloadOverlay: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, backgroundColor: "#ffffff" },
|
|
10478
10804
|
hidden: { zIndex: -1, opacity: 0, width: 1, height: 1, overflow: "hidden" },
|
|
10479
10805
|
visible: { zIndex: 9999, opacity: 1 }
|