Skip to content

Commit

Permalink
Merge pull request #19169 from Expensify/OSBotify-cherry-pick-staging…
Browse files Browse the repository at this point in the history
…-18692

🍒 Cherry pick PR #18692 to staging 🍒
  • Loading branch information
OSBotify authored May 18, 2023
2 parents e3d4137 + cccc1f3 commit 1225c39
Show file tree
Hide file tree
Showing 47 changed files with 692 additions and 544 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 1001031511
versionName "1.3.15-11"
versionCode 1001031512
versionName "1.3.15-12"
}

splits {
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.3.15.11</string>
<string>1.3.15.12</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.3.15.11</string>
<string>1.3.15.12</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.15-11",
"version": "1.3.15-12",
"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
2 changes: 2 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ const CONST = {
},
STATE: {
SUBMITTED: 'SUBMITTED',
PROCESSING: 'PROCESSING',
},
STATE_NUM: {
OPEN: 0,
Expand Down Expand Up @@ -960,6 +961,7 @@ const CONST = {
ELSEWHERE: 'Elsewhere',
EXPENSIFY: 'Expensify',
PAYPAL_ME: 'PayPal.me',
VBBA: 'ACH',
},
MONEY_REQUEST_TYPE: {
SEND: 'send',
Expand Down
3 changes: 3 additions & 0 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export default {
// A unique identifier that each user has that's used to send notifications
NVP_PRIVATE_PUSH_NOTIFICATION_ID: 'private_pushNotificationID',

// The NVP with the last payment method used per policy
NVP_LAST_PAYMENT_METHOD: 'nvp_lastPaymentMethod',

// Does this user have push notifications enabled for this device?
PUSH_NOTIFICATIONS_ENABLED: 'pushNotificationsEnabled',

Expand Down
1 change: 1 addition & 0 deletions src/ROUTES.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const SETTINGS_CONTACT_METHODS = 'settings/profile/contact-methods';

export default {
BANK_ACCOUNT: 'bank-account',
BANK_ACCOUNT_NEW: 'bank-account/new',
BANK_ACCOUNT_WITH_STEP_TO_OPEN: 'bank-account/:stepToOpen?',
BANK_ACCOUNT_PERSONAL: 'bank-account/personal',
getBankAccountRoute: (stepToOpen = '', policyID = '') => `bank-account/${stepToOpen}?policyID=${policyID}`,
Expand Down
11 changes: 8 additions & 3 deletions src/components/AddPaymentMethodMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ import PopoverMenu from './PopoverMenu';
import paypalMeDataPropTypes from './paypalMeDataPropTypes';

const propTypes = {
/** Should the component be visible? */
isVisible: PropTypes.bool.isRequired,

/** Callback to execute when the component closes. */
onClose: PropTypes.func.isRequired,

/** Anchor position for the AddPaymentMenu. */
anchorPosition: PropTypes.shape({
top: PropTypes.number,
left: PropTypes.number,
horizontal: PropTypes.number,
vertical: PropTypes.number,
}),

/** Account details for PayPal.Me */
Expand All @@ -43,7 +48,7 @@ const AddPaymentMethodMenu = (props) => (
isVisible={props.isVisible}
onClose={props.onClose}
anchorPosition={props.anchorPosition}
onItemSelected={() => props.onClose()}
onItemSelected={props.onClose}
menuItems={[
{
text: props.translate('common.bankAccount'),
Expand Down
1 change: 1 addition & 0 deletions src/components/AvatarWithImagePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ class AvatarWithImagePicker extends React.Component {
onItemSelected={() => this.setState({isMenuVisible: false})}
menuItems={this.createMenuItems(openPicker)}
anchorPosition={this.props.anchorPosition}
anchorAlignment={this.props.anchorAlignment}
/>
</>
)}
Expand Down
18 changes: 17 additions & 1 deletion src/components/Button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ const propTypes = {

/** Accessibility label for the component */
accessibilityLabel: PropTypes.string,

/** A ref to forward the button */
forwardedRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({current: PropTypes.oneOfType([PropTypes.instanceOf(React.Component), PropTypes.func])})]),
};

const defaultProps = {
Expand Down Expand Up @@ -141,6 +144,7 @@ const defaultProps = {
shouldEnableHapticFeedback: false,
nativeID: '',
accessibilityLabel: '',
forwardedRef: undefined,
};

class Button extends Component {
Expand Down Expand Up @@ -240,6 +244,7 @@ class Button extends Component {
render() {
return (
<PressableWithFeedback
ref={this.props.forwardedRef}
onPress={(e) => {
if (e && e.type === 'click') {
e.currentTarget.blur();
Expand Down Expand Up @@ -303,4 +308,15 @@ class Button extends Component {
Button.propTypes = propTypes;
Button.defaultProps = defaultProps;

export default compose(withNavigationFallback, withNavigationFocus)(Button);
export default compose(
withNavigationFallback,
withNavigationFocus,
)(
React.forwardRef((props, ref) => (
<Button
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
forwardedRef={ref}
/>
)),
);
65 changes: 0 additions & 65 deletions src/components/ButtonWithDropdown.js

This file was deleted.

139 changes: 139 additions & 0 deletions src/components/ButtonWithDropdownMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React, {useState, useRef, useEffect} from 'react';
import PropTypes from 'prop-types';
import {View} from 'react-native';
import _ from 'underscore';
import useWindowDimensions from '../hooks/useWindowDimensions';
import styles from '../styles/styles';
import Button from './Button';
import PopoverMenu from './PopoverMenu';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import themeColors from '../styles/themes/default';
import CONST from '../CONST';

const propTypes = {
/** Text to display for the menu header */
menuHeaderText: PropTypes.string,

/** Callback to execute when the main button is pressed */
onPress: PropTypes.func.isRequired,

/** Whether we should show a loading state for the main button */
isLoading: PropTypes.bool,

/** Should the confirmation button be disabled? */
isDisabled: PropTypes.bool,

/** Additional styles to add to the component */
style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]),

/** Menu options to display */
/** e.g. [{text: 'Pay with Expensify', icon: Wallet}, {text: 'PayPal', icon: PayPal}] */
options: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.string.isRequired,
text: PropTypes.string.isRequired,
icon: PropTypes.elementType,
iconWidth: PropTypes.number,
iconHeight: PropTypes.number,
iconDescription: PropTypes.string,
}),
).isRequired,
};

const defaultProps = {
isLoading: false,
isDisabled: false,
menuHeaderText: '',
style: [],
};

const ButtonWithDropdownMenu = (props) => {
const [selectedItemIndex, setSelectedItemIndex] = useState(0);
const [isMenuVisible, setIsMenuVisible] = useState(false);
const [popoverAnchorPosition, setPopoverAnchorPosition] = useState(null);
const {width: windowWidth, height: windowHeight} = useWindowDimensions();
const caretButton = useRef(null);
useEffect(() => {
if (!caretButton.current) {
return;
}
caretButton.current.measureInWindow((x, y, w, h) => {
setPopoverAnchorPosition({
horizontal: x + w,
vertical: y + h,
});
});
}, [windowWidth, windowHeight]);

const selectedItem = props.options[selectedItemIndex];
return (
<View>
{props.options.length > 1 ? (
<View style={[styles.flexRow, styles.justifyContentBetween, styles.alignItemsCenter, ...props.style]}>
<Button
success
onPress={(event) => props.onPress(event, selectedItem.value)}
text={selectedItem.text}
isDisabled={props.isDisabled}
isLoading={props.isLoading}
shouldRemoveRightBorderRadius
style={[styles.flex1, styles.pr0]}
pressOnEnter
/>
<View style={styles.buttonDivider} />
<Button
ref={caretButton}
success
isDisabled={props.isDisabled}
style={[styles.pl0]}
onPress={() => {
setIsMenuVisible(true);
}}
shouldRemoveLeftBorderRadius
>
<Icon
src={Expensicons.DownArrow}
fill={themeColors.textLight}
/>
</Button>
</View>
) : (
<Button
success
isDisabled={props.isDisabled}
style={[styles.w100, ...props.style]}
isLoading={props.isLoading}
text={selectedItem.text}
onPress={(event) => props.onPress(event, props.options[0].value)}
pressOnEnter
/>
)}
{props.options.length > 1 && !_.isEmpty(popoverAnchorPosition) && (
<PopoverMenu
isVisible={isMenuVisible}
onClose={() => setIsMenuVisible(false)}
onItemSelected={() => setIsMenuVisible(false)}
anchorPosition={popoverAnchorPosition}
anchorAlignment={{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
}}
headerText={props.menuHeaderText}
menuItems={_.map(props.options, (item, index) => ({
...item,
onSelected: () => {
setSelectedItemIndex(index);
},
}))}
/>
)}
</View>
);
};

ButtonWithDropdownMenu.propTypes = propTypes;
ButtonWithDropdownMenu.defaultProps = defaultProps;
ButtonWithDropdownMenu.displayName = 'ButtonWithDropdownMenu';

export default React.memo(ButtonWithDropdownMenu);
Loading

0 comments on commit 1225c39

Please sign in to comment.