mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 00:32:04 +00:00
improved touch handling player controls
This commit is contained in:
parent
a8f10fbcd8
commit
8b267fb6d7
3 changed files with 155 additions and 105 deletions
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue