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>
zio/stable
Samuel Newman 2024-06-06 16:21:22 +03:00 committed by GitHub
parent 48796449ea
commit 85e676257e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 11 deletions

View File

@ -107,7 +107,9 @@ export const ComposePost = observer(function ComposePost({
text: initText, text: initText,
imageUris: initImageUris, imageUris: initImageUris,
cancelRef, cancelRef,
isModalReady,
}: Props & { }: Props & {
isModalReady: boolean
cancelRef?: React.RefObject<CancelRef> cancelRef?: React.RefObject<CancelRef>
}) { }) {
const {currentAccount} = useSession() const {currentAccount} = useSession()
@ -155,12 +157,6 @@ export const ComposePost = observer(function ComposePost({
const [labels, setLabels] = useState<string[]>([]) const [labels, setLabels] = useState<string[]>([])
const [threadgate, setThreadgate] = useState<ThreadgateSetting[]>([]) const [threadgate, setThreadgate] = useState<ThreadgateSetting[]>([])
React.useEffect(() => {
if (!isAndroid) return
const id = setTimeout(() => textInput.current?.focus(), 100)
return () => clearTimeout(id)
}, [])
const gallery = useMemo( const gallery = useMemo(
() => new GalleryModel(initImageUris), () => new GalleryModel(initImageUris),
[initImageUris], [initImageUris],
@ -181,9 +177,7 @@ export const ComposePost = observer(function ComposePost({
const onPressCancel = useCallback(() => { const onPressCancel = useCallback(() => {
if (graphemeLength > 0 || !gallery.isEmpty || extGif) { if (graphemeLength > 0 || !gallery.isEmpty || extGif) {
closeAllDialogs() closeAllDialogs()
if (Keyboard) { Keyboard.dismiss()
Keyboard.dismiss()
}
discardPromptControl.open() discardPromptControl.open()
} else { } else {
onClose() onClose()
@ -524,7 +518,11 @@ export const ComposePost = observer(function ComposePost({
ref={textInput} ref={textInput}
richtext={richtext} richtext={richtext}
placeholder={selectTextInputPlaceholder} placeholder={selectTextInputPlaceholder}
autoFocus={!isAndroid} // fixes autofocus on android
key={
isAndroid ? (isModalReady ? 'ready' : 'animating') : 'static'
}
autoFocus={isAndroid ? isModalReady : true}
setRichText={setRichText} setRichText={setRichText}
onPhotoPasted={onPhotoPasted} onPhotoPasted={onPhotoPasted}
onPressPublish={onPressPublish} onPressPublish={onPressPublish}

View File

@ -1,4 +1,4 @@
import React, {useLayoutEffect} from 'react' import React, {useLayoutEffect, useState} from 'react'
import {Modal, View} from 'react-native' import {Modal, View} from 'react-native'
import {GestureHandlerRootView} from 'react-native-gesture-handler' import {GestureHandlerRootView} from 'react-native-gesture-handler'
import {RootSiblingParent} from 'react-native-root-siblings' import {RootSiblingParent} from 'react-native-root-siblings'
@ -24,8 +24,16 @@ export const Composer = observer(function ComposerImpl({}: {
const t = useTheme() const t = useTheme()
const state = useComposerState() const state = useComposerState()
const ref = useComposerCancelRef() const ref = useComposerCancelRef()
const [isModalReady, setIsModalReady] = useState(false)
const open = !!state const open = !!state
const [prevOpen, setPrevOpen] = useState(open)
if (open !== prevOpen) {
setPrevOpen(open)
if (!open) {
setIsModalReady(false)
}
}
return ( return (
<Modal <Modal
@ -34,10 +42,12 @@ export const Composer = observer(function ComposerImpl({}: {
visible={open} visible={open}
presentationStyle="formSheet" presentationStyle="formSheet"
animationType="slide" animationType="slide"
onShow={() => setIsModalReady(true)}
onRequestClose={() => ref.current?.onPressCancel()}> onRequestClose={() => ref.current?.onPressCancel()}>
<View style={[t.atoms.bg, a.flex_1]}> <View style={[t.atoms.bg, a.flex_1]}>
<Providers open={open}> <Providers open={open}>
<ComposePost <ComposePost
isModalReady={isModalReady}
cancelRef={ref} cancelRef={ref}
replyTo={state?.replyTo} replyTo={state?.replyTo}
onPost={state?.onPost} onPost={state?.onPost}

View File

@ -56,6 +56,7 @@ export function Composer({}: {winHeight: number}) {
t.atoms.border_contrast_medium, t.atoms.border_contrast_medium,
]}> ]}>
<ComposePost <ComposePost
isModalReady={true}
replyTo={state.replyTo} replyTo={state.replyTo}
quote={state.quote} quote={state.quote}
onPost={state.onPost} onPost={state.onPost}