mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-27 03:22:53 +00:00
test
This commit is contained in:
parent
1cb4b5f2ec
commit
6a0295b94e
2 changed files with 288 additions and 128 deletions
|
|
@ -374,14 +374,14 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
const onVolumeGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
const onVolumeGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
||||||
const { translationY, state } = event.nativeEvent;
|
const { translationY, state } = event.nativeEvent;
|
||||||
const screenHeight = screenDimensions.height;
|
const screenHeight = screenDimensions.height;
|
||||||
const sensitivity = 0.003; // Adjust sensitivity
|
const sensitivity = 0.002; // Reduced for finer control
|
||||||
|
|
||||||
if (state === State.ACTIVE) {
|
if (state === State.ACTIVE) {
|
||||||
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
||||||
const volumeChange = deltaY * sensitivity;
|
const volumeChange = deltaY * sensitivity;
|
||||||
const newVolume = Math.max(0, Math.min(1, volume + volumeChange));
|
const newVolume = Math.max(0, Math.min(1, volume + volumeChange));
|
||||||
|
|
||||||
if (Math.abs(newVolume - volume) > 0.01) { // Only update if significant change
|
if (Math.abs(newVolume - volume) > 0.005) { // Reduced threshold for smoother updates
|
||||||
setVolume(newVolume);
|
setVolume(newVolume);
|
||||||
lastVolumeChange.current = Date.now();
|
lastVolumeChange.current = Date.now();
|
||||||
|
|
||||||
|
|
@ -389,12 +389,13 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
logger.log(`[AndroidVideoPlayer] Volume set to: ${newVolume}`);
|
logger.log(`[AndroidVideoPlayer] Volume set to: ${newVolume}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show overlay
|
// Show overlay with smoother animation
|
||||||
if (!showVolumeOverlay) {
|
if (!showVolumeOverlay) {
|
||||||
setShowVolumeOverlay(true);
|
setShowVolumeOverlay(true);
|
||||||
Animated.timing(volumeOverlayOpacity, {
|
Animated.spring(volumeOverlayOpacity, {
|
||||||
toValue: 1,
|
toValue: 1,
|
||||||
duration: 200,
|
tension: 100,
|
||||||
|
friction: 8,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
@ -404,16 +405,16 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
clearTimeout(volumeOverlayTimeout.current);
|
clearTimeout(volumeOverlayTimeout.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide overlay after 2 seconds
|
// Hide overlay after 1.5 seconds (reduced from 2 seconds)
|
||||||
volumeOverlayTimeout.current = setTimeout(() => {
|
volumeOverlayTimeout.current = setTimeout(() => {
|
||||||
Animated.timing(volumeOverlayOpacity, {
|
Animated.timing(volumeOverlayOpacity, {
|
||||||
toValue: 0,
|
toValue: 0,
|
||||||
duration: 300,
|
duration: 250,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start(() => {
|
}).start(() => {
|
||||||
setShowVolumeOverlay(false);
|
setShowVolumeOverlay(false);
|
||||||
});
|
});
|
||||||
}, 2000);
|
}, 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -422,14 +423,14 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
const onBrightnessGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
const onBrightnessGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
||||||
const { translationY, state } = event.nativeEvent;
|
const { translationY, state } = event.nativeEvent;
|
||||||
const screenHeight = screenDimensions.height;
|
const screenHeight = screenDimensions.height;
|
||||||
const sensitivity = 0.003; // Adjust sensitivity
|
const sensitivity = 0.002; // Reduced for finer control
|
||||||
|
|
||||||
if (state === State.ACTIVE) {
|
if (state === State.ACTIVE) {
|
||||||
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
||||||
const brightnessChange = deltaY * sensitivity;
|
const brightnessChange = deltaY * sensitivity;
|
||||||
const newBrightness = Math.max(0, Math.min(1, brightness + brightnessChange));
|
const newBrightness = Math.max(0, Math.min(1, brightness + brightnessChange));
|
||||||
|
|
||||||
if (Math.abs(newBrightness - brightness) > 0.01) { // Only update if significant change
|
if (Math.abs(newBrightness - brightness) > 0.005) { // Reduced threshold for smoother updates
|
||||||
setBrightness(newBrightness);
|
setBrightness(newBrightness);
|
||||||
lastBrightnessChange.current = Date.now();
|
lastBrightnessChange.current = Date.now();
|
||||||
|
|
||||||
|
|
@ -443,12 +444,13 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
logger.warn('[AndroidVideoPlayer] Error setting device brightness:', error);
|
logger.warn('[AndroidVideoPlayer] Error setting device brightness:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show overlay
|
// Show overlay with smoother animation
|
||||||
if (!showBrightnessOverlay) {
|
if (!showBrightnessOverlay) {
|
||||||
setShowBrightnessOverlay(true);
|
setShowBrightnessOverlay(true);
|
||||||
Animated.timing(brightnessOverlayOpacity, {
|
Animated.spring(brightnessOverlayOpacity, {
|
||||||
toValue: 1,
|
toValue: 1,
|
||||||
duration: 200,
|
tension: 100,
|
||||||
|
friction: 8,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
@ -458,16 +460,16 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
clearTimeout(brightnessOverlayTimeout.current);
|
clearTimeout(brightnessOverlayTimeout.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide overlay after 2 seconds
|
// Hide overlay after 1.5 seconds (reduced from 2 seconds)
|
||||||
brightnessOverlayTimeout.current = setTimeout(() => {
|
brightnessOverlayTimeout.current = setTimeout(() => {
|
||||||
Animated.timing(brightnessOverlayOpacity, {
|
Animated.timing(brightnessOverlayOpacity, {
|
||||||
toValue: 0,
|
toValue: 0,
|
||||||
duration: 300,
|
duration: 250,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start(() => {
|
}).start(() => {
|
||||||
setShowBrightnessOverlay(false);
|
setShowBrightnessOverlay(false);
|
||||||
});
|
});
|
||||||
}, 2000);
|
}, 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2284,15 +2286,16 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
onGestureEvent={onBrightnessGestureEvent}
|
onGestureEvent={onBrightnessGestureEvent}
|
||||||
activeOffsetY={[-10, 10]}
|
activeOffsetY={[-10, 10]}
|
||||||
failOffsetX={[-50, 50]}
|
failOffsetX={[-50, 50]}
|
||||||
shouldCancelWhenOutside={false}
|
shouldCancelWhenOutside={true}
|
||||||
|
simultaneousHandlers={[]}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: screenDimensions.height * 0.15, // Minimal top margin
|
||||||
left: 0,
|
left: 0,
|
||||||
width: screenDimensions.width * 0.3, // Left 30% of screen
|
width: screenDimensions.width * 0.4, // Much wider area (40% of screen)
|
||||||
height: screenDimensions.height,
|
height: screenDimensions.height * 0.7, // Larger middle portion (70% of screen)
|
||||||
zIndex: 10,
|
zIndex: 5, // Lower z-index than controls
|
||||||
}} />
|
}} />
|
||||||
</PanGestureHandler>
|
</PanGestureHandler>
|
||||||
|
|
||||||
|
|
@ -2301,15 +2304,16 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
onGestureEvent={onVolumeGestureEvent}
|
onGestureEvent={onVolumeGestureEvent}
|
||||||
activeOffsetY={[-10, 10]}
|
activeOffsetY={[-10, 10]}
|
||||||
failOffsetX={[-50, 50]}
|
failOffsetX={[-50, 50]}
|
||||||
shouldCancelWhenOutside={false}
|
shouldCancelWhenOutside={true}
|
||||||
|
simultaneousHandlers={[]}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: screenDimensions.height * 0.15, // Minimal top margin
|
||||||
right: 0,
|
right: 0,
|
||||||
width: screenDimensions.width * 0.3, // Right 30% of screen
|
width: screenDimensions.width * 0.4, // Much wider area (40% of screen)
|
||||||
height: screenDimensions.height,
|
height: screenDimensions.height * 0.7, // Larger middle portion (70% of screen)
|
||||||
zIndex: 10,
|
zIndex: 5, // Lower z-index than controls
|
||||||
}} />
|
}} />
|
||||||
</PanGestureHandler>
|
</PanGestureHandler>
|
||||||
|
|
||||||
|
|
@ -2813,53 +2817,91 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: 20 + insets.right,
|
left: screenDimensions.width / 2 - 60,
|
||||||
top: '50%',
|
top: screenDimensions.height / 2 - 60,
|
||||||
transform: [{ translateY: -50 }],
|
|
||||||
opacity: volumeOverlayOpacity,
|
opacity: volumeOverlayOpacity,
|
||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
backgroundColor: 'rgba(0, 0, 0, 0.9)',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
padding: 16,
|
padding: 16,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
minWidth: 80,
|
width: 120,
|
||||||
|
height: 120,
|
||||||
|
justifyContent: 'center',
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOffset: { width: 0, height: 4 },
|
shadowOffset: { width: 0, height: 4 },
|
||||||
shadowOpacity: 0.3,
|
shadowOpacity: 0.5,
|
||||||
shadowRadius: 8,
|
shadowRadius: 8,
|
||||||
elevation: 8,
|
elevation: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||||
}}>
|
}}>
|
||||||
<MaterialIcons
|
<MaterialIcons
|
||||||
name={volume === 0 ? "volume-off" : volume < 0.5 ? "volume-down" : "volume-up"}
|
name={volume === 0 ? "volume-off" : volume < 0.3 ? "volume-mute" : volume < 0.7 ? "volume-down" : "volume-up"}
|
||||||
size={24}
|
size={24}
|
||||||
color="#FFFFFF"
|
color={volume === 0 ? "#FF6B6B" : "#FFFFFF"}
|
||||||
style={{ marginBottom: 8 }}
|
style={{ marginBottom: 8 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Horizontal Dotted Progress Bar */}
|
||||||
<View style={{
|
<View style={{
|
||||||
width: 4,
|
width: 80,
|
||||||
height: 60,
|
height: 6,
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
||||||
borderRadius: 2,
|
borderRadius: 3,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
marginBottom: 8,
|
||||||
}}>
|
}}>
|
||||||
|
{/* Dotted background */}
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
width: 4,
|
right: 0,
|
||||||
height: `${volume * 100}%`,
|
bottom: 0,
|
||||||
backgroundColor: '#E50914',
|
flexDirection: 'row',
|
||||||
borderRadius: 2,
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: 1,
|
||||||
|
}}>
|
||||||
|
{Array.from({ length: 16 }, (_, i) => (
|
||||||
|
<View
|
||||||
|
key={i}
|
||||||
|
style={{
|
||||||
|
width: 1.5,
|
||||||
|
height: 1.5,
|
||||||
|
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
||||||
|
borderRadius: 0.75,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Progress fill */}
|
||||||
|
<View style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: `${volume * 100}%`,
|
||||||
|
height: 6,
|
||||||
|
backgroundColor: volume === 0 ? '#FF6B6B' : '#E50914',
|
||||||
|
borderRadius: 3,
|
||||||
|
shadowColor: volume === 0 ? '#FF6B6B' : '#E50914',
|
||||||
|
shadowOffset: { width: 0, height: 1 },
|
||||||
|
shadowOpacity: 0.6,
|
||||||
|
shadowRadius: 2,
|
||||||
}} />
|
}} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Text style={{
|
<Text style={{
|
||||||
color: '#FFFFFF',
|
color: '#FFFFFF',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
marginTop: 8,
|
letterSpacing: 0.5,
|
||||||
}}>
|
}}>
|
||||||
{Math.round(volume * 100)}%
|
{Math.round(volume * 100)}%
|
||||||
</Text>
|
</Text>
|
||||||
|
|
@ -2872,53 +2914,91 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 20 + insets.left,
|
left: screenDimensions.width / 2 - 60,
|
||||||
top: '50%',
|
top: screenDimensions.height / 2 - 60,
|
||||||
transform: [{ translateY: -50 }],
|
|
||||||
opacity: brightnessOverlayOpacity,
|
opacity: brightnessOverlayOpacity,
|
||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
backgroundColor: 'rgba(0, 0, 0, 0.9)',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
padding: 16,
|
padding: 16,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
minWidth: 80,
|
width: 120,
|
||||||
|
height: 120,
|
||||||
|
justifyContent: 'center',
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOffset: { width: 0, height: 4 },
|
shadowOffset: { width: 0, height: 4 },
|
||||||
shadowOpacity: 0.3,
|
shadowOpacity: 0.5,
|
||||||
shadowRadius: 8,
|
shadowRadius: 8,
|
||||||
elevation: 8,
|
elevation: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||||
}}>
|
}}>
|
||||||
<MaterialIcons
|
<MaterialIcons
|
||||||
name={brightness < 0.3 ? "brightness-low" : brightness < 0.7 ? "brightness-medium" : "brightness-high"}
|
name={brightness < 0.2 ? "brightness-low" : brightness < 0.5 ? "brightness-medium" : brightness < 0.8 ? "brightness-high" : "brightness-auto"}
|
||||||
size={24}
|
size={24}
|
||||||
color="#FFFFFF"
|
color={brightness < 0.2 ? "#FFD700" : "#FFFFFF"}
|
||||||
style={{ marginBottom: 8 }}
|
style={{ marginBottom: 8 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Horizontal Dotted Progress Bar */}
|
||||||
<View style={{
|
<View style={{
|
||||||
width: 4,
|
width: 80,
|
||||||
height: 60,
|
height: 6,
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
||||||
borderRadius: 2,
|
borderRadius: 3,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
marginBottom: 8,
|
||||||
}}>
|
}}>
|
||||||
|
{/* Dotted background */}
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
width: 4,
|
right: 0,
|
||||||
height: `${brightness * 100}%`,
|
bottom: 0,
|
||||||
backgroundColor: '#FFD700',
|
flexDirection: 'row',
|
||||||
borderRadius: 2,
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: 1,
|
||||||
|
}}>
|
||||||
|
{Array.from({ length: 16 }, (_, i) => (
|
||||||
|
<View
|
||||||
|
key={i}
|
||||||
|
style={{
|
||||||
|
width: 1.5,
|
||||||
|
height: 1.5,
|
||||||
|
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
||||||
|
borderRadius: 0.75,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Progress fill */}
|
||||||
|
<View style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: `${brightness * 100}%`,
|
||||||
|
height: 6,
|
||||||
|
backgroundColor: brightness < 0.2 ? '#FFD700' : '#FFA500',
|
||||||
|
borderRadius: 3,
|
||||||
|
shadowColor: brightness < 0.2 ? '#FFD700' : '#FFA500',
|
||||||
|
shadowOffset: { width: 0, height: 1 },
|
||||||
|
shadowOpacity: 0.6,
|
||||||
|
shadowRadius: 2,
|
||||||
}} />
|
}} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Text style={{
|
<Text style={{
|
||||||
color: '#FFFFFF',
|
color: '#FFFFFF',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
marginTop: 8,
|
letterSpacing: 0.5,
|
||||||
}}>
|
}}>
|
||||||
{Math.round(brightness * 100)}%
|
{Math.round(brightness * 100)}%
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
|
|
@ -380,14 +380,14 @@ const VideoPlayer: React.FC = () => {
|
||||||
const onVolumeGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
const onVolumeGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
||||||
const { translationY, state } = event.nativeEvent;
|
const { translationY, state } = event.nativeEvent;
|
||||||
const screenHeight = screenDimensions.height;
|
const screenHeight = screenDimensions.height;
|
||||||
const sensitivity = 0.3; // Adjust sensitivity for VLC (0-100 range)
|
const sensitivity = 0.2; // Reduced for finer control (VLC 0-100 range)
|
||||||
|
|
||||||
if (state === State.ACTIVE) {
|
if (state === State.ACTIVE) {
|
||||||
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
||||||
const volumeChange = deltaY * sensitivity;
|
const volumeChange = deltaY * sensitivity;
|
||||||
const newVolume = Math.max(0, Math.min(100, volume + volumeChange));
|
const newVolume = Math.max(0, Math.min(100, volume + volumeChange));
|
||||||
|
|
||||||
if (Math.abs(newVolume - volume) > 1) { // Only update if significant change
|
if (Math.abs(newVolume - volume) > 0.5) { // Reduced threshold for smoother updates
|
||||||
setVolume(newVolume);
|
setVolume(newVolume);
|
||||||
lastVolumeChange.current = Date.now();
|
lastVolumeChange.current = Date.now();
|
||||||
|
|
||||||
|
|
@ -404,12 +404,13 @@ const VideoPlayer: React.FC = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show overlay
|
// Show overlay with smoother animation
|
||||||
if (!showVolumeOverlay) {
|
if (!showVolumeOverlay) {
|
||||||
setShowVolumeOverlay(true);
|
setShowVolumeOverlay(true);
|
||||||
Animated.timing(volumeOverlayOpacity, {
|
Animated.spring(volumeOverlayOpacity, {
|
||||||
toValue: 1,
|
toValue: 1,
|
||||||
duration: 200,
|
tension: 100,
|
||||||
|
friction: 8,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
@ -419,16 +420,16 @@ const VideoPlayer: React.FC = () => {
|
||||||
clearTimeout(volumeOverlayTimeout.current);
|
clearTimeout(volumeOverlayTimeout.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide overlay after 2 seconds
|
// Hide overlay after 1.5 seconds (reduced from 2 seconds)
|
||||||
volumeOverlayTimeout.current = setTimeout(() => {
|
volumeOverlayTimeout.current = setTimeout(() => {
|
||||||
Animated.timing(volumeOverlayOpacity, {
|
Animated.timing(volumeOverlayOpacity, {
|
||||||
toValue: 0,
|
toValue: 0,
|
||||||
duration: 300,
|
duration: 250,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start(() => {
|
}).start(() => {
|
||||||
setShowVolumeOverlay(false);
|
setShowVolumeOverlay(false);
|
||||||
});
|
});
|
||||||
}, 2000);
|
}, 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -437,14 +438,14 @@ const VideoPlayer: React.FC = () => {
|
||||||
const onBrightnessGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
const onBrightnessGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
|
||||||
const { translationY, state } = event.nativeEvent;
|
const { translationY, state } = event.nativeEvent;
|
||||||
const screenHeight = screenDimensions.height;
|
const screenHeight = screenDimensions.height;
|
||||||
const sensitivity = 0.003; // Adjust sensitivity
|
const sensitivity = 0.002; // Reduced for finer control
|
||||||
|
|
||||||
if (state === State.ACTIVE) {
|
if (state === State.ACTIVE) {
|
||||||
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
const deltaY = -translationY; // Invert for natural feel (up = increase)
|
||||||
const brightnessChange = deltaY * sensitivity;
|
const brightnessChange = deltaY * sensitivity;
|
||||||
const newBrightness = Math.max(0, Math.min(1, brightness + brightnessChange));
|
const newBrightness = Math.max(0, Math.min(1, brightness + brightnessChange));
|
||||||
|
|
||||||
if (Math.abs(newBrightness - brightness) > 0.01) { // Only update if significant change
|
if (Math.abs(newBrightness - brightness) > 0.005) { // Reduced threshold for smoother updates
|
||||||
setBrightness(newBrightness);
|
setBrightness(newBrightness);
|
||||||
lastBrightnessChange.current = Date.now();
|
lastBrightnessChange.current = Date.now();
|
||||||
|
|
||||||
|
|
@ -458,12 +459,13 @@ const VideoPlayer: React.FC = () => {
|
||||||
logger.warn('[VideoPlayer] Error setting device brightness:', error);
|
logger.warn('[VideoPlayer] Error setting device brightness:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show overlay
|
// Show overlay with smoother animation
|
||||||
if (!showBrightnessOverlay) {
|
if (!showBrightnessOverlay) {
|
||||||
setShowBrightnessOverlay(true);
|
setShowBrightnessOverlay(true);
|
||||||
Animated.timing(brightnessOverlayOpacity, {
|
Animated.spring(brightnessOverlayOpacity, {
|
||||||
toValue: 1,
|
toValue: 1,
|
||||||
duration: 200,
|
tension: 100,
|
||||||
|
friction: 8,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
@ -473,16 +475,16 @@ const VideoPlayer: React.FC = () => {
|
||||||
clearTimeout(brightnessOverlayTimeout.current);
|
clearTimeout(brightnessOverlayTimeout.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide overlay after 2 seconds
|
// Hide overlay after 1.5 seconds (reduced from 2 seconds)
|
||||||
brightnessOverlayTimeout.current = setTimeout(() => {
|
brightnessOverlayTimeout.current = setTimeout(() => {
|
||||||
Animated.timing(brightnessOverlayOpacity, {
|
Animated.timing(brightnessOverlayOpacity, {
|
||||||
toValue: 0,
|
toValue: 0,
|
||||||
duration: 300,
|
duration: 250,
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}).start(() => {
|
}).start(() => {
|
||||||
setShowBrightnessOverlay(false);
|
setShowBrightnessOverlay(false);
|
||||||
});
|
});
|
||||||
}, 2000);
|
}, 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2096,15 +2098,16 @@ const VideoPlayer: React.FC = () => {
|
||||||
onGestureEvent={onBrightnessGestureEvent}
|
onGestureEvent={onBrightnessGestureEvent}
|
||||||
activeOffsetY={[-10, 10]}
|
activeOffsetY={[-10, 10]}
|
||||||
failOffsetX={[-50, 50]}
|
failOffsetX={[-50, 50]}
|
||||||
shouldCancelWhenOutside={false}
|
shouldCancelWhenOutside={true}
|
||||||
|
simultaneousHandlers={[]}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: screenDimensions.height * 0.15, // Minimal top margin
|
||||||
left: 0,
|
left: 0,
|
||||||
width: screenDimensions.width * 0.3, // Left 30% of screen
|
width: screenDimensions.width * 0.4, // Much wider area (40% of screen)
|
||||||
height: screenDimensions.height,
|
height: screenDimensions.height * 0.7, // Larger middle portion (70% of screen)
|
||||||
zIndex: 10,
|
zIndex: 5, // Lower z-index than controls
|
||||||
}} />
|
}} />
|
||||||
</PanGestureHandler>
|
</PanGestureHandler>
|
||||||
|
|
||||||
|
|
@ -2113,15 +2116,16 @@ const VideoPlayer: React.FC = () => {
|
||||||
onGestureEvent={onVolumeGestureEvent}
|
onGestureEvent={onVolumeGestureEvent}
|
||||||
activeOffsetY={[-10, 10]}
|
activeOffsetY={[-10, 10]}
|
||||||
failOffsetX={[-50, 50]}
|
failOffsetX={[-50, 50]}
|
||||||
shouldCancelWhenOutside={false}
|
shouldCancelWhenOutside={true}
|
||||||
|
simultaneousHandlers={[]}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: screenDimensions.height * 0.15, // Minimal top margin
|
||||||
right: 0,
|
right: 0,
|
||||||
width: screenDimensions.width * 0.3, // Right 30% of screen
|
width: screenDimensions.width * 0.4, // Much wider area (40% of screen)
|
||||||
height: screenDimensions.height,
|
height: screenDimensions.height * 0.7, // Larger middle portion (70% of screen)
|
||||||
zIndex: 10,
|
zIndex: 5, // Lower z-index than controls
|
||||||
}} />
|
}} />
|
||||||
</PanGestureHandler>
|
</PanGestureHandler>
|
||||||
|
|
||||||
|
|
@ -2586,53 +2590,91 @@ const VideoPlayer: React.FC = () => {
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: 20 + insets.right,
|
left: screenDimensions.width / 2 - 60,
|
||||||
top: '50%',
|
top: screenDimensions.height / 2 - 60,
|
||||||
transform: [{ translateY: -50 }],
|
|
||||||
opacity: volumeOverlayOpacity,
|
opacity: volumeOverlayOpacity,
|
||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
backgroundColor: 'rgba(0, 0, 0, 0.9)',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
padding: 16,
|
padding: 16,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
minWidth: 80,
|
width: 120,
|
||||||
|
height: 120,
|
||||||
|
justifyContent: 'center',
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOffset: { width: 0, height: 4 },
|
shadowOffset: { width: 0, height: 4 },
|
||||||
shadowOpacity: 0.3,
|
shadowOpacity: 0.5,
|
||||||
shadowRadius: 8,
|
shadowRadius: 8,
|
||||||
elevation: 8,
|
elevation: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||||
}}>
|
}}>
|
||||||
<MaterialIcons
|
<MaterialIcons
|
||||||
name={volume === 0 ? "volume-off" : volume < 50 ? "volume-down" : "volume-up"}
|
name={volume === 0 ? "volume-off" : volume < 30 ? "volume-mute" : volume < 70 ? "volume-down" : "volume-up"}
|
||||||
size={24}
|
size={24}
|
||||||
color="#FFFFFF"
|
color={volume === 0 ? "#FF6B6B" : "#FFFFFF"}
|
||||||
style={{ marginBottom: 8 }}
|
style={{ marginBottom: 8 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Horizontal Dotted Progress Bar */}
|
||||||
<View style={{
|
<View style={{
|
||||||
width: 4,
|
width: 80,
|
||||||
height: 60,
|
height: 6,
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
||||||
borderRadius: 2,
|
borderRadius: 3,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
marginBottom: 8,
|
||||||
}}>
|
}}>
|
||||||
|
{/* Dotted background */}
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
width: 4,
|
right: 0,
|
||||||
height: `${volume}%`,
|
bottom: 0,
|
||||||
backgroundColor: '#E50914',
|
flexDirection: 'row',
|
||||||
borderRadius: 2,
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: 1,
|
||||||
|
}}>
|
||||||
|
{Array.from({ length: 16 }, (_, i) => (
|
||||||
|
<View
|
||||||
|
key={i}
|
||||||
|
style={{
|
||||||
|
width: 1.5,
|
||||||
|
height: 1.5,
|
||||||
|
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
||||||
|
borderRadius: 0.75,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Progress fill */}
|
||||||
|
<View style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: `${volume}%`,
|
||||||
|
height: 6,
|
||||||
|
backgroundColor: volume === 0 ? '#FF6B6B' : '#E50914',
|
||||||
|
borderRadius: 3,
|
||||||
|
shadowColor: volume === 0 ? '#FF6B6B' : '#E50914',
|
||||||
|
shadowOffset: { width: 0, height: 1 },
|
||||||
|
shadowOpacity: 0.6,
|
||||||
|
shadowRadius: 2,
|
||||||
}} />
|
}} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Text style={{
|
<Text style={{
|
||||||
color: '#FFFFFF',
|
color: '#FFFFFF',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
marginTop: 8,
|
letterSpacing: 0.5,
|
||||||
}}>
|
}}>
|
||||||
{volume}%
|
{volume}%
|
||||||
</Text>
|
</Text>
|
||||||
|
|
@ -2645,53 +2687,91 @@ const VideoPlayer: React.FC = () => {
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 20 + insets.left,
|
left: screenDimensions.width / 2 - 60,
|
||||||
top: '50%',
|
top: screenDimensions.height / 2 - 60,
|
||||||
transform: [{ translateY: -50 }],
|
|
||||||
opacity: brightnessOverlayOpacity,
|
opacity: brightnessOverlayOpacity,
|
||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View style={{
|
<View style={{
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
backgroundColor: 'rgba(0, 0, 0, 0.9)',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
padding: 16,
|
padding: 16,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
minWidth: 80,
|
width: 120,
|
||||||
|
height: 120,
|
||||||
|
justifyContent: 'center',
|
||||||
shadowColor: '#000',
|
shadowColor: '#000',
|
||||||
shadowOffset: { width: 0, height: 4 },
|
shadowOffset: { width: 0, height: 4 },
|
||||||
shadowOpacity: 0.3,
|
shadowOpacity: 0.5,
|
||||||
shadowRadius: 8,
|
shadowRadius: 8,
|
||||||
elevation: 8,
|
elevation: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||||
}}>
|
}}>
|
||||||
<MaterialIcons
|
<MaterialIcons
|
||||||
name={brightness < 0.3 ? "brightness-low" : brightness < 0.7 ? "brightness-medium" : "brightness-high"}
|
name={brightness < 0.2 ? "brightness-low" : brightness < 0.5 ? "brightness-medium" : brightness < 0.8 ? "brightness-high" : "brightness-auto"}
|
||||||
size={24}
|
size={24}
|
||||||
color="#FFFFFF"
|
color={brightness < 0.2 ? "#FFD700" : "#FFFFFF"}
|
||||||
style={{ marginBottom: 8 }}
|
style={{ marginBottom: 8 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Horizontal Dotted Progress Bar */}
|
||||||
<View style={{
|
<View style={{
|
||||||
width: 4,
|
width: 80,
|
||||||
height: 60,
|
height: 6,
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
||||||
borderRadius: 2,
|
borderRadius: 3,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
marginBottom: 8,
|
||||||
}}>
|
}}>
|
||||||
|
{/* Dotted background */}
|
||||||
<View style={{
|
<View style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
width: 4,
|
right: 0,
|
||||||
height: `${brightness * 100}%`,
|
bottom: 0,
|
||||||
backgroundColor: '#FFD700',
|
flexDirection: 'row',
|
||||||
borderRadius: 2,
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: 1,
|
||||||
|
}}>
|
||||||
|
{Array.from({ length: 16 }, (_, i) => (
|
||||||
|
<View
|
||||||
|
key={i}
|
||||||
|
style={{
|
||||||
|
width: 1.5,
|
||||||
|
height: 1.5,
|
||||||
|
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
||||||
|
borderRadius: 0.75,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Progress fill */}
|
||||||
|
<View style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: `${brightness * 100}%`,
|
||||||
|
height: 6,
|
||||||
|
backgroundColor: brightness < 0.2 ? '#FFD700' : '#FFA500',
|
||||||
|
borderRadius: 3,
|
||||||
|
shadowColor: brightness < 0.2 ? '#FFD700' : '#FFA500',
|
||||||
|
shadowOffset: { width: 0, height: 1 },
|
||||||
|
shadowOpacity: 0.6,
|
||||||
|
shadowRadius: 2,
|
||||||
}} />
|
}} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Text style={{
|
<Text style={{
|
||||||
color: '#FFFFFF',
|
color: '#FFFFFF',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
marginTop: 8,
|
letterSpacing: 0.5,
|
||||||
}}>
|
}}>
|
||||||
{Math.round(brightness * 100)}%
|
{Math.round(brightness * 100)}%
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue