onLongPress triggers instead of onPress for single tap - react-native

I have a card item with TouchableOpacity which has both onPress and onLongPress. When I intend to perform onPress action by taping on the record onLongPress gets triggered. This is happening only when remote debugger is enabled. And this is happening both in emulator and real device.
Issue reported in github as well long back, but no solution as of now.
Any help is appreciated to prevent this behavior.Thank you.

Related

How to make PanResponder work as expected when user double taps by inadvertance while dragging his finger?

I'm trying to build a recording button where the user needs to keep pressing on the button to record, and then release the button when he wants to finish recording. Also, if the user releases its finger while outside of the button area, the recording gets cancelled.
I'm using a PanResponder to implement this behavior:
<View {...panResponder.panHandlers}>
<Button />
</View>
Everything works fine in the most cases. However, if the user taps somewhere else on the screen with another finger while recording (most often by inadvertance), then the PanResponder stops to capture the recording drag. The onResponderRelease method is not called.
I have no clue how to solve this. I want the recording drag to be resilient to extra touches.
I have tried catching and blocking any extra touch, if in recording state, inside the parent view but it does not work.
Any help is appreciated !

React Native - Keyboard is automatically hiding

I've got a problem with keyboard in react native. I have a component with TextInput inside of it. The problem is when I am touching it - keyboard is starting to show, but immediately hiding back. (Checked with event listeners of Keyboard - event keyboardWilHide triggers, but I don't know what triggered it).
My assumption that the core of the problem in my navigation architecture. I have materialBottomTabNavigator which has materialTopTabNavigator inside, which has StackNavigator inside, and my component is a screen in stack navigator. Probably some tabs properties are triggering Keyboard Hide event, but I did not found any.
(In terms of debug launched app with my component moved out of this type of navigation and everything works fine).
Would appreciate any help. Thanks in advance!

How can i make my TouchableOpacity's reaction to onPress immediate by changing its opacity so users can easily feel they actually press that button?

Sometimes my app is quite busy with other stuff so for a noticeable amount of time,
it becomes unresponsive to touch events bound to my TouchableOpacity components.
activeOpacity property makes the button changing its opacity with some delay (1-2 seconds) if that kind of heavy load being present so users do not feel that they actually press that button and keep pressing until they see a reaction. Of course it creates some frustration for them.
My understanding is that I think these opacity changing animation also requires some communication between JS and native side over the bridge. That's why it is affected by other bridge communication and becomes unresponsive for a while.
Is there any way to overcome this situation in React Native side and make the button immediately change its opacity?
Or can it be handled only by creating a new native button component for that purpose ?
Check out requestAnimationFrame https://reactnative.dev/docs/timers.
"requestAnimationFrame(fn) is not the same as setTimeout(fn, 0) - the former will fire after all the frame has flushed, whereas the latter will fire as quickly as possible (over 1000x per second on a iPhone 5S)."
Wrap your onPress logic in requestAnimationFrame so that the animation happens before the logic.

How to disable Android default "Touchable onPress" sound from react-native code?

I'm developing an app for Android in react-native with expo. I'm using expo's Audio.Sound API in order to play different sounds in my app. What annoys me is that whenever I press a TouchableOpacity component I get both my sound and the default onPress sound from Android (it disappears only if I mute the sound from the hardware buttons of my phone). I'd like to disable the default sound. Is there a way to do this programatically from react-native code?
You can actually use touchSoundDisabled={true} which is not covered in TouchableOpacity docs, but is part of a Button component. But it still works for touchables as well
I had the exact same problem using TouchableWithoutFeedback. The touchable events always play the default android button noise when clicked.
The solution I found was to instead use the onStartShouldSetResponder prop of the View component. This basically turns a view into a button and is equivalent to the 'onPress' prop.
<View onStartShouldSetResponder={() => this.onPress()}/>
Use Pressable instead of TouchableOpacity and add android_disableSound={true}
<Pressable android_disableSound={true} onPress={() => {}}

What's the best way to see if someone is still using the app?

Here's the problem: I have a React-Native/Redux app. I need to make sure I can lock the screen (display a modal, really) after X minutes of app inactivity (theoretically someone may have their screen "always on", so I can't rely on the screen turning itself off).
My proposed solution: I want to detect when any touch event happens. I don't want to interfere with them or do anything about it other than reset a setTimeout. But I just want to know when the screen is touched at all.
Displaying the modal itself isn't an issue and is already working. I also have it display the modal if the app leaves the foreground for any reason. I just need the timeout.
I've tried using a TouchableWthoutFeedback that wraps the whole UI and that sorta works, but it doesn't receive any event when a Touchable is farther down the component tree and handles the event. But I've also only used onPressIn and I'm unsure if anything else on it will work as needed. I've looked briefly at PanResponder but that looks a bit more complex than I might need? Not sure on that one, yet.
I'm open to other suggestions, but the only other thing I can think of is having literally every other action in the app (even ones I haven't created yet) send an dispatch up the redux flagpole, and that seems very heavy-handed and prone to error.
is this feasible? What are my options if it's not?
I found the solution. It's to add a onStartShouldSetResponderCapture callback as a prop on a containing View. I can return false in this callback but still notice all the touch events that come through. The Capture portion is important because it gives you access to the event before a "real" touchable can get to it.
Then, in the callback, I just clear and re-create the timer.