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 for: mWeb/Chrome - Payment - The keyboard overlaps the "Make default payment method" button #14725

Merged
merged 15 commits into from
Feb 9, 2023
Merged
21 changes: 0 additions & 21 deletions src/components/KeyboardSpacer/index.android.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/KeyboardSpacer/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* On non native platforms we do not need to implement a keyboard spacer, so we return a null component.
* On non iOS platforms we do not need to implement a keyboard spacer, so we return a null component.
*
* @returns {null}
* @constructor
Expand Down
2 changes: 1 addition & 1 deletion src/components/Modal/BaseModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class BaseModal extends PureComponent {
backdropOpacity={hideBackdrop ? 0 : variables.overlayOpacity}
backdropTransitionOutTiming={0}
hasBackdrop={this.props.fullscreen}
coverScreen={this.props.fullscreen}
coverScreen={this.props.disableCoverScreen ? false : this.props.fullscreen}
style={modalStyle}
deviceHeight={this.props.windowHeight}
deviceWidth={this.props.windowWidth}
Expand Down
1 change: 1 addition & 0 deletions src/components/PasswordPopover/BasePasswordPopover.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class BasePasswordPopover extends Component {
render() {
return (
<Popover
disableCoverScreen={this.props.disableCoverScreen}
isVisible={this.props.isVisible}
onClose={this.props.onClose}
anchorPosition={this.props.anchorPosition}
Expand Down
69 changes: 69 additions & 0 deletions src/components/withViewportOffsetTop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import lodashGet from 'lodash/get';
import getComponentDisplayName from '../libs/getComponentDisplayName';
import addViewportResizeListener from '../libs/VisualViewport';

const viewportOffsetTopPropTypes = {
viewportOffsetTop: PropTypes.number.isRequired,
jasperhuangg marked this conversation as resolved.
Show resolved Hide resolved
};

export default function (WrappedComponent) {
class WithViewportOffsetTop extends Component {
constructor(props) {
super(props);

this.updateDimensions = this.updateDimensions.bind(this);

this.state = {
viewportOffsetTop: 0,
};
}

componentDidMount() {
this.removeViewportResizeListener = addViewportResizeListener(this.updateDimensions);
}

componentWillUnmount() {
this.removeViewportResizeListener();
}

/**
* @param {SyntheticEvent} e
*/
updateDimensions(e) {
const viewportOffsetTop = lodashGet(e, 'target.offsetTop', 0);
this.setState({viewportOffsetTop});
}

render() {
return (
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...this.props}
ref={this.props.forwardedRef}
viewportOffsetTop={this.state.viewportOffsetTop}
/>
);
}
}

WithViewportOffsetTop.displayName = `WithViewportOffsetTop(${getComponentDisplayName(WrappedComponent)})`;
WithViewportOffsetTop.propTypes = {
forwardedRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({current: PropTypes.instanceOf(React.Component)}),
]),
};
WithViewportOffsetTop.defaultProps = {
forwardedRef: undefined,
};
return React.forwardRef((props, ref) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<WithViewportOffsetTop {...props} forwardedRef={ref} />
));
}

export {
viewportOffsetTopPropTypes,
};
22 changes: 4 additions & 18 deletions src/pages/home/ReportScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import CONST from '../../CONST';
import ReportActionsSkeletonView from '../../components/ReportActionsSkeletonView';
import reportActionPropTypes from './report/reportActionPropTypes';
import toggleReportActionComposeView from '../../libs/toggleReportActionComposeView';
import addViewportResizeListener from '../../libs/VisualViewport';
import {withNetwork} from '../../components/OnyxProvider';
import compose from '../../libs/compose';
import networkPropTypes from '../../components/networkPropTypes';
Expand All @@ -33,6 +32,7 @@ import withLocalize from '../../components/withLocalize';
import reportPropTypes from '../reportPropTypes';
import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView';
import ReportHeaderSkeletonView from '../../components/ReportHeaderSkeletonView';
import withViewportOffsetTop, {viewportOffsetTopPropTypes} from '../../components/withViewportOffsetTop';

const propTypes = {
/** Navigation route context info provided by react navigation */
Expand Down Expand Up @@ -73,6 +73,7 @@ const propTypes = {

...windowDimensionsPropTypes,
...withDrawerPropTypes,
...viewportOffsetTopPropTypes,
};

const defaultProps = {
Expand Down Expand Up @@ -107,22 +108,18 @@ class ReportScreen extends React.Component {
super(props);

this.onSubmitComment = this.onSubmitComment.bind(this);
this.updateViewportOffsetTop = this.updateViewportOffsetTop.bind(this);
this.chatWithAccountManager = this.chatWithAccountManager.bind(this);
this.dismissBanner = this.dismissBanner.bind(this);
this.removeViewportResizeListener = () => {};

this.state = {
skeletonViewContainerHeight: reportActionsListViewHeight,
viewportOffsetTop: 0,
isBannerVisible: true,
};
}

componentDidMount() {
this.fetchReportIfNeeded();
toggleReportActionComposeView(true);
this.removeViewportResizeListener = addViewportResizeListener(this.updateViewportOffsetTop);
}

componentDidUpdate(prevProps) {
Expand All @@ -134,10 +131,6 @@ class ReportScreen extends React.Component {
toggleReportActionComposeView(true);
}

componentWillUnmount() {
this.removeViewportResizeListener();
}

/**
* @param {String} text
*/
Expand Down Expand Up @@ -171,14 +164,6 @@ class ReportScreen extends React.Component {
Report.openReport(reportIDFromPath);
}

/**
* @param {SyntheticEvent} e
*/
updateViewportOffsetTop(e) {
const viewportOffsetTop = lodashGet(e, 'target.offsetTop', 0);
this.setState({viewportOffsetTop});
}

dismissBanner() {
this.setState({isBannerVisible: false});
}
Expand Down Expand Up @@ -214,7 +199,7 @@ class ReportScreen extends React.Component {
const reportID = getReportID(this.props.route);
const addWorkspaceRoomOrChatPendingAction = lodashGet(this.props.report, 'pendingFields.addWorkspaceRoom') || lodashGet(this.props.report, 'pendingFields.createChat');
const addWorkspaceRoomOrChatErrors = lodashGet(this.props.report, 'errorFields.addWorkspaceRoom') || lodashGet(this.props.report, 'errorFields.createChat');
const screenWrapperStyle = [styles.appContent, styles.flex1, {marginTop: this.state.viewportOffsetTop}];
const screenWrapperStyle = [styles.appContent, styles.flex1, {marginTop: this.props.viewportOffsetTop}];

// There are no reportActions at all to display and we are still in the process of loading the next set of actions.
const isLoadingInitialReportActions = _.isEmpty(this.props.reportActions) && this.props.report.isLoadingReportActions;
Expand Down Expand Up @@ -332,6 +317,7 @@ ReportScreen.propTypes = propTypes;
ReportScreen.defaultProps = defaultProps;

export default compose(
withViewportOffsetTop,
withLocalize,
withWindowDimensions,
withDrawerState,
Expand Down
9 changes: 8 additions & 1 deletion src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import OfflineWithFeedback from '../../../../components/OfflineWithFeedback';
import ConfirmContent from '../../../../components/ConfirmContent';
import Button from '../../../../components/Button';
import themeColors from '../../../../styles/themes/default';
import withViewportOffsetTop from '../../../../components/withViewportOffsetTop';

class BasePaymentsPage extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -341,8 +342,9 @@ class BasePaymentsPage extends React.Component {

// Determines whether or not the modal popup is mounted from the bottom of the screen instead of the side mount on Web or Desktop screens
const isPopoverBottomMount = this.state.anchorPositionTop === 0 || this.props.isSmallScreenWidth;
const screenWrapperStyle = [{marginTop: this.props.viewportOffsetTop}];
return (
<ScreenWrapper>
<ScreenWrapper style={screenWrapperStyle}>
<HeaderWithCloseButton
title={this.props.translate('common.payments')}
shouldShowBackButton
Expand Down Expand Up @@ -478,6 +480,10 @@ class BasePaymentsPage extends React.Component {
)}
</Popover>
<PasswordPopover

// Disable coverScreen to mount the modal within the component
// hierarchy, otherwise it will not resize with screenWrapper.
disableCoverScreen
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add comment what this prop is for

isVisible={this.state.shouldShowPasswordPrompt}
onClose={this.hidePasswordPrompt}
anchorPosition={{
Expand All @@ -499,6 +505,7 @@ BasePaymentsPage.propTypes = propTypes;
BasePaymentsPage.defaultProps = defaultProps;

export default compose(
withViewportOffsetTop,
withWindowDimensions,
withLocalize,
withNetwork(),
Expand Down