@zezosoft/zezo-ott-react-native-video-player 1.0.4 → 1.0.6

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 (73) hide show
  1. package/lib/module/AdsPlayer/store/adsPlayerStore.js +3 -3
  2. package/lib/module/AdsPlayer/store/adsPlayerStore.js.map +1 -1
  3. package/lib/module/VideoPlayer/store/videoPlayerStore.js +3 -3
  4. package/lib/module/VideoPlayer/store/videoPlayerStore.js.map +1 -1
  5. package/lib/typescript/src/AdsPlayer/store/adsPlayerStore.d.ts +2 -3
  6. package/lib/typescript/src/AdsPlayer/store/adsPlayerStore.d.ts.map +1 -1
  7. package/lib/typescript/src/VideoPlayer/store/videoPlayerStore.d.ts +2 -3
  8. package/lib/typescript/src/VideoPlayer/store/videoPlayerStore.d.ts.map +1 -1
  9. package/package.json +5 -3
  10. package/src/AdsPlayer/AdsPlayer.tsx +0 -311
  11. package/src/AdsPlayer/MediaControls/AdBottomControls.tsx +0 -191
  12. package/src/AdsPlayer/MediaControls/AdMediaControls.tsx +0 -104
  13. package/src/AdsPlayer/MediaControls/AdMediaControlsProvider.tsx +0 -62
  14. package/src/AdsPlayer/MediaControls/AdMiddleControls.tsx +0 -63
  15. package/src/AdsPlayer/MediaControls/AdTopControls.tsx +0 -191
  16. package/src/AdsPlayer/MediaControls/index.ts +0 -5
  17. package/src/AdsPlayer/components/RotatingLoader.tsx +0 -79
  18. package/src/AdsPlayer/index.ts +0 -4
  19. package/src/AdsPlayer/store/adsPlayer.type.ts +0 -29
  20. package/src/AdsPlayer/store/adsPlayerStore.ts +0 -59
  21. package/src/AdsPlayer/store/index.ts +0 -2
  22. package/src/AdsPlayer/utils/adStateReset.ts +0 -29
  23. package/src/AdsPlayer/utils/controls.ts +0 -69
  24. package/src/AdsPlayer/utils/useAdControlsAutoHide.ts +0 -32
  25. package/src/AdsPlayer/utils/useAdInitialization.ts +0 -86
  26. package/src/AdsPlayer/utils/useAdTracking.ts +0 -89
  27. package/src/AdsPlayer/utils/useAdsManager.ts +0 -215
  28. package/src/VideoPlayer/MediaControls/BottomControls.tsx +0 -210
  29. package/src/VideoPlayer/MediaControls/MediaControls.tsx +0 -30
  30. package/src/VideoPlayer/MediaControls/MediaControlsProvider.tsx +0 -104
  31. package/src/VideoPlayer/MediaControls/MiddleControls.tsx +0 -259
  32. package/src/VideoPlayer/MediaControls/TopControls.tsx +0 -100
  33. package/src/VideoPlayer/Settings/AudioAndSubtitles.tsx +0 -295
  34. package/src/VideoPlayer/Settings/Episodes.tsx +0 -297
  35. package/src/VideoPlayer/Settings/SettingModal.tsx +0 -127
  36. package/src/VideoPlayer/Settings/SpeedControls.tsx +0 -130
  37. package/src/VideoPlayer/Settings/VideoPlayerSettings.tsx +0 -141
  38. package/src/VideoPlayer/VideoPlayerCore.tsx +0 -356
  39. package/src/VideoPlayer/components/ProgressBar.tsx +0 -211
  40. package/src/VideoPlayer/components/SkipAndNextControls.tsx +0 -192
  41. package/src/VideoPlayer/components/SubtitleView.tsx +0 -53
  42. package/src/VideoPlayer/components/Toast.tsx +0 -61
  43. package/src/VideoPlayer/context/VideoPlayerConfig.tsx +0 -65
  44. package/src/VideoPlayer/context/index.ts +0 -5
  45. package/src/VideoPlayer/index.ts +0 -4
  46. package/src/VideoPlayer/store/index.ts +0 -2
  47. package/src/VideoPlayer/store/videoPlayer.type.ts +0 -214
  48. package/src/VideoPlayer/store/videoPlayerStore.ts +0 -97
  49. package/src/VideoPlayer/styles/globalStyles.ts +0 -73
  50. package/src/VideoPlayer/utils/display/Display.ts +0 -10
  51. package/src/VideoPlayer/utils/display/index.ts +0 -1
  52. package/src/VideoPlayer/utils/format/index.ts +0 -1
  53. package/src/VideoPlayer/utils/format/timeFormatter.ts +0 -44
  54. package/src/VideoPlayer/utils/hooks/index.ts +0 -5
  55. package/src/VideoPlayer/utils/hooks/useAdEventHandler.ts +0 -95
  56. package/src/VideoPlayer/utils/hooks/useOrientationLock.ts +0 -29
  57. package/src/VideoPlayer/utils/hooks/usePauseVideoOnAd.ts +0 -46
  58. package/src/VideoPlayer/utils/hooks/useVideoPlayerBack.ts +0 -66
  59. package/src/VideoPlayer/utils/hooks/useVideoResolutions.ts +0 -125
  60. package/src/VideoPlayer/utils/index.ts +0 -6
  61. package/src/VideoPlayer/utils/platform/PlatformSelector.ts +0 -13
  62. package/src/VideoPlayer/utils/platform/index.ts +0 -2
  63. package/src/VideoPlayer/utils/platform/lockOrientation.ts +0 -40
  64. package/src/VideoPlayer/utils/player/index.ts +0 -2
  65. package/src/VideoPlayer/utils/player/playerEvents.ts +0 -97
  66. package/src/VideoPlayer/utils/player/useWatchReporter.ts +0 -105
  67. package/src/VideoPlayer/utils/video/index.ts +0 -5
  68. package/src/VideoPlayer/utils/video/videoControl.ts +0 -185
  69. package/src/VideoPlayer/utils/video/videoRef.ts +0 -21
  70. package/src/VideoPlayer/utils/video/videoResume.ts +0 -23
  71. package/src/VideoPlayer/utils/video/videoSource.ts +0 -23
  72. package/src/VideoPlayer.tsx +0 -181
  73. package/src/index.tsx +0 -3
@@ -1,30 +0,0 @@
1
- import { memo } from 'react';
2
- import { StyleSheet, View } from 'react-native';
3
- import TopControls from './TopControls';
4
- import MiddleControls from './MiddleControls';
5
- import BottomControls from './BottomControls';
6
-
7
- export type MediaControlsProps = {
8
- onClose?: () => void;
9
- };
10
-
11
- const MediaControls: React.FC<MediaControlsProps> = ({ onClose }) => {
12
- return (
13
- <View style={styles.container}>
14
- <TopControls onClose={onClose} />
15
- <MiddleControls />
16
- <BottomControls />
17
- </View>
18
- );
19
- };
20
-
21
- export default memo(MediaControls);
22
-
23
- const styles = StyleSheet.create({
24
- container: {
25
- flex: 1,
26
- flexDirection: 'column',
27
- justifyContent: 'space-between',
28
- minHeight: 0,
29
- },
30
- });
@@ -1,104 +0,0 @@
1
- import React, { useEffect, useRef, useMemo } from 'react';
2
- import { TouchableOpacity, View, type ViewStyle, Animated } from 'react-native';
3
- import { type EdgeInsets } from 'react-native-safe-area-context';
4
- import { moderateScale } from 'react-native-size-matters';
5
- import MediaControls, { type MediaControlsProps } from './MediaControls';
6
- import SettingModal from '../Settings/SettingModal';
7
- import { useVideoPlayerStore } from '../store/videoPlayerStore';
8
- import SkipAndNextControls from '../components/SkipAndNextControls';
9
- import type { MediaEpisode } from '../store/videoPlayer.type';
10
- import globalStyles from '../styles/globalStyles';
11
- import type { ExtendedWatchProgress } from '../utils';
12
- import SubtitleView from '../components/SubtitleView';
13
-
14
- const HORIZONTAL_PADDING = moderateScale(12);
15
- const BOTTOM_PADDING_EXTRA = moderateScale(8);
16
- const MIN_TOP_PADDING = moderateScale(10);
17
-
18
- interface MediaControlsProviderProps extends MediaControlsProps {
19
- children: React.ReactNode;
20
- onPressEpisode: ({ episode }: { episode: MediaEpisode }) => Promise<boolean>;
21
- reportProgress: (event: ExtendedWatchProgress['event']) => void;
22
- insets: EdgeInsets;
23
- }
24
-
25
- const MediaControlsProvider: React.FC<MediaControlsProviderProps> = ({
26
- children,
27
- onClose,
28
- onPressEpisode,
29
- reportProgress,
30
- insets,
31
- }) => {
32
- const { top, bottom, left, right } = insets;
33
- const controlsVisible = useVideoPlayerStore((state) => state.controlsVisible);
34
- const setControlsVisible = useVideoPlayerStore(
35
- (state) => state.setControlsVisible
36
- );
37
- const controlsTimer = useVideoPlayerStore((state) => state.controlsTimer);
38
- const timeoutId = React.useRef<NodeJS.Timeout | null>(null);
39
- const fadeAnim = useRef(new Animated.Value(0)).current;
40
-
41
- // Safe-area padding: never negative, single source of truth (MediaControls uses View, not SafeAreaView)
42
- const containerPadding: ViewStyle = useMemo(
43
- () => ({
44
- paddingTop: top - MIN_TOP_PADDING,
45
- paddingBottom: bottom + BOTTOM_PADDING_EXTRA,
46
- paddingLeft: left + HORIZONTAL_PADDING,
47
- paddingRight: right + HORIZONTAL_PADDING,
48
- }),
49
- [top, bottom, left, right]
50
- );
51
-
52
- // Memoize animated style
53
- const animatedStyle = useMemo(
54
- () => [globalStyles.absoluteFill, { opacity: fadeAnim }],
55
- [fadeAnim]
56
- );
57
-
58
- useEffect(() => {
59
- Animated.timing(fadeAnim, {
60
- toValue: controlsVisible ? 1 : 0,
61
- duration: 200,
62
- useNativeDriver: true,
63
- }).start();
64
-
65
- if (controlsVisible) {
66
- timeoutId.current = setTimeout(() => {
67
- setControlsVisible(false);
68
- }, controlsTimer * 1000);
69
- }
70
-
71
- return () => {
72
- if (timeoutId.current) clearTimeout(timeoutId.current);
73
- };
74
- }, [controlsVisible, controlsTimer, setControlsVisible, fadeAnim]);
75
-
76
- return (
77
- <View style={globalStyles.flexOne}>
78
- {children}
79
- <Animated.View
80
- pointerEvents={controlsVisible ? 'auto' : 'none'}
81
- style={animatedStyle}
82
- >
83
- <TouchableOpacity
84
- onPress={() => setControlsVisible(false)}
85
- style={[globalStyles.controlsContainer, containerPadding]}
86
- activeOpacity={1}
87
- >
88
- <MediaControls onClose={onClose} />
89
- </TouchableOpacity>
90
- </Animated.View>
91
- <SettingModal
92
- onPressEpisode={onPressEpisode}
93
- reportProgress={reportProgress}
94
- />
95
- <SubtitleView />
96
- <SkipAndNextControls
97
- onPressEpisode={onPressEpisode}
98
- reportProgress={reportProgress}
99
- />
100
- </View>
101
- );
102
- };
103
-
104
- export default MediaControlsProvider;
@@ -1,259 +0,0 @@
1
- import React, { useState, useRef, useMemo } from 'react';
2
- import {
3
- StyleSheet,
4
- Text,
5
- TouchableOpacity,
6
- View,
7
- Animated,
8
- Easing,
9
- } from 'react-native';
10
- import { moderateScale, scale } from 'react-native-size-matters';
11
- import { RFValue } from 'react-native-responsive-fontsize';
12
- import { Play, Pause, RotateCcw, RotateCw } from 'lucide-react-native';
13
-
14
- import { useVideoPlayerStore } from '../store/videoPlayerStore';
15
- import { videoRef } from '../utils';
16
- import { handlePause } from '../utils';
17
- import { useVideoPlayerConfig } from '../context';
18
- import RotatingLoader from '../../AdsPlayer/components/RotatingLoader';
19
- import globalStyles from '../styles/globalStyles';
20
-
21
- const BUTTON_SIZE = moderateScale(80);
22
- const SMALL_BUTTON_SIZE = moderateScale(60);
23
- const FEEDBACK_DURATION = 500;
24
- const MOVE_DISTANCE = 60;
25
- const SKIP_INCREMENT = 10;
26
-
27
- type SkipButtonProps = {
28
- direction: 'forward' | 'backward';
29
- onPress: ({ second }: { second: number }) => void;
30
- colors: { text: string };
31
- disabled?: boolean;
32
- };
33
-
34
- const MiddleControls: React.FC = () => {
35
- const {
36
- isPaused,
37
- isBuffering,
38
- setStartWatchTime,
39
- error,
40
- setIsPaused,
41
- duration,
42
- currentTime,
43
- setCurrentTime,
44
- } = useVideoPlayerStore();
45
-
46
- const { colors } = useVideoPlayerConfig();
47
-
48
- const isVideoEnded = duration > 0 && currentTime >= duration;
49
-
50
- const handleSkip = (delta: number) => {
51
- let newTime = currentTime + delta;
52
- if (newTime < 0) newTime = 0;
53
- if (newTime > duration) newTime = duration;
54
-
55
- videoRef?.current?.seek(newTime);
56
- setCurrentTime(newTime);
57
- };
58
-
59
- const handlePlayPause = () => {
60
- if (isVideoEnded) {
61
- videoRef.current?.seek(0);
62
- setCurrentTime(0);
63
- setIsPaused(false);
64
- setStartWatchTime(Date.now());
65
- return;
66
- }
67
-
68
- if (!isPaused) {
69
- handlePause();
70
- setIsPaused(true);
71
- } else {
72
- setIsPaused(false);
73
- setStartWatchTime(Date.now());
74
- }
75
- };
76
-
77
- // Memoize container style
78
- const containerStyle = useMemo(
79
- () => [globalStyles.absoluteFill, styles.container],
80
- []
81
- );
82
-
83
- if (error) {
84
- return (
85
- <View style={containerStyle}>
86
- <Text style={[styles.errorText, { color: colors.text }]}>{error}</Text>
87
- </View>
88
- );
89
- }
90
-
91
- return (
92
- <View style={containerStyle}>
93
- <SkipButton
94
- direction="backward"
95
- onPress={({ second }) => handleSkip(-second)}
96
- colors={colors}
97
- disabled={currentTime <= 0}
98
- />
99
-
100
- {isBuffering ? (
101
- <View style={[styles.button, styles.playButton]}>
102
- <RotatingLoader
103
- color={colors.text}
104
- autoRotate={isBuffering}
105
- size={scale(50)}
106
- />
107
- </View>
108
- ) : (
109
- <TouchableOpacity
110
- onPress={handlePlayPause}
111
- style={[styles.button, styles.playButton]}
112
- activeOpacity={0.8}
113
- >
114
- {isPaused ? (
115
- <Play size={scale(50)} color={colors.text} />
116
- ) : (
117
- <Pause size={scale(50)} color={colors.text} />
118
- )}
119
- </TouchableOpacity>
120
- )}
121
-
122
- <SkipButton
123
- direction="forward"
124
- onPress={({ second }) => handleSkip(second)}
125
- colors={colors}
126
- disabled={currentTime >= duration}
127
- />
128
- </View>
129
- );
130
- };
131
-
132
- export default MiddleControls;
133
-
134
- const SkipButton: React.FC<SkipButtonProps> = ({
135
- direction,
136
- onPress,
137
- colors,
138
- disabled,
139
- }) => {
140
- const [step, setStep] = useState(0);
141
- const anim = useRef(new Animated.Value(0)).current;
142
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
143
-
144
- const handlePress = () => {
145
- if (disabled) return;
146
-
147
- const newStep = step + SKIP_INCREMENT;
148
- setStep(newStep);
149
- onPress({ second: newStep });
150
-
151
- anim.setValue(0);
152
- Animated.timing(anim, {
153
- toValue: 1,
154
- duration: FEEDBACK_DURATION,
155
- easing: Easing.out(Easing.quad),
156
- useNativeDriver: true,
157
- }).start();
158
-
159
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
160
- timeoutRef.current = setTimeout(() => setStep(0), FEEDBACK_DURATION);
161
- };
162
-
163
- const translateX = anim.interpolate({
164
- inputRange: [0, 1],
165
- outputRange:
166
- direction === 'forward'
167
- ? [SMALL_BUTTON_SIZE, SMALL_BUTTON_SIZE + MOVE_DISTANCE]
168
- : [-SMALL_BUTTON_SIZE, -SMALL_BUTTON_SIZE - MOVE_DISTANCE],
169
- });
170
-
171
- const opacity = anim.interpolate({
172
- inputRange: [0, 0.8, 1],
173
- outputRange: [1, 1, 0],
174
- });
175
-
176
- const scaleAnim = anim.interpolate({
177
- inputRange: [0, 0.5, 1],
178
- outputRange: [1, 1.3, 1],
179
- });
180
-
181
- return (
182
- <TouchableOpacity
183
- onPress={handlePress}
184
- style={[
185
- styles.button,
186
- styles.smallButton,
187
- disabled && styles.disabledButton,
188
- ]}
189
- activeOpacity={disabled ? 1 : 0.7}
190
- disabled={disabled}
191
- >
192
- {/* Skip Icon */}
193
- {direction === 'forward' ? (
194
- <RotateCw size={scale(35)} color={colors.text} />
195
- ) : (
196
- <RotateCcw size={scale(35)} color={colors.text} />
197
- )}
198
-
199
- {/* Skip Duration Feedback */}
200
- {step > 0 && !disabled && (
201
- <Animated.View
202
- style={[
203
- styles.feedbackOverlay,
204
- {
205
- transform: [{ translateX }, { scale: scaleAnim }],
206
- opacity,
207
- },
208
- ]}
209
- >
210
- <Text style={[styles.feedbackText, { color: colors.text }]}>
211
- {step}s
212
- </Text>
213
- </Animated.View>
214
- )}
215
- </TouchableOpacity>
216
- );
217
- };
218
-
219
- const styles = StyleSheet.create({
220
- container: {
221
- flex: 1,
222
- flexDirection: 'row',
223
- justifyContent: 'center',
224
- alignItems: 'center',
225
- },
226
- button: {
227
- justifyContent: 'center',
228
- alignItems: 'center',
229
- borderRadius: 100,
230
- },
231
- playButton: {
232
- width: BUTTON_SIZE,
233
- height: BUTTON_SIZE,
234
- marginHorizontal: moderateScale(14),
235
- },
236
- smallButton: {
237
- width: SMALL_BUTTON_SIZE,
238
- height: SMALL_BUTTON_SIZE,
239
- marginHorizontal: moderateScale(10),
240
- },
241
- disabledButton: {
242
- opacity: 0.3,
243
- },
244
- errorText: {
245
- fontSize: RFValue(18),
246
- fontWeight: '600',
247
- textAlign: 'center',
248
- paddingHorizontal: scale(20),
249
- },
250
- feedbackOverlay: {
251
- position: 'absolute',
252
- justifyContent: 'center',
253
- alignItems: 'center',
254
- },
255
- feedbackText: {
256
- fontSize: RFValue(15),
257
- fontWeight: '600',
258
- },
259
- });
@@ -1,100 +0,0 @@
1
- import React from 'react';
2
- import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
3
- import { moderateScale } from 'react-native-size-matters';
4
- import { RFValue } from 'react-native-responsive-fontsize';
5
- import { X } from 'lucide-react-native';
6
- import { lockToPortrait } from '../utils';
7
- import { useVideoPlayerConfig } from '../context';
8
- import { useVideoPlayerStore } from '../store/videoPlayerStore';
9
-
10
- interface TopControlsProps {
11
- onClose?: () => void;
12
- }
13
-
14
- const TopControls: React.FC<TopControlsProps> = ({ onClose }) => {
15
- const { activeTrack } = useVideoPlayerStore();
16
- const { colors } = useVideoPlayerConfig();
17
- const handleClose = () => {
18
- // onClose already handles reportProgress and store reset in VideoPlayerCore
19
- onClose?.();
20
- lockToPortrait();
21
- };
22
-
23
- const showSubtitle =
24
- activeTrack?.isTrailer ||
25
- activeTrack?.seasonNumber !== undefined ||
26
- activeTrack?.episodeNumber !== undefined;
27
-
28
- return (
29
- <View style={styles.container}>
30
- <View style={styles.textContainer}>
31
- <Text
32
- numberOfLines={1}
33
- ellipsizeMode="tail"
34
- style={[styles.title, { color: colors.text }]}
35
- >
36
- {activeTrack?.title || 'Unknown'}
37
- </Text>
38
- {showSubtitle && (
39
- <Text style={[styles.subtitle, { color: colors.text }]}>
40
- {activeTrack?.isTrailer
41
- ? 'Trailer'
42
- : `${
43
- activeTrack?.seasonNumber
44
- ? `S${activeTrack.seasonNumber} `
45
- : ''
46
- }${
47
- activeTrack?.episodeNumber
48
- ? `E${activeTrack.episodeNumber}`
49
- : ''
50
- }`}
51
- </Text>
52
- )}
53
- </View>
54
-
55
- <TouchableOpacity
56
- style={styles.closeButton}
57
- onPress={handleClose}
58
- accessibilityRole="button"
59
- accessibilityLabel="Close player"
60
- accessibilityHint="Closes the video player and exits"
61
- >
62
- <X size={moderateScale(25)} color={colors.text} />
63
- </TouchableOpacity>
64
- </View>
65
- );
66
- };
67
-
68
- export default TopControls;
69
-
70
- const styles = StyleSheet.create({
71
- container: {
72
- flexDirection: 'row',
73
- justifyContent: 'space-between',
74
- alignItems: 'center',
75
- paddingHorizontal: moderateScale(16),
76
- paddingVertical: moderateScale(8),
77
- zIndex: 51,
78
- },
79
- textContainer: {
80
- flex: 1,
81
- minWidth: 0,
82
- paddingRight: moderateScale(10),
83
- },
84
- title: {
85
- fontSize: RFValue(18),
86
- fontWeight: '600',
87
- },
88
- subtitle: {
89
- fontSize: RFValue(14),
90
- fontWeight: '400',
91
- marginTop: moderateScale(2),
92
- },
93
- closeButton: {
94
- width: moderateScale(40),
95
- height: moderateScale(40),
96
- justifyContent: 'center',
97
- alignItems: 'center',
98
- borderRadius: moderateScale(20),
99
- },
100
- });