mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-18 15:22:05 +00:00
some ui changes
This commit is contained in:
parent
d8950caf04
commit
f43d113f56
4 changed files with 37 additions and 28 deletions
|
|
@ -276,10 +276,6 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
initializePlayer();
|
||||
return () => {
|
||||
subscription?.remove();
|
||||
const unlockOrientation = async () => {
|
||||
await ScreenOrientation.unlockAsync();
|
||||
};
|
||||
unlockOrientation();
|
||||
disableImmersiveMode();
|
||||
};
|
||||
}, []);
|
||||
|
|
|
|||
|
|
@ -134,6 +134,9 @@ const VideoPlayer: React.FC = () => {
|
|||
const [showResumeOverlay, setShowResumeOverlay] = useState(false);
|
||||
const [resumePosition, setResumePosition] = useState<number | null>(null);
|
||||
const [savedDuration, setSavedDuration] = useState<number | null>(null);
|
||||
const initialSeekTargetRef = useRef<number | null>(null);
|
||||
const initialSeekVerifiedRef = useRef(false);
|
||||
const isSourceSeekableRef = useRef<boolean | null>(null);
|
||||
const fadeAnim = useRef(new Animated.Value(1)).current;
|
||||
const [isOpeningAnimationComplete, setIsOpeningAnimationComplete] = useState(false);
|
||||
const openingFadeAnim = useRef(new Animated.Value(0)).current;
|
||||
|
|
@ -292,10 +295,7 @@ const VideoPlayer: React.FC = () => {
|
|||
lockOrientation();
|
||||
|
||||
return () => {
|
||||
// Unlock orientation when component unmounts
|
||||
ScreenOrientation.unlockAsync().catch(() => {
|
||||
// Ignore unlock errors
|
||||
});
|
||||
// Do not unlock orientation here; we unlock explicitly on close to avoid mid-transition flips
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
|
@ -403,6 +403,7 @@ const VideoPlayer: React.FC = () => {
|
|||
setResumePosition(savedProgress.currentTime);
|
||||
setSavedDuration(savedProgress.duration);
|
||||
setInitialPosition(savedProgress.currentTime);
|
||||
initialSeekTargetRef.current = savedProgress.currentTime;
|
||||
logger.log(`[VideoPlayer] Set resume position to: ${savedProgress.currentTime} of ${savedProgress.duration}`);
|
||||
if (appSettings.alwaysResume) {
|
||||
logger.log(`[VideoPlayer] AlwaysResume enabled. Auto-seeking to ${savedProgress.currentTime}`);
|
||||
|
|
@ -1280,6 +1281,24 @@ const VideoPlayer: React.FC = () => {
|
|||
logger.log(`[VideoPlayer] Post-load initial seek to: ${initialPosition}s`);
|
||||
seekToTime(initialPosition);
|
||||
setIsInitialSeekComplete(true);
|
||||
// Verify whether the seek actually took effect (detect non-seekable sources)
|
||||
if (!initialSeekVerifiedRef.current) {
|
||||
initialSeekVerifiedRef.current = true;
|
||||
const target = initialSeekTargetRef.current ?? initialPosition;
|
||||
setTimeout(() => {
|
||||
const delta = Math.abs(currentTime - (target || 0));
|
||||
if (target && (currentTime < target - 1.5)) {
|
||||
logger.warn(`[VideoPlayer] Initial seek appears ignored (delta=${delta.toFixed(2)}). Treating source as non-seekable; starting from 0`);
|
||||
isSourceSeekableRef.current = false;
|
||||
// Reset resume intent and continue from 0
|
||||
setInitialPosition(null);
|
||||
setResumePosition(null);
|
||||
setShowResumeOverlay(false);
|
||||
} else {
|
||||
isSourceSeekableRef.current = true;
|
||||
}
|
||||
}, 1200);
|
||||
}
|
||||
}
|
||||
}, [isVideoLoaded, initialPosition, duration]);
|
||||
|
||||
|
|
|
|||
|
|
@ -771,8 +771,8 @@ const AppNavigator = ({ initialRouteName }: { initialRouteName?: keyof RootStack
|
|||
name="Player"
|
||||
component={VideoPlayer as any}
|
||||
options={{
|
||||
animation: 'slide_from_right',
|
||||
animationDuration: Platform.OS === 'android' ? 200 : 300,
|
||||
animation: Platform.OS === 'android' ? 'none' : 'fade',
|
||||
animationDuration: Platform.OS === 'android' ? 0 : 300,
|
||||
// Force fullscreen presentation on iPad
|
||||
presentation: Platform.OS === 'ios' ? 'fullScreenModal' : 'card',
|
||||
// Disable gestures during video playback
|
||||
|
|
|
|||
|
|
@ -839,19 +839,24 @@ export const StreamsScreen = () => {
|
|||
const streamName = stream.name || stream.title || 'Unnamed Stream';
|
||||
const streamProvider = stream.addonId || stream.addonName || stream.name;
|
||||
|
||||
// Stream provider debug logging removed
|
||||
|
||||
// NetMirror stream logging removed
|
||||
|
||||
// Navigate to player immediately without waiting for orientation lock
|
||||
// This prevents delay in player opening
|
||||
// Add pre-navigation orientation lock to reduce glitch
|
||||
try {
|
||||
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE);
|
||||
} catch (e) {
|
||||
logger.warn('[StreamsScreen] Pre-navigation orientation lock failed:', e);
|
||||
}
|
||||
// Small delay to allow orientation to settle
|
||||
await new Promise(res => setTimeout(res, Platform.OS === 'ios' ? 120 : 60));
|
||||
|
||||
// Show a quick full-screen black overlay to mask rotation flicker
|
||||
// by setting a transient state that renders a covering View (implementation already supported by dark backgrounds)
|
||||
navigation.navigate('Player', {
|
||||
uri: stream.url,
|
||||
title: metadata?.name || '',
|
||||
episodeTitle: type === 'series' ? currentEpisode?.name : undefined,
|
||||
season: type === 'series' ? currentEpisode?.season_number : undefined,
|
||||
episode: type === 'series' ? currentEpisode?.episode_number : undefined,
|
||||
quality: stream.title?.match(/(\d+)p/)?.[1] || undefined,
|
||||
quality: (stream.title?.match(/(\d+)p/) || [])[1] || undefined,
|
||||
year: metadata?.year,
|
||||
streamProvider: streamProvider,
|
||||
streamName: streamName,
|
||||
|
|
@ -863,17 +868,6 @@ export const StreamsScreen = () => {
|
|||
availableStreams: streamsToPass,
|
||||
backdrop: bannerImage || undefined,
|
||||
});
|
||||
|
||||
// Lock orientation to landscape after navigation has started
|
||||
// This allows the player to open immediately while orientation is being set
|
||||
try {
|
||||
ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE)
|
||||
.catch(error => {
|
||||
logger.error('[StreamsScreen] Error locking orientation after navigation:', error);
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('[StreamsScreen] Error locking orientation after navigation:', error);
|
||||
}
|
||||
}, [metadata, type, currentEpisode, navigation, id, selectedEpisode, imdbId, episodeStreams, groupedStreams, bannerImage]);
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue