mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
small bug fixes
This commit is contained in:
parent
9b1368e7c6
commit
46cdf95cd4
5 changed files with 75 additions and 6 deletions
5
App.tsx
5
App.tsx
|
|
@ -25,6 +25,7 @@ import { CatalogProvider } from './src/contexts/CatalogContext';
|
|||
import { GenreProvider } from './src/contexts/GenreContext';
|
||||
import { TraktProvider } from './src/contexts/TraktContext';
|
||||
import { ThemeProvider, useTheme } from './src/contexts/ThemeContext';
|
||||
import { TrailerProvider } from './src/contexts/TrailerContext';
|
||||
import SplashScreen from './src/components/SplashScreen';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import * as Sentry from '@sentry/react-native';
|
||||
|
|
@ -129,7 +130,9 @@ function App(): React.JSX.Element {
|
|||
<CatalogProvider>
|
||||
<TraktProvider>
|
||||
<ThemeProvider>
|
||||
<ThemedApp />
|
||||
<TrailerProvider>
|
||||
<ThemedApp />
|
||||
</TrailerProvider>
|
||||
</ThemeProvider>
|
||||
</TraktProvider>
|
||||
</CatalogProvider>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import Animated, {
|
|||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import { useTraktContext } from '../../contexts/TraktContext';
|
||||
import { useSettings } from '../../hooks/useSettings';
|
||||
import { useTrailer } from '../../contexts/TrailerContext';
|
||||
import { logger } from '../../utils/logger';
|
||||
import { TMDBService } from '../../services/tmdbService';
|
||||
import TrailerService from '../../services/trailerService';
|
||||
|
|
@ -697,6 +698,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
|||
const { currentTheme } = useTheme();
|
||||
const { isAuthenticated: isTraktAuthenticated } = useTraktContext();
|
||||
const { settings, updateSetting } = useSettings();
|
||||
const { isTrailerPlaying: globalTrailerPlaying, setTrailerPlaying } = useTrailer();
|
||||
|
||||
// Performance optimization: Refs for avoiding re-renders
|
||||
const interactionComplete = useRef(false);
|
||||
|
|
@ -710,7 +712,6 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
|||
const [trailerError, setTrailerError] = useState(false);
|
||||
// Use persistent setting instead of local state
|
||||
const trailerMuted = settings.trailerMuted;
|
||||
const [isTrailerPlaying, setIsTrailerPlaying] = useState(false);
|
||||
const [trailerReady, setTrailerReady] = useState(false);
|
||||
const [trailerPreloaded, setTrailerPreloaded] = useState(false);
|
||||
const trailerVideoRef = useRef<any>(null);
|
||||
|
|
@ -745,7 +746,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
|||
setTrailerPreloaded(true);
|
||||
}
|
||||
setTrailerReady(true);
|
||||
setIsTrailerPlaying(true);
|
||||
setTrailerPlaying(true);
|
||||
|
||||
// Smooth transition: fade out thumbnail, fade in trailer
|
||||
thumbnailOpacity.value = withTiming(0, { duration: 500 });
|
||||
|
|
@ -768,7 +769,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
|||
const handleTrailerError = useCallback(() => {
|
||||
setTrailerError(true);
|
||||
setTrailerReady(false);
|
||||
setIsTrailerPlaying(false);
|
||||
setTrailerPlaying(false);
|
||||
|
||||
// Fade back to thumbnail
|
||||
trailerOpacity.value = withTiming(0, { duration: 300 });
|
||||
|
|
@ -1068,7 +1069,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
|||
<TrailerPlayer
|
||||
ref={trailerVideoRef}
|
||||
trailerUrl={trailerUrl}
|
||||
autoPlay={true}
|
||||
autoPlay={globalTrailerPlaying}
|
||||
muted={trailerMuted}
|
||||
style={styles.absoluteFill}
|
||||
hideLoadingSpinner={true}
|
||||
|
|
@ -1215,7 +1216,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
|||
getEpisodeDetails={getEpisodeDetails}
|
||||
animatedStyle={watchProgressAnimatedStyle}
|
||||
isWatched={isWatched}
|
||||
isTrailerPlaying={isTrailerPlaying}
|
||||
isTrailerPlaying={globalTrailerPlaying}
|
||||
trailerMuted={trailerMuted}
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -164,6 +164,11 @@ const TrailerPlayer = React.forwardRef<any, TrailerPlayerProps>(({
|
|||
setIsMuted(muted);
|
||||
}, [muted]);
|
||||
|
||||
// Sync internal playing state with autoPlay prop
|
||||
useEffect(() => {
|
||||
setIsPlaying(autoPlay);
|
||||
}, [autoPlay]);
|
||||
|
||||
// Cleanup timeout on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
|
|
|
|||
47
src/contexts/TrailerContext.tsx
Normal file
47
src/contexts/TrailerContext.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import React, { createContext, useContext, useState, useCallback, useMemo, ReactNode } from 'react';
|
||||
|
||||
interface TrailerContextValue {
|
||||
isTrailerPlaying: boolean;
|
||||
pauseTrailer: () => void;
|
||||
resumeTrailer: () => void;
|
||||
setTrailerPlaying: (playing: boolean) => void;
|
||||
}
|
||||
|
||||
const TrailerContext = createContext<TrailerContextValue | undefined>(undefined);
|
||||
|
||||
export const TrailerProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
const [isTrailerPlaying, setIsTrailerPlaying] = useState(true);
|
||||
|
||||
const pauseTrailer = useCallback(() => {
|
||||
setIsTrailerPlaying(false);
|
||||
}, []);
|
||||
|
||||
const resumeTrailer = useCallback(() => {
|
||||
setIsTrailerPlaying(true);
|
||||
}, []);
|
||||
|
||||
const setTrailerPlaying = useCallback((playing: boolean) => {
|
||||
setIsTrailerPlaying(playing);
|
||||
}, []);
|
||||
|
||||
const value: TrailerContextValue = useMemo(() => ({
|
||||
isTrailerPlaying,
|
||||
pauseTrailer,
|
||||
resumeTrailer,
|
||||
setTrailerPlaying,
|
||||
}), [isTrailerPlaying, pauseTrailer, resumeTrailer, setTrailerPlaying]);
|
||||
|
||||
return (
|
||||
<TrailerContext.Provider value={value}>
|
||||
{children}
|
||||
</TrailerContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useTrailer = (): TrailerContextValue => {
|
||||
const context = useContext(TrailerContext);
|
||||
if (!context) {
|
||||
throw new Error('useTrailer must be used within a TrailerProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
|
@ -30,6 +30,7 @@ import { RootStackParamList, RootStackNavigationProp } from '../navigation/AppNa
|
|||
import { useMetadata } from '../hooks/useMetadata';
|
||||
import { useMetadataAssets } from '../hooks/useMetadataAssets';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
import { useTrailer } from '../contexts/TrailerContext';
|
||||
import { Stream } from '../types/metadata';
|
||||
import { tmdbService } from '../services/tmdbService';
|
||||
import { stremioService } from '../services/stremioService';
|
||||
|
|
@ -360,6 +361,7 @@ export const StreamsScreen = () => {
|
|||
const { settings } = useSettings();
|
||||
const { currentTheme } = useTheme();
|
||||
const { colors } = currentTheme;
|
||||
const { pauseTrailer, resumeTrailer } = useTrailer();
|
||||
|
||||
// Add ref to prevent excessive updates
|
||||
const isMounted = useRef(true);
|
||||
|
|
@ -383,6 +385,17 @@ export const StreamsScreen = () => {
|
|||
console.log('[StreamsScreen] Received thumbnail from params:', episodeThumbnail);
|
||||
}, [episodeThumbnail]);
|
||||
|
||||
// Pause trailer when StreamsScreen is opened
|
||||
useEffect(() => {
|
||||
// Pause trailer when component mounts
|
||||
pauseTrailer();
|
||||
|
||||
// Resume trailer when component unmounts
|
||||
return () => {
|
||||
resumeTrailer();
|
||||
};
|
||||
}, [pauseTrailer, resumeTrailer]);
|
||||
|
||||
const {
|
||||
metadata,
|
||||
episodes,
|
||||
|
|
|
|||
Loading…
Reference in a new issue