From e45f0b6c43b751a3b23f8967fee4c6664a6844ae Mon Sep 17 00:00:00 2001
From: Hailey <153161762+haileyok@users.noreply.github.com>
Date: Tue, 30 Jan 2024 15:48:03 -0800
Subject: 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
---
 src/view/com/modals/AltImage.tsx | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

(limited to 'src/view/com/modals/AltImage.tsx')

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
-- 
cgit 1.4.1

