@umituz/react-native-subscription 2.12.7 → 2.12.9
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.12.
|
|
3
|
+
"version": "2.12.9",
|
|
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",
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Paywall Modal
|
|
3
|
-
* Modern paywall with
|
|
3
|
+
* Modern paywall with responsive design and theme support
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import React, { useState, useCallback } from "react";
|
|
7
7
|
import { View, ScrollView, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
BaseModal,
|
|
11
|
-
useAppDesignTokens,
|
|
12
|
-
AtomicText,
|
|
13
|
-
AtomicIcon,
|
|
14
|
-
useDesignSystemTheme,
|
|
15
|
-
} from "@umituz/react-native-design-system";
|
|
8
|
+
import { BaseModal, useAppDesignTokens, AtomicText, AtomicIcon } from "@umituz/react-native-design-system";
|
|
16
9
|
import type { PurchasesPackage } from "react-native-purchases";
|
|
17
10
|
import { PlanCard } from "./PlanCard";
|
|
18
11
|
import { CreditCard } from "./CreditCard";
|
|
@@ -56,9 +49,6 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
|
|
|
56
49
|
} = props;
|
|
57
50
|
|
|
58
51
|
const tokens = useAppDesignTokens();
|
|
59
|
-
const { themeMode } = useDesignSystemTheme();
|
|
60
|
-
const isDark = themeMode === "dark";
|
|
61
|
-
|
|
62
52
|
const [selectedPlanId, setSelectedPlanId] = useState<string | null>(null);
|
|
63
53
|
const [selectedCreditId, setSelectedCreditId] = useState<string | null>(null);
|
|
64
54
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
@@ -66,10 +56,6 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
|
|
|
66
56
|
const showCredits = mode === "credits";
|
|
67
57
|
const showSubscription = mode === "subscription" || mode === "hybrid";
|
|
68
58
|
|
|
69
|
-
const gradientColors: readonly [string, string, string] = isDark
|
|
70
|
-
? ["#1e3a5f", "#2d1e3f", "#1a1a2e"]
|
|
71
|
-
: ["#4a5568", "#5a4a78", "#3a3a4a"];
|
|
72
|
-
|
|
73
59
|
const handlePurchase = useCallback(async () => {
|
|
74
60
|
setIsProcessing(true);
|
|
75
61
|
try {
|
|
@@ -98,10 +84,10 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
|
|
|
98
84
|
|
|
99
85
|
return (
|
|
100
86
|
<BaseModal visible={visible} onClose={onClose} contentStyle={styles.modalContent}>
|
|
101
|
-
<
|
|
87
|
+
<View style={[styles.container, { backgroundColor: tokens.colors.surface }]}>
|
|
102
88
|
<TouchableOpacity
|
|
103
89
|
onPress={onClose}
|
|
104
|
-
style={[styles.closeBtn, { backgroundColor: tokens.colors.
|
|
90
|
+
style={[styles.closeBtn, { backgroundColor: tokens.colors.surfaceSecondary }]}
|
|
105
91
|
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
106
92
|
>
|
|
107
93
|
<AtomicIcon name="close-outline" size="md" customColor={tokens.colors.textPrimary} />
|
|
@@ -109,24 +95,24 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
|
|
|
109
95
|
|
|
110
96
|
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.scroll}>
|
|
111
97
|
<View style={styles.header}>
|
|
112
|
-
<AtomicText type="headlineLarge" style={[styles.title, { color: tokens.colors.
|
|
98
|
+
<AtomicText type="headlineLarge" style={[styles.title, { color: tokens.colors.textPrimary }]}>
|
|
113
99
|
{translations.title}
|
|
114
100
|
</AtomicText>
|
|
115
101
|
{translations.subtitle && (
|
|
116
|
-
<AtomicText type="bodyLarge" style={[styles.subtitle, { color: tokens.colors.
|
|
102
|
+
<AtomicText type="bodyLarge" style={[styles.subtitle, { color: tokens.colors.textSecondary }]}>
|
|
117
103
|
{translations.subtitle}
|
|
118
104
|
</AtomicText>
|
|
119
105
|
)}
|
|
120
106
|
</View>
|
|
121
107
|
|
|
122
108
|
{features.length > 0 && (
|
|
123
|
-
<View style={[styles.features, { backgroundColor:
|
|
109
|
+
<View style={[styles.features, { backgroundColor: tokens.colors.surfaceSecondary }]}>
|
|
124
110
|
{features.map((feature, idx) => (
|
|
125
111
|
<View key={idx} style={styles.featureRow}>
|
|
126
112
|
<View style={[styles.featureIcon, { backgroundColor: tokens.colors.primaryLight }]}>
|
|
127
113
|
<AtomicIcon name={feature.icon} customSize={20} customColor={tokens.colors.primary} />
|
|
128
114
|
</View>
|
|
129
|
-
<AtomicText type="bodyLarge" style={[styles.featureText, { color: tokens.colors.
|
|
115
|
+
<AtomicText type="bodyLarge" style={[styles.featureText, { color: tokens.colors.textPrimary }]}>
|
|
130
116
|
{feature.text}
|
|
131
117
|
</AtomicText>
|
|
132
118
|
</View>
|
|
@@ -136,8 +122,8 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
|
|
|
136
122
|
|
|
137
123
|
{isLoading ? (
|
|
138
124
|
<View style={styles.loading}>
|
|
139
|
-
<ActivityIndicator color={tokens.colors.
|
|
140
|
-
<AtomicText type="bodyMedium" style={[styles.loadingText, { color: tokens.colors.
|
|
125
|
+
<ActivityIndicator color={tokens.colors.primary} />
|
|
126
|
+
<AtomicText type="bodyMedium" style={[styles.loadingText, { color: tokens.colors.textSecondary }]}>
|
|
141
127
|
{translations.loadingText}
|
|
142
128
|
</AtomicText>
|
|
143
129
|
</View>
|
|
@@ -176,28 +162,28 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
|
|
|
176
162
|
<View style={styles.footer}>
|
|
177
163
|
{legalUrls.termsUrl && (
|
|
178
164
|
<TouchableOpacity onPress={() => {}}>
|
|
179
|
-
<AtomicText type="bodySmall" style={[styles.footerLink, { color: tokens.colors.
|
|
165
|
+
<AtomicText type="bodySmall" style={[styles.footerLink, { color: tokens.colors.textSecondary }]}>
|
|
180
166
|
{translations.termsOfServiceText}
|
|
181
167
|
</AtomicText>
|
|
182
168
|
</TouchableOpacity>
|
|
183
169
|
)}
|
|
184
170
|
{onRestore && (
|
|
185
171
|
<TouchableOpacity onPress={handleRestore}>
|
|
186
|
-
<AtomicText type="bodySmall" style={[styles.footerLink, { color: tokens.colors.
|
|
172
|
+
<AtomicText type="bodySmall" style={[styles.footerLink, { color: tokens.colors.textSecondary }]}>
|
|
187
173
|
{translations.restoreButtonText}
|
|
188
174
|
</AtomicText>
|
|
189
175
|
</TouchableOpacity>
|
|
190
176
|
)}
|
|
191
177
|
{legalUrls.privacyUrl && (
|
|
192
178
|
<TouchableOpacity onPress={() => {}}>
|
|
193
|
-
<AtomicText type="bodySmall" style={[styles.footerLink, { color: tokens.colors.
|
|
179
|
+
<AtomicText type="bodySmall" style={[styles.footerLink, { color: tokens.colors.textSecondary }]}>
|
|
194
180
|
{translations.privacyText}
|
|
195
181
|
</AtomicText>
|
|
196
182
|
</TouchableOpacity>
|
|
197
183
|
)}
|
|
198
184
|
</View>
|
|
199
185
|
</ScrollView>
|
|
200
|
-
</
|
|
186
|
+
</View>
|
|
201
187
|
</BaseModal>
|
|
202
188
|
);
|
|
203
189
|
});
|
|
@@ -206,22 +192,22 @@ PaywallModal.displayName = "PaywallModal";
|
|
|
206
192
|
|
|
207
193
|
const styles = StyleSheet.create({
|
|
208
194
|
modalContent: { padding: 0, borderWidth: 0, overflow: "hidden" },
|
|
209
|
-
|
|
195
|
+
container: { flex: 1 },
|
|
210
196
|
closeBtn: { position: "absolute", top: 16, right: 16, width: 36, height: 36, borderRadius: 18, justifyContent: "center", alignItems: "center", zIndex: 10 },
|
|
211
|
-
scroll: { padding: 24, paddingTop: 56 },
|
|
197
|
+
scroll: { flexGrow: 1, padding: 24, paddingTop: 56 },
|
|
212
198
|
header: { alignItems: "center", marginBottom: 24 },
|
|
213
199
|
title: { fontWeight: "700", textAlign: "center", marginBottom: 8 },
|
|
214
|
-
subtitle: { textAlign: "center", lineHeight: 24
|
|
200
|
+
subtitle: { textAlign: "center", lineHeight: 24 },
|
|
215
201
|
features: { borderRadius: 16, padding: 16, marginBottom: 20, gap: 12 },
|
|
216
202
|
featureRow: { flexDirection: "row", alignItems: "center" },
|
|
217
203
|
featureIcon: { width: 40, height: 40, borderRadius: 20, justifyContent: "center", alignItems: "center", marginRight: 12 },
|
|
218
204
|
featureText: { flex: 1, fontWeight: "500" },
|
|
219
205
|
loading: { alignItems: "center", paddingVertical: 40 },
|
|
220
|
-
loadingText: { marginTop: 12
|
|
206
|
+
loadingText: { marginTop: 12 },
|
|
221
207
|
plans: { marginBottom: 20 },
|
|
222
208
|
cta: { borderRadius: 16, paddingVertical: 18, alignItems: "center", marginBottom: 16 },
|
|
223
209
|
ctaDisabled: { opacity: 0.5 },
|
|
224
210
|
ctaText: { fontWeight: "700" },
|
|
225
211
|
footer: { flexDirection: "row", justifyContent: "space-between", paddingHorizontal: 8 },
|
|
226
|
-
footerLink: {
|
|
212
|
+
footerLink: {},
|
|
227
213
|
});
|