diff options
author | Ansh <anshnanda10@gmail.com> | 2023-07-06 18:41:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-06 20:41:27 -0500 |
commit | df7552135a50d715a50ab592874eb84fc7c8bbcf (patch) | |
tree | bc107dec5ee45a57d3e97980136eb9a7dabfda1d | |
parent | bf1785765d47c08d7f04c50b3bfd6c04a1bc795b (diff) | |
download | voidsky-df7552135a50d715a50ab592874eb84fc7c8bbcf.tar.zst |
[APP-703] Android horizontal scroll registers as tap (#960)
* use Touchables from react-native-gesture-handler * upgrade `react-native-gesture-handler` to latest version * add FixedTouchableHighlight for android * add workaround comment * wait for animations to complete before loading data * downgrade RNGH back to the version we had
-rw-r--r-- | src/view/com/pager/FixedTouchableHighlight.tsx | 42 | ||||
-rw-r--r-- | src/view/com/util/Link.tsx | 25 | ||||
-rw-r--r-- | src/view/screens/PostThread.tsx | 16 |
3 files changed, 74 insertions, 9 deletions
diff --git a/src/view/com/pager/FixedTouchableHighlight.tsx b/src/view/com/pager/FixedTouchableHighlight.tsx new file mode 100644 index 000000000..d07196975 --- /dev/null +++ b/src/view/com/pager/FixedTouchableHighlight.tsx @@ -0,0 +1,42 @@ +// FixedTouchableHighlight.tsx +import React, {ComponentProps, useRef} from 'react' +import {GestureResponderEvent, TouchableHighlight} from 'react-native' + +type Position = {pageX: number; pageY: number} + +export default function FixedTouchableHighlight({ + onPress, + onPressIn, + ...props +}: ComponentProps<typeof TouchableHighlight>) { + const _touchActivatePositionRef = useRef<Position | null>(null) + + function _onPressIn(e: GestureResponderEvent) { + const {pageX, pageY} = e.nativeEvent + + _touchActivatePositionRef.current = { + pageX, + pageY, + } + + onPressIn?.(e) + } + + function _onPress(e: GestureResponderEvent) { + const {pageX, pageY} = e.nativeEvent + + const absX = Math.abs(_touchActivatePositionRef.current?.pageX! - pageX) + const absY = Math.abs(_touchActivatePositionRef.current?.pageY! - pageY) + + const dragged = absX > 2 || absY > 2 + if (!dragged) { + onPress?.(e) + } + } + + return ( + <TouchableHighlight onPressIn={_onPressIn} onPress={_onPress} {...props}> + {props.children} + </TouchableHighlight> + ) +} diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 7ff896344..1dec97e78 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -5,11 +5,11 @@ import { GestureResponderEvent, Platform, StyleProp, - TouchableWithoutFeedback, - TouchableOpacity, TextStyle, View, ViewStyle, + TouchableOpacity, + TouchableWithoutFeedback, } from 'react-native' import { useLinkProps, @@ -22,8 +22,9 @@ import {NavigationProp} from 'lib/routes/types' import {router} from '../../../routes' import {useStores, RootStoreModel} from 'state/index' import {convertBskyAppUrlIfNeeded, isExternalUrl} from 'lib/strings/url-helpers' -import {isDesktopWeb} from 'platform/detection' +import {isAndroid, isDesktopWeb} from 'platform/detection' import {sanitizeUrl} from '@braintree/sanitize-url' +import FixedTouchableHighlight from '../pager/FixedTouchableHighlight' type Event = | React.MouseEvent<HTMLAnchorElement, MouseEvent> @@ -65,6 +66,24 @@ export const Link = observer(function Link({ ) if (noFeedback) { + if (isAndroid) { + // workaround for Android not working well with left/right swipe gestures and TouchableWithoutFeedback + // https://github.com/callstack/react-native-pager-view/issues/424 + return ( + <FixedTouchableHighlight + testID={testID} + onPress={onPress} + // @ts-ignore web only -prf + href={asAnchor ? sanitizeUrl(href) : undefined} + accessible={accessible} + accessibilityRole="link" + {...props}> + <View style={style}> + {children ? children : <Text>{title || 'link'}</Text>} + </View> + </FixedTouchableHighlight> + ) + } return ( <TouchableWithoutFeedback testID={testID} diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx index e3ceb0bef..86b2d3027 100644 --- a/src/view/screens/PostThread.tsx +++ b/src/view/screens/PostThread.tsx @@ -1,5 +1,5 @@ import React, {useMemo} from 'react' -import {StyleSheet, View} from 'react-native' +import {InteractionManager, StyleSheet, View} from 'react-native' import {useFocusEffect} from '@react-navigation/native' import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' import {makeRecordUri} from 'lib/strings/url-helpers' @@ -31,11 +31,15 @@ export const PostThreadScreen = withAuthRequired(({route}: Props) => { React.useCallback(() => { store.shell.setMinimalShellMode(false) const threadCleanup = view.registerListeners() - if (!view.hasLoaded && !view.isLoading) { - view.setup().catch(err => { - store.log.error('Failed to fetch thread', err) - }) - } + + InteractionManager.runAfterInteractions(() => { + if (!view.hasLoaded && !view.isLoading) { + view.setup().catch(err => { + store.log.error('Failed to fetch thread', err) + }) + } + }) + return () => { threadCleanup() } |