improved touch handling player controls

This commit is contained in:
tapframe 2026-01-26 23:10:46 +05:30
parent a8f10fbcd8
commit 8b267fb6d7
3 changed files with 155 additions and 105 deletions

View file

@ -52,78 +52,104 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
return 'brightness-high'; return 'brightness-high';
}; };
// Create refs for all gesture handlers to enable cross-referencing
const leftPanRef = React.useRef(null);
const rightPanRef = React.useRef(null);
const leftTapRef = React.useRef(null);
const rightTapRef = React.useRef(null);
const centerTapRef = React.useRef(null);
const leftLongPressRef = React.useRef(null);
const rightLongPressRef = React.useRef(null);
// Shared style for left side gesture area
const leftSideStyle = {
position: 'absolute' as const,
top: screenDimensions.height * 0.15,
left: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
};
// Shared style for right side gesture area
const rightSideStyle = {
position: 'absolute' as const,
top: screenDimensions.height * 0.15,
right: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
};
return ( return (
<> <>
{/* Left side gesture handler - brightness + tap + long press */} {/* Left side gestures - brightness + tap + long press (flat structure) */}
<LongPressGestureHandler <LongPressGestureHandler
ref={leftLongPressRef}
onActivated={onLongPressActivated} onActivated={onLongPressActivated}
onEnded={onLongPressEnd} onEnded={onLongPressEnd}
onHandlerStateChange={onLongPressStateChange} onHandlerStateChange={onLongPressStateChange}
minDurationMs={500} minDurationMs={500}
shouldCancelWhenOutside={false} shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
> >
<PanGestureHandler <View style={leftSideStyle} />
onGestureEvent={gestureControls.onBrightnessGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-30, 30]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
>
<View style={{
position: 'absolute',
top: screenDimensions.height * 0.15,
left: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
}} />
</TapGestureHandler>
</PanGestureHandler>
</LongPressGestureHandler> </LongPressGestureHandler>
{/* Right side gesture handler - volume + tap + long press */} <PanGestureHandler
ref={leftPanRef}
onGestureEvent={gestureControls.onBrightnessGestureEvent}
activeOffsetY={[-15, 15]}
failOffsetX={[-60, 60]}
shouldCancelWhenOutside={false}
maxPointers={1}
>
<View style={leftSideStyle} />
</PanGestureHandler>
<TapGestureHandler
ref={leftTapRef}
onActivated={toggleControls}
shouldCancelWhenOutside={false}
waitFor={[leftPanRef, leftLongPressRef]}
>
<View style={leftSideStyle} />
</TapGestureHandler>
{/* Right side gestures - volume + tap + long press (flat structure) */}
<LongPressGestureHandler <LongPressGestureHandler
ref={rightLongPressRef}
onActivated={onLongPressActivated} onActivated={onLongPressActivated}
onEnded={onLongPressEnd} onEnded={onLongPressEnd}
onHandlerStateChange={onLongPressStateChange} onHandlerStateChange={onLongPressStateChange}
minDurationMs={500} minDurationMs={500}
shouldCancelWhenOutside={false} shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
> >
<PanGestureHandler <View style={rightSideStyle} />
onGestureEvent={gestureControls.onVolumeGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-30, 30]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
>
<View style={{
position: 'absolute',
top: screenDimensions.height * 0.15,
right: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
}} />
</TapGestureHandler>
</PanGestureHandler>
</LongPressGestureHandler> </LongPressGestureHandler>
<PanGestureHandler
ref={rightPanRef}
onGestureEvent={gestureControls.onVolumeGestureEvent}
activeOffsetY={[-15, 15]}
failOffsetX={[-60, 60]}
shouldCancelWhenOutside={false}
maxPointers={1}
>
<View style={rightSideStyle} />
</PanGestureHandler>
<TapGestureHandler
ref={rightTapRef}
onActivated={toggleControls}
shouldCancelWhenOutside={false}
waitFor={[rightPanRef, rightLongPressRef]}
>
<View style={rightSideStyle} />
</TapGestureHandler>
{/* Center area tap handler */} {/* Center area tap handler */}
<TapGestureHandler <TapGestureHandler
ref={centerTapRef}
onActivated={() => { onActivated={() => {
if (showControls) { if (showControls) {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
@ -138,7 +164,6 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
} }
}} }}
shouldCancelWhenOutside={false} shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
> >
<View style={{ <View style={{
position: 'absolute', position: 'absolute',
@ -146,7 +171,7 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
left: screenDimensions.width * 0.4, left: screenDimensions.width * 0.4,
width: screenDimensions.width * 0.2, width: screenDimensions.width * 0.2,
height: screenDimensions.height * 0.7, height: screenDimensions.height * 0.7,
zIndex: 5, zIndex: 10,
}} /> }} />
</TapGestureHandler> </TapGestureHandler>

View file

@ -386,7 +386,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
{/* Center Controls - CloudStream Style */} {/* Center Controls - CloudStream Style */}
<View style={[styles.controls, { <View style={[styles.controls, {
transform: [{ translateY: -(playButtonSize / 2) }] transform: [{ translateY: -(playButtonSize / 2) }]
}]}> }]} pointerEvents="box-none">
{/* Backward Seek Button (-10s) */} {/* Backward Seek Button (-10s) */}
<TouchableOpacity <TouchableOpacity

View file

@ -37,78 +37,104 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
// Helper to get dimensions (using passed screenDimensions) // Helper to get dimensions (using passed screenDimensions)
const getDimensions = () => screenDimensions; const getDimensions = () => screenDimensions;
// Create refs for all gesture handlers to enable cross-referencing
const leftPanRef = React.useRef(null);
const rightPanRef = React.useRef(null);
const leftTapRef = React.useRef(null);
const rightTapRef = React.useRef(null);
const centerTapRef = React.useRef(null);
const leftLongPressRef = React.useRef(null);
const rightLongPressRef = React.useRef(null);
// Shared style for left side gesture area
const leftSideStyle = {
position: 'absolute' as const,
top: screenDimensions.height * 0.15,
left: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
};
// Shared style for right side gesture area
const rightSideStyle = {
position: 'absolute' as const,
top: screenDimensions.height * 0.15,
right: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
};
return ( return (
<> <>
{/* Left side gesture handler - brightness + tap + long press */} {/* Left side gestures - brightness + tap + long press (flat structure) */}
<LongPressGestureHandler <LongPressGestureHandler
ref={leftLongPressRef}
onActivated={onLongPressActivated} onActivated={onLongPressActivated}
onEnded={onLongPressEnd} onEnded={onLongPressEnd}
onHandlerStateChange={onLongPressStateChange} onHandlerStateChange={onLongPressStateChange}
minDurationMs={500} minDurationMs={500}
shouldCancelWhenOutside={false} shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
> >
<PanGestureHandler <View style={leftSideStyle} />
onGestureEvent={gestureControls.onBrightnessGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-30, 30]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
>
<View style={{
position: 'absolute',
top: screenDimensions.height * 0.15,
left: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
}} />
</TapGestureHandler>
</PanGestureHandler>
</LongPressGestureHandler> </LongPressGestureHandler>
{/* Right side gesture handler - volume + tap + long press */} <PanGestureHandler
ref={leftPanRef}
onGestureEvent={gestureControls.onBrightnessGestureEvent}
activeOffsetY={[-15, 15]}
failOffsetX={[-60, 60]}
shouldCancelWhenOutside={false}
maxPointers={1}
>
<View style={leftSideStyle} />
</PanGestureHandler>
<TapGestureHandler
ref={leftTapRef}
onActivated={toggleControls}
shouldCancelWhenOutside={false}
waitFor={[leftPanRef, leftLongPressRef]}
>
<View style={leftSideStyle} />
</TapGestureHandler>
{/* Right side gestures - volume + tap + long press (flat structure) */}
<LongPressGestureHandler <LongPressGestureHandler
ref={rightLongPressRef}
onActivated={onLongPressActivated} onActivated={onLongPressActivated}
onEnded={onLongPressEnd} onEnded={onLongPressEnd}
onHandlerStateChange={onLongPressStateChange} onHandlerStateChange={onLongPressStateChange}
minDurationMs={500} minDurationMs={500}
shouldCancelWhenOutside={false} shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
> >
<PanGestureHandler <View style={rightSideStyle} />
onGestureEvent={gestureControls.onVolumeGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-30, 30]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
>
<View style={{
position: 'absolute',
top: screenDimensions.height * 0.15,
right: 0,
width: screenDimensions.width * 0.4,
height: screenDimensions.height * 0.7,
zIndex: 10,
}} />
</TapGestureHandler>
</PanGestureHandler>
</LongPressGestureHandler> </LongPressGestureHandler>
<PanGestureHandler
ref={rightPanRef}
onGestureEvent={gestureControls.onVolumeGestureEvent}
activeOffsetY={[-15, 15]}
failOffsetX={[-60, 60]}
shouldCancelWhenOutside={false}
maxPointers={1}
>
<View style={rightSideStyle} />
</PanGestureHandler>
<TapGestureHandler
ref={rightTapRef}
onActivated={toggleControls}
shouldCancelWhenOutside={false}
waitFor={[rightPanRef, rightLongPressRef]}
>
<View style={rightSideStyle} />
</TapGestureHandler>
{/* Center area tap handler */} {/* Center area tap handler */}
<TapGestureHandler <TapGestureHandler
ref={centerTapRef}
onActivated={() => { onActivated={() => {
if (showControls) { if (showControls) {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
@ -123,7 +149,6 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
} }
}} }}
shouldCancelWhenOutside={false} shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
> >
<View style={{ <View style={{
position: 'absolute', position: 'absolute',
@ -131,7 +156,7 @@ export const GestureControls: React.FC<GestureControlsProps> = ({
left: screenDimensions.width * 0.4, left: screenDimensions.width * 0.4,
width: screenDimensions.width * 0.2, width: screenDimensions.width * 0.2,
height: screenDimensions.height * 0.7, height: screenDimensions.height * 0.7,
zIndex: 5, zIndex: 10,
}} /> }} />
</TapGestureHandler> </TapGestureHandler>