Fix 1405 handle android back button in composer (#1446)

* handle android back button in composer

* improve backHandler error handling

* simplify composer onClose functionality
zio/stable
Ansh 2023-09-29 10:49:59 +07:00 committed by GitHub
parent 1f60e1a748
commit 04fda0f142
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 17 deletions

View File

@ -1,8 +1,19 @@
import {isAndroid} from 'platform/detection'
import {BackHandler} from 'react-native' import {BackHandler} from 'react-native'
import {RootStoreModel} from 'state/index' import {RootStoreModel} from 'state/index'
export function init(store: RootStoreModel) { export function init(store: RootStoreModel) {
BackHandler.addEventListener('hardwareBackPress', () => { // only register back handler on android, otherwise it throws an error
if (isAndroid) {
const backHandler = BackHandler.addEventListener(
'hardwareBackPress',
() => {
return store.shell.closeAnyActiveElement() return store.shell.closeAnyActiveElement()
}) },
)
return () => {
backHandler.remove()
}
}
return () => {}
} }

View File

@ -2,6 +2,7 @@ import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import { import {
ActivityIndicator, ActivityIndicator,
BackHandler,
Keyboard, Keyboard,
KeyboardAvoidingView, KeyboardAvoidingView,
Platform, Platform,
@ -49,14 +50,10 @@ import {SelectLangBtn} from './select-language/SelectLangBtn'
import {EmojiPickerButton} from './text-input/web/EmojiPicker.web' import {EmojiPickerButton} from './text-input/web/EmojiPicker.web'
import {insertMentionAt} from 'lib/strings/mention-manip' import {insertMentionAt} from 'lib/strings/mention-manip'
type Props = ComposerOpts & { type Props = ComposerOpts
onClose: () => void
}
export const ComposePost = observer(function ComposePost({ export const ComposePost = observer(function ComposePost({
replyTo, replyTo,
onPost, onPost,
onClose,
quote: initQuote, quote: initQuote,
mention: initMention, mention: initMention,
}: Props) { }: Props) {
@ -90,6 +87,9 @@ export const ComposePost = observer(function ComposePost({
const [labels, setLabels] = useState<string[]>([]) const [labels, setLabels] = useState<string[]>([])
const [suggestedLinks, setSuggestedLinks] = useState<Set<string>>(new Set()) const [suggestedLinks, setSuggestedLinks] = useState<Set<string>>(new Set())
const gallery = useMemo(() => new GalleryModel(store), [store]) const gallery = useMemo(() => new GalleryModel(store), [store])
const onClose = useCallback(() => {
store.shell.closeComposer()
}, [store])
const autocompleteView = useMemo<UserAutocompleteModel>( const autocompleteView = useMemo<UserAutocompleteModel>(
() => new UserAutocompleteModel(store), () => new UserAutocompleteModel(store),
@ -129,6 +129,20 @@ export const ComposePost = observer(function ComposePost({
onClose() onClose()
} }
}, [store, onClose, graphemeLength, gallery]) }, [store, onClose, graphemeLength, gallery])
// android back button
useEffect(() => {
const backHandler = BackHandler.addEventListener(
'hardwareBackPress',
() => {
onPressCancel()
return true
},
)
return () => {
backHandler.remove()
}
}, [onPressCancel])
// initial setup // initial setup
useEffect(() => { useEffect(() => {

View File

@ -11,7 +11,6 @@ export const Composer = observer(function ComposerImpl({
winHeight, winHeight,
replyTo, replyTo,
onPost, onPost,
onClose,
quote, quote,
mention, mention,
}: { }: {
@ -19,7 +18,6 @@ export const Composer = observer(function ComposerImpl({
winHeight: number winHeight: number
replyTo?: ComposerOpts['replyTo'] replyTo?: ComposerOpts['replyTo']
onPost?: ComposerOpts['onPost'] onPost?: ComposerOpts['onPost']
onClose: () => void
quote?: ComposerOpts['quote'] quote?: ComposerOpts['quote']
mention?: ComposerOpts['mention'] mention?: ComposerOpts['mention']
}) { }) {
@ -64,7 +62,6 @@ export const Composer = observer(function ComposerImpl({
<ComposePost <ComposePost
replyTo={replyTo} replyTo={replyTo}
onPost={onPost} onPost={onPost}
onClose={onClose}
quote={quote} quote={quote}
mention={mention} mention={mention}
/> />

View File

@ -13,7 +13,6 @@ export const Composer = observer(function ComposerImpl({
replyTo, replyTo,
quote, quote,
onPost, onPost,
onClose,
mention, mention,
}: { }: {
active: boolean active: boolean
@ -21,7 +20,6 @@ export const Composer = observer(function ComposerImpl({
replyTo?: ComposerOpts['replyTo'] replyTo?: ComposerOpts['replyTo']
quote: ComposerOpts['quote'] quote: ComposerOpts['quote']
onPost?: ComposerOpts['onPost'] onPost?: ComposerOpts['onPost']
onClose: () => void
mention?: ComposerOpts['mention'] mention?: ComposerOpts['mention']
}) { }) {
const pal = usePalette('default') const pal = usePalette('default')
@ -47,7 +45,6 @@ export const Composer = observer(function ComposerImpl({
replyTo={replyTo} replyTo={replyTo}
quote={quote} quote={quote}
onPost={onPost} onPost={onPost}
onClose={onClose}
mention={mention} mention={mention}
/> />
</View> </View>

View File

@ -44,7 +44,10 @@ const ShellInner = observer(function ShellInnerImpl() {
) )
const canGoBack = useNavigationState(state => !isStateAtTabRoot(state)) const canGoBack = useNavigationState(state => !isStateAtTabRoot(state))
React.useEffect(() => { React.useEffect(() => {
backHandler.init(store) const listener = backHandler.init(store)
return () => {
listener()
}
}, [store]) }, [store])
return ( return (
@ -68,7 +71,6 @@ const ShellInner = observer(function ShellInnerImpl() {
</View> </View>
<Composer <Composer
active={store.shell.isComposerActive} active={store.shell.isComposerActive}
onClose={() => store.shell.closeComposer()}
winHeight={winDim.height} winHeight={winDim.height}
replyTo={store.shell.composerOpts?.replyTo} replyTo={store.shell.composerOpts?.replyTo}
onPost={store.shell.composerOpts?.onPost} onPost={store.shell.composerOpts?.onPost}

View File

@ -48,7 +48,6 @@ const ShellInner = observer(function ShellInnerImpl() {
)} )}
<Composer <Composer
active={store.shell.isComposerActive} active={store.shell.isComposerActive}
onClose={() => store.shell.closeComposer()}
winHeight={0} winHeight={0}
replyTo={store.shell.composerOpts?.replyTo} replyTo={store.shell.composerOpts?.replyTo}
quote={store.shell.composerOpts?.quote} quote={store.shell.composerOpts?.quote}