diff options
-rw-r--r-- | src/state/modals/index.tsx | 2 | ||||
-rw-r--r-- | src/view/com/modals/AltImage.tsx | 25 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx index 45856e108..ab710a3d0 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -6,7 +6,7 @@ import {Image as RNImage} from 'react-native-image-crop-picker' import {ImageModel} from '#/state/models/media/image' import {GalleryModel} from '#/state/models/media/gallery' 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' export interface ConfirmModal { diff --git a/src/view/com/modals/AltImage.tsx b/src/view/com/modals/AltImage.tsx index 5156511d6..7671c29c8 100644 --- a/src/view/com/modals/AltImage.tsx +++ b/src/view/com/modals/AltImage.tsx @@ -4,7 +4,9 @@ import { StyleSheet, TouchableOpacity, View, + TextInput as RNTextInput, useWindowDimensions, + ScrollView as RNScrollView, } from 'react-native' import {ScrollView, TextInput} from './util' import {Image} from 'expo-image' @@ -13,6 +15,7 @@ import {gradients, s} from 'lib/styles' import {enforceLen} from 'lib/strings/helpers' import {MAX_ALT_TEXT} from 'lib/constants' import {useTheme} from 'lib/ThemeContext' +import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible' import {Text} from '../util/text/Text' import LinearGradient from 'react-native-linear-gradient' import {isWeb} from 'platform/detection' @@ -34,6 +37,24 @@ export function Component({image}: Props) { const [altText, setAltText] = useState(image.altText) const windim = useWindowDimensions() 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 maxWidth = isWeb ? 450 : windim.width @@ -71,6 +92,7 @@ export function Component({image}: Props) { testID="altTextImageModal" style={[pal.view, styles.scrollContainer]} keyboardShouldPersistTaps="always" + ref={scrollViewRef} nativeID="imageAltText"> <View style={styles.scrollInner}> <View style={[pal.viewLight, styles.imageContainer]}> @@ -97,7 +119,8 @@ export function Component({image}: Props) { accessibilityLabel={_(msg`Image alt text`)} accessibilityHint="" accessibilityLabelledBy="imageAltText" - autoFocus + // @ts-ignore This is fine, type is weird on the BottomSheetTextInput + ref={inputRef} /> <View style={styles.buttonControls}> <TouchableOpacity |