Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Gesture Handling Enhancement for use with FlatList #104

Open
coofzilla opened this issue Apr 2, 2024 · 5 comments · May be fixed by #120
Open

Feature: Gesture Handling Enhancement for use with FlatList #104

coofzilla opened this issue Apr 2, 2024 · 5 comments · May be fixed by #120
Assignees
Labels
bug Something isn't working

Comments

@coofzilla
Copy link

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>
  )}
/>
@LunatiqueCoder LunatiqueCoder added the bug Something isn't working label Aug 9, 2024
@LunatiqueCoder LunatiqueCoder self-assigned this Aug 10, 2024
@LunatiqueCoder
Copy link
Owner

LunatiqueCoder commented Aug 10, 2024

@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: facebook/react-native#28135

@LunatiqueCoder
Copy link
Owner

LunatiqueCoder commented Aug 10, 2024

@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

@LunatiqueCoder LunatiqueCoder linked a pull request Aug 10, 2024 that will close this issue
@LunatiqueCoder LunatiqueCoder linked a pull request Aug 10, 2024 that will close this issue
@coofzilla
Copy link
Author

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.

@LunatiqueCoder
Copy link
Owner

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.

@LunatiqueCoder
Copy link
Owner

LunatiqueCoder commented Aug 12, 2024

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants