Skip to content

Commit

Permalink
Merge branch 'main' into arrow-feature-signed
Browse files Browse the repository at this point in the history
  • Loading branch information
JediWattson committed Dec 21, 2022
2 parents c257f2c + 89e3eef commit 95069f2
Show file tree
Hide file tree
Showing 36 changed files with 345 additions and 455 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001024201
versionName "1.2.42-1"
versionCode 1001024301
versionName "1.2.43-1"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()

if (isNewArchitectureEnabled()) {
Expand Down
2 changes: 1 addition & 1 deletion contributingGuides/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ All contributors should be a member of **two** Slack channels:
1. #expensify-open-source -- used to ask **general questions**, facilitate **discussions**, and make **feature requests**.
2. #expensify-bugs -- used to discuss or report **bugs** specifically.

To request an invite to these two Slack channels, just email contributors@expensify.com with the subject `Slack Channel Invites` and include a link to your Upwork profile. We'll send you an invite!
To request an invite to these two Slack channels, just email contributors@expensify.com with the subject `Slack Channel Invites` and **include a link to your Upwork profile**. We'll send you an invite!

Note: the Expensify team will not be able to respond to direct messages in Slack.

Expand Down
6 changes: 4 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.2.42</string>
<string>1.2.43</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -30,7 +30,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.2.42.1</string>
<string>1.2.43.1</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down Expand Up @@ -67,6 +67,8 @@
<string>Your camera is used to create chat attachments, documents, and facial capture.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Your location is used to determine your default currency and timezone.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is used to determine your default currency and timezone.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Required for video capture</string>
<key>NSPhotoLibraryAddUsageDescription</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.2.42</string>
<string>1.2.43</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.2.42.1</string>
<string>1.2.43.1</string>
</dict>
</plist>
18 changes: 9 additions & 9 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.2.42-1",
"version": "1.2.43-1",
"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 Expand Up @@ -100,7 +100,7 @@
"react-native-image-picker": "^4.10.2",
"react-native-image-size": "git+https://github.com/Expensify/react-native-image-size#6b5ab5110dc3ed554f8eafbc38d7d87c17147972",
"react-native-modal": "^13.0.0",
"react-native-onyx": "1.0.31",
"react-native-onyx": "1.0.29",
"react-native-pdf": "^6.6.2",
"react-native-performance": "^2.0.0",
"react-native-permissions": "^3.0.1",
Expand Down
1 change: 1 addition & 0 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export default {
CLOSE_ACCOUNT_FORM: 'closeAccount',
PROFILE_SETTINGS_FORM: 'profileSettingsForm',
DISPLAY_NAME_FORM: 'displayNameForm',
NEW_ROOM_FORM: 'newRoomForm',
},

// Whether we should show the compose input or not
Expand Down
16 changes: 10 additions & 6 deletions src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,19 @@ class Form extends React.Component {

// Look for any inputs nested in a custom component, e.g AddressForm or IdentityForm
if (_.isFunction(child.type)) {
const nestedChildren = new child.type(child.props);
const childNode = new child.type(child.props);

if (!React.isValidElement(nestedChildren) || !lodashGet(nestedChildren, 'props.children')) {
return child;
// If the custom component has a render method, use it to get the nested children
const nestedChildren = _.isFunction(childNode.render) ? childNode.render() : childNode;

// Render the custom component if it's a valid React element
// If the custom component has nested children, Loop over them and supply From props
if (React.isValidElement(nestedChildren) || lodashGet(nestedChildren, 'props.children')) {
return this.childrenWrapperWithProps(nestedChildren);
}

return React.cloneElement(nestedChildren, {
children: this.childrenWrapperWithProps(lodashGet(nestedChildren, 'props.children')),
});
// Just render the child if it's custom component not a valid React element, or if it hasn't children
return child;
}

// We check if the child has the inputID prop.
Expand Down
8 changes: 7 additions & 1 deletion src/components/ImageView/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,18 @@ class ImageView extends PureComponent {
}

this.setState({imageHeight: undefined, imageWidth: undefined});
ImageSize.getSize(this.props.url).then(({width, height}) => {
ImageSize.getSize(this.props.url).then(({width, height, rotation}) => {
let imageWidth = width;
let imageHeight = height;
const containerWidth = Math.round(this.props.windowWidth);
const containerHeight = Math.round(this.state.containerHeight);

// On specific Android devices, the dimensions are sometimes returned to us flipped here, with `rotation` set to 90 degrees.
// Swap them back to make sure the image fits nicely in the container. On iOS, the rotation is always undefined, so this does not apply.
if (rotation === 90 || rotation === 270) {
[imageWidth, imageHeight] = [imageHeight, imageWidth];
}

const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth);

imageHeight *= aspectRatio;
Expand Down
1 change: 1 addition & 0 deletions src/components/InvertedFlatList/index.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default forwardRef((props, ref) => (
// Manually invert the FlatList to circumvent a react-native bug that causes ANR (application not responding) on android 13
inverted={false}
style={styles.invert}
ListFooterComponentStyle={styles.invert}
verticalScrollbarPosition="left" // We are mirroring the X and Y axis, so we need to swap the scrollbar position

CellRendererComponent={InvertedCell}
Expand Down
8 changes: 8 additions & 0 deletions src/components/RoomNameInput/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, {Component} from 'react';
import _ from 'underscore';
import CONST from '../../CONST';
import withLocalize from '../withLocalize';
import TextInput from '../TextInput';
Expand Down Expand Up @@ -26,6 +27,11 @@ class RoomNameInput extends Component {
const modifiedRoomName = RoomNameInputUtils.modifyRoomName(roomName);
this.props.onChangeText(modifiedRoomName);

// if custom component has onInputChange, use it to trigger changes (Form input)
if (_.isFunction(this.props.onInputChange)) {
this.props.onInputChange(modifiedRoomName);
}

// Prevent cursor jump behaviour:
// Check if newRoomNameWithHash is the same as modifiedRoomName
// If it is then the room name is valid (does not contain unallowed characters); no action required
Expand Down Expand Up @@ -65,6 +71,8 @@ class RoomNameInput extends Component {
onSelectionChange={event => this.setSelection(event.nativeEvent.selection)}
errorText={this.props.errorText}
autoCapitalize="none"
onBlur={this.props.onBlur}
autoFocus={this.props.autoFocus}
/>
);
}
Expand Down
8 changes: 8 additions & 0 deletions src/components/RoomNameInput/index.native.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, {Component} from 'react';
import _ from 'underscore';
import CONST from '../../CONST';
import withLocalize from '../withLocalize';
import TextInput from '../TextInput';
Expand All @@ -21,6 +22,11 @@ class RoomNameInput extends Component {
const roomName = event.nativeEvent.text;
const modifiedRoomName = RoomNameInputUtils.modifyRoomName(roomName);
this.props.onChangeText(modifiedRoomName);

// if custom component has onInputChange, use it to trigger changes (Form input)
if (_.isFunction(this.props.onInputChange)) {
this.props.onInputChange(modifiedRoomName);
}
}

render() {
Expand All @@ -37,6 +43,8 @@ class RoomNameInput extends Component {
errorText={this.props.errorText}
maxLength={CONST.REPORT.MAX_ROOM_NAME_LENGTH}
keyboardType={keyboardType} // this is a bit hacky solution to a RN issue https://github.com/facebook/react-native/issues/27449
onBlur={this.props.onBlur}
autoFocus={this.props.autoFocus}
/>
);
}
Expand Down
13 changes: 13 additions & 0 deletions src/components/RoomNameInput/roomNameInputPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ const propTypes = {

/** A ref forwarded to the TextInput */
forwardedRef: PropTypes.func,

/** The ID used to uniquely identify the input in a Form */
inputID: PropTypes.string,

/** Callback that is called when the text input is blurred */
onBlur: PropTypes.func,

/** AutoFocus */
autoFocus: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -26,6 +35,10 @@ const defaultProps = {
disabled: false,
errorText: '',
forwardedRef: () => {},

inputID: undefined,
onBlur: () => {},
autoFocus: false,
};

export {propTypes, defaultProps};
1 change: 0 additions & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ export default {
},
profilePage: {
profile: 'Profile',
tellUsAboutYourself: 'Tell us about yourself, we would love to get to know you!',
john: 'John',
doe: 'Doe',
preferredPronouns: 'Preferred pronouns',
Expand Down
1 change: 0 additions & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ export default {
},
profilePage: {
profile: 'Perfil',
tellUsAboutYourself: '¡Cuéntanos algo sobre tí, nos encantaría conocerte!',
john: 'Juan',
doe: 'Nadie',
preferredPronouns: 'Pronombres preferidos',
Expand Down
6 changes: 6 additions & 0 deletions src/libs/Middleware/Logging.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ function Logging(response, request) {
};

if (error.message === CONST.ERROR.FAILED_TO_FETCH) {
// If the command that failed is Log it's possible that the next call to Log may also fail.
// This will lead to infinitely complex log params that can eventually crash the app.
if (request.command === 'Log') {
delete logParams.request;
}

// Throw when we get a "Failed to fetch" error so we can retry. Very common if a user is offline or experiencing an unlikely scenario like
// incorrect url, bad cors headers returned by the server, DNS lookup failure etc.
Log.hmmm('[Network] API request error: Failed to fetch', logParams);
Expand Down
4 changes: 2 additions & 2 deletions src/libs/Navigation/AppNavigator/PublicScreens.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {createStackNavigator} from '@react-navigation/stack';
import SignInPage from '../../../pages/signin/SignInPage';
import SetPasswordPage from '../../../pages/SetPasswordPage';
import ValidateLoginPage from '../../../pages/ValidateLoginPage';
import LogInWithShortLivedTokenPage from '../../../pages/LogInWithShortLivedTokenPage';
import LogInWithShortLivedAuthTokenPage from '../../../pages/LogInWithShortLivedAuthTokenPage';
import ConciergePage from '../../../pages/ConciergePage';
import SCREENS from '../../../SCREENS';
import defaultScreenOptions from './defaultScreenOptions';
Expand All @@ -20,7 +20,7 @@ const PublicScreens = () => (
<RootStack.Screen
name={SCREENS.TRANSITION_FROM_OLD_DOT}
options={defaultScreenOptions}
component={LogInWithShortLivedTokenPage}
component={LogInWithShortLivedAuthTokenPage}
/>
<RootStack.Screen
name="ValidateLogin"
Expand Down
5 changes: 5 additions & 0 deletions src/libs/ReportActionsUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ function getSortedReportActions(reportActions, shouldSortInDescendingOrder = fal
}
const invertedMultiplier = shouldSortInDescendingOrder ? -1 : 1;
reportActions.sort((first, second) => {
// If only one action is a report created action, return the created action first.
if ((first.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED || second.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) && first.actionName !== second.actionName) {
return ((first.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ? -1 : 1) * invertedMultiplier;
}

if (first.created !== second.created) {
return (first.created < second.created ? -1 : 1) * invertedMultiplier;
}
Expand Down
1 change: 1 addition & 0 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ function buildOptimisticCreatedReportAction(ownerEmail) {
return {
0: {
actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
reportActionID: NumberUtils.rand64(),
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
actorAccountID: currentUserAccountID,
message: [
Expand Down
18 changes: 12 additions & 6 deletions src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,13 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment
groupChatReport.lastReadTimestamp = Date.now();
groupChatReport.lastMessageText = groupIOUReportAction.message[0].text;
groupChatReport.lastMessageHtml = groupIOUReportAction.message[0].html;
groupChatReport.pendingFields = {
createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
};

// If we have an existing groupChatReport use it's pending fields, otherwise indicate that we are adding a chat
if (!existingGroupChatReport) {
groupChatReport.pendingFields = {
createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
};
}

const optimisticData = [
{
Expand Down Expand Up @@ -379,9 +383,11 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment
oneOnOneChatReport.lastReadSequenceNumber = oneOnOneChatReportMaxSequenceNumber + 1;
oneOnOneChatReport.lastMessageText = oneOnOneIOUReportAction.message[0].text;
oneOnOneChatReport.lastMessageHtml = oneOnOneIOUReportAction.message[0].html;
oneOnOneChatReport.pendingFields = {
createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
};
if (!existingOneOnOneChatReport) {
oneOnOneChatReport.pendingFields = {
createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
};
}

optimisticData.push(
{
Expand Down
Loading

0 comments on commit 95069f2

Please sign in to comment.