Autofocus the alt text input on all platforms, improve dismissability on native (#2690)
* sneak in a eslint fix * autofocus the alt text input whenever we open the modal * properly use the hook
This commit is contained in:
parent
c5edd0a065
commit
e45f0b6c43
2 changed files with 25 additions and 2 deletions
|
@ -6,7 +6,7 @@ import {Image as RNImage} from 'react-native-image-crop-picker'
|
||||||
import {ImageModel} from '#/state/models/media/image'
|
import {ImageModel} from '#/state/models/media/image'
|
||||||
import {GalleryModel} from '#/state/models/media/gallery'
|
import {GalleryModel} from '#/state/models/media/gallery'
|
||||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||||
import {EmbedPlayerSource} from '#/lib/strings/embed-player.ts'
|
import {EmbedPlayerSource} from '#/lib/strings/embed-player'
|
||||||
import {ThreadgateSetting} from '../queries/threadgate'
|
import {ThreadgateSetting} from '../queries/threadgate'
|
||||||
|
|
||||||
export interface ConfirmModal {
|
export interface ConfirmModal {
|
||||||
|
|
|
@ -4,7 +4,9 @@ import {
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
|
TextInput as RNTextInput,
|
||||||
useWindowDimensions,
|
useWindowDimensions,
|
||||||
|
ScrollView as RNScrollView,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {ScrollView, TextInput} from './util'
|
import {ScrollView, TextInput} from './util'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
|
@ -13,6 +15,7 @@ import {gradients, s} from 'lib/styles'
|
||||||
import {enforceLen} from 'lib/strings/helpers'
|
import {enforceLen} from 'lib/strings/helpers'
|
||||||
import {MAX_ALT_TEXT} from 'lib/constants'
|
import {MAX_ALT_TEXT} from 'lib/constants'
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
import {useTheme} from 'lib/ThemeContext'
|
||||||
|
import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
import LinearGradient from 'react-native-linear-gradient'
|
import LinearGradient from 'react-native-linear-gradient'
|
||||||
import {isWeb} from 'platform/detection'
|
import {isWeb} from 'platform/detection'
|
||||||
|
@ -34,6 +37,24 @@ export function Component({image}: Props) {
|
||||||
const [altText, setAltText] = useState(image.altText)
|
const [altText, setAltText] = useState(image.altText)
|
||||||
const windim = useWindowDimensions()
|
const windim = useWindowDimensions()
|
||||||
const {closeModal} = useModalControls()
|
const {closeModal} = useModalControls()
|
||||||
|
const inputRef = React.useRef<RNTextInput>(null)
|
||||||
|
const scrollViewRef = React.useRef<RNScrollView>(null)
|
||||||
|
const keyboardShown = useIsKeyboardVisible()
|
||||||
|
|
||||||
|
// Autofocus hack when we open the modal. We have to wait for the animation to complete first
|
||||||
|
React.useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
inputRef.current?.focus()
|
||||||
|
}, 500)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// We'd rather be at the bottom here so that we can easily dismiss the modal instead of having to scroll
|
||||||
|
// (especially on android, it acts weird)
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (keyboardShown[0]) {
|
||||||
|
scrollViewRef.current?.scrollToEnd()
|
||||||
|
}
|
||||||
|
}, [keyboardShown])
|
||||||
|
|
||||||
const imageStyles = useMemo<ImageStyle>(() => {
|
const imageStyles = useMemo<ImageStyle>(() => {
|
||||||
const maxWidth = isWeb ? 450 : windim.width
|
const maxWidth = isWeb ? 450 : windim.width
|
||||||
|
@ -71,6 +92,7 @@ export function Component({image}: Props) {
|
||||||
testID="altTextImageModal"
|
testID="altTextImageModal"
|
||||||
style={[pal.view, styles.scrollContainer]}
|
style={[pal.view, styles.scrollContainer]}
|
||||||
keyboardShouldPersistTaps="always"
|
keyboardShouldPersistTaps="always"
|
||||||
|
ref={scrollViewRef}
|
||||||
nativeID="imageAltText">
|
nativeID="imageAltText">
|
||||||
<View style={styles.scrollInner}>
|
<View style={styles.scrollInner}>
|
||||||
<View style={[pal.viewLight, styles.imageContainer]}>
|
<View style={[pal.viewLight, styles.imageContainer]}>
|
||||||
|
@ -97,7 +119,8 @@ export function Component({image}: Props) {
|
||||||
accessibilityLabel={_(msg`Image alt text`)}
|
accessibilityLabel={_(msg`Image alt text`)}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
accessibilityLabelledBy="imageAltText"
|
accessibilityLabelledBy="imageAltText"
|
||||||
autoFocus
|
// @ts-ignore This is fine, type is weird on the BottomSheetTextInput
|
||||||
|
ref={inputRef}
|
||||||
/>
|
/>
|
||||||
<View style={styles.buttonControls}>
|
<View style={styles.buttonControls}>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue