Skip to content

Commit cbdc035

Browse files
committed
ChatScreen: Fix blank strip between compose box and keyboard on iOS
Fixes: #3370
1 parent 47b7ead commit cbdc035

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

src/chat/ChatScreen.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,14 @@ export default function ChatScreen(props: Props): Node {
198198
);
199199

200200
return (
201-
<KeyboardAvoider style={[componentStyles.screen, { backgroundColor }]} behavior="padding">
201+
<KeyboardAvoider
202+
style={[componentStyles.screen, { backgroundColor }]}
203+
behavior="padding"
204+
compensateOverpadding={
205+
// We let the compose box pad the bottom inset.
206+
showComposeBox
207+
}
208+
>
202209
<ChatNavBar narrow={narrow} editMessage={editMessage} />
203210
<UnreadNotice narrow={narrow} />
204211
{(() => {

src/common/KeyboardAvoider.js

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import type { Node } from 'react';
44
import { Platform, View } from 'react-native';
55
import type { ViewStyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet';
6+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
67

78
import KeyboardAvoidingView from '../third/react-native/KeyboardAvoidingView';
89

@@ -12,8 +13,9 @@ type Props = $ReadOnly<{|
1213
style?: ViewStyleProp,
1314
contentContainerStyle?: ViewStyleProp,
1415

15-
/** How much the top of `KeyboardAvoider`'s layout *parent* is
16-
* displaced downward from the top of the screen.
16+
/**
17+
* How much the top of `KeyboardAvoider`'s layout *parent* is
18+
* displaced downward from the top of the screen.
1719
*
1820
* If this isn't set correctly, the keyboard will hide some of
1921
* the bottom of the screen (an area whose height is what this
@@ -30,6 +32,19 @@ type Props = $ReadOnly<{|
3032
* we can use to balance the equation if we need to.
3133
*/
3234
keyboardVerticalOffset?: number,
35+
36+
/**
37+
* Whether to shorten the excursion by the height of the bottom inset.
38+
*
39+
* Use this when a child component uses SafeAreaView to pad the bottom
40+
* inset, and you want the open keyboard to cover that padding.
41+
*
42+
* (SafeAreaView has a bug where it applies a constant padding no matter
43+
* where it's positioned onscreen -- so in particular, if you ask for
44+
* bottom padding, you'll get bottom padding even when KeyboardAvoider
45+
* pushes the SafeAreaView up and out of the bottom inset.)
46+
*/
47+
compensateOverpadding?: boolean,
3348
|}>;
3449

3550
/**
@@ -40,7 +55,16 @@ type Props = $ReadOnly<{|
4055
* to that component.
4156
*/
4257
export default function KeyboardAvoider(props: Props): Node {
43-
const { behavior, children, style, contentContainerStyle, keyboardVerticalOffset } = props;
58+
const {
59+
behavior,
60+
children,
61+
style,
62+
contentContainerStyle,
63+
keyboardVerticalOffset = 0, // Same default value as KeyboardAvoidingView
64+
compensateOverpadding = false,
65+
} = props;
66+
67+
const bottomInsetHeight = useSafeAreaInsets().bottom;
4468

4569
if (Platform.OS === 'android') {
4670
return <View style={style}>{children}</View>;
@@ -51,7 +75,13 @@ export default function KeyboardAvoider(props: Props): Node {
5175
behavior={behavior}
5276
contentContainerStyle={contentContainerStyle}
5377
// See comment on this prop in the jsdoc.
54-
keyboardVerticalOffset={keyboardVerticalOffset}
78+
keyboardVerticalOffset={
79+
keyboardVerticalOffset
80+
// A negative term here reduces the bottom inset we use for the
81+
// child, when the keyboard is open, so that the keyboard covers its
82+
// bottom padding.
83+
+ (compensateOverpadding ? -bottomInsetHeight : 0)
84+
}
5585
style={style}
5686
>
5787
{children}

src/compose/ComposeBox.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,8 @@ const ComposeBox: React$AbstractComponent<Props, ImperativeHandle> = forwardRef(
729729
</View>
730730
<SafeAreaView
731731
mode="padding"
732+
// When the keyboard is open, this bottom padding is compensated
733+
// for: we pass KeyboardAvoider's compensateOverpadding prop.
732734
edges={['bottom']}
733735
style={styles.composeBox}
734736
onLayout={handleLayoutChange}

0 commit comments

Comments
 (0)