mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
added aspect ratio indicator
This commit is contained in:
parent
b33fde8c9e
commit
154d568aa3
4 changed files with 147 additions and 39 deletions
|
|
@ -704,9 +704,21 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
}, []);
|
||||
|
||||
const cycleResizeMode = useCallback(() => {
|
||||
if (playerState.resizeMode === 'contain') playerState.setResizeMode('cover');
|
||||
else playerState.setResizeMode('contain');
|
||||
}, [playerState.resizeMode]);
|
||||
gestureControls.showResizeModeOverlayFn(() => {
|
||||
switch (playerState.resizeMode) {
|
||||
case 'contain':
|
||||
playerState.setResizeMode('cover');
|
||||
break;
|
||||
case 'cover':
|
||||
playerState.setResizeMode('stretch');
|
||||
break;
|
||||
case 'stretch':
|
||||
default:
|
||||
playerState.setResizeMode('contain');
|
||||
break;
|
||||
}
|
||||
});
|
||||
}, [playerState.resizeMode, gestureControls.showResizeModeOverlayFn]);
|
||||
|
||||
// Memoize selectedTextTrack to prevent unnecessary re-renders
|
||||
const memoizedSelectedTextTrack = useMemo(() => {
|
||||
|
|
@ -861,6 +873,8 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
volume={volume}
|
||||
brightness={brightness}
|
||||
controlsTimeout={controlsTimeout}
|
||||
resizeMode={playerState.resizeMode}
|
||||
resizeMode={playerState.resizeMode}
|
||||
/>
|
||||
|
||||
<PlayerControls
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import { View, Text, StyleSheet, Animated } from 'react-native';
|
||||
import {
|
||||
TapGestureHandler,
|
||||
PanGestureHandler,
|
||||
|
|
@ -21,6 +21,7 @@ interface GestureControlsProps {
|
|||
volume: number;
|
||||
brightness: number;
|
||||
controlsTimeout: React.MutableRefObject<NodeJS.Timeout | null>;
|
||||
resizeMode?: string;
|
||||
}
|
||||
|
||||
export const GestureControls: React.FC<GestureControlsProps> = ({
|
||||
|
|
@ -34,7 +35,8 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
|
|||
hideControls,
|
||||
volume,
|
||||
brightness,
|
||||
controlsTimeout
|
||||
controlsTimeout,
|
||||
resizeMode = 'contain'
|
||||
}) => {
|
||||
|
||||
const getVolumeIcon = (value: number) => {
|
||||
|
|
@ -151,42 +153,77 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
|
|||
{/* Volume/Brightness Pill Overlay */}
|
||||
{(gestureControls.showVolumeOverlay || gestureControls.showBrightnessOverlay) && (
|
||||
<View style={localStyles.gestureIndicatorContainer}>
|
||||
<View
|
||||
style={[
|
||||
localStyles.iconWrapper,
|
||||
{
|
||||
backgroundColor: gestureControls.showVolumeOverlay && volume === 0
|
||||
? 'rgba(242, 184, 181)'
|
||||
: 'rgba(59, 59, 59)'
|
||||
}
|
||||
]}
|
||||
>
|
||||
<MaterialIcons
|
||||
name={
|
||||
gestureControls.showVolumeOverlay
|
||||
? getVolumeIcon(volume)
|
||||
: getBrightnessIcon(brightness)
|
||||
}
|
||||
size={24}
|
||||
color={
|
||||
gestureControls.showVolumeOverlay && volume === 0
|
||||
? 'rgba(96, 20, 16)'
|
||||
: 'rgba(255, 255, 255)'
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
<View style={localStyles.gestureIndicatorPill}>
|
||||
<View
|
||||
style={[
|
||||
localStyles.iconWrapper,
|
||||
{
|
||||
backgroundColor: gestureControls.showVolumeOverlay && volume === 0
|
||||
? 'rgba(242, 184, 181)'
|
||||
: 'rgba(59, 59, 59)'
|
||||
}
|
||||
]}
|
||||
>
|
||||
<MaterialIcons
|
||||
name={
|
||||
gestureControls.showVolumeOverlay
|
||||
? getVolumeIcon(volume)
|
||||
: getBrightnessIcon(brightness)
|
||||
}
|
||||
size={24}
|
||||
color={
|
||||
gestureControls.showVolumeOverlay && volume === 0
|
||||
? 'rgba(96, 20, 16)'
|
||||
: 'rgba(255, 255, 255)'
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text
|
||||
<Text
|
||||
style={[
|
||||
localStyles.gestureText,
|
||||
gestureControls.showVolumeOverlay && volume === 0 && { color: 'rgba(242, 184, 181)' }
|
||||
]}
|
||||
>
|
||||
{gestureControls.showVolumeOverlay && volume === 0
|
||||
? "Muted"
|
||||
: `${Math.round((gestureControls.showVolumeOverlay ? volume : brightness) * 100)}%`
|
||||
}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Aspect Ratio Overlay */}
|
||||
{gestureControls.showResizeModeOverlay && (
|
||||
<View style={localStyles.gestureIndicatorContainer}>
|
||||
<Animated.View
|
||||
style={[
|
||||
localStyles.gestureText,
|
||||
gestureControls.showVolumeOverlay && volume === 0 && { color: 'rgba(242, 184, 181)' }
|
||||
localStyles.gestureIndicatorPill,
|
||||
{ opacity: gestureControls.resizeModeOverlayOpacity }
|
||||
]}
|
||||
>
|
||||
{gestureControls.showVolumeOverlay && volume === 0
|
||||
? "Muted"
|
||||
: `${Math.round((gestureControls.showVolumeOverlay ? volume : brightness) * 100)}%`
|
||||
}
|
||||
</Text>
|
||||
<View
|
||||
style={[
|
||||
localStyles.iconWrapper,
|
||||
{
|
||||
backgroundColor: 'rgba(59, 59, 59)'
|
||||
}
|
||||
]}
|
||||
>
|
||||
<MaterialIcons
|
||||
name="aspect-ratio"
|
||||
size={24}
|
||||
color="rgba(255, 255, 255)"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text
|
||||
style={localStyles.gestureText}
|
||||
>
|
||||
{resizeMode.charAt(0).toUpperCase() + resizeMode.slice(1)}
|
||||
</Text>
|
||||
</Animated.View>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import { View, Text, StyleSheet, Animated } from 'react-native';
|
||||
import {
|
||||
TapGestureHandler,
|
||||
PanGestureHandler,
|
||||
|
|
@ -21,6 +21,7 @@ interface GestureControlsProps {
|
|||
volume: number;
|
||||
brightness: number;
|
||||
controlsTimeout: React.MutableRefObject<NodeJS.Timeout | null>;
|
||||
resizeMode?: string;
|
||||
}
|
||||
|
||||
export const GestureControls: React.FC<GestureControlsProps> = ({
|
||||
|
|
@ -34,7 +35,8 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
|
|||
hideControls,
|
||||
volume,
|
||||
brightness,
|
||||
controlsTimeout
|
||||
controlsTimeout,
|
||||
resizeMode = 'contain'
|
||||
}) => {
|
||||
|
||||
const getVolumeIcon = (value: number) => {
|
||||
|
|
@ -194,6 +196,29 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
|
|||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{gestureControls.showResizeModeOverlay && (
|
||||
<View style={localStyles.gestureIndicatorContainer}>
|
||||
<Animated.View
|
||||
style={[
|
||||
localStyles.gestureIndicatorPill,
|
||||
{ opacity: gestureControls.resizeModeOverlayOpacity }
|
||||
]}
|
||||
>
|
||||
<View style={localStyles.iconWrapper}>
|
||||
<MaterialIcons
|
||||
name="aspect-ratio"
|
||||
size={18}
|
||||
color={'rgba(255, 255, 255, 0.9)'}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text style={localStyles.gestureText}>
|
||||
{resizeMode.charAt(0).toUpperCase() + resizeMode.slice(1)}
|
||||
</Text>
|
||||
</Animated.View>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,18 +19,21 @@ export const usePlayerGestureControls = (config: GestureControlConfig) => {
|
|||
// State for overlays
|
||||
const [showVolumeOverlay, setShowVolumeOverlay] = useState(false);
|
||||
const [showBrightnessOverlay, setShowBrightnessOverlay] = useState(false);
|
||||
const [showResizeModeOverlay, setShowResizeModeOverlay] = useState(false);
|
||||
|
||||
// Animated values
|
||||
const volumeGestureTranslateY = useRef(new Animated.Value(0)).current;
|
||||
const brightnessGestureTranslateY = useRef(new Animated.Value(0)).current;
|
||||
const volumeOverlayOpacity = useRef(new Animated.Value(0)).current;
|
||||
const brightnessOverlayOpacity = useRef(new Animated.Value(0)).current;
|
||||
const resizeModeOverlayOpacity = useRef(new Animated.Value(0)).current;
|
||||
|
||||
// Tracking refs
|
||||
const lastVolumeGestureY = useRef(0);
|
||||
const lastBrightnessGestureY = useRef(0);
|
||||
const volumeOverlayTimeout = useRef<NodeJS.Timeout | null>(null);
|
||||
const brightnessOverlayTimeout = useRef<NodeJS.Timeout | null>(null);
|
||||
const resizeModeOverlayTimeout = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
// Extract config with defaults and platform adjustments
|
||||
const volumeRange = config.volumeRange || { min: 0, max: 1 };
|
||||
|
|
@ -152,6 +155,30 @@ export const usePlayerGestureControls = (config: GestureControlConfig) => {
|
|||
if (brightnessOverlayTimeout.current) {
|
||||
clearTimeout(brightnessOverlayTimeout.current);
|
||||
}
|
||||
if (resizeModeOverlayTimeout.current) {
|
||||
clearTimeout(resizeModeOverlayTimeout.current);
|
||||
}
|
||||
};
|
||||
|
||||
const showResizeModeOverlayFn = (callback?: () => void) => {
|
||||
if (resizeModeOverlayTimeout.current) {
|
||||
clearTimeout(resizeModeOverlayTimeout.current);
|
||||
}
|
||||
setShowResizeModeOverlay(true);
|
||||
Animated.timing(resizeModeOverlayOpacity, {
|
||||
toValue: 1,
|
||||
duration: 100,
|
||||
useNativeDriver: true,
|
||||
}).start(() => {
|
||||
if (callback) callback();
|
||||
resizeModeOverlayTimeout.current = setTimeout(() => {
|
||||
Animated.timing(resizeModeOverlayOpacity, {
|
||||
toValue: 0,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
}).start(() => setShowResizeModeOverlay(false));
|
||||
}, overlayTimeout);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
@ -162,8 +189,13 @@ export const usePlayerGestureControls = (config: GestureControlConfig) => {
|
|||
// Overlay state
|
||||
showVolumeOverlay,
|
||||
showBrightnessOverlay,
|
||||
showResizeModeOverlay,
|
||||
volumeOverlayOpacity,
|
||||
brightnessOverlayOpacity,
|
||||
resizeModeOverlayOpacity,
|
||||
|
||||
// Overlay functions
|
||||
showResizeModeOverlayFn,
|
||||
|
||||
// Cleanup
|
||||
cleanup,
|
||||
|
|
|
|||
Loading…
Reference in a new issue