Skip to content

Commit

Permalink
Merge branch 'main' into jules-fixSendMoneyIOUPreviewBug
Browse files Browse the repository at this point in the history
  • Loading branch information
Julesssss committed Mar 7, 2023
2 parents 61024b6 + 71a119f commit 2c37fe3
Show file tree
Hide file tree
Showing 38 changed files with 892 additions and 225 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 1001027800
versionName "1.2.78-0"
versionCode 1001027900
versionName "1.2.79-0"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()

if (isNewArchitectureEnabled()) {
Expand Down
17 changes: 17 additions & 0 deletions assets/emojis.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import Smiley from './images/emoji.svg';
import AnimalsAndNature from './images/emojiCategoryIcons/plant.svg';
import FoodAndDrink from './images/emojiCategoryIcons/hamburger.svg';
import TravelAndPlaces from './images/emojiCategoryIcons/plane.svg';
import Activities from './images/emojiCategoryIcons/soccer-ball.svg';
import Objects from './images/emojiCategoryIcons/light-bulb.svg';
import Symbols from './images/emojiCategoryIcons/peace-sign.svg';
import Flags from './images/emojiCategoryIcons/flag.svg';

/*
* This list is generated from the code here https://github.com/github/gemoji/blob/master/db/emoji.json
* Each code is then converted to hex by replacing the "U+" with "0x"
Expand Down Expand Up @@ -68,6 +77,7 @@ const emojis = [
{
code: 'smileysAndEmotion',
header: true,
icon: Smiley,
},
{
name: 'grinning',
Expand Down Expand Up @@ -6965,6 +6975,7 @@ const emojis = [
{
code: 'animalsAndNature',
header: true,
icon: AnimalsAndNature,
},
{
name: 'monkey_face',
Expand Down Expand Up @@ -8138,6 +8149,7 @@ const emojis = [
{
code: 'foodAndDrink',
header: true,
icon: FoodAndDrink,
},
{
name: 'grapes',
Expand Down Expand Up @@ -9315,6 +9327,7 @@ const emojis = [
{
code: 'travelAndPlaces',
header: true,
icon: TravelAndPlaces,
},
{
name: 'earth_africa',
Expand Down Expand Up @@ -11434,6 +11447,7 @@ const emojis = [
{
code: 'activities',
header: true,
icon: Activities,
},
{
name: 'jack_o_lantern',
Expand Down Expand Up @@ -12271,6 +12285,7 @@ const emojis = [
{
code: 'objects',
header: true,
icon: Objects,
},
{
name: 'eyeglasses',
Expand Down Expand Up @@ -14600,6 +14615,7 @@ const emojis = [
{
code: 'symbols',
header: true,
icon: Symbols,
},
{
name: 'atm',
Expand Down Expand Up @@ -16590,6 +16606,7 @@ const emojis = [
{
code: 'flags',
header: true,
icon: Flags,
},
{
name: 'checkered_flag',
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.2.78</string>
<string>1.2.79</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -30,7 +30,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.2.78.0</string>
<string>1.2.79.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.2.78</string>
<string>1.2.79</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.2.78.0</string>
<string>1.2.79.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.2.78-0",
"version": "1.2.79-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
3 changes: 2 additions & 1 deletion src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ const CONST = {
US_PHONE_WITH_OPTIONAL_COUNTRY_CODE: /^(\+1)?\d{10}$/,
DIGITS_AND_PLUS: /^\+?[0-9]*$/,
PHONE_E164_PLUS: /^\+?[1-9]\d{1,14}$/,
PHONE_WITH_SPECIAL_CHARS: /^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\\./0-9]{0,12}$/,
PHONE_WITH_SPECIAL_CHARS: /^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$/,
ALPHABETIC_CHARS: /[a-zA-Z]+/,
POSITIVE_INTEGER: /^\d+$/,
NON_ALPHA_NUMERIC: /[^A-Za-z0-9+]/g,
Expand All @@ -821,6 +821,7 @@ const CONST = {
EMOJIS: /[\p{Extended_Pictographic}\u200d\u{1f1e6}-\u{1f1ff}\u{1f3fb}-\u{1f3ff}\u{e0020}-\u{e007f}\u20E3\uFE0F]|[#*0-9]\uFE0F?\u20E3/gu,
TAX_ID: /^\d{9}$/,
NON_NUMERIC: /\D/g,
NON_NUMERIC_WITH_PLUS: /[^0-9+]/g,
EMOJI_NAME: /:[\w+-]+:/g,
EMOJI_SUGGESTIONS: /:[a-zA-Z0-9_+-]{1,40}$/,
AFTER_FIRST_LINE_BREAK: /\n.*/g,
Expand Down
2 changes: 2 additions & 0 deletions src/ROUTES.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export default {
SETTINGS_PERSONAL_DETAILS_DATE_OF_BIRTH: `${SETTINGS_PERSONAL_DETAILS}/date-of-birth`,
SETTINGS_PERSONAL_DETAILS_ADDRESS: `${SETTINGS_PERSONAL_DETAILS}/address`,
SETTINGS_CONTACT_METHODS,
SETTINGS_CONTACT_METHOD_DETAILS: `${SETTINGS_CONTACT_METHODS}/:contactMethod/details`,
getEditContactMethodRoute: contactMethod => `${SETTINGS_CONTACT_METHODS}/${encodeURIComponent(contactMethod)}/details`,
NEW_GROUP: 'new/group',
NEW_CHAT: 'new/chat',
REPORT,
Expand Down
49 changes: 35 additions & 14 deletions src/components/AvatarWithIndicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {policyPropTypes} from '../pages/workspace/withPolicy';
import walletTermsPropTypes from '../pages/EnablePayments/walletTermsPropTypes';
import * as PolicyUtils from '../libs/PolicyUtils';
import * as PaymentMethods from '../libs/actions/PaymentMethods';
import * as UserUtils from '../libs/UserUtils';
import themeColors from '../styles/themes/default';

const propTypes = {
/** URL for the avatar */
Expand All @@ -26,6 +28,8 @@ const propTypes = {
/** To show a tooltip on hover */
tooltipText: PropTypes.string,

/* Onyx Props */

/** The employee list of all policies (coming from Onyx) */
policiesMemberList: PropTypes.objectOf(policyMemberPropType),

Expand All @@ -43,6 +47,15 @@ const propTypes = {

/** Information about the user accepting the terms for payments */
walletTerms: walletTermsPropTypes,

/** Login list for the user that is signed in */
loginList: PropTypes.shape({
/** Date login was validated, used to show info indicator status */
validatedDate: PropTypes.string,

/** Field-specific server side errors keyed by microtime */
errorFields: PropTypes.objectOf(PropTypes.objectOf(PropTypes.string)),
}),
};

const defaultProps = {
Expand All @@ -54,45 +67,50 @@ const defaultProps = {
cardList: {},
userWallet: {},
walletTerms: {},
loginList: {},
};

const AvatarWithIndicator = (props) => {
const isLarge = props.size === 'large';
const indicatorStyles = [
styles.alignItemsCenter,
styles.justifyContentCenter,
isLarge ? styles.statusIndicatorLarge : styles.statusIndicator,
];

// If a policy was just deleted from Onyx, then Onyx will pass a null value to the props, and
// those should be cleaned out before doing any error checking
const cleanPolicies = _.pick(props.policies, policy => policy);
const cleanPolicyMembers = _.pick(props.policiesMemberList, member => member);

// All of the error-checking methods are put into an array. This is so that using _.some() will return
// early as soon as the first error is returned. This makes the error checking very efficient since
// we only care if a single error exists anywhere.
// All of the error & info-checking methods are put into an array. This is so that using _.some() will return
// early as soon as the first error / info condition is returned. This makes the checks very efficient since
// we only care if a single error / info condition exists anywhere.
const errorCheckingMethods = [
() => !_.isEmpty(props.userWallet.errors),
() => PaymentMethods.hasPaymentMethodError(props.bankAccountList, props.cardList),
() => _.some(cleanPolicies, PolicyUtils.hasPolicyError),
() => _.some(cleanPolicies, PolicyUtils.hasCustomUnitsError),
() => _.some(cleanPolicyMembers, PolicyUtils.hasPolicyMemberError),
() => UserUtils.hasLoginListError(props.loginList),

// Wallet term errors that are not caused by an IOU (we show the red brick indicator for those in the LHN instead)
() => !_.isEmpty(props.walletTerms.errors) && !props.walletTerms.chatReportID,
];
const shouldShowIndicator = _.some(errorCheckingMethods, errorCheckingMethod => errorCheckingMethod());
const infoCheckingMethods = [
() => UserUtils.hasLoginListInfo(props.loginList),
];
const shouldShowErrorIndicator = _.some(errorCheckingMethods, errorCheckingMethod => errorCheckingMethod());
const shouldShowInfoIndicator = !shouldShowErrorIndicator && _.some(infoCheckingMethods, infoCheckingMethod => infoCheckingMethod());

const indicatorColor = shouldShowErrorIndicator ? themeColors.danger : themeColors.success;
const indicatorStyles = [
styles.alignItemsCenter,
styles.justifyContentCenter,
styles.statusIndicator(indicatorColor),
];

return (
<View style={[isLarge ? styles.avatarLarge : styles.sidebarAvatar]}>
<View style={[styles.sidebarAvatar]}>
<Tooltip text={props.tooltipText}>
<Avatar
imageStyles={[isLarge ? styles.avatarLarge : null]}
source={props.source}
size={props.size}
/>
{shouldShowIndicator && (
{(shouldShowErrorIndicator || shouldShowInfoIndicator) && (
<View style={StyleSheet.flatten(indicatorStyles)} />
)}
</Tooltip>
Expand Down Expand Up @@ -123,4 +141,7 @@ export default withOnyx({
walletTerms: {
key: ONYXKEYS.WALLET_TERMS,
},
loginList: {
key: ONYXKEYS.LOGIN_LIST,
},
})(AvatarWithIndicator);
51 changes: 18 additions & 33 deletions src/components/EmojiPicker/CategoryShortcutBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,33 @@ import PropTypes from 'prop-types';
import {View} from 'react-native';
import _ from 'underscore';
import styles from '../../styles/styles';
import FrequentlyUsed from '../../../assets/images/history.svg';
import Smiley from '../../../assets/images/emoji.svg';
import AnimalsAndNature from '../../../assets/images/emojiCategoryIcons/plant.svg';
import FoodAndDrink from '../../../assets/images/emojiCategoryIcons/hamburger.svg';
import TravelAndPlaces from '../../../assets/images/emojiCategoryIcons/plane.svg';
import Activities from '../../../assets/images/emojiCategoryIcons/soccer-ball.svg';
import Objects from '../../../assets/images/emojiCategoryIcons/light-bulb.svg';
import Symbols from '../../../assets/images/emojiCategoryIcons/peace-sign.svg';
import Flags from '../../../assets/images/emojiCategoryIcons/flag.svg';
import CategoryShortcutButton from './CategoryShortcutButton';
import getOperatingSystem from '../../libs/getOperatingSystem';
import CONST from '../../CONST';

const propTypes = {
/** The function to call when an emoji is selected */
onPress: PropTypes.func.isRequired,

/** The indices that the icons should link to */
headerIndices: PropTypes.arrayOf(PropTypes.number).isRequired,
/** The emojis consisting emoji code and indices that the icons should link to */
headerEmojis: PropTypes.arrayOf(PropTypes.shape({
code: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
icon: PropTypes.func.isRequired,
})).isRequired,
};

const CategoryShortcutBar = (props) => {
const icons = [Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags];
const CategoryShortcutBar = props => (
<View style={[styles.pt2, styles.ph4, styles.flexRow]}>
{_.map(props.headerEmojis, (headerEmoji, i) => (
<CategoryShortcutButton
icon={headerEmoji.icon}
onPress={() => props.onPress(headerEmoji.index)}
key={`categoryShortcut${i}`}
code={headerEmoji.code}
/>
))}
</View>
);

// If the user has frequently used emojis, there will be 9 headers, otherwise there will be 8
// Or for Windows OS there will be 8 headers, otherwise there will be 7
if (props.headerIndices.length === 9 || (getOperatingSystem() === CONST.OS.WINDOWS && props.headerIndices.length === 8)) {
icons.unshift(FrequentlyUsed);
}

return (
<View style={[styles.pt2, styles.ph4, styles.flexRow]}>
{_.map(props.headerIndices, (headerIndex, i) => (
<CategoryShortcutButton
icon={icons[i]}
onPress={() => props.onPress(headerIndex)}
key={`categoryShortcut${i}`}
/>
))}
</View>
);
};
CategoryShortcutBar.propTypes = propTypes;
CategoryShortcutBar.displayName = 'CategoryShortcutBar';

Expand Down
19 changes: 15 additions & 4 deletions src/components/EmojiPicker/CategoryShortcutButton.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Pressable, View} from 'react-native';
import {Pressable} from 'react-native';
import Icon from '../Icon';
import Tooltip from '../Tooltip';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import variables from '../../styles/variables';
import styles from '../../styles/styles';
import * as StyleUtils from '../../styles/StyleUtils';
import getButtonState from '../../libs/getButtonState';
import themeColors from '../../styles/themes/default';

const propTypes = {
/** The emoji code of the category header */
code: PropTypes.string.isRequired,

/** The icon representation of the category that this button links to */
icon: PropTypes.func.isRequired,

/** The function to call when an emoji is selected */
onPress: PropTypes.func.isRequired,

...withLocalizePropTypes,
};

class CategoryShortcutButton extends PureComponent {
Expand All @@ -36,18 +43,22 @@ class CategoryShortcutButton extends PureComponent {
this.state.isHighlighted && styles.emojiItemHighlighted,
])}
>
<View style={styles.alignSelfCenter}>
<Tooltip
containerStyles={[styles.flex1, styles.alignSelfStretch, styles.alignItemsCenter, styles.justifyContentCenter]}
text={this.props.translate(`emojiPicker.headers.${this.props.code}`)}
shiftVertical={-4}
>
<Icon
fill={themeColors.icon}
src={this.props.icon}
height={variables.iconSizeNormal}
width={variables.iconSizeNormal}
/>
</View>
</Tooltip>
</Pressable>
);
}
}
CategoryShortcutButton.propTypes = propTypes;

export default CategoryShortcutButton;
export default withLocalize(CategoryShortcutButton);
Loading

0 comments on commit 2c37fe3

Please sign in to comment.