about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/screens/Messages/components/MessageInput.tsx48
-rw-r--r--src/view/screens/Storybook/Forms.tsx19
-rw-r--r--src/view/screens/Storybook/index.tsx32
3 files changed, 59 insertions, 40 deletions
diff --git a/src/screens/Messages/components/MessageInput.tsx b/src/screens/Messages/components/MessageInput.tsx
index 85509211b..c97918fa0 100644
--- a/src/screens/Messages/components/MessageInput.tsx
+++ b/src/screens/Messages/components/MessageInput.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import {useCallback, useState} from 'react'
 import {Pressable, TextInput, useWindowDimensions, View} from 'react-native'
 import {
   useFocusedInputHandler,
@@ -19,7 +19,7 @@ import Graphemer from 'graphemer'
 import {HITSLOP_10, MAX_DM_GRAPHEME_LENGTH} from '#/lib/constants'
 import {useHaptics} from '#/lib/haptics'
 import {useEmail} from '#/lib/hooks/useEmail'
-import {isIOS} from '#/platform/detection'
+import {isIOS, isWeb} from '#/platform/detection'
 import {
   useMessageDraft,
   useSaveMessageDraft,
@@ -58,16 +58,17 @@ export function MessageInput({
   const isInputScrollable = useSharedValue(false)
 
   const inputStyles = useSharedInputStyles()
-  const [isFocused, setIsFocused] = React.useState(false)
-  const [message, setMessage] = React.useState(getDraft)
+  const [isFocused, setIsFocused] = useState(false)
+  const [message, setMessage] = useState(getDraft)
   const inputRef = useAnimatedRef<TextInput>()
+  const [shouldEnforceClear, setShouldEnforceClear] = useState(false)
 
   const {needsEmailVerification} = useEmail()
 
   useSaveMessageDraft(message)
   useExtractEmbedFromFacets(message, setEmbed)
 
-  const onSubmit = React.useCallback(() => {
+  const onSubmit = useCallback(() => {
     if (needsEmailVerification) {
       return
     }
@@ -81,14 +82,18 @@ export function MessageInput({
     clearDraft()
     onSendMessage(message)
     playHaptic()
-    setMessage('')
     setEmbed(undefined)
-
-    // Pressing the send button causes the text input to lose focus, so we need to
-    // re-focus it after sending
-    setTimeout(() => {
-      inputRef.current?.focus()
-    }, 100)
+    setMessage('')
+    if (isIOS) {
+      setShouldEnforceClear(true)
+    }
+    if (isWeb) {
+      // Pressing the send button causes the text input to lose focus, so we need to
+      // re-focus it after sending
+      setTimeout(() => {
+        inputRef.current?.focus()
+      }, 100)
+    }
   }, [
     needsEmailVerification,
     hasEmbed,
@@ -97,8 +102,8 @@ export function MessageInput({
     onSendMessage,
     playHaptic,
     setEmbed,
-    _,
     inputRef,
+    _,
   ])
 
   useFocusedInputHandler(
@@ -149,8 +154,21 @@ export function MessageInput({
           placeholder={_(msg`Write a message`)}
           placeholderTextColor={t.palette.contrast_500}
           value={message}
+          onChange={evt => {
+            // bit of a hack: iOS automatically accepts autocomplete suggestions when you tap anywhere on the screen
+            // including the button we just pressed - and this overrides clearing the input! so we watch for the
+            // next change and double make sure the input is cleared. It should *always* send an onChange event after
+            // clearing via setMessage('') that happens in onSubmit()
+            // -sfn
+            if (isIOS && shouldEnforceClear) {
+              setShouldEnforceClear(false)
+              setMessage('')
+              return
+            }
+            const text = evt.nativeEvent.text
+            setMessage(text)
+          }}
           multiline={true}
-          onChangeText={setMessage}
           style={[
             a.flex_1,
             a.text_md,
@@ -160,7 +178,7 @@ export function MessageInput({
             animatedStyle,
           ]}
           keyboardAppearance={t.name === 'light' ? 'light' : 'dark'}
-          blurOnSubmit={false}
+          submitBehavior="submit"
           onFocus={() => setIsFocused(true)}
           onBlur={() => setIsFocused(false)}
           ref={inputRef}
diff --git a/src/view/screens/Storybook/Forms.tsx b/src/view/screens/Storybook/Forms.tsx
index 8ec118ae3..ad130b376 100644
--- a/src/view/screens/Storybook/Forms.tsx
+++ b/src/view/screens/Storybook/Forms.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import {View} from 'react-native'
+import {TextInput, View} from 'react-native'
 
 import {atoms as a} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
@@ -19,6 +19,8 @@ export function Forms() {
   const [value, setValue] = React.useState('')
   const [date, setDate] = React.useState('2001-01-01')
 
+  const inputRef = React.useRef<TextInput>(null)
+
   return (
     <View style={[a.gap_4xl, a.align_start]}>
       <H1>Forms</H1>
@@ -33,22 +35,23 @@ export function Forms() {
         />
 
         <View style={[a.flex_row, a.align_start, a.gap_sm]}>
-          <View
-            style={[
-              {
-                width: '50%',
-              },
-            ]}>
+          <View style={[a.flex_1]}>
             <TextField.Root>
               <TextField.Icon icon={Globe} />
               <TextField.Input
+                inputRef={inputRef}
                 value={value}
                 onChangeText={setValue}
                 label="Text field"
               />
             </TextField.Root>
           </View>
-          <Button label="Submit" size="large" variant="solid" color="primary">
+          <Button
+            label="Submit"
+            size="large"
+            variant="solid"
+            color="primary"
+            onPress={() => inputRef.current?.clear()}>
             <ButtonText>Submit</ButtonText>
           </Button>
         </View>
diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx
index de3d46533..0146bc3c6 100644
--- a/src/view/screens/Storybook/index.tsx
+++ b/src/view/screens/Storybook/index.tsx
@@ -1,13 +1,11 @@
 import React from 'react'
-import {ScrollView, View} from 'react-native'
+import {View} from 'react-native'
 import {useNavigation} from '@react-navigation/native'
 
 import {NavigationProp} from '#/lib/routes/types'
-import {isWeb} from '#/platform/detection'
 import {useSetThemePrefs} from '#/state/shell'
-import {CenteredView} from '#/view/com/util/Views'
 import {ListContained} from '#/view/screens/Storybook/ListContained'
-import {atoms as a, ThemeProvider, useTheme} from '#/alf'
+import {atoms as a, ThemeProvider} from '#/alf'
 import {Button, ButtonText} from '#/components/Button'
 import * as Layout from '#/components/Layout'
 import {Admonitions} from './Admonitions'
@@ -27,25 +25,27 @@ import {Typography} from './Typography'
 export function Storybook() {
   return (
     <Layout.Screen>
-      {isWeb ? (
+      <Layout.Header.Outer>
+        <Layout.Header.BackButton />
+        <Layout.Header.Content>
+          <Layout.Header.TitleText>Storybook</Layout.Header.TitleText>
+        </Layout.Header.Content>
+        <Layout.Header.Slot />
+      </Layout.Header.Outer>
+      <Layout.Content keyboardShouldPersistTaps="handled">
         <StorybookInner />
-      ) : (
-        <ScrollView>
-          <StorybookInner />
-        </ScrollView>
-      )}
+      </Layout.Content>
     </Layout.Screen>
   )
 }
 
 function StorybookInner() {
-  const t = useTheme()
   const {setColorMode, setDarkTheme} = useSetThemePrefs()
   const [showContainedList, setShowContainedList] = React.useState(false)
   const navigation = useNavigation<NavigationProp>()
 
   return (
-    <CenteredView style={[t.atoms.bg]}>
+    <>
       <View style={[a.p_xl, a.gap_5xl, {paddingBottom: 100}]}>
         {!showContainedList ? (
           <>
@@ -100,10 +100,6 @@ function StorybookInner() {
               <ButtonText>Open Shared Prefs Tester</ButtonText>
             </Button>
 
-            <Admonitions />
-
-            <Settings />
-
             <ThemeProvider theme="light">
               <Theming />
             </ThemeProvider>
@@ -126,6 +122,8 @@ function StorybookInner() {
             <Menus />
             <Breakpoints />
             <Dialogs />
+            <Admonitions />
+            <Settings />
 
             <Button
               variant="solid"
@@ -150,6 +148,6 @@ function StorybookInner() {
           </>
         )}
       </View>
-    </CenteredView>
+    </>
   )
 }