mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-20 16:22:04 +00:00
made some changes to streamscreen
This commit is contained in:
parent
b6916dcafd
commit
3f57a19ea2
4 changed files with 47 additions and 54 deletions
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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}>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue