@umituz/react-native-subscription 2.24.12 → 2.24.14
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.24.
|
|
3
|
+
"version": "2.24.14",
|
|
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",
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Paywall Hooks Index
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export { usePaywall } from
|
|
6
|
-
export { useSubscriptionModal } from
|
|
5
|
+
export { usePaywall } from './usePaywall';
|
|
6
|
+
export { useSubscriptionModal } from './useSubscriptionModal';
|
|
7
|
+
export { usePaywallActions } from './usePaywallActions';
|
|
7
8
|
export {
|
|
8
9
|
usePaywallTranslations,
|
|
9
10
|
type UsePaywallTranslationsParams,
|
|
10
11
|
type UsePaywallTranslationsResult,
|
|
11
|
-
} from
|
|
12
|
+
} from './usePaywallTranslations';
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
TextInput,
|
|
13
13
|
KeyboardAvoidingView,
|
|
14
14
|
} from "react-native";
|
|
15
|
-
import { AtomicText } from "@umituz/react-native-design-system";
|
|
15
|
+
import { AtomicText, BaseModal } from "@umituz/react-native-design-system";
|
|
16
16
|
import { useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
17
17
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
18
18
|
import { usePaywallFeedback } from "../../hooks/feedback/usePaywallFeedback";
|
|
@@ -54,7 +54,7 @@ export const PaywallFeedbackModal: React.FC<PaywallFeedbackModalProps> = React.m
|
|
|
54
54
|
setOtherText,
|
|
55
55
|
selectReason,
|
|
56
56
|
handleSubmit,
|
|
57
|
-
handleSkip,
|
|
57
|
+
handleSkip, // BaseModal's onClose will handle skipping
|
|
58
58
|
canSubmit,
|
|
59
59
|
} = usePaywallFeedback({ onSubmit, onClose });
|
|
60
60
|
|
|
@@ -68,101 +68,111 @@ export const PaywallFeedbackModal: React.FC<PaywallFeedbackModalProps> = React.m
|
|
|
68
68
|
const displaySubmitText = submitText || t("paywall.feedback.submit");
|
|
69
69
|
const displayOtherPlaceholder = otherPlaceholder || t("paywall.feedback.otherPlaceholder");
|
|
70
70
|
|
|
71
|
+
// BaseModal from design system handles animations, safe areas, keyboard avoiding, and overlay backdrop
|
|
71
72
|
return (
|
|
72
|
-
<
|
|
73
|
+
<BaseModal
|
|
73
74
|
visible={visible}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
onClose={handleSkip}
|
|
76
|
+
title={displayTitle}
|
|
77
|
+
swipeToClose={true}
|
|
77
78
|
>
|
|
78
|
-
<
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
>
|
|
83
|
-
<Pressable onPress={(e) => e.stopPropagation()}>
|
|
84
|
-
<View style={styles.container}>
|
|
85
|
-
<View style={styles.header}>
|
|
86
|
-
<AtomicText type="headlineMedium" style={styles.title}>
|
|
87
|
-
{displayTitle}
|
|
88
|
-
</AtomicText>
|
|
89
|
-
<AtomicText type="bodyMedium" style={styles.subtitle}>
|
|
90
|
-
{displaySubtitle}
|
|
91
|
-
</AtomicText>
|
|
92
|
-
</View>
|
|
93
|
-
|
|
94
|
-
<View style={styles.optionsContainer}>
|
|
95
|
-
{FEEDBACK_OPTION_IDS.map((optionId, index) => {
|
|
96
|
-
const isSelected = selectedReason === optionId;
|
|
97
|
-
const isLast = index === FEEDBACK_OPTION_IDS.length - 1;
|
|
98
|
-
const displayText = t(`paywall.feedback.reasons.${optionId}`);
|
|
99
|
-
|
|
100
|
-
return (
|
|
101
|
-
<View key={optionId}>
|
|
102
|
-
<TouchableOpacity
|
|
103
|
-
style={[
|
|
104
|
-
styles.optionRow,
|
|
105
|
-
isLast && styles.optionRowLast,
|
|
106
|
-
]}
|
|
107
|
-
onPress={() => selectReason(optionId)}
|
|
108
|
-
activeOpacity={0.7}
|
|
109
|
-
>
|
|
110
|
-
<AtomicText
|
|
111
|
-
type="bodyMedium"
|
|
112
|
-
style={[
|
|
113
|
-
styles.optionText,
|
|
114
|
-
isSelected && styles.optionTextSelected,
|
|
115
|
-
]}
|
|
116
|
-
>
|
|
117
|
-
{displayText}
|
|
118
|
-
</AtomicText>
|
|
79
|
+
<View style={{ paddingBottom: tokens.spacing.lg }}>
|
|
80
|
+
<AtomicText type="bodyMedium" style={[styles.subtitle, { marginBottom: tokens.spacing.md }]}>
|
|
81
|
+
{displaySubtitle}
|
|
82
|
+
</AtomicText>
|
|
119
83
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
<TextInput
|
|
135
|
-
style={styles.textInput}
|
|
136
|
-
placeholder={displayOtherPlaceholder}
|
|
137
|
-
placeholderTextColor={tokens.colors.textTertiary}
|
|
138
|
-
multiline
|
|
139
|
-
maxLength={200}
|
|
140
|
-
value={otherText}
|
|
141
|
-
onChangeText={setOtherText}
|
|
142
|
-
autoFocus
|
|
143
|
-
/>
|
|
144
|
-
</View>
|
|
145
|
-
)}
|
|
146
|
-
</View>
|
|
147
|
-
);
|
|
148
|
-
})}
|
|
149
|
-
</View>
|
|
84
|
+
<View style={[styles.optionsContainer, { backgroundColor: 'transparent', padding: 0 }]}>
|
|
85
|
+
{FEEDBACK_OPTION_IDS.map((optionId, index) => {
|
|
86
|
+
const isSelected = selectedReason === optionId;
|
|
87
|
+
const isOther = optionId === "other";
|
|
88
|
+
const showInput = isSelected && isOther;
|
|
89
|
+
const displayText = t(`paywall.feedback.reasons.${optionId}`);
|
|
90
|
+
|
|
91
|
+
// Dynamic styles for the container
|
|
92
|
+
const containerStyle = {
|
|
93
|
+
marginBottom: tokens.spacing.sm,
|
|
94
|
+
backgroundColor: tokens.colors.surfaceVariant,
|
|
95
|
+
borderRadius: tokens.borderRadius.md,
|
|
96
|
+
overflow: 'hidden' as const, // Ensure children don't bleed out
|
|
97
|
+
};
|
|
150
98
|
|
|
99
|
+
return (
|
|
100
|
+
<View key={optionId} style={containerStyle}>
|
|
151
101
|
<TouchableOpacity
|
|
152
|
-
style={
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
102
|
+
style={{
|
|
103
|
+
borderBottomWidth: showInput ? 1 : 0,
|
|
104
|
+
borderBottomColor: tokens.colors.surface, // Subtle separator
|
|
105
|
+
paddingVertical: tokens.spacing.md,
|
|
106
|
+
paddingHorizontal: tokens.spacing.md,
|
|
107
|
+
flexDirection: 'row',
|
|
108
|
+
alignItems: 'center',
|
|
109
|
+
justifyContent: 'space-between',
|
|
110
|
+
}}
|
|
111
|
+
onPress={() => selectReason(optionId)}
|
|
112
|
+
activeOpacity={0.7}
|
|
156
113
|
>
|
|
157
|
-
<AtomicText
|
|
158
|
-
|
|
114
|
+
<AtomicText
|
|
115
|
+
type="bodyMedium"
|
|
116
|
+
style={[
|
|
117
|
+
styles.optionText,
|
|
118
|
+
isSelected && { color: tokens.colors.primary, fontWeight: '600' },
|
|
119
|
+
]}
|
|
120
|
+
>
|
|
121
|
+
{displayText}
|
|
159
122
|
</AtomicText>
|
|
123
|
+
|
|
124
|
+
<View
|
|
125
|
+
style={[
|
|
126
|
+
styles.radioButton,
|
|
127
|
+
isSelected && styles.radioButtonSelected,
|
|
128
|
+
]}
|
|
129
|
+
>
|
|
130
|
+
{isSelected && (
|
|
131
|
+
<View style={styles.radioButtonInner} />
|
|
132
|
+
)}
|
|
133
|
+
</View>
|
|
160
134
|
</TouchableOpacity>
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
135
|
+
|
|
136
|
+
{showInput && (
|
|
137
|
+
<View style={[styles.inputContainer, { backgroundColor: 'transparent', marginTop: 0, padding: tokens.spacing.sm }]}>
|
|
138
|
+
<TextInput
|
|
139
|
+
style={[
|
|
140
|
+
styles.textInput,
|
|
141
|
+
{
|
|
142
|
+
minHeight: 80,
|
|
143
|
+
textAlignVertical: 'top',
|
|
144
|
+
backgroundColor: tokens.colors.surface, // Slightly different background for input
|
|
145
|
+
borderRadius: tokens.borderRadius.sm,
|
|
146
|
+
padding: tokens.spacing.sm,
|
|
147
|
+
}
|
|
148
|
+
]}
|
|
149
|
+
placeholder={displayOtherPlaceholder}
|
|
150
|
+
placeholderTextColor={tokens.colors.textTertiary}
|
|
151
|
+
multiline
|
|
152
|
+
maxLength={200}
|
|
153
|
+
value={otherText}
|
|
154
|
+
onChangeText={setOtherText}
|
|
155
|
+
autoFocus
|
|
156
|
+
/>
|
|
157
|
+
</View>
|
|
158
|
+
)}
|
|
159
|
+
</View>
|
|
160
|
+
);
|
|
161
|
+
})}
|
|
162
|
+
</View>
|
|
163
|
+
|
|
164
|
+
<TouchableOpacity
|
|
165
|
+
style={[styles.submitButton, { marginTop: tokens.spacing.lg }]}
|
|
166
|
+
onPress={handleSubmit}
|
|
167
|
+
disabled={!canSubmit}
|
|
168
|
+
activeOpacity={0.8}
|
|
169
|
+
>
|
|
170
|
+
<AtomicText type="labelLarge" style={styles.submitText}>
|
|
171
|
+
{displaySubmitText}
|
|
172
|
+
</AtomicText>
|
|
173
|
+
</TouchableOpacity>
|
|
174
|
+
</View>
|
|
175
|
+
</BaseModal>
|
|
166
176
|
);
|
|
167
177
|
});
|
|
168
178
|
|