Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into maria-transfer-wallet…
Browse files Browse the repository at this point in the history
…-balance-error-handling

# Conflicts:
#	src/pages/settings/Payments/TransferBalancePage.js
  • Loading branch information
MariaHCD committed Jul 27, 2022
2 parents 77e16bf + 7c98c20 commit 99d5d3e
Show file tree
Hide file tree
Showing 45 changed files with 1,170 additions and 1,061 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001018508
versionName "1.1.85-8"
versionCode 1001018604
versionName "1.1.86-4"
}
splits {
abi {
Expand Down
2 changes: 2 additions & 0 deletions contributingGuides/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Payment for your contributions will be made no less than 7 days after the pull r

New contributors are limited to working on one job at a time, however experienced contributors may work on numerous jobs simultaneously.

Please be aware that compensation for any support in solving an issue is provided **entirely at Expensify’s discretion**. Personal time or resources applied towards investigating a proposal **will not guarantee compensation**. Compensation is only guaranteed to those who **[propose a solution and get hired for that job](https://github.com/Expensify/App/blob/main/contributingGuides/CONTRIBUTING.md#propose-a-solution-for-the-job)**. We understand there may be cases where a selected proposal may take inspiration from a previous proposal. Unfortunately, it’s not possible for us to evaluate every individual case and we have no process that can efficiently do so. Issues with higher rewards come with higher risk factors so try to keep things civil and make the best proposal you can. Once again, **any information provided may not necessarily lead to you getting hired for that issue or compensated in any way.**

## Finding Jobs
There are two ways you can find a job that you can contribute to:

Expand Down
4 changes: 2 additions & 2 deletions ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.85</string>
<string>1.1.86</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -30,7 +30,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.1.85.8</string>
<string>1.1.86.4</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
4 changes: 2 additions & 2 deletions ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.85</string>
<string>1.1.86</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.85.8</string>
<string>1.1.86.4</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.1.85-8",
"version": "1.1.86-4",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
Expand Down
5 changes: 3 additions & 2 deletions src/components/AddPlaidBankAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ class AddPlaidBankAccount extends React.Component {
<ActivityIndicator color={themeColors.spinner} size="large" />
</View>
)}
{this.props.plaidData.error && (
{Boolean(this.props.plaidData.error) && (
<Text style={[styles.formError, styles.mh5]}>
{this.props.plaidData.error}
</Text>
)}
{token && (
{Boolean(token) && (
<PlaidLink
token={token}
onSuccess={({publicToken, metadata}) => {
Expand Down Expand Up @@ -217,6 +217,7 @@ export default compose(
},
plaidLinkToken: {
key: ONYXKEYS.PLAID_LINK_TOKEN,
initWithStoredValues: false,
},
}),
)(AddPlaidBankAccount);
8 changes: 7 additions & 1 deletion src/components/Avatar.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import themeColors from '../styles/themes/default';
import CONST from '../CONST';
import * as StyleUtils from '../styles/StyleUtils';
import * as Expensicons from './Icon/Expensicons';
import getAvatarDefaultSource from '../libs/getAvatarDefaultSource';

const propTypes = {
/** Source for the avatar. Can be a URL or an icon. */
Expand Down Expand Up @@ -70,7 +71,12 @@ class Avatar extends PureComponent {
/>
)
: (
<Image source={{uri: this.props.source}} style={imageStyle} onError={() => this.setState({imageError: true})} />
<Image
source={{uri: this.props.source}}
defaultSource={getAvatarDefaultSource(this.props.source)}
style={imageStyle}
onError={() => this.setState({imageError: true})}
/>
)}
</View>
);
Expand Down
25 changes: 20 additions & 5 deletions src/components/EmojiPicker/EmojiPickerMenu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ class EmojiPickerMenu extends Component {
this.isMobileLandscape = this.isMobileLandscape.bind(this);
this.onSelectionChange = this.onSelectionChange.bind(this);
this.updatePreferredSkinTone = this.updatePreferredSkinTone.bind(this);
this.setFirstNonHeaderIndex = this.setFirstNonHeaderIndex.bind(this);

this.currentScrollOffset = 0;
this.firstNonHeaderIndex = 0;

this.state = {
filteredEmojis: this.emojis,
Expand All @@ -111,6 +113,7 @@ class EmojiPickerMenu extends Component {
this.props.forwardedRef(this.searchInput);
}
this.setupEventHandlers();
this.setFirstNonHeaderIndex(this.emojis);
}

componentWillUnmount() {
Expand All @@ -126,6 +129,14 @@ class EmojiPickerMenu extends Component {
this.setState({selection: event.nativeEvent.selection});
}

/**
* Find and store index of the first emoji item
* @param {Array} filteredEmojis
*/
setFirstNonHeaderIndex(filteredEmojis) {
this.firstNonHeaderIndex = _.findIndex(filteredEmojis, item => !item.spacer && !item.header);
}

/**
* Setup and attach keypress/mouse handlers for highlight navigation.
*/
Expand Down Expand Up @@ -214,10 +225,12 @@ class EmojiPickerMenu extends Component {
* @param {String} arrowKey
*/
highlightAdjacentEmoji(arrowKey) {
const firstNonHeaderIndex = this.state.filteredEmojis.length === this.emojis.length ? this.numColumns : 0;
if (this.state.filteredEmojis.length === 0) {
return;
}

// Arrow Down and Arrow Right enable arrow navigation when search is focused
if (this.searchInput && this.searchInput.isFocused() && this.state.filteredEmojis.length) {
if (this.searchInput && this.searchInput.isFocused()) {
if (arrowKey !== 'ArrowDown' && arrowKey !== 'ArrowRight') {
return;
}
Expand All @@ -242,7 +255,7 @@ class EmojiPickerMenu extends Component {
// If nothing is highlighted and an arrow key is pressed
// select the first emoji
if (this.state.highlightedIndex === -1) {
this.setState({highlightedIndex: firstNonHeaderIndex});
this.setState({highlightedIndex: this.firstNonHeaderIndex});
this.scrollToHighlightedIndex();
return;
}
Expand Down Expand Up @@ -273,7 +286,7 @@ class EmojiPickerMenu extends Component {
break;
case 'ArrowLeft':
move(-1,
() => this.state.highlightedIndex - 1 < firstNonHeaderIndex,
() => this.state.highlightedIndex - 1 < this.firstNonHeaderIndex,
() => {
// Reaching start of the list, arrow left set the focus to searchInput.
this.focusInputWithTextSelect();
Expand All @@ -286,7 +299,7 @@ class EmojiPickerMenu extends Component {
case 'ArrowUp':
move(
-this.numColumns,
() => this.state.highlightedIndex - this.numColumns < firstNonHeaderIndex,
() => this.state.highlightedIndex - this.numColumns < this.firstNonHeaderIndex,
() => {
// Reaching start of the list, arrow up set the focus to searchInput.
this.focusInputWithTextSelect();
Expand Down Expand Up @@ -356,6 +369,7 @@ class EmojiPickerMenu extends Component {
headerIndices: this.unfilteredHeaderIndices,
highlightedIndex: -1,
});
this.setFirstNonHeaderIndex(this.emojis);
return;
}

Expand All @@ -370,6 +384,7 @@ class EmojiPickerMenu extends Component {

// Remove sticky header indices. There are no headers while searching and we don't want to make emojis sticky
this.setState({filteredEmojis: newFilteredEmojiList, headerIndices: [], highlightedIndex: 0});
this.setFirstNonHeaderIndex(newFilteredEmojiList);
}

/**
Expand Down
60 changes: 17 additions & 43 deletions src/components/ScreenWrapper.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'underscore';
import React from 'react';
import PropTypes from 'prop-types';
import {View, KeyboardAvoidingView} from 'react-native';
import {View} from 'react-native';
import {SafeAreaInsetsContext} from 'react-native-safe-area-context';
import {withOnyx} from 'react-native-onyx';
import styles from '../styles/styles';
Expand All @@ -15,10 +15,6 @@ import compose from '../libs/compose';
import ONYXKEYS from '../ONYXKEYS';
import CONST from '../CONST';
import withNavigation from './withNavigation';
import withWindowDimensions from './withWindowDimensions';
import OfflineIndicator from './OfflineIndicator';
import {withNetwork} from './OnyxProvider';
import networkPropTypes from './networkPropTypes';

const propTypes = {
/** Array of additional styles to add */
Expand All @@ -39,13 +35,6 @@ const propTypes = {
// Called when navigated Screen's transition is finished.
onTransitionEnd: PropTypes.func,

/** Is the window width narrow, like on a mobile device */
isSmallScreenWidth: PropTypes.bool.isRequired,

/** 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']),

// react-navigation navigation object available to screen components
navigation: PropTypes.shape({
// Method to attach listener to Navigation state.
Expand All @@ -58,9 +47,6 @@ const propTypes = {
willAlertModalBecomeVisible: PropTypes.bool,
}),

/** Information about the network */
network: networkPropTypes.isRequired,

};

const defaultProps = {
Expand All @@ -72,7 +58,6 @@ const defaultProps = {
addListener: () => {},
},
modal: {},
keyboardAvoidingViewBehavior: 'padding',
};

class ScreenWrapper extends React.Component {
Expand Down Expand Up @@ -120,36 +105,27 @@ class ScreenWrapper extends React.Component {
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) {
if (this.props.includePaddingBottom) {
paddingStyle.paddingBottom = paddingBottom;
}

return (
<View
style={[
...this.props.style,
styles.flex1,
paddingStyle,
]}
<View style={[
...this.props.style,
styles.flex1,
paddingStyle,
]}
>
<KeyboardAvoidingView style={[styles.w100, styles.h100]} behavior={this.props.keyboardAvoidingViewBehavior}>
<HeaderGap />
{// 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
}
<KeyboardShortcutsModal />
{this.props.isSmallScreenWidth && this.props.network.isOffline && (
<View style={styles.chatItemComposeSecondaryRow}>
<OfflineIndicator />
</View>
)}
</KeyboardAvoidingView>
<HeaderGap />
{// 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
}
<KeyboardShortcutsModal />
</View>
);
}}
Expand All @@ -163,11 +139,9 @@ ScreenWrapper.defaultProps = defaultProps;

export default compose(
withNavigation,
withWindowDimensions,
withOnyx({
modal: {
key: ONYXKEYS.MODAL,
},
}),
withNetwork(),
)(ScreenWrapper);
4 changes: 0 additions & 4 deletions src/components/TextInput/BaseTextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import * as Expensicons from '../Icon/Expensicons';
import Text from '../Text';
import * as styleConst from './styleConst';
import * as StyleUtils from '../../styles/StyleUtils';
import variables from '../../styles/variables';
import getSecureEntryKeyboardType from '../../libs/getSecureEntryKeyboardType';

class BaseTextInput extends Component {
Expand All @@ -31,7 +30,6 @@ class BaseTextInput extends Component {
passwordHidden: props.secureTextEntry,
textInputWidth: 0,
prefixWidth: 0,
height: variables.componentSizeLarge,

// Value should be kept in state for the autoGrow feature to work - https://github.com/Expensify/App/pull/8232#issuecomment-1077282006
value,
Expand Down Expand Up @@ -214,7 +212,6 @@ class BaseTextInput extends Component {
>
<TouchableWithoutFeedback onPress={this.onPress} focusable={false}>
<View
onLayout={event => this.setState({height: event.nativeEvent.layout.height})}
style={[
textInputContainerStyles,

Expand Down Expand Up @@ -267,7 +264,6 @@ class BaseTextInput extends Component {
!hasLabel && styles.pv0,
this.props.prefixCharacter && StyleUtils.getPaddingLeft(this.state.prefixWidth + styles.pl1.paddingLeft),
this.props.secureTextEntry && styles.secureInput,
{height: this.state.height},
]}
multiline={this.props.multiline}
maxLength={this.props.maxLength}
Expand Down
3 changes: 2 additions & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@ export default {
notOwnerOfFund: 'There was an error setting this card as your default payment method.',
setDefaultFailure: 'Something went wrong. Please chat with Concierge for further assistance.',
},
addBankAccountSuccess: 'Your bank account has successfully been added.',
addBankAccountFailure: 'And unexpected error occurred while trying to add your bank account. Please try again.',
},
transferAmountPage: {
Expand Down Expand Up @@ -569,6 +568,8 @@ export default {
enterPassword: 'Enter Expensify password',
alreadyAdded: 'This account has already been added.',
chooseAccountLabel: 'Account',
successTitle: 'Personal bank account added!',
successMessage: 'Congrats, your bank account is set up and ready to receive reimbursements.',
},
attachmentView: {
unknownFilename: 'Unknown filename',
Expand Down
3 changes: 2 additions & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@ export default {
notOwnerOfFund: 'Ha ocurrido un error al establecer esta tarjeta de crédito como tu método de pago predeterminado.',
setDefaultFailure: 'No se ha podido configurar el método de pago.',
},
addBankAccountSuccess: 'Su cuenta bancaria ha sido añadida con éxito.',
addBankAccountFailure: 'Y ocurrió un error inesperado al intentar agregar su cuenta bancaria. Inténtalo de nuevo.',
},
transferAmountPage: {
Expand Down Expand Up @@ -569,6 +568,8 @@ export default {
enterPassword: 'Escribe tu contraseña de Expensify',
alreadyAdded: 'Esta cuenta ya ha sido agregada.',
chooseAccountLabel: 'Cuenta',
successTitle: '¡Cuenta bancaria personal añadida!',
successMessage: 'Enhorabuena, tu cuenta bancaria está lista para recibir reembolsos.',
},
attachmentView: {
unknownFilename: 'Archivo desconocido',
Expand Down
Loading

0 comments on commit 99d5d3e

Please sign in to comment.