[🐴] Move `KeyboardAvoidingView` up to the main screen (#3953)
parent
e729647c02
commit
54c4baacb6
|
@ -1,16 +1,12 @@
|
||||||
import React, {useCallback, useRef} from 'react'
|
import React, {useCallback, useRef} from 'react'
|
||||||
import {FlatList, View} from 'react-native'
|
import {FlatList, View} from 'react-native'
|
||||||
import {
|
import {useKeyboardHandler} from 'react-native-keyboard-controller'
|
||||||
KeyboardAvoidingView,
|
|
||||||
useKeyboardHandler,
|
|
||||||
} from 'react-native-keyboard-controller'
|
|
||||||
import {runOnJS, useSharedValue} from 'react-native-reanimated'
|
import {runOnJS, useSharedValue} from 'react-native-reanimated'
|
||||||
import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/reanimated2/hook/commonTypes'
|
import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/reanimated2/hook/commonTypes'
|
||||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
|
||||||
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
|
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
|
||||||
|
|
||||||
import {shortenLinks} from '#/lib/strings/rich-text-manip'
|
import {shortenLinks} from '#/lib/strings/rich-text-manip'
|
||||||
import {isIOS, isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {useConvo} from '#/state/messages/convo'
|
import {useConvo} from '#/state/messages/convo'
|
||||||
import {ConvoItem, ConvoStatus} from '#/state/messages/convo/types'
|
import {ConvoItem, ConvoStatus} from '#/state/messages/convo/types'
|
||||||
import {useAgent} from '#/state/session'
|
import {useAgent} from '#/state/session'
|
||||||
|
@ -19,7 +15,6 @@ import {isWeb} from 'platform/detection'
|
||||||
import {List} from 'view/com/util/List'
|
import {List} from 'view/com/util/List'
|
||||||
import {MessageInput} from '#/screens/Messages/Conversation/MessageInput'
|
import {MessageInput} from '#/screens/Messages/Conversation/MessageInput'
|
||||||
import {MessageListError} from '#/screens/Messages/Conversation/MessageListError'
|
import {MessageListError} from '#/screens/Messages/Conversation/MessageListError'
|
||||||
import {atoms as a, useBreakpoints} from '#/alf'
|
|
||||||
import {MessageItem} from '#/components/dms/MessageItem'
|
import {MessageItem} from '#/components/dms/MessageItem'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
@ -199,10 +194,6 @@ export function MessagesList() {
|
||||||
})
|
})
|
||||||
}, [isMomentumScrolling])
|
}, [isMomentumScrolling])
|
||||||
|
|
||||||
const {bottom: bottomInset, top: topInset} = useSafeAreaInsets()
|
|
||||||
const {gtMobile} = useBreakpoints()
|
|
||||||
const bottomBarHeight = gtMobile ? 0 : isIOS ? 40 : 60
|
|
||||||
|
|
||||||
// This is only used inside the useKeyboardHandler because the worklet won't work with a ref directly.
|
// This is only used inside the useKeyboardHandler because the worklet won't work with a ref directly.
|
||||||
const scrollToEndNow = React.useCallback(() => {
|
const scrollToEndNow = React.useCallback(() => {
|
||||||
flatListRef.current?.scrollToEnd({animated: false})
|
flatListRef.current?.scrollToEnd({animated: false})
|
||||||
|
@ -216,11 +207,7 @@ export function MessagesList() {
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardAvoidingView
|
<>
|
||||||
style={[a.flex_1, {marginBottom: bottomInset + bottomBarHeight}]}
|
|
||||||
keyboardVerticalOffset={isIOS ? topInset : 0}
|
|
||||||
behavior="padding"
|
|
||||||
contentContainerStyle={a.flex_1}>
|
|
||||||
{/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */}
|
{/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */}
|
||||||
<ScrollProvider onScroll={onScroll} onMomentumEnd={onMomentumEnd}>
|
<ScrollProvider onScroll={onScroll} onMomentumEnd={onMomentumEnd}>
|
||||||
<List
|
<List
|
||||||
|
@ -252,6 +239,6 @@ export function MessagesList() {
|
||||||
/>
|
/>
|
||||||
</ScrollProvider>
|
</ScrollProvider>
|
||||||
<MessageInput onSendMessage={onSendMessage} scrollToEnd={scrollToEnd} />
|
<MessageInput onSendMessage={onSendMessage} scrollToEnd={scrollToEnd} />
|
||||||
</KeyboardAvoidingView>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import React, {useCallback} from 'react'
|
import React, {useCallback} from 'react'
|
||||||
import {TouchableOpacity, View} from 'react-native'
|
import {TouchableOpacity, View} from 'react-native'
|
||||||
import {KeyboardProvider} from 'react-native-keyboard-controller'
|
import {KeyboardProvider} from 'react-native-keyboard-controller'
|
||||||
|
import {KeyboardAvoidingView} from 'react-native-keyboard-controller'
|
||||||
|
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
import {AppBskyActorDefs} from '@atproto/api'
|
import {AppBskyActorDefs} from '@atproto/api'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
|
@ -12,7 +14,7 @@ import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
||||||
import {useGate} from '#/lib/statsig/statsig'
|
import {useGate} from '#/lib/statsig/statsig'
|
||||||
import {useCurrentConvoId} from '#/state/messages/current-convo-id'
|
import {useCurrentConvoId} from '#/state/messages/current-convo-id'
|
||||||
import {BACK_HITSLOP} from 'lib/constants'
|
import {BACK_HITSLOP} from 'lib/constants'
|
||||||
import {isWeb} from 'platform/detection'
|
import {isIOS, isWeb} from 'platform/detection'
|
||||||
import {ConvoProvider, useConvo} from 'state/messages/convo'
|
import {ConvoProvider, useConvo} from 'state/messages/convo'
|
||||||
import {ConvoStatus} from 'state/messages/convo/types'
|
import {ConvoStatus} from 'state/messages/convo/types'
|
||||||
import {PreviewableUserAvatar} from 'view/com/util/UserAvatar'
|
import {PreviewableUserAvatar} from 'view/com/util/UserAvatar'
|
||||||
|
@ -25,7 +27,6 @@ import {ListMaybePlaceholder} from '#/components/Lists'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {ClipClopGate} from '../gate'
|
import {ClipClopGate} from '../gate'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<
|
type Props = NativeStackScreenProps<
|
||||||
CommonNavigatorParams,
|
CommonNavigatorParams,
|
||||||
'MessagesConversation'
|
'MessagesConversation'
|
||||||
|
@ -60,6 +61,10 @@ function Inner() {
|
||||||
|
|
||||||
const [hasInitiallyRendered, setHasInitiallyRendered] = React.useState(false)
|
const [hasInitiallyRendered, setHasInitiallyRendered] = React.useState(false)
|
||||||
|
|
||||||
|
const {bottom: bottomInset, top: topInset} = useSafeAreaInsets()
|
||||||
|
const {gtMobile} = useBreakpoints()
|
||||||
|
const bottomBarHeight = gtMobile ? 0 : isIOS ? 40 : 60
|
||||||
|
|
||||||
// HACK: Because we need to scroll to the bottom of the list once initial items are added to the list, we also have
|
// HACK: Because we need to scroll to the bottom of the list once initial items are added to the list, we also have
|
||||||
// to take into account that scrolling to the end of the list on native will happen asynchronously. This will cause
|
// to take into account that scrolling to the end of the list on native will happen asynchronously. This will cause
|
||||||
// a little flicker when the items are first renedered at the top and immediately scrolled to the bottom. to prevent
|
// a little flicker when the items are first renedered at the top and immediately scrolled to the bottom. to prevent
|
||||||
|
@ -95,6 +100,11 @@ function Inner() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardProvider>
|
<KeyboardProvider>
|
||||||
|
<KeyboardAvoidingView
|
||||||
|
style={[a.flex_1, {marginBottom: bottomInset + bottomBarHeight}]}
|
||||||
|
keyboardVerticalOffset={isIOS ? topInset : 0}
|
||||||
|
behavior="padding"
|
||||||
|
contentContainerStyle={a.flex_1}>
|
||||||
<CenteredView style={a.flex_1} sideBorders>
|
<CenteredView style={a.flex_1} sideBorders>
|
||||||
<Header profile={convo.recipients?.[0]} />
|
<Header profile={convo.recipients?.[0]} />
|
||||||
<View style={[a.flex_1]}>
|
<View style={[a.flex_1]}>
|
||||||
|
@ -121,6 +131,7 @@ function Inner() {
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</CenteredView>
|
</CenteredView>
|
||||||
|
</KeyboardAvoidingView>
|
||||||
</KeyboardProvider>
|
</KeyboardProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue