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.
This commit is contained in:
tapframe 2025-06-21 02:14:13 +05:30
parent 7086184eae
commit cfb8ee56cf
2 changed files with 63 additions and 29 deletions

View file

@ -152,6 +152,15 @@ const AndroidVideoPlayer: React.FC = () => {
const [currentStreamProvider, setCurrentStreamProvider] = useState<string | undefined>(streamProvider);
const [currentStreamName, setCurrentStreamName] = useState<string | undefined>(streamName);
const isMounted = useRef(true);
const controlsTimeout = useRef<NodeJS.Timeout | null>(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) => {

View file

@ -147,6 +147,15 @@ const VideoPlayer: React.FC = () => {
const [currentStreamProvider, setCurrentStreamProvider] = useState<string | undefined>(streamProvider);
const [currentStreamName, setCurrentStreamName] = useState<string | undefined>(streamName);
const isMounted = useRef(true);
const controlsTimeout = useRef<NodeJS.Timeout | null>(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);
};