Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/media-console/src/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const AnimatedVideoPlayer = (
disableOverlay,
navigator,
rewindTime = 15,
pan: {horizontal: horizontalPan, inverted: invertedPan} = {},
pan,
testID,
} = props;

Expand Down Expand Up @@ -291,8 +291,7 @@ const AnimatedVideoPlayer = (
setSeeking,
setControlTimeout,
onEnd: events.onEnd,
horizontal: horizontalPan,
inverted: invertedPan,
pan,
});

useEffect(() => {
Expand Down
33 changes: 25 additions & 8 deletions packages/media-console/src/hooks/usePanResponders.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Dispatch, SetStateAction, useEffect} from 'react';
import {PanResponder} from 'react-native';
import {VideoPlayerProps} from '../types';

interface PanRespondersProps {
interface PanRespondersProps extends Pick<VideoPlayerProps, 'pan'> {
duration: number;
seekerOffset: number;
volumeOffset: number;
Expand All @@ -16,8 +17,6 @@ interface PanRespondersProps {
setSeeking: Dispatch<SetStateAction<boolean>>;
setControlTimeout: () => void;
onEnd: () => void;
horizontal?: boolean;
inverted?: boolean;
}

export const usePanResponders = ({
Expand All @@ -35,14 +34,31 @@ export const usePanResponders = ({
setSeeking,
setControlTimeout,
onEnd,
horizontal = true,
inverted = false,
pan: {horizontal = true, inverted = false, parentList} = {},
}: PanRespondersProps) => {
const {ref, scrollEnabled = true} = parentList || {};

const enableParentScroll = () =>
ref?.current?.setNativeProps({scrollEnabled});

const disableParentScroll = () =>
ref?.current?.setNativeProps({scrollEnabled: false});

/**
* Options to make the video player work seamlessly within FlatLists or ScrollViews.
* @link https://github.com/LunatiqueCoder/react-native-media-console/issues/104
*/
const parentScrollPanOptions = {
onPanResponderEnd: enableParentScroll,
onPanResponderTerminationRequest: () => false, // https://stackoverflow.com/a/76875305/14056591
};

const volumePanResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
clearControlTimeout();
disableParentScroll();
},
onPanResponderMove: (_evt, gestureState) => {
const diff = horizontal ? gestureState.dx : gestureState.dy;
Expand All @@ -52,6 +68,7 @@ export const usePanResponders = ({
onPanResponderRelease: () => {
setControlTimeout();
},
...parentScrollPanOptions,
});

const seekPanResponder = PanResponder.create({
Expand All @@ -62,6 +79,7 @@ export const usePanResponders = ({
clearControlTimeout();
const position = evt.nativeEvent.locationX;
setSeekerPosition(position);
disableParentScroll();
},
onPanResponderMove: (_evt, gestureState) => {
const diff = horizontal ? gestureState.dx : gestureState.dy;
Expand All @@ -74,14 +92,13 @@ export const usePanResponders = ({
const time = duration * percent;

if (time >= duration && !loading) {
if (typeof onEnd === 'function') {
onEnd();
}
onEnd?.();
}

setSeeking(false);
seek && seek(time);
},
...parentScrollPanOptions,
});

useEffect(() => {
Expand Down
29 changes: 26 additions & 3 deletions packages/media-console/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type {RefObject} from 'react';
import type {ViewStyle, StyleProp, Animated} from 'react-native';
import {
ViewStyle,
StyleProp,
Animated,
FlatList,
ScrollView,
} from 'react-native';
import type Reanimated from 'react-native-reanimated';
import type {StyleProps} from 'react-native-reanimated';
import type {VideoRef, ReactVideoProps} from 'react-native-video';
Expand Down Expand Up @@ -245,7 +251,7 @@ export interface VideoPlayerProps extends ReactVideoProps {
rewindTime?: number;

/**
* Object allowing fine grained control of the pan responder
* Object allowing fine-grained control of the pan responder
*
* @default { horizontal: true, inverted: false }
*/
Expand All @@ -256,13 +262,30 @@ export interface VideoPlayerProps extends ReactVideoProps {
* @default true
*/
horizontal?: boolean;

/**
* Boolean representing if the player controls pan gesture should be inverted
*
* @default false
*/
inverted?: boolean;
/**
* Options to make the video player work seamlessly within FlatLists or ScrollViews.
*
* @link https://github.com/LunatiqueCoder/react-native-media-console/issues/104
*/
parentList?: {
/**
* Internally, `ref?.current?.setNativeProps({scrollEnabled: boolean});` is used in order
* to make the video player work seamlessly within FlatLists or ScrollViews:
* @link https://github.com/LunatiqueCoder/react-native-media-console/issues/104
*/
ref: RefObject<FlatList | ScrollView>;
/**
* Used to keep the state consistency when using `ref?.current?.setNativeProps({scrollEnabled: boolean});`.
* @see ref
*/
scrollEnabled?: boolean;
};
};
/**
* testID selector for testing
Expand Down