@umituz/react-native-subscription 2.37.47 → 2.37.49
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 +1 -1
- package/src/domains/credits/application/creditDocumentHelpers.ts +2 -2
- package/src/domains/paywall/components/PaywallContainer.tsx +0 -1
- package/src/domains/subscription/core/SubscriptionConstants.ts +0 -1
- package/src/domains/subscription/infrastructure/utils/renewal/PackageTierComparator.ts +0 -1
- package/src/domains/subscription/presentation/components/details/PremiumDetailsCard.tsx +3 -10
- package/src/domains/subscription/presentation/components/details/PremiumDetailsCardHeader.tsx +2 -1
- package/src/domains/subscription/presentation/components/details/PremiumDetailsCardTypes.ts +0 -2
- package/src/domains/subscription/presentation/components/sections/SubscriptionSection.tsx +0 -3
- package/src/domains/subscription/presentation/screens/SubscriptionDetailScreen.tsx +0 -1
- package/src/domains/subscription/presentation/screens/SubscriptionDetailScreen.types.ts +3 -3
- package/src/domains/subscription/presentation/screens/components/SubscriptionHeader.tsx +0 -2
- package/src/domains/subscription/presentation/screens/components/SubscriptionHeader.types.ts +3 -3
- package/src/domains/subscription/presentation/screens/components/SubscriptionHeaderContent.tsx +87 -94
- package/src/utils/packageTypeDetector.ts +0 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-subscription",
|
|
3
|
-
"version": "2.37.
|
|
3
|
+
"version": "2.37.49",
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import type { UserCreditsDocumentRead } from "../core/UserCreditsDocument";
|
|
1
|
+
import type { UserCreditsDocumentRead, FirestoreTimestamp } from "../core/UserCreditsDocument";
|
|
2
2
|
import { serverTimestamp, type DocumentSnapshot } from "@umituz/react-native-firebase";
|
|
3
3
|
import { SUBSCRIPTION_STATUS, type Platform } from "../../subscription/core/SubscriptionConstants";
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ export function getCreditDocumentOrDefault(
|
|
|
10
10
|
return creditsDoc.data() as UserCreditsDocumentRead;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const now = serverTimestamp() as
|
|
13
|
+
const now = serverTimestamp() as unknown as FirestoreTimestamp;
|
|
14
14
|
|
|
15
15
|
const defaultDocument: UserCreditsDocumentRead = {
|
|
16
16
|
credits: 0,
|
|
@@ -43,7 +43,6 @@ export const PaywallContainer: React.FC<PaywallContainerProps> = (props) => {
|
|
|
43
43
|
}, [providedCreditAmounts, packageAllocations, packages]);
|
|
44
44
|
|
|
45
45
|
// When using credit system, only show packages that have a credit allocation.
|
|
46
|
-
// This filters out lifetime/"unlimited" plans that aren't part of the credit model.
|
|
47
46
|
const displayPackages = useMemo(() => {
|
|
48
47
|
if (!creditAmounts || Object.keys(creditAmounts).length === 0) return packages;
|
|
49
48
|
return packages.filter((pkg) => creditAmounts[pkg.product.identifier] != null);
|
|
@@ -16,7 +16,6 @@ export const PremiumDetailsCard: React.FC<PremiumDetailsCardProps> = ({
|
|
|
16
16
|
isPremium,
|
|
17
17
|
expirationDate,
|
|
18
18
|
purchaseDate,
|
|
19
|
-
isLifetime = false,
|
|
20
19
|
daysRemaining,
|
|
21
20
|
credits,
|
|
22
21
|
translations,
|
|
@@ -33,16 +32,10 @@ export const PremiumDetailsCard: React.FC<PremiumDetailsCardProps> = ({
|
|
|
33
32
|
|
|
34
33
|
{isPremium && (
|
|
35
34
|
<View style={styles.detailsSection}>
|
|
36
|
-
{
|
|
37
|
-
<DetailRow label={translations.
|
|
38
|
-
) : (
|
|
39
|
-
<>
|
|
40
|
-
{expirationDate && (
|
|
41
|
-
<DetailRow label={translations.expiresLabel} value={expirationDate} highlight={shouldHighlightExpiration(daysRemaining)} />
|
|
42
|
-
)}
|
|
43
|
-
{purchaseDate && <DetailRow label={translations.purchasedLabel} value={purchaseDate} />}
|
|
44
|
-
</>
|
|
35
|
+
{expirationDate && (
|
|
36
|
+
<DetailRow label={translations.expiresLabel} value={expirationDate} highlight={shouldHighlightExpiration(daysRemaining)} />
|
|
45
37
|
)}
|
|
38
|
+
{purchaseDate && <DetailRow label={translations.purchasedLabel} value={purchaseDate} />}
|
|
46
39
|
</View>
|
|
47
40
|
)}
|
|
48
41
|
|
package/src/domains/subscription/presentation/components/details/PremiumDetailsCardHeader.tsx
CHANGED
|
@@ -3,10 +3,11 @@ import { View } from "react-native";
|
|
|
3
3
|
import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
|
|
4
4
|
import { PremiumStatusBadge } from "./PremiumStatusBadge";
|
|
5
5
|
import { styles } from "./PremiumDetailsCard.styles";
|
|
6
|
+
import type { SubscriptionStatusType } from "../../../core/SubscriptionConstants";
|
|
6
7
|
import type { PremiumDetailsTranslations } from "./PremiumDetailsCardTypes";
|
|
7
8
|
|
|
8
9
|
interface PremiumDetailsCardHeaderProps {
|
|
9
|
-
statusType:
|
|
10
|
+
statusType: SubscriptionStatusType;
|
|
10
11
|
translations: PremiumDetailsTranslations;
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -16,7 +16,6 @@ export interface PremiumDetailsTranslations {
|
|
|
16
16
|
remainingLabel?: string;
|
|
17
17
|
manageButton?: string;
|
|
18
18
|
upgradeButton?: string;
|
|
19
|
-
lifetimeLabel?: string;
|
|
20
19
|
statusActive: string;
|
|
21
20
|
statusExpired: string;
|
|
22
21
|
statusInactive: string;
|
|
@@ -28,7 +27,6 @@ export interface PremiumDetailsCardProps {
|
|
|
28
27
|
isPremium: boolean;
|
|
29
28
|
expirationDate?: string | null;
|
|
30
29
|
purchaseDate?: string | null;
|
|
31
|
-
isLifetime?: boolean;
|
|
32
30
|
daysRemaining?: number | null;
|
|
33
31
|
credits?: CreditInfo[];
|
|
34
32
|
translations: PremiumDetailsTranslations;
|
|
@@ -23,8 +23,6 @@ export interface SubscriptionSectionConfig {
|
|
|
23
23
|
expirationDate?: string | null;
|
|
24
24
|
/** Formatted purchase date string */
|
|
25
25
|
purchaseDate?: string | null;
|
|
26
|
-
/** Whether subscription is lifetime */
|
|
27
|
-
isLifetime?: boolean;
|
|
28
26
|
/** Days remaining until expiration */
|
|
29
27
|
daysRemaining?: number | null;
|
|
30
28
|
/** Credit info array (app-specific, passed from app) */
|
|
@@ -54,7 +52,6 @@ export const SubscriptionSection: React.FC<SubscriptionSectionProps> = ({
|
|
|
54
52
|
isPremium={config.isPremium}
|
|
55
53
|
expirationDate={config.expirationDate}
|
|
56
54
|
purchaseDate={config.purchaseDate}
|
|
57
|
-
isLifetime={config.isLifetime}
|
|
58
55
|
daysRemaining={config.daysRemaining}
|
|
59
56
|
credits={config.credits}
|
|
60
57
|
translations={config.translations}
|
|
@@ -45,7 +45,6 @@ export const SubscriptionDetailScreen: React.FC<SubscriptionDetailScreenProps> =
|
|
|
45
45
|
<SubscriptionHeader
|
|
46
46
|
statusType={config.statusType}
|
|
47
47
|
showExpirationDate={showExpirationDate}
|
|
48
|
-
isLifetime={config.isLifetime}
|
|
49
48
|
expirationDate={config.expirationDate}
|
|
50
49
|
purchaseDate={config.purchaseDate}
|
|
51
50
|
daysRemaining={config.daysRemaining}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { SubscriptionStatusType } from "../../core/SubscriptionConstants";
|
|
2
|
+
|
|
1
3
|
export interface SubscriptionDisplayFlags {
|
|
2
4
|
showHeader: boolean;
|
|
3
5
|
showCredits: boolean;
|
|
@@ -12,7 +14,6 @@ export interface SubscriptionDetailTranslations {
|
|
|
12
14
|
statusFree: string;
|
|
13
15
|
statusCanceled: string;
|
|
14
16
|
statusLabel: string;
|
|
15
|
-
lifetimeLabel: string;
|
|
16
17
|
expiresLabel: string;
|
|
17
18
|
purchasedLabel: string;
|
|
18
19
|
usageTitle?: string;
|
|
@@ -48,8 +49,7 @@ export interface CreditInfo {
|
|
|
48
49
|
|
|
49
50
|
export interface SubscriptionDetailConfig {
|
|
50
51
|
display: SubscriptionDisplayFlags;
|
|
51
|
-
statusType:
|
|
52
|
-
isLifetime: boolean;
|
|
52
|
+
statusType: SubscriptionStatusType;
|
|
53
53
|
expirationDate?: string;
|
|
54
54
|
purchaseDate?: string;
|
|
55
55
|
daysRemaining?: number | null;
|
|
@@ -10,7 +10,6 @@ import { SubscriptionHeaderContent } from "./SubscriptionHeaderContent";
|
|
|
10
10
|
export const SubscriptionHeader: React.FC<SubscriptionHeaderProps> = ({
|
|
11
11
|
statusType,
|
|
12
12
|
showExpirationDate,
|
|
13
|
-
isLifetime,
|
|
14
13
|
expirationDate,
|
|
15
14
|
purchaseDate,
|
|
16
15
|
daysRemaining,
|
|
@@ -49,7 +48,6 @@ export const SubscriptionHeader: React.FC<SubscriptionHeaderProps> = ({
|
|
|
49
48
|
</View>
|
|
50
49
|
|
|
51
50
|
<SubscriptionHeaderContent
|
|
52
|
-
isLifetime={isLifetime}
|
|
53
51
|
showExpirationDate={showExpirationDate}
|
|
54
52
|
expirationDate={expirationDate}
|
|
55
53
|
purchaseDate={purchaseDate}
|
package/src/domains/subscription/presentation/screens/components/SubscriptionHeader.types.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { SubscriptionStatusType } from "../../../core/SubscriptionConstants";
|
|
2
|
+
|
|
1
3
|
export interface SubscriptionHeaderProps {
|
|
2
|
-
statusType:
|
|
4
|
+
statusType: SubscriptionStatusType;
|
|
3
5
|
showExpirationDate: boolean;
|
|
4
|
-
isLifetime: boolean;
|
|
5
6
|
expirationDate?: string;
|
|
6
7
|
purchaseDate?: string;
|
|
7
8
|
daysRemaining?: number | null;
|
|
@@ -13,7 +14,6 @@ export interface SubscriptionHeaderProps {
|
|
|
13
14
|
statusFree: string;
|
|
14
15
|
statusCanceled: string;
|
|
15
16
|
statusLabel: string;
|
|
16
|
-
lifetimeLabel: string;
|
|
17
17
|
expiresLabel: string;
|
|
18
18
|
purchasedLabel: string;
|
|
19
19
|
willRenewLabel?: string;
|
package/src/domains/subscription/presentation/screens/components/SubscriptionHeaderContent.tsx
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { View } from "react-native";
|
|
2
|
+
import { View, type ViewStyle, type TextStyle } from "react-native";
|
|
3
3
|
import { DetailRow } from "../../components/details/DetailRow";
|
|
4
4
|
import type { SubscriptionHeaderProps } from "./SubscriptionHeader.types";
|
|
5
5
|
import { formatPackageTypeForDisplay } from "../../../../subscription/utils/packageTypeFormatter";
|
|
6
6
|
|
|
7
|
+
interface SubscriptionHeaderContentStyles {
|
|
8
|
+
details: ViewStyle;
|
|
9
|
+
row: ViewStyle;
|
|
10
|
+
label: TextStyle;
|
|
11
|
+
value: TextStyle;
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
interface SubscriptionHeaderContentProps {
|
|
8
|
-
isLifetime: boolean;
|
|
9
15
|
showExpirationDate: boolean;
|
|
10
16
|
expirationDate?: string;
|
|
11
17
|
purchaseDate?: string;
|
|
12
18
|
showExpiring: boolean;
|
|
13
19
|
translations: SubscriptionHeaderProps["translations"];
|
|
14
|
-
styles:
|
|
20
|
+
styles: SubscriptionHeaderContentStyles;
|
|
15
21
|
willRenew?: boolean | null;
|
|
16
22
|
periodType?: string | null;
|
|
17
23
|
packageType?: string | null;
|
|
@@ -23,7 +29,6 @@ interface SubscriptionHeaderContentProps {
|
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
export const SubscriptionHeaderContent: React.FC<SubscriptionHeaderContentProps> = ({
|
|
26
|
-
isLifetime,
|
|
27
32
|
showExpirationDate,
|
|
28
33
|
expirationDate,
|
|
29
34
|
purchaseDate,
|
|
@@ -40,101 +45,89 @@ export const SubscriptionHeaderContent: React.FC<SubscriptionHeaderContentProps>
|
|
|
40
45
|
isSandbox,
|
|
41
46
|
}) => (
|
|
42
47
|
<View style={styles.details}>
|
|
43
|
-
{
|
|
48
|
+
{showExpirationDate && expirationDate && (
|
|
49
|
+
<DetailRow
|
|
50
|
+
label={translations.expiresLabel}
|
|
51
|
+
value={expirationDate}
|
|
52
|
+
highlight={showExpiring}
|
|
53
|
+
style={styles.row}
|
|
54
|
+
labelStyle={styles.label}
|
|
55
|
+
valueStyle={styles.value}
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
{purchaseDate && (
|
|
59
|
+
<DetailRow
|
|
60
|
+
label={translations.purchasedLabel}
|
|
61
|
+
value={purchaseDate}
|
|
62
|
+
style={styles.row}
|
|
63
|
+
labelStyle={styles.label}
|
|
64
|
+
valueStyle={styles.value}
|
|
65
|
+
/>
|
|
66
|
+
)}
|
|
67
|
+
{willRenew !== null && willRenew !== undefined && translations.willRenewLabel && (
|
|
68
|
+
<DetailRow
|
|
69
|
+
label={translations.willRenewLabel}
|
|
70
|
+
value={willRenew ? "Yes" : "No"}
|
|
71
|
+
highlight={!willRenew}
|
|
72
|
+
style={styles.row}
|
|
73
|
+
labelStyle={styles.label}
|
|
74
|
+
valueStyle={styles.value}
|
|
75
|
+
/>
|
|
76
|
+
)}
|
|
77
|
+
{packageType && translations.periodTypeLabel && (
|
|
78
|
+
<DetailRow
|
|
79
|
+
label={translations.periodTypeLabel}
|
|
80
|
+
value={formatPackageTypeForDisplay(packageType)}
|
|
81
|
+
style={styles.row}
|
|
82
|
+
labelStyle={styles.label}
|
|
83
|
+
valueStyle={styles.value}
|
|
84
|
+
/>
|
|
85
|
+
)}
|
|
86
|
+
{store && translations.storeLabel && (
|
|
87
|
+
<DetailRow
|
|
88
|
+
label={translations.storeLabel}
|
|
89
|
+
value={store}
|
|
90
|
+
style={styles.row}
|
|
91
|
+
labelStyle={styles.label}
|
|
92
|
+
valueStyle={styles.value}
|
|
93
|
+
/>
|
|
94
|
+
)}
|
|
95
|
+
{originalPurchaseDate && translations.originalPurchaseDateLabel && (
|
|
96
|
+
<DetailRow
|
|
97
|
+
label={translations.originalPurchaseDateLabel}
|
|
98
|
+
value={originalPurchaseDate}
|
|
99
|
+
style={styles.row}
|
|
100
|
+
labelStyle={styles.label}
|
|
101
|
+
valueStyle={styles.value}
|
|
102
|
+
/>
|
|
103
|
+
)}
|
|
104
|
+
{latestPurchaseDate && translations.latestPurchaseDateLabel && (
|
|
105
|
+
<DetailRow
|
|
106
|
+
label={translations.latestPurchaseDateLabel}
|
|
107
|
+
value={latestPurchaseDate}
|
|
108
|
+
style={styles.row}
|
|
109
|
+
labelStyle={styles.label}
|
|
110
|
+
valueStyle={styles.value}
|
|
111
|
+
/>
|
|
112
|
+
)}
|
|
113
|
+
{billingIssuesDetected && translations.billingIssuesLabel && (
|
|
114
|
+
<DetailRow
|
|
115
|
+
label={translations.billingIssuesLabel}
|
|
116
|
+
value="Detected"
|
|
117
|
+
highlight={true}
|
|
118
|
+
style={styles.row}
|
|
119
|
+
labelStyle={styles.label}
|
|
120
|
+
valueStyle={styles.value}
|
|
121
|
+
/>
|
|
122
|
+
)}
|
|
123
|
+
{typeof __DEV__ !== 'undefined' && __DEV__ && isSandbox && translations.sandboxLabel && (
|
|
44
124
|
<DetailRow
|
|
45
|
-
label={translations.
|
|
46
|
-
value=
|
|
125
|
+
label={translations.sandboxLabel}
|
|
126
|
+
value="Test Mode"
|
|
47
127
|
style={styles.row}
|
|
48
128
|
labelStyle={styles.label}
|
|
49
129
|
valueStyle={styles.value}
|
|
50
130
|
/>
|
|
51
|
-
) : (
|
|
52
|
-
<>
|
|
53
|
-
{showExpirationDate && expirationDate && (
|
|
54
|
-
<DetailRow
|
|
55
|
-
label={translations.expiresLabel}
|
|
56
|
-
value={expirationDate}
|
|
57
|
-
highlight={showExpiring}
|
|
58
|
-
style={styles.row}
|
|
59
|
-
labelStyle={styles.label}
|
|
60
|
-
valueStyle={styles.value}
|
|
61
|
-
/>
|
|
62
|
-
)}
|
|
63
|
-
{purchaseDate && (
|
|
64
|
-
<DetailRow
|
|
65
|
-
label={translations.purchasedLabel}
|
|
66
|
-
value={purchaseDate}
|
|
67
|
-
style={styles.row}
|
|
68
|
-
labelStyle={styles.label}
|
|
69
|
-
valueStyle={styles.value}
|
|
70
|
-
/>
|
|
71
|
-
)}
|
|
72
|
-
{willRenew !== null && willRenew !== undefined && translations.willRenewLabel && (
|
|
73
|
-
<DetailRow
|
|
74
|
-
label={translations.willRenewLabel}
|
|
75
|
-
value={willRenew ? "Yes" : "No"}
|
|
76
|
-
highlight={!willRenew}
|
|
77
|
-
style={styles.row}
|
|
78
|
-
labelStyle={styles.label}
|
|
79
|
-
valueStyle={styles.value}
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
82
|
-
{packageType && translations.periodTypeLabel && (
|
|
83
|
-
<DetailRow
|
|
84
|
-
label={translations.periodTypeLabel}
|
|
85
|
-
value={formatPackageTypeForDisplay(packageType)}
|
|
86
|
-
style={styles.row}
|
|
87
|
-
labelStyle={styles.label}
|
|
88
|
-
valueStyle={styles.value}
|
|
89
|
-
/>
|
|
90
|
-
)}
|
|
91
|
-
{store && translations.storeLabel && (
|
|
92
|
-
<DetailRow
|
|
93
|
-
label={translations.storeLabel}
|
|
94
|
-
value={store}
|
|
95
|
-
style={styles.row}
|
|
96
|
-
labelStyle={styles.label}
|
|
97
|
-
valueStyle={styles.value}
|
|
98
|
-
/>
|
|
99
|
-
)}
|
|
100
|
-
{originalPurchaseDate && translations.originalPurchaseDateLabel && (
|
|
101
|
-
<DetailRow
|
|
102
|
-
label={translations.originalPurchaseDateLabel}
|
|
103
|
-
value={originalPurchaseDate}
|
|
104
|
-
style={styles.row}
|
|
105
|
-
labelStyle={styles.label}
|
|
106
|
-
valueStyle={styles.value}
|
|
107
|
-
/>
|
|
108
|
-
)}
|
|
109
|
-
{latestPurchaseDate && translations.latestPurchaseDateLabel && (
|
|
110
|
-
<DetailRow
|
|
111
|
-
label={translations.latestPurchaseDateLabel}
|
|
112
|
-
value={latestPurchaseDate}
|
|
113
|
-
style={styles.row}
|
|
114
|
-
labelStyle={styles.label}
|
|
115
|
-
valueStyle={styles.value}
|
|
116
|
-
/>
|
|
117
|
-
)}
|
|
118
|
-
{billingIssuesDetected && translations.billingIssuesLabel && (
|
|
119
|
-
<DetailRow
|
|
120
|
-
label={translations.billingIssuesLabel}
|
|
121
|
-
value="Detected"
|
|
122
|
-
highlight={true}
|
|
123
|
-
style={styles.row}
|
|
124
|
-
labelStyle={styles.label}
|
|
125
|
-
valueStyle={styles.value}
|
|
126
|
-
/>
|
|
127
|
-
)}
|
|
128
|
-
{typeof __DEV__ !== 'undefined' && __DEV__ && isSandbox && translations.sandboxLabel && (
|
|
129
|
-
<DetailRow
|
|
130
|
-
label={translations.sandboxLabel}
|
|
131
|
-
value="Test Mode"
|
|
132
|
-
style={styles.row}
|
|
133
|
-
labelStyle={styles.label}
|
|
134
|
-
valueStyle={styles.value}
|
|
135
|
-
/>
|
|
136
|
-
)}
|
|
137
|
-
</>
|
|
138
131
|
)}
|
|
139
132
|
</View>
|
|
140
133
|
);
|
|
@@ -30,9 +30,5 @@ export function detectPackageType(productIdentifier: string): SubscriptionPackag
|
|
|
30
30
|
return PACKAGE_TYPE.YEARLY;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
if (/\blifetime\b|_lifetime_|-lifetime-|\.lifetime\./i.test(normalized)) {
|
|
34
|
-
return PACKAGE_TYPE.LIFETIME;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
33
|
return PACKAGE_TYPE.UNKNOWN;
|
|
38
34
|
}
|