Fix alt text selection in lightbox on both platforms

Move the tap-to-expand handlers from the wrapping Pressable onto the
selectable Text itself. Text selection is driven by the native text
view's long-press (RN Text on Android, UITextView on iOS); a parent
touchable consumes that long-press before the selectable node can begin
a selection, which broke selection entirely on Android.

This restores the pre-#10330 structure so the same native node owns both
the tap-to-expand and the long-press-to-select. The earlier #10654 fix
only addressed iOS (its UITextView selection recognizer coexists with
the parent Pressable); Android needs the handlers on the Text node.
This commit is contained in:
vineyardbovines
2026-06-02 17:18:58 -04:00
parent cbf8e95bdb
commit ec2556f87d
+28 -19
View File
@@ -1,11 +1,5 @@
import {useRef} from 'react'
import {
LayoutAnimation,
Pressable,
ScrollView,
StyleSheet,
View,
} from 'react-native'
import {LayoutAnimation, ScrollView, StyleSheet, View} from 'react-native'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {useLingui} from '@lingui/react/macro'
@@ -46,26 +40,41 @@ export function Footer({altText, isAltExpanded, onToggleAltExpanded}: Props) {
isMomentumScrolling.current = false
}}
contentContainerStyle={[a.px_md, a.py_sm]}>
<Pressable
<View
accessibilityRole="button"
accessibilityLabel={l`Expand alt text`}
accessibilityHint=""
onPress={() => {
if (isMomentumScrolling.current) return
LayoutAnimation.configureNext({
duration: 450,
update: {type: 'spring', springDamping: 1},
})
onToggleAltExpanded()
}}>
accessibilityHint="">
{/*
* The press handlers must live on the Text itself, not on a
* wrapping Pressable. Text selection is driven by the platform's
* native text view long-press (RN Text on Android, UITextView on
* iOS). A parent touchable consumes that long-press before the
* selectable Text can begin a selection - on Android this prevents
* selection entirely. Keeping onPress/onLongPress on the Text lets
* the same native node own both the tap-to-expand and the
* long-press-to-select. The empty onLongPress is intentional: it
* reserves the long-press for the OS selection gesture instead of
* firing the expand toggle. RN exposes no API to arbitrate tap vs
* native selection on a single node, so this is the supported
* workaround, and it behaves consistently on both platforms.
*/}
<Text
emoji
selectable
style={[a.text_sm, {color: t.palette.white}]}
numberOfLines={isAltExpanded ? undefined : 3}>
numberOfLines={isAltExpanded ? undefined : 3}
onPress={() => {
if (isMomentumScrolling.current) return
LayoutAnimation.configureNext({
duration: 450,
update: {type: 'spring', springDamping: 1},
})
onToggleAltExpanded()
}}
onLongPress={() => {}}>
{altText}
</Text>
</Pressable>
</View>
</ScrollView>
</View>
</View>