made some changes to streamscreen

This commit is contained in:
tapframe 2025-08-10 13:43:15 +05:30
parent b6916dcafd
commit 3f57a19ea2
4 changed files with 47 additions and 54 deletions

View file

@ -1581,6 +1581,7 @@ const AndroidVideoPlayer: React.FC = () => {
cycleAspectRatio={cycleAspectRatio} cycleAspectRatio={cycleAspectRatio}
setShowAudioModal={setShowAudioModal} setShowAudioModal={setShowAudioModal}
setShowSubtitleModal={setShowSubtitleModal} setShowSubtitleModal={setShowSubtitleModal}
isSubtitleModalOpen={showSubtitleModal}
setShowSourcesModal={setShowSourcesModal} setShowSourcesModal={setShowSourcesModal}
onSliderValueChange={handleSliderValueChange} onSliderValueChange={handleSliderValueChange}
onSlidingStart={handleSlidingStart} onSlidingStart={handleSlidingStart}

View file

@ -1497,6 +1497,7 @@ const VideoPlayer: React.FC = () => {
cycleAspectRatio={cycleAspectRatio} cycleAspectRatio={cycleAspectRatio}
setShowAudioModal={setShowAudioModal} setShowAudioModal={setShowAudioModal}
setShowSubtitleModal={setShowSubtitleModal} setShowSubtitleModal={setShowSubtitleModal}
isSubtitleModalOpen={showSubtitleModal}
setShowSourcesModal={setShowSourcesModal} setShowSourcesModal={setShowSourcesModal}
onSliderValueChange={handleSliderValueChange} onSliderValueChange={handleSliderValueChange}
onSlidingStart={handleSlidingStart} onSlidingStart={handleSlidingStart}

View file

@ -31,6 +31,7 @@ interface PlayerControlsProps {
cycleAspectRatio: () => void; cycleAspectRatio: () => void;
setShowAudioModal: (show: boolean) => void; setShowAudioModal: (show: boolean) => void;
setShowSubtitleModal: (show: boolean) => void; setShowSubtitleModal: (show: boolean) => void;
isSubtitleModalOpen?: boolean;
setShowSourcesModal?: (show: boolean) => void; setShowSourcesModal?: (show: boolean) => void;
// Slider-specific props // Slider-specific props
onSliderValueChange: (value: number) => void; onSliderValueChange: (value: number) => void;
@ -65,6 +66,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
cycleAspectRatio, cycleAspectRatio,
setShowAudioModal, setShowAudioModal,
setShowSubtitleModal, setShowSubtitleModal,
isSubtitleModalOpen,
setShowSourcesModal, setShowSourcesModal,
onSliderValueChange, onSliderValueChange,
onSlidingStart, onSlidingStart,
@ -182,7 +184,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
{/* Subtitle Button - Always available for external subtitle search */} {/* Subtitle Button - Always available for external subtitle search */}
<TouchableOpacity <TouchableOpacity
style={styles.bottomButton} style={styles.bottomButton}
onPress={() => setShowSubtitleModal(true)} onPress={() => setShowSubtitleModal(!isSubtitleModalOpen)}
> >
<Ionicons name="text" size={20} color="white" /> <Ionicons name="text" size={20} color="white" />
<Text style={styles.bottomButtonText}> <Text style={styles.bottomButtonText}>

View file

@ -305,8 +305,8 @@ const ProviderFilter = memo(({
const styles = React.useMemo(() => createStyles(theme.colors), [theme.colors]); const styles = React.useMemo(() => createStyles(theme.colors), [theme.colors]);
const renderItem = useCallback(({ item, index }: { item: { id: string; name: string }; index: number }) => ( const renderItem = useCallback(({ item, index }: { item: { id: string; name: string }; index: number }) => (
<TouchableOpacity <Animated.View entering={FadeIn.duration(300).delay(index * 75)}>
key={item.id} <TouchableOpacity
style={[ style={[
styles.filterChip, styles.filterChip,
selectedProvider === item.id && styles.filterChipSelected selectedProvider === item.id && styles.filterChipSelected
@ -320,6 +320,7 @@ const ProviderFilter = memo(({
{item.name} {item.name}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
</Animated.View>
), [selectedProvider, onSelect, styles]); ), [selectedProvider, onSelect, styles]);
return ( return (
@ -1284,16 +1285,17 @@ export const StreamsScreen = () => {
const isLoading = false; // If streams are being rendered, they're available and shouldn't be loading const isLoading = false; // If streams are being rendered, they're available and shouldn't be loading
return ( return (
<StreamCard <Animated.View entering={FadeIn.duration(300).delay(index * 50)}>
key={`${stream.url}-${index}`} <StreamCard
stream={stream} stream={stream}
onPress={() => handleStreamPress(stream)} onPress={() => handleStreamPress(stream)}
index={index} index={index}
isLoading={isLoading} isLoading={isLoading}
statusMessage={undefined} statusMessage={undefined}
theme={currentTheme} theme={currentTheme}
showLogos={settings.showScraperLogos} showLogos={settings.showScraperLogos}
/> />
</Animated.View>
); );
}, [handleStreamPress, currentTheme, settings.showScraperLogos]); }, [handleStreamPress, currentTheme, settings.showScraperLogos]);
@ -1369,44 +1371,32 @@ export const StreamsScreen = () => {
</Animated.View> </Animated.View>
)} )}
{type === 'series' && currentEpisode && ( {type === 'series' && (
<Animated.View style={[styles.streamsHeroContainer, heroStyle]}> <Animated.View style={[styles.streamsHeroContainer, heroStyle]}>
<Animated.View <Animated.View entering={FadeIn.duration(300)} style={StyleSheet.absoluteFill}>
entering={FadeIn.duration(300)} <Animated.View
style={StyleSheet.absoluteFill} entering={FadeIn.duration(400).delay(100).withInitialValues({ transform: [{ scale: 1.05 }] })}
>
<Animated.View
entering={FadeIn.duration(400).delay(100).withInitialValues({
transform: [{ scale: 1.05 }]
})}
style={StyleSheet.absoluteFill} style={StyleSheet.absoluteFill}
> >
<ImageBackground <Image
source={episodeImage ? { uri: episodeImage } : undefined} source={episodeImage ? { uri: episodeImage } : undefined}
style={styles.streamsHeroBackground} style={styles.streamsHeroBackground}
fadeDuration={0} contentFit="cover"
resizeMode="cover" transition={500}
/>
<LinearGradient
colors={['rgba(0,0,0,0)', 'rgba(0,0,0,0.3)', 'rgba(0,0,0,0.5)', 'rgba(0,0,0,0.7)', colors.darkBackground]}
locations={[0, 0.4, 0.6, 0.8, 1]}
style={styles.streamsHeroGradient}
> >
<LinearGradient <View style={styles.streamsHeroContent}>
colors={[ {currentEpisode ? (
'rgba(0,0,0,0)', <Animated.View entering={FadeIn.duration(400).delay(300)} style={styles.streamsHeroInfo}>
'rgba(0,0,0,0.3)', <Text style={styles.streamsHeroEpisodeNumber}>{currentEpisode.episodeString}</Text>
'rgba(0,0,0,0.5)',
'rgba(0,0,0,0.7)',
colors.darkBackground
]}
locations={[0, 0.4, 0.6, 0.8, 1]}
style={styles.streamsHeroGradient}
>
<View style={styles.streamsHeroContent}>
<View style={styles.streamsHeroInfo}>
<Text style={styles.streamsHeroEpisodeNumber}>
{currentEpisode.episodeString}
</Text>
<Text style={styles.streamsHeroTitle} numberOfLines={1}> <Text style={styles.streamsHeroTitle} numberOfLines={1}>
{currentEpisode.name} {currentEpisode.name}
</Text> </Text>
{currentEpisode.overview && ( {!!currentEpisode.overview && (
<Text style={styles.streamsHeroOverview} numberOfLines={2}> <Text style={styles.streamsHeroOverview} numberOfLines={2}>
{currentEpisode.overview} {currentEpisode.overview}
</Text> </Text>
@ -1417,17 +1407,13 @@ export const StreamsScreen = () => {
</Text> </Text>
{currentEpisode.vote_average > 0 && ( {currentEpisode.vote_average > 0 && (
<View style={styles.streamsHeroRating}> <View style={styles.streamsHeroRating}>
<Image <Image source={{ uri: TMDB_LOGO }} style={styles.tmdbLogo} contentFit="contain" />
source={{ uri: TMDB_LOGO }}
style={styles.tmdbLogo}
contentFit="contain"
/>
<Text style={styles.streamsHeroRatingText}> <Text style={styles.streamsHeroRatingText}>
{currentEpisode.vote_average.toFixed(1)} {currentEpisode.vote_average.toFixed(1)}
</Text> </Text>
</View> </View>
)} )}
{currentEpisode.runtime && ( {!!currentEpisode.runtime && (
<View style={styles.streamsHeroRuntime}> <View style={styles.streamsHeroRuntime}>
<MaterialIcons name="schedule" size={16} color={colors.mediumEmphasis} /> <MaterialIcons name="schedule" size={16} color={colors.mediumEmphasis} />
<Text style={styles.streamsHeroRuntimeText}> <Text style={styles.streamsHeroRuntimeText}>
@ -1438,10 +1424,13 @@ export const StreamsScreen = () => {
</View> </View>
)} )}
</View> </View>
</View> </Animated.View>
</View> ) : (
</LinearGradient> // Placeholder to reserve space and avoid layout shift while loading
</ImageBackground> <View style={{ width: '100%', height: 120 }} />
)}
</View>
</LinearGradient>
</Animated.View> </Animated.View>
</Animated.View> </Animated.View>
</Animated.View> </Animated.View>
@ -1800,7 +1789,7 @@ const createStyles = (colors: any) => StyleSheet.create({
}, },
streamsHeroContainer: { streamsHeroContainer: {
width: '100%', width: '100%',
height: 220, height: 220, // Fixed height to prevent layout shift
marginBottom: 0, marginBottom: 0,
position: 'relative', position: 'relative',
backgroundColor: colors.black, backgroundColor: colors.black,
@ -1812,7 +1801,7 @@ const createStyles = (colors: any) => StyleSheet.create({
backgroundColor: colors.black, backgroundColor: colors.black,
}, },
streamsHeroGradient: { streamsHeroGradient: {
flex: 1, ...StyleSheet.absoluteFillObject,
justifyContent: 'flex-end', justifyContent: 'flex-end',
padding: 16, padding: 16,
paddingBottom: 0, paddingBottom: 0,