@zezosoft/zezo-ott-react-native-ui-kit 1.1.2 → 1.1.3
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/lib/module/components/Auth/QrLogin/QrLogin.js +304 -138
- package/lib/module/components/Auth/QrLogin/QrLogin.js.map +1 -1
- package/lib/module/components/Auth/QrLogin/components/QrViewArea.js +193 -141
- package/lib/module/components/Auth/QrLogin/components/QrViewArea.js.map +1 -1
- package/lib/module/components/Content/Card/Category/Category.js +83 -11
- package/lib/module/components/Content/Card/Category/Category.js.map +1 -1
- package/lib/module/components/Content/Card/NowWatching/NowWatching.js +237 -108
- package/lib/module/components/Content/Card/NowWatching/NowWatching.js.map +1 -1
- package/lib/module/components/Content/Card/Sliders/Styles/One.js +185 -126
- package/lib/module/components/Content/Card/Sliders/Styles/One.js.map +1 -1
- package/lib/module/components/Content/Card/Sliders/Styles/Two.js +139 -92
- package/lib/module/components/Content/Card/Sliders/Styles/Two.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/Five.js +131 -48
- package/lib/module/components/Content/Card/Styles/Five.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/Four.js +126 -59
- package/lib/module/components/Content/Card/Styles/Four.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/One.js +125 -50
- package/lib/module/components/Content/Card/Styles/One.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/RotateInOut.js +138 -53
- package/lib/module/components/Content/Card/Styles/RotateInOut.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/Six.js +207 -115
- package/lib/module/components/Content/Card/Styles/Six.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/Three.js +134 -79
- package/lib/module/components/Content/Card/Styles/Three.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/TopTen.js +186 -171
- package/lib/module/components/Content/Card/Styles/TopTen.js.map +1 -1
- package/lib/module/components/Content/Card/Styles/Two.js +144 -64
- package/lib/module/components/Content/Card/Styles/Two.js.map +1 -1
- package/lib/module/components/Content/Card/components/AdsPoster.js +162 -0
- package/lib/module/components/Content/Card/components/AdsPoster.js.map +1 -0
- package/lib/module/components/Content/Card/components/CardPoster.js +120 -136
- package/lib/module/components/Content/Card/components/CardPoster.js.map +1 -1
- package/lib/module/components/Content/Card/components/index.js +4 -0
- package/lib/module/components/Content/Card/components/index.js.map +1 -0
- package/lib/module/components/Content/Content.js +67 -27
- package/lib/module/components/Content/Content.js.map +1 -1
- package/lib/module/components/Content/Sections.js +32 -11
- package/lib/module/components/Content/Sections.js.map +1 -1
- package/lib/module/constants/dummySections.js +44 -4
- package/lib/module/constants/dummySections.js.map +1 -1
- package/lib/module/hooks/Images/index.js +5 -0
- package/lib/module/hooks/Images/index.js.map +1 -0
- package/lib/module/hooks/Images/useImageLoader.js +168 -0
- package/lib/module/hooks/Images/useImageLoader.js.map +1 -0
- package/lib/module/hooks/Images/useImageValidation.js +36 -0
- package/lib/module/hooks/Images/useImageValidation.js.map +1 -0
- package/lib/module/hooks/index.js +3 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useAdTracking.js +270 -0
- package/lib/module/hooks/useAdTracking.js.map +1 -0
- package/lib/module/hooks/useCards.js +164 -0
- package/lib/module/hooks/useCards.js.map +1 -0
- package/lib/module/hooks/usePaginatedSection.js +11 -6
- package/lib/module/hooks/usePaginatedSection.js.map +1 -1
- package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts +2 -0
- package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts.map +1 -1
- package/lib/typescript/src/components/Auth/QrLogin/components/QrViewArea.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Category/Category.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/NowWatching/NowWatching.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Sliders/Styles/One.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Sliders/Styles/Two.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/Five.d.ts +13 -1
- package/lib/typescript/src/components/Content/Card/Styles/Five.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/Four.d.ts +13 -1
- package/lib/typescript/src/components/Content/Card/Styles/Four.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/One.d.ts +15 -3
- package/lib/typescript/src/components/Content/Card/Styles/One.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/RotateInOut.d.ts +13 -1
- package/lib/typescript/src/components/Content/Card/Styles/RotateInOut.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/Six.d.ts +1 -0
- package/lib/typescript/src/components/Content/Card/Styles/Six.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/Three.d.ts +13 -5
- package/lib/typescript/src/components/Content/Card/Styles/Three.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/TopTen.d.ts +1 -0
- package/lib/typescript/src/components/Content/Card/Styles/TopTen.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/Styles/Two.d.ts +13 -1
- package/lib/typescript/src/components/Content/Card/Styles/Two.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/components/AdsPoster.d.ts +26 -0
- package/lib/typescript/src/components/Content/Card/components/AdsPoster.d.ts.map +1 -0
- package/lib/typescript/src/components/Content/Card/components/CardPoster.d.ts +3 -1
- package/lib/typescript/src/components/Content/Card/components/CardPoster.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/components/index.d.ts +2 -0
- package/lib/typescript/src/components/Content/Card/components/index.d.ts.map +1 -0
- package/lib/typescript/src/components/Content/Card/index.d.ts +76 -6
- package/lib/typescript/src/components/Content/Card/index.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Content.d.ts +4 -3
- package/lib/typescript/src/components/Content/Content.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Sections.d.ts +20 -6
- package/lib/typescript/src/components/Content/Sections.d.ts.map +1 -1
- package/lib/typescript/src/constants/dummySections.d.ts +5 -0
- package/lib/typescript/src/constants/dummySections.d.ts.map +1 -1
- package/lib/typescript/src/hooks/Images/index.d.ts +3 -0
- package/lib/typescript/src/hooks/Images/index.d.ts.map +1 -0
- package/lib/typescript/src/hooks/Images/useImageLoader.d.ts +36 -0
- package/lib/typescript/src/hooks/Images/useImageLoader.d.ts.map +1 -0
- package/lib/typescript/src/hooks/Images/useImageValidation.d.ts +17 -0
- package/lib/typescript/src/hooks/Images/useImageValidation.d.ts.map +1 -0
- package/lib/typescript/src/hooks/index.d.ts +3 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useAdTracking.d.ts +39 -0
- package/lib/typescript/src/hooks/useAdTracking.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useCards.d.ts +36 -0
- package/lib/typescript/src/hooks/useCards.d.ts.map +1 -0
- package/lib/typescript/src/hooks/usePaginatedSection.d.ts +12 -2
- package/lib/typescript/src/hooks/usePaginatedSection.d.ts.map +1 -1
- package/lib/typescript/src/types/sections/index.d.ts +7 -4
- package/lib/typescript/src/types/sections/index.d.ts.map +1 -1
- package/package.json +6 -3
- package/src/components/Auth/QrLogin/QrLogin.tsx +382 -122
- package/src/components/Auth/QrLogin/components/QrViewArea.tsx +291 -197
- package/src/components/Content/Card/Category/Category.tsx +95 -8
- package/src/components/Content/Card/NowWatching/NowWatching.tsx +281 -136
- package/src/components/Content/Card/Sliders/Styles/One.tsx +244 -148
- package/src/components/Content/Card/Sliders/Styles/Two.tsx +171 -102
- package/src/components/Content/Card/Styles/Five.tsx +161 -62
- package/src/components/Content/Card/Styles/Four.tsx +164 -85
- package/src/components/Content/Card/Styles/One.tsx +161 -71
- package/src/components/Content/Card/Styles/RotateInOut.tsx +157 -60
- package/src/components/Content/Card/Styles/Six.tsx +242 -142
- package/src/components/Content/Card/Styles/Three.tsx +166 -133
- package/src/components/Content/Card/Styles/TopTen.tsx +230 -191
- package/src/components/Content/Card/Styles/Two.tsx +182 -79
- package/src/components/Content/Card/components/AdsPoster.tsx +202 -0
- package/src/components/Content/Card/components/CardPoster.tsx +134 -154
- package/src/components/Content/Card/components/index.ts +1 -0
- package/src/components/Content/Content.tsx +83 -45
- package/src/components/Content/Sections.tsx +51 -10
- package/src/constants/dummySections.ts +48 -1
- package/src/hooks/Images/index.ts +2 -0
- package/src/hooks/Images/useImageLoader.ts +206 -0
- package/src/hooks/Images/useImageValidation.ts +36 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useAdTracking.ts +349 -0
- package/src/hooks/useCards.ts +228 -0
- package/src/hooks/usePaginatedSection.ts +26 -7
- package/src/types/sections/index.ts +7 -4
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @LastModified Sat 28 Jun 2025 at 01:00 AM
|
|
4
4
|
**/
|
|
5
5
|
|
|
6
|
-
import React, { memo, useCallback, useRef } from 'react';
|
|
6
|
+
import React, { memo, useCallback, useMemo, useRef } from 'react';
|
|
7
7
|
import {
|
|
8
8
|
View,
|
|
9
9
|
FlatList,
|
|
@@ -24,7 +24,6 @@ import { useInternalTheme } from '../../../../theme/hook/useInternalTheme';
|
|
|
24
24
|
import NavigateToMore from '../components/NavigateToMore';
|
|
25
25
|
import { ThumbnailCard } from '../components/ThumbnailCard';
|
|
26
26
|
import { Text } from '../../../Text';
|
|
27
|
-
import { usePaginatedSection } from '../../../../hooks/usePaginatedSection';
|
|
28
27
|
import type { ThemeOverride } from '../../../../theme/themes';
|
|
29
28
|
import type {
|
|
30
29
|
IGetSectionData,
|
|
@@ -34,10 +33,42 @@ import type {
|
|
|
34
33
|
import { RFValue } from 'react-native-responsive-fontsize';
|
|
35
34
|
import RentOrBuyIcon from '../components/RentOrBuyIcon';
|
|
36
35
|
import type { IContentData } from '@zezosoft/zezo-ott-api-client';
|
|
36
|
+
import { useCards } from '../../../../hooks';
|
|
37
|
+
|
|
38
|
+
// Default dimensions and styling constants
|
|
37
39
|
const DEFAULT_ITEM_WIDTH = moderateScale(160);
|
|
38
40
|
const DEFAULT_BORDER_RADIUS = moderateScale(5);
|
|
39
41
|
const DEFAULT_SKELETON_COUNT = 3;
|
|
40
42
|
|
|
43
|
+
// Spacing constants
|
|
44
|
+
const ITEM_MARGIN_LEFT = moderateScale(10);
|
|
45
|
+
const ITEM_MARGIN_TOP = verticalScale(4);
|
|
46
|
+
const FIRST_SKELETON_MARGIN_LEFT = moderateScale(12);
|
|
47
|
+
const SKELETON_MARGIN_RIGHT = moderateScale(12);
|
|
48
|
+
const CONTAINER_PADDING_HORIZONTAL = moderateScale(10);
|
|
49
|
+
const CONTAINER_MARGIN_BOTTOM = verticalScale(8);
|
|
50
|
+
const ROOT_MARGIN_VERTICAL = verticalScale(6);
|
|
51
|
+
const LIST_PADDING_RIGHT = moderateScale(15);
|
|
52
|
+
|
|
53
|
+
// Skeleton styling constants
|
|
54
|
+
const SKELETON_TITLE_WIDTH = moderateScale(100);
|
|
55
|
+
const SKELETON_TITLE_HEIGHT = moderateScale(20);
|
|
56
|
+
const SKELETON_TITLE_BORDER_RADIUS = moderateScale(4);
|
|
57
|
+
const SKELETON_TITLE_MARGIN_HORIZONTAL = moderateScale(15);
|
|
58
|
+
const SKELETON_TITLE_MARGIN_BOTTOM = verticalScale(6);
|
|
59
|
+
const SKELETON_THUMBNAIL_HEIGHT_RATIO = 9 / 16;
|
|
60
|
+
const SKELETON_TEXT_WIDTH_RATIO = 0.8;
|
|
61
|
+
const SKELETON_TEXT_HEIGHT = moderateScale(13);
|
|
62
|
+
const SKELETON_TEXT_BORDER_RADIUS = moderateScale(3);
|
|
63
|
+
const SKELETON_TEXT_MARGIN_TOP = verticalScale(6);
|
|
64
|
+
|
|
65
|
+
// FlatList performance constants
|
|
66
|
+
const INITIAL_NUM_TO_RENDER = 5;
|
|
67
|
+
const ON_END_REACHED_THRESHOLD = 0.5;
|
|
68
|
+
|
|
69
|
+
// Touchable opacity constant
|
|
70
|
+
const ACTIVE_OPACITY = 0.8;
|
|
71
|
+
|
|
41
72
|
type MovieCardSixProps = {
|
|
42
73
|
theme?: ThemeOverride;
|
|
43
74
|
title: string;
|
|
@@ -54,6 +85,7 @@ type MovieCardSixProps = {
|
|
|
54
85
|
itemWidth?: number;
|
|
55
86
|
borderRadius?: number;
|
|
56
87
|
skeletonCount?: number;
|
|
88
|
+
paginationSkeletonCount?: number;
|
|
57
89
|
containerStyle?: StyleProp<ViewStyle>;
|
|
58
90
|
titleStyle?: StyleProp<TextStyle>;
|
|
59
91
|
itemStyle?: StyleProp<ViewStyle>;
|
|
@@ -65,13 +97,14 @@ const MovieCardSix: React.FC<MovieCardSixProps> = ({
|
|
|
65
97
|
title,
|
|
66
98
|
section_id,
|
|
67
99
|
type,
|
|
68
|
-
data:
|
|
100
|
+
data: externalData,
|
|
69
101
|
moreFetchData,
|
|
70
102
|
onPressItem,
|
|
71
103
|
onPressMore,
|
|
72
104
|
itemWidth = DEFAULT_ITEM_WIDTH,
|
|
73
105
|
borderRadius = DEFAULT_BORDER_RADIUS,
|
|
74
106
|
skeletonCount = DEFAULT_SKELETON_COUNT,
|
|
107
|
+
paginationSkeletonCount,
|
|
75
108
|
containerStyle,
|
|
76
109
|
titleStyle,
|
|
77
110
|
itemStyle,
|
|
@@ -79,22 +112,31 @@ const MovieCardSix: React.FC<MovieCardSixProps> = ({
|
|
|
79
112
|
accessibilityLabel,
|
|
80
113
|
accessibilityHint,
|
|
81
114
|
}) => {
|
|
115
|
+
// Refs
|
|
82
116
|
const flatListRef = useRef<FlatList<IContentData>>(null);
|
|
83
117
|
const onEndReachedCalledDuringMomentum = useRef(false);
|
|
84
|
-
const { theme: appliedTheme } = useInternalTheme(theme);
|
|
85
118
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
moreFetchData,
|
|
89
|
-
initialData?.data,
|
|
90
|
-
isLoading
|
|
91
|
-
);
|
|
119
|
+
// Theme
|
|
120
|
+
const { theme: appliedTheme } = useInternalTheme(theme);
|
|
92
121
|
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
122
|
+
// Data management using custom hook
|
|
123
|
+
const {
|
|
124
|
+
listData,
|
|
125
|
+
pagination,
|
|
126
|
+
loadMore,
|
|
127
|
+
isEmpty,
|
|
128
|
+
isPaging: isPaginating,
|
|
129
|
+
} = useCards({
|
|
130
|
+
sectionId: section_id,
|
|
131
|
+
data: externalData,
|
|
132
|
+
fetchMore: moreFetchData,
|
|
133
|
+
loading: isLoading,
|
|
134
|
+
initialSkeleton: skeletonCount,
|
|
135
|
+
pagingSkeleton: paginationSkeletonCount,
|
|
136
|
+
adsRender: false,
|
|
137
|
+
});
|
|
97
138
|
|
|
139
|
+
// Event handlers
|
|
98
140
|
const handleItemPress = useCallback(
|
|
99
141
|
(item: IContentData) => {
|
|
100
142
|
onPressItem?.(item);
|
|
@@ -113,161 +155,219 @@ const MovieCardSix: React.FC<MovieCardSixProps> = ({
|
|
|
113
155
|
pagination?.nextPage
|
|
114
156
|
) {
|
|
115
157
|
onEndReachedCalledDuringMomentum.current = true;
|
|
116
|
-
|
|
158
|
+
loadMore(pagination.nextPage);
|
|
117
159
|
}
|
|
118
|
-
}, [pagination?.hasNextPage, pagination?.nextPage,
|
|
160
|
+
}, [pagination?.hasNextPage, pagination?.nextPage, loadMore]);
|
|
161
|
+
|
|
162
|
+
const handleScrollBeginDrag = useCallback(() => {
|
|
163
|
+
onEndReachedCalledDuringMomentum.current = false;
|
|
164
|
+
}, []);
|
|
119
165
|
|
|
166
|
+
const handleMomentumScrollBegin = useCallback(() => {
|
|
167
|
+
onEndReachedCalledDuringMomentum.current = false;
|
|
168
|
+
}, []);
|
|
169
|
+
|
|
170
|
+
// Generate key for FlatList items
|
|
171
|
+
const keyExtractor = useCallback(
|
|
172
|
+
(item: IContentData, index: number) => `${item._id}-${index}`,
|
|
173
|
+
[]
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// Render functions
|
|
120
177
|
const renderItem = useCallback(
|
|
121
|
-
({ item }: ListRenderItemInfo<IContentData>) =>
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
178
|
+
({ item }: ListRenderItemInfo<IContentData>) => {
|
|
179
|
+
const thumbnailWrapperStyle = { width: itemWidth };
|
|
180
|
+
const titleContainerStyle = {
|
|
181
|
+
width: itemWidth,
|
|
182
|
+
marginTop: ITEM_MARGIN_TOP,
|
|
183
|
+
};
|
|
184
|
+
const titleTextStyle = {
|
|
185
|
+
color: appliedTheme.colors.textPrimary,
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<TouchableOpacity
|
|
190
|
+
style={[styles.item, itemStyle]}
|
|
191
|
+
onPress={() => handleItemPress(item)}
|
|
192
|
+
activeOpacity={ACTIVE_OPACITY}
|
|
193
|
+
>
|
|
194
|
+
<RentOrBuyIcon
|
|
195
|
+
theme={appliedTheme}
|
|
196
|
+
content_offering_type={item.content_offering_type}
|
|
197
|
+
/>
|
|
198
|
+
<ThumbnailCard
|
|
199
|
+
thumbnailUri={item.thumbnail}
|
|
200
|
+
theme={appliedTheme}
|
|
201
|
+
isLoading={false}
|
|
202
|
+
borderRadius={borderRadius}
|
|
203
|
+
wrapperStyle={thumbnailWrapperStyle}
|
|
204
|
+
resizeMode={FastImage.resizeMode.cover}
|
|
205
|
+
/>
|
|
206
|
+
<View style={titleContainerStyle}>
|
|
207
|
+
<Text style={[styles.itemTitle, titleTextStyle]} numberOfLines={1}>
|
|
208
|
+
{item.name}
|
|
209
|
+
</Text>
|
|
210
|
+
</View>
|
|
211
|
+
</TouchableOpacity>
|
|
212
|
+
);
|
|
213
|
+
},
|
|
152
214
|
[handleItemPress, itemStyle, appliedTheme, borderRadius, itemWidth]
|
|
153
215
|
);
|
|
154
216
|
|
|
155
217
|
const renderSkeletonItem = useCallback(
|
|
156
|
-
(index: number) =>
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
marginRight={moderateScale(12)}
|
|
218
|
+
(index: number) => {
|
|
219
|
+
const isFirstSkeleton = index === 0;
|
|
220
|
+
const thumbnailHeight = itemWidth * SKELETON_THUMBNAIL_HEIGHT_RATIO;
|
|
221
|
+
const textWidth = itemWidth * SKELETON_TEXT_WIDTH_RATIO;
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<SkeletonPlaceholder
|
|
225
|
+
key={`skeleton-${index}`}
|
|
226
|
+
highlightColor={appliedTheme.colors.skeletonHighlightColor}
|
|
227
|
+
backgroundColor={appliedTheme.colors.skeletonBaseColor}
|
|
228
|
+
borderRadius={borderRadius}
|
|
168
229
|
>
|
|
169
|
-
{/* Thumbnail */}
|
|
170
230
|
<SkeletonPlaceholder.Item
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
231
|
+
flexDirection="column"
|
|
232
|
+
alignItems="flex-start"
|
|
233
|
+
marginLeft={isFirstSkeleton ? FIRST_SKELETON_MARGIN_LEFT : 0}
|
|
234
|
+
marginRight={SKELETON_MARGIN_RIGHT}
|
|
235
|
+
>
|
|
236
|
+
{/* Thumbnail */}
|
|
237
|
+
<SkeletonPlaceholder.Item
|
|
238
|
+
width={itemWidth}
|
|
239
|
+
height={thumbnailHeight}
|
|
240
|
+
borderRadius={borderRadius}
|
|
241
|
+
/>
|
|
175
242
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
243
|
+
{/* Title */}
|
|
244
|
+
<SkeletonPlaceholder.Item
|
|
245
|
+
width={textWidth}
|
|
246
|
+
height={SKELETON_TEXT_HEIGHT}
|
|
247
|
+
borderRadius={SKELETON_TEXT_BORDER_RADIUS}
|
|
248
|
+
marginTop={SKELETON_TEXT_MARGIN_TOP}
|
|
249
|
+
/>
|
|
250
|
+
</SkeletonPlaceholder.Item>
|
|
251
|
+
</SkeletonPlaceholder>
|
|
252
|
+
);
|
|
253
|
+
},
|
|
186
254
|
[appliedTheme.colors, itemWidth, borderRadius]
|
|
187
255
|
);
|
|
188
|
-
|
|
256
|
+
|
|
257
|
+
// Filter out ads to ensure only IContentData items are passed to FlatList
|
|
258
|
+
const contentData = useMemo(
|
|
259
|
+
() =>
|
|
260
|
+
listData.filter(
|
|
261
|
+
(item): item is IContentData => !('type' in item && item.type === 'ads')
|
|
262
|
+
),
|
|
263
|
+
[listData]
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
// Render pagination skeleton footer
|
|
267
|
+
const renderPaginationSkeleton = useCallback(() => {
|
|
268
|
+
if (!isPaginating) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
return renderSkeletonItem(0);
|
|
272
|
+
}, [isPaginating, renderSkeletonItem]);
|
|
273
|
+
|
|
274
|
+
// Early returns for edge cases
|
|
275
|
+
if (!externalData) {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const shouldHideSection = !isLoading && contentData.length === 0 && !isEmpty;
|
|
280
|
+
if (shouldHideSection) {
|
|
189
281
|
return null;
|
|
190
282
|
}
|
|
191
|
-
if (!isLoading && sectionData.length === 0) return null;
|
|
192
283
|
|
|
284
|
+
// Loading skeleton state
|
|
285
|
+
if (isLoading) {
|
|
286
|
+
const skeletonDataLength = isPaginating ? 1 : skeletonCount;
|
|
287
|
+
const skeletonData = Array.from(
|
|
288
|
+
{ length: skeletonDataLength },
|
|
289
|
+
(_, i) => i
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<View
|
|
294
|
+
style={[styles.root, containerStyle]}
|
|
295
|
+
accessibilityLabel={accessibilityLabel || `Movie section: ${title}`}
|
|
296
|
+
accessibilityHint={accessibilityHint || 'Scroll to view content'}
|
|
297
|
+
>
|
|
298
|
+
<SkeletonPlaceholder
|
|
299
|
+
highlightColor={appliedTheme.colors.skeletonHighlightColor}
|
|
300
|
+
backgroundColor={appliedTheme.colors.skeletonBaseColor}
|
|
301
|
+
>
|
|
302
|
+
<SkeletonPlaceholder.Item
|
|
303
|
+
width={SKELETON_TITLE_WIDTH}
|
|
304
|
+
height={SKELETON_TITLE_HEIGHT}
|
|
305
|
+
borderRadius={SKELETON_TITLE_BORDER_RADIUS}
|
|
306
|
+
marginHorizontal={SKELETON_TITLE_MARGIN_HORIZONTAL}
|
|
307
|
+
marginBottom={SKELETON_TITLE_MARGIN_BOTTOM}
|
|
308
|
+
/>
|
|
309
|
+
</SkeletonPlaceholder>
|
|
310
|
+
<ScrollView
|
|
311
|
+
horizontal
|
|
312
|
+
showsHorizontalScrollIndicator={false}
|
|
313
|
+
contentContainerStyle={styles.skeletonList}
|
|
314
|
+
>
|
|
315
|
+
{skeletonData.map((index) => renderSkeletonItem(index))}
|
|
316
|
+
</ScrollView>
|
|
317
|
+
</View>
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Main content render
|
|
193
322
|
return (
|
|
194
323
|
<View
|
|
195
324
|
style={[styles.root, containerStyle]}
|
|
196
325
|
accessibilityLabel={accessibilityLabel || `Movie section: ${title}`}
|
|
197
326
|
accessibilityHint={accessibilityHint || 'Scroll to view content'}
|
|
198
327
|
>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
titleStyle={[
|
|
229
|
-
styles.title,
|
|
230
|
-
{ color: appliedTheme.colors.textPrimary },
|
|
231
|
-
titleStyle,
|
|
232
|
-
]}
|
|
233
|
-
containerStyle={styles.navigateToMoreContainer}
|
|
234
|
-
showAllProps={{ iconColor: appliedTheme.colors.textPrimary, theme }}
|
|
235
|
-
/>
|
|
236
|
-
<FlatList
|
|
237
|
-
ref={flatListRef}
|
|
238
|
-
data={sectionData}
|
|
239
|
-
horizontal
|
|
240
|
-
keyExtractor={(item, index) => `${item._id}-${index}`}
|
|
241
|
-
renderItem={renderItem}
|
|
242
|
-
showsHorizontalScrollIndicator={false}
|
|
243
|
-
contentContainerStyle={styles.listContent}
|
|
244
|
-
initialNumToRender={5}
|
|
245
|
-
onEndReached={handleEndReached}
|
|
246
|
-
onEndReachedThreshold={0.5}
|
|
247
|
-
onScrollBeginDrag={() => {
|
|
248
|
-
onEndReachedCalledDuringMomentum.current = false;
|
|
249
|
-
}}
|
|
250
|
-
onMomentumScrollBegin={() => {
|
|
251
|
-
onEndReachedCalledDuringMomentum.current = false;
|
|
252
|
-
}}
|
|
253
|
-
ListFooterComponent={isPaginating ? renderSkeletonItem(0) : null}
|
|
254
|
-
/>
|
|
255
|
-
</>
|
|
256
|
-
)}
|
|
328
|
+
<NavigateToMore
|
|
329
|
+
title={title}
|
|
330
|
+
onPress={handlePressMore}
|
|
331
|
+
titleStyle={[
|
|
332
|
+
styles.title,
|
|
333
|
+
{ color: appliedTheme.colors.textPrimary },
|
|
334
|
+
titleStyle,
|
|
335
|
+
]}
|
|
336
|
+
containerStyle={styles.navigateToMoreContainer}
|
|
337
|
+
showAllProps={{
|
|
338
|
+
iconColor: appliedTheme.colors.textPrimary,
|
|
339
|
+
theme,
|
|
340
|
+
}}
|
|
341
|
+
/>
|
|
342
|
+
<FlatList
|
|
343
|
+
ref={flatListRef}
|
|
344
|
+
data={contentData}
|
|
345
|
+
horizontal
|
|
346
|
+
keyExtractor={keyExtractor}
|
|
347
|
+
renderItem={renderItem}
|
|
348
|
+
showsHorizontalScrollIndicator={false}
|
|
349
|
+
contentContainerStyle={styles.listContent}
|
|
350
|
+
initialNumToRender={INITIAL_NUM_TO_RENDER}
|
|
351
|
+
onEndReached={handleEndReached}
|
|
352
|
+
onEndReachedThreshold={ON_END_REACHED_THRESHOLD}
|
|
353
|
+
onScrollBeginDrag={handleScrollBeginDrag}
|
|
354
|
+
onMomentumScrollBegin={handleMomentumScrollBegin}
|
|
355
|
+
ListFooterComponent={renderPaginationSkeleton}
|
|
356
|
+
/>
|
|
257
357
|
</View>
|
|
258
358
|
);
|
|
259
359
|
};
|
|
260
360
|
|
|
261
361
|
const styles = StyleSheet.create({
|
|
262
362
|
root: {
|
|
263
|
-
marginVertical:
|
|
363
|
+
marginVertical: ROOT_MARGIN_VERTICAL,
|
|
264
364
|
},
|
|
265
365
|
item: {
|
|
266
|
-
marginLeft:
|
|
366
|
+
marginLeft: ITEM_MARGIN_LEFT,
|
|
267
367
|
},
|
|
268
368
|
navigateToMoreContainer: {
|
|
269
|
-
paddingHorizontal:
|
|
270
|
-
marginBottom:
|
|
369
|
+
paddingHorizontal: CONTAINER_PADDING_HORIZONTAL,
|
|
370
|
+
marginBottom: CONTAINER_MARGIN_BOTTOM,
|
|
271
371
|
},
|
|
272
372
|
title: {
|
|
273
373
|
fontSize: RFValue(13),
|
|
@@ -276,16 +376,16 @@ const styles = StyleSheet.create({
|
|
|
276
376
|
itemTitle: {
|
|
277
377
|
fontSize: RFValue(9),
|
|
278
378
|
fontWeight: '500',
|
|
279
|
-
lineHeight:
|
|
280
|
-
height:
|
|
379
|
+
lineHeight: SKELETON_TEXT_HEIGHT,
|
|
380
|
+
height: SKELETON_TEXT_HEIGHT,
|
|
281
381
|
},
|
|
282
382
|
listContent: {
|
|
283
|
-
paddingRight:
|
|
383
|
+
paddingRight: LIST_PADDING_RIGHT,
|
|
284
384
|
},
|
|
285
385
|
skeletonList: {
|
|
286
386
|
flexDirection: 'row',
|
|
287
387
|
alignItems: 'flex-start',
|
|
288
|
-
paddingRight:
|
|
388
|
+
paddingRight: LIST_PADDING_RIGHT,
|
|
289
389
|
},
|
|
290
390
|
});
|
|
291
391
|
|