react-native-media-console
react-native-media-console copied to clipboard
Feature: Gesture Handling Enhancement for use with FlatList
Problem
When embedding the VideoPlayer component within a horizontally scrolling FlatList, there is a gesture conflict that arises. Specifically, when attempting to seek in the video (or volume) by dragging the seeker control left or right, the FlatList interprets this gesture as a horizontal scroll, leading to an unintended navigation away from the current video item instead of seeking within the video.
Expected Behavior
The expected behavior is that when interacting with the video player's seeking controls, the FlatList scrolling should be temporarily disabled or the gesture should be captured exclusively by the video player, allowing for a smooth seeking experience without triggering a scroll in the FlatList.
Current Workaround
Still trying to figure this out 😅
Example Snippet
Here is a simplified code snippet demonstrating the setup:
<FlatList
data={videos}
horizontal
renderItem={({ item }) => (
<View>
<VideoPlayer
source={{ uri: item.url }}
// Other necessary props
/>
</View>
)}
/>
@coofzilla Indeed, this is an ugly one... Not sure if I can find a good fix, but perhaps we can workaround it. I'm still looking into it. Will let you know if I find something useful.
Related: https://github.com/facebook/react-native/issues/28135
@coofzilla What do you think about the following fix? The parentListRef would accept either FlatList or Scrollview refs. Internally, it would call parentListRef?.current?.setNativeProps({scrollEnabled: boolean}); in order to avoid this issue.
export const VideoList = () => {
const flatListRef = useRef<FlatList>(null);
return (
<FlatList
ref={flatListRef}
data={videos}
horizontal
renderItem={({ item }) => (
<View>
<VideoPlayer
parentListRef={flatListRef}
source={{ uri: item.url }}
// Other necessary props
/>
</View>
)}
/>
)
}
The issue with this approach is that if the developers are using scrollEnabled prop with useState, it might interfere with this workaround and lead to unexpected behaviour and issues. More info here: https://reactnative.dev/docs/direct-manipulation
Looks good to me, especially since you've documented the change—this will give developers a clear example to follow when implementing it.
Just to clarify, would this approach work the same way for VideoPlayers inside FlatLists or ScrollViews that are vertical? Essentially, the same snippet you provided, but without horizontal.
Just to clarify, would this approach work the same way for VideoPlayers inside FlatLists or ScrollViews that are vertical? Essentially, the same snippet you provided, but without horizontal.
@coofzilla Yes, I think so. I will update the PR today and you'll be able to test it in ./examples/MyTVProject. If you confirm everything works fine, I'll merge and release a new version with the fix.
@coofzilla The branch is updated. The final implementation is like this:
export const VideoList = () => {
const flatListRef = useRef<FlatList>(null);
const [scrollEnabled, setScrollEnabled] = useState<boolean>(true)
return (
<FlatList
ref={flatListRef}
scrollEnabled={scrollEnabled}
data={videos}
horizontal
renderItem={({ item }) => (
<View>
<VideoPlayer
pan={{
parentList: {
ref: flatListRef,
scrollEnabled: scrollEnabled, // This is optional and only needed if `scrollEnabled` prop is used with FlatList
},
}}
source={{uri: 'https://vjs.zencdn.net/v/oceans.mp4'}}
/>
</View>
)}
/>
)
}
You can test those changes in ./examples/MyTVProject. See https://github.com/LunatiqueCoder/react-native-media-console/blob/master/CONTRIBUTING.md
Let me know if this fixes your issues
@LunatiqueCoder i am not able to find this code, can you please help me to figure that out