Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 17866: After pressing the back arrow to "Send/Request money" screen, the keyboard flashes #30065

Merged
merged 9 commits into from
Nov 1, 2023
6 changes: 5 additions & 1 deletion src/components/ScreenWrapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import OfflineIndicator from '@components/OfflineIndicator';
import SafeAreaConsumer from '@components/SafeAreaConsumer';
import TestToolsModal from '@components/TestToolsModal';
import useEnvironment from '@hooks/useEnvironment';
import useInitialDimensions from '@hooks/useInitialWindowDimensions';
import useKeyboardState from '@hooks/useKeyboardState';
import useNetwork from '@hooks/useNetwork';
import useWindowDimensions from '@hooks/useWindowDimensions';
Expand All @@ -22,6 +23,7 @@ import {defaultProps, propTypes} from './propTypes';

function ScreenWrapper({
shouldEnableMaxHeight,
shouldEnableMinHeight,
sarious marked this conversation as resolved.
Show resolved Hide resolved
includePaddingTop,
keyboardAvoidingViewBehavior,
includeSafeAreaPaddingBottom,
Expand All @@ -37,12 +39,14 @@ function ScreenWrapper({
testID,
}) {
const {windowHeight, isSmallScreenWidth} = useWindowDimensions();
const {initialHeight} = useInitialDimensions();
const keyboardState = useKeyboardState();
const {isDevelopment} = useEnvironment();
const {isOffline} = useNetwork();
const navigation = useNavigation();
const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false);
const maxHeight = shouldEnableMaxHeight ? windowHeight : undefined;
const minHeight = shouldEnableMinHeight ? initialHeight : undefined;
const isKeyboardShown = lodashGet(keyboardState, 'isKeyboardShown', false);

const panResponder = useRef(
Expand Down Expand Up @@ -125,7 +129,7 @@ function ScreenWrapper({
{...keyboardDissmissPanResponder.panHandlers}
>
<KeyboardAvoidingView
style={[styles.w100, styles.h100, {maxHeight}]}
style={[styles.w100, styles.h100, {maxHeight, minHeight}]}
sarious marked this conversation as resolved.
Show resolved Hide resolved
behavior={keyboardAvoidingViewBehavior}
enabled={shouldEnableKeyboardAvoidingView}
>
Expand Down
3 changes: 3 additions & 0 deletions src/components/ScreenWrapper/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const propTypes = {
/** Whether to use the maxHeight (true) or use the 100% of the height (false) */
shouldEnableMaxHeight: PropTypes.bool,

/** Whether to use the minHeight. Use true for screens where the window height are changing because of Virtual Keyboard */
shouldEnableMinHeight: PropTypes.bool,

/** Array of additional styles for header gap */
headerGapStyles: PropTypes.arrayOf(PropTypes.object),

Expand Down
59 changes: 59 additions & 0 deletions src/hooks/useInitialWindowDimensions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// eslint-disable-next-line no-restricted-imports
import {useEffect, useState} from 'react';
import {Dimensions} from 'react-native';
import {initialWindowMetrics} from 'react-native-safe-area-context';

/**
* A convenience hook that provides initial size (width and height).
* An initial height allows to know the real height of window,
* while the standard useWindowDimensions hook return the height minus Virtual keyboard height
* @returns {Object} with information about initial width and height
*/
export default function () {
const [dimensions, setDimensions] = useState(() => {
const window = Dimensions.get('window');
const screen = Dimensions.get('screen');

return {
screenHeight: screen.height,
screenWidth: screen.width,
initialHeight: window.height,
initialWidth: window.width,
};
});

useEffect(() => {
const onDimensionChange = (newDimensions) => {
const {window, screen} = newDimensions;

setDimensions((oldState) => {
if (screen.width !== oldState.screenWidth || screen.height !== oldState.screenHeight || window.height > oldState.initialHeight) {
return {
initialHeight: window.height,
initialWidth: window.width,
screenHeight: screen.height,
screenWidth: screen.width,
};
}

return oldState;
});
};

const dimensionsEventListener = Dimensions.addEventListener('change', onDimensionChange);

return () => {
if (!dimensionsEventListener) {
return;
}
dimensionsEventListener.remove();
};
}, []);

const bottomInset = initialWindowMetrics && initialWindowMetrics.insets && initialWindowMetrics.insets.bottom ? initialWindowMetrics.insets.bottom : 0;

return {
initialWidth: dimensions.initialWidth,
initialHeight: dimensions.initialHeight - bottomInset,
sarious marked this conversation as resolved.
Show resolved Hide resolved
};
}
2 changes: 2 additions & 0 deletions src/pages/EditRequestAmountPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {useCallback, useRef} from 'react';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import useLocalize from '@hooks/useLocalize';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import CONST from '@src/CONST';
import MoneyRequestAmountForm from './iou/steps/MoneyRequestAmountForm';

Expand Down Expand Up @@ -43,6 +44,7 @@ function EditRequestAmountPage({defaultAmount, defaultCurrency, onNavigateToCurr
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
shouldEnableMaxHeight
shouldEnableMinHeight={DeviceCapabilities.canUseTouchScreen()}
testID={EditRequestAmountPage.displayName}
>
<HeaderWithBackButton title={translate('iou.amount')} />
Expand Down
2 changes: 2 additions & 0 deletions src/pages/iou/MoneyRequestSelectorPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import TabSelector from '@components/TabSelector/TabSelector';
import useLocalize from '@hooks/useLocalize';
import usePrevious from '@hooks/usePrevious';
import compose from '@libs/compose';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import * as IOUUtils from '@libs/IOUUtils';
import Navigation from '@libs/Navigation/Navigation';
import OnyxTabNavigator, {TopTab} from '@libs/Navigation/OnyxTabNavigator';
Expand Down Expand Up @@ -94,6 +95,7 @@ function MoneyRequestSelectorPage(props) {
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
shouldEnableKeyboardAvoidingView={false}
shouldEnableMinHeight={DeviceCapabilities.canUseTouchScreen()}
sarious marked this conversation as resolved.
Show resolved Hide resolved
headerGapStyles={isDraggingOver ? [styles.receiptDropHeaderGap] : []}
testID={MoneyRequestSelectorPage.displayName}
>
Expand Down
Loading