Skip to content

Commit

Permalink
Merge branch 'main' into df/19631
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangzinh committed Jun 17, 2023
2 parents 7d468e4 + 83ab016 commit f4ca4c8
Show file tree
Hide file tree
Showing 50 changed files with 460 additions and 310 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001032805
versionName "1.3.28-5"
versionCode 1001032900
versionName "1.3.29-0"
}

splits {
Expand Down
4 changes: 2 additions & 2 deletions ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.3.28</string>
<string>1.3.29</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.3.28.5</string>
<string>1.3.29.0</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.3.28</string>
<string>1.3.29</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.3.28.5</string>
<string>1.3.29.0</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions 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.3.28-5",
"version": "1.3.29-0",
"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
1 change: 1 addition & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -2485,6 +2485,7 @@ const CONST = {
MODERATION: {
MODERATOR_DECISION_PENDING: 'pending',
MODERATOR_DECISION_PENDING_HIDE: 'pendingHide',
MODERATOR_DECISION_PENDING_REMOVE: 'pendingRemove',
MODERATOR_DECISION_APPROVED: 'approved',
MODERATOR_DECISION_HIDDEN: 'hidden',
FLAG_SEVERITY_SPAM: 'spam',
Expand Down
6 changes: 1 addition & 5 deletions src/components/CheckboxWithLabel.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react';
import React, {useState} from 'react';
import PropTypes from 'prop-types';
import {View} from 'react-native';
import _ from 'underscore';
Expand Down Expand Up @@ -89,10 +89,6 @@ function CheckboxWithLabel(props) {
setIsChecked(newState);
};

useEffect(() => {
setIsChecked(props.isChecked);
}, [props.isChecked]);

const LabelComponent = props.LabelComponent;

return (
Expand Down
24 changes: 17 additions & 7 deletions src/components/Form.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useState, useEffect, useCallback, useRef} from 'react';
import React, {useState, useEffect, useCallback, useMemo, useRef} from 'react';
import lodashGet from 'lodash/get';
import {Keyboard, ScrollView, StyleSheet} from 'react-native';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -95,6 +95,7 @@ function Form(props) {
const formContentRef = useRef(null);
const inputRefs = useRef({});
const touchedInputs = useRef({});
const isFirstRender = useRef(true);

const {validate, onSubmit, children} = props;

Expand Down Expand Up @@ -146,12 +147,21 @@ function Form(props) {
);

useEffect(() => {
// We want to skip Form validation on initial render.
// This also avoids a bug where we immediately clear server errors when the loading indicator unmounts and Form remounts with server errors.
if (isFirstRender.current) {
isFirstRender.current = false;
return;
}

onValidate(inputValues);
}, [onValidate, inputValues]);

const getErrorMessage = useCallback(() => {
// eslint-disable-next-line react-hooks/exhaustive-deps -- we just want to revalidate the form on update if the preferred locale changed on another device so that errors get translated
}, [props.preferredLocale]);

const errorMessage = useMemo(() => {
const latestErrorMessage = ErrorUtils.getLatestErrorMessage(props.formState);
return props.formState.error || (typeof latestErrorMessage === 'string' ? latestErrorMessage : '');
return typeof latestErrorMessage === 'string' ? latestErrorMessage : '';
}, [props.formState]);

/**
Expand Down Expand Up @@ -325,9 +335,9 @@ function Form(props) {
{props.isSubmitButtonVisible && (
<FormAlertWithSubmitButton
buttonText={props.submitButtonText}
isAlertVisible={_.size(errors) > 0 || Boolean(getErrorMessage()) || !_.isEmpty(props.formState.errorFields)}
isAlertVisible={_.size(errors) > 0 || Boolean(errorMessage) || !_.isEmpty(props.formState.errorFields)}
isLoading={props.formState.isLoading}
message={_.isEmpty(props.formState.errorFields) ? getErrorMessage() : null}
message={_.isEmpty(props.formState.errorFields) ? errorMessage : null}
onSubmit={submit}
footerContent={props.footerContent}
onFixTheErrorsLinkPressed={() => {
Expand Down Expand Up @@ -363,7 +373,7 @@ function Form(props) {
errors,
formContentRef,
formRef,
getErrorMessage,
errorMessage,
inputRefs,
inputValues,
submit,
Expand Down
13 changes: 9 additions & 4 deletions src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import htmlRendererPropTypes from './htmlRendererPropTypes';
import AttachmentModal from '../../AttachmentModal';
import styles from '../../../styles/styles';
import ThumbnailImage from '../../ThumbnailImage';
import PressableWithoutFocus from '../../PressableWithoutFocus';
import PressableWithoutFocus from '../../Pressable/PressableWithoutFocus';
import CONST from '../../../CONST';
import {ShowContextMenuContext, showContextMenuForReport} from '../../ShowContextMenuContext';
import tryResolveUrlFromApiRoot from '../../../libs/tryResolveUrlFromApiRoot';
import * as ReportUtils from '../../../libs/ReportUtils';
import withLocalize, {withLocalizePropTypes} from '../../withLocalize';

const propTypes = {...htmlRendererPropTypes, ...withLocalizePropTypes};

function ImageRenderer(props) {
const htmlAttribs = props.tnode.attributes;
Expand Down Expand Up @@ -60,9 +63,11 @@ function ImageRenderer(props) {
>
{({show}) => (
<PressableWithoutFocus
style={styles.noOutline}
style={[styles.noOutline]}
onPress={show}
onLongPress={(event) => showContextMenuForReport(event, anchor, report.reportID, action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
accessibilityRole="imagebutton"
accessibilityLabel={props.translate('accessibilityHints.viewAttachment')}
>
<ThumbnailImage
previewSourceURL={previewSource}
Expand All @@ -79,7 +84,7 @@ function ImageRenderer(props) {
);
}

ImageRenderer.propTypes = htmlRendererPropTypes;
ImageRenderer.propTypes = propTypes;
ImageRenderer.displayName = 'ImageRenderer';

export default ImageRenderer;
export default withLocalize(ImageRenderer);
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ function MentionUserRenderer(props) {
href={ROUTES.getDetailsRoute(loginWithoutLeadingAt)}
style={[_.omit(props.style, 'color'), StyleUtils.getMentionStyle(isOurMention), {color: StyleUtils.getMentionTextColor(isOurMention)}]}
onPress={() => showUserDetails(loginWithoutLeadingAt)}
// Add testID so it is NOT selected as an anchor tag by SelectionScraper
testID="span"
>
<TNodeChildrenRenderer tnode={props.tnode} />
</TextLink>
Expand Down
4 changes: 2 additions & 2 deletions src/components/HeaderWithBackButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ const defaultProps = {
title: '',
subtitle: '',
onDownloadButtonPress: () => {},
onBackButtonPress: Navigation.goBack,
onCloseButtonPress: Navigation.dismissModal,
onBackButtonPress: () => Navigation.goBack(),
onCloseButtonPress: () => Navigation.dismissModal(),
onThreeDotsButtonPress: () => {},
shouldShowBorderBottom: false,
shouldShowDownloadButton: false,
Expand Down
7 changes: 6 additions & 1 deletion src/components/LHNOptionsList/OptionRowLHN.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ function OptionRowLHN(props) {
const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor;

const hasBrickError = optionItem.brickRoadIndicator === CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
const shouldShowGreenDotIndicator = !hasBrickError && (optionItem.isUnreadWithMention || (optionItem.hasOutstandingIOU && !optionItem.isIOUReportOwner));
const shouldShowGreenDotIndicator =
!hasBrickError &&
(optionItem.isUnreadWithMention ||
(optionItem.hasOutstandingIOU && !optionItem.isIOUReportOwner) ||
(optionItem.isTaskReport && optionItem.isTaskAssignee && !optionItem.isTaskCompleted));

/**
* Show the ReportActionContextMenu modal popover.
Expand All @@ -104,6 +108,7 @@ function OptionRowLHN(props) {
false,
false,
optionItem.isPinned,
optionItem.isUnread,
);
};

Expand Down
8 changes: 6 additions & 2 deletions src/components/OfflineWithFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ function applyStrikeThrough(children) {

function OfflineWithFeedback(props) {
const hasErrors = !_.isEmpty(props.errors);

// Some errors have a null message. This is used to apply opacity only and to avoid showing redundant messages.
const errorMessages = _.omit(props.errors, (e) => e === null);
const hasErrorMessages = !_.isEmpty(errorMessages);
const isOfflinePendingAction = props.network.isOffline && props.pendingAction;
const isUpdateOrDeleteError = hasErrors && (props.pendingAction === 'delete' || props.pendingAction === 'update');
const isAddError = hasErrors && props.pendingAction === 'add';
Expand All @@ -111,11 +115,11 @@ function OfflineWithFeedback(props) {
{children}
</View>
)}
{props.shouldShowErrorMessages && hasErrors && (
{props.shouldShowErrorMessages && hasErrorMessages && (
<View style={StyleUtils.combineStyles(styles.offlineFeedback.error, props.errorRowStyles)}>
<DotIndicatorMessage
style={[styles.flex1]}
messages={props.errors}
messages={errorMessages}
type="error"
/>
<Tooltip text={props.translate('common.close')}>
Expand Down
9 changes: 6 additions & 3 deletions src/components/PinButton.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import {Pressable} from 'react-native';
import styles from '../styles/styles';
import themeColors from '../styles/themes/default';
import Icon from './Icon';
Expand All @@ -9,6 +8,7 @@ import reportPropTypes from '../pages/reportPropTypes';
import * as Report from '../libs/actions/Report';
import * as Expensicons from './Icon/Expensicons';
import * as Session from '../libs/actions/Session';
import PressableWithFeedback from './Pressable/PressableWithFeedback';

const propTypes = {
/** Report to pin */
Expand All @@ -23,15 +23,18 @@ const defaultProps = {
function PinButton(props) {
return (
<Tooltip text={props.report.isPinned ? props.translate('common.unPin') : props.translate('common.pin')}>
<Pressable
<PressableWithFeedback
onPress={Session.checkIfActionIsAllowed(() => Report.togglePinnedState(props.report.reportID, props.report.isPinned))}
style={[styles.touchableButtonImage]}
accessibilityState={{checked: props.report.isPinned}}
accessibilityLabel={props.report.isPinned ? props.translate('common.unPin') : props.translate('common.pin')}
accessibilityRole="button"
>
<Icon
src={Expensicons.Pin}
fill={props.report.isPinned ? themeColors.heading : themeColors.icon}
/>
</Pressable>
</PressableWithFeedback>
</Tooltip>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Pressable/PressableWithFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import * as StyleUtils from '../../styles/StyleUtils';
const omittedProps = ['style', 'pressStyle', 'hoverStyle', 'focusStyle', 'wrapperStyle'];

const PressableWithFeedbackPropTypes = {
..._.omit(GenericPressablePropTypes.pressablePropTypes, omittedProps),
...GenericPressablePropTypes.pressablePropTypes,
/**
* Determines what opacity value should be applied to the underlaying view when Pressable is pressed.
* To disable dimming, pass 1 as pressDimmingValue
Expand All @@ -31,7 +31,7 @@ const PressableWithFeedbackPropTypes = {
};

const PressableWithFeedbackDefaultProps = {
..._.omit(GenericPressablePropTypes.defaultProps, omittedProps),
...GenericPressablePropTypes.defaultProps,
pressDimmingValue: variables.pressDimValue,
hoverDimmingValue: variables.hoverDimValue,
nativeID: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import {Pressable} from 'react-native';
import _ from 'underscore';
import PropTypes from 'prop-types';
import GenericPressable from './GenericPressable';
import genericPressablePropTypes from './GenericPressable/PropTypes';

const propTypes = {
/** Element that should be clickable */
Expand All @@ -14,11 +16,14 @@ const propTypes = {

/** Styles that should be passed to touchable container */
// eslint-disable-next-line react/forbid-prop-types
styles: PropTypes.arrayOf(PropTypes.object),
style: PropTypes.arrayOf(PropTypes.object),

/** Proptypes of pressable component used for implementation */
...genericPressablePropTypes.pressablePropTypes,
};

const defaultProps = {
styles: [],
style: [],
onLongPress: undefined,
};

Expand All @@ -41,15 +46,18 @@ class PressableWithoutFocus extends React.Component {
}

render() {
const restProps = _.omit(this.props, ['children', 'onPress', 'onLongPress', 'style']);
return (
<Pressable
<GenericPressable
onPress={this.pressAndBlur}
onLongPress={this.props.onLongPress}
ref={(el) => (this.pressableRef = el)}
style={this.props.styles}
style={this.props.style}
// eslint-disable-next-line react/jsx-props-no-spreading
{...restProps}
>
{this.props.children}
</Pressable>
</GenericPressable>
);
}
}
Expand Down
8 changes: 1 addition & 7 deletions src/components/QRCode/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ const propTypes = {
* The QRCode background color
*/
backgroundColor: PropTypes.string,

/**
* The QRCode logo background color
*/
logoBackgroundColor: PropTypes.string,
/**
* Function to retrieve the internal component ref and be able to call it's
* methods
Expand All @@ -50,7 +45,6 @@ const defaultProps = {
logo: undefined,
size: 120,
color: defaultTheme.text,
logoBackgroundColor: defaultTheme.icon,
backgroundColor: defaultTheme.highlightBG,
getRef: undefined,
logoRatio: CONST.QR.DEFAULT_LOGO_SIZE_RATIO,
Expand All @@ -64,7 +58,7 @@ function QRCode(props) {
value={props.url}
size={props.size}
logo={props.logo}
logoBackgroundColor={props.logoBackgroundColor}
logoBackgroundColor={props.backgroundColor}
logoSize={props.size * props.logoRatio}
logoMargin={props.size * props.logoMarginRatio}
logoBorderRadius={props.size}
Expand Down
Loading

0 comments on commit f4ca4c8

Please sign in to comment.