@umituz/react-native-subscription 2.2.30 → 2.2.32
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.2.
|
|
3
|
+
"version": "2.2.32",
|
|
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",
|
package/src/index.ts
CHANGED
|
@@ -108,6 +108,11 @@ export { SubscriptionPlanCard } from "./presentation/components/paywall/Subscrip
|
|
|
108
108
|
export { PaywallFeaturesList } from "./presentation/components/paywall/PaywallFeaturesList";
|
|
109
109
|
export { PaywallFeatureItem } from "./presentation/components/paywall/PaywallFeatureItem";
|
|
110
110
|
export { PaywallLegalFooter } from "./presentation/components/paywall/PaywallLegalFooter";
|
|
111
|
+
export {
|
|
112
|
+
PaywallModal,
|
|
113
|
+
type PaywallModalProps,
|
|
114
|
+
type PaywallModalStyles,
|
|
115
|
+
} from "./presentation/components/paywall/PaywallModal";
|
|
111
116
|
|
|
112
117
|
// =============================================================================
|
|
113
118
|
// PRESENTATION LAYER - Premium Details Components
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import React, { useEffect } from "react";
|
|
7
|
-
import { View, Modal, StyleSheet, TouchableOpacity } from "react-native";
|
|
7
|
+
import { View, Modal, StyleSheet, TouchableOpacity, Dimensions } from "react-native";
|
|
8
8
|
import { useAppDesignTokens } from "@umituz/react-native-design-system-theme";
|
|
9
9
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
10
10
|
import type { PurchasesPackage } from "react-native-purchases";
|
|
@@ -13,10 +13,34 @@ import { PaywallHeader } from "./PaywallHeader";
|
|
|
13
13
|
import { PaywallTabBar } from "./PaywallTabBar";
|
|
14
14
|
import { CreditsTabContent } from "./CreditsTabContent";
|
|
15
15
|
import { SubscriptionTabContent } from "./SubscriptionTabContent";
|
|
16
|
+
import { ModalLayoutConfig } from "./SubscriptionModalOverlay";
|
|
16
17
|
import type { PaywallTabType } from "../../../domain/entities/paywall/PaywallTab";
|
|
17
18
|
import type { CreditsPackage } from "../../../domain/entities/paywall/CreditsPackage";
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
const { height: SCREEN_HEIGHT } = Dimensions.get("window");
|
|
21
|
+
|
|
22
|
+
export interface PaywallModalStyles {
|
|
23
|
+
headerTopPadding?: number;
|
|
24
|
+
contentHorizontalPadding?: number;
|
|
25
|
+
contentBottomPadding?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const DEFAULT_LAYOUT: ModalLayoutConfig = {
|
|
29
|
+
maxWidth: 480,
|
|
30
|
+
maxHeightPercent: 0.88,
|
|
31
|
+
widthPercent: 0.92,
|
|
32
|
+
borderRadius: 32,
|
|
33
|
+
backdropOpacity: 0.85,
|
|
34
|
+
horizontalPadding: 20,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const DEFAULT_STYLES: PaywallModalStyles = {
|
|
38
|
+
headerTopPadding: 48,
|
|
39
|
+
contentHorizontalPadding: 24,
|
|
40
|
+
contentBottomPadding: 32,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export interface PaywallModalProps {
|
|
20
44
|
visible: boolean;
|
|
21
45
|
onClose: () => void;
|
|
22
46
|
initialTab?: PaywallTabType;
|
|
@@ -36,32 +60,40 @@ interface PaywallModalProps {
|
|
|
36
60
|
privacyText?: string;
|
|
37
61
|
termsOfServiceText?: string;
|
|
38
62
|
restoreButtonText?: string;
|
|
63
|
+
layoutConfig?: ModalLayoutConfig;
|
|
64
|
+
styleConfig?: PaywallModalStyles;
|
|
39
65
|
}
|
|
40
66
|
|
|
41
67
|
export const PaywallModal: React.FC<PaywallModalProps> = React.memo(
|
|
42
|
-
({
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
(props) => {
|
|
69
|
+
const {
|
|
70
|
+
visible,
|
|
71
|
+
onClose,
|
|
72
|
+
initialTab = "credits",
|
|
73
|
+
creditsPackages,
|
|
74
|
+
subscriptionPackages,
|
|
75
|
+
currentCredits,
|
|
76
|
+
requiredCredits,
|
|
77
|
+
onCreditsPurchase,
|
|
78
|
+
onSubscriptionPurchase,
|
|
79
|
+
onRestore,
|
|
80
|
+
subscriptionFeatures = [],
|
|
81
|
+
isLoading = false,
|
|
82
|
+
title,
|
|
83
|
+
subtitle,
|
|
84
|
+
privacyUrl,
|
|
85
|
+
termsUrl,
|
|
86
|
+
privacyText,
|
|
87
|
+
termsOfServiceText,
|
|
88
|
+
restoreButtonText,
|
|
89
|
+
layoutConfig,
|
|
90
|
+
styleConfig,
|
|
91
|
+
} = props;
|
|
92
|
+
|
|
63
93
|
const tokens = useAppDesignTokens();
|
|
64
94
|
const { t } = useLocalization();
|
|
95
|
+
const config = { ...DEFAULT_LAYOUT, ...layoutConfig };
|
|
96
|
+
const styles_ = { ...DEFAULT_STYLES, ...styleConfig };
|
|
65
97
|
|
|
66
98
|
const {
|
|
67
99
|
activeTab,
|
|
@@ -96,16 +128,29 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo(
|
|
|
96
128
|
animationType="fade"
|
|
97
129
|
onRequestClose={onClose}
|
|
98
130
|
>
|
|
99
|
-
<View style={styles.overlay}>
|
|
131
|
+
<View style={[styles.overlay, { paddingHorizontal: config.horizontalPadding }]}>
|
|
100
132
|
<TouchableOpacity
|
|
101
|
-
style={
|
|
133
|
+
style={[
|
|
134
|
+
styles.backdrop,
|
|
135
|
+
{ backgroundColor: `rgba(0, 0, 0, ${config.backdropOpacity ?? 0.85})` }
|
|
136
|
+
]}
|
|
102
137
|
activeOpacity={1}
|
|
103
138
|
onPress={onClose}
|
|
104
139
|
/>
|
|
105
140
|
<View
|
|
106
|
-
style={[
|
|
141
|
+
style={[
|
|
142
|
+
styles.content,
|
|
143
|
+
{
|
|
144
|
+
backgroundColor: tokens.colors.surface,
|
|
145
|
+
borderRadius: config.borderRadius ?? 32,
|
|
146
|
+
maxHeight: SCREEN_HEIGHT * (config.maxHeightPercent ?? 0.88),
|
|
147
|
+
height: SCREEN_HEIGHT * (config.maxHeightPercent ?? 0.88), // Explicit height to prevent collapse
|
|
148
|
+
width: `${(config.widthPercent ?? 0.92) * 100}%`,
|
|
149
|
+
maxWidth: config.maxWidth ?? 480,
|
|
150
|
+
}
|
|
151
|
+
]}
|
|
107
152
|
>
|
|
108
|
-
<View style={styles.contentInner}>
|
|
153
|
+
<View style={[styles.contentInner, { paddingTop: styles_.headerTopPadding }]}>
|
|
109
154
|
<PaywallHeader
|
|
110
155
|
title={displayTitle}
|
|
111
156
|
subtitle={displaySubtitle}
|
|
@@ -120,34 +165,36 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo(
|
|
|
120
165
|
subscriptionLabel={t("paywall.tabs.subscription", { defaultValue: "Subscription" })}
|
|
121
166
|
/>
|
|
122
167
|
|
|
123
|
-
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
168
|
+
<View style={{ flex: 1 }}>
|
|
169
|
+
{activeTab === "credits" ? (
|
|
170
|
+
<CreditsTabContent
|
|
171
|
+
packages={creditsPackages}
|
|
172
|
+
selectedPackageId={selectedCreditsPackageId}
|
|
173
|
+
onSelectPackage={handleCreditsPackageSelect}
|
|
174
|
+
onPurchase={handleCreditsPurchase}
|
|
175
|
+
currentCredits={currentCredits}
|
|
176
|
+
requiredCredits={requiredCredits}
|
|
177
|
+
isLoading={isLoading}
|
|
178
|
+
purchaseButtonText={t("paywall.purchase", { defaultValue: "Purchase" })}
|
|
179
|
+
/>
|
|
180
|
+
) : (
|
|
181
|
+
<SubscriptionTabContent
|
|
182
|
+
packages={subscriptionPackages}
|
|
183
|
+
selectedPackage={selectedSubscriptionPkg}
|
|
184
|
+
onSelectPackage={handleSubscriptionPackageSelect}
|
|
185
|
+
onPurchase={handleSubscriptionPurchase}
|
|
186
|
+
features={subscriptionFeatures}
|
|
187
|
+
isLoading={isLoading}
|
|
188
|
+
purchaseButtonText={t("paywall.subscribe", { defaultValue: "Subscribe" })}
|
|
189
|
+
onRestore={onRestore}
|
|
190
|
+
privacyUrl={privacyUrl}
|
|
191
|
+
termsUrl={termsUrl}
|
|
192
|
+
privacyText={privacyText}
|
|
193
|
+
termsOfServiceText={termsOfServiceText}
|
|
194
|
+
restoreButtonText={restoreButtonText}
|
|
195
|
+
/>
|
|
196
|
+
)}
|
|
197
|
+
</View>
|
|
151
198
|
</View>
|
|
152
199
|
</View>
|
|
153
200
|
</View>
|
|
@@ -163,24 +210,17 @@ const styles = StyleSheet.create({
|
|
|
163
210
|
flex: 1,
|
|
164
211
|
justifyContent: "center",
|
|
165
212
|
alignItems: "center",
|
|
166
|
-
paddingHorizontal: 20,
|
|
167
213
|
},
|
|
168
214
|
backdrop: {
|
|
169
215
|
...StyleSheet.absoluteFillObject,
|
|
170
|
-
backgroundColor: "rgba(0, 0, 0, 0.85)",
|
|
171
216
|
},
|
|
172
217
|
content: {
|
|
173
|
-
borderRadius: 32,
|
|
174
|
-
maxHeight: "88%",
|
|
175
|
-
width: "92%",
|
|
176
|
-
maxWidth: 480,
|
|
177
218
|
overflow: "hidden",
|
|
178
219
|
borderWidth: 1,
|
|
179
220
|
borderColor: "rgba(255, 255, 255, 0.08)",
|
|
180
221
|
},
|
|
181
222
|
contentInner: {
|
|
182
223
|
flex: 1,
|
|
183
|
-
paddingTop: 20,
|
|
184
224
|
paddingBottom: 20,
|
|
185
225
|
},
|
|
186
226
|
});
|
|
@@ -60,6 +60,7 @@ export const SubscriptionModalOverlay: React.FC<SubscriptionModalOverlayProps> =
|
|
|
60
60
|
variant,
|
|
61
61
|
visible,
|
|
62
62
|
layoutConfig: config,
|
|
63
|
+
screenHeight: SCREEN_HEIGHT,
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -67,7 +68,8 @@ export const SubscriptionModalOverlay: React.FC<SubscriptionModalOverlayProps> =
|
|
|
67
68
|
|
|
68
69
|
const getFullscreenContentStyle = (): ViewStyle => ({
|
|
69
70
|
width: Math.min(SCREEN_WIDTH * (config.widthPercent ?? 0.92), config.maxWidth ?? 480),
|
|
70
|
-
|
|
71
|
+
// Fullscreen varyantı için yüksekliği sabitleyelim ki ScrollView çökmesin
|
|
72
|
+
height: SCREEN_HEIGHT * (config.maxHeightPercent ?? 0.88),
|
|
71
73
|
borderRadius: config.borderRadius ?? 32,
|
|
72
74
|
overflow: "hidden",
|
|
73
75
|
borderWidth: 1,
|