@umituz/react-native-subscription 2.14.68 → 2.14.70
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-subscription",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.70",
|
|
4
4
|
"description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Mode: credits | subscription | hybrid
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { useCallback, useEffect, useMemo } from "react";
|
|
7
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
8
8
|
import type { PurchasesPackage } from "react-native-purchases";
|
|
9
9
|
import { usePaywallVisibility } from "../../../presentation/hooks/usePaywallVisibility";
|
|
10
10
|
import { useSubscriptionPackages } from "../../../revenuecat/presentation/hooks/useSubscriptionPackages";
|
|
@@ -38,6 +38,10 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
|
|
|
38
38
|
const { data: allPackages = [], isLoading, isFetching, status, error } = useSubscriptionPackages(userId ?? undefined);
|
|
39
39
|
const { mutateAsync: purchasePackage } = usePurchasePackage(userId ?? undefined);
|
|
40
40
|
const { mutateAsync: restorePurchases } = useRestorePurchase(userId ?? undefined);
|
|
41
|
+
|
|
42
|
+
// Store pending package for post-auth purchase
|
|
43
|
+
const [pendingPackage, setPendingPackage] = useState<PurchasesPackage | null>(null);
|
|
44
|
+
const wasAnonymousRef = useRef(isAnonymous);
|
|
41
45
|
|
|
42
46
|
const { filteredPackages, computedCreditAmounts } = useMemo(() => {
|
|
43
47
|
const filtered = filterPackagesByMode(allPackages, mode, packageFilterConfig);
|
|
@@ -67,13 +71,50 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
|
|
|
67
71
|
}
|
|
68
72
|
}, [showPaywall, userId, isAnonymous, mode, allPackages.length, filteredPackages.length, isLoading, isFetching, status, error]);
|
|
69
73
|
|
|
74
|
+
// Auto-purchase when user authenticates after selecting a package
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const wasAnonymous = wasAnonymousRef.current;
|
|
77
|
+
wasAnonymousRef.current = isAnonymous;
|
|
78
|
+
|
|
79
|
+
// If user was anonymous, now authenticated, and has pending package
|
|
80
|
+
if (wasAnonymous && !isAnonymous && pendingPackage && userId) {
|
|
81
|
+
if (__DEV__) {
|
|
82
|
+
console.log("[PaywallContainer] User authenticated, auto-purchasing pending package:", pendingPackage.identifier);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Execute the purchase
|
|
86
|
+
(async () => {
|
|
87
|
+
try {
|
|
88
|
+
const result = await purchasePackage(pendingPackage);
|
|
89
|
+
if (result.success) {
|
|
90
|
+
if (__DEV__) {
|
|
91
|
+
console.log("[PaywallContainer] Auto-purchase successful");
|
|
92
|
+
}
|
|
93
|
+
onPurchaseSuccess?.();
|
|
94
|
+
closePaywall();
|
|
95
|
+
}
|
|
96
|
+
} catch (err) {
|
|
97
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
98
|
+
if (__DEV__) {
|
|
99
|
+
console.error("[PaywallContainer] Auto-purchase failed:", message);
|
|
100
|
+
}
|
|
101
|
+
onPurchaseError?.(message);
|
|
102
|
+
} finally {
|
|
103
|
+
setPendingPackage(null);
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
}
|
|
107
|
+
}, [isAnonymous, userId, pendingPackage, purchasePackage, onPurchaseSuccess, onPurchaseError, closePaywall]);
|
|
108
|
+
|
|
70
109
|
const handlePurchase = useCallback(
|
|
71
110
|
async (pkg: PurchasesPackage) => {
|
|
72
111
|
// Auth gating: require authentication for anonymous users
|
|
73
112
|
if (isAnonymous) {
|
|
74
113
|
if (__DEV__) {
|
|
75
|
-
console.log("[PaywallContainer] Anonymous user, requiring auth
|
|
114
|
+
console.log("[PaywallContainer] Anonymous user, storing package and requiring auth:", pkg.identifier);
|
|
76
115
|
}
|
|
116
|
+
// Store package for auto-purchase after auth
|
|
117
|
+
setPendingPackage(pkg);
|
|
77
118
|
// Don't close paywall - keep it open so user can purchase after auth
|
|
78
119
|
onAuthRequired?.();
|
|
79
120
|
return;
|
|
@@ -99,7 +140,7 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = ({
|
|
|
99
140
|
onPurchaseError?.(message);
|
|
100
141
|
}
|
|
101
142
|
},
|
|
102
|
-
[isAnonymous, purchasePackage, closePaywall, onPurchaseSuccess, onPurchaseError, onAuthRequired]
|
|
143
|
+
[isAnonymous, purchasePackage, closePaywall, onPurchaseSuccess, onPurchaseError, onAuthRequired, setPendingPackage]
|
|
103
144
|
);
|
|
104
145
|
|
|
105
146
|
const handleRestore = useCallback(async () => {
|
|
@@ -77,6 +77,9 @@ export const useCredits = ({
|
|
|
77
77
|
enabled: enabled && !!userId && isConfigured,
|
|
78
78
|
staleTime,
|
|
79
79
|
gcTime,
|
|
80
|
+
refetchOnMount: true, // Refetch when component mounts
|
|
81
|
+
refetchOnWindowFocus: true, // Refetch when app becomes active
|
|
82
|
+
refetchOnReconnect: true, // Refetch when network reconnects
|
|
80
83
|
});
|
|
81
84
|
|
|
82
85
|
const credits = data ?? null;
|
|
@@ -12,5 +12,7 @@ export const SUBSCRIPTION_QUERY_KEYS = {
|
|
|
12
12
|
["subscription", "initialized", userId] as const,
|
|
13
13
|
} as const;
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// No cache - always fetch fresh data for subscription packages
|
|
16
|
+
// This ensures users always see real-time subscription status
|
|
17
|
+
export const STALE_TIME = 0; // Always stale - refetch immediately
|
|
18
|
+
export const GC_TIME = 0; // Don't cache - garbage collect immediately
|
|
@@ -38,5 +38,7 @@ export const useSubscriptionPackages = (userId: string | undefined) => {
|
|
|
38
38
|
gcTime: GC_TIME,
|
|
39
39
|
enabled: isConfigured,
|
|
40
40
|
refetchOnMount: true,
|
|
41
|
+
refetchOnWindowFocus: true, // Refetch when app becomes active
|
|
42
|
+
refetchOnReconnect: true, // Refetch when network reconnects
|
|
41
43
|
});
|
|
42
44
|
};
|