mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
Refactor AndroidVideoPlayer and VideoPlayer components to simplify resume functionality and remove preference handling
This update streamlines the resume functionality in both the AndroidVideoPlayer and VideoPlayer components by removing the remember choice and resume preference states. The logic for showing the resume overlay has been simplified, enhancing the user experience. Additionally, the ResumeOverlay component has been updated to reflect these changes, removing unnecessary props related to user preferences. This refactor aims to create a more straightforward and efficient playback experience.
This commit is contained in:
parent
87cd33b90b
commit
3fbec2c096
5 changed files with 20 additions and 213 deletions
|
|
@ -107,8 +107,6 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
const [showResumeOverlay, setShowResumeOverlay] = useState(false);
|
||||
const [resumePosition, setResumePosition] = useState<number | null>(null);
|
||||
const [savedDuration, setSavedDuration] = useState<number | null>(null);
|
||||
const [rememberChoice, setRememberChoice] = useState(false);
|
||||
const [resumePreference, setResumePreference] = useState<string | null>(null);
|
||||
const fadeAnim = useRef(new Animated.Value(1)).current;
|
||||
const [isOpeningAnimationComplete, setIsOpeningAnimationComplete] = useState(false);
|
||||
const openingFadeAnim = useRef(new Animated.Value(0)).current;
|
||||
|
|
@ -282,20 +280,8 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
setResumePosition(savedProgress.currentTime);
|
||||
setSavedDuration(savedProgress.duration);
|
||||
logger.log(`[AndroidVideoPlayer] Set resume position to: ${savedProgress.currentTime} of ${savedProgress.duration}`);
|
||||
|
||||
const pref = await AsyncStorage.getItem(RESUME_PREF_KEY);
|
||||
logger.log(`[AndroidVideoPlayer] Resume preference: ${pref}`);
|
||||
|
||||
if (pref === RESUME_PREF.ALWAYS_RESUME) {
|
||||
setInitialPosition(savedProgress.currentTime);
|
||||
logger.log(`[AndroidVideoPlayer] Auto-resuming due to preference`);
|
||||
} else if (pref === RESUME_PREF.ALWAYS_START_OVER) {
|
||||
setInitialPosition(0);
|
||||
logger.log(`[AndroidVideoPlayer] Auto-starting over due to preference`);
|
||||
} else {
|
||||
setShowResumeOverlay(true);
|
||||
logger.log(`[AndroidVideoPlayer] Showing resume overlay`);
|
||||
}
|
||||
setShowResumeOverlay(true);
|
||||
logger.log(`[AndroidVideoPlayer] Showing resume overlay`);
|
||||
} else {
|
||||
logger.log(`[AndroidVideoPlayer] Progress too high (${progressPercent.toFixed(1)}%), not showing resume overlay`);
|
||||
}
|
||||
|
|
@ -592,79 +578,17 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const loadResumePreference = async () => {
|
||||
try {
|
||||
logger.log(`[AndroidVideoPlayer] Loading resume preference, resumePosition=${resumePosition}`);
|
||||
const pref = await AsyncStorage.getItem(RESUME_PREF_KEY);
|
||||
logger.log(`[AndroidVideoPlayer] Resume preference loaded: ${pref}`);
|
||||
|
||||
if (pref) {
|
||||
setResumePreference(pref);
|
||||
if (pref === RESUME_PREF.ALWAYS_RESUME && resumePosition !== null) {
|
||||
logger.log(`[AndroidVideoPlayer] Auto-resuming due to preference`);
|
||||
setShowResumeOverlay(false);
|
||||
setInitialPosition(resumePosition);
|
||||
} else if (pref === RESUME_PREF.ALWAYS_START_OVER) {
|
||||
logger.log(`[AndroidVideoPlayer] Auto-starting over due to preference`);
|
||||
setShowResumeOverlay(false);
|
||||
setInitialPosition(0);
|
||||
}
|
||||
// Don't override overlay if no specific preference or preference doesn't match
|
||||
} else {
|
||||
logger.log(`[AndroidVideoPlayer] No resume preference found, keeping overlay state`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('[AndroidVideoPlayer] Error loading resume preference:', error);
|
||||
}
|
||||
};
|
||||
loadResumePreference();
|
||||
}, [resumePosition]);
|
||||
|
||||
const resetResumePreference = async () => {
|
||||
try {
|
||||
await AsyncStorage.removeItem(RESUME_PREF_KEY);
|
||||
setResumePreference(null);
|
||||
} catch (error) {
|
||||
logger.error('[AndroidVideoPlayer] Error resetting resume preference:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleResume = async () => {
|
||||
if (resumePosition !== null) {
|
||||
if (rememberChoice) {
|
||||
try {
|
||||
await AsyncStorage.setItem(RESUME_PREF_KEY, RESUME_PREF.ALWAYS_RESUME);
|
||||
} catch (error) {
|
||||
logger.error('[AndroidVideoPlayer] Error saving resume preference:', error);
|
||||
}
|
||||
}
|
||||
|
||||
setShowResumeOverlay(false);
|
||||
|
||||
// If video is already loaded and ready, seek immediately
|
||||
if (isPlayerReady && duration > 0 && videoRef.current) {
|
||||
seekToTime(resumePosition);
|
||||
} else {
|
||||
// Otherwise, set initial position for when video loads
|
||||
setInitialPosition(resumePosition);
|
||||
}
|
||||
if (resumePosition) {
|
||||
seekToTime(resumePosition);
|
||||
}
|
||||
setShowResumeOverlay(false);
|
||||
};
|
||||
|
||||
const handleStartFromBeginning = async () => {
|
||||
if (DEBUG_MODE) logger.log("[AndroidVideoPlayer] Starting from beginning.");
|
||||
seekToTime(0);
|
||||
setShowResumeOverlay(false);
|
||||
if (videoRef.current) {
|
||||
seekToTime(0);
|
||||
}
|
||||
await resetResumePreference();
|
||||
setPaused(false);
|
||||
// Start playback
|
||||
if (isMounted.current) {
|
||||
setIsInitialSeekComplete(true);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleControls = () => {
|
||||
|
|
@ -1113,13 +1037,9 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
showResumeOverlay={showResumeOverlay}
|
||||
resumePosition={resumePosition}
|
||||
duration={savedDuration || duration}
|
||||
title={title}
|
||||
title={episodeTitle || title}
|
||||
season={season}
|
||||
episode={episode}
|
||||
rememberChoice={rememberChoice}
|
||||
setRememberChoice={setRememberChoice}
|
||||
resumePreference={resumePreference}
|
||||
resetResumePreference={resetResumePreference}
|
||||
handleResume={handleResume}
|
||||
handleStartFromBeginning={handleStartFromBeginning}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -102,8 +102,6 @@ const VideoPlayer: React.FC = () => {
|
|||
const [showResumeOverlay, setShowResumeOverlay] = useState(false);
|
||||
const [resumePosition, setResumePosition] = useState<number | null>(null);
|
||||
const [savedDuration, setSavedDuration] = useState<number | null>(null);
|
||||
const [rememberChoice, setRememberChoice] = useState(false);
|
||||
const [resumePreference, setResumePreference] = useState<string | null>(null);
|
||||
const fadeAnim = useRef(new Animated.Value(1)).current;
|
||||
const [isOpeningAnimationComplete, setIsOpeningAnimationComplete] = useState(false);
|
||||
const openingFadeAnim = useRef(new Animated.Value(0)).current;
|
||||
|
|
@ -277,20 +275,8 @@ const VideoPlayer: React.FC = () => {
|
|||
setResumePosition(savedProgress.currentTime);
|
||||
setSavedDuration(savedProgress.duration);
|
||||
logger.log(`[VideoPlayer] Set resume position to: ${savedProgress.currentTime} of ${savedProgress.duration}`);
|
||||
|
||||
const pref = await AsyncStorage.getItem(RESUME_PREF_KEY);
|
||||
logger.log(`[VideoPlayer] Resume preference: ${pref}`);
|
||||
|
||||
if (pref === RESUME_PREF.ALWAYS_RESUME) {
|
||||
setInitialPosition(savedProgress.currentTime);
|
||||
logger.log(`[VideoPlayer] Auto-resuming due to preference`);
|
||||
} else if (pref === RESUME_PREF.ALWAYS_START_OVER) {
|
||||
setInitialPosition(0);
|
||||
logger.log(`[VideoPlayer] Auto-starting over due to preference`);
|
||||
} else {
|
||||
setShowResumeOverlay(true);
|
||||
logger.log(`[VideoPlayer] Showing resume overlay`);
|
||||
}
|
||||
setShowResumeOverlay(true);
|
||||
logger.log(`[VideoPlayer] Showing resume overlay`);
|
||||
} else {
|
||||
logger.log(`[VideoPlayer] Progress too high (${progressPercent.toFixed(1)}%), not showing resume overlay`);
|
||||
}
|
||||
|
|
@ -606,81 +592,17 @@ const VideoPlayer: React.FC = () => {
|
|||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const loadResumePreference = async () => {
|
||||
try {
|
||||
logger.log(`[VideoPlayer] Loading resume preference, resumePosition=${resumePosition}`);
|
||||
const pref = await AsyncStorage.getItem(RESUME_PREF_KEY);
|
||||
logger.log(`[VideoPlayer] Resume preference loaded: ${pref}`);
|
||||
|
||||
if (pref) {
|
||||
setResumePreference(pref);
|
||||
if (pref === RESUME_PREF.ALWAYS_RESUME && resumePosition !== null) {
|
||||
logger.log(`[VideoPlayer] Auto-resuming due to preference`);
|
||||
setShowResumeOverlay(false);
|
||||
setInitialPosition(resumePosition);
|
||||
} else if (pref === RESUME_PREF.ALWAYS_START_OVER) {
|
||||
logger.log(`[VideoPlayer] Auto-starting over due to preference`);
|
||||
setShowResumeOverlay(false);
|
||||
setInitialPosition(0);
|
||||
}
|
||||
// Don't override overlay if no specific preference or preference doesn't match
|
||||
} else {
|
||||
logger.log(`[VideoPlayer] No resume preference found, keeping overlay state`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('[VideoPlayer] Error loading resume preference:', error);
|
||||
}
|
||||
};
|
||||
loadResumePreference();
|
||||
}, [resumePosition]);
|
||||
|
||||
const resetResumePreference = async () => {
|
||||
try {
|
||||
await AsyncStorage.removeItem(RESUME_PREF_KEY);
|
||||
setResumePreference(null);
|
||||
} catch (error) {
|
||||
logger.error('[VideoPlayer] Error resetting resume preference:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleResume = async () => {
|
||||
if (resumePosition !== null) {
|
||||
if (rememberChoice) {
|
||||
try {
|
||||
await AsyncStorage.setItem(RESUME_PREF_KEY, RESUME_PREF.ALWAYS_RESUME);
|
||||
} catch (error) {
|
||||
logger.error('[VideoPlayer] Error saving resume preference:', error);
|
||||
}
|
||||
}
|
||||
|
||||
setShowResumeOverlay(false);
|
||||
|
||||
// If video is already loaded and ready, seek immediately
|
||||
if (isPlayerReady && duration > 0 && vlcRef.current) {
|
||||
seekToTime(resumePosition);
|
||||
} else {
|
||||
// Otherwise, set initial position for when video loads
|
||||
setInitialPosition(resumePosition);
|
||||
}
|
||||
if (resumePosition) {
|
||||
seekToTime(resumePosition);
|
||||
}
|
||||
setShowResumeOverlay(false);
|
||||
};
|
||||
|
||||
const handleStartFromBeginning = async () => {
|
||||
if (rememberChoice) {
|
||||
try {
|
||||
await AsyncStorage.setItem(RESUME_PREF_KEY, RESUME_PREF.ALWAYS_START_OVER);
|
||||
} catch (error) {
|
||||
logger.error('[VideoPlayer] Error saving resume preference:', error);
|
||||
}
|
||||
}
|
||||
seekToTime(0);
|
||||
setShowResumeOverlay(false);
|
||||
setInitialPosition(0);
|
||||
if (vlcRef.current) {
|
||||
seekToTime(0);
|
||||
setCurrentTime(0);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleControls = () => {
|
||||
|
|
@ -1127,13 +1049,9 @@ const VideoPlayer: React.FC = () => {
|
|||
showResumeOverlay={showResumeOverlay}
|
||||
resumePosition={resumePosition}
|
||||
duration={savedDuration || duration}
|
||||
title={title}
|
||||
title={episodeTitle || title}
|
||||
season={season}
|
||||
episode={episode}
|
||||
rememberChoice={rememberChoice}
|
||||
setRememberChoice={setRememberChoice}
|
||||
resumePreference={resumePreference}
|
||||
resetResumePreference={resetResumePreference}
|
||||
handleResume={handleResume}
|
||||
handleStartFromBeginning={handleStartFromBeginning}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@ interface ResumeOverlayProps {
|
|||
title: string;
|
||||
season?: number;
|
||||
episode?: number;
|
||||
rememberChoice: boolean;
|
||||
setRememberChoice: (remember: boolean) => void;
|
||||
resumePreference: string | null;
|
||||
resetResumePreference: () => void;
|
||||
handleResume: () => void;
|
||||
handleStartFromBeginning: () => void;
|
||||
}
|
||||
|
|
@ -28,10 +24,6 @@ export const ResumeOverlay: React.FC<ResumeOverlayProps> = ({
|
|||
title,
|
||||
season,
|
||||
episode,
|
||||
rememberChoice,
|
||||
setRememberChoice,
|
||||
resumePreference,
|
||||
resetResumePreference,
|
||||
handleResume,
|
||||
handleStartFromBeginning,
|
||||
}) => {
|
||||
|
|
@ -78,29 +70,6 @@ export const ResumeOverlay: React.FC<ResumeOverlayProps> = ({
|
|||
</View>
|
||||
</View>
|
||||
|
||||
{/* Remember choice checkbox */}
|
||||
<TouchableOpacity
|
||||
style={styles.rememberChoiceContainer}
|
||||
onPress={() => setRememberChoice(!rememberChoice)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<View style={styles.checkboxContainer}>
|
||||
<View style={[styles.checkbox, rememberChoice && styles.checkboxChecked]}>
|
||||
{rememberChoice && <Ionicons name="checkmark" size={12} color="white" />}
|
||||
</View>
|
||||
<Text style={styles.rememberChoiceText}>Remember my choice</Text>
|
||||
</View>
|
||||
|
||||
{resumePreference && (
|
||||
<TouchableOpacity
|
||||
onPress={resetResumePreference}
|
||||
style={styles.resetPreferenceButton}
|
||||
>
|
||||
<Text style={styles.resetPreferenceText}>Reset</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.resumeButtons}>
|
||||
<TouchableOpacity
|
||||
style={styles.resumeButton}
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ const HomeScreen = () => {
|
|||
.map(item => [item.poster, item.banner, item.logo])
|
||||
.flat()
|
||||
.filter(Boolean) as string[];
|
||||
|
||||
|
||||
// Process in small batches to prevent memory pressure
|
||||
for (let i = 0; i < allImages.length; i += BATCH_SIZE) {
|
||||
const batch = allImages.slice(i, i + BATCH_SIZE);
|
||||
|
|
@ -383,15 +383,15 @@ const HomeScreen = () => {
|
|||
|
||||
// Lock orientation to landscape before navigation to prevent glitches
|
||||
try {
|
||||
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE);
|
||||
|
||||
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE);
|
||||
|
||||
// Longer delay to ensure orientation is fully set before navigation
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
} catch (orientationError) {
|
||||
// If orientation lock fails, continue anyway but log it
|
||||
logger.warn('[HomeScreen] Orientation lock failed:', orientationError);
|
||||
// Still add a small delay
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
|
||||
navigation.navigate('Player', {
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ export const StreamsScreen = () => {
|
|||
const loadStartTimeRef = useRef(0);
|
||||
const hasDoneInitialLoadRef = useRef(false);
|
||||
|
||||
|
||||
|
||||
|
||||
// Add timing logs
|
||||
const [loadStartTime, setLoadStartTime] = useState(0);
|
||||
|
|
@ -1022,7 +1022,7 @@ export const StreamsScreen = () => {
|
|||
backgroundColor="transparent"
|
||||
barStyle="light-content"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<Animated.View
|
||||
entering={FadeIn.duration(300)}
|
||||
|
|
|
|||
Loading…
Reference in a new issue