@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
|
@@ -27,13 +27,31 @@ import { ThumbnailCard } from '../../components/ThumbnailCard';
|
|
|
27
27
|
import type { ThemeOverride } from '../../../../../theme/themes';
|
|
28
28
|
import type { IContentData } from '@zezosoft/zezo-ott-api-client';
|
|
29
29
|
|
|
30
|
+
// ============================================================================
|
|
30
31
|
// Constants
|
|
32
|
+
// ============================================================================
|
|
31
33
|
const DEFAULT_SKELETON_COUNT = 3;
|
|
32
34
|
const CAROUSEL_WIDTH = Display.fullWidth;
|
|
33
35
|
const CAROUSEL_HEIGHT = verticalScale(180);
|
|
34
36
|
const BORDER_RADIUS = scale(10);
|
|
37
|
+
const SCROLL_ANIMATION_DURATION = 1000;
|
|
38
|
+
const AUTO_PLAY_INTERVAL = 2500;
|
|
39
|
+
const PARALLAX_SCROLLING_OFFSET = 48;
|
|
40
|
+
const PARALLAX_SCROLLING_SCALE = 0.9;
|
|
41
|
+
const PAN_GESTURE_ACTIVE_OFFSET_X = [-10, 10];
|
|
42
|
+
const PAN_GESTURE_FAIL_OFFSET_Y = [-5, 5];
|
|
43
|
+
const GRADIENT_OVERLAY_COLORS = ['transparent', 'rgba(0,0,0,0.6)'];
|
|
44
|
+
const INDICATOR_WIDTH_ACTIVE = scale(18);
|
|
45
|
+
const INDICATOR_WIDTH_INACTIVE = scale(8);
|
|
46
|
+
const INDICATOR_HEIGHT = scale(8);
|
|
47
|
+
const INDICATOR_BORDER_RADIUS = scale(50);
|
|
48
|
+
const PLAY_ICON_SIZE = scale(25);
|
|
49
|
+
const PLAY_ICON_CONTAINER_SIZE = scale(40);
|
|
50
|
+
const PLAY_TEXT_MAX_WIDTH = scale(220);
|
|
35
51
|
|
|
36
|
-
//
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Types
|
|
54
|
+
// ============================================================================
|
|
37
55
|
type SliderOneProps = {
|
|
38
56
|
index: number;
|
|
39
57
|
data: ISectionContent | null;
|
|
@@ -44,12 +62,15 @@ type SliderOneProps = {
|
|
|
44
62
|
theme?: ThemeOverride;
|
|
45
63
|
} & AccessibilityProps;
|
|
46
64
|
|
|
47
|
-
// ImageTouchable component
|
|
48
65
|
type ImageTouchableProps = {
|
|
49
66
|
children: React.ReactNode;
|
|
50
67
|
onImagePress?: () => void;
|
|
51
68
|
};
|
|
52
69
|
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// Helper Components
|
|
72
|
+
// ============================================================================
|
|
73
|
+
|
|
53
74
|
const ImageTouchable = memo<ImageTouchableProps>(
|
|
54
75
|
({ children, onImagePress }) => (
|
|
55
76
|
<TouchableOpacity
|
|
@@ -64,7 +85,11 @@ const ImageTouchable = memo<ImageTouchableProps>(
|
|
|
64
85
|
)
|
|
65
86
|
);
|
|
66
87
|
|
|
67
|
-
|
|
88
|
+
ImageTouchable.displayName = 'ImageTouchable';
|
|
89
|
+
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Main Component
|
|
92
|
+
// ============================================================================
|
|
68
93
|
const SliderOne: React.FC<SliderOneProps> = ({
|
|
69
94
|
index,
|
|
70
95
|
data,
|
|
@@ -76,99 +101,162 @@ const SliderOne: React.FC<SliderOneProps> = ({
|
|
|
76
101
|
accessibilityLabel = 'Content carousel',
|
|
77
102
|
accessibilityHint = 'Swipe to view content',
|
|
78
103
|
}) => {
|
|
104
|
+
// ========================================================================
|
|
105
|
+
// Hooks & State
|
|
106
|
+
// ========================================================================
|
|
79
107
|
const { theme: appliedTheme } = useInternalTheme(theme);
|
|
80
|
-
const contentData = useMemo(() => data?.data ?? [], [data]);
|
|
81
108
|
const [activeIndex, setActiveIndex] = useState<number>(0);
|
|
82
109
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
110
|
+
// ========================================================================
|
|
111
|
+
// Data Processing
|
|
112
|
+
// ========================================================================
|
|
113
|
+
const contentData = useMemo(
|
|
114
|
+
() =>
|
|
115
|
+
(data?.data ?? []).filter(
|
|
116
|
+
(item): item is IContentData => !('type' in item && item.type === 'ads')
|
|
117
|
+
),
|
|
118
|
+
[data]
|
|
86
119
|
);
|
|
87
120
|
|
|
88
|
-
const handleSnapToItem = useCallback((i: number) => setActiveIndex(i), []);
|
|
89
|
-
|
|
90
|
-
// Memoize skeleton items
|
|
91
121
|
const skeletonItems = useSkeletonItems(skeletonCount);
|
|
92
122
|
|
|
93
|
-
// Memoize indicator array
|
|
94
123
|
const indicatorArray = useMemo(
|
|
95
|
-
() =>
|
|
96
|
-
|
|
124
|
+
() =>
|
|
125
|
+
Array.from(
|
|
126
|
+
{ length: isLoading ? skeletonItems.length : contentData.length },
|
|
127
|
+
(_, i) => i
|
|
128
|
+
),
|
|
129
|
+
[isLoading, skeletonItems.length, contentData.length]
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// ========================================================================
|
|
133
|
+
// Memoized Values
|
|
134
|
+
// ========================================================================
|
|
135
|
+
const gradientColors = useMemo(
|
|
136
|
+
() => [appliedTheme.colors.primary, appliedTheme.colors.primary],
|
|
137
|
+
[appliedTheme.colors.primary]
|
|
97
138
|
);
|
|
98
139
|
|
|
99
|
-
// Memoize play icon style
|
|
100
140
|
const playIconStyle = useMemo(
|
|
101
141
|
() => [styles.playIcon, { backgroundColor: appliedTheme.colors.button }],
|
|
102
142
|
[appliedTheme.colors.button]
|
|
103
143
|
);
|
|
104
144
|
|
|
105
|
-
// Memoize play text style
|
|
106
145
|
const playTextStyle = useMemo(
|
|
107
146
|
() => [styles.playText, { color: appliedTheme.colors.white }],
|
|
108
147
|
[appliedTheme.colors.white]
|
|
109
148
|
);
|
|
110
149
|
|
|
111
|
-
|
|
150
|
+
const carouselProps = useMemo(
|
|
151
|
+
() => ({
|
|
152
|
+
width: CAROUSEL_WIDTH,
|
|
153
|
+
height: CAROUSEL_HEIGHT,
|
|
154
|
+
autoPlay: !isLoading && contentData.length > 1,
|
|
155
|
+
loop: !isLoading && contentData.length > 1,
|
|
156
|
+
scrollAnimationDuration: SCROLL_ANIMATION_DURATION,
|
|
157
|
+
autoPlayInterval: AUTO_PLAY_INTERVAL,
|
|
158
|
+
style: styles.carousel,
|
|
159
|
+
// Optimize rendering
|
|
160
|
+
windowSize: 3,
|
|
161
|
+
enabled: true,
|
|
162
|
+
}),
|
|
163
|
+
[isLoading, contentData.length]
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
const parallaxConfig = useMemo(
|
|
167
|
+
() => ({
|
|
168
|
+
parallaxScrollingOffset: PARALLAX_SCROLLING_OFFSET,
|
|
169
|
+
parallaxScrollingScale: PARALLAX_SCROLLING_SCALE,
|
|
170
|
+
}),
|
|
171
|
+
[]
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
const panGestureConfig = useCallback(
|
|
175
|
+
(gesture: any) =>
|
|
176
|
+
gesture
|
|
177
|
+
.activeOffsetX(PAN_GESTURE_ACTIVE_OFFSET_X)
|
|
178
|
+
.failOffsetY(PAN_GESTURE_FAIL_OFFSET_Y),
|
|
179
|
+
[]
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
// ========================================================================
|
|
183
|
+
// Event Handlers
|
|
184
|
+
// ========================================================================
|
|
185
|
+
const handleSnapToItem = useCallback((i: number) => setActiveIndex(i), []);
|
|
186
|
+
|
|
187
|
+
const handleItemPress = useCallback(
|
|
188
|
+
(item: IContentData) => {
|
|
189
|
+
onPressItem?.(item);
|
|
190
|
+
},
|
|
191
|
+
[onPressItem]
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// ========================================================================
|
|
195
|
+
// Render Functions
|
|
196
|
+
// ========================================================================
|
|
112
197
|
const renderCarouselItem = useCallback(
|
|
113
|
-
({ item }: { item: IContentData }) =>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
198
|
+
({ item }: { item: IContentData }) => {
|
|
199
|
+
const handlePress = () => handleItemPress(item);
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<View style={styles.sliderContainer}>
|
|
203
|
+
<ImageTouchable onImagePress={handlePress}>
|
|
204
|
+
<RentOrBuyIcon
|
|
205
|
+
theme={appliedTheme}
|
|
206
|
+
content_offering_type={item.content_offering_type}
|
|
207
|
+
/>
|
|
208
|
+
<ThumbnailCard
|
|
209
|
+
thumbnailUri={item.thumbnail}
|
|
210
|
+
theme={appliedTheme}
|
|
211
|
+
isLoading={false}
|
|
212
|
+
borderRadius={BORDER_RADIUS}
|
|
213
|
+
wrapperStyle={styles.imageWrapper}
|
|
214
|
+
imageStyle={styles.sliderImage}
|
|
215
|
+
resizeMode={FastImage.resizeMode.cover}
|
|
216
|
+
/>
|
|
217
|
+
{showPlayIcon && (
|
|
218
|
+
<LinearGradient
|
|
219
|
+
colors={GRADIENT_OVERLAY_COLORS}
|
|
220
|
+
style={styles.gradientOverlay}
|
|
221
|
+
>
|
|
222
|
+
<View style={styles.playOverlay}>
|
|
223
|
+
<TouchableOpacity
|
|
224
|
+
onPress={handlePress}
|
|
225
|
+
style={playIconStyle}
|
|
226
|
+
activeOpacity={0.8}
|
|
227
|
+
accessibilityRole="button"
|
|
228
|
+
accessibilityLabel="Play content"
|
|
229
|
+
>
|
|
230
|
+
<Play
|
|
231
|
+
size={PLAY_ICON_SIZE}
|
|
232
|
+
color={appliedTheme.colors.black}
|
|
233
|
+
fill={appliedTheme.colors.black}
|
|
234
|
+
/>
|
|
235
|
+
</TouchableOpacity>
|
|
236
|
+
<Text
|
|
237
|
+
style={playTextStyle}
|
|
238
|
+
numberOfLines={1}
|
|
239
|
+
accessibilityLabel={item.name}
|
|
240
|
+
>
|
|
241
|
+
{item.name}
|
|
242
|
+
</Text>
|
|
243
|
+
</View>
|
|
244
|
+
</LinearGradient>
|
|
245
|
+
)}
|
|
246
|
+
</ImageTouchable>
|
|
247
|
+
</View>
|
|
248
|
+
);
|
|
249
|
+
},
|
|
250
|
+
[appliedTheme, showPlayIcon, handleItemPress, playIconStyle, playTextStyle]
|
|
162
251
|
);
|
|
163
252
|
|
|
164
|
-
// Render skeleton item
|
|
165
253
|
const renderSkeletonItem = useCallback(
|
|
166
|
-
() => (
|
|
254
|
+
({ item: _item }: { item: any }) => (
|
|
167
255
|
<View style={styles.sliderContainer}>
|
|
168
256
|
<SkeletonPlaceholder
|
|
169
257
|
backgroundColor={appliedTheme.colors.skeletonBaseColor}
|
|
170
258
|
highlightColor={appliedTheme.colors.skeletonHighlightColor}
|
|
171
|
-
speed={
|
|
259
|
+
speed={SCROLL_ANIMATION_DURATION}
|
|
172
260
|
>
|
|
173
261
|
<SkeletonPlaceholder.Item
|
|
174
262
|
width={CAROUSEL_WIDTH}
|
|
@@ -178,42 +266,48 @@ const SliderOne: React.FC<SliderOneProps> = ({
|
|
|
178
266
|
</SkeletonPlaceholder>
|
|
179
267
|
</View>
|
|
180
268
|
),
|
|
181
|
-
[
|
|
269
|
+
[
|
|
270
|
+
appliedTheme.colors.skeletonBaseColor,
|
|
271
|
+
appliedTheme.colors.skeletonHighlightColor,
|
|
272
|
+
]
|
|
182
273
|
);
|
|
183
274
|
|
|
184
|
-
// Render indicator
|
|
185
275
|
const renderIndicator = useCallback(
|
|
186
|
-
(_: number, i: number) =>
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
276
|
+
(_: number, i: number) => {
|
|
277
|
+
const isActive = i === activeIndex;
|
|
278
|
+
|
|
279
|
+
return (
|
|
280
|
+
<View key={i} style={styles.indicatorWrapper}>
|
|
281
|
+
{isLoading ? (
|
|
282
|
+
<SkeletonPlaceholder
|
|
283
|
+
backgroundColor={appliedTheme.colors.skeletonBaseColor}
|
|
284
|
+
highlightColor={appliedTheme.colors.skeletonHighlightColor}
|
|
285
|
+
speed={AUTO_PLAY_INTERVAL}
|
|
286
|
+
>
|
|
287
|
+
<SkeletonPlaceholder.Item
|
|
288
|
+
width={INDICATOR_WIDTH_ACTIVE}
|
|
289
|
+
height={INDICATOR_HEIGHT}
|
|
290
|
+
borderRadius={INDICATOR_BORDER_RADIUS}
|
|
291
|
+
/>
|
|
292
|
+
</SkeletonPlaceholder>
|
|
293
|
+
) : isActive ? (
|
|
294
|
+
<LinearGradient
|
|
295
|
+
start={{ x: 0, y: 0 }}
|
|
296
|
+
end={{ x: 1, y: 0 }}
|
|
297
|
+
colors={gradientColors}
|
|
298
|
+
style={styles.activeIndicator}
|
|
198
299
|
/>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
styles.inactiveIndicator,
|
|
211
|
-
{ backgroundColor: appliedTheme.colors.onSurface },
|
|
212
|
-
]}
|
|
213
|
-
/>
|
|
214
|
-
)}
|
|
215
|
-
</View>
|
|
216
|
-
),
|
|
300
|
+
) : (
|
|
301
|
+
<View
|
|
302
|
+
style={[
|
|
303
|
+
styles.inactiveIndicator,
|
|
304
|
+
{ backgroundColor: appliedTheme.colors.onSurface },
|
|
305
|
+
]}
|
|
306
|
+
/>
|
|
307
|
+
)}
|
|
308
|
+
</View>
|
|
309
|
+
);
|
|
310
|
+
},
|
|
217
311
|
[
|
|
218
312
|
isLoading,
|
|
219
313
|
appliedTheme.colors.skeletonBaseColor,
|
|
@@ -224,23 +318,21 @@ const SliderOne: React.FC<SliderOneProps> = ({
|
|
|
224
318
|
]
|
|
225
319
|
);
|
|
226
320
|
|
|
227
|
-
//
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
if (isLoading) {
|
|
321
|
+
// ========================================================================
|
|
322
|
+
// Early Returns & Loading State
|
|
323
|
+
// ========================================================================
|
|
324
|
+
// Show skeleton immediately if:
|
|
325
|
+
// 1. Loading is true, OR
|
|
326
|
+
// 2. Data is null/undefined (initial state), OR
|
|
327
|
+
// 3. No content data available
|
|
328
|
+
const shouldShowSkeleton =
|
|
329
|
+
isLoading ||
|
|
330
|
+
!data ||
|
|
331
|
+
!contentData.length ||
|
|
332
|
+
(skeletonItems.length > 0 && !contentData.length);
|
|
333
|
+
|
|
334
|
+
// Show skeleton immediately while data is loading or not available
|
|
335
|
+
if (shouldShowSkeleton && skeletonItems.length > 0) {
|
|
244
336
|
return (
|
|
245
337
|
<View
|
|
246
338
|
style={styles.container}
|
|
@@ -252,27 +344,34 @@ const SliderOne: React.FC<SliderOneProps> = ({
|
|
|
252
344
|
data={skeletonItems}
|
|
253
345
|
renderItem={renderSkeletonItem}
|
|
254
346
|
mode="parallax"
|
|
255
|
-
modeConfig={
|
|
256
|
-
|
|
257
|
-
parallaxScrollingScale: 0.9,
|
|
258
|
-
}}
|
|
259
|
-
onConfigurePanGesture={(gesture) =>
|
|
260
|
-
gesture.activeOffsetX([-10, 10]).failOffsetY([-5, 5])
|
|
261
|
-
}
|
|
347
|
+
modeConfig={parallaxConfig}
|
|
348
|
+
onConfigurePanGesture={panGestureConfig}
|
|
262
349
|
/>
|
|
263
|
-
|
|
264
|
-
<View style={styles.
|
|
265
|
-
{
|
|
266
|
-
|
|
267
|
-
|
|
350
|
+
{indicatorArray.length > 0 && (
|
|
351
|
+
<View style={styles.indicatorContainer}>
|
|
352
|
+
<View style={styles.indicator}>
|
|
353
|
+
{indicatorArray.map((i) => renderIndicator(0, i))}
|
|
354
|
+
</View>
|
|
268
355
|
</View>
|
|
269
|
-
|
|
356
|
+
)}
|
|
270
357
|
</View>
|
|
271
358
|
);
|
|
272
359
|
}
|
|
360
|
+
|
|
361
|
+
// If not loading and no data, return null
|
|
362
|
+
if (!isLoading && !data) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
|
|
273
366
|
if (!isLoading && !contentData.length) {
|
|
274
367
|
return null;
|
|
275
368
|
}
|
|
369
|
+
|
|
370
|
+
// ========================================================================
|
|
371
|
+
// Render Main Content
|
|
372
|
+
// ========================================================================
|
|
373
|
+
const shouldShowIndicators = index === 0;
|
|
374
|
+
|
|
276
375
|
return (
|
|
277
376
|
<View
|
|
278
377
|
style={styles.container}
|
|
@@ -285,15 +384,10 @@ const SliderOne: React.FC<SliderOneProps> = ({
|
|
|
285
384
|
renderItem={renderCarouselItem}
|
|
286
385
|
onSnapToItem={handleSnapToItem}
|
|
287
386
|
mode="parallax"
|
|
288
|
-
modeConfig={
|
|
289
|
-
|
|
290
|
-
parallaxScrollingScale: 0.9,
|
|
291
|
-
}}
|
|
292
|
-
onConfigurePanGesture={(gesture) =>
|
|
293
|
-
gesture.activeOffsetX([-10, 10]).failOffsetY([-5, 5])
|
|
294
|
-
}
|
|
387
|
+
modeConfig={parallaxConfig}
|
|
388
|
+
onConfigurePanGesture={panGestureConfig}
|
|
295
389
|
/>
|
|
296
|
-
{
|
|
390
|
+
{shouldShowIndicators && (
|
|
297
391
|
<View style={styles.indicatorContainer}>
|
|
298
392
|
<View style={styles.indicator}>
|
|
299
393
|
{indicatorArray.map((i) => renderIndicator(0, i))}
|
|
@@ -304,7 +398,9 @@ const SliderOne: React.FC<SliderOneProps> = ({
|
|
|
304
398
|
);
|
|
305
399
|
};
|
|
306
400
|
|
|
401
|
+
// ============================================================================
|
|
307
402
|
// Styles
|
|
403
|
+
// ============================================================================
|
|
308
404
|
const styles = StyleSheet.create({
|
|
309
405
|
container: {
|
|
310
406
|
flex: 1,
|
|
@@ -342,16 +438,16 @@ const styles = StyleSheet.create({
|
|
|
342
438
|
paddingHorizontal: scale(12),
|
|
343
439
|
},
|
|
344
440
|
playIcon: {
|
|
345
|
-
width:
|
|
346
|
-
height:
|
|
347
|
-
borderRadius:
|
|
441
|
+
width: PLAY_ICON_CONTAINER_SIZE,
|
|
442
|
+
height: PLAY_ICON_CONTAINER_SIZE,
|
|
443
|
+
borderRadius: INDICATOR_BORDER_RADIUS,
|
|
348
444
|
alignItems: 'center',
|
|
349
445
|
justifyContent: 'center',
|
|
350
446
|
},
|
|
351
447
|
playText: {
|
|
352
448
|
fontSize: RFValue(15),
|
|
353
449
|
fontWeight: 'bold',
|
|
354
|
-
maxWidth:
|
|
450
|
+
maxWidth: PLAY_TEXT_MAX_WIDTH,
|
|
355
451
|
},
|
|
356
452
|
indicatorContainer: {
|
|
357
453
|
alignItems: 'center',
|
|
@@ -369,14 +465,14 @@ const styles = StyleSheet.create({
|
|
|
369
465
|
justifyContent: 'center',
|
|
370
466
|
},
|
|
371
467
|
activeIndicator: {
|
|
372
|
-
width:
|
|
373
|
-
height:
|
|
374
|
-
borderRadius:
|
|
468
|
+
width: INDICATOR_WIDTH_ACTIVE,
|
|
469
|
+
height: INDICATOR_HEIGHT,
|
|
470
|
+
borderRadius: INDICATOR_BORDER_RADIUS,
|
|
375
471
|
},
|
|
376
472
|
inactiveIndicator: {
|
|
377
|
-
width:
|
|
378
|
-
height:
|
|
379
|
-
borderRadius:
|
|
473
|
+
width: INDICATOR_WIDTH_INACTIVE,
|
|
474
|
+
height: INDICATOR_HEIGHT,
|
|
475
|
+
borderRadius: INDICATOR_BORDER_RADIUS,
|
|
380
476
|
},
|
|
381
477
|
emptyState: {
|
|
382
478
|
padding: scale(12),
|