react-native-ios-context-menu icon indicating copy to clipboard operation
react-native-ios-context-menu copied to clipboard

Pressables not working after context menu opened

Open mrousavy opened this issue 4 years ago • 4 comments

When wrapping Pressables (<Pressable>, <TouchableOpacity>, ...) with a context menu, the entire JS responder system will fail/crash once you open the context menu once. In other words, your entire screen becomes unresponsive if you open a context menu that contains a pressable.

There might be some extra treatment required to support inlining the JS pressability API.

(Also, it looks like native buttons such as the back button from react-native-navigation are still working, it's just the current screen that "freezes"/doesn't trigger onPress events anymore)

https://user-images.githubusercontent.com/15199031/104899395-14d0a680-597b-11eb-9d4e-c851136042f7.mov

Code:

return (
  <View style={styles.container}>
    <ContextMenuView onPressMenuItem={onContextActionPressed} menuConfig={menuConfig} previewConfig={previewConfig}>
      <Pressable style={styles.imageContainer} onPress={onImagePressed}>
        <FastImage
          style={styles.image}
          source={imageSource}
        />
      </Pressable>
    </ContextMenuView>
  </View>
);

mrousavy avatar Jan 18 '21 09:01 mrousavy

Hey. The same above code is working out for me. The only thing that I am facing is the crash when you navigate quickly when the context menu view is still visible. Here's what I am talking about.

https://user-images.githubusercontent.com/42263739/121296533-4803da00-c90a-11eb-9b30-8a16035323e2.mov

RazaShehryar avatar Jun 09 '21 05:06 RazaShehryar

Just solved the @RazaShehryar's issue. Here's a code:

<ContextMenuView { ...props }>
    <Pressable
        delayLongPress={100} // Leave room for a user to be able to click
        onPress={action} // Here's your action
        onLongPress={() => {}} // A callback that does nothing
</ContextMenuView>

Explanation:

Pressable always invokes onPress right after onPressOut. onLongPress, if defined, is called instead if a certain time from onPressIn passes. It means onPress will always be called if onLongPress is not defined. (even if you've been pressing eternity)

The conflict happens, Pressable navigates a user to a different screen (common behavior), and ContextMenuView tries to mount a context menu, but a parent component for the context menu doesn't exist anymore.

What we did is we set up a time frame for onPress. If a user clicks, onPress is called. If the user presses long enough, a context menu is rendered. If the user starts pressing but removes his/her/their finger too soon, nothing happens.

@mrousavy , this might be a reason for your bug as well.

I hope it will help you guys.

rorazliev-old avatar Feb 21 '22 16:02 rorazliev-old