ui changes for next episode

This commit is contained in:
tapframe 2025-08-13 13:56:45 +05:30
parent a9bb8c1131
commit ac504b99c8
3 changed files with 37 additions and 43 deletions

View file

@ -781,15 +781,12 @@ const AndroidVideoPlayer: React.FC = () => {
}
disableImmersiveMode();
// For series, reset to streams screen for current episode to ensure no hidden players remain on the stack
// For series, hard reset to a single Streams route to avoid stacking multiple modals/pages
if (type === 'series' && id && episodeId) {
(navigation as any).reset({
index: 0,
routes: [
{
name: 'Streams',
params: { id, type: 'series', episodeId }
}
{ name: 'Streams', params: { id, type: 'series', episodeId } }
]
});
} else {
@ -804,15 +801,12 @@ const AndroidVideoPlayer: React.FC = () => {
}
disableImmersiveMode();
// For series, reset to streams screen for current episode to ensure no hidden players remain on the stack
// For series, hard reset to a single Streams route to avoid stacking multiple modals/pages
if (type === 'series' && id && episodeId) {
(navigation as any).reset({
index: 0,
routes: [
{
name: 'Streams',
params: { id, type: 'series', episodeId }
}
{ name: 'Streams', params: { id, type: 'series', episodeId } }
]
});
} else {
@ -1418,7 +1412,7 @@ const AndroidVideoPlayer: React.FC = () => {
// Handle next episode button visibility based on current time and next episode availability
useEffect(() => {
if ((type as any) !== 'series' || !nextEpisode || duration <= 0 || isLoadingNextEpisode) {
if ((type as any) !== 'series' || !nextEpisode || duration <= 0) {
if (showNextEpisodeButton) {
// Hide button with animation
Animated.parallel([
@ -1439,9 +1433,9 @@ const AndroidVideoPlayer: React.FC = () => {
return;
}
// Show button when 2.5 minutes (150 seconds) remain
// Show button when 1 minute (60 seconds) remains
const timeRemaining = duration - currentTime;
const shouldShowButton = timeRemaining <= 150 && timeRemaining > 10; // Hide in last 10 seconds
const shouldShowButton = timeRemaining <= 60 && timeRemaining > 10; // Hide in last 10 seconds
if (shouldShowButton && !showNextEpisodeButton) {
setShowNextEpisodeButton(true);
@ -1474,7 +1468,7 @@ const AndroidVideoPlayer: React.FC = () => {
setShowNextEpisodeButton(false);
});
}
}, [type, nextEpisode, duration, currentTime, showNextEpisodeButton, isLoadingNextEpisode]);
}, [type, nextEpisode, duration, currentTime, showNextEpisodeButton]);
useEffect(() => {
isMounted.current = true;
@ -1980,11 +1974,11 @@ const AndroidVideoPlayer: React.FC = () => {
{/* Next Episode Button */}
{showNextEpisodeButton && nextEpisode && (
<Animated.View
<Animated.View
style={{
position: 'absolute',
bottom: 80 + insets.bottom,
right: 24 + insets.right,
right: 8 + insets.right,
opacity: nextEpisodeButtonOpacity,
transform: [{ scale: nextEpisodeButtonScale }],
}}
@ -1992,9 +1986,9 @@ const AndroidVideoPlayer: React.FC = () => {
<TouchableOpacity
style={{
backgroundColor: 'rgba(255,255,255,0.95)',
borderRadius: 25,
paddingHorizontal: 20,
paddingVertical: 12,
borderRadius: 18,
paddingHorizontal: 14,
paddingVertical: 8,
flexDirection: 'row',
alignItems: 'center',
shadowColor: '#000',
@ -2004,19 +1998,18 @@ const AndroidVideoPlayer: React.FC = () => {
elevation: 8,
}}
onPress={handlePlayNextEpisode}
disabled={isLoadingNextEpisode}
activeOpacity={0.8}
>
{isLoadingNextEpisode ? (
<ActivityIndicator size="small" color="#000000" style={{ marginRight: 8 }} />
) : (
<MaterialIcons name="skip-next" size={20} color="#000000" style={{ marginRight: 8 }} />
<MaterialIcons name="skip-next" size={18} color="#000000" style={{ marginRight: 8 }} />
)}
<View>
<Text style={{ color: '#000000', fontSize: 12, fontWeight: '600', opacity: 0.7 }}>
{isLoadingNextEpisode ? 'Loading...' : 'Up Next'}
<Text style={{ color: '#000000', fontSize: 11, fontWeight: '700', opacity: 0.8 }}>
{isLoadingNextEpisode ? 'Loading next episode…' : 'Up next'}
</Text>
<Text style={{ color: '#000000', fontSize: 14, fontWeight: '700' }} numberOfLines={1}>
<Text style={{ color: '#000000', fontSize: 13, fontWeight: '700' }} numberOfLines={1}>
S{nextEpisode.season_number}E{nextEpisode.episode_number}
{nextEpisode.name ? `: ${nextEpisode.name}` : ''}
</Text>

View file

@ -825,15 +825,12 @@ const VideoPlayer: React.FC = () => {
// Navigate back with proper handling for fullscreen modal
try {
// For series, reset to streams screen for current episode to ensure no hidden players remain on the stack
// For series, hard reset to a single Streams route to avoid stacking multiple modals/pages
if (type === 'series' && id && episodeId) {
(navigation as any).reset({
index: 0,
routes: [
{
name: 'Streams',
params: { id, type: 'series', episodeId }
}
{ name: 'Streams', params: { id, type: 'series', episodeId } }
]
});
} else if (navigation.canGoBack()) {
@ -1319,7 +1316,7 @@ const VideoPlayer: React.FC = () => {
// Handle next episode button visibility based on current time and next episode availability
useEffect(() => {
if (type !== 'series' || !nextEpisode || duration <= 0 || isLoadingNextEpisode) {
if (type !== 'series' || !nextEpisode || duration <= 0) {
if (showNextEpisodeButton) {
// Hide button with animation
Animated.parallel([
@ -1340,9 +1337,9 @@ const VideoPlayer: React.FC = () => {
return;
}
// Show button when 2.5 minutes (150 seconds) remain
// Show button when 1 minute (60 seconds) remains
const timeRemaining = duration - currentTime;
const shouldShowButton = timeRemaining <= 150 && timeRemaining > 10; // Hide in last 10 seconds
const shouldShowButton = timeRemaining <= 60 && timeRemaining > 10; // Hide in last 10 seconds
if (shouldShowButton && !showNextEpisodeButton) {
setShowNextEpisodeButton(true);
@ -1375,7 +1372,7 @@ const VideoPlayer: React.FC = () => {
setShowNextEpisodeButton(false);
});
}
}, [type, nextEpisode, duration, currentTime, showNextEpisodeButton, isLoadingNextEpisode]);
}, [type, nextEpisode, duration, currentTime, showNextEpisodeButton]);
useEffect(() => {
isMounted.current = true;
@ -1888,7 +1885,7 @@ const VideoPlayer: React.FC = () => {
style={{
position: 'absolute',
bottom: 80 + insets.bottom,
right: 24 + insets.right,
right: 8 + insets.right,
opacity: nextEpisodeButtonOpacity,
transform: [{ scale: nextEpisodeButtonScale }],
}}
@ -1896,9 +1893,9 @@ const VideoPlayer: React.FC = () => {
<TouchableOpacity
style={{
backgroundColor: 'rgba(255,255,255,0.95)',
borderRadius: 25,
paddingHorizontal: 20,
paddingVertical: 12,
borderRadius: 18,
paddingHorizontal: 14,
paddingVertical: 8,
flexDirection: 'row',
alignItems: 'center',
shadowColor: '#000',
@ -1908,19 +1905,18 @@ const VideoPlayer: React.FC = () => {
elevation: 8,
}}
onPress={handlePlayNextEpisode}
disabled={isLoadingNextEpisode}
activeOpacity={0.8}
>
{isLoadingNextEpisode ? (
<ActivityIndicator size="small" color="#000000" style={{ marginRight: 8 }} />
) : (
<MaterialIcons name="skip-next" size={20} color="#000000" style={{ marginRight: 8 }} />
<MaterialIcons name="skip-next" size={18} color="#000000" style={{ marginRight: 8 }} />
)}
<View>
<Text style={{ color: '#000000', fontSize: 12, fontWeight: '600', opacity: 0.7 }}>
{isLoadingNextEpisode ? 'Loading...' : 'Up Next'}
<Text style={{ color: '#000000', fontSize: 11, fontWeight: '700', opacity: 0.8 }}>
{isLoadingNextEpisode ? 'Loading next episode…' : 'Up next'}
</Text>
<Text style={{ color: '#000000', fontSize: 14, fontWeight: '700' }} numberOfLines={1}>
<Text style={{ color: '#000000', fontSize: 13, fontWeight: '700' }} numberOfLines={1}>
S{nextEpisode.season_number}E{nextEpisode.episode_number}
{nextEpisode.name ? `: ${nextEpisode.name}` : ''}
</Text>

View file

@ -16,6 +16,7 @@ import {
Linking,
Clipboard,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import * as ScreenOrientation from 'expo-screen-orientation';
import { useRoute, useNavigation, useFocusEffect } from '@react-navigation/native';
@ -349,6 +350,7 @@ const ProviderFilter = memo(({
});
export const StreamsScreen = () => {
const insets = useSafeAreaInsets();
const route = useRoute<RouteProp<RootStackParamList, 'Streams'>>();
const navigation = useNavigation<RootStackNavigationProp>();
const { id, type, episodeId, episodeThumbnail } = route.params;
@ -1381,7 +1383,10 @@ export const StreamsScreen = () => {
style={[styles.backButtonContainer]}
>
<TouchableOpacity
style={styles.backButton}
style={[
styles.backButton,
Platform.OS === 'ios' ? { paddingTop: Math.max(insets.top, 12) + 6 } : null
]}
onPress={handleBack}
activeOpacity={0.7}
>