@umituz/react-native-subscription 2.17.11 → 2.18.0
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.
|
|
3
|
+
"version": "2.18.0",
|
|
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",
|
|
@@ -13,17 +13,19 @@ import { usePaywallActions } from "../hooks/usePaywallActions";
|
|
|
13
13
|
import type { PaywallContainerProps } from "./PaywallContainer.types";
|
|
14
14
|
|
|
15
15
|
export const PaywallContainer: React.FC<PaywallContainerProps> = (props) => {
|
|
16
|
-
const { userId, isAnonymous = false, translations, mode = "subscription", legalUrls, features, heroImage, bestValueIdentifier, creditsLabel, creditAmounts, packageFilterConfig, source
|
|
16
|
+
const { userId, isAnonymous = false, translations, mode = "subscription", legalUrls, features, heroImage, bestValueIdentifier, creditsLabel, creditAmounts, packageFilterConfig, source, onPurchaseSuccess, onPurchaseError, onAuthRequired, visible, onClose } = props;
|
|
17
17
|
|
|
18
|
-
const { showPaywall, closePaywall } = usePaywallVisibility();
|
|
18
|
+
const { showPaywall, closePaywall, currentSource } = usePaywallVisibility();
|
|
19
19
|
const isVisible = visible ?? showPaywall;
|
|
20
20
|
const handleClose = onClose ?? closePaywall;
|
|
21
21
|
|
|
22
|
+
const purchaseSource = source ?? currentSource ?? "settings";
|
|
23
|
+
|
|
22
24
|
const { data: allPackages = [], isLoading } = useSubscriptionPackages(userId ?? undefined);
|
|
23
25
|
const { handlePurchase, handleRestore } = usePaywallActions({
|
|
24
26
|
userId: userId ?? undefined,
|
|
25
27
|
isAnonymous,
|
|
26
|
-
source,
|
|
28
|
+
source: purchaseSource,
|
|
27
29
|
onPurchaseSuccess,
|
|
28
30
|
onPurchaseError,
|
|
29
31
|
onAuthRequired,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import type { ImageSourcePropType } from "react-native";
|
|
7
7
|
import type { PaywallMode, PaywallTranslations, PaywallLegalUrls, SubscriptionFeature } from "../entities";
|
|
8
8
|
import type { PackageFilterConfig } from "../../../utils/packageFilter";
|
|
9
|
+
import type { PurchaseSource } from "../../../domain/entities/Credits";
|
|
9
10
|
|
|
10
11
|
export interface PaywallContainerProps {
|
|
11
12
|
/** User ID for subscription management */
|
|
@@ -31,7 +32,7 @@ export interface PaywallContainerProps {
|
|
|
31
32
|
/** Custom filter config for package categorization */
|
|
32
33
|
readonly packageFilterConfig?: PackageFilterConfig;
|
|
33
34
|
/** Source of the paywall - affects pending purchase handling */
|
|
34
|
-
readonly source?:
|
|
35
|
+
readonly source?: PurchaseSource;
|
|
35
36
|
/** Callback when purchase succeeds */
|
|
36
37
|
readonly onPurchaseSuccess?: () => void;
|
|
37
38
|
/** Callback when purchase fails */
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import type { PurchasesPackage } from "react-native-purchases";
|
|
3
|
-
import { usePurchasePackage } from "../../../revenuecat/presentation/hooks/usePurchasePackage";
|
|
4
3
|
import { useRestorePurchase } from "../../../revenuecat/presentation/hooks/useRestorePurchase";
|
|
4
|
+
import { useAuthAwarePurchase } from "../../../presentation/hooks/useAuthAwarePurchase";
|
|
5
|
+
import type { PurchaseSource } from "../../../domain/entities/Credits";
|
|
5
6
|
|
|
6
7
|
declare const __DEV__: boolean;
|
|
7
8
|
|
|
8
9
|
interface UsePaywallActionsProps {
|
|
9
10
|
userId?: string;
|
|
10
11
|
isAnonymous: boolean;
|
|
11
|
-
source?:
|
|
12
|
+
source?: PurchaseSource;
|
|
12
13
|
onPurchaseSuccess?: () => void;
|
|
13
14
|
onPurchaseError?: (error: string) => void;
|
|
14
15
|
onAuthRequired?: () => void;
|
|
@@ -18,12 +19,13 @@ interface UsePaywallActionsProps {
|
|
|
18
19
|
export const usePaywallActions = ({
|
|
19
20
|
userId,
|
|
20
21
|
isAnonymous,
|
|
22
|
+
source,
|
|
21
23
|
onPurchaseSuccess,
|
|
22
24
|
onPurchaseError,
|
|
23
25
|
onAuthRequired,
|
|
24
26
|
onClose,
|
|
25
27
|
}: UsePaywallActionsProps) => {
|
|
26
|
-
const {
|
|
28
|
+
const { handlePurchase: authAwarePurchase } = useAuthAwarePurchase({ source });
|
|
27
29
|
const { mutateAsync: restorePurchases } = useRestorePurchase(userId);
|
|
28
30
|
|
|
29
31
|
const handlePurchase = useCallback(async (pkg: PurchasesPackage) => {
|
|
@@ -35,8 +37,8 @@ export const usePaywallActions = ({
|
|
|
35
37
|
|
|
36
38
|
try {
|
|
37
39
|
if (__DEV__) console.log("[PaywallActions] Purchase started:", pkg.product.identifier);
|
|
38
|
-
const res = await
|
|
39
|
-
if (res
|
|
40
|
+
const res = await authAwarePurchase(pkg, source);
|
|
41
|
+
if (res) {
|
|
40
42
|
onPurchaseSuccess?.();
|
|
41
43
|
onClose();
|
|
42
44
|
}
|
|
@@ -44,7 +46,7 @@ export const usePaywallActions = ({
|
|
|
44
46
|
const message = err instanceof Error ? err.message : String(err);
|
|
45
47
|
onPurchaseError?.(message);
|
|
46
48
|
}
|
|
47
|
-
}, [isAnonymous,
|
|
49
|
+
}, [isAnonymous, authAwarePurchase, source, onClose, onPurchaseSuccess, onPurchaseError, onAuthRequired]);
|
|
48
50
|
|
|
49
51
|
const handleRestore = useCallback(async () => {
|
|
50
52
|
try {
|
|
@@ -60,5 +62,5 @@ export const usePaywallActions = ({
|
|
|
60
62
|
}
|
|
61
63
|
}, [restorePurchases, onClose, onPurchaseSuccess, onPurchaseError]);
|
|
62
64
|
|
|
63
|
-
return { handlePurchase, handleRestore
|
|
65
|
+
return { handlePurchase, handleRestore };
|
|
64
66
|
};
|
|
@@ -5,10 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { useCallback, useSyncExternalStore } from "react";
|
|
8
|
+
import type { PurchaseSource } from "../../domain/entities/Credits";
|
|
8
9
|
|
|
9
10
|
type Listener = () => void;
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
interface PaywallState {
|
|
13
|
+
visible: boolean;
|
|
14
|
+
source?: PurchaseSource;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let paywallState: PaywallState = { visible: false, source: undefined };
|
|
12
18
|
const listeners = new Set<Listener>();
|
|
13
19
|
|
|
14
20
|
const subscribe = (listener: Listener): (() => void) => {
|
|
@@ -16,10 +22,10 @@ const subscribe = (listener: Listener): (() => void) => {
|
|
|
16
22
|
return () => listeners.delete(listener);
|
|
17
23
|
};
|
|
18
24
|
|
|
19
|
-
const getSnapshot = ():
|
|
25
|
+
const getSnapshot = (): PaywallState => paywallState;
|
|
20
26
|
|
|
21
|
-
const
|
|
22
|
-
|
|
27
|
+
const setPaywallState = (visible: boolean, source?: PurchaseSource): void => {
|
|
28
|
+
paywallState = { visible, source };
|
|
23
29
|
listeners.forEach((listener) => listener());
|
|
24
30
|
};
|
|
25
31
|
|
|
@@ -27,35 +33,38 @@ const setPaywallVisible = (visible: boolean): void => {
|
|
|
27
33
|
* Direct paywall control for non-React contexts (e.g., appInitializer)
|
|
28
34
|
*/
|
|
29
35
|
export const paywallControl = {
|
|
30
|
-
open: () =>
|
|
31
|
-
close: () =>
|
|
32
|
-
isOpen: () =>
|
|
36
|
+
open: (source?: PurchaseSource) => setPaywallState(true, source),
|
|
37
|
+
close: () => setPaywallState(false, undefined),
|
|
38
|
+
isOpen: () => paywallState.visible,
|
|
39
|
+
getSource: () => paywallState.source,
|
|
33
40
|
};
|
|
34
41
|
|
|
35
42
|
export interface UsePaywallVisibilityResult {
|
|
36
43
|
showPaywall: boolean;
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
currentSource?: PurchaseSource;
|
|
45
|
+
setShowPaywall: (visible: boolean, source?: PurchaseSource) => void;
|
|
46
|
+
openPaywall: (source?: PurchaseSource) => void;
|
|
39
47
|
closePaywall: () => void;
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
export function usePaywallVisibility(): UsePaywallVisibilityResult {
|
|
43
|
-
const
|
|
51
|
+
const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
44
52
|
|
|
45
|
-
const setShowPaywall = useCallback((visible: boolean) => {
|
|
46
|
-
|
|
53
|
+
const setShowPaywall = useCallback((visible: boolean, source?: PurchaseSource) => {
|
|
54
|
+
setPaywallState(visible, source);
|
|
47
55
|
}, []);
|
|
48
56
|
|
|
49
|
-
const openPaywall = useCallback(() => {
|
|
50
|
-
|
|
57
|
+
const openPaywall = useCallback((source?: PurchaseSource) => {
|
|
58
|
+
setPaywallState(true, source);
|
|
51
59
|
}, []);
|
|
52
60
|
|
|
53
61
|
const closePaywall = useCallback(() => {
|
|
54
|
-
|
|
62
|
+
setPaywallState(false, undefined);
|
|
55
63
|
}, []);
|
|
56
64
|
|
|
57
65
|
return {
|
|
58
|
-
showPaywall,
|
|
66
|
+
showPaywall: state.visible,
|
|
67
|
+
currentSource: state.source,
|
|
59
68
|
setShowPaywall,
|
|
60
69
|
openPaywall,
|
|
61
70
|
closePaywall,
|