diff --git a/src/CONST.js b/src/CONST.js
index b981c6e92624..63a705738b34 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -477,6 +477,7 @@ const CONST = {
EMOJI_PICKER_ITEM_HEIGHT: 40,
EMOJI_PICKER_HEADER_HEIGHT: 38,
COMPOSER_MAX_HEIGHT: 125,
+ CHAT_FOOTER_MIN_HEIGHT: 65,
CHAT_SKELETON_VIEW: {
AVERAGE_ROW_HEIGHT: 80,
HEIGHT_FOR_ROW_COUNT: {
diff --git a/src/components/ScreenWrapper.js b/src/components/ScreenWrapper.js
deleted file mode 100644
index bc6a416dbd01..000000000000
--- a/src/components/ScreenWrapper.js
+++ /dev/null
@@ -1,147 +0,0 @@
-import _ from 'underscore';
-import React from 'react';
-import PropTypes from 'prop-types';
-import {View} from 'react-native';
-import {SafeAreaInsetsContext} from 'react-native-safe-area-context';
-import {withOnyx} from 'react-native-onyx';
-import styles from '../styles/styles';
-import * as StyleUtils from '../styles/StyleUtils';
-import HeaderGap from './HeaderGap';
-import KeyboardShortcutsModal from './KeyboardShortcutsModal';
-import KeyboardShortcut from '../libs/KeyboardShortcut';
-import onScreenTransitionEnd from '../libs/onScreenTransitionEnd';
-import Navigation from '../libs/Navigation/Navigation';
-import compose from '../libs/compose';
-import ONYXKEYS from '../ONYXKEYS';
-import CONST from '../CONST';
-import withNavigation from './withNavigation';
-
-const propTypes = {
- /** Array of additional styles to add */
- style: PropTypes.arrayOf(PropTypes.object),
-
- /** Returns a function as a child to pass insets to or a node to render without insets */
- children: PropTypes.oneOfType([
- PropTypes.node,
- PropTypes.func,
- ]).isRequired,
-
- /** Whether to include padding bottom */
- includePaddingBottom: PropTypes.bool,
-
- /** Whether to include padding top */
- includePaddingTop: PropTypes.bool,
-
- // Called when navigated Screen's transition is finished.
- onTransitionEnd: PropTypes.func,
-
- // react-navigation navigation object available to screen components
- navigation: PropTypes.shape({
- // Method to attach listener to Navigation state.
- addListener: PropTypes.func.isRequired,
- }),
-
- /** Details about any modals being used */
- modal: PropTypes.shape({
- /** Indicates when an Alert modal is about to be visible */
- willAlertModalBecomeVisible: PropTypes.bool,
- }),
-
-};
-
-const defaultProps = {
- style: [],
- includePaddingBottom: true,
- includePaddingTop: true,
- onTransitionEnd: () => {},
- navigation: {
- addListener: () => {},
- },
- modal: {},
-};
-
-class ScreenWrapper extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {
- didScreenTransitionEnd: false,
- };
- }
-
- componentDidMount() {
- const shortcutConfig = CONST.KEYBOARD_SHORTCUTS.ESCAPE;
- this.unsubscribeEscapeKey = KeyboardShortcut.subscribe(shortcutConfig.shortcutKey, () => {
- if (this.props.modal.willAlertModalBecomeVisible) {
- return;
- }
-
- Navigation.dismissModal();
- }, shortcutConfig.descriptionKey, shortcutConfig.modifiers, true);
-
- this.unsubscribeTransitionEnd = onScreenTransitionEnd(this.props.navigation, () => {
- this.setState({didScreenTransitionEnd: true});
- this.props.onTransitionEnd();
- });
- }
-
- componentWillUnmount() {
- if (this.unsubscribeEscapeKey) {
- this.unsubscribeEscapeKey();
- }
- if (this.unsubscribeTransitionEnd) {
- this.unsubscribeTransitionEnd();
- }
- }
-
- render() {
- return (
-
- {(insets) => {
- const {paddingTop, paddingBottom} = StyleUtils.getSafeAreaPadding(insets);
- const paddingStyle = {};
-
- if (this.props.includePaddingTop) {
- paddingStyle.paddingTop = paddingTop;
- }
-
- if (this.props.includePaddingBottom) {
- paddingStyle.paddingBottom = paddingBottom;
- }
-
- return (
-
-
- {// If props.children is a function, call it to provide the insets to the children.
- _.isFunction(this.props.children)
- ? this.props.children({
- insets,
- didScreenTransitionEnd: this.state.didScreenTransitionEnd,
- })
- : this.props.children
- }
-
-
- );
- }}
-
- );
- }
-}
-
-ScreenWrapper.propTypes = propTypes;
-ScreenWrapper.defaultProps = defaultProps;
-
-export default compose(
- withNavigation,
- withOnyx({
- modal: {
- key: ONYXKEYS.MODAL,
- },
- }),
-)(ScreenWrapper);
diff --git a/src/components/ScreenWrapper/BaseScreenWrapper.js b/src/components/ScreenWrapper/BaseScreenWrapper.js
new file mode 100644
index 000000000000..a80a013a1c66
--- /dev/null
+++ b/src/components/ScreenWrapper/BaseScreenWrapper.js
@@ -0,0 +1,115 @@
+import {KeyboardAvoidingView, View} from 'react-native';
+import React from 'react';
+import {SafeAreaInsetsContext} from 'react-native-safe-area-context';
+import _ from 'underscore';
+import {withOnyx} from 'react-native-onyx';
+import CONST from '../../CONST';
+import KeyboardShortcut from '../../libs/KeyboardShortcut';
+import Navigation from '../../libs/Navigation/Navigation';
+import onScreenTransitionEnd from '../../libs/onScreenTransitionEnd';
+import * as StyleUtils from '../../styles/StyleUtils';
+import styles from '../../styles/styles';
+import HeaderGap from '../HeaderGap';
+import KeyboardShortcutsModal from '../KeyboardShortcutsModal';
+import OfflineIndicator from '../OfflineIndicator';
+import compose from '../../libs/compose';
+import withNavigation from '../withNavigation';
+import withWindowDimensions from '../withWindowDimensions';
+import ONYXKEYS from '../../ONYXKEYS';
+import {withNetwork} from '../OnyxProvider';
+import {propTypes, defaultProps} from './propTypes';
+
+class BaseScreenWrapper extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ didScreenTransitionEnd: false,
+ };
+ }
+
+ componentDidMount() {
+ const shortcutConfig = CONST.KEYBOARD_SHORTCUTS.ESCAPE;
+ this.unsubscribeEscapeKey = KeyboardShortcut.subscribe(shortcutConfig.shortcutKey, () => {
+ if (this.props.modal.willAlertModalBecomeVisible) {
+ return;
+ }
+
+ Navigation.dismissModal();
+ }, shortcutConfig.descriptionKey, shortcutConfig.modifiers, true);
+
+ this.unsubscribeTransitionEnd = onScreenTransitionEnd(this.props.navigation, () => {
+ this.setState({didScreenTransitionEnd: true});
+ this.props.onTransitionEnd();
+ });
+ }
+
+ componentWillUnmount() {
+ if (this.unsubscribeEscapeKey) {
+ this.unsubscribeEscapeKey();
+ }
+ if (this.unsubscribeTransitionEnd) {
+ this.unsubscribeTransitionEnd();
+ }
+ }
+
+ render() {
+ return (
+
+ {(insets) => {
+ const {paddingTop, paddingBottom} = StyleUtils.getSafeAreaPadding(insets);
+ const paddingStyle = {};
+
+ if (this.props.includePaddingTop) {
+ paddingStyle.paddingTop = paddingTop;
+ }
+
+ // We always need the safe area padding bottom if we're showing the offline indicator since it is bottom-docked.
+ if (this.props.includePaddingBottom || this.props.network.isOffline) {
+ paddingStyle.paddingBottom = paddingBottom;
+ }
+
+ return (
+
+
+
+ {// If props.children is a function, call it to provide the insets to the children.
+ _.isFunction(this.props.children)
+ ? this.props.children({
+ insets,
+ didScreenTransitionEnd: this.state.didScreenTransitionEnd,
+ })
+ : this.props.children
+ }
+
+ {this.props.isSmallScreenWidth && (
+
+ )}
+
+
+ );
+ }}
+
+ );
+ }
+}
+
+BaseScreenWrapper.propTypes = propTypes;
+BaseScreenWrapper.defaultProps = defaultProps;
+
+export default compose(
+ withNavigation,
+ withWindowDimensions,
+ withOnyx({
+ modal: {
+ key: ONYXKEYS.MODAL,
+ },
+ }),
+ withNetwork(),
+)(BaseScreenWrapper);
diff --git a/src/components/ScreenWrapper/index.android.js b/src/components/ScreenWrapper/index.android.js
new file mode 100644
index 000000000000..55067bd50923
--- /dev/null
+++ b/src/components/ScreenWrapper/index.android.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import BaseScreenWrapper from './BaseScreenWrapper';
+import {defaultProps, propTypes} from './propTypes';
+
+const ScreenWrapper = props => (
+
+ {props.children}
+
+);
+ScreenWrapper.propTypes = propTypes;
+ScreenWrapper.defaultProps = defaultProps;
+
+export default ScreenWrapper;
diff --git a/src/components/ScreenWrapper/index.js b/src/components/ScreenWrapper/index.js
new file mode 100644
index 000000000000..29c537442985
--- /dev/null
+++ b/src/components/ScreenWrapper/index.js
@@ -0,0 +1,16 @@
+import React from 'react';
+import BaseScreenWrapper from './BaseScreenWrapper';
+import {defaultProps, propTypes} from './propTypes';
+
+const ScreenWrapper = props => (
+
+ {props.children}
+
+);
+ScreenWrapper.propTypes = propTypes;
+ScreenWrapper.defaultProps = defaultProps;
+
+export default ScreenWrapper;
diff --git a/src/components/ScreenWrapper/propTypes.js b/src/components/ScreenWrapper/propTypes.js
new file mode 100644
index 000000000000..ce1858ef20bd
--- /dev/null
+++ b/src/components/ScreenWrapper/propTypes.js
@@ -0,0 +1,42 @@
+import PropTypes from 'prop-types';
+
+const propTypes = {
+ /** Array of additional styles to add */
+ style: PropTypes.arrayOf(PropTypes.object),
+
+ /** Returns a function as a child to pass insets to or a node to render without insets */
+ children: PropTypes.oneOfType([
+ PropTypes.node,
+ PropTypes.func,
+ ]).isRequired,
+
+ /** Whether to include padding bottom */
+ includePaddingBottom: PropTypes.bool,
+
+ /** Whether to include padding top */
+ includePaddingTop: PropTypes.bool,
+
+ // Called when navigated Screen's transition is finished.
+ onTransitionEnd: PropTypes.func,
+
+ /** The behavior to pass to the KeyboardAvoidingView, requires some trial and error depending on the layout/devices used.
+ * Search 'switch(behavior)' in ./node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js for more context */
+ keyboardAvoidingViewBehavior: PropTypes.oneOf(['padding', 'height', 'position']),
+
+ /** Details about any modals being used */
+ modal: PropTypes.shape({
+ /** Indicates when an Alert modal is about to be visible */
+ willAlertModalBecomeVisible: PropTypes.bool,
+ }),
+};
+
+const defaultProps = {
+ style: [],
+ includePaddingBottom: true,
+ includePaddingTop: true,
+ onTransitionEnd: () => {},
+ modal: {},
+ keyboardAvoidingViewBehavior: 'padding',
+};
+
+export {propTypes, defaultProps};
diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js
index 71daa5f13f72..d2ab86fccc9e 100644
--- a/src/pages/EnablePayments/AdditionalDetailsStep.js
+++ b/src/pages/EnablePayments/AdditionalDetailsStep.js
@@ -3,9 +3,7 @@ import _ from 'underscore';
import React from 'react';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
-import {
- View, KeyboardAvoidingView,
-} from 'react-native';
+import {View} from 'react-native';
import IdologyQuestions from './IdologyQuestions';
import ScreenWrapper from '../../components/ScreenWrapper';
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
@@ -254,19 +252,17 @@ class AdditionalDetailsStep extends React.Component {
render() {
if (!_.isEmpty(this.props.walletAdditionalDetails.questions)) {
return (
-
-
- Navigation.dismissModal()}
- shouldShowBackButton
- onBackButtonPress={() => Wallet.setAdditionalDetailsQuestions(null)}
- />
-
-
+
+ Navigation.dismissModal()}
+ shouldShowBackButton
+ onBackButtonPress={() => Wallet.setAdditionalDetailsQuestions(null)}
+ />
+
);
}
@@ -277,127 +273,125 @@ class AdditionalDetailsStep extends React.Component {
const {firstName, lastName} = PersonalDetails.extractFirstAndLastNameFromAvailableDetails(this.props.currentUserPersonalDetails);
return (
-
-
- Navigation.dismissModal()}
- />
-
-
- {this.props.translate('additionalDetailsStep.helpText')}
-
- {this.props.translate('additionalDetailsStep.helpLink')}
-
-
- this.form = el}>
-
-
- this.clearErrorAndSetValue('legalFirstName', val)}
- value={this.props.walletAdditionalDetailsDraft.legalFirstName || firstName}
- errorText={this.getErrorText('legalFirstName')}
- />
- this.clearErrorAndSetValue('legalLastName', val)}
- value={this.props.walletAdditionalDetailsDraft.legalLastName || lastName}
- errorText={this.getErrorText('legalLastName')}
- />
- {
- const renamedFields = {
- street: 'addressStreet',
- state: 'addressState',
- zipCode: 'addressZip',
- city: 'addressCity',
- };
- _.each(values, (value, inputKey) => {
- const renamedInputKey = lodashGet(renamedFields, inputKey, inputKey);
- this.clearErrorAndSetValue(renamedInputKey, value);
- });
- }}
- errorText={this.getErrorText('addressStreet')}
- hint={this.props.translate('common.noPO')}
- />
- {this.props.walletAdditionalDetailsDraft.addressStreet ? (
- <>
- {/** Once the user has started entering his address, show the other address fields (city, state, zip) */}
- {/** We'll autofill them when the user selects a full address from the google autocomplete */}
- this.clearErrorAndSetValue('addressCity', val)}
- value={this.props.walletAdditionalDetailsDraft.addressCity || ''}
- errorText={this.getErrorText('addressCity')}
- />
- this.clearErrorAndSetValue('addressState', val)}
- value={this.props.walletAdditionalDetailsDraft.addressState || ''}
- errorText={this.getErrorText('addressState')}
- />
- this.clearErrorAndSetValue('addressZip', val)}
- value={this.props.walletAdditionalDetailsDraft.addressZip || ''}
- errorText={this.getErrorText('addressZip')}
- />
- >
- ) : null}
-
+
+ Navigation.dismissModal()}
+ />
+
+
+ {this.props.translate('additionalDetailsStep.helpText')}
+
+ {this.props.translate('additionalDetailsStep.helpLink')}
+
+
+ this.form = el}>
+
+
this.clearErrorAndSetValue('phoneNumber', val)}
- value={this.props.walletAdditionalDetailsDraft.phoneNumber || ''}
- placeholder={this.props.translate('common.phoneNumberPlaceholder')}
- errorText={this.getErrorText('phoneNumber')}
+ label={this.props.translate(this.fieldNameTranslationKeys.legalFirstName)}
+ onChangeText={val => this.clearErrorAndSetValue('legalFirstName', val)}
+ value={this.props.walletAdditionalDetailsDraft.legalFirstName || firstName}
+ errorText={this.getErrorText('legalFirstName')}
/>
- this.clearDateErrorsAndSetValue(val)}
- defaultValue={this.props.walletAdditionalDetailsDraft.dob || ''}
- placeholder={this.props.translate('common.dob')}
- errorText={this.getErrorText('dob') || this.getErrorText('age')}
- maximumDate={new Date()}
+ label={this.props.translate(this.fieldNameTranslationKeys.legalLastName)}
+ onChangeText={val => this.clearErrorAndSetValue('legalLastName', val)}
+ value={this.props.walletAdditionalDetailsDraft.legalLastName || lastName}
+ errorText={this.getErrorText('legalLastName')}
/>
- this.clearSSNErrorAndSetValue(val)}
- value={this.props.walletAdditionalDetailsDraft.ssn || ''}
- errorText={this.getErrorText('ssnFull9') || this.getErrorText('ssn')}
- maxLength={shouldAskForFullSSN ? 9 : 4}
- keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD}
+ onInputChange={(values) => {
+ const renamedFields = {
+ street: 'addressStreet',
+ state: 'addressState',
+ zipCode: 'addressZip',
+ city: 'addressCity',
+ };
+ _.each(values, (value, inputKey) => {
+ const renamedInputKey = lodashGet(renamedFields, inputKey, inputKey);
+ this.clearErrorAndSetValue(renamedInputKey, value);
+ });
+ }}
+ errorText={this.getErrorText('addressStreet')}
+ hint={this.props.translate('common.noPO')}
/>
+ {this.props.walletAdditionalDetailsDraft.addressStreet ? (
+ <>
+ {/** Once the user has started entering his address, show the other address fields (city, state, zip) */}
+ {/** We'll autofill them when the user selects a full address from the google autocomplete */}
+ this.clearErrorAndSetValue('addressCity', val)}
+ value={this.props.walletAdditionalDetailsDraft.addressCity || ''}
+ errorText={this.getErrorText('addressCity')}
+ />
+ this.clearErrorAndSetValue('addressState', val)}
+ value={this.props.walletAdditionalDetailsDraft.addressState || ''}
+ errorText={this.getErrorText('addressState')}
+ />
+ this.clearErrorAndSetValue('addressZip', val)}
+ value={this.props.walletAdditionalDetailsDraft.addressZip || ''}
+ errorText={this.getErrorText('addressZip')}
+ />
+ >
+ ) : null}
- {
- this.form.scrollTo({y: 0, animated: true});
- }}
- message={this.props.walletAdditionalDetails.additionalErrorMessage}
- isLoading={this.props.walletAdditionalDetails.loading}
- buttonText={this.props.translate('common.saveAndContinue')}
+ this.clearErrorAndSetValue('phoneNumber', val)}
+ value={this.props.walletAdditionalDetailsDraft.phoneNumber || ''}
+ placeholder={this.props.translate('common.phoneNumberPlaceholder')}
+ errorText={this.getErrorText('phoneNumber')}
/>
-
-
-
+ this.clearDateErrorsAndSetValue(val)}
+ defaultValue={this.props.walletAdditionalDetailsDraft.dob || ''}
+ placeholder={this.props.translate('common.dob')}
+ errorText={this.getErrorText('dob') || this.getErrorText('age')}
+ maximumDate={new Date()}
+ />
+ this.clearSSNErrorAndSetValue(val)}
+ value={this.props.walletAdditionalDetailsDraft.ssn || ''}
+ errorText={this.getErrorText('ssnFull9') || this.getErrorText('ssn')}
+ maxLength={shouldAskForFullSSN ? 9 : 4}
+ keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD}
+ />
+
+ {
+ this.form.scrollTo({y: 0, animated: true});
+ }}
+ message={this.props.walletAdditionalDetails.additionalErrorMessage}
+ isLoading={this.props.walletAdditionalDetails.loading}
+ buttonText={this.props.translate('common.saveAndContinue')}
+ />
+
+
);
}
diff --git a/src/pages/EnablePayments/EnablePaymentsPage.js b/src/pages/EnablePayments/EnablePaymentsPage.js
index f1ac80846a05..53f25dfeffd7 100644
--- a/src/pages/EnablePayments/EnablePaymentsPage.js
+++ b/src/pages/EnablePayments/EnablePaymentsPage.js
@@ -1,7 +1,6 @@
import _ from 'underscore';
import React from 'react';
import {withOnyx} from 'react-native-onyx';
-import {KeyboardAvoidingView} from 'react-native';
import ScreenWrapper from '../../components/ScreenWrapper';
import * as BankAccounts from '../../libs/actions/BankAccounts';
import ONYXKEYS from '../../ONYXKEYS';
@@ -59,14 +58,12 @@ class EnablePaymentsPage extends React.Component {
if (this.props.userWallet.shouldShowFailedKYC) {
return (
-
-
- Navigation.dismissModal()}
- />
-
-
+
+ Navigation.dismissModal()}
+ />
+
);
}
diff --git a/src/pages/GetAssistancePage.js b/src/pages/GetAssistancePage.js
index 030ea26bac8a..4a07075b0d3f 100644
--- a/src/pages/GetAssistancePage.js
+++ b/src/pages/GetAssistancePage.js
@@ -3,7 +3,6 @@ import {View} from 'react-native';
import PropTypes from 'prop-types';
import ScreenWrapper from '../components/ScreenWrapper';
import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
-import KeyboardAvoidingView from '../components/KeyboardAvoidingView';
import HeaderWithCloseButton from '../components/HeaderWithCloseButton';
import Section from '../components/Section';
import Navigation from '../libs/Navigation/Navigation';
@@ -28,36 +27,34 @@ const propTypes = {
const GetAssistancePage = props => (
-
- Navigation.dismissModal(true)}
- shouldShowBackButton
- onBackButtonPress={() => Navigation.goBack()}
- />
- Report.navigateToConciergeChat(),
- icon: Expensicons.ChatBubble,
- shouldShowRightIcon: true,
- },
- {
- title: props.translate('getAssistancePage.requestSetupCall'),
- onPress: () => Navigation.navigate(ROUTES.getRequestCallRoute(props.route.params.taskID)),
- icon: Expensicons.Phone,
- shouldShowRightIcon: true,
- },
- ]}
- >
-
- {props.translate('getAssistancePage.description')}
-
-
-
+ Navigation.dismissModal(true)}
+ shouldShowBackButton
+ onBackButtonPress={() => Navigation.goBack()}
+ />
+ Report.navigateToConciergeChat(),
+ icon: Expensicons.ChatBubble,
+ shouldShowRightIcon: true,
+ },
+ {
+ title: props.translate('getAssistancePage.requestSetupCall'),
+ onPress: () => Navigation.navigate(ROUTES.getRequestCallRoute(props.route.params.taskID)),
+ icon: Expensicons.Phone,
+ shouldShowRightIcon: true,
+ },
+ ]}
+ >
+
+ {props.translate('getAssistancePage.description')}
+
+
);
diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js
index 0e55bdbccfbc..2c8a0231c8cb 100755
--- a/src/pages/NewChatPage.js
+++ b/src/pages/NewChatPage.js
@@ -16,7 +16,6 @@ import ScreenWrapper from '../components/ScreenWrapper';
import FullScreenLoadingIndicator from '../components/FullscreenLoadingIndicator';
import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
import compose from '../libs/compose';
-import KeyboardAvoidingView from '../components/KeyboardAvoidingView';
import personalDetailsPropType from './personalDetailsPropType';
const propTypes = {
@@ -211,9 +210,9 @@ class NewChatPage extends Component {
maxParticipantsReached,
);
return (
-
+
{({didScreenTransitionEnd}) => (
-
+ <>
)}
-
+ >
)}
);
diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js
index 21a15777b738..9f022bd00bc4 100644
--- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js
+++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js
@@ -14,7 +14,6 @@ import CONST from '../../CONST';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import compose from '../../libs/compose';
import styles from '../../styles/styles';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import getPlaidOAuthReceivedRedirectURI from '../../libs/getPlaidOAuthReceivedRedirectURI';
import Text from '../../components/Text';
import {withNetwork} from '../../components/OnyxProvider';
@@ -219,34 +218,32 @@ class ReimbursementAccountPage extends React.Component {
}
return (
-
- {currentStep === CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT && (
-
- )}
- {currentStep === CONST.BANK_ACCOUNT.STEP.COMPANY && (
-
- )}
- {currentStep === CONST.BANK_ACCOUNT.STEP.REQUESTOR && (
-
- )}
- {currentStep === CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT && (
-
- )}
- {currentStep === CONST.BANK_ACCOUNT.STEP.VALIDATION && (
-
- )}
- {currentStep === CONST.BANK_ACCOUNT.STEP.ENABLE && (
-
- )}
-
-
+ {currentStep === CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT && (
+
+ )}
+ {currentStep === CONST.BANK_ACCOUNT.STEP.COMPANY && (
+
+ )}
+ {currentStep === CONST.BANK_ACCOUNT.STEP.REQUESTOR && (
+
+ )}
+ {currentStep === CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT && (
+
+ )}
+ {currentStep === CONST.BANK_ACCOUNT.STEP.VALIDATION && (
+
+ )}
+ {currentStep === CONST.BANK_ACCOUNT.STEP.ENABLE && (
+
+ )}
+
);
}
diff --git a/src/pages/RequestCallPage.js b/src/pages/RequestCallPage.js
index cbfd52a4390c..d2b8fa817e8c 100644
--- a/src/pages/RequestCallPage.js
+++ b/src/pages/RequestCallPage.js
@@ -23,7 +23,6 @@ import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes,
import TextInput from '../components/TextInput';
import Text from '../components/Text';
import Section from '../components/Section';
-import KeyboardAvoidingView from '../components/KeyboardAvoidingView';
import * as Illustrations from '../components/Icon/Illustrations';
import * as Expensicons from '../components/Icon/Expensicons';
import * as LoginUtils from '../libs/LoginUtils';
@@ -285,86 +284,84 @@ class RequestCallPage extends Component {
return (
-
- Navigation.goBack()}
- onCloseButtonPress={() => Navigation.dismissModal(true)}
- />
- {this.props.requestCallForm.didRequestCallSucceed
- ? (
-
- ) : (
- <>
-
-
-
-
- {this.props.translate('requestCallPage.description')}
-
- this.setState({firstName})}
- onChangeLastName={lastName => this.setState({lastName})}
- style={[styles.mv4]}
- />
- this.setState({phoneNumber})}
- />
- this.setState({phoneExtension})}
- containerStyles={[styles.mt4]}
- />
- {this.getWaitTimeMessage()}
-
-
-
-
- {isBlockedFromConcierge && (
-
-
- {this.props.translate('requestCallPage.blockedFromConcierge')}
-
- )}
- {!_.isEmpty(this.props.requestCallForm.error) && (
-
- {this.props.requestCallForm.error}
+ Navigation.goBack()}
+ onCloseButtonPress={() => Navigation.dismissModal(true)}
+ />
+ {this.props.requestCallForm.didRequestCallSucceed
+ ? (
+
+ ) : (
+ <>
+
+
+
+
+ {this.props.translate('requestCallPage.description')}
- )}
-
-
- >
- )}
-
+ this.setState({firstName})}
+ onChangeLastName={lastName => this.setState({lastName})}
+ style={[styles.mv4]}
+ />
+ this.setState({phoneNumber})}
+ />
+ this.setState({phoneExtension})}
+ containerStyles={[styles.mt4]}
+ />
+ {this.getWaitTimeMessage()}
+
+
+
+
+ {isBlockedFromConcierge && (
+
+
+ {this.props.translate('requestCallPage.blockedFromConcierge')}
+
+ )}
+ {!_.isEmpty(this.props.requestCallForm.error) && (
+
+ {this.props.requestCallForm.error}
+
+ )}
+
+
+ >
+ )}
);
}
diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js
index 9a5756240e50..3f8534ca2b5f 100755
--- a/src/pages/SearchPage.js
+++ b/src/pages/SearchPage.js
@@ -7,7 +7,6 @@ import OptionsSelector from '../components/OptionsSelector';
import * as OptionsListUtils from '../libs/OptionsListUtils';
import ONYXKEYS from '../ONYXKEYS';
import styles from '../styles/styles';
-import KeyboardSpacer from '../components/KeyboardSpacer';
import Navigation from '../libs/Navigation/Navigation';
import ROUTES from '../ROUTES';
import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions';
@@ -189,7 +188,6 @@ class SearchPage extends Component {
shouldShowOptions={didScreenTransitionEnd}
/>
-
>
)}
diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js
index fd9282a88021..c0490d0ebff1 100644
--- a/src/pages/home/ReportScreen.js
+++ b/src/pages/home/ReportScreen.js
@@ -16,13 +16,15 @@ import Permissions from '../../libs/Permissions';
import * as ReportUtils from '../../libs/ReportUtils';
import ReportActionsView from './report/ReportActionsView';
import ReportActionCompose from './report/ReportActionCompose';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import SwipeableView from '../../components/SwipeableView';
import CONST from '../../CONST';
import ReportActionsSkeletonView from '../../components/ReportActionsSkeletonView';
import reportActionPropTypes from './report/reportActionPropTypes';
import ArchivedReportFooter from '../../components/ArchivedReportFooter';
import toggleReportActionComposeView from '../../libs/toggleReportActionComposeView';
+import {withNetwork} from '../../components/OnyxProvider';
+import compose from '../../libs/compose';
+import networkPropTypes from '../../components/networkPropTypes';
const propTypes = {
/** Navigation route context info provided by react navigation */
@@ -77,6 +79,9 @@ const propTypes = {
/** The type of the policy */
type: PropTypes.string,
})).isRequired,
+
+ /** Information about the network */
+ network: networkPropTypes.isRequired,
};
const defaultProps = {
@@ -149,12 +154,8 @@ class ReportScreen extends React.Component {
Report.addComment(getReportID(this.props.route), text);
}
- /**
- * @param {SyntheticEvent} e
- */
- updateViewportOffsetTop(e) {
- const viewportOffsetTop = lodashGet(e, 'target.offsetTop', 0);
- this.setState({viewportOffsetTop});
+ setChatFooterStyles(isOffline) {
+ return {...styles.chatFooter, minHeight: !isOffline ? CONST.CHAT_FOOTER_MIN_HEIGHT : 0};
}
/**
@@ -181,6 +182,14 @@ class ReportScreen extends React.Component {
Report.updateCurrentlyViewedReportID(reportID);
}
+ /**
+ * @param {SyntheticEvent} e
+ */
+ updateViewportOffsetTop(e) {
+ const viewportOffsetTop = lodashGet(e, 'target.offsetTop', 0);
+ this.setState({viewportOffsetTop});
+ }
+
render() {
if (!this.props.isSidebarLoaded) {
return null;
@@ -206,57 +215,55 @@ class ReportScreen extends React.Component {
}
return (
-
- Navigation.navigate(ROUTES.HOME)}
- />
-
- this.setState({skeletonViewContainerHeight: event.nativeEvent.layout.height})}
- >
- {this.shouldShowLoader()
- ? (
-
- )
- : (
-
- )}
- {(isArchivedRoom || this.props.session.shouldShowComposeInput) && (
-
- {
- isArchivedRoom
- ? (
- Navigation.navigate(ROUTES.HOME)}
+ />
+
+ this.setState({skeletonViewContainerHeight: event.nativeEvent.layout.height})}
+ >
+ {this.shouldShowLoader()
+ ? (
+
+ )
+ : (
+
+ )}
+ {(isArchivedRoom || this.props.session.shouldShowComposeInput) && (
+
+ {
+ isArchivedRoom
+ ? (
+
+ ) : (
+
+
- ) : (
-
-
-
- )
- }
-
- )}
-
-
+
+ )
+ }
+
+ )}
+
);
}
@@ -265,7 +272,7 @@ class ReportScreen extends React.Component {
ReportScreen.propTypes = propTypes;
ReportScreen.defaultProps = defaultProps;
-export default withOnyx({
+export default compose(withNetwork(), withOnyx({
isSidebarLoaded: {
key: ONYXKEYS.IS_SIDEBAR_LOADED,
},
@@ -292,4 +299,4 @@ export default withOnyx({
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
-})(ReportScreen);
+}))(ReportScreen);
diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js
index 6e58ae1f5715..51791c723367 100755
--- a/src/pages/home/report/ReportActionCompose.js
+++ b/src/pages/home/report/ReportActionCompose.js
@@ -496,7 +496,11 @@ class ReportActionCompose extends React.Component {
const hasExceededMaxCommentLength = this.comment.length > CONST.MAX_COMMENT_LENGTH;
return (
-
+
{shouldShowReportRecipientLocalTime
&& }
-
-
+
+ {!this.props.isSmallScreenWidth && }
diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js
index 424353b09ca6..5ef4b3603808 100644
--- a/src/pages/home/report/ReportActionsList.js
+++ b/src/pages/home/report/ReportActionsList.js
@@ -103,7 +103,7 @@ class ReportActionsList extends React.Component {
const minimumReportActionHeight = styles.chatItem.paddingTop + styles.chatItem.paddingBottom
+ variables.fontSizeNormalHeight;
const availableHeight = this.props.windowHeight
- - (styles.chatFooter.minHeight + variables.contentHeaderHeight);
+ - (CONST.CHAT_FOOTER_MIN_HEIGHT + variables.contentHeaderHeight);
return Math.ceil(availableHeight / minimumReportActionHeight);
}
diff --git a/src/pages/home/report/ReportTypingIndicator.js b/src/pages/home/report/ReportTypingIndicator.js
index 0ba4e2463b2e..2ee31974690d 100755
--- a/src/pages/home/report/ReportTypingIndicator.js
+++ b/src/pages/home/report/ReportTypingIndicator.js
@@ -67,7 +67,7 @@ class ReportTypingIndicator extends React.Component {
leadingText={PersonalDetails.getDisplayName(this.state.usersTyping[0])}
trailingText={` ${this.props.translate('reportTypingIndicator.isTyping')}`}
textStyle={[styles.chatItemComposeSecondaryRowSubText]}
- wrapperStyle={styles.chatItemComposeSecondaryRow}
+ wrapperStyle={[styles.chatItemComposeSecondaryRow]}
leadingTextParentStyle={styles.chatItemComposeSecondaryRowOffset}
/>
);
@@ -78,6 +78,7 @@ class ReportTypingIndicator extends React.Component {
style={[
styles.chatItemComposeSecondaryRowSubText,
styles.chatItemComposeSecondaryRowOffset,
+ ...this.props.containerStyles,
]}
numberOfLines={1}
>
diff --git a/src/pages/iou/IOUCurrencySelection.js b/src/pages/iou/IOUCurrencySelection.js
index b8b408b4c815..d0f9861ee819 100644
--- a/src/pages/iou/IOUCurrencySelection.js
+++ b/src/pages/iou/IOUCurrencySelection.js
@@ -10,7 +10,6 @@ import ScreenWrapper from '../../components/ScreenWrapper';
import HeaderWithCloseButton from '../../components/HeaderWithCloseButton';
import compose from '../../libs/compose';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import * as IOU from '../../libs/actions/IOU';
import * as CurrencySymbolUtils from '../../libs/CurrencySymbolUtils';
import {withNetwork} from '../../components/OnyxProvider';
@@ -117,21 +116,19 @@ class IOUCurrencySelection extends Component {
const headerMessage = this.state.searchValue.trim() && !this.state.currencyData.length ? this.props.translate('common.noResultsFound') : '';
return (
-
-
-
-
+
+
);
}
diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js
index 14a24b473aad..508456ebe9a4 100755
--- a/src/pages/iou/IOUModal.js
+++ b/src/pages/iou/IOUModal.js
@@ -23,7 +23,6 @@ import AnimatedStep from '../../components/AnimatedStep';
import ScreenWrapper from '../../components/ScreenWrapper';
import Tooltip from '../../components/Tooltip';
import CONST from '../../CONST';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import * as PersonalDetails from '../../libs/actions/PersonalDetails';
import withCurrentUserPersonalDetails from '../../components/withCurrentUserPersonalDetails';
import ROUTES from '../../ROUTES';
@@ -174,7 +173,7 @@ class IOUModal extends Component {
* Decides our animation type based on whether we're increasing or decreasing
* our step index.
* @returns {String}
- */
+ */
getDirection() {
if (this.state.previousStepIndex < this.state.currentStepIndex) {
return 'in';
@@ -358,7 +357,7 @@ class IOUModal extends Component {
return (
{({didScreenTransitionEnd}) => (
-
+ <>
)}
-
+ >
)}
);
diff --git a/src/pages/settings/AddSecondaryLoginPage.js b/src/pages/settings/AddSecondaryLoginPage.js
index 7a15526de572..afffdb7cfdbd 100755
--- a/src/pages/settings/AddSecondaryLoginPage.js
+++ b/src/pages/settings/AddSecondaryLoginPage.js
@@ -14,7 +14,6 @@ import ONYXKEYS from '../../ONYXKEYS';
import Button from '../../components/Button';
import ROUTES from '../../ROUTES';
import CONST from '../../CONST';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import compose from '../../libs/compose';
import FixedFooter from '../../components/FixedFooter';
@@ -101,62 +100,60 @@ class AddSecondaryLoginPage extends Component {
this.phoneNumberInputRef.focus();
}}
>
-
- Navigation.navigate(ROUTES.SETTINGS_PROFILE)}
- onCloseButtonPress={() => Navigation.dismissModal()}
- />
-
-
- {this.props.translate(this.formType === CONST.LOGIN_TYPE.PHONE
- ? 'addSecondaryLoginPage.enterPreferredPhoneNumberToSendValidationLink'
- : 'addSecondaryLoginPage.enterPreferredEmailToSendValidationLink')}
-
-
- this.phoneNumberInputRef = el}
- value={this.state.login}
- onChangeText={this.onSecondaryLoginChange}
- keyboardType={this.formType === CONST.LOGIN_TYPE.PHONE
- ? CONST.KEYBOARD_TYPE.PHONE_PAD : undefined}
- returnKeyType="done"
- />
-
-
- this.setState({password})}
- secureTextEntry
- autoCompleteType="password"
- textContentType="password"
- onSubmitEditing={this.submitForm}
- />
-
- {!_.isEmpty(this.props.user.error) && (
-
- {this.props.user.error}
-
- )}
-
-
-
-
+
+ {!_.isEmpty(this.props.user.error) && (
+
+ {this.props.user.error}
+
+ )}
+
+
+
+
);
}
diff --git a/src/pages/settings/PasswordPage.js b/src/pages/settings/PasswordPage.js
index 23d70132c056..69270c2bacaf 100755
--- a/src/pages/settings/PasswordPage.js
+++ b/src/pages/settings/PasswordPage.js
@@ -14,7 +14,6 @@ import * as ValidationUtils from '../../libs/ValidationUtils';
import * as User from '../../libs/actions/User';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import compose from '../../libs/compose';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import FixedFooter from '../../components/FixedFooter';
import TextInput from '../../components/TextInput';
import * as Session from '../../libs/actions/Session';
@@ -147,86 +146,84 @@ class PasswordPage extends Component {
this.currentPasswordInputRef.focus();
}}
>
-
- Navigation.goBack()}
- onCloseButtonPress={() => Navigation.dismissModal(true)}
- />
- {!_.isEmpty(this.props.account.success)
- ? (
-
- ) : (
- <>
-
-
- {this.props.translate('passwordPage.changingYourPasswordPrompt')}
+ Navigation.goBack()}
+ onCloseButtonPress={() => Navigation.dismissModal(true)}
+ />
+ {!_.isEmpty(this.props.account.success)
+ ? (
+
+ ) : (
+ <>
+
+
+ {this.props.translate('passwordPage.changingYourPasswordPrompt')}
+
+
+ this.currentPasswordInputRef = el}
+ secureTextEntry
+ autoCompleteType="password"
+ textContentType="password"
+ value={this.state.currentPassword}
+ onChangeText={text => this.clearErrorAndSetValue('currentPassword', text)}
+ returnKeyType="done"
+ hasError={this.state.errors.currentPassword}
+ errorText={this.getErrorText('currentPassword')}
+ onSubmitEditing={this.submit}
+ />
+
+
+ this.clearErrorAndSetValue('newPassword', text, ['newPasswordSameAsOld'])}
+ onSubmitEditing={this.submit}
+ />
+ {shouldShowNewPasswordPrompt && (
+
+ {this.props.translate('passwordPage.newPasswordPrompt')}
-
- this.currentPasswordInputRef = el}
- secureTextEntry
- autoCompleteType="password"
- textContentType="password"
- value={this.state.currentPassword}
- onChangeText={text => this.clearErrorAndSetValue('currentPassword', text)}
- returnKeyType="done"
- hasError={this.state.errors.currentPassword}
- errorText={this.getErrorText('currentPassword')}
- onSubmitEditing={this.submit}
- />
-
-
- this.clearErrorAndSetValue('newPassword', text, ['newPasswordSameAsOld'])}
- onSubmitEditing={this.submit}
- />
- {shouldShowNewPasswordPrompt && (
-
- {this.props.translate('passwordPage.newPasswordPrompt')}
-
- )}
-
- {_.every(this.state.errors, error => !error) && !_.isEmpty(this.props.account.error) && (
-
- {this.props.account.error}
-
)}
-
-
-
-
- >
- )}
-
+
+ {_.every(this.state.errors, error => !error) && !_.isEmpty(this.props.account.error) && (
+
+ {this.props.account.error}
+
+ )}
+
+
+
+
+ >
+ )}
);
}
diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js
index 9e1ccee29c72..b59619f8e052 100644
--- a/src/pages/settings/Payments/AddDebitCardPage.js
+++ b/src/pages/settings/Payments/AddDebitCardPage.js
@@ -9,7 +9,6 @@ import Text from '../../../components/Text';
import TextLink from '../../../components/TextLink';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import * as PaymentMethods from '../../../libs/actions/PaymentMethods';
-import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
import * as ValidationUtils from '../../../libs/ValidationUtils';
import CheckboxWithLabel from '../../../components/CheckboxWithLabel';
import StatePicker from '../../../components/StatePicker';
@@ -88,94 +87,92 @@ class DebitCardPage extends Component {
render() {
return (
-
- Navigation.goBack()}
- onCloseButtonPress={() => Navigation.dismissModal(true)}
+ Navigation.goBack()}
+ onCloseButtonPress={() => Navigation.dismissModal(true)}
+ />
+
-
+
+ (
+ <>
+ {`${this.props.translate('common.iAcceptThe')}`}
+
+ {`${this.props.translate('addDebitCardPage.expensifyTermsOfService')}`}
+
+ >
+ )}
+ style={[styles.mt4]}
+ shouldSaveDraft
+ />
+
);
}
diff --git a/src/pages/settings/Payments/AddPayPalMePage.js b/src/pages/settings/Payments/AddPayPalMePage.js
index fde6b501547a..2e8bdff1d8e7 100644
--- a/src/pages/settings/Payments/AddPayPalMePage.js
+++ b/src/pages/settings/Payments/AddPayPalMePage.js
@@ -13,7 +13,6 @@ import styles from '../../../styles/styles';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import compose from '../../../libs/compose';
import Button from '../../../components/Button';
-import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
import FixedFooter from '../../../components/FixedFooter';
import Growl from '../../../libs/Growl';
import TextInput from '../../../components/TextInput';
@@ -61,44 +60,42 @@ class AddPayPalMePage extends React.Component {
render() {
return (
-
- Navigation.navigate(ROUTES.SETTINGS_PAYMENTS)}
- onCloseButtonPress={() => Navigation.dismissModal(true)}
- />
-
-
-
- {this.props.translate('addPayPalMePage.enterYourUsernameToGetPaidViaPayPal')}
-
- this.setState({payPalMeUsername: text, payPalMeUsernameError: false})}
- returnKeyType="done"
- hasError={this.state.payPalMeUsernameError}
- errorText={this.state.payPalMeUsernameError ? this.props.translate('addPayPalMePage.formatError') : ''}
- />
-
-
-
-
-
+
+
+
+
+
);
}
diff --git a/src/pages/settings/Payments/ChooseTransferAccountPage.js b/src/pages/settings/Payments/ChooseTransferAccountPage.js
index b1d878340048..99d0b1fe2623 100644
--- a/src/pages/settings/Payments/ChooseTransferAccountPage.js
+++ b/src/pages/settings/Payments/ChooseTransferAccountPage.js
@@ -5,7 +5,6 @@ import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton';
import ScreenWrapper from '../../../components/ScreenWrapper';
import Navigation from '../../../libs/Navigation/Navigation';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
-import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
import CONST from '../../../CONST';
import PaymentMethodList from './PaymentMethodList';
import * as PaymentMethods from '../../../libs/actions/PaymentMethods';
@@ -58,30 +57,28 @@ const ChooseTransferAccountPage = (props) => {
return (
-
- Navigation.goBack()}
- onCloseButtonPress={() => Navigation.dismissModal()}
+ Navigation.goBack()}
+ onCloseButtonPress={() => Navigation.dismissModal()}
+ />
+
+
-
-
-
-
-
+
+
);
};
diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
index 56f39910e421..f5d6e1ddd072 100644
--- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js
@@ -14,7 +14,6 @@ import Navigation from '../../../../libs/Navigation/Navigation';
import styles from '../../../../styles/styles';
import withLocalize from '../../../../components/withLocalize';
import compose from '../../../../libs/compose';
-import KeyboardAvoidingView from '../../../../components/KeyboardAvoidingView/index';
import * as BankAccounts from '../../../../libs/actions/BankAccounts';
import Popover from '../../../../components/Popover';
import MenuItem from '../../../../components/MenuItem';
@@ -33,7 +32,6 @@ import KYCWall from '../../../../components/KYCWall';
import {propTypes, defaultProps} from './paymentsPagePropTypes';
import {withNetwork} from '../../../../components/OnyxProvider';
import * as PaymentUtils from '../../../../libs/PaymentUtils';
-import OfflineIndicator from '../../../../components/OfflineIndicator';
class BasePaymentsPage extends React.Component {
constructor(props) {
@@ -266,178 +264,175 @@ class BasePaymentsPage extends React.Component {
const isPopoverBottomMount = this.state.anchorPositionTop === 0 || this.props.isSmallScreenWidth;
return (
-
- Navigation.navigate(ROUTES.SETTINGS)}
- onCloseButtonPress={() => Navigation.dismissModal(true)}
- />
-
- {Permissions.canUseWallet(this.props.betas) && (
- <>
-
-
-
- {this.props.userWallet.currentBalance > 0 && (
-
- {triggerKYCFlow => (
-
- )}
-
- )}
- >
- )}
-
- {this.props.translate('paymentsPage.paymentMethodsTitle')}
-
-
-
- this.addPaymentMethodTypePressed(method)}
- />
-
-
- {isPopoverBottomMount && (
-
- )}
- {shouldShowMakeDefaultButton && (
- {
- this.setState({
- shouldShowDefaultDeleteMenu: false,
- });
-
- // Wait for the previous modal to close, before opening a new one. A modal will be considered completely closed when closing animation is finished.
- // InteractionManager fires after the currently running animation is completed.
- // https://github.com/Expensify/App/issues/7768#issuecomment-1044879541
- InteractionManager.runAfterInteractions(() => {
- this.setState({
- shouldShowPasswordPrompt: true,
- passwordButtonText: this.props.translate('paymentsPage.setDefaultConfirmation'),
- });
- });
- }}
- style={[styles.button, styles.alignSelfCenter, styles.w100]}
+ Navigation.navigate(ROUTES.SETTINGS)}
+ onCloseButtonPress={() => Navigation.dismissModal(true)}
+ />
+
+ {Permissions.canUseWallet(this.props.betas) && (
+ <>
+
+
+
+ {this.props.userWallet.currentBalance > 0 && (
+
-
- {this.props.translate('paymentsPage.setDefaultConfirmation')}
-
-
+ {triggerKYCFlow => (
+
+ )}
+
)}
+ >
+ )}
+
+ {this.props.translate('paymentsPage.paymentMethodsTitle')}
+
+
+
+ this.addPaymentMethodTypePressed(method)}
+ />
+
+
+ {isPopoverBottomMount && (
+
+ )}
+ {shouldShowMakeDefaultButton && (
{
this.setState({
shouldShowDefaultDeleteMenu: false,
});
+
+ // Wait for the previous modal to close, before opening a new one. A modal will be considered completely closed when closing animation is finished.
+ // InteractionManager fires after the currently running animation is completed.
+ // https://github.com/Expensify/App/issues/7768#issuecomment-1044879541
InteractionManager.runAfterInteractions(() => {
this.setState({
- shouldShowConfirmPopover: true,
+ shouldShowPasswordPrompt: true,
+ passwordButtonText: this.props.translate('paymentsPage.setDefaultConfirmation'),
});
});
}}
- style={[
- styles.button,
- styles.buttonDanger,
- shouldShowMakeDefaultButton && styles.mt4,
- styles.alignSelfCenter,
- styles.w100,
- ]}
+ style={[styles.button, styles.alignSelfCenter, styles.w100]}
>
-
- {this.props.translate('common.delete')}
+
+ {this.props.translate('paymentsPage.setDefaultConfirmation')}
-
-
- {
- this.hidePasswordPrompt();
- this.makeDefaultPaymentMethod(password);
- }}
- submitButtonText={this.state.passwordButtonText}
- isDangerousAction
- />
- {
- this.setState({
- shouldShowConfirmPopover: false,
- });
- this.deletePaymentMethod();
- }}
- onCancel={() => {
- this.setState({shouldShowConfirmPopover: false});
- }}
- shouldShowCancelButton
- danger
- />
-
-
+ )}
+ {
+ this.setState({
+ shouldShowDefaultDeleteMenu: false,
+ });
+ InteractionManager.runAfterInteractions(() => {
+ this.setState({
+ shouldShowConfirmPopover: true,
+ });
+ });
+ }}
+ style={[
+ styles.button,
+ styles.buttonDanger,
+ shouldShowMakeDefaultButton && styles.mt4,
+ styles.alignSelfCenter,
+ styles.w100,
+ ]}
+ >
+
+ {this.props.translate('common.delete')}
+
+
+
+
+ {
+ this.hidePasswordPrompt();
+ this.makeDefaultPaymentMethod(password);
+ }}
+ submitButtonText={this.state.passwordButtonText}
+ isDangerousAction
+ />
+ {
+ this.setState({
+ shouldShowConfirmPopover: false,
+ });
+ this.deletePaymentMethod();
+ }}
+ onCancel={() => {
+ this.setState({shouldShowConfirmPopover: false});
+ }}
+ shouldShowCancelButton
+ danger
+ />
);
}
diff --git a/src/pages/settings/Payments/TransferBalancePage.js b/src/pages/settings/Payments/TransferBalancePage.js
index b1699f367e8f..7cc1d6bc5e4f 100644
--- a/src/pages/settings/Payments/TransferBalancePage.js
+++ b/src/pages/settings/Payments/TransferBalancePage.js
@@ -9,7 +9,6 @@ import ScreenWrapper from '../../../components/ScreenWrapper';
import Navigation from '../../../libs/Navigation/Navigation';
import styles from '../../../styles/styles';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
-import {withNetwork} from '../../../components/OnyxProvider';
import compose from '../../../libs/compose';
import * as Expensicons from '../../../components/Icon/Expensicons';
import * as Illustrations from '../../../components/Icon/Illustrations';
@@ -28,8 +27,8 @@ import * as PaymentUtils from '../../../libs/PaymentUtils';
import cardPropTypes from '../../../components/cardPropTypes';
import userWalletPropTypes from '../../EnablePayments/userWalletPropTypes';
import ROUTES from '../../../ROUTES';
-import OfflineIndicator from '../../../components/OfflineIndicator';
import FormAlertWithSubmitButton from '../../../components/FormAlertWithSubmitButton';
+import {withNetwork} from '../../../components/OnyxProvider';
const propTypes = {
/** User's wallet information */
@@ -296,7 +295,6 @@ class TransferBalancePage extends React.Component {
isAlertVisible={!_.isEmpty(error)}
/>
-
);
}
diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js
index 3dadbc80f92d..4ca5555059fb 100755
--- a/src/pages/settings/Profile/ProfilePage.js
+++ b/src/pages/settings/Profile/ProfilePage.js
@@ -19,7 +19,6 @@ import LoginField from './LoginField';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import compose from '../../../libs/compose';
import Button from '../../../components/Button';
-import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
import FixedFooter from '../../../components/FixedFooter';
import TextInput from '../../../components/TextInput';
import Picker from '../../../components/Picker';
@@ -223,99 +222,97 @@ class ProfilePage extends Component {
return (
-
- Navigation.navigate(ROUTES.SETTINGS)}
- onCloseButtonPress={() => Navigation.dismissModal(true)}
+ Navigation.navigate(ROUTES.SETTINGS)}
+ onCloseButtonPress={() => Navigation.dismissModal(true)}
+ />
+
+
-
-
-
- {this.props.translate('profilePage.tellUsAboutYourself')}
-
- this.setState({firstName})}
- onChangeLastName={lastName => this.setState({lastName})}
- style={[styles.mt4, styles.mb4]}
- />
-
- {
- const hasSelfSelectedPronouns = pronouns === CONST.PRONOUNS.SELF_SELECT;
- this.setState({
- pronouns: hasSelfSelectedPronouns ? '' : pronouns,
- hasSelfSelectedPronouns,
- });
- }}
- items={pronounsList}
- placeholder={{
- value: '',
- label: this.props.translate('profilePage.selectYourPronouns'),
- }}
- value={pronounsPickerValue}
- />
- {this.state.hasSelfSelectedPronouns && (
-
- this.setState({pronouns})}
- placeholder={this.props.translate('profilePage.selfSelectYourPronoun')}
- errorText={PersonalDetails.getMaxCharacterError(this.state.hasPronounError)}
- />
-
- )}
-
-
-
-
- this.setState({selectedTimezone})}
- items={timezones}
- isDisabled={this.state.isAutomaticTimezone}
- value={this.state.selectedTimezone}
- />
-
-
+ {this.props.translate('profilePage.tellUsAboutYourself')}
+
+ this.setState({firstName})}
+ onChangeLastName={lastName => this.setState({lastName})}
+ style={[styles.mt4, styles.mb4]}
+ />
+
+ {
+ const hasSelfSelectedPronouns = pronouns === CONST.PRONOUNS.SELF_SELECT;
+ this.setState({
+ pronouns: hasSelfSelectedPronouns ? '' : pronouns,
+ hasSelfSelectedPronouns,
+ });
+ }}
+ items={pronounsList}
+ placeholder={{
+ value: '',
+ label: this.props.translate('profilePage.selectYourPronouns'),
+ }}
+ value={pronounsPickerValue}
/>
-
-
-
-
+
+
+
+
+
+
);
}
diff --git a/src/pages/settings/Security/CloseAccountPage.js b/src/pages/settings/Security/CloseAccountPage.js
index e57ee744b1d0..96e8aa70be4a 100644
--- a/src/pages/settings/Security/CloseAccountPage.js
+++ b/src/pages/settings/Security/CloseAccountPage.js
@@ -15,7 +15,6 @@ import Button from '../../../components/Button';
import Text from '../../../components/Text';
import FixedFooter from '../../../components/FixedFooter';
import ConfirmModal from '../../../components/ConfirmModal';
-import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
import * as CloseAccount from '../../../libs/actions/CloseAccount';
@@ -61,84 +60,82 @@ class CloseAccountPage extends Component {
const userEmailOrPhone = Str.removeSMSDomain(this.props.session.email);
return (
-
- Navigation.navigate(ROUTES.SETTINGS_SECURITY)}
- onCloseButtonPress={() => Navigation.dismissModal(true)}
+ Navigation.navigate(ROUTES.SETTINGS_SECURITY)}
+ onCloseButtonPress={() => Navigation.dismissModal(true)}
+ />
+
+ {this.props.translate('closeAccountPage.reasonForLeavingPrompt')}
+ this.setState({reasonForLeaving})}
+ label={this.props.translate('closeAccountPage.enterMessageHere')}
+ containerStyles={[styles.mt5, styles.closeAccountMessageInput]}
/>
-
- {this.props.translate('closeAccountPage.reasonForLeavingPrompt')}
- this.setState({reasonForLeaving})}
- label={this.props.translate('closeAccountPage.enterMessageHere')}
- containerStyles={[styles.mt5, styles.closeAccountMessageInput]}
- />
-
-
- {this.props.translate('closeAccountPage.closeAccountWarning')}
-
- {' '}
- {this.props.translate('closeAccountPage.closeAccountPermanentlyDeleteData')}
+
+
+ {this.props.translate('closeAccountPage.closeAccountWarning')}
-
-
- {this.props.translate('closeAccountPage.defaultContact')}
+ {' '}
+ {this.props.translate('closeAccountPage.closeAccountPermanentlyDeleteData')}
+
+
+
+ {this.props.translate('closeAccountPage.defaultContact')}
+
+ {' '}
+ {userEmailOrPhone}
+
+ this.setState({phoneOrEmail: phoneOrEmail.toLowerCase()})}
+ label={this.props.translate('closeAccountPage.enterDefaultContact')}
+ containerStyles={[styles.mt5]}
+ />
+
+
+
+
+ {this.props.translate('closeAccountPage.closeAccountActionRequired')}
+ {' '}
+ { Linking.openURL('https://community.expensify.com/discussion/4724/faq-why-cant-i-close-my-account'); }}
+ >
+ {this.props.translate('common.here')}
{' '}
- {userEmailOrPhone}
+ {this.props.translate('closeAccountPage.closeAccountTryAgainAfter')}
- this.setState({phoneOrEmail: phoneOrEmail.toLowerCase()})}
- label={this.props.translate('closeAccountPage.enterDefaultContact')}
- containerStyles={[styles.mt5]}
- />
-
-
-
-
- {this.props.translate('closeAccountPage.closeAccountActionRequired')}
- {' '}
- { Linking.openURL('https://community.expensify.com/discussion/4724/faq-why-cant-i-close-my-account'); }}
- >
- {this.props.translate('common.here')}
-
- {' '}
- {this.props.translate('closeAccountPage.closeAccountTryAgainAfter')}
-
- )}
- onConfirm={CloseAccount.clearError}
- isVisible={Boolean(this.props.closeAccount.error)}
- shouldShowCancelButton={false}
- />
-
+ )}
+ onConfirm={CloseAccount.clearError}
+ isVisible={Boolean(this.props.closeAccount.error)}
+ shouldShowCancelButton={false}
+ />
);
}
diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js
index 0940abd51d55..ec3906eed06e 100644
--- a/src/pages/workspace/WorkspaceInvitePage.js
+++ b/src/pages/workspace/WorkspaceInvitePage.js
@@ -13,7 +13,6 @@ import compose from '../../libs/compose';
import ONYXKEYS from '../../ONYXKEYS';
import * as Policy from '../../libs/actions/Policy';
import TextInput from '../../components/TextInput';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import FormAlertWithSubmitButton from '../../components/FormAlertWithSubmitButton';
import OptionsSelector from '../../components/OptionsSelector';
import * as OptionsListUtils from '../../libs/OptionsListUtils';
@@ -244,7 +243,7 @@ class WorkspaceInvitePage extends React.Component {
return (
{({didScreenTransitionEnd}) => (
-
+ <>
-
+ >
)}
);
diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js
index 5740c74ae2e4..1dae4d8d5b67 100644
--- a/src/pages/workspace/WorkspaceNewRoomPage.js
+++ b/src/pages/workspace/WorkspaceNewRoomPage.js
@@ -20,7 +20,6 @@ import Button from '../../components/Button';
import FixedFooter from '../../components/FixedFooter';
import Permissions from '../../libs/Permissions';
import Log from '../../libs/Log';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import * as ValidationUtils from '../../libs/ValidationUtils';
const propTypes = {
@@ -151,52 +150,50 @@ class WorkspaceNewRoomPage extends React.Component {
return (
-
- Navigation.dismissModal()}
- />
-
-
- this.clearErrorAndSetValue('roomName', roomName)}
- />
-
-
- this.clearErrorAndSetValue('policyID', policyID)}
- />
-
-
- this.setState({visibility})}
- />
-
-
- {_.find(visibilityOptions, option => option.value === this.state.visibility).description}
-
-
-
-
-
+
+
+ this.setState({visibility})}
+ />
+
+
+ {_.find(visibilityOptions, option => option.value === this.state.visibility).description}
+
+
+
+
+
);
}
diff --git a/src/pages/workspace/WorkspacePageWithSections.js b/src/pages/workspace/WorkspacePageWithSections.js
index 6eaf7118fca4..d1acbc2306c4 100644
--- a/src/pages/workspace/WorkspacePageWithSections.js
+++ b/src/pages/workspace/WorkspacePageWithSections.js
@@ -16,7 +16,6 @@ import * as BankAccounts from '../../libs/actions/BankAccounts';
import BankAccount from '../../libs/models/BankAccount';
import reimbursementAccountPropTypes from '../ReimbursementAccount/reimbursementAccountPropTypes';
import userPropTypes from '../settings/userPropTypes';
-import KeyboardAvoidingView from '../../components/KeyboardAvoidingView';
import withFullPolicy from './withFullPolicy';
import {withNetwork} from '../../components/OnyxProvider';
import networkPropTypes from '../../components/networkPropTypes';
@@ -96,35 +95,33 @@ class WorkspacePageWithSections extends React.Component {
return (
-
- Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policyID))}
- onCloseButtonPress={() => Navigation.dismissModal()}
- />
- {this.props.reimbursementAccount.loading ? (
-
-
-
- ) : (
- <>
-
-
-
- {this.props.children(hasVBA, policyID, isUsingECard)}
-
-
-
- {this.props.footer}
- >
- )}
-
+ Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policyID))}
+ onCloseButtonPress={() => Navigation.dismissModal()}
+ />
+ {this.props.reimbursementAccount.loading ? (
+
+
+
+ ) : (
+ <>
+
+
+
+ {this.props.children(hasVBA, policyID, isUsingECard)}
+
+
+
+ {this.props.footer}
+ >
+ )}
);
}
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 31efe3cb6be2..4b01cac73fa1 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -670,7 +670,8 @@ const styles = {
},
offlineIndicatorMobile: {
- marginLeft: 25,
+ paddingLeft: 20,
+ paddingBottom: 9,
},
// Actions
@@ -1367,7 +1368,6 @@ const styles = {
},
chatFooter: {
- minHeight: 65,
marginBottom: 5,
paddingLeft: 20,
paddingRight: 20,