From 8d5a744bb3075f140b731ec77e22e39bb3482fcc Mon Sep 17 00:00:00 2001 From: Ovidiu Cristescu <55203625+LunatiqueCoder@users.noreply.github.com> Date: Sun, 11 Aug 2024 00:14:52 +0300 Subject: [PATCH 1/3] 1104-flatlist-gesture-handling-enhancement --- packages/media-console/src/VideoPlayer.tsx | 5 ++-- .../src/hooks/usePanResponders.tsx | 23 ++++++++++----- packages/media-console/src/types.ts | 29 +++++++++++++++++-- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/packages/media-console/src/VideoPlayer.tsx b/packages/media-console/src/VideoPlayer.tsx index 9ee82de..14575c5 100644 --- a/packages/media-console/src/VideoPlayer.tsx +++ b/packages/media-console/src/VideoPlayer.tsx @@ -74,7 +74,7 @@ const AnimatedVideoPlayer = ( disableOverlay, navigator, rewindTime = 15, - pan: {horizontal: horizontalPan, inverted: invertedPan} = {}, + pan, testID, } = props; @@ -291,8 +291,7 @@ const AnimatedVideoPlayer = ( setSeeking, setControlTimeout, onEnd: events.onEnd, - horizontal: horizontalPan, - inverted: invertedPan, + pan, }); useEffect(() => { diff --git a/packages/media-console/src/hooks/usePanResponders.tsx b/packages/media-console/src/hooks/usePanResponders.tsx index e9618d3..8c3ad93 100644 --- a/packages/media-console/src/hooks/usePanResponders.tsx +++ b/packages/media-console/src/hooks/usePanResponders.tsx @@ -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 { duration: number; seekerOffset: number; volumeOffset: number; @@ -16,8 +17,6 @@ interface PanRespondersProps { setSeeking: Dispatch>; setControlTimeout: () => void; onEnd: () => void; - horizontal?: boolean; - inverted?: boolean; } export const usePanResponders = ({ @@ -35,14 +34,19 @@ export const usePanResponders = ({ setSeeking, setControlTimeout, onEnd, - horizontal = true, - inverted = false, + pan: {horizontal = true, inverted = false, parentList} = {}, }: PanRespondersProps) => { + const enableParentScroll = () => + parentList?.ref?.current?.setNativeProps({ + scrollEnabled: parentList?.scrollEnabled, + }); + const volumePanResponder = PanResponder.create({ onStartShouldSetPanResponder: () => true, onMoveShouldSetPanResponder: () => true, onPanResponderGrant: () => { clearControlTimeout(); + parentList?.ref?.current?.setNativeProps({scrollEnabled: false}); }, onPanResponderMove: (_evt, gestureState) => { const diff = horizontal ? gestureState.dx : gestureState.dy; @@ -52,6 +56,8 @@ export const usePanResponders = ({ onPanResponderRelease: () => { setControlTimeout(); }, + onPanResponderEnd: enableParentScroll, + onPanResponderTerminationRequest: () => false, // https://stackoverflow.com/a/76875305/14056591 }); const seekPanResponder = PanResponder.create({ @@ -62,6 +68,7 @@ export const usePanResponders = ({ clearControlTimeout(); const position = evt.nativeEvent.locationX; setSeekerPosition(position); + parentList?.ref?.current?.setNativeProps({scrollEnabled: false}); }, onPanResponderMove: (_evt, gestureState) => { const diff = horizontal ? gestureState.dx : gestureState.dy; @@ -74,14 +81,14 @@ export const usePanResponders = ({ const time = duration * percent; if (time >= duration && !loading) { - if (typeof onEnd === 'function') { - onEnd(); - } + onEnd?.(); } setSeeking(false); seek && seek(time); }, + onPanResponderEnd: enableParentScroll, + onPanResponderTerminationRequest: () => false, // https://stackoverflow.com/a/76875305/14056591 }); useEffect(() => { diff --git a/packages/media-console/src/types.ts b/packages/media-console/src/types.ts index 87c401b..00a6214 100644 --- a/packages/media-console/src/types.ts +++ b/packages/media-console/src/types.ts @@ -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'; @@ -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 } */ @@ -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 fix this issue: + * @link https://github.com/LunatiqueCoder/react-native-media-console/issues/104 + */ + ref: RefObject; + /** + * Used to keep a consistency when using `ref?.current?.setNativeProps({scrollEnabled: boolean});`. + * @see ref + */ + scrollEnabled: boolean; + }; }; /** * testID selector for testing From c934f4c18dcc385768c4a32564ca1d557f04a812 Mon Sep 17 00:00:00 2001 From: Ovidiu Cristescu <55203625+LunatiqueCoder@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:41:25 +0300 Subject: [PATCH 2/3] 1104-flatlist-gesture-handling-enhancement - small improvements --- .../src/hooks/usePanResponders.tsx | 28 +++++++++++++------ packages/media-console/src/types.ts | 6 ++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/media-console/src/hooks/usePanResponders.tsx b/packages/media-console/src/hooks/usePanResponders.tsx index 8c3ad93..030a90b 100644 --- a/packages/media-console/src/hooks/usePanResponders.tsx +++ b/packages/media-console/src/hooks/usePanResponders.tsx @@ -36,17 +36,29 @@ export const usePanResponders = ({ onEnd, pan: {horizontal = true, inverted = false, parentList} = {}, }: PanRespondersProps) => { + const {ref, scrollEnabled} = parentList || {}; + const enableParentScroll = () => - parentList?.ref?.current?.setNativeProps({ - scrollEnabled: parentList?.scrollEnabled, - }); + 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(); - parentList?.ref?.current?.setNativeProps({scrollEnabled: false}); + disableParentScroll(); }, onPanResponderMove: (_evt, gestureState) => { const diff = horizontal ? gestureState.dx : gestureState.dy; @@ -56,8 +68,7 @@ export const usePanResponders = ({ onPanResponderRelease: () => { setControlTimeout(); }, - onPanResponderEnd: enableParentScroll, - onPanResponderTerminationRequest: () => false, // https://stackoverflow.com/a/76875305/14056591 + ...parentScrollPanOptions, }); const seekPanResponder = PanResponder.create({ @@ -68,7 +79,7 @@ export const usePanResponders = ({ clearControlTimeout(); const position = evt.nativeEvent.locationX; setSeekerPosition(position); - parentList?.ref?.current?.setNativeProps({scrollEnabled: false}); + disableParentScroll(); }, onPanResponderMove: (_evt, gestureState) => { const diff = horizontal ? gestureState.dx : gestureState.dy; @@ -87,8 +98,7 @@ export const usePanResponders = ({ setSeeking(false); seek && seek(time); }, - onPanResponderEnd: enableParentScroll, - onPanResponderTerminationRequest: () => false, // https://stackoverflow.com/a/76875305/14056591 + ...parentScrollPanOptions, }); useEffect(() => { diff --git a/packages/media-console/src/types.ts b/packages/media-console/src/types.ts index 00a6214..f05a85b 100644 --- a/packages/media-console/src/types.ts +++ b/packages/media-console/src/types.ts @@ -276,15 +276,15 @@ export interface VideoPlayerProps extends ReactVideoProps { parentList?: { /** * Internally, `ref?.current?.setNativeProps({scrollEnabled: boolean});` is used in order - * to fix this issue: + * to make the video player work seamlessly within FlatLists or ScrollViews: * @link https://github.com/LunatiqueCoder/react-native-media-console/issues/104 */ ref: RefObject; /** - * Used to keep a consistency when using `ref?.current?.setNativeProps({scrollEnabled: boolean});`. + * Used to keep the state consistency when using `ref?.current?.setNativeProps({scrollEnabled: boolean});`. * @see ref */ - scrollEnabled: boolean; + scrollEnabled?: boolean; }; }; /** From 75aafc81805d8f038d65e77686b2fc92d8f6095c Mon Sep 17 00:00:00 2001 From: Ovidiu Cristescu <55203625+LunatiqueCoder@users.noreply.github.com> Date: Tue, 13 Aug 2024 03:13:43 +0300 Subject: [PATCH 3/3] 1104-flatlist-gesture-handling-enhancement - small improvements --- packages/media-console/src/hooks/usePanResponders.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/media-console/src/hooks/usePanResponders.tsx b/packages/media-console/src/hooks/usePanResponders.tsx index 030a90b..2e502ee 100644 --- a/packages/media-console/src/hooks/usePanResponders.tsx +++ b/packages/media-console/src/hooks/usePanResponders.tsx @@ -36,7 +36,7 @@ export const usePanResponders = ({ onEnd, pan: {horizontal = true, inverted = false, parentList} = {}, }: PanRespondersProps) => { - const {ref, scrollEnabled} = parentList || {}; + const {ref, scrollEnabled = true} = parentList || {}; const enableParentScroll = () => ref?.current?.setNativeProps({scrollEnabled});