From cfb8ee56cf56ab452301f544331c5259ef2f1768 Mon Sep 17 00:00:00 2001 From: tapframe Date: Sat, 21 Jun 2025 02:14:13 +0530 Subject: [PATCH] Add control visibility timeout and animation to video player components This update introduces a timeout mechanism for hiding video player controls in both AndroidVideoPlayer and VideoPlayer components. The controls will fade out after 3 seconds of inactivity, enhancing user experience by keeping the interface clean. Additionally, the toggleControls function is updated to clear the timeout when controls are shown, ensuring that the controls remain visible as long as the user interacts with the player. --- src/components/player/AndroidVideoPlayer.tsx | 56 +++++++++++++------- src/components/player/VideoPlayer.tsx | 36 +++++++++---- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index 13d5c965..dfe8dcef 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -152,6 +152,15 @@ const AndroidVideoPlayer: React.FC = () => { const [currentStreamProvider, setCurrentStreamProvider] = useState(streamProvider); const [currentStreamName, setCurrentStreamName] = useState(streamName); const isMounted = useRef(true); + const controlsTimeout = useRef(null); + + const hideControls = () => { + Animated.timing(fadeAnim, { + toValue: 0, + duration: 300, + useNativeDriver: true, + }).start(() => setShowControls(false)); + }; const calculateVideoStyles = (videoWidth: number, videoHeight: number, screenWidth: number, screenHeight: number) => { return { @@ -489,6 +498,7 @@ const AndroidVideoPlayer: React.FC = () => { }, 1000); } completeOpeningAnimation(); + controlsTimeout.current = setTimeout(hideControls, 3000); } }; @@ -624,35 +634,41 @@ const AndroidVideoPlayer: React.FC = () => { }; const handleStartFromBeginning = async () => { - if (rememberChoice) { - try { - await AsyncStorage.setItem(RESUME_PREF_KEY, RESUME_PREF.ALWAYS_START_OVER); - } catch (error) { - logger.error('[AndroidVideoPlayer] Error saving resume preference:', error); - } - } + if (DEBUG_MODE) logger.log("[AndroidVideoPlayer] Starting from beginning."); setShowResumeOverlay(false); - setInitialPosition(0); if (videoRef.current) { - seekToTime(0); - setCurrentTime(0); + seekToTime(0); + } + await resetResumePreference(); + setPaused(false); + // Start playback + if (isMounted.current) { + setIsInitialSeekComplete(true); } }; const toggleControls = () => { - setShowControls(previousState => !previousState); + if (controlsTimeout.current) { + clearTimeout(controlsTimeout.current); + controlsTimeout.current = null; + } + + setShowControls(prevShowControls => { + const newShowControls = !prevShowControls; + Animated.timing(fadeAnim, { + toValue: newShowControls ? 1 : 0, + duration: 300, + useNativeDriver: true, + }).start(); + if (newShowControls) { + controlsTimeout.current = setTimeout(hideControls, 3000); + } + return newShowControls; + }); }; - useEffect(() => { - Animated.timing(fadeAnim, { - toValue: showControls ? 1 : 0, - duration: 300, - useNativeDriver: true, - }).start(); - }, [showControls]); - const handleError = (error: any) => { - logger.error('[AndroidVideoPlayer] Playback Error:', error); + logger.error('AndroidVideoPlayer error: ', error); }; const onBuffer = (data: any) => { diff --git a/src/components/player/VideoPlayer.tsx b/src/components/player/VideoPlayer.tsx index f5d28576..cbcfd127 100644 --- a/src/components/player/VideoPlayer.tsx +++ b/src/components/player/VideoPlayer.tsx @@ -147,6 +147,15 @@ const VideoPlayer: React.FC = () => { const [currentStreamProvider, setCurrentStreamProvider] = useState(streamProvider); const [currentStreamName, setCurrentStreamName] = useState(streamName); const isMounted = useRef(true); + const controlsTimeout = useRef(null); + + const hideControls = () => { + Animated.timing(fadeAnim, { + toValue: 0, + duration: 300, + useNativeDriver: true, + }).start(() => setShowControls(false)); + }; const calculateVideoStyles = (videoWidth: number, videoHeight: number, screenWidth: number, screenHeight: number) => { return { @@ -499,6 +508,7 @@ const VideoPlayer: React.FC = () => { }, 1000); } completeOpeningAnimation(); + controlsTimeout.current = setTimeout(hideControls, 3000); } }; @@ -658,17 +668,25 @@ const VideoPlayer: React.FC = () => { }; const toggleControls = () => { - setShowControls(previousState => !previousState); + if (controlsTimeout.current) { + clearTimeout(controlsTimeout.current); + controlsTimeout.current = null; + } + + setShowControls(prevShowControls => { + const newShowControls = !prevShowControls; + Animated.timing(fadeAnim, { + toValue: newShowControls ? 1 : 0, + duration: 300, + useNativeDriver: true, + }).start(); + if (newShowControls) { + controlsTimeout.current = setTimeout(hideControls, 3000); + } + return newShowControls; + }); }; - useEffect(() => { - Animated.timing(fadeAnim, { - toValue: showControls ? 1 : 0, - duration: 300, - useNativeDriver: true, - }).start(); - }, [showControls]); - const handleError = (error: any) => { logger.error('[VideoPlayer] Playback Error:', error); };