Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Composer - make sure android keyboard opens (#4390)

* keep trying to open keyboard until it's open

* limit number of retries

* keep the original 50ms one as well

* Proper fix!

* disable autoFocus if not visible

* Reset derived state

* Revert "Reset derived state"

This reverts commit 71f57391ae78bac717282e699d1b83cbd87771eb.

* Use derived state pattern

* Rename for clarity

---------

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>

authored by

Samuel Newman
Dan Abramov
and committed by
GitHub
85e67625 48796449

+20 -11
+8 -10
src/view/com/composer/Composer.tsx
··· 107 107 text: initText, 108 108 imageUris: initImageUris, 109 109 cancelRef, 110 + isModalReady, 110 111 }: Props & { 112 + isModalReady: boolean 111 113 cancelRef?: React.RefObject<CancelRef> 112 114 }) { 113 115 const {currentAccount} = useSession() ··· 155 157 const [labels, setLabels] = useState<string[]>([]) 156 158 const [threadgate, setThreadgate] = useState<ThreadgateSetting[]>([]) 157 159 158 - React.useEffect(() => { 159 - if (!isAndroid) return 160 - const id = setTimeout(() => textInput.current?.focus(), 100) 161 - return () => clearTimeout(id) 162 - }, []) 163 - 164 160 const gallery = useMemo( 165 161 () => new GalleryModel(initImageUris), 166 162 [initImageUris], ··· 181 177 const onPressCancel = useCallback(() => { 182 178 if (graphemeLength > 0 || !gallery.isEmpty || extGif) { 183 179 closeAllDialogs() 184 - if (Keyboard) { 185 - Keyboard.dismiss() 186 - } 180 + Keyboard.dismiss() 187 181 discardPromptControl.open() 188 182 } else { 189 183 onClose() ··· 524 518 ref={textInput} 525 519 richtext={richtext} 526 520 placeholder={selectTextInputPlaceholder} 527 - autoFocus={!isAndroid} 521 + // fixes autofocus on android 522 + key={ 523 + isAndroid ? (isModalReady ? 'ready' : 'animating') : 'static' 524 + } 525 + autoFocus={isAndroid ? isModalReady : true} 528 526 setRichText={setRichText} 529 527 onPhotoPasted={onPhotoPasted} 530 528 onPressPublish={onPressPublish}
+11 -1
src/view/shell/Composer.tsx
··· 1 - import React, {useLayoutEffect} from 'react' 1 + import React, {useLayoutEffect, useState} from 'react' 2 2 import {Modal, View} from 'react-native' 3 3 import {GestureHandlerRootView} from 'react-native-gesture-handler' 4 4 import {RootSiblingParent} from 'react-native-root-siblings' ··· 24 24 const t = useTheme() 25 25 const state = useComposerState() 26 26 const ref = useComposerCancelRef() 27 + const [isModalReady, setIsModalReady] = useState(false) 27 28 28 29 const open = !!state 30 + const [prevOpen, setPrevOpen] = useState(open) 31 + if (open !== prevOpen) { 32 + setPrevOpen(open) 33 + if (!open) { 34 + setIsModalReady(false) 35 + } 36 + } 29 37 30 38 return ( 31 39 <Modal ··· 34 42 visible={open} 35 43 presentationStyle="formSheet" 36 44 animationType="slide" 45 + onShow={() => setIsModalReady(true)} 37 46 onRequestClose={() => ref.current?.onPressCancel()}> 38 47 <View style={[t.atoms.bg, a.flex_1]}> 39 48 <Providers open={open}> 40 49 <ComposePost 50 + isModalReady={isModalReady} 41 51 cancelRef={ref} 42 52 replyTo={state?.replyTo} 43 53 onPost={state?.onPost}
+1
src/view/shell/Composer.web.tsx
··· 56 56 t.atoms.border_contrast_medium, 57 57 ]}> 58 58 <ComposePost 59 + isModalReady={true} 59 60 replyTo={state.replyTo} 60 61 quote={state.quote} 61 62 onPost={state.onPost}