Bluesky app fork with some witchin' additions ๐Ÿ’ซ

[๐Ÿด] Move `KeyboardAvoidingView` up to the main screen (#3953)

authored by hailey.at and committed by

GitHub 54c4baac e729647c

+42 -44
+4 -17
src/screens/Messages/Conversation/MessagesList.tsx
··· 1 1 import React, {useCallback, useRef} from 'react' 2 2 import {FlatList, View} from 'react-native' 3 - import { 4 - KeyboardAvoidingView, 5 - useKeyboardHandler, 6 - } from 'react-native-keyboard-controller' 3 + import {useKeyboardHandler} from 'react-native-keyboard-controller' 7 4 import {runOnJS, useSharedValue} from 'react-native-reanimated' 8 5 import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/reanimated2/hook/commonTypes' 9 - import {useSafeAreaInsets} from 'react-native-safe-area-context' 10 6 import {AppBskyRichtextFacet, RichText} from '@atproto/api' 11 7 12 8 import {shortenLinks} from '#/lib/strings/rich-text-manip' 13 - import {isIOS, isNative} from '#/platform/detection' 9 + import {isNative} from '#/platform/detection' 14 10 import {useConvo} from '#/state/messages/convo' 15 11 import {ConvoItem, ConvoStatus} from '#/state/messages/convo/types' 16 12 import {useAgent} from '#/state/session' ··· 19 15 import {List} from 'view/com/util/List' 20 16 import {MessageInput} from '#/screens/Messages/Conversation/MessageInput' 21 17 import {MessageListError} from '#/screens/Messages/Conversation/MessageListError' 22 - import {atoms as a, useBreakpoints} from '#/alf' 23 18 import {MessageItem} from '#/components/dms/MessageItem' 24 19 import {Loader} from '#/components/Loader' 25 20 import {Text} from '#/components/Typography' ··· 199 194 }) 200 195 }, [isMomentumScrolling]) 201 196 202 - const {bottom: bottomInset, top: topInset} = useSafeAreaInsets() 203 - const {gtMobile} = useBreakpoints() 204 - const bottomBarHeight = gtMobile ? 0 : isIOS ? 40 : 60 205 - 206 197 // This is only used inside the useKeyboardHandler because the worklet won't work with a ref directly. 207 198 const scrollToEndNow = React.useCallback(() => { 208 199 flatListRef.current?.scrollToEnd({animated: false}) ··· 216 207 }) 217 208 218 209 return ( 219 - <KeyboardAvoidingView 220 - style={[a.flex_1, {marginBottom: bottomInset + bottomBarHeight}]} 221 - keyboardVerticalOffset={isIOS ? topInset : 0} 222 - behavior="padding" 223 - contentContainerStyle={a.flex_1}> 210 + <> 224 211 {/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */} 225 212 <ScrollProvider onScroll={onScroll} onMomentumEnd={onMomentumEnd}> 226 213 <List ··· 252 239 /> 253 240 </ScrollProvider> 254 241 <MessageInput onSendMessage={onSendMessage} scrollToEnd={scrollToEnd} /> 255 - </KeyboardAvoidingView> 242 + </> 256 243 ) 257 244 }
+38 -27
src/screens/Messages/Conversation/index.tsx
··· 1 1 import React, {useCallback} from 'react' 2 2 import {TouchableOpacity, View} from 'react-native' 3 3 import {KeyboardProvider} from 'react-native-keyboard-controller' 4 + import {KeyboardAvoidingView} from 'react-native-keyboard-controller' 5 + import {useSafeAreaInsets} from 'react-native-safe-area-context' 4 6 import {AppBskyActorDefs} from '@atproto/api' 5 7 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 6 8 import {msg} from '@lingui/macro' ··· 12 14 import {useGate} from '#/lib/statsig/statsig' 13 15 import {useCurrentConvoId} from '#/state/messages/current-convo-id' 14 16 import {BACK_HITSLOP} from 'lib/constants' 15 - import {isWeb} from 'platform/detection' 17 + import {isIOS, isWeb} from 'platform/detection' 16 18 import {ConvoProvider, useConvo} from 'state/messages/convo' 17 19 import {ConvoStatus} from 'state/messages/convo/types' 18 20 import {PreviewableUserAvatar} from 'view/com/util/UserAvatar' ··· 25 27 import {Loader} from '#/components/Loader' 26 28 import {Text} from '#/components/Typography' 27 29 import {ClipClopGate} from '../gate' 28 - 29 30 type Props = NativeStackScreenProps< 30 31 CommonNavigatorParams, 31 32 'MessagesConversation' ··· 59 60 const {_} = useLingui() 60 61 61 62 const [hasInitiallyRendered, setHasInitiallyRendered] = React.useState(false) 63 + 64 + const {bottom: bottomInset, top: topInset} = useSafeAreaInsets() 65 + const {gtMobile} = useBreakpoints() 66 + const bottomBarHeight = gtMobile ? 0 : isIOS ? 40 : 60 62 67 63 68 // HACK: Because we need to scroll to the bottom of the list once initial items are added to the list, we also have 64 69 // to take into account that scrolling to the end of the list on native will happen asynchronously. This will cause ··· 95 100 96 101 return ( 97 102 <KeyboardProvider> 98 - <CenteredView style={a.flex_1} sideBorders> 99 - <Header profile={convo.recipients?.[0]} /> 100 - <View style={[a.flex_1]}> 101 - {convo.status !== ConvoStatus.Ready ? ( 102 - <ListMaybePlaceholder isLoading /> 103 - ) : ( 104 - <MessagesList /> 105 - )} 106 - {!hasInitiallyRendered && ( 107 - <View 108 - style={[ 109 - a.absolute, 110 - a.z_10, 111 - a.w_full, 112 - a.h_full, 113 - a.justify_center, 114 - a.align_center, 115 - t.atoms.bg, 116 - ]}> 117 - <View style={[{marginBottom: 75}]}> 118 - <Loader size="xl" /> 103 + <KeyboardAvoidingView 104 + style={[a.flex_1, {marginBottom: bottomInset + bottomBarHeight}]} 105 + keyboardVerticalOffset={isIOS ? topInset : 0} 106 + behavior="padding" 107 + contentContainerStyle={a.flex_1}> 108 + <CenteredView style={a.flex_1} sideBorders> 109 + <Header profile={convo.recipients?.[0]} /> 110 + <View style={[a.flex_1]}> 111 + {convo.status !== ConvoStatus.Ready ? ( 112 + <ListMaybePlaceholder isLoading /> 113 + ) : ( 114 + <MessagesList /> 115 + )} 116 + {!hasInitiallyRendered && ( 117 + <View 118 + style={[ 119 + a.absolute, 120 + a.z_10, 121 + a.w_full, 122 + a.h_full, 123 + a.justify_center, 124 + a.align_center, 125 + t.atoms.bg, 126 + ]}> 127 + <View style={[{marginBottom: 75}]}> 128 + <Loader size="xl" /> 129 + </View> 119 130 </View> 120 - </View> 121 - )} 122 - </View> 123 - </CenteredView> 131 + )} 132 + </View> 133 + </CenteredView> 134 + </KeyboardAvoidingView> 124 135 </KeyboardProvider> 125 136 ) 126 137 }