@umituz/react-native-subscription 2.27.98 → 2.27.100
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 +3 -3
- package/src/domains/credits/presentation/useDeductCredit.ts +1 -9
- package/src/domains/paywall/components/PaywallModal.tsx +0 -15
- package/src/domains/subscription/infrastructure/hooks/useRevenueCatTrialEligibility.ts +1 -1
- package/src/domains/subscription/infrastructure/services/RevenueCatInitializer.ts +1 -1
- package/src/domains/subscription/presentation/stores/purchaseLoadingStore.ts +0 -8
- package/src/domains/subscription/presentation/useFeatureGate.ts +1 -1
- package/src/domains/wallet/presentation/components/TransactionItem.tsx +3 -16
- package/src/domains/wallet/utils/index.ts +1 -0
- package/src/domains/wallet/utils/transactionIconMap.ts +26 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-subscription",
|
|
3
|
-
"version": "2.27.
|
|
3
|
+
"version": "2.27.100",
|
|
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",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"expo-constants": ">=17.0.0",
|
|
38
38
|
"expo-image": ">=3.0.0",
|
|
39
39
|
"firebase": ">=10.0.0",
|
|
40
|
-
"react": ">=
|
|
41
|
-
"react-native": ">=0.
|
|
40
|
+
"react": ">=19.0.0",
|
|
41
|
+
"react-native": ">=0.81.0",
|
|
42
42
|
"react-native-purchases": ">=7.0.0",
|
|
43
43
|
"react-native-safe-area-context": ">=5.0.0",
|
|
44
44
|
"zustand": ">=5.0.0"
|
|
@@ -81,22 +81,14 @@ export const useDeductCredit = ({
|
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
const deductCredit = useCallback(async (cost: number = 1): Promise<boolean> => {
|
|
84
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
85
|
-
}
|
|
86
84
|
try {
|
|
87
85
|
const res = await mutation.mutateAsync(cost);
|
|
88
86
|
if (!res.success) {
|
|
89
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
90
|
-
}
|
|
91
87
|
if (res.error?.code === "CREDITS_EXHAUSTED") onCreditsExhausted?.();
|
|
92
88
|
return false;
|
|
93
89
|
}
|
|
94
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
95
|
-
}
|
|
96
90
|
return true;
|
|
97
|
-
} catch
|
|
98
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
99
|
-
}
|
|
91
|
+
} catch {
|
|
100
92
|
return false;
|
|
101
93
|
}
|
|
102
94
|
}, [mutation, onCreditsExhausted]);
|
|
@@ -73,45 +73,30 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
|
|
|
73
73
|
const handlePurchase = useCallback(async () => {
|
|
74
74
|
if (!selectedPlanId || !onPurchase) return;
|
|
75
75
|
|
|
76
|
-
if (__DEV__) {
|
|
77
|
-
}
|
|
78
|
-
|
|
79
76
|
setIsLocalProcessing(true);
|
|
80
77
|
startPurchase(selectedPlanId, "manual");
|
|
81
78
|
|
|
82
79
|
try {
|
|
83
80
|
const pkg = packages.find((p) => p.product.identifier === selectedPlanId);
|
|
84
81
|
if (pkg) {
|
|
85
|
-
if (__DEV__) {
|
|
86
|
-
}
|
|
87
82
|
await onPurchase(pkg);
|
|
88
|
-
if (__DEV__) {
|
|
89
|
-
}
|
|
90
83
|
}
|
|
91
84
|
} catch (error) {
|
|
92
|
-
// Error is handled by usePurchasePackage, just log for debugging
|
|
93
85
|
if (__DEV__) {
|
|
94
86
|
console.error("[PaywallModal] Purchase failed:", error);
|
|
95
87
|
}
|
|
96
88
|
} finally {
|
|
97
89
|
setIsLocalProcessing(false);
|
|
98
90
|
endPurchase();
|
|
99
|
-
if (__DEV__) {
|
|
100
|
-
}
|
|
101
91
|
}
|
|
102
92
|
}, [selectedPlanId, packages, onPurchase, startPurchase, endPurchase]);
|
|
103
93
|
|
|
104
94
|
const handleRestore = useCallback(async () => {
|
|
105
95
|
if (!onRestore || isProcessing) return;
|
|
106
96
|
|
|
107
|
-
if (__DEV__) {
|
|
108
|
-
}
|
|
109
|
-
|
|
110
97
|
setIsLocalProcessing(true);
|
|
111
98
|
try {
|
|
112
99
|
await onRestore();
|
|
113
|
-
if (__DEV__) {
|
|
114
|
-
}
|
|
115
100
|
} finally {
|
|
116
101
|
setIsLocalProcessing(false);
|
|
117
102
|
}
|
|
@@ -117,7 +117,7 @@ export function useRevenueCatTrialEligibility(): UseRevenueCatTrialEligibilityRe
|
|
|
117
117
|
if (isMountedRef.current) {
|
|
118
118
|
setEligibilityMap((prev) => ({ ...prev, ...newMap }));
|
|
119
119
|
}
|
|
120
|
-
} catch
|
|
120
|
+
} catch {
|
|
121
121
|
// On error, default to eligible (better UX)
|
|
122
122
|
const fallbackMap: TrialEligibilityMap = {};
|
|
123
123
|
for (const productId of productIds) {
|
|
@@ -102,7 +102,7 @@ export async function initializeSDK(
|
|
|
102
102
|
]);
|
|
103
103
|
|
|
104
104
|
return buildSuccessResult(deps, customerInfo, offerings);
|
|
105
|
-
} catch
|
|
105
|
+
} catch {
|
|
106
106
|
return { success: false, offering: null, isPremium: false };
|
|
107
107
|
} finally {
|
|
108
108
|
configurationState.configurationInProgress = false;
|
|
@@ -46,9 +46,6 @@ export const usePurchaseLoadingStore = create<PurchaseLoadingStore>((set, get) =
|
|
|
46
46
|
newSource: source,
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
// Still update to the new purchase to recover from potential stuck state
|
|
50
|
-
}
|
|
51
|
-
if (__DEV__) {
|
|
52
49
|
}
|
|
53
50
|
set({
|
|
54
51
|
isPurchasing: true,
|
|
@@ -63,9 +60,6 @@ export const usePurchaseLoadingStore = create<PurchaseLoadingStore>((set, get) =
|
|
|
63
60
|
if (__DEV__) {
|
|
64
61
|
console.warn("[PurchaseLoadingStore] endPurchase called while no purchase in progress");
|
|
65
62
|
}
|
|
66
|
-
// Reset to initial state to recover from potential stuck state
|
|
67
|
-
}
|
|
68
|
-
if (__DEV__) {
|
|
69
63
|
}
|
|
70
64
|
set({
|
|
71
65
|
isPurchasing: false,
|
|
@@ -75,8 +69,6 @@ export const usePurchaseLoadingStore = create<PurchaseLoadingStore>((set, get) =
|
|
|
75
69
|
},
|
|
76
70
|
|
|
77
71
|
reset: () => {
|
|
78
|
-
if (__DEV__) {
|
|
79
|
-
}
|
|
80
72
|
set(initialState);
|
|
81
73
|
},
|
|
82
74
|
}));
|
|
@@ -127,7 +127,7 @@ export function useFeatureGate(params: UseFeatureGateParams): UseFeatureGateResu
|
|
|
127
127
|
|
|
128
128
|
action();
|
|
129
129
|
},
|
|
130
|
-
[isAuthenticated, onShowAuthModal
|
|
130
|
+
[isAuthenticated, onShowAuthModal]
|
|
131
131
|
);
|
|
132
132
|
|
|
133
133
|
const hasCredits = creditBalance >= requiredCredits;
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
AtomicIcon,
|
|
14
14
|
} from "@umituz/react-native-design-system";
|
|
15
15
|
import { timezoneService } from "@umituz/react-native-design-system";
|
|
16
|
-
import type { CreditLog
|
|
16
|
+
import type { CreditLog } from "../../domain/types/transaction.types";
|
|
17
|
+
import { getTransactionIcon } from "../../utils/transactionIconMap";
|
|
17
18
|
|
|
18
19
|
export interface TransactionItemTranslations {
|
|
19
20
|
purchase: string;
|
|
@@ -32,20 +33,6 @@ export interface TransactionItemProps {
|
|
|
32
33
|
dateFormatter?: (timestamp: number) => string;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
const getReasonIcon = (reason: TransactionReason): string => {
|
|
36
|
-
const iconMap: Record<TransactionReason, string> = {
|
|
37
|
-
purchase: "shopping-cart",
|
|
38
|
-
usage: "zap",
|
|
39
|
-
refund: "rotate-ccw",
|
|
40
|
-
bonus: "gift",
|
|
41
|
-
subscription: "star",
|
|
42
|
-
admin: "shield",
|
|
43
|
-
reward: "award",
|
|
44
|
-
expired: "clock",
|
|
45
|
-
};
|
|
46
|
-
return iconMap[reason] || "circle";
|
|
47
|
-
};
|
|
48
|
-
|
|
49
36
|
const defaultDateFormatter = (timestamp: number): string => {
|
|
50
37
|
return timezoneService.formatToDisplayDateTime(new Date(timestamp));
|
|
51
38
|
};
|
|
@@ -64,7 +51,7 @@ export const TransactionItem: React.FC<TransactionItemProps> = ({
|
|
|
64
51
|
const isPositive = transaction.change > 0;
|
|
65
52
|
const changeColor = isPositive ? tokens.colors.success : tokens.colors.error;
|
|
66
53
|
const changePrefix = isPositive ? "+" : "";
|
|
67
|
-
const iconName =
|
|
54
|
+
const iconName = getTransactionIcon(transaction.reason);
|
|
68
55
|
|
|
69
56
|
return (
|
|
70
57
|
<View
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./transactionIconMap";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction Icon Mapping Utility
|
|
3
|
+
* Maps transaction reasons to their corresponding icons
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { TransactionReason } from "../domain/types/transaction.types";
|
|
7
|
+
|
|
8
|
+
const ICON_MAP: Record<TransactionReason, string> = {
|
|
9
|
+
purchase: "shopping-cart",
|
|
10
|
+
usage: "zap",
|
|
11
|
+
refund: "rotate-ccw",
|
|
12
|
+
bonus: "gift",
|
|
13
|
+
subscription: "star",
|
|
14
|
+
admin: "shield",
|
|
15
|
+
reward: "award",
|
|
16
|
+
expired: "clock",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get icon name for a transaction reason
|
|
21
|
+
* @param reason - Transaction reason type
|
|
22
|
+
* @returns Icon name for the transaction
|
|
23
|
+
*/
|
|
24
|
+
export function getTransactionIcon(reason: TransactionReason): string {
|
|
25
|
+
return ICON_MAP[reason] || "circle";
|
|
26
|
+
}
|