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

Show the Copilot details if a delegate is set in a report action #20738

Merged
merged 12 commits into from
Jun 21, 2023
45 changes: 31 additions & 14 deletions src/components/UserDetailsTooltip/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,47 @@ import Tooltip from '../Tooltip';
import {propTypes, defaultProps} from './userDetailsTooltipPropTypes';
import styles from '../../styles/styles';
import ONYXKEYS from '../../ONYXKEYS';
import withLocalize from '../withLocalize';
import compose from '../../libs/compose';
import * as UserUtils from '../../libs/UserUtils';

function UserDetailsTooltip(props) {
const userDetails = lodashGet(props.personalDetailsList, props.accountID, props.fallbackUserDetails);
let userDisplayName = userDetails.displayName ? userDetails.displayName.trim() : '';
let userLogin = String(userDetails.login).trim() && !_.isEqual(userDetails.login, userDetails.displayName) ? Str.removeSMSDomain(userDetails.login) : '';
Copy link
Contributor

Choose a reason for hiding this comment

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

Same bad copy pasta

let userAvatar = userDetails.avatar;
let userAccountID = props.accountID;

// We replace the actor's email, name, and avatar with the Copilot manually for now. This will be improved upon when
// the Copilot feature is implemented.
if (props.delegateAccountID) {
const delegateUserDetails = lodashGet(props.personalDetailsList, props.delegateAccountID, {});
const delegateUserDisplayName = delegateUserDetails.displayName ? delegateUserDetails.displayName.trim() : '';
userDisplayName = `${delegateUserDisplayName} (${props.translate('reportAction.asCopilot')} ${userDisplayName})`;
userLogin = delegateUserDetails.login;
userAvatar = delegateUserDetails.avatar;
userAccountID = props.delegateAccountID;
hayata-suenaga marked this conversation as resolved.
Show resolved Hide resolved
}

const renderTooltipContent = useCallback(
() => (
<View style={[styles.alignItemsCenter, styles.ph2, styles.pv2]}>
<View style={styles.emptyAvatar}>
<Avatar
containerStyles={[styles.actionAvatar]}
source={UserUtils.getAvatar(userDetails.avatar, userDetails.login)}
source={UserUtils.getAvatar(userAvatar, userAccountID)}
/>
</View>

<Text style={[styles.mt2, styles.textMicroBold, styles.textReactionSenders, styles.textAlignCenter]}>
{String(userDetails.displayName).trim() ? userDetails.displayName : ''}
</Text>
<Text style={[styles.mt2, styles.textMicroBold, styles.textReactionSenders, styles.textAlignCenter]}>{userDisplayName}</Text>

<Text style={[styles.textMicro, styles.fontColorReactionLabel]}>
{String(userDetails.login).trim() && !_.isEqual(userDetails.login, userDetails.displayName) ? Str.removeSMSDomain(userDetails.login) : ''}
</Text>
<Text style={[styles.textMicro, styles.fontColorReactionLabel]}>{userLogin}</Text>
</View>
),
[userDetails.avatar, userDetails.displayName, userDetails.login],
[userAvatar, userDisplayName, userLogin, userAccountID],
);

if (!userDetails.displayName && !userDetails.login) {
if (!userDisplayName && !userLogin) {
return props.children;
}

Expand All @@ -46,8 +60,11 @@ UserDetailsTooltip.propTypes = propTypes;
UserDetailsTooltip.defaultProps = defaultProps;
UserDetailsTooltip.displayName = 'UserDetailsTooltip';

export default withOnyx({
personalDetailsList: {
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
},
})(UserDetailsTooltip);
export default compose(
withLocalize,
withOnyx({
personalDetailsList: {
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
},
}),
)(UserDetailsTooltip);
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import personalDetailsPropType from '../../pages/personalDetailsPropType';
import {withLocalizePropTypes} from '../withLocalize';

const propTypes = {
/** User's Account ID */
Expand All @@ -17,12 +18,19 @@ const propTypes = {
children: PropTypes.node.isRequired,
/** List of personalDetails (keyed by accountID) */
personalDetailsList: PropTypes.objectOf(personalDetailsPropType),

/** The accountID of the copilot who took this action on behalf of the user */
delegateAccountID: PropTypes.number,

/** Localization props */
...withLocalizePropTypes,
};

const defaultProps = {
accountID: '',
fallbackUserDetails: {displayName: '', login: '', avatar: ''},
personalDetailsList: {},
delegateAccountID: 0,
};

export {propTypes, defaultProps};
3 changes: 3 additions & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ export default {
sayHello: 'Say hello!',
usePlusButton: '\n\nYou can also use the + button below to send or request money!',
},
reportAction: {
asCopilot: 'as copilot for',
},
mentionSuggestions: {
hereAlternateText: 'Notify everyone online in this room',
},
Expand Down
3 changes: 3 additions & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ export default {
sayHello: '¡Saluda!',
usePlusButton: '\n\n¡También puedes usar el botón + de abajo para enviar o pedir dinero!',
},
reportAction: {
asCopilot: 'como copiloto de',
},
mentionSuggestions: {
hereAlternateText: 'Notificar a todos los que estén en linea de esta sala',
},
Expand Down
9 changes: 8 additions & 1 deletion src/pages/home/report/ReportActionItemFragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ const propTypes = {
// Additional styles to add after local styles
style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]),

/** The accountID of the copilot who took this action on behalf of the user */
delegateAccountID: PropTypes.number,

...windowDimensionsPropTypes,

/** localization props */
Expand All @@ -75,6 +78,7 @@ const defaultProps = {
isSingleLine: false,
source: '',
style: [],
delegateAccountID: 0,
};

function ReportActionItemFragment(props) {
Expand Down Expand Up @@ -145,7 +149,10 @@ function ReportActionItemFragment(props) {
}
case 'TEXT':
return (
<UserDetailsTooltip accountID={props.accountID}>
<UserDetailsTooltip
accountID={props.accountID}
delegateAccountID={props.delegateAccountID}
>
<Text
numberOfLines={props.isSingleLine ? 1 : undefined}
style={[styles.chatItemMessageHeaderSender, props.isSingleLine ? styles.pre : styles.preWrap]}
Expand Down
25 changes: 20 additions & 5 deletions src/pages/home/report/ReportActionItemSingle.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,19 @@ const showUserDetails = (accountID) => {
function ReportActionItemSingle(props) {
const actorEmail = lodashGet(props.action, 'actorEmail', '').replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, '');
const actorAccountID = props.action.actorAccountID;
const {avatar, displayName, pendingFields} = props.personalDetailsList[actorAccountID] || {};
const avatarSource = UserUtils.getAvatar(avatar, actorAccountID);
let {avatar, displayName} = props.personalDetailsList[actorAccountID] || {};
const {pendingFields} = props.personalDetailsList[actorAccountID] || {};
hayata-suenaga marked this conversation as resolved.
Show resolved Hide resolved

// We replace the actor's email, name, and avatar with the Copilot manually for now. This will be improved upon when
// the Copilot feature is implemented.
if (props.action.delegateAccountID) {
const delegateDetails = props.personalDetailsList[props.action.delegateAccountID];
const delegateDisplayName = delegateDetails.displayName;
displayName = `${delegateDisplayName} (${props.translate('reportAction.asCopilot')} ${displayName})`;
avatar = delegateDetails.avatar;
}

const avatarSource = UserUtils.getAvatar(avatar, props.action.delegateAccountID ? props.action.delegateAccountID : actorAccountID);

// Since the display name for a report action message is delivered with the report history as an array of fragments
// we'll need to take the displayName from personal details and have it be in the same format for now. Eventually,
Expand All @@ -89,7 +100,7 @@ function ReportActionItemSingle(props) {
style={[styles.alignSelfStart, styles.mr3]}
onPressIn={ControlSelection.block}
onPressOut={ControlSelection.unblock}
onPress={() => showUserDetails(actorAccountID)}
onPress={() => showUserDetails(props.action.delegateAccountID ? props.action.delegateAccountID : actorAccountID)}
>
<OfflineWithFeedback pendingAction={lodashGet(pendingFields, 'avatar', null)}>
{props.shouldShowSubscriptAvatar ? (
Expand All @@ -101,7 +112,10 @@ function ReportActionItemSingle(props) {
noMargin
/>
) : (
<UserDetailsTooltip accountID={actorAccountID}>
<UserDetailsTooltip
accountID={actorAccountID}
delegateAccountID={props.action.delegateAccountID}
>
<View>
<Avatar
containerStyles={[styles.actionAvatar]}
Expand All @@ -119,7 +133,7 @@ function ReportActionItemSingle(props) {
style={[styles.flexShrink1, styles.mr1]}
onPressIn={ControlSelection.block}
onPressOut={ControlSelection.unblock}
onPress={() => showUserDetails(actorAccountID)}
onPress={() => showUserDetails(props.action.delegateAccountID ? props.action.delegateAccountID : actorAccountID)}
>
{_.map(personArray, (fragment, index) => (
<ReportActionItemFragment
Expand All @@ -128,6 +142,7 @@ function ReportActionItemSingle(props) {
fragment={fragment}
isAttachment={props.action.isAttachment}
isLoading={props.action.isLoading}
delegateAccountID={props.action.delegateAccountID}
isSingleLine
/>
))}
Expand Down