Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render banner in Concierge chat #11363

Merged
merged 15 commits into from
Sep 29, 2022
3 changes: 3 additions & 0 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export default {
// Holds information about the users account that is logging in
ACCOUNT: 'account',

// Holds the reportID for the report between the user and their account manager
ACCOUNT_MANAGER_REPORT_ID: 'accountManagerReportID',

// Boolean flag only true when first set
NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER: 'isFirstTimeNewExpensifyUser',

Expand Down
1 change: 1 addition & 0 deletions src/components/ArchivedReportFooter.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const ArchivedReportFooter = (props) => {
policyName: `<strong>${ReportUtils.getPolicyName(props.report, props.policies)}</strong>`,
})}
shouldRenderHTML={archiveReason !== CONST.REPORT.ARCHIVE_REASON.DEFAULT}
shouldShowIcon
/>
);
};
Expand Down
72 changes: 60 additions & 12 deletions src/components/Banner.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {memo} from 'react';
import PropTypes from 'prop-types';
import {View} from 'react-native';
import {View, Pressable} from 'react-native';
import compose from '../libs/compose';
import Hoverable from './Hoverable';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
Expand All @@ -9,17 +10,45 @@ import Text from './Text';
import styles from '../styles/styles';
import * as StyleUtils from '../styles/StyleUtils';
import getButtonState from '../libs/getButtonState';
import Tooltip from './Tooltip';
import withLocalize, {withLocalizePropTypes} from './withLocalize';

const propTypes = {
/** Text to display in the banner. */
text: PropTypes.string.isRequired,

/** Should this component render the left-aligned exclamation icon? */
shouldShowIcon: PropTypes.bool,

/** Should this component render a close button? */
shouldShowCloseButton: PropTypes.bool,

/** Should this component render the text as HTML? */
shouldRenderHTML: PropTypes.bool,

/** Callback called when the close button is pressed */
onClose: PropTypes.func,

/** Callback called when the message is pressed */
onPress: PropTypes.func,

// eslint-disable-next-line react/forbid-prop-types
containerStyles: PropTypes.arrayOf(PropTypes.object),

// eslint-disable-next-line react/forbid-prop-types
textStyles: PropTypes.arrayOf(PropTypes.object),

...withLocalizePropTypes,
};

const defaultProps = {
shouldRenderHTML: false,
shouldShowIcon: false,
shouldShowCloseButton: false,
onClose: () => {},
onPress: () => {},
containerStyles: [],
textStyles: [],
};

const Banner = props => (
Expand All @@ -32,19 +61,35 @@ const Banner = props => (
styles.borderRadiusNormal,
isHovered ? styles.activeComponentBG : styles.hoveredComponentBG,
styles.breakAll,
...props.containerStyles,
]}
>
<View style={[styles.mr3]}>
<Icon
src={Expensicons.Exclamation}
fill={StyleUtils.getIconFillColor(getButtonState(isHovered))}
/>
<View style={[styles.flexRow, styles.flexGrow1, styles.mw100, styles.alignItemsCenter]}>
{props.shouldShowIcon && (
<View style={[styles.mr3]}>
<Icon
src={Expensicons.Exclamation}
fill={StyleUtils.getIconFillColor(getButtonState(isHovered))}
/>
</View>
)}
{
props.shouldRenderHTML
? <RenderHTML html={props.text} />
: <Text style={[...props.textStyles]} onPress={props.onPress}>{props.text}</Text>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, just noting that we should have used flexWrap to prevent text overflow on native.

#42373 (comment)

}
</View>
{
props.shouldRenderHTML
? <RenderHTML html={props.text} />
: <Text>{props.text}</Text>
}
{props.shouldShowCloseButton && (
<Tooltip text={props.translate('common.close')}>
<Pressable
onPress={props.onClose}
accessibilityRole="button"
accessibilityLabel={props.translate('common.close')}
>
<Icon src={Expensicons.Close} />
</Pressable>
</Tooltip>
)}
</View>
)}
</Hoverable>
Expand All @@ -54,4 +99,7 @@ Banner.propTypes = propTypes;
Banner.defaultProps = defaultProps;
Banner.displayName = 'Banner';

export default memo(Banner);
export default compose(
withLocalize,
memo,
)(Banner);
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export default {
beginningOfChatHistoryPolicyExpenseChatPartOne: 'Collaboration between ',
beginningOfChatHistoryPolicyExpenseChatPartTwo: ' and ',
beginningOfChatHistoryPolicyExpenseChatPartThree: ' starts here! 🎉 This is the place to chat, request money and settle up.',
chatWithAccountManager: 'Chat with your account manager here',
},
newMessages: 'New messages',
reportTypingIndicator: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export default {
beginningOfChatHistoryPolicyExpenseChatPartOne: '¡La colaboración entre ',
beginningOfChatHistoryPolicyExpenseChatPartTwo: ' y ',
beginningOfChatHistoryPolicyExpenseChatPartThree: ' empieza aquí! :tada: Este es el lugar donde chatear, pedir dinero y pagar.',
chatWithAccountManager: 'Chatea con tu gestor de cuenta aquí',
},
newMessages: 'Mensajes nuevos',
reportTypingIndicator: {
Expand Down
17 changes: 12 additions & 5 deletions src/libs/Navigation/DeprecatedCustomActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,23 @@ function pushDrawerRoute(route) {
const screenRoute = {type: 'route', name: newScreenName};
const history = _.map(state.history ? [...state.history] : [screenRoute], () => screenRoute);

// Force drawer to close
// https://github.com/react-navigation/react-navigation/blob/94ab791cae5061455f036cd3f6bc7fa63167e7c7/packages/routers/src/DrawerRouter.tsx#L142
const hasDrawerhistory = _.find(state.history || [], h => h.type === 'drawer');
if (!hasDrawerhistory || currentState.type !== 'drawer') {
const drawerHistoryItem = _.find(state.history || [], h => h.type === 'drawer');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More context about the changes in DeprecatedCustomActions.js this thread

const isDrawerClosed = drawerHistoryItem && drawerHistoryItem.status === 'closed';
if (!drawerHistoryItem || currentState.type !== 'drawer') {
// Add the drawer item to the navigation history to control if the drawer should be in open or closed state
history.push({
type: 'drawer',

// If current state is not from drawer navigator then always use closed status to close the drawer
// If current state is not from drawer navigator then always force the drawer to close by using closed status
// https://github.com/react-navigation/react-navigation/blob/94ab791cae5061455f036cd3f6bc7fa63167e7c7/packages/routers/src/DrawerRouter.tsx#L142
status: currentState.type !== 'drawer' || currentState.default === 'open' ? 'closed' : 'open',
});
} else if (isDrawerClosed) {
// Keep the drawer closed if it's already closed
history.push({
type: 'drawer',
status: 'closed',
});
}

return CommonActions.reset({
Expand Down
27 changes: 27 additions & 0 deletions src/pages/home/ReportScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/
import OfflineIndicator from '../../components/OfflineIndicator';
import OfflineWithFeedback from '../../components/OfflineWithFeedback';
import withDrawerState, {withDrawerPropTypes} from '../../components/withDrawerState';
import Banner from '../../components/Banner';
import withLocalize from '../../components/withLocalize';
import reportPropTypes from '../reportPropTypes';

const propTypes = {
Expand Down Expand Up @@ -112,11 +114,14 @@ class ReportScreen extends React.Component {

this.onSubmitComment = this.onSubmitComment.bind(this);
this.updateViewportOffsetTop = this.updateViewportOffsetTop.bind(this);
this.chatWithAccountManager = this.chatWithAccountManager.bind(this);
this.dismissBanner = this.dismissBanner.bind(this);
this.removeViewportResizeListener = () => {};

this.state = {
skeletonViewContainerHeight: 0,
viewportOffsetTop: 0,
isBannerVisible: true,
};
}

Expand Down Expand Up @@ -191,6 +196,14 @@ class ReportScreen extends React.Component {
this.setState({viewportOffsetTop});
}

dismissBanner() {
this.setState({isBannerVisible: false});
}

chatWithAccountManager() {
Navigation.navigate(ROUTES.getReportRoute(this.props.accountManagerReportID));
}

render() {
if (!this.props.isSidebarLoaded) {
return null;
Expand Down Expand Up @@ -236,6 +249,16 @@ class ReportScreen extends React.Component {
onNavigationMenuButtonClicked={() => Navigation.navigate(ROUTES.HOME)}
/>
</OfflineWithFeedback>
{this.props.accountManagerReportID && ReportUtils.isConciergeChatReport(this.props.report) && this.state.isBannerVisible && (
<Banner
containerStyles={[styles.mh4, styles.mt4, styles.p4, styles.bgDark]}
textStyles={[styles.colorReversed]}
text={this.props.translate('reportActionsView.chatWithAccountManager')}
onClose={this.dismissBanner}
onPress={this.chatWithAccountManager}
shouldShowCloseButton
/>
)}
<View
nativeID={CONST.REPORT.DROP_NATIVE_ID}
style={[styles.flex1, styles.justifyContentEnd, styles.overflowHidden]}
Expand Down Expand Up @@ -300,6 +323,7 @@ ReportScreen.propTypes = propTypes;
ReportScreen.defaultProps = defaultProps;

export default compose(
withLocalize,
withWindowDimensions,
withDrawerState,
withNetwork(),
Expand All @@ -326,5 +350,8 @@ export default compose(
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
accountManagerReportID: {
key: ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID,
},
}),
)(ReportScreen);
4 changes: 4 additions & 0 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ const styles = {
backgroundColor: 'transparent',
},

bgDark: {
backgroundColor: colors.dark,
},

opacity0: {
opacity: 0,
},
Expand Down
Loading