@zezosoft/zezo-ott-react-native-ui-kit 1.3.6 → 1.3.8
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 +40 -36
- package/lib/module/components/Content/Card/components/AdsPoster.js +40 -55
- package/lib/module/components/Content/Card/components/AdsPoster.js.map +1 -1
- package/lib/module/components/Content/Card/components/CardPoster.js +81 -107
- package/lib/module/components/Content/Card/components/CardPoster.js.map +1 -1
- package/lib/module/components/Content/Card/components/ThumbnailCard.js +48 -70
- package/lib/module/components/Content/Card/components/ThumbnailCard.js.map +1 -1
- package/lib/module/components/Search/components/SearchCard.js +2 -2
- package/lib/module/components/Search/components/SearchCard.js.map +1 -1
- package/lib/typescript/src/components/Content/Card/components/AdsPoster.d.ts +1 -1
- package/lib/typescript/src/components/Content/Card/components/AdsPoster.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/components/CardPoster.d.ts.map +1 -1
- package/lib/typescript/src/components/Content/Card/components/ThumbnailCard.d.ts +1 -1
- package/lib/typescript/src/components/Content/Card/components/ThumbnailCard.d.ts.map +1 -1
- package/lib/typescript/src/components/Search/components/SearchCard.d.ts.map +1 -1
- package/package.json +1 -3
- package/lib/module/utils/colorUtils.js +0 -68
- package/lib/module/utils/colorUtils.js.map +0 -1
- package/lib/typescript/src/utils/colorUtils.d.ts +0 -19
- package/lib/typescript/src/utils/colorUtils.d.ts.map +0 -1
- package/src/assets/animations/135037-payment-processing-error.json +0 -1347
- package/src/assets/animations/7227-vui-animation.json +0 -3377
- package/src/assets/animations/Failed.json +0 -2103
- package/src/assets/animations/Pending.json +0 -522
- package/src/assets/animations/Successful.json +0 -2289
- package/src/assets/animations/heart.json +0 -788
- package/src/assets/animations/succesfull-payment.json +0 -2379
- package/src/assets/animations/voice-icon.json +0 -542
- package/src/assets/img/back.png +0 -0
- package/src/assets/img/bottom-panel.png +0 -0
- package/src/assets/img/camera.png +0 -0
- package/src/assets/img/camera2.png +0 -0
- package/src/assets/img/home.png +0 -0
- package/src/assets/img/lock.png +0 -0
- package/src/assets/img/play.png +0 -0
- package/src/assets/img/profile.jpg +0 -0
- package/src/assets/img/qr-code.png +0 -0
- package/src/assets/img/shadow.png +0 -0
- package/src/assets/img/shadow2.png +0 -0
- package/src/assets/img/user.png +0 -0
- package/src/assets/svg/Account.svg +0 -4
- package/src/assets/svg/Favourite.svg +0 -14
- package/src/assets/svg/Upcoming.svg +0 -4
- package/src/assets/svg/content-error.svg +0 -28
- package/src/assets/svg/download.svg +0 -3
- package/src/assets/svg/eye-off.svg +0 -10
- package/src/assets/svg/favorites.svg +0 -3
- package/src/assets/svg/h.svg +0 -4
- package/src/assets/svg/home.svg +0 -5
- package/src/assets/svg/home1.svg +0 -3
- package/src/assets/svg/menu-bar.svg +0 -4
- package/src/assets/svg/my-space.svg +0 -14
- package/src/assets/svg/play-icon-with-bg.svg +0 -5
- package/src/assets/svg/profile.svg +0 -4
- package/src/assets/svg/search.svg +0 -5
- package/src/assets/svg/search1.svg +0 -4
- package/src/assets/svg/server-error.svg +0 -139
- package/src/components/Account/Account.tsx +0 -354
- package/src/components/Account/index.ts +0 -6
- package/src/components/Alert/AlertDialog.tsx +0 -253
- package/src/components/Alert/UAAlert.tsx +0 -176
- package/src/components/Alert/index.ts +0 -7
- package/src/components/Auth/AuthProvider/AuthProvider.tsx +0 -412
- package/src/components/Auth/One/ForgotPassword/ForgotPassword.tsx +0 -333
- package/src/components/Auth/One/Login/LoginWithEmail.tsx +0 -449
- package/src/components/Auth/One/Login/LoginWithPhone.tsx +0 -309
- package/src/components/Auth/One/OTP/OTP.tsx +0 -539
- package/src/components/Auth/One/QrLogin/QrLogin.tsx +0 -329
- package/src/components/Auth/One/QrLogin/components/index.ts +0 -8
- package/src/components/Auth/One/QrLogin/components/qr-scanner-fallback.tsx +0 -158
- package/src/components/Auth/One/QrLogin/components/qr-scanner-frame.tsx +0 -207
- package/src/components/Auth/One/QrLogin/components/qr-scanner-header.tsx +0 -65
- package/src/components/Auth/One/QrLogin/components/qr-scanner-intro.tsx +0 -255
- package/src/components/Auth/One/QrLogin/components/qr-scanner-overlay.tsx +0 -291
- package/src/components/Auth/One/SignUp/SignUp.tsx +0 -470
- package/src/components/Auth/One/SplashScreen/SplashScreen.tsx +0 -229
- package/src/components/Auth/One/SplashScreen/components/SplashImage/SplashImage.tsx +0 -92
- package/src/components/Auth/One/SplashScreen/components/SplashLottie/SplashLottie.tsx +0 -129
- package/src/components/Auth/One/SplashScreen/components/SplashVideo/SplashVideo.tsx +0 -172
- package/src/components/Auth/One/SplashScreen/utils/splashUtils.ts +0 -23
- package/src/components/Auth/One/index.ts +0 -24
- package/src/components/Auth/Two/AuthHeader/AuthHeader.tsx +0 -130
- package/src/components/Auth/Two/ForgotPassword/ForgotPassword.tsx +0 -331
- package/src/components/Auth/Two/Login/EmailOrPhoneLogin.tsx +0 -612
- package/src/components/Auth/Two/OTP/OTP.tsx +0 -504
- package/src/components/Auth/Two/SignUp/SignUp.tsx +0 -439
- package/src/components/Auth/Two/index.ts +0 -20
- package/src/components/Auth/index.ts +0 -16
- package/src/components/BackgroundLayout/One/One.tsx +0 -184
- package/src/components/BackgroundLayout/Two/Two.tsx +0 -65
- package/src/components/BackgroundLayout/index.ts +0 -14
- package/src/components/BlogView/BlogView.tsx +0 -282
- package/src/components/BlogView/index.ts +0 -8
- package/src/components/BlurView/BlurView.tsx +0 -199
- package/src/components/BlurView/index.ts +0 -7
- package/src/components/BottomSheet/BottomSheet.tsx +0 -204
- package/src/components/BottomSheet/BottomSheetOne.tsx +0 -223
- package/src/components/BottomSheet/index.ts +0 -9
- package/src/components/Button/BackBtn.tsx +0 -149
- package/src/components/Button/MenuBtn.tsx +0 -220
- package/src/components/Button/PrimaryBtn.tsx +0 -123
- package/src/components/Button/SecondaryBtn.tsx +0 -123
- package/src/components/Button/TextButton.tsx +0 -150
- package/src/components/Button/index.ts +0 -18
- package/src/components/Button/types.ts +0 -33
- package/src/components/Content/Card/Category/Category.tsx +0 -436
- package/src/components/Content/Card/Category/CategroyTwo.tsx +0 -429
- package/src/components/Content/Card/NowWatching/NowWatching.tsx +0 -607
- package/src/components/Content/Card/Sliders/Styles/One.tsx +0 -490
- package/src/components/Content/Card/Sliders/Styles/Three.tsx +0 -1017
- package/src/components/Content/Card/Sliders/Styles/Two.tsx +0 -395
- package/src/components/Content/Card/Sliders/index.ts +0 -18
- package/src/components/Content/Card/Styles/Five.tsx +0 -367
- package/src/components/Content/Card/Styles/Four.tsx +0 -366
- package/src/components/Content/Card/Styles/One.tsx +0 -372
- package/src/components/Content/Card/Styles/RotateInOut.tsx +0 -413
- package/src/components/Content/Card/Styles/Six.tsx +0 -378
- package/src/components/Content/Card/Styles/Three.tsx +0 -312
- package/src/components/Content/Card/Styles/TopTen.tsx +0 -402
- package/src/components/Content/Card/Styles/Two.tsx +0 -404
- package/src/components/Content/Card/components/AdsPoster.tsx +0 -207
- package/src/components/Content/Card/components/CardPoster.tsx +0 -377
- package/src/components/Content/Card/components/LiveBadge.tsx +0 -125
- package/src/components/Content/Card/components/NavigateToMore.tsx +0 -97
- package/src/components/Content/Card/components/RentOrBuyIcon.tsx +0 -134
- package/src/components/Content/Card/components/ShowAllButton.tsx +0 -92
- package/src/components/Content/Card/components/ThumbnailCard.tsx +0 -219
- package/src/components/Content/Card/components/index.ts +0 -12
- package/src/components/Content/Card/index.ts +0 -31
- package/src/components/Content/Content.tsx +0 -338
- package/src/components/Content/Sections.tsx +0 -239
- package/src/components/Content/types.ts +0 -180
- package/src/components/ContentView/MoreContentList.tsx +0 -330
- package/src/components/ContentView/One/ContentViewOne.tsx +0 -251
- package/src/components/ContentView/One/components/CastCard.tsx +0 -266
- package/src/components/ContentView/One/components/HeroBanner.tsx +0 -413
- package/src/components/ContentView/One/components/MiniInfo.tsx +0 -343
- package/src/components/ContentView/One/components/Title.tsx +0 -149
- package/src/components/ContentView/Two/ContentViewTwo.tsx +0 -332
- package/src/components/ContentView/Two/components/Details.tsx +0 -196
- package/src/components/ContentView/Two/components/HeroBanner.tsx +0 -267
- package/src/components/ContentView/Two/components/LikeShareActions.tsx +0 -125
- package/src/components/ContentView/Two/components/MoreLikeThisContentList .tsx +0 -308
- package/src/components/ContentView/Two/components/PlayOrTrailer.tsx +0 -162
- package/src/components/ContentView/Two/components/SectionTabs.tsx +0 -181
- package/src/components/ContentView/Two/components/Title.tsx +0 -229
- package/src/components/ContentView/Two/components/index.ts +0 -12
- package/src/components/ContentView/index.ts +0 -13
- package/src/components/ContentView/shared/AboutSection.tsx +0 -226
- package/src/components/ContentView/shared/EpisodeCard.tsx +0 -600
- package/src/components/ContentView/shared/GenreTags.tsx +0 -189
- package/src/components/ContentView/shared/PlayButton.tsx +0 -52
- package/src/components/ContentView/shared/TrailerButton.tsx +0 -76
- package/src/components/Fallbacks/NoContentFallback.tsx +0 -175
- package/src/components/Fallbacks/NotFoundFallback.tsx +0 -94
- package/src/components/Fallbacks/index.ts +0 -7
- package/src/components/Headers/AppHeader.tsx +0 -151
- package/src/components/Headers/Four.tsx +0 -84
- package/src/components/Headers/One.tsx +0 -115
- package/src/components/Headers/Three.tsx +0 -137
- package/src/components/Headers/Two.tsx +0 -101
- package/src/components/Headers/index.ts +0 -34
- package/src/components/Input/Input.ts +0 -18
- package/src/components/Input/InputOne.tsx +0 -265
- package/src/components/Input/InputThree.tsx +0 -205
- package/src/components/Input/InputTwo.tsx +0 -217
- package/src/components/Input/PhoneInput/One/One.tsx +0 -415
- package/src/components/Input/PhoneInput/Two/Two.tsx +0 -406
- package/src/components/Input/PhoneInput/index.ts +0 -14
- package/src/components/Keyboard/HideKeyboard.tsx +0 -91
- package/src/components/Loader/Loader.tsx +0 -49
- package/src/components/Logo/Logo.tsx +0 -150
- package/src/components/NewRelease/NewReleaseSheet.tsx +0 -260
- package/src/components/NewRelease/index.ts +0 -6
- package/src/components/Reels/ReelsSeries/MediaControls/BottomControls.tsx +0 -226
- package/src/components/Reels/ReelsSeries/MediaControls/MediaControlsProvider.tsx +0 -324
- package/src/components/Reels/ReelsSeries/MediaControls/MiddleControls.tsx +0 -201
- package/src/components/Reels/ReelsSeries/MediaControls/RightControls.tsx +0 -100
- package/src/components/Reels/ReelsSeries/MediaControls/TopControls.tsx +0 -168
- package/src/components/Reels/ReelsSeries/Model/DetailsModal.tsx +0 -207
- package/src/components/Reels/ReelsSeries/Model/SettingModal.tsx +0 -151
- package/src/components/Reels/ReelsSeries/Model/UnlockModal.tsx +0 -159
- package/src/components/Reels/ReelsSeries/ReelsSeries.tsx +0 -278
- package/src/components/Reels/ReelsSeries/ReelsSeriesItem.tsx +0 -569
- package/src/components/Reels/ReelsSeries/components/AnimatedThreeLines.tsx +0 -189
- package/src/components/Reels/ReelsSeries/components/Episodes.tsx +0 -159
- package/src/components/Reels/ReelsSeries/components/GradientOverlay.tsx +0 -46
- package/src/components/Reels/ReelsSeries/components/Like.tsx +0 -45
- package/src/components/Reels/ReelsSeries/components/RotatingLoader.tsx +0 -84
- package/src/components/Reels/ReelsSeries/components/Synopsis.tsx +0 -338
- package/src/components/Reels/ReelsSeries/components/VideoControls/QualityControl.tsx +0 -185
- package/src/components/Reels/ReelsSeries/components/VideoControls/SpeedControl.tsx +0 -77
- package/src/components/Reels/ReelsSeries/components/VideoControls/index.ts +0 -7
- package/src/components/Reels/ReelsSeries/types.ts +0 -78
- package/src/components/Reels/ReelsSeries/useReelsWatchProgress.ts +0 -90
- package/src/components/Reels/ReelsSeries/utils/quality.ts +0 -72
- package/src/components/Reels/index.ts +0 -9
- package/src/components/Reels/utils/Controls/gestureUtils.ts +0 -46
- package/src/components/Reels/utils/Controls/index.ts +0 -9
- package/src/components/Reels/utils/Controls/overlayUtils.ts +0 -40
- package/src/components/Reels/utils/Controls/videoControlsConstants.ts +0 -30
- package/src/components/Reels/utils/Controls/videoRef.ts +0 -9
- package/src/components/Reels/utils/index.ts +0 -6
- package/src/components/Reels/utils/timeoutUtils.ts +0 -34
- package/src/components/Search/One.tsx +0 -262
- package/src/components/Search/components/RecentSearchesSection.tsx +0 -181
- package/src/components/Search/components/SearchCard.tsx +0 -285
- package/src/components/Search/index.ts +0 -16
- package/src/components/Settings/AppSettings.tsx +0 -442
- package/src/components/Settings/index.ts +0 -6
- package/src/components/Subscription/SubOne.tsx +0 -423
- package/src/components/Subscription/components/SubsDetailsModal.tsx +0 -347
- package/src/components/Subscription/components/SubscriptionCard.tsx +0 -342
- package/src/components/Subscription/index.ts +0 -12
- package/src/components/TabBar/One.tsx +0 -145
- package/src/components/TabBar/Three.tsx +0 -162
- package/src/components/TabBar/Two.tsx +0 -179
- package/src/components/TabBar/index.ts +0 -20
- package/src/components/Text/Text.tsx +0 -90
- package/src/components/Text/index.ts +0 -6
- package/src/components/User/DeviceSessions/DeviceSessions.tsx +0 -468
- package/src/components/User/ProfileUpdate/ProfileUpdate.tsx +0 -293
- package/src/components/User/PurchaseHistory/PurchaseHistory.tsx +0 -504
- package/src/components/User/WatchHistory/WatchHistory.tsx +0 -214
- package/src/components/User/WatchLater/WatchLater.tsx +0 -400
- package/src/components/User/components/UserAvatar.tsx +0 -121
- package/src/components/User/components/UserSection.tsx +0 -218
- package/src/components/User/index.ts +0 -18
- package/src/components/View/View.tsx +0 -38
- package/src/components/View/index.ts +0 -6
- package/src/components/common/AppStatusBar.tsx +0 -57
- package/src/components/common/index.ts +0 -1
- package/src/components/index.ts +0 -30
- package/src/components/layout/SafeAreaWrapper.tsx +0 -50
- package/src/components/layout/index.ts +0 -6
- package/src/constants/dummySections.ts +0 -103
- package/src/hooks/Images/index.ts +0 -6
- package/src/hooks/Images/useImageLoader.ts +0 -209
- package/src/hooks/index.ts +0 -16
- package/src/hooks/useAdTracking.ts +0 -354
- package/src/hooks/useCards.ts +0 -247
- package/src/hooks/useDebounce.ts +0 -40
- package/src/hooks/useKeyboard.ts +0 -43
- package/src/hooks/useNavigationMode.ts +0 -48
- package/src/hooks/usePaginatedSection.ts +0 -108
- package/src/hooks/usePrevious.ts +0 -28
- package/src/hooks/useSafeCallback.ts +0 -29
- package/src/hooks/useSkeletonItems.ts +0 -30
- package/src/hooks/useSplashCache.ts +0 -245
- package/src/index.tsx +0 -9
- package/src/store/RecentSearchesStore.ts +0 -72
- package/src/store/splashStore.ts +0 -86
- package/src/store/storage.ts +0 -29
- package/src/theme/ThemeContext.ts +0 -19
- package/src/theme/ThemeProvider.tsx +0 -87
- package/src/theme/hooks/index.ts +0 -6
- package/src/theme/hooks/useTheme.ts +0 -118
- package/src/theme/index.ts +0 -8
- package/src/theme/store/theme.ts +0 -50
- package/src/theme/themes.ts +0 -262
- package/src/theme/utils/cleanColors.ts +0 -71
- package/src/theme/utils/toRgba.ts +0 -150
- package/src/types/content/content-view.types.ts +0 -209
- package/src/types/hook/index.ts +0 -6
- package/src/types/hook/usePaginatedSection.ts +0 -20
- package/src/types/index.ts +0 -10
- package/src/types/navigation.ts +0 -17
- package/src/types/sections/index.ts +0 -87
- package/src/types/user.ts +0 -18
- package/src/utils/Display.ts +0 -15
- package/src/utils/Formater.ts +0 -33
- package/src/utils/SizeMatters.ts +0 -8
- package/src/utils/Spacing.ts +0 -27
- package/src/utils/colorUtils.ts +0 -70
- package/src/utils/imageValidation.ts +0 -36
- package/src/utils/interaction.ts +0 -19
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Naresh Dhamu
|
|
3
|
-
* @LastModified Mon 13 Jul 2026 at 10:13 AM
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import type { IReelsWatchProgress } from './types';
|
|
8
|
-
|
|
9
|
-
type UseReelsWatchProgressParams = {
|
|
10
|
-
/**
|
|
11
|
-
* Whether the parent screen is currently focused/visible.
|
|
12
|
-
* When this becomes false, the last watch progress will be flushed once.
|
|
13
|
-
*/
|
|
14
|
-
isFocused: boolean;
|
|
15
|
-
/**
|
|
16
|
-
* Callback invoked whenever an episode's watch progress should be
|
|
17
|
-
* "finalized" – e.g. when the user switches episodes, leaves the screen
|
|
18
|
-
* or the component unmounts.
|
|
19
|
-
*/
|
|
20
|
-
onFlush: (progress: IReelsWatchProgress) => void;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
type UseReelsWatchProgressResult = {
|
|
24
|
-
/**
|
|
25
|
-
* Pass this directly to `ReelsSeries` / `ReelsSeriesItem` as
|
|
26
|
-
* the `onWatchProgress` handler.
|
|
27
|
-
*/
|
|
28
|
-
handleWatchProgress: (progress: IReelsWatchProgress) => void;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Reusable hook that tracks the last watched episode progress and ensures
|
|
33
|
-
* it is flushed exactly once when:
|
|
34
|
-
* - The user switches to a different episode
|
|
35
|
-
* - The parent screen loses focus
|
|
36
|
-
* - The parent component unmounts
|
|
37
|
-
*
|
|
38
|
-
* This hook is intentionally UI-kit only and delegates side‑effects
|
|
39
|
-
* (API calls, analytics, etc.) to the provided `onFlush` callback.
|
|
40
|
-
*/
|
|
41
|
-
export const useReelsWatchProgress = ({
|
|
42
|
-
isFocused,
|
|
43
|
-
onFlush,
|
|
44
|
-
}: UseReelsWatchProgressParams): UseReelsWatchProgressResult => {
|
|
45
|
-
const lastProgressRef = React.useRef<IReelsWatchProgress | null>(null);
|
|
46
|
-
const flushProgressRef = React.useRef(onFlush);
|
|
47
|
-
|
|
48
|
-
// Always keep the latest flush callback
|
|
49
|
-
React.useEffect(() => {
|
|
50
|
-
flushProgressRef.current = onFlush;
|
|
51
|
-
}, [onFlush]);
|
|
52
|
-
|
|
53
|
-
const handleWatchProgress = React.useCallback(
|
|
54
|
-
(progress: IReelsWatchProgress) => {
|
|
55
|
-
const previous = lastProgressRef.current;
|
|
56
|
-
|
|
57
|
-
// If user changed episode, flush previous episode's progress once
|
|
58
|
-
if (
|
|
59
|
-
previous &&
|
|
60
|
-
previous.episode.episodeId !== progress.episode.episodeId
|
|
61
|
-
) {
|
|
62
|
-
flushProgressRef.current(previous);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Always store the latest progress for the current episode
|
|
66
|
-
lastProgressRef.current = progress;
|
|
67
|
-
},
|
|
68
|
-
[]
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
// When screen loses focus (user navigates away), flush last progress once
|
|
72
|
-
React.useEffect(() => {
|
|
73
|
-
if (!isFocused && lastProgressRef.current) {
|
|
74
|
-
flushProgressRef.current(lastProgressRef.current);
|
|
75
|
-
lastProgressRef.current = null;
|
|
76
|
-
}
|
|
77
|
-
}, [isFocused]);
|
|
78
|
-
|
|
79
|
-
// On unmount, flush any remaining progress
|
|
80
|
-
React.useEffect(() => {
|
|
81
|
-
return () => {
|
|
82
|
-
if (lastProgressRef.current) {
|
|
83
|
-
flushProgressRef.current(lastProgressRef.current);
|
|
84
|
-
lastProgressRef.current = null;
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
}, []);
|
|
88
|
-
|
|
89
|
-
return { handleWatchProgress };
|
|
90
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Naresh Dhamu
|
|
3
|
-
* @LastModified Mon 13 Jul 2026 at 10:13 AM
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface QualityOption {
|
|
7
|
-
quality: string;
|
|
8
|
-
url: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const DEFAULT_QUALITIES: QualityOption[] = [
|
|
12
|
-
{
|
|
13
|
-
quality: 'Auto',
|
|
14
|
-
url: '',
|
|
15
|
-
},
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
// Simple in-memory cache
|
|
19
|
-
const qualitiesCache: Record<string, QualityOption[]> = {};
|
|
20
|
-
|
|
21
|
-
export const getVideoQualities = async (
|
|
22
|
-
m3u8Url: string
|
|
23
|
-
): Promise<QualityOption[]> => {
|
|
24
|
-
// Return cached result
|
|
25
|
-
if (qualitiesCache[m3u8Url]) {
|
|
26
|
-
return qualitiesCache[m3u8Url];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const res = await fetch(m3u8Url);
|
|
31
|
-
const text = await res.text();
|
|
32
|
-
const qualities: QualityOption[] = [];
|
|
33
|
-
const lines = text.split('\n');
|
|
34
|
-
|
|
35
|
-
for (let i = 0; i < lines.length; i++) {
|
|
36
|
-
if (lines?.[i]?.includes('#EXT-X-STREAM-INF')) {
|
|
37
|
-
const resolutionMatch = lines?.[i]?.match(/RESOLUTION=\d+x(\d+)/);
|
|
38
|
-
const url = lines[i + 1]?.trim();
|
|
39
|
-
|
|
40
|
-
if (resolutionMatch && url) {
|
|
41
|
-
qualities.push({
|
|
42
|
-
quality: `${resolutionMatch[1]}p`,
|
|
43
|
-
url: new URL(url, m3u8Url).toString(), // handle relative URLs
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const sortedQualities = qualities.sort(
|
|
50
|
-
(a, b) => parseInt(b.quality, 10) - parseInt(a.quality, 10)
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
// ✅ Add Auto option at the top
|
|
54
|
-
const finalQualities: QualityOption[] = [
|
|
55
|
-
{
|
|
56
|
-
quality: 'Auto',
|
|
57
|
-
url: m3u8Url, // master playlist
|
|
58
|
-
},
|
|
59
|
-
...sortedQualities,
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
qualitiesCache[m3u8Url] = finalQualities;
|
|
63
|
-
return finalQualities;
|
|
64
|
-
} catch {
|
|
65
|
-
return [
|
|
66
|
-
{
|
|
67
|
-
quality: 'Auto',
|
|
68
|
-
url: m3u8Url,
|
|
69
|
-
},
|
|
70
|
-
];
|
|
71
|
-
}
|
|
72
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Naresh Dhamu
|
|
3
|
-
* @LastModified Mon 13 Jul 2026 at 10:13 AM
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
useTapGesture,
|
|
8
|
-
useExclusiveGestures,
|
|
9
|
-
type TapGesture,
|
|
10
|
-
} from 'react-native-gesture-handler';
|
|
11
|
-
import { GESTURE_MAX_DURATION } from './videoControlsConstants';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Create a tap gesture handler using the new hook-based API
|
|
15
|
-
*/
|
|
16
|
-
export const useCreateTapGesture = (
|
|
17
|
-
onAction: () => void,
|
|
18
|
-
numberOfTaps: number,
|
|
19
|
-
isInOverlay: (x: number, y: number) => boolean,
|
|
20
|
-
isLocked: boolean,
|
|
21
|
-
handleLockedTap: () => void
|
|
22
|
-
) => {
|
|
23
|
-
return useTapGesture({
|
|
24
|
-
maxDuration: GESTURE_MAX_DURATION,
|
|
25
|
-
numberOfTaps,
|
|
26
|
-
runOnJS: true,
|
|
27
|
-
onActivate: ({ x, y }) => {
|
|
28
|
-
if (isInOverlay(x, y)) return;
|
|
29
|
-
if (isLocked) {
|
|
30
|
-
handleLockedTap();
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
onAction();
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Create combined gesture (single tap and double tap) using the new hook-based API
|
|
40
|
-
*/
|
|
41
|
-
export const useCombinedGesture = (
|
|
42
|
-
singleTap: TapGesture,
|
|
43
|
-
doubleTap: TapGesture
|
|
44
|
-
) => {
|
|
45
|
-
return useExclusiveGestures(doubleTap, singleTap);
|
|
46
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Naresh Dhamu
|
|
3
|
-
* @LastModified Mon 13 Jul 2026 at 10:13 AM
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useMemo, useCallback } from 'react';
|
|
7
|
-
import { Dimensions } from 'react-native';
|
|
8
|
-
import {
|
|
9
|
-
OVERLAY_RIGHT_OFFSET,
|
|
10
|
-
OVERLAY_BOTTOM_OFFSET,
|
|
11
|
-
} from './videoControlsConstants';
|
|
12
|
-
|
|
13
|
-
const { width } = Dimensions.get('window');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Calculate overlay thresholds
|
|
17
|
-
*/
|
|
18
|
-
export const useOverlayThresholds = (videoHeight: number) => {
|
|
19
|
-
const rightThreshold = useMemo(() => width - OVERLAY_RIGHT_OFFSET, []);
|
|
20
|
-
|
|
21
|
-
const bottomThreshold = useMemo(
|
|
22
|
-
() => videoHeight - OVERLAY_BOTTOM_OFFSET,
|
|
23
|
-
[videoHeight]
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
return { rightThreshold, bottomThreshold };
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Check if coordinates are in overlay area
|
|
31
|
-
*/
|
|
32
|
-
export const useIsInOverlay = (
|
|
33
|
-
rightThreshold: number,
|
|
34
|
-
bottomThreshold: number
|
|
35
|
-
) => {
|
|
36
|
-
return useCallback(
|
|
37
|
-
(x: number, y: number) => x > rightThreshold || y > bottomThreshold,
|
|
38
|
-
[rightThreshold, bottomThreshold]
|
|
39
|
-
);
|
|
40
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Naresh Dhamu
|
|
3
|
-
* @LastModified Mon 13 Jul 2026 at 10:13 AM
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Video Controls Constants
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export const GESTURE_MAX_DURATION = 300;
|
|
11
|
-
export const PAUSE_ICON_TIMEOUT = 800;
|
|
12
|
-
export const LIKE_ANIM_TIMEOUT = 1200;
|
|
13
|
-
export const UNLOCK_MODAL_DELAY = 500;
|
|
14
|
-
export const OVERLAY_RIGHT_OFFSET = 80;
|
|
15
|
-
export const OVERLAY_BOTTOM_OFFSET = 150;
|
|
16
|
-
|
|
17
|
-
export const videoControlsStyles = {
|
|
18
|
-
hideForward: true,
|
|
19
|
-
hideDuration: true,
|
|
20
|
-
hideFullscreen: true,
|
|
21
|
-
hidePlayPause: true,
|
|
22
|
-
hideNavigationBarOnFullScreenMode: true,
|
|
23
|
-
hideNotificationBarOnFullScreenMode: true,
|
|
24
|
-
hideNext: true,
|
|
25
|
-
hidePosition: true,
|
|
26
|
-
hidePrevious: true,
|
|
27
|
-
hideRewind: true,
|
|
28
|
-
hideSeekBar: true,
|
|
29
|
-
hideSettingButton: true,
|
|
30
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Naresh Dhamu
|
|
3
|
-
* @LastModified Mon 13 Jul 2026 at 10:13 AM
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { type MutableRefObject } from 'react';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Safely clears a timeout stored in a ref
|
|
10
|
-
* @param ref - React ref containing the timeout
|
|
11
|
-
*/
|
|
12
|
-
export const clearTimeoutSafely = (
|
|
13
|
-
ref: MutableRefObject<NodeJS.Timeout | null>
|
|
14
|
-
): void => {
|
|
15
|
-
if (ref.current) {
|
|
16
|
-
clearTimeout(ref.current);
|
|
17
|
-
ref.current = null;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Safely sets a timeout and stores it in a ref, clearing any existing timeout first
|
|
23
|
-
* @param ref - React ref to store the timeout
|
|
24
|
-
* @param callback - Function to execute after delay
|
|
25
|
-
* @param delay - Delay in milliseconds
|
|
26
|
-
*/
|
|
27
|
-
export const setTimeoutSafely = (
|
|
28
|
-
ref: MutableRefObject<NodeJS.Timeout | null>,
|
|
29
|
-
callback: () => void,
|
|
30
|
-
delay: number
|
|
31
|
-
): void => {
|
|
32
|
-
clearTimeoutSafely(ref);
|
|
33
|
-
ref.current = setTimeout(callback, delay);
|
|
34
|
-
};
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Naresh Dhamu
|
|
3
|
-
* @LastModified Mon 13 Jul 2026 at 10:13 AM
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import React, { memo, useCallback, useMemo } from 'react';
|
|
7
|
-
import {
|
|
8
|
-
View,
|
|
9
|
-
StyleSheet,
|
|
10
|
-
Platform,
|
|
11
|
-
FlatList,
|
|
12
|
-
Keyboard,
|
|
13
|
-
type ListRenderItem,
|
|
14
|
-
} from 'react-native';
|
|
15
|
-
import { useTheme } from '../../theme';
|
|
16
|
-
import InputTwo from '../Input/InputTwo';
|
|
17
|
-
import { LucideSearch, XCircle } from 'lucide-react-native';
|
|
18
|
-
import { Text } from '../Text';
|
|
19
|
-
import { scale, verticalScale } from 'react-native-size-matters';
|
|
20
|
-
import HideKeyboard from '../Keyboard/HideKeyboard';
|
|
21
|
-
import SearchCard, {
|
|
22
|
-
type SearchCardSkeletonConfig,
|
|
23
|
-
} from './components/SearchCard';
|
|
24
|
-
import { useDebounce } from '../../hooks/useDebounce';
|
|
25
|
-
import { useSkeletonItems } from '../../hooks/useSkeletonItems';
|
|
26
|
-
import type { IGetSectionData, ISectionItem, MoreFetchData } from '../../types';
|
|
27
|
-
import type { ThemeOverride } from '../../theme/themes';
|
|
28
|
-
import { useRecentSearchesStore } from '../../store/RecentSearchesStore';
|
|
29
|
-
import RecentSearchesSection from './components/RecentSearchesSection';
|
|
30
|
-
import Cards from '../Content/Card';
|
|
31
|
-
import type { RecommendedCardStyles } from '../../types/content/content-view.types';
|
|
32
|
-
import { RFValue } from 'react-native-responsive-fontsize';
|
|
33
|
-
import type { IContentData } from '@zezosoft/zezo-ott-api-client';
|
|
34
|
-
|
|
35
|
-
// Types
|
|
36
|
-
export type ISearchItem = IContentData;
|
|
37
|
-
export type SearchOneFormValues = { keyword: string };
|
|
38
|
-
|
|
39
|
-
export type SearchOneProps = {
|
|
40
|
-
placeholder?: string;
|
|
41
|
-
results?: ISearchItem[];
|
|
42
|
-
search: string;
|
|
43
|
-
isLoading?: boolean;
|
|
44
|
-
events?: {
|
|
45
|
-
onSubmit: (values: SearchOneFormValues) => void;
|
|
46
|
-
onClear?: () => void;
|
|
47
|
-
onChangeText?: (text: string) => void;
|
|
48
|
-
onItemPress?: (args: { item: IContentData }) => void;
|
|
49
|
-
onPressRecommendedItem?: (args: { item: IContentData }) => void;
|
|
50
|
-
onPressRecommendedMore?: (args: {
|
|
51
|
-
section_id: IGetSectionData['_id'];
|
|
52
|
-
name: IGetSectionData['name'];
|
|
53
|
-
type: IGetSectionData['type'];
|
|
54
|
-
}) => void;
|
|
55
|
-
moreFetchDataRecommended?: MoreFetchData<IContentData>;
|
|
56
|
-
};
|
|
57
|
-
pillMaxCount?: number;
|
|
58
|
-
skeletonCardCount?: number;
|
|
59
|
-
noResultsText?: string;
|
|
60
|
-
recommendedContentCardStyles?: RecommendedCardStyles;
|
|
61
|
-
skeletonConfig?: SearchCardSkeletonConfig;
|
|
62
|
-
theme?: ThemeOverride;
|
|
63
|
-
recommendedContent?: ISectionItem | null;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const SearchBar: React.FC<SearchOneProps> = ({
|
|
67
|
-
placeholder = 'Search',
|
|
68
|
-
results,
|
|
69
|
-
search = '',
|
|
70
|
-
isLoading = false,
|
|
71
|
-
events,
|
|
72
|
-
pillMaxCount = 20,
|
|
73
|
-
skeletonCardCount = 6,
|
|
74
|
-
skeletonConfig,
|
|
75
|
-
noResultsText = 'No results found',
|
|
76
|
-
recommendedContentCardStyles,
|
|
77
|
-
theme,
|
|
78
|
-
recommendedContent,
|
|
79
|
-
}) => {
|
|
80
|
-
const { theme: appliedTheme } = useTheme(theme);
|
|
81
|
-
const {
|
|
82
|
-
recentSearches,
|
|
83
|
-
addSearchTerm,
|
|
84
|
-
clearSearches,
|
|
85
|
-
isLoading: recentSearchesLoading,
|
|
86
|
-
} = useRecentSearchesStore();
|
|
87
|
-
|
|
88
|
-
const {
|
|
89
|
-
colors: { textPrimary, background },
|
|
90
|
-
} = appliedTheme;
|
|
91
|
-
|
|
92
|
-
const trimmedSearch = search.trim();
|
|
93
|
-
|
|
94
|
-
const debouncedSubmit = useDebounce((keyword: string) => {
|
|
95
|
-
const trimmed = keyword.trim();
|
|
96
|
-
if (trimmed) {
|
|
97
|
-
events?.onSubmit({ keyword: trimmed });
|
|
98
|
-
addSearchTerm(trimmed, pillMaxCount);
|
|
99
|
-
}
|
|
100
|
-
}, 600);
|
|
101
|
-
|
|
102
|
-
const handleTyping = useCallback(
|
|
103
|
-
(text: string) => {
|
|
104
|
-
events?.onChangeText?.(text);
|
|
105
|
-
debouncedSubmit(text);
|
|
106
|
-
},
|
|
107
|
-
[events, debouncedSubmit]
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
const handleClear = useCallback(() => {
|
|
111
|
-
events?.onChangeText?.('');
|
|
112
|
-
events?.onSubmit({ keyword: '' });
|
|
113
|
-
events?.onClear?.();
|
|
114
|
-
Keyboard.dismiss();
|
|
115
|
-
}, [events]);
|
|
116
|
-
|
|
117
|
-
const handleItemPress = useCallback(
|
|
118
|
-
(item: ISearchItem) => {
|
|
119
|
-
events?.onItemPress?.({ item });
|
|
120
|
-
},
|
|
121
|
-
[events]
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
const skeletonItems = useSkeletonItems<ISearchItem>(skeletonCardCount);
|
|
125
|
-
|
|
126
|
-
const showRecent =
|
|
127
|
-
!recentSearchesLoading && trimmedSearch === '' && recentSearches.length > 0;
|
|
128
|
-
|
|
129
|
-
const shouldShowFooter = !isLoading && (!results || results.length === 0);
|
|
130
|
-
|
|
131
|
-
const renderItem: ListRenderItem<ISearchItem> = ({ item, index }) => (
|
|
132
|
-
<View style={styles.container} key={item?._id || index}>
|
|
133
|
-
<SearchCard
|
|
134
|
-
isLoading={isLoading}
|
|
135
|
-
title={item?.name}
|
|
136
|
-
thumbnail={item?.thumbnail || item?.poster || ''}
|
|
137
|
-
description={item?.description}
|
|
138
|
-
category={item?.type}
|
|
139
|
-
theme={theme}
|
|
140
|
-
contentType={item?.type}
|
|
141
|
-
onPress={() => !isLoading && handleItemPress(item)}
|
|
142
|
-
skeletonConfig={skeletonConfig}
|
|
143
|
-
/>
|
|
144
|
-
</View>
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
const renderFooter = useMemo(() => {
|
|
148
|
-
if (!shouldShowFooter) return undefined;
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<>
|
|
152
|
-
{showRecent && (
|
|
153
|
-
<View style={styles.container}>
|
|
154
|
-
<RecentSearchesSection
|
|
155
|
-
recentSearches={recentSearches}
|
|
156
|
-
isLoading={isLoading}
|
|
157
|
-
onPressItem={handleTyping}
|
|
158
|
-
onClearAll={clearSearches}
|
|
159
|
-
theme={appliedTheme}
|
|
160
|
-
/>
|
|
161
|
-
</View>
|
|
162
|
-
)}
|
|
163
|
-
|
|
164
|
-
{recommendedContent && recommendedContent?.content?.data.length > 0 && (
|
|
165
|
-
<Cards.Styles.Two
|
|
166
|
-
section_id={recommendedContent._id}
|
|
167
|
-
title={recommendedContent.name}
|
|
168
|
-
titleStyle={styles.recommendedTitle}
|
|
169
|
-
type={recommendedContent.type}
|
|
170
|
-
data={recommendedContent.content}
|
|
171
|
-
isLoading={isLoading}
|
|
172
|
-
theme={theme}
|
|
173
|
-
onPressItem={(item) => events?.onPressRecommendedItem?.({ item })}
|
|
174
|
-
onPressMore={events?.onPressRecommendedMore}
|
|
175
|
-
moreFetchData={events?.moreFetchDataRecommended}
|
|
176
|
-
{...recommendedContentCardStyles}
|
|
177
|
-
/>
|
|
178
|
-
)}
|
|
179
|
-
</>
|
|
180
|
-
);
|
|
181
|
-
}, [
|
|
182
|
-
shouldShowFooter,
|
|
183
|
-
showRecent,
|
|
184
|
-
recentSearches,
|
|
185
|
-
isLoading,
|
|
186
|
-
handleTyping,
|
|
187
|
-
clearSearches,
|
|
188
|
-
appliedTheme,
|
|
189
|
-
recommendedContent,
|
|
190
|
-
theme,
|
|
191
|
-
events,
|
|
192
|
-
recommendedContentCardStyles,
|
|
193
|
-
]);
|
|
194
|
-
|
|
195
|
-
const renderEmptyComponent = () =>
|
|
196
|
-
!isLoading && trimmedSearch.length > 0 && results?.length === 0 ? (
|
|
197
|
-
<Text style={styles.emptyText} color={textPrimary}>
|
|
198
|
-
{noResultsText}
|
|
199
|
-
</Text>
|
|
200
|
-
) : undefined;
|
|
201
|
-
|
|
202
|
-
return (
|
|
203
|
-
<View style={[styles.mainContainer, { backgroundColor: background }]}>
|
|
204
|
-
<View style={styles.container}>
|
|
205
|
-
<InputTwo
|
|
206
|
-
theme={theme}
|
|
207
|
-
value={search}
|
|
208
|
-
placeholder={placeholder}
|
|
209
|
-
onChangeText={handleTyping}
|
|
210
|
-
leftIcon={<LucideSearch size={scale(20)} color="#aaa" />}
|
|
211
|
-
rightIcon={
|
|
212
|
-
search.length > 0 ? <XCircle size={24} color={textPrimary} /> : null
|
|
213
|
-
}
|
|
214
|
-
onPressRightIcon={handleClear}
|
|
215
|
-
accessibilityLabel="Search"
|
|
216
|
-
/>
|
|
217
|
-
</View>
|
|
218
|
-
|
|
219
|
-
<HideKeyboard keyboardVerticalOffset={scale(10)}>
|
|
220
|
-
<FlatList
|
|
221
|
-
data={isLoading ? skeletonItems : results}
|
|
222
|
-
keyExtractor={(item, idx) => item?._id || `item-${idx}`}
|
|
223
|
-
renderItem={renderItem}
|
|
224
|
-
ListEmptyComponent={renderEmptyComponent()}
|
|
225
|
-
ListFooterComponent={renderFooter}
|
|
226
|
-
contentContainerStyle={styles.listContent}
|
|
227
|
-
showsVerticalScrollIndicator={false}
|
|
228
|
-
keyboardShouldPersistTaps="handled"
|
|
229
|
-
style={styles.list}
|
|
230
|
-
/>
|
|
231
|
-
</HideKeyboard>
|
|
232
|
-
</View>
|
|
233
|
-
);
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
export default memo(SearchBar);
|
|
237
|
-
|
|
238
|
-
const styles = StyleSheet.create({
|
|
239
|
-
mainContainer: {
|
|
240
|
-
flex: 1,
|
|
241
|
-
paddingTop: Platform.OS === 'ios' ? scale(18) : scale(12),
|
|
242
|
-
},
|
|
243
|
-
container: {
|
|
244
|
-
paddingHorizontal: scale(16),
|
|
245
|
-
},
|
|
246
|
-
recommendedTitle: {
|
|
247
|
-
fontSize: RFValue(13),
|
|
248
|
-
},
|
|
249
|
-
emptyText: {
|
|
250
|
-
fontSize: RFValue(12),
|
|
251
|
-
textAlign: 'center',
|
|
252
|
-
marginTop: verticalScale(20),
|
|
253
|
-
},
|
|
254
|
-
list: {
|
|
255
|
-
flex: 1,
|
|
256
|
-
marginTop: scale(2),
|
|
257
|
-
},
|
|
258
|
-
listContent: {
|
|
259
|
-
paddingBottom: verticalScale(80),
|
|
260
|
-
paddingTop: scale(12),
|
|
261
|
-
},
|
|
262
|
-
});
|