@zezosoft/zezo-ott-react-native-ui-kit 1.0.8 → 1.0.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/README.md +1 -1
- package/lib/module/components/Account/Account.js +1 -1
- package/lib/module/components/Account/Account.js.map +1 -1
- package/lib/module/components/Auth/AuthProvider/AuthProvider.js +48 -19
- package/lib/module/components/Auth/AuthProvider/AuthProvider.js.map +1 -1
- package/lib/module/components/Auth/Login/LoginWithEmail.js +4 -2
- package/lib/module/components/Auth/Login/LoginWithEmail.js.map +1 -1
- package/lib/module/components/Auth/OTP/OTP.js +15 -1
- package/lib/module/components/Auth/OTP/OTP.js.map +1 -1
- package/lib/module/components/Auth/SignUp/SignUp.js +4 -2
- package/lib/module/components/Auth/SignUp/SignUp.js.map +1 -1
- package/lib/module/components/BlurView/BlurView.js +171 -0
- package/lib/module/components/BlurView/BlurView.js.map +1 -0
- package/lib/module/components/BlurView/index.js +9 -0
- package/lib/module/components/BlurView/index.js.map +1 -0
- package/lib/module/components/Content/Card/Styles/Four.js +1 -1
- package/lib/module/components/Content/Card/Styles/Four.js.map +1 -1
- package/lib/module/components/Content/Content.js +4 -2
- package/lib/module/components/Content/Content.js.map +1 -1
- package/lib/module/components/ContentView/ContentView.js +4 -2
- package/lib/module/components/ContentView/ContentView.js.map +1 -1
- package/lib/module/components/ContentView/components/MiniInfo.js +64 -19
- package/lib/module/components/ContentView/components/MiniInfo.js.map +1 -1
- package/lib/module/components/Settings/AppSettings.js +1 -1
- package/lib/module/components/Settings/AppSettings.js.map +1 -1
- package/lib/module/components/Subscription/SubOne.js +340 -13
- package/lib/module/components/Subscription/SubOne.js.map +1 -1
- package/lib/module/components/TabBar/One.js +71 -108
- package/lib/module/components/TabBar/One.js.map +1 -1
- package/lib/module/components/TabBar/Three.js +63 -78
- package/lib/module/components/TabBar/Three.js.map +1 -1
- package/lib/module/components/TabBar/Two.js +110 -106
- package/lib/module/components/TabBar/Two.js.map +1 -1
- package/lib/module/components/User/PurchaseHistory/PurchaseHistory.js +324 -0
- package/lib/module/components/User/PurchaseHistory/PurchaseHistory.js.map +1 -0
- package/lib/module/components/User/index.js +2 -1
- package/lib/module/components/User/index.js.map +1 -1
- package/lib/module/components/index.js +1 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/hooks/useNavigationMode.js +34 -0
- package/lib/module/hooks/useNavigationMode.js.map +1 -0
- package/lib/module/utils/Spacing.js +26 -0
- package/lib/module/utils/Spacing.js.map +1 -0
- package/lib/typescript/src/components/Auth/AuthProvider/AuthProvider.d.ts +1 -0
- package/lib/typescript/src/components/Auth/AuthProvider/AuthProvider.d.ts.map +1 -1
- package/lib/typescript/src/components/Auth/Login/LoginWithEmail.d.ts.map +1 -1
- package/lib/typescript/src/components/Auth/OTP/OTP.d.ts +2 -0
- package/lib/typescript/src/components/Auth/OTP/OTP.d.ts.map +1 -1
- package/lib/typescript/src/components/Auth/SignUp/SignUp.d.ts.map +1 -1
- package/lib/typescript/src/components/Auth/index.d.ts +2 -0
- package/lib/typescript/src/components/Auth/index.d.ts.map +1 -1
- package/lib/typescript/src/components/BlurView/BlurView.d.ts +48 -0
- package/lib/typescript/src/components/BlurView/BlurView.d.ts.map +1 -0
- package/lib/typescript/src/components/BlurView/index.d.ts +7 -0
- package/lib/typescript/src/components/BlurView/index.d.ts.map +1 -0
- package/lib/typescript/src/components/Content/Card/Styles/Four.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Content.d.ts.map +1 -1
- package/lib/typescript/src/components/ContentView/ContentView.d.ts +1 -1
- package/lib/typescript/src/components/ContentView/ContentView.d.ts.map +1 -1
- package/lib/typescript/src/components/ContentView/components/MiniInfo.d.ts +17 -1
- package/lib/typescript/src/components/ContentView/components/MiniInfo.d.ts.map +1 -1
- package/lib/typescript/src/components/Subscription/SubOne.d.ts +6 -0
- package/lib/typescript/src/components/Subscription/SubOne.d.ts.map +1 -1
- package/lib/typescript/src/components/Subscription/index.d.ts.map +1 -1
- package/lib/typescript/src/components/TabBar/One.d.ts +2 -2
- package/lib/typescript/src/components/TabBar/One.d.ts.map +1 -1
- package/lib/typescript/src/components/TabBar/Three.d.ts +3 -2
- package/lib/typescript/src/components/TabBar/Three.d.ts.map +1 -1
- package/lib/typescript/src/components/TabBar/Two.d.ts +13 -4
- package/lib/typescript/src/components/TabBar/Two.d.ts.map +1 -1
- package/lib/typescript/src/components/TabBar/index.d.ts +1 -1
- package/lib/typescript/src/components/User/PurchaseHistory/PurchaseHistory.d.ts +50 -0
- package/lib/typescript/src/components/User/PurchaseHistory/PurchaseHistory.d.ts.map +1 -0
- package/lib/typescript/src/components/User/index.d.ts +2 -1
- package/lib/typescript/src/components/User/index.d.ts.map +1 -1
- package/lib/typescript/src/components/index.d.ts +1 -0
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNavigationMode.d.ts +14 -0
- package/lib/typescript/src/hooks/useNavigationMode.d.ts.map +1 -0
- package/lib/typescript/src/types/content/content-view.types.d.ts +2 -0
- package/lib/typescript/src/types/content/content-view.types.d.ts.map +1 -1
- package/lib/typescript/src/utils/Spacing.d.ts +16 -0
- package/lib/typescript/src/utils/Spacing.d.ts.map +1 -0
- package/package.json +9 -5
- package/src/components/Account/Account.tsx +1 -1
- package/src/components/Auth/AuthProvider/AuthProvider.tsx +82 -37
- package/src/components/Auth/Login/LoginWithEmail.tsx +9 -2
- package/src/components/Auth/OTP/OTP.tsx +37 -1
- package/src/components/Auth/SignUp/SignUp.tsx +9 -2
- package/src/components/BlurView/BlurView.tsx +199 -0
- package/src/components/BlurView/index.ts +7 -0
- package/src/components/Content/Card/Styles/Four.tsx +3 -1
- package/src/components/Content/Content.tsx +5 -4
- package/src/components/ContentView/ContentView.tsx +8 -1
- package/src/components/ContentView/components/MiniInfo.tsx +99 -22
- package/src/components/Settings/AppSettings.tsx +1 -1
- package/src/components/Subscription/SubOne.tsx +422 -11
- package/src/components/TabBar/One.tsx +79 -141
- package/src/components/TabBar/Three.tsx +84 -99
- package/src/components/TabBar/Two.tsx +139 -110
- package/src/components/User/PurchaseHistory/PurchaseHistory.tsx +439 -0
- package/src/components/User/index.ts +8 -1
- package/src/components/index.ts +1 -0
- package/src/hooks/useNavigationMode.ts +35 -0
- package/src/types/content/content-view.types.ts +5 -0
- package/src/utils/Spacing.ts +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spacing.d.ts","sourceRoot":"","sources":["../../../../src/utils/Spacing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GACrC,cAAa,MAAW,KACvB,MAIF,CAAC;AAGF,eAAO,MAAM,oBAAoB,iBARlB,MAAM,KAClB,MAO2D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zezosoft/zezo-ott-react-native-ui-kit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "A professional React Native UI component library built for OTT applications.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "lib/typescript/src/index.d.ts",
|
|
@@ -85,6 +85,7 @@
|
|
|
85
85
|
"eslint-plugin-prettier": "^5.2.3",
|
|
86
86
|
"jest": "^29.7.0",
|
|
87
87
|
"lottie-react-native": "^7.3.4",
|
|
88
|
+
"moment": "^2.30.1",
|
|
88
89
|
"prettier": "^3.0.3",
|
|
89
90
|
"react": "19.0.0",
|
|
90
91
|
"react-native": "0.79.6",
|
|
@@ -97,6 +98,7 @@
|
|
|
97
98
|
"react-native-markdown-display": "^7.0.2",
|
|
98
99
|
"react-native-mmkv": "^3.3.0",
|
|
99
100
|
"react-native-modal": "^14.0.0-rc.1",
|
|
101
|
+
"react-native-navigation-mode": "^1.2.3",
|
|
100
102
|
"react-native-reanimated": "^4.1.0",
|
|
101
103
|
"react-native-safe-area-context": "^5.6.1",
|
|
102
104
|
"react-native-super-grid": "^6.0.2",
|
|
@@ -110,9 +112,10 @@
|
|
|
110
112
|
"peerDependencies": {
|
|
111
113
|
"@react-native-community/blur": "^4.4.0",
|
|
112
114
|
"@react-native-masked-view/masked-view": "^0.3.0",
|
|
113
|
-
"@react-navigation/bottom-tabs": "
|
|
114
|
-
"@react-navigation/native": "
|
|
115
|
-
"lottie-react-native": "
|
|
115
|
+
"@react-navigation/bottom-tabs": "*",
|
|
116
|
+
"@react-navigation/native": "*",
|
|
117
|
+
"lottie-react-native": "*",
|
|
118
|
+
"moment": "*",
|
|
116
119
|
"react": "*",
|
|
117
120
|
"react-native": "*",
|
|
118
121
|
"react-native-device-info": "^14.0.0",
|
|
@@ -121,6 +124,7 @@
|
|
|
121
124
|
"react-native-gesture-handler": "^2.0.0",
|
|
122
125
|
"react-native-linear-gradient": "^2.8.0",
|
|
123
126
|
"react-native-mmkv": "*",
|
|
127
|
+
"react-native-navigation-mode": "*",
|
|
124
128
|
"react-native-nitro-modules": "^0.29.0",
|
|
125
129
|
"react-native-reanimated": "*",
|
|
126
130
|
"react-native-safe-area-context": "*",
|
|
@@ -129,7 +133,7 @@
|
|
|
129
133
|
"react-native-svg": "*",
|
|
130
134
|
"react-native-video": "*",
|
|
131
135
|
"react-native-vision-camera": "*",
|
|
132
|
-
"react-native-worklets": "
|
|
136
|
+
"react-native-worklets": "*"
|
|
133
137
|
},
|
|
134
138
|
"dependencies": {
|
|
135
139
|
"color": "^5.0.0",
|
|
@@ -133,7 +133,7 @@ export const Account: React.FC<AccountProps> = ({
|
|
|
133
133
|
<ScrollView
|
|
134
134
|
contentContainerStyle={[
|
|
135
135
|
styles.content,
|
|
136
|
-
{ paddingBottom: insets.bottom
|
|
136
|
+
{ paddingBottom: verticalScale(100) + insets.bottom },
|
|
137
137
|
]}
|
|
138
138
|
showsVerticalScrollIndicator={false}
|
|
139
139
|
keyboardShouldPersistTaps="handled"
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
* @author Naresh Dhamu
|
|
3
3
|
* @lastModified Tue 22 Oct 2025
|
|
4
4
|
*/
|
|
5
|
-
import React, { useEffect, useRef, useState } from 'react';
|
|
5
|
+
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import {
|
|
7
7
|
View,
|
|
8
8
|
StyleSheet,
|
|
9
9
|
SafeAreaView,
|
|
10
10
|
TouchableOpacity,
|
|
11
11
|
Animated,
|
|
12
|
-
Platform,
|
|
13
12
|
} from 'react-native';
|
|
14
13
|
import { moderateScale, scale, verticalScale } from 'react-native-size-matters';
|
|
15
14
|
import { useInternalTheme } from '../../../theme/hook/useInternalTheme';
|
|
@@ -19,6 +18,7 @@ import { Text } from '../../Text';
|
|
|
19
18
|
import { BackgroundLayout } from '../../BackgroundLayout/BackgroundLayout';
|
|
20
19
|
import { Phone, Mail } from 'lucide-react-native';
|
|
21
20
|
import { Button } from '../../Button';
|
|
21
|
+
import { default as SkeletonPlaceholder } from 'react-native-skeleton-placeholder';
|
|
22
22
|
|
|
23
23
|
export interface AuthProviderProps {
|
|
24
24
|
logoUri: string;
|
|
@@ -35,6 +35,7 @@ export interface AuthProviderProps {
|
|
|
35
35
|
};
|
|
36
36
|
variant?: 'one' | 'two';
|
|
37
37
|
theme?: ThemeOverride;
|
|
38
|
+
isLoading?: boolean;
|
|
38
39
|
authProvider?: {
|
|
39
40
|
phone?: {
|
|
40
41
|
enabled?: boolean;
|
|
@@ -55,6 +56,7 @@ const AuthProvider: React.FC<AuthProviderProps> = ({
|
|
|
55
56
|
text,
|
|
56
57
|
variant = 'one',
|
|
57
58
|
theme: overrideTheme,
|
|
59
|
+
isLoading = false,
|
|
58
60
|
authProvider = {
|
|
59
61
|
phone: { enabled: true },
|
|
60
62
|
email: { enabled: true },
|
|
@@ -105,46 +107,70 @@ const AuthProvider: React.FC<AuthProviderProps> = ({
|
|
|
105
107
|
label: string;
|
|
106
108
|
icon: React.ReactNode;
|
|
107
109
|
enabled: boolean;
|
|
108
|
-
}[] =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
110
|
+
}[] = useMemo(
|
|
111
|
+
() => [
|
|
112
|
+
{
|
|
113
|
+
key: 'phone',
|
|
114
|
+
label: text?.loginWithPhone || 'Phone',
|
|
115
|
+
icon: <Phone size={moderateScale(16)} />,
|
|
116
|
+
enabled: phoneEnabled,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
key: 'email',
|
|
120
|
+
label: text?.loginWithEmail || 'Email',
|
|
121
|
+
icon: <Mail size={moderateScale(16)} />,
|
|
122
|
+
enabled: emailEnabled,
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
[text?.loginWithPhone, text?.loginWithEmail, phoneEnabled, emailEnabled]
|
|
126
|
+
);
|
|
122
127
|
|
|
123
128
|
const renderButtons = () => (
|
|
124
129
|
<View style={styles.buttonContainer}>
|
|
125
130
|
{authMethods
|
|
126
131
|
.filter((item) => item.enabled)
|
|
127
132
|
.map((item) => (
|
|
128
|
-
<
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
133
|
+
<React.Fragment key={item.key}>
|
|
134
|
+
{isLoading ? (
|
|
135
|
+
<SkeletonPlaceholder
|
|
136
|
+
backgroundColor={colors.skeletonBaseColor}
|
|
137
|
+
highlightColor={colors.skeletonHighlightColor}
|
|
138
|
+
borderRadius={moderateScale(8)}
|
|
139
|
+
>
|
|
140
|
+
<View
|
|
141
|
+
style={{
|
|
142
|
+
width: '100%',
|
|
143
|
+
height: verticalScale(48),
|
|
144
|
+
borderRadius: moderateScale(8),
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
</SkeletonPlaceholder>
|
|
148
|
+
) : (
|
|
149
|
+
<Button.Secondary
|
|
150
|
+
containerStyle={{
|
|
151
|
+
backgroundColor:
|
|
152
|
+
activeTab === item.key ? colors.button : 'transparent',
|
|
153
|
+
borderWidth: 1.2,
|
|
154
|
+
borderColor: colors.button,
|
|
155
|
+
}}
|
|
156
|
+
titleStyle={{
|
|
157
|
+
color:
|
|
158
|
+
activeTab === item.key
|
|
159
|
+
? colors.buttonText
|
|
160
|
+
: colors.textPrimary,
|
|
161
|
+
}}
|
|
162
|
+
title={`Continue with ${item.label}`}
|
|
163
|
+
onPress={() => handlePress(item.key)}
|
|
164
|
+
leftIcon={React.cloneElement(item.icon as any, {
|
|
165
|
+
color:
|
|
166
|
+
activeTab === item.key
|
|
167
|
+
? colors.buttonText
|
|
168
|
+
: colors.textPrimary,
|
|
169
|
+
size: moderateScale(18),
|
|
170
|
+
})}
|
|
171
|
+
/>
|
|
172
|
+
)}
|
|
173
|
+
</React.Fragment>
|
|
148
174
|
))}
|
|
149
175
|
</View>
|
|
150
176
|
);
|
|
@@ -152,6 +178,25 @@ const AuthProvider: React.FC<AuthProviderProps> = ({
|
|
|
152
178
|
// Toggle render without absolute
|
|
153
179
|
const renderToggle = () => {
|
|
154
180
|
const enabledMethods = authMethods.filter((m) => m.enabled);
|
|
181
|
+
|
|
182
|
+
if (isLoading) {
|
|
183
|
+
return (
|
|
184
|
+
<SkeletonPlaceholder
|
|
185
|
+
backgroundColor={colors.skeletonBaseColor}
|
|
186
|
+
highlightColor={colors.skeletonHighlightColor}
|
|
187
|
+
borderRadius={50}
|
|
188
|
+
>
|
|
189
|
+
<View
|
|
190
|
+
style={{
|
|
191
|
+
width: '100%',
|
|
192
|
+
height: verticalScale(48),
|
|
193
|
+
borderRadius: 50,
|
|
194
|
+
}}
|
|
195
|
+
/>
|
|
196
|
+
</SkeletonPlaceholder>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
155
200
|
return (
|
|
156
201
|
<View
|
|
157
202
|
style={[
|
|
@@ -257,7 +302,7 @@ const styles = StyleSheet.create({
|
|
|
257
302
|
bottomSection: {
|
|
258
303
|
width: '100%',
|
|
259
304
|
alignItems: 'center',
|
|
260
|
-
paddingBottom: verticalScale(
|
|
305
|
+
paddingBottom: verticalScale(30),
|
|
261
306
|
},
|
|
262
307
|
title: {
|
|
263
308
|
fontSize: moderateScale(18),
|
|
@@ -24,6 +24,7 @@ import BackBtn from '../../Button/BackBtn';
|
|
|
24
24
|
import { Text } from '../../Text';
|
|
25
25
|
import type { ThemeOverride } from '../../../theme/themes';
|
|
26
26
|
import { RFValue } from 'react-native-responsive-fontsize';
|
|
27
|
+
import { getResponsiveBottomSpacing } from '../../../utils/Spacing';
|
|
27
28
|
|
|
28
29
|
type FormValues = {
|
|
29
30
|
email: string;
|
|
@@ -313,7 +314,14 @@ const LoginWithEmail: React.FC<LoginWithEmailProps> = ({
|
|
|
313
314
|
</View>
|
|
314
315
|
|
|
315
316
|
{!isKeyboardOpen && shouldRender(onSignup || renderSignupPrompt) && (
|
|
316
|
-
<View
|
|
317
|
+
<View
|
|
318
|
+
style={[
|
|
319
|
+
styles.signupContainer,
|
|
320
|
+
{
|
|
321
|
+
bottom: getResponsiveBottomSpacing(35),
|
|
322
|
+
},
|
|
323
|
+
]}
|
|
324
|
+
>
|
|
317
325
|
{renderSignupPrompt ? (
|
|
318
326
|
renderSignupPrompt({
|
|
319
327
|
onPress: () => handleKeyboardDismiss(onSignup),
|
|
@@ -388,7 +396,6 @@ const styles = StyleSheet.create({
|
|
|
388
396
|
},
|
|
389
397
|
signupContainer: {
|
|
390
398
|
position: 'absolute',
|
|
391
|
-
bottom: verticalScale(30),
|
|
392
399
|
left: 0,
|
|
393
400
|
right: 0,
|
|
394
401
|
alignItems: 'center',
|
|
@@ -47,6 +47,8 @@ type OTPProps = {
|
|
|
47
47
|
otpDigitCount?: number;
|
|
48
48
|
keyboardType?: KeyboardTypeOptions;
|
|
49
49
|
phoneNumber?: string;
|
|
50
|
+
enableAutoFill?: boolean;
|
|
51
|
+
autoSubmitOnFill?: boolean;
|
|
50
52
|
text?: {
|
|
51
53
|
otpLabel?: string;
|
|
52
54
|
otpPlaceholder?: string;
|
|
@@ -110,6 +112,8 @@ const OTP: React.FC<OTPProps> = ({
|
|
|
110
112
|
otpDigitCount = 4,
|
|
111
113
|
keyboardType = 'number-pad',
|
|
112
114
|
phoneNumber,
|
|
115
|
+
enableAutoFill = true,
|
|
116
|
+
autoSubmitOnFill = true,
|
|
113
117
|
text = DEFAULT_TEXT,
|
|
114
118
|
onResendOtp,
|
|
115
119
|
renderResendButton,
|
|
@@ -239,6 +243,31 @@ const OTP: React.FC<OTPProps> = ({
|
|
|
239
243
|
}
|
|
240
244
|
}, [onSubmit, otp, otpDigitCount]);
|
|
241
245
|
|
|
246
|
+
// Auto-submit when OTP is auto-filled and complete
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
if (
|
|
249
|
+
autoSubmitOnFill &&
|
|
250
|
+
otp.length === otpDigitCount &&
|
|
251
|
+
!isSubmitting &&
|
|
252
|
+
!loading &&
|
|
253
|
+
onSubmit
|
|
254
|
+
) {
|
|
255
|
+
const timer = setTimeout(() => {
|
|
256
|
+
handleSubmit();
|
|
257
|
+
}, 300); // Small delay to ensure OTP is fully set
|
|
258
|
+
return () => clearTimeout(timer);
|
|
259
|
+
}
|
|
260
|
+
return;
|
|
261
|
+
}, [
|
|
262
|
+
otp,
|
|
263
|
+
otpDigitCount,
|
|
264
|
+
autoSubmitOnFill,
|
|
265
|
+
isSubmitting,
|
|
266
|
+
loading,
|
|
267
|
+
onSubmit,
|
|
268
|
+
handleSubmit,
|
|
269
|
+
]);
|
|
270
|
+
|
|
242
271
|
const handleResendOtp = useCallback(() => {
|
|
243
272
|
if (onResendOtp) {
|
|
244
273
|
onResendOtp();
|
|
@@ -325,7 +354,14 @@ const OTP: React.FC<OTPProps> = ({
|
|
|
325
354
|
cellCount={otpDigitCount}
|
|
326
355
|
rootStyle={styles.codeFieldRoot}
|
|
327
356
|
keyboardType={keyboardType}
|
|
328
|
-
textContentType=
|
|
357
|
+
textContentType={enableAutoFill ? 'oneTimeCode' : 'none'}
|
|
358
|
+
autoComplete={
|
|
359
|
+
enableAutoFill
|
|
360
|
+
? Platform.OS === 'android'
|
|
361
|
+
? 'sms-otp'
|
|
362
|
+
: 'off'
|
|
363
|
+
: 'off'
|
|
364
|
+
}
|
|
329
365
|
renderCell={({ index, symbol, isFocused }) => (
|
|
330
366
|
<Text
|
|
331
367
|
key={index}
|
|
@@ -25,6 +25,7 @@ import BackBtn from '../../Button/BackBtn';
|
|
|
25
25
|
import { Text } from '../../Text';
|
|
26
26
|
import type { ThemeOverride } from '../../../theme/themes';
|
|
27
27
|
import { RFValue } from 'react-native-responsive-fontsize';
|
|
28
|
+
import { getResponsiveBottomSpacing } from '../../../utils/Spacing';
|
|
28
29
|
|
|
29
30
|
type FormValues = {
|
|
30
31
|
username: string;
|
|
@@ -349,7 +350,14 @@ const Signup: React.FC<SignupProps> = ({
|
|
|
349
350
|
(renderLoginPrompt ? (
|
|
350
351
|
renderLoginPrompt()
|
|
351
352
|
) : (
|
|
352
|
-
<View
|
|
353
|
+
<View
|
|
354
|
+
style={[
|
|
355
|
+
styles.loginContainerWrapper,
|
|
356
|
+
{
|
|
357
|
+
bottom: getResponsiveBottomSpacing(35),
|
|
358
|
+
},
|
|
359
|
+
]}
|
|
360
|
+
>
|
|
353
361
|
<View style={styles.loginContainer}>
|
|
354
362
|
<View style={styles.loginRow}>
|
|
355
363
|
<Text
|
|
@@ -415,7 +423,6 @@ const styles = StyleSheet.create({
|
|
|
415
423
|
},
|
|
416
424
|
loginContainerWrapper: {
|
|
417
425
|
position: 'absolute',
|
|
418
|
-
bottom: verticalScale(30),
|
|
419
426
|
left: 0,
|
|
420
427
|
right: 0,
|
|
421
428
|
alignItems: 'center',
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Naresh Dhamu
|
|
3
|
+
* @lastModified Thu 06 Nov 2025 at 05:00 PM
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { View, StyleSheet, type ViewStyle, type StyleProp } from 'react-native';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* BlurView Props - Same as @react-native-community/blur
|
|
11
|
+
*/
|
|
12
|
+
export interface BlurViewProps {
|
|
13
|
+
/** Style of the BlurView container */
|
|
14
|
+
style?: StyleProp<ViewStyle>;
|
|
15
|
+
|
|
16
|
+
/** The blur type (tint) - exactly matches community lib */
|
|
17
|
+
blurType?:
|
|
18
|
+
| 'dark'
|
|
19
|
+
| 'light'
|
|
20
|
+
| 'xlight'
|
|
21
|
+
| 'extraDark'
|
|
22
|
+
| 'regular'
|
|
23
|
+
| 'prominent'
|
|
24
|
+
| 'chromeMaterial'
|
|
25
|
+
| 'material'
|
|
26
|
+
| 'thickMaterial'
|
|
27
|
+
| 'thinMaterial'
|
|
28
|
+
| 'ultraThinMaterial'
|
|
29
|
+
| 'chromeMaterialDark'
|
|
30
|
+
| 'materialDark'
|
|
31
|
+
| 'thickMaterialDark'
|
|
32
|
+
| 'thinMaterialDark'
|
|
33
|
+
| 'ultraThinMaterialDark'
|
|
34
|
+
| 'chromeMaterialLight'
|
|
35
|
+
| 'materialLight'
|
|
36
|
+
| 'thickMaterialLight'
|
|
37
|
+
| 'thinMaterialLight'
|
|
38
|
+
| 'ultraThinMaterialLight';
|
|
39
|
+
|
|
40
|
+
/** The blur intensity amount (0-100) - exactly matches community lib */
|
|
41
|
+
blurAmount?: number;
|
|
42
|
+
|
|
43
|
+
/** Fallback color for reduced transparency - exactly matches community lib */
|
|
44
|
+
reducedTransparencyFallbackColor?: string;
|
|
45
|
+
|
|
46
|
+
/** iOS only: Overlay color - exactly matches community lib */
|
|
47
|
+
overlayColor?: string;
|
|
48
|
+
|
|
49
|
+
/** Android only: Downsample factor (higher = more blur but lower quality) */
|
|
50
|
+
downsampleFactor?: number;
|
|
51
|
+
|
|
52
|
+
/** Android only: Blur radius */
|
|
53
|
+
blurRadius?: number;
|
|
54
|
+
|
|
55
|
+
/** Child components */
|
|
56
|
+
children?: React.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Custom BlurView - 100% Compatible with @react-native-community/blur
|
|
61
|
+
*
|
|
62
|
+
* ✅ Same API as @react-native-community/blur
|
|
63
|
+
* ✅ Works on iOS, Android, and Web
|
|
64
|
+
* ✅ Drop-in replacement - just change the import
|
|
65
|
+
* 🚫 Simulates blur (no live backdrop) using semi-transparent layers
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* <BlurView
|
|
70
|
+
* style={styles.blur}
|
|
71
|
+
* blurType="light"
|
|
72
|
+
* blurAmount={10}
|
|
73
|
+
* reducedTransparencyFallbackColor="white"
|
|
74
|
+
* />
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
const BlurView: React.FC<BlurViewProps> = ({
|
|
78
|
+
style,
|
|
79
|
+
blurType = 'light',
|
|
80
|
+
blurAmount = 100,
|
|
81
|
+
reducedTransparencyFallbackColor,
|
|
82
|
+
overlayColor,
|
|
83
|
+
children,
|
|
84
|
+
}) => {
|
|
85
|
+
// Clamp blur amount to 0-100 range (same as community lib)
|
|
86
|
+
const intensity = Math.max(0, Math.min(100, blurAmount));
|
|
87
|
+
|
|
88
|
+
// Get tint style based on blur type
|
|
89
|
+
const tintStyle = getBlurTintStyle(
|
|
90
|
+
blurType,
|
|
91
|
+
intensity,
|
|
92
|
+
reducedTransparencyFallbackColor,
|
|
93
|
+
overlayColor
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Platform-specific rendering
|
|
97
|
+
return (
|
|
98
|
+
<View style={[styles.container, style]}>
|
|
99
|
+
{/* Background blur layer */}
|
|
100
|
+
<View style={[StyleSheet.absoluteFillObject, tintStyle]} />
|
|
101
|
+
|
|
102
|
+
{/* Content layer */}
|
|
103
|
+
<View pointerEvents="box-none" style={styles.content}>
|
|
104
|
+
{children}
|
|
105
|
+
</View>
|
|
106
|
+
</View>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get blur tint style based on blurType
|
|
112
|
+
* Matches the exact behavior of @react-native-community/blur
|
|
113
|
+
*/
|
|
114
|
+
function getBlurTintStyle(
|
|
115
|
+
blurType: string,
|
|
116
|
+
intensity: number,
|
|
117
|
+
fallbackColor?: string,
|
|
118
|
+
overlayColor?: string
|
|
119
|
+
): ViewStyle {
|
|
120
|
+
// If overlayColor is provided, use it (iOS behavior)
|
|
121
|
+
if (overlayColor) {
|
|
122
|
+
return { backgroundColor: overlayColor };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Calculate opacity based on intensity (0-100)
|
|
126
|
+
// Higher intensity = more opaque = stronger blur effect
|
|
127
|
+
const opacity = Math.min(0.95, intensity / 100);
|
|
128
|
+
const lightOpacity = opacity * 0.7;
|
|
129
|
+
const darkOpacity = opacity * 0.8;
|
|
130
|
+
|
|
131
|
+
// Match exact blur types from @react-native-community/blur
|
|
132
|
+
switch (blurType) {
|
|
133
|
+
// Dark blur types
|
|
134
|
+
case 'dark':
|
|
135
|
+
return { backgroundColor: `rgba(0, 0, 0, ${darkOpacity})` };
|
|
136
|
+
case 'extraDark':
|
|
137
|
+
return {
|
|
138
|
+
backgroundColor: `rgba(0, 0, 0, ${Math.min(0.98, darkOpacity * 1.2)})`,
|
|
139
|
+
};
|
|
140
|
+
case 'materialDark':
|
|
141
|
+
case 'thickMaterialDark':
|
|
142
|
+
case 'chromeMaterialDark':
|
|
143
|
+
return { backgroundColor: `rgba(28, 28, 30, ${darkOpacity})` };
|
|
144
|
+
case 'thinMaterialDark':
|
|
145
|
+
return { backgroundColor: `rgba(28, 28, 30, ${darkOpacity * 0.7})` };
|
|
146
|
+
case 'ultraThinMaterialDark':
|
|
147
|
+
return { backgroundColor: `rgba(28, 28, 30, ${darkOpacity * 0.5})` };
|
|
148
|
+
|
|
149
|
+
// Light blur types
|
|
150
|
+
case 'light':
|
|
151
|
+
return {
|
|
152
|
+
backgroundColor:
|
|
153
|
+
fallbackColor || `rgba(255, 255, 255, ${lightOpacity})`,
|
|
154
|
+
};
|
|
155
|
+
case 'xlight':
|
|
156
|
+
return { backgroundColor: `rgba(255, 255, 255, ${lightOpacity * 0.6})` };
|
|
157
|
+
case 'materialLight':
|
|
158
|
+
case 'chromeMaterialLight':
|
|
159
|
+
return { backgroundColor: `rgba(255, 255, 255, ${lightOpacity})` };
|
|
160
|
+
case 'thickMaterialLight':
|
|
161
|
+
return { backgroundColor: `rgba(242, 242, 247, ${lightOpacity})` };
|
|
162
|
+
case 'thinMaterialLight':
|
|
163
|
+
return { backgroundColor: `rgba(242, 242, 247, ${lightOpacity * 0.7})` };
|
|
164
|
+
case 'ultraThinMaterialLight':
|
|
165
|
+
return { backgroundColor: `rgba(242, 242, 247, ${lightOpacity * 0.5})` };
|
|
166
|
+
|
|
167
|
+
// Regular/prominent types
|
|
168
|
+
case 'regular':
|
|
169
|
+
case 'prominent':
|
|
170
|
+
return { backgroundColor: `rgba(255, 255, 255, ${lightOpacity * 0.8})` };
|
|
171
|
+
case 'material':
|
|
172
|
+
case 'chromeMaterial':
|
|
173
|
+
return { backgroundColor: `rgba(242, 242, 247, ${lightOpacity})` };
|
|
174
|
+
case 'thickMaterial':
|
|
175
|
+
return { backgroundColor: `rgba(242, 242, 247, ${lightOpacity * 1.1})` };
|
|
176
|
+
case 'thinMaterial':
|
|
177
|
+
return { backgroundColor: `rgba(242, 242, 247, ${lightOpacity * 0.7})` };
|
|
178
|
+
case 'ultraThinMaterial':
|
|
179
|
+
return { backgroundColor: `rgba(242, 242, 247, ${lightOpacity * 0.5})` };
|
|
180
|
+
|
|
181
|
+
// Default
|
|
182
|
+
default:
|
|
183
|
+
return {
|
|
184
|
+
backgroundColor:
|
|
185
|
+
fallbackColor || `rgba(255, 255, 255, ${lightOpacity})`,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const styles = StyleSheet.create({
|
|
191
|
+
container: {
|
|
192
|
+
overflow: 'hidden',
|
|
193
|
+
},
|
|
194
|
+
content: {
|
|
195
|
+
flex: 1,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
export default BlurView;
|
|
@@ -234,7 +234,9 @@ const MovieCardFour: React.FC<MovieCardFourProps> = ({
|
|
|
234
234
|
ref={flatListRef}
|
|
235
235
|
data={data}
|
|
236
236
|
horizontal
|
|
237
|
-
keyExtractor={(item, index) =>
|
|
237
|
+
keyExtractor={(item, index) =>
|
|
238
|
+
item._id || `item-${item.slug || item.name || index}`
|
|
239
|
+
}
|
|
238
240
|
renderItem={renderItem}
|
|
239
241
|
showsHorizontalScrollIndicator={false}
|
|
240
242
|
contentContainerStyle={styles.listContent}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type StyleProp,
|
|
13
13
|
type ViewStyle,
|
|
14
14
|
} from 'react-native';
|
|
15
|
-
import { scale } from 'react-native-size-matters';
|
|
15
|
+
import { scale, verticalScale } from 'react-native-size-matters';
|
|
16
16
|
import Animated, {
|
|
17
17
|
type AnimatedStyle,
|
|
18
18
|
type SharedValue,
|
|
@@ -26,6 +26,7 @@ import type { IHistoryItem } from './Card/NowWatching/NowWatching';
|
|
|
26
26
|
import type { ThemeOverride } from '../../theme/themes';
|
|
27
27
|
import { NoContentFallback, type NoContentFallbackProps } from '../Fallbacks';
|
|
28
28
|
import { useInternalTheme } from '../../theme/hook';
|
|
29
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
29
30
|
|
|
30
31
|
export interface ICustomComponentsForContent {
|
|
31
32
|
type: string;
|
|
@@ -150,6 +151,7 @@ export const Content: React.FC<IContentProps> = ({
|
|
|
150
151
|
isLoading,
|
|
151
152
|
noContentFallbackProps,
|
|
152
153
|
}) => {
|
|
154
|
+
const insets = useSafeAreaInsets();
|
|
153
155
|
const sectionData = useMemo<IGetSectionData[]>(
|
|
154
156
|
() => contentData?.sectionData ?? [],
|
|
155
157
|
[contentData?.sectionData]
|
|
@@ -247,9 +249,8 @@ export const Content: React.FC<IContentProps> = ({
|
|
|
247
249
|
}
|
|
248
250
|
onEndReachedThreshold={0.7}
|
|
249
251
|
contentContainerStyle={[
|
|
250
|
-
{
|
|
251
|
-
|
|
252
|
-
},
|
|
252
|
+
{ paddingBottom: verticalScale(100) + insets.bottom },
|
|
253
|
+
|
|
253
254
|
contentContainerStyle,
|
|
254
255
|
]}
|
|
255
256
|
/>
|
|
@@ -33,6 +33,7 @@ export const ContentView = ({
|
|
|
33
33
|
recommendedContentCardStyles,
|
|
34
34
|
history,
|
|
35
35
|
episodeCardMode,
|
|
36
|
+
pricingAndExpiryInfo,
|
|
36
37
|
}: ComponentProps) => {
|
|
37
38
|
const { theme: appliedTheme } = useInternalTheme(theme);
|
|
38
39
|
const seekTime = history?.currentTime || 0;
|
|
@@ -95,7 +96,13 @@ export const ContentView = ({
|
|
|
95
96
|
isLoading={isLoading}
|
|
96
97
|
style={genreTagsStyles}
|
|
97
98
|
/>
|
|
98
|
-
<MiniInfo
|
|
99
|
+
<MiniInfo
|
|
100
|
+
content={content}
|
|
101
|
+
theme={theme}
|
|
102
|
+
isLoading={isLoading}
|
|
103
|
+
{...pricingAndExpiryInfo}
|
|
104
|
+
/>
|
|
105
|
+
|
|
99
106
|
<AboutSection
|
|
100
107
|
theme={appliedTheme}
|
|
101
108
|
description={content?.description}
|