@zezosoft/zezo-ott-react-native-ui-kit 1.0.3 → 1.0.4

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.
Files changed (108) hide show
  1. package/README.md +1 -1
  2. package/lib/module/assets/animations/heart.json +788 -0
  3. package/lib/module/components/Auth/QrLogin/QrLogin.js +267 -0
  4. package/lib/module/components/Auth/QrLogin/QrLogin.js.map +1 -0
  5. package/lib/module/components/Auth/QrLogin/components/QrViewArea.js +178 -0
  6. package/lib/module/components/Auth/QrLogin/components/QrViewArea.js.map +1 -0
  7. package/lib/module/components/Auth/index.js +3 -1
  8. package/lib/module/components/Auth/index.js.map +1 -1
  9. package/lib/module/components/Headers/AppHeader.js +1 -1
  10. package/lib/module/components/Headers/AppHeader.js.map +1 -1
  11. package/lib/module/components/Headers/One.js +1 -1
  12. package/lib/module/components/Headers/One.js.map +1 -1
  13. package/lib/module/components/Headers/Two.js +1 -1
  14. package/lib/module/components/Headers/Two.js.map +1 -1
  15. package/lib/module/components/Reels/ReelsSeries/Model/Episodes.js +110 -0
  16. package/lib/module/components/Reels/ReelsSeries/Model/Episodes.js.map +1 -0
  17. package/lib/module/components/Reels/ReelsSeries/Model/Synopsis.js +216 -0
  18. package/lib/module/components/Reels/ReelsSeries/Model/Synopsis.js.map +1 -0
  19. package/lib/module/components/Reels/ReelsSeries/ReelSeriesDetailsModal.js +182 -0
  20. package/lib/module/components/Reels/ReelsSeries/ReelSeriesDetailsModal.js.map +1 -0
  21. package/lib/module/components/Reels/ReelsSeries/ReelSeriesOverlay.js +203 -0
  22. package/lib/module/components/Reels/ReelsSeries/ReelSeriesOverlay.js.map +1 -0
  23. package/lib/module/components/Reels/ReelsSeries/ReelsSeries.js +121 -0
  24. package/lib/module/components/Reels/ReelsSeries/ReelsSeries.js.map +1 -0
  25. package/lib/module/components/Reels/ReelsSeries/ReelsSeriesItem.js +290 -0
  26. package/lib/module/components/Reels/ReelsSeries/ReelsSeriesItem.js.map +1 -0
  27. package/lib/module/components/Reels/ReelsSeries/types.js +2 -0
  28. package/lib/module/components/Reels/ReelsSeries/types.js.map +1 -0
  29. package/lib/module/components/Reels/index.js +11 -0
  30. package/lib/module/components/Reels/index.js.map +1 -0
  31. package/lib/module/components/User/DeviceSessions/DeviceSessions.js +8 -0
  32. package/lib/module/components/User/DeviceSessions/DeviceSessions.js.map +1 -1
  33. package/lib/module/components/User/ProfileUpdate/ProfileUpdate.js +258 -0
  34. package/lib/module/components/User/ProfileUpdate/ProfileUpdate.js.map +1 -0
  35. package/lib/module/components/User/components/UserSection.js +8 -13
  36. package/lib/module/components/User/components/UserSection.js.map +1 -1
  37. package/lib/module/components/User/index.js +2 -1
  38. package/lib/module/components/User/index.js.map +1 -1
  39. package/lib/module/components/index.js +1 -0
  40. package/lib/module/components/index.js.map +1 -1
  41. package/lib/module/theme/ThemeProvider.js +13 -10
  42. package/lib/module/theme/ThemeProvider.js.map +1 -1
  43. package/lib/module/theme/themes.js +2 -0
  44. package/lib/module/theme/themes.js.map +1 -1
  45. package/lib/module/utils/Formater.js +17 -0
  46. package/lib/module/utils/Formater.js.map +1 -0
  47. package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts +32 -0
  48. package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts.map +1 -0
  49. package/lib/typescript/src/components/Auth/QrLogin/components/QrViewArea.d.ts +15 -0
  50. package/lib/typescript/src/components/Auth/QrLogin/components/QrViewArea.d.ts.map +1 -0
  51. package/lib/typescript/src/components/Auth/index.d.ts +1 -0
  52. package/lib/typescript/src/components/Auth/index.d.ts.map +1 -1
  53. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Episodes.d.ts +12 -0
  54. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Episodes.d.ts.map +1 -0
  55. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Synopsis.d.ts +9 -0
  56. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Synopsis.d.ts.map +1 -0
  57. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesDetailsModal.d.ts +13 -0
  58. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesDetailsModal.d.ts.map +1 -0
  59. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesOverlay.d.ts +18 -0
  60. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesOverlay.d.ts.map +1 -0
  61. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeries.d.ts +15 -0
  62. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeries.d.ts.map +1 -0
  63. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeriesItem.d.ts +18 -0
  64. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeriesItem.d.ts.map +1 -0
  65. package/lib/typescript/src/components/Reels/ReelsSeries/types.d.ts +24 -0
  66. package/lib/typescript/src/components/Reels/ReelsSeries/types.d.ts.map +1 -0
  67. package/lib/typescript/src/components/Reels/index.d.ts +8 -0
  68. package/lib/typescript/src/components/Reels/index.d.ts.map +1 -0
  69. package/lib/typescript/src/components/User/DeviceSessions/DeviceSessions.d.ts +1 -0
  70. package/lib/typescript/src/components/User/DeviceSessions/DeviceSessions.d.ts.map +1 -1
  71. package/lib/typescript/src/components/User/ProfileUpdate/ProfileUpdate.d.ts +27 -0
  72. package/lib/typescript/src/components/User/ProfileUpdate/ProfileUpdate.d.ts.map +1 -0
  73. package/lib/typescript/src/components/User/components/UserSection.d.ts.map +1 -1
  74. package/lib/typescript/src/components/User/index.d.ts +2 -1
  75. package/lib/typescript/src/components/User/index.d.ts.map +1 -1
  76. package/lib/typescript/src/components/index.d.ts +1 -0
  77. package/lib/typescript/src/components/index.d.ts.map +1 -1
  78. package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -1
  79. package/lib/typescript/src/theme/themes.d.ts +1 -0
  80. package/lib/typescript/src/theme/themes.d.ts.map +1 -1
  81. package/lib/typescript/src/utils/Formater.d.ts +2 -0
  82. package/lib/typescript/src/utils/Formater.d.ts.map +1 -0
  83. package/package.json +13 -5
  84. package/src/assets/animations/heart.json +788 -0
  85. package/src/components/Auth/QrLogin/QrLogin.tsx +306 -0
  86. package/src/components/Auth/QrLogin/components/QrViewArea.tsx +213 -0
  87. package/src/components/Auth/index.ts +2 -0
  88. package/src/components/Headers/AppHeader.tsx +1 -1
  89. package/src/components/Headers/One.tsx +1 -1
  90. package/src/components/Headers/Two.tsx +1 -1
  91. package/src/components/Reels/ReelsSeries/Model/Episodes.tsx +133 -0
  92. package/src/components/Reels/ReelsSeries/Model/Synopsis.tsx +249 -0
  93. package/src/components/Reels/ReelsSeries/ReelSeriesDetailsModal.tsx +209 -0
  94. package/src/components/Reels/ReelsSeries/ReelSeriesOverlay.tsx +185 -0
  95. package/src/components/Reels/ReelsSeries/ReelsSeries.tsx +163 -0
  96. package/src/components/Reels/ReelsSeries/ReelsSeriesItem.tsx +333 -0
  97. package/src/components/Reels/ReelsSeries/types.ts +27 -0
  98. package/src/components/Reels/index.ts +8 -0
  99. package/src/components/User/DeviceSessions/DeviceSessions.tsx +11 -0
  100. package/src/components/User/ProfileUpdate/ProfileUpdate.tsx +265 -0
  101. package/src/components/User/components/UserSection.tsx +10 -13
  102. package/src/components/User/index.ts +3 -1
  103. package/src/components/index.ts +1 -0
  104. package/src/theme/ThemeProvider.tsx +12 -9
  105. package/src/theme/themes.ts +3 -0
  106. package/src/utils/Formater.ts +14 -0
  107. /package/lib/module/assets/{img → svg}/h.svg +0 -0
  108. /package/src/assets/{img → svg}/h.svg +0 -0
@@ -0,0 +1,265 @@
1
+ /**
2
+ * @author Naresh Dhamu
3
+ * @lastModified Fri 03 Oct 2025 at 01:09 PM
4
+ */
5
+ import { useCallback } from 'react';
6
+ import {
7
+ View,
8
+ StyleSheet,
9
+ KeyboardAvoidingView,
10
+ Platform,
11
+ TouchableWithoutFeedback,
12
+ Keyboard,
13
+ TouchableOpacity,
14
+ } from 'react-native';
15
+ import { moderateScale, scale, verticalScale } from 'react-native-size-matters';
16
+ import { RFValue } from 'react-native-responsive-fontsize';
17
+ import { Camera } from 'lucide-react-native';
18
+ import { useForm, Controller } from 'react-hook-form';
19
+ import { Text } from '../../Text';
20
+ import AppHeader from '../../Headers/AppHeader';
21
+ import { useTheme } from '../../../theme/hook/useTheme';
22
+ import type { AppTheme } from '../../../theme/themes';
23
+ import UserAvatar from '../components/UserAvatar';
24
+ import { Input } from '../../Input/Input';
25
+ import { Button } from '../../Button';
26
+ import ImageCropPicker, { type Image } from 'react-native-image-crop-picker';
27
+
28
+ export type ProfileUpdateFormValues = {
29
+ fullName: string;
30
+ avatarFile: Image; // new field to store actual file
31
+ };
32
+
33
+ export type ProfileUpdateProps = {
34
+ title?: string;
35
+ name?: string;
36
+ avatarUri?: string;
37
+ onBackPress?: () => void;
38
+ onSubmit?: (val: { fullName: string; avatarFile: Image }) => void;
39
+ theme?: AppTheme;
40
+ loading?: boolean;
41
+ onError?: (error: { message: string }) => void;
42
+ };
43
+
44
+ export const ProfileUpdate = ({
45
+ title = 'My Profile',
46
+ name = '',
47
+ avatarUri = '',
48
+ onBackPress,
49
+ onSubmit,
50
+ theme,
51
+ loading = false,
52
+ onError,
53
+ }: ProfileUpdateProps) => {
54
+ const { theme: appliedTheme } = useTheme(theme);
55
+ const { colors } = appliedTheme;
56
+
57
+ const {
58
+ control,
59
+ handleSubmit,
60
+ formState: { errors },
61
+ trigger,
62
+ setValue,
63
+ watch,
64
+ } = useForm<ProfileUpdateFormValues>({
65
+ defaultValues: {
66
+ fullName: name,
67
+ avatarFile: {
68
+ path: avatarUri,
69
+ },
70
+ },
71
+ mode: 'onChange',
72
+ reValidateMode: 'onBlur',
73
+ });
74
+
75
+ const avatar = watch('avatarFile');
76
+
77
+ const handlePickImage = async () => {
78
+ try {
79
+ const image = await ImageCropPicker.openPicker({
80
+ width: 400,
81
+ height: 400,
82
+ cropping: true,
83
+ showCropGuidelines: false,
84
+ cropperCircleOverlay: true,
85
+ showCropFrame: false,
86
+ compressImageQuality: 0.7,
87
+ mediaType: 'photo',
88
+ });
89
+
90
+ if (image?.path && image?.path !== '' && image.path !== avatarUri) {
91
+ setValue('avatarFile', image, {
92
+ shouldValidate: true,
93
+ shouldDirty: true,
94
+ });
95
+ } else {
96
+ onError?.({ message: 'No image selected' });
97
+ }
98
+ } catch (error) {
99
+ const message = (error as Error).message;
100
+ onError?.({ message });
101
+ }
102
+ };
103
+
104
+ const handleFormSubmit = useCallback(
105
+ (data: ProfileUpdateFormValues) => {
106
+ Keyboard.dismiss();
107
+ if (data.avatarFile.path !== avatarUri) {
108
+ onSubmit?.({
109
+ avatarFile: data.avatarFile,
110
+ fullName: data.fullName,
111
+ });
112
+ } else {
113
+ onError?.({ message: 'No image selected' });
114
+ }
115
+ },
116
+ [avatarUri, onError, onSubmit]
117
+ );
118
+
119
+ return (
120
+ <KeyboardAvoidingView
121
+ style={[styles.container, { backgroundColor: colors.background }]}
122
+ behavior={Platform.OS === 'ios' ? 'padding' : undefined}
123
+ >
124
+ <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
125
+ <View style={{ flex: 1 }}>
126
+ <AppHeader
127
+ title={title}
128
+ onBackPress={onBackPress}
129
+ theme={appliedTheme}
130
+ titleAlign="left"
131
+ />
132
+
133
+ <View style={styles.content}>
134
+ <View style={styles.avatarBox}>
135
+ <UserAvatar
136
+ avatarUri={avatar.path}
137
+ theme={appliedTheme}
138
+ size={100}
139
+ />
140
+ <TouchableOpacity
141
+ style={[
142
+ styles.cameraBtn,
143
+ {
144
+ borderColor: colors.button,
145
+ backgroundColor: colors.surfaceVariant,
146
+ shadowColor: colors.shadow || colors.surface,
147
+ },
148
+ ]}
149
+ activeOpacity={0.8}
150
+ onPress={handlePickImage}
151
+ >
152
+ <Camera
153
+ size={moderateScale(13)}
154
+ color={colors.button}
155
+ strokeWidth={2}
156
+ />
157
+ </TouchableOpacity>
158
+ </View>
159
+
160
+ <Text style={[styles.label, { color: colors.textPrimary }]}>
161
+ Basic Detail
162
+ </Text>
163
+
164
+ <View style={styles.formContainer}>
165
+ <Controller
166
+ control={control}
167
+ name="fullName"
168
+ rules={{
169
+ required: 'Name is required',
170
+ minLength: { value: 3, message: 'At least 3 characters' },
171
+ }}
172
+ render={({ field: { onChange, value, onBlur } }) => (
173
+ <View style={{ width: '100%' }}>
174
+ <Input.One
175
+ label="Full Name"
176
+ value={value}
177
+ onChangeText={(text) => {
178
+ onChange(text);
179
+ trigger('fullName');
180
+ }}
181
+ onBlur={onBlur}
182
+ placeholder={'Enter your full name'}
183
+ placeholderTextColor={colors.textDisabled}
184
+ containerStyle={{ marginTop: verticalScale(20) }}
185
+ theme={appliedTheme}
186
+ returnKeyType="done"
187
+ onSubmitEditing={handleSubmit(handleFormSubmit)}
188
+ />
189
+ {errors.fullName && (
190
+ <Text style={[styles.errorText, { color: colors.error }]}>
191
+ {errors.fullName.message}
192
+ </Text>
193
+ )}
194
+ </View>
195
+ )}
196
+ />
197
+
198
+ <Button.Primary
199
+ title={'Update Profile'}
200
+ onPress={handleSubmit(handleFormSubmit)}
201
+ theme={appliedTheme}
202
+ titleStyle={{ fontSize: RFValue(14) }}
203
+ loading={loading}
204
+ containerStyle={{ marginTop: verticalScale(5) }}
205
+ />
206
+ </View>
207
+ </View>
208
+ </View>
209
+ </TouchableWithoutFeedback>
210
+ </KeyboardAvoidingView>
211
+ );
212
+ };
213
+
214
+ export default ProfileUpdate;
215
+
216
+ namespace ProfileUpdate {
217
+ export type Props = ProfileUpdateProps;
218
+ }
219
+
220
+ const styles = StyleSheet.create({
221
+ container: { flex: 1 },
222
+ content: {
223
+ flex: 1,
224
+ alignItems: 'center',
225
+ padding: moderateScale(16),
226
+ },
227
+ avatarBox: {
228
+ marginVertical: verticalScale(20),
229
+ alignItems: 'center',
230
+ justifyContent: 'center',
231
+ },
232
+ cameraBtn: {
233
+ position: 'absolute',
234
+ bottom: scale(3),
235
+ right: scale(3),
236
+ padding: scale(2),
237
+ width: scale(23),
238
+ height: scale(23),
239
+ borderRadius: scale(13.5),
240
+ alignItems: 'center',
241
+ justifyContent: 'center',
242
+ borderWidth: 1,
243
+ elevation: 3,
244
+ shadowOffset: { width: 0, height: 1 },
245
+ shadowOpacity: 0.2,
246
+ shadowRadius: 1.5,
247
+ },
248
+ label: {
249
+ fontSize: RFValue(12),
250
+ fontWeight: '500',
251
+ alignSelf: 'flex-start',
252
+ margin: scale(5),
253
+ marginTop: verticalScale(10),
254
+ },
255
+ formContainer: {
256
+ width: '100%',
257
+ alignItems: 'center',
258
+ },
259
+ errorText: {
260
+ fontSize: RFValue(11),
261
+ marginTop: verticalScale(5),
262
+ marginLeft: scale(5),
263
+ alignSelf: 'flex-start',
264
+ },
265
+ });
@@ -80,7 +80,7 @@ const UserSection: React.FC<UserSectionProps> = ({
80
80
  styles.editButton,
81
81
  {
82
82
  borderColor: appliedTheme.colors.primary,
83
- backgroundColor: appliedTheme.colors.white,
83
+ backgroundColor: appliedTheme.colors.surfaceVariant,
84
84
  shadowColor: appliedTheme.colors.surface,
85
85
  },
86
86
  ]}
@@ -88,12 +88,10 @@ const UserSection: React.FC<UserSectionProps> = ({
88
88
  color: appliedTheme.colors.surfaceDisabled,
89
89
  }}
90
90
  >
91
- <View style={styles.editContent}>
92
- <Edit3
93
- size={moderateScale(14)}
94
- color={appliedTheme.colors.primary}
95
- />
96
- </View>
91
+ <Edit3
92
+ size={moderateScale(13)}
93
+ color={appliedTheme.colors.primary}
94
+ />
97
95
  </Pressable>
98
96
  )}
99
97
  </>
@@ -143,8 +141,10 @@ const styles = {
143
141
  position: 'absolute',
144
142
  bottom: scale(2),
145
143
  right: scale(2),
146
- width: scale(22),
147
- height: scale(22),
144
+ padding: scale(2),
145
+ width: scale(23),
146
+ height: scale(23),
147
+ overflow: 'hidden',
148
148
  borderRadius: scale(11),
149
149
  alignItems: 'center',
150
150
  justifyContent: 'center',
@@ -154,10 +154,7 @@ const styles = {
154
154
  shadowOpacity: 0.1,
155
155
  shadowRadius: 0.5,
156
156
  } as ViewStyle,
157
- editContent: {
158
- alignItems: 'center',
159
- justifyContent: 'center',
160
- } as ViewStyle,
157
+
161
158
  editLabel: {
162
159
  fontSize: RFValue(8),
163
160
  marginTop: verticalScale(1),
@@ -6,4 +6,6 @@
6
6
  import { WatchHistory } from './WatchHistory/WatchHistory';
7
7
  import { WatchLater } from './WatchLater/WatchLater';
8
8
  import { DeviceSessions } from './DeviceSessions/DeviceSessions';
9
- export { WatchHistory, WatchLater, DeviceSessions };
9
+ import { ProfileUpdate } from './ProfileUpdate/ProfileUpdate';
10
+
11
+ export { WatchHistory, WatchLater, DeviceSessions, ProfileUpdate };
@@ -22,3 +22,4 @@ export * from './ContentView';
22
22
  export * from './Search';
23
23
  export * from './Subscription';
24
24
  export * from './Alert';
25
+ export * from './Reels';
@@ -17,6 +17,7 @@ import {
17
17
  initialWindowMetrics,
18
18
  } from 'react-native-safe-area-context';
19
19
  import { LightTheme, DarkTheme, type ITheme, type AppTheme } from './themes';
20
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
20
21
 
21
22
  type ThemeContextType = {
22
23
  theme: ITheme;
@@ -124,14 +125,16 @@ export const ZezoUIProvider: React.FC<ZezoUIProviderProps> = ({
124
125
  );
125
126
 
126
127
  return (
127
- <SafeAreaProvider initialMetrics={initialWindowMetrics}>
128
- <ThemeContext.Provider value={contextValue}>
129
- <View
130
- style={{ flex: 1, backgroundColor: mergedTheme.colors.background }}
131
- >
132
- {children}
133
- </View>
134
- </ThemeContext.Provider>
135
- </SafeAreaProvider>
128
+ <GestureHandlerRootView>
129
+ <SafeAreaProvider initialMetrics={initialWindowMetrics}>
130
+ <ThemeContext.Provider value={contextValue}>
131
+ <View
132
+ style={{ flex: 1, backgroundColor: mergedTheme.colors.background }}
133
+ >
134
+ {children}
135
+ </View>
136
+ </ThemeContext.Provider>
137
+ </SafeAreaProvider>
138
+ </GestureHandlerRootView>
136
139
  );
137
140
  };
@@ -51,6 +51,7 @@ export type BaseColors = {
51
51
  shadow: string;
52
52
  scrim: string;
53
53
  backdrop: string;
54
+ overlay: string;
54
55
 
55
56
  inverseSurface: string;
56
57
  inverseOnSurface: string;
@@ -140,6 +141,7 @@ export const LightTheme: ITheme = {
140
141
  shadow: 'rgba(0, 0, 0, 0.1)',
141
142
  scrim: 'rgba(0, 0, 0, 0.2)',
142
143
  backdrop: 'rgba(243, 244, 246, 0.7)',
144
+ overlay: 'rgba(0,0,0,0.55)',
143
145
 
144
146
  inverseSurface: 'rgba(31, 41, 55, 1)',
145
147
  inverseOnSurface: 'rgba(249, 250, 251, 1)',
@@ -241,6 +243,7 @@ export const DarkTheme: ITheme = {
241
243
  shadow: 'rgba(0, 0, 0, 0.5)',
242
244
  scrim: 'rgba(0, 0, 0, 0.4)',
243
245
  backdrop: 'rgba(30, 41, 59, 0.7)',
246
+ overlay: 'rgba(0,0,0,0.55)',
244
247
 
245
248
  inverseSurface: 'rgba(229, 231, 235, 1)',
246
249
  inverseOnSurface: 'rgba(31, 41, 55, 1)',
@@ -0,0 +1,14 @@
1
+ export function formatCount(count: number): string {
2
+ if (count < 1000) {
3
+ return count.toString();
4
+ } else if (count < 1000000) {
5
+ const thousands = count / 1000;
6
+ return thousands % 1 === 0 ? `${thousands}K` : `${thousands.toFixed(1)}K`;
7
+ } else if (count < 1000000000) {
8
+ const millions = count / 1000000;
9
+ return millions % 1 === 0 ? `${millions}M` : `${millions.toFixed(1)}M`;
10
+ } else {
11
+ const billions = count / 1000000000;
12
+ return billions % 1 === 0 ? `${billions}B` : `${billions.toFixed(1)}B`;
13
+ }
14
+ }
File without changes
File without changes