diff --git a/src/CONST.js b/src/CONST.js
index 68e309e589bf..76910d5d8737 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -1109,6 +1109,7 @@ const CONST = {
LARGE_BORDERED: 'large-bordered',
HEADER: 'header',
MENTION_ICON: 'mention-icon',
+ SMALL_NORMAL: 'small-normal',
},
AVATAR_ROW_SIZE: {
DEFAULT: 4,
diff --git a/src/components/Avatar.js b/src/components/Avatar.js
index b59a8902eb13..51e791251f2c 100644
--- a/src/components/Avatar.js
+++ b/src/components/Avatar.js
@@ -45,7 +45,7 @@ const propTypes = {
/** Denotes whether it is an avatar or a workspace avatar */
type: PropTypes.oneOf([CONST.ICON_TYPE_AVATAR, CONST.ICON_TYPE_WORKSPACE]),
- /** Owner of the avatar, typically a login email or workspace name */
+ /** Owner of the avatar. If user, displayName. If workspace, policy name */
name: PropTypes.string,
};
@@ -76,7 +76,7 @@ function Avatar(props) {
const imageStyle =
props.imageStyles && props.imageStyles.length
? [StyleUtils.getAvatarStyle(props.size), ...props.imageStyles, StyleUtils.getAvatarBorderRadius(props.size, props.type)]
- : [StyleUtils.getAvatarStyle(props.size), styles.noBorderRadius];
+ : [StyleUtils.getAvatarStyle(props.size), StyleUtils.getAvatarBorderStyle(props.size, props.type)];
const iconStyle = props.imageStyles && props.imageStyles.length ? [StyleUtils.getAvatarStyle(props.size), styles.bgTransparent, ...props.imageStyles] : undefined;
diff --git a/src/components/AvatarWithDisplayName.js b/src/components/AvatarWithDisplayName.js
index a5a12e6de980..f63b51cacf99 100644
--- a/src/components/AvatarWithDisplayName.js
+++ b/src/components/AvatarWithDisplayName.js
@@ -70,8 +70,6 @@ function AvatarWithDisplayName(props) {
backgroundColor={themeColors.highlightBG}
mainAvatar={icons[0]}
secondaryAvatar={icons[1]}
- mainTooltip={props.report.ownerEmail}
- secondaryTooltip={subtitle}
size={props.size}
/>
) : (
diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js
index ca812a408474..0aa21115d5f8 100644
--- a/src/components/LHNOptionsList/OptionRowLHN.js
+++ b/src/components/LHNOptionsList/OptionRowLHN.js
@@ -19,7 +19,6 @@ import SubscriptAvatar from '../SubscriptAvatar';
import CONST from '../../CONST';
import themeColors from '../../styles/themes/default';
import SidebarUtils from '../../libs/SidebarUtils';
-import TextPill from '../TextPill';
import OfflineWithFeedback from '../OfflineWithFeedback';
import PressableWithSecondaryInteraction from '../PressableWithSecondaryInteraction';
import * as ReportActionContextMenu from '../../pages/home/report/ContextMenu/ReportActionContextMenu';
@@ -83,7 +82,6 @@ function OptionRowLHN(props) {
const textStyle = props.isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText;
const textUnreadStyle = optionItem.isUnread ? [textStyle, styles.sidebarLinkTextBold] : [textStyle];
const displayNameStyle = StyleUtils.combineStyles([styles.optionDisplayName, styles.optionDisplayNameCompact, styles.pre, ...textUnreadStyle], props.style);
- const textPillStyle = props.isFocused ? [styles.ml1, StyleUtils.getBackgroundColorWithOpacityStyle(themeColors.icon, 0.5)] : [styles.ml1];
const alternateTextStyle = StyleUtils.combineStyles(
props.viewMode === CONST.OPTION_MODE.COMPACT
? [textStyle, styles.optionAlternateText, styles.pre, styles.textLabelSupporting, styles.optionAlternateTextCompact, styles.ml2]
@@ -101,6 +99,7 @@ function OptionRowLHN(props) {
const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor;
const hasBrickError = optionItem.brickRoadIndicator === CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
+ const defaultSubscriptSize = optionItem.isExpenseRequest ? CONST.AVATAR_SIZE.SMALL_NORMAL : CONST.AVATAR_SIZE.DEFAULT;
const shouldShowGreenDotIndicator =
!hasBrickError &&
(optionItem.isUnreadWithMention ||
@@ -172,9 +171,7 @@ function OptionRowLHN(props) {
backgroundColor={props.isFocused ? themeColors.activeComponentBG : themeColors.sidebar}
mainAvatar={optionItem.icons[0]}
secondaryAvatar={optionItem.icons[1]}
- mainTooltip={optionItem.ownerEmail}
- secondaryTooltip={optionItem.subtitle}
- size={props.viewMode === CONST.OPTION_MODE.COMPACT ? CONST.AVATAR_SIZE.SMALL : CONST.AVATAR_SIZE.DEFAULT}
+ size={props.viewMode === CONST.OPTION_MODE.COMPACT ? CONST.AVATAR_SIZE.SMALL : defaultSubscriptSize}
/>
) : (
- {optionItem.isChatRoom && !optionItem.isThread && (
-
- )}
{optionItem.alternateText ? (
-
-
+
+
{/* View is necessary for tooltip to show for multiple avatars in LHN */}
-
+
{props.icons.length === 2 ? (
-
+
@@ -257,7 +258,7 @@ function MultipleAvatars(props) {
) : (
-
+
1;
+ const defaultSubscriptSize = this.props.option.isExpenseRequest ? CONST.AVATAR_SIZE.SMALL_NORMAL : CONST.AVATAR_SIZE.DEFAULT;
// We only create tooltips for the first 10 users or so since some reports have hundreds of users, causing performance to degrade.
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(
@@ -193,9 +194,8 @@ class OptionRow extends Component {
) : (
-
+
-
-
-
+
+
+
-
+
);
}
diff --git a/src/components/UserDetailsTooltip/index.js b/src/components/UserDetailsTooltip/index.js
index a13728fb1074..116e5f34abfe 100644
--- a/src/components/UserDetailsTooltip/index.js
+++ b/src/components/UserDetailsTooltip/index.js
@@ -12,6 +12,7 @@ import ONYXKEYS from '../../ONYXKEYS';
import withLocalize from '../withLocalize';
import compose from '../../libs/compose';
import * as UserUtils from '../../libs/UserUtils';
+import CONST from '../../CONST';
import * as LocalePhoneNumber from '../../libs/LocalePhoneNumber';
function UserDetailsTooltip(props) {
@@ -32,27 +33,30 @@ function UserDetailsTooltip(props) {
userAccountID = props.delegateAccountID;
}
+ let title = String(userDisplayName).trim() ? userDisplayName : '';
+ const subtitle = (userLogin || '').trim() && !_.isEqual(LocalePhoneNumber.formatPhoneNumber(userLogin || ''), userDisplayName) ? Str.removeSMSDomain(userLogin) : '';
+ if (props.icon && props.icon.type === CONST.ICON_TYPE_WORKSPACE) {
+ title = props.icon.name;
+ }
const renderTooltipContent = useCallback(
() => (
-
- {userDisplayName}
-
-
- {(userLogin || '').trim() && !_.isEqual(LocalePhoneNumber.formatPhoneNumber(userLogin || ''), userDisplayName) ? Str.removeSMSDomain(userLogin) : ''}
-
+ {title}
+ {subtitle}
),
- [userAvatar, userDisplayName, userLogin, userAccountID],
+ [props.icon, userAvatar, userAccountID, userLogin, title, subtitle],
);
- if (!userDisplayName && !userLogin) {
+ if (!props.icon && !userDisplayName && !userLogin) {
return props.children;
}
diff --git a/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js b/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js
index 0bf0f5f9b7cb..271e74aaf06c 100644
--- a/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js
+++ b/src/components/UserDetailsTooltip/userDetailsTooltipPropTypes.js
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import personalDetailsPropType from '../../pages/personalDetailsPropType';
+import avatarPropTypes from '../avatarPropTypes';
import {withLocalizePropTypes} from '../withLocalize';
const propTypes = {
@@ -13,7 +14,11 @@ const propTypes = {
displayName: PropTypes.string,
/** Login */
login: PropTypes.string,
+ /** Whether this is a Workspace Avatar or User Avatar */
+ type: PropTypes.string,
}),
+ /** Optionally, pass in the icon instead of calculating it. If defined, will take precedence. */
+ icon: avatarPropTypes,
/** Component that displays the tooltip */
children: PropTypes.node.isRequired,
/** List of personalDetails (keyed by accountID) */
@@ -28,9 +33,10 @@ const propTypes = {
const defaultProps = {
accountID: '',
- fallbackUserDetails: {displayName: '', login: '', avatar: ''},
+ fallbackUserDetails: {displayName: '', login: '', avatar: '', type: ''},
personalDetailsList: {},
delegateAccountID: 0,
+ icon: undefined,
};
export {propTypes, defaultProps};
diff --git a/src/components/avatarPropTypes.js b/src/components/avatarPropTypes.js
index c068b481c596..7e978fc74963 100644
--- a/src/components/avatarPropTypes.js
+++ b/src/components/avatarPropTypes.js
@@ -5,4 +5,5 @@ export default PropTypes.shape({
source: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
type: PropTypes.oneOf([CONST.ICON_TYPE_AVATAR, CONST.ICON_TYPE_WORKSPACE]),
name: PropTypes.string,
+ id: PropTypes.number,
});
diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js
index d19ecb79a67a..558d2f9bb7ba 100644
--- a/src/libs/OptionsListUtils.js
+++ b/src/libs/OptionsListUtils.js
@@ -444,6 +444,7 @@ function createOption(accountIDs, personalDetails, report, reportActions = {}, {
isArchivedRoom: false,
shouldShowSubscript: false,
isPolicyExpenseChat: false,
+ isExpenseReport: false,
};
const personalDetailMap = getPersonalDetailsForAccountIDs(accountIDs, personalDetails);
@@ -460,6 +461,7 @@ function createOption(accountIDs, personalDetails, report, reportActions = {}, {
result.isDefaultRoom = ReportUtils.isDefaultRoom(report);
result.isArchivedRoom = ReportUtils.isArchivedRoom(report);
result.isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report);
+ result.isExpenseReport = ReportUtils.isExpenseReport(report);
result.isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report);
result.isThread = ReportUtils.isChatThread(report);
result.isTaskReport = ReportUtils.isTaskReport(report);
diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js
index 72f642d3e844..e481f83c707c 100644
--- a/src/libs/ReportUtils.js
+++ b/src/libs/ReportUtils.js
@@ -356,6 +356,20 @@ function getBankAccountRoute(report) {
return isPolicyExpenseChat(report) ? ROUTES.getBankAccountRoute('', report.policyID) : ROUTES.SETTINGS_ADD_BANK_ACCOUNT;
}
+/**
+ * Checks if a report is a task report from a policy expense chat.
+ *
+ * @param {Object} report
+ * @returns {Boolean}
+ */
+function isWorkspaceTaskReport(report) {
+ if (!isTaskReport(report)) {
+ return false;
+ }
+ const parentReport = allReports[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`];
+ return isPolicyExpenseChat(parentReport);
+}
+
/**
* Returns true if report has a parent
*
@@ -531,6 +545,26 @@ function isPolicyExpenseChatAdmin(report, policies) {
return policyRole === CONST.POLICY.ROLE.ADMIN;
}
+/**
+ * Returns true if report is a DM/Group DM chat.
+ *
+ * @param {Object} report
+ * @returns {Boolean}
+ */
+function isDM(report) {
+ return !getChatType(report);
+}
+
+/**
+ * If the report is a thread and has a chat type set, it is a workspace chat.
+ *
+ * @param {Object} report
+ * @returns {Boolean}
+ */
+function isWorkspaceThread(report) {
+ return Boolean(isThread(report) && !isDM(report));
+}
+
/**
* Returns true if reportAction has a child.
*
@@ -552,6 +586,22 @@ function isThreadFirstChat(reportAction, reportID) {
return !_.isUndefined(reportAction.childReportID) && reportAction.childReportID.toString() === reportID;
}
+/**
+ * An Expense Request is a thread where the parent report is an Expense Report and
+ * the parentReportAction is a transaction.
+ *
+ * @param {Object} report
+ * @returns {Boolean}
+ */
+function isExpenseRequest(report) {
+ if (isThread(report)) {
+ const parentReportAction = ReportActionsUtils.getParentReportAction(report);
+ const parentReport = lodashGet(allReports, [`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`]);
+ return isExpenseReport(parentReport) && ReportActionsUtils.isTransactionThread(parentReportAction);
+ }
+ return false;
+}
+
/**
* Get welcome message based on room type
* @param {Object} report
@@ -700,6 +750,24 @@ function getIconsForParticipants(participants, personalDetails) {
return avatars;
}
+/**
+ * Given a report, return the associated workspace icon.
+ *
+ * @param {Object} report
+ * @returns {Object}
+ */
+function getWorkspaceIcon(report) {
+ const workspaceName = getPolicyName(report);
+ const policyExpenseChatAvatarSource = lodashGet(allPolicies, [`${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`, 'avatar']) || getDefaultWorkspaceAvatar(workspaceName);
+ const workspaceIcon = {
+ source: policyExpenseChatAvatarSource,
+ type: CONST.ICON_TYPE_WORKSPACE,
+ name: workspaceName,
+ id: -1,
+ };
+ return workspaceIcon;
+}
+
/**
* Returns the appropriate icons for the given chat report using the stored personalDetails.
* The Avatar sources can be URLs or Icon components according to the chat type.
@@ -712,27 +780,32 @@ function getIconsForParticipants(participants, personalDetails) {
* @param {Number} [defaultAccountID]
* @returns {Array<*>}
*/
-function getIcons(report, personalDetails, defaultIcon = null, isPayer = false, defaultName = '', defaultAccountID = undefined) {
- const result = {
- source: '',
- type: CONST.ICON_TYPE_AVATAR,
- name: '',
- };
-
+function getIcons(report, personalDetails, defaultIcon = null, isPayer = false) {
if (_.isEmpty(report)) {
- result.source = defaultIcon || Expensicons.FallbackAvatar;
- result.name = defaultName || '';
- result.id = defaultAccountID;
- return [result];
+ const fallbackIcon = {
+ source: defaultIcon || Expensicons.FallbackAvatar,
+ type: CONST.ICON_TYPE_AVATAR,
+ name: '',
+ id: -1,
+ };
+ return [fallbackIcon];
}
- if (isArchivedRoom(report)) {
- result.source = Expensicons.DeletedRoomAvatar;
- return [result];
+ if (isExpenseRequest(report)) {
+ const parentReportAction = ReportActionsUtils.getParentReportAction(report);
+ const workspaceIcon = getWorkspaceIcon(report);
+ const memberIcon = {
+ source: UserUtils.getAvatar(lodashGet(personalDetails, [parentReportAction.actorAccountID, 'avatar']), parentReportAction.actorAccountID),
+ id: parentReportAction.actorAccountID,
+ type: CONST.ICON_TYPE_AVATAR,
+ name: lodashGet(personalDetails, [parentReportAction.actorAccountID, 'displayName'], ''),
+ };
+
+ return [memberIcon, workspaceIcon];
}
if (isChatThread(report)) {
const parentReportAction = ReportActionsUtils.getParentReportAction(report);
- const actorAccountID = lodashGet(parentReportAction, 'actorAccountID', 0);
+ const actorAccountID = lodashGet(parentReportAction, 'actorAccountID', -1);
const actorDisplayName = lodashGet(allPersonalDetails, [actorAccountID, 'displayName'], '');
const actorIcon = {
id: actorAccountID,
@@ -741,78 +814,70 @@ function getIcons(report, personalDetails, defaultIcon = null, isPayer = false,
type: CONST.ICON_TYPE_AVATAR,
};
+ if (isWorkspaceThread(report)) {
+ const workspaceIcon = getWorkspaceIcon(report);
+ return [actorIcon, workspaceIcon];
+ }
return [actorIcon];
}
if (isTaskReport(report)) {
- const ownerEmail = report.ownerEmail || '';
const ownerIcon = {
id: report.ownerAccountID,
source: UserUtils.getAvatar(lodashGet(personalDetails, [report.ownerAccountID, 'avatar']), report.ownerAccountID),
- name: ownerEmail,
type: CONST.ICON_TYPE_AVATAR,
+ name: lodashGet(personalDetails, [report.ownerAccountID, 'displayName'], ''),
};
+ if (isWorkspaceTaskReport(report)) {
+ const workspaceIcon = getWorkspaceIcon(report);
+ return [ownerIcon, workspaceIcon];
+ }
+
return [ownerIcon];
}
if (isDomainRoom(report)) {
- result.source = Expensicons.DomainRoomAvatar;
- return [result];
- }
- if (isAdminRoom(report)) {
- result.source = Expensicons.AdminRoomAvatar;
- return [result];
- }
- if (isAnnounceRoom(report)) {
- result.source = Expensicons.AnnounceRoomAvatar;
- return [result];
+ // Get domain name after the #. Domain Rooms use our default workspace avatar pattern.
+ const domainName = report.reportName.substring(1);
+ const policyExpenseChatAvatarSource = getDefaultWorkspaceAvatar(domainName);
+ const domainIcon = {
+ source: policyExpenseChatAvatarSource,
+ type: CONST.ICON_TYPE_WORKSPACE,
+ name: domainName,
+ id: -1,
+ };
+ return [domainIcon];
}
- if (isChatRoom(report)) {
- result.source = Expensicons.ActiveRoomAvatar;
- return [result];
+ if (isAdminRoom(report) || isAnnounceRoom(report) || isChatRoom(report) || isArchivedRoom(report)) {
+ const workspaceIcon = getWorkspaceIcon(report);
+ return [workspaceIcon];
}
if (isPolicyExpenseChat(report) || isExpenseReport(report)) {
- const workspaceName = getPolicyName(report);
-
- const policyExpenseChatAvatarSource = getWorkspaceAvatar(report);
-
- // Return the workspace avatar if the user is the owner of the policy expense chat
- if (report.isOwnPolicyExpenseChat && !isExpenseReport(report)) {
- result.source = policyExpenseChatAvatarSource;
- result.type = CONST.ICON_TYPE_WORKSPACE;
- result.name = workspaceName;
- return [result];
- }
-
- const adminIcon = {
- id: report.ownerAccountID,
+ const workspaceIcon = getWorkspaceIcon(report);
+ const memberIcon = {
source: UserUtils.getAvatar(lodashGet(personalDetails, [report.ownerAccountID, 'avatar']), report.ownerAccountID),
- name: report.ownerEmail,
+ id: report.ownerAccountID,
+ type: CONST.ICON_TYPE_AVATAR,
+ name: lodashGet(personalDetails, [report.ownerAccountID, 'displayName'], ''),
+ };
+ return isExpenseReport(report) ? [memberIcon, workspaceIcon] : [workspaceIcon, memberIcon];
+ }
+ if (isIOUReport(report)) {
+ const managerIcon = {
+ source: UserUtils.getAvatar(lodashGet(personalDetails, [report.managerID, 'avatar']), report.managerID),
+ id: report.managerID,
type: CONST.ICON_TYPE_AVATAR,
+ name: lodashGet(personalDetails, [report.managerID, 'displayName'], ''),
};
- const workspaceIcon = {
- source: policyExpenseChatAvatarSource,
- type: CONST.ICON_TYPE_WORKSPACE,
- name: workspaceName,
+ const ownerIcon = {
+ id: report.ownerAccountID,
+ source: UserUtils.getAvatar(lodashGet(personalDetails, [report.ownerAccountID, 'avatar']), report.ownerAccountID),
+ type: CONST.ICON_TYPE_AVATAR,
+ name: lodashGet(personalDetails, [report.ownerAccountID, 'displayName'], ''),
};
- // If the user is an admin, return avatar source of the other participant of the report
- // (their workspace chat) and the avatar source of the workspace
- return [adminIcon, workspaceIcon];
- }
- if (isIOUReport(report)) {
- const email = isPayer ? report.managerEmail : report.ownerEmail;
- const accountID = isPayer ? report.managerID : report.ownerAccountID;
- return [
- {
- id: accountID,
- source: UserUtils.getAvatar(lodashGet(personalDetails, [accountID, 'avatar']), accountID),
- name: email,
- type: CONST.ICON_TYPE_AVATAR,
- },
- ];
+ return isPayer ? [managerIcon, ownerIcon] : [ownerIcon, managerIcon];
}
-
return getIconsForParticipants(report.participantAccountIDs, personalDetails);
}
@@ -2324,7 +2389,7 @@ function getWhisperDisplayNames(participantAccountIDs) {
}
/**
- * Show subscript on IOU or expense report
+ * Show subscript on workspace chats / threads and expense requests
* @param {Object} report
* @returns {Boolean}
*/
@@ -2337,7 +2402,23 @@ function shouldReportShowSubscript(report) {
return true;
}
- return isExpenseReport(report);
+ if (isPolicyExpenseChat(report) && !isThread(report) && !isTaskReport(report)) {
+ return true;
+ }
+
+ if (isExpenseRequest(report)) {
+ return true;
+ }
+
+ if (isWorkspaceTaskReport(report)) {
+ return true;
+ }
+
+ if (isWorkspaceThread(report)) {
+ return true;
+ }
+
+ return false;
}
/**
@@ -2451,6 +2532,7 @@ export {
getDisplayNameForParticipant,
isChatReport,
isExpenseReport,
+ isExpenseRequest,
isIOUReport,
isTaskReport,
isTaskCompleted,
diff --git a/src/libs/SidebarUtils.js b/src/libs/SidebarUtils.js
index f51623e6fa0a..1e7a9131df2f 100644
--- a/src/libs/SidebarUtils.js
+++ b/src/libs/SidebarUtils.js
@@ -258,6 +258,7 @@ function getOptionData(reportID) {
shouldShowSubscript: false,
isPolicyExpenseChat: false,
isMoneyRequestReport: false,
+ isExpenseRequest: false,
};
const participantPersonalDetailList = _.values(OptionsListUtils.getPersonalDetailsForAccountIDs(report.participantAccountIDs, personalDetails));
@@ -272,6 +273,7 @@ function getOptionData(reportID) {
}
result.isArchivedRoom = ReportUtils.isArchivedRoom(report);
result.isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report);
+ result.isExpenseRequest = ReportUtils.isExpenseRequest(report);
result.isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report);
result.shouldShowSubscript = ReportUtils.shouldReportShowSubscript(report);
result.pendingAction = report.pendingFields ? report.pendingFields.addWorkspaceRoom || report.pendingFields.createChat : null;
diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js
index 955b5e5c2936..e0c338657ba6 100644
--- a/src/pages/home/HeaderView.js
+++ b/src/pages/home/HeaderView.js
@@ -130,6 +130,7 @@ function HeaderView(props) {
const shouldShowThreeDotsButton = !!threeDotMenuItems.length;
const shouldShowSubscript = ReportUtils.shouldReportShowSubscript(props.report);
+ const defaultSubscriptSize = ReportUtils.isExpenseRequest(props.report) ? CONST.AVATAR_SIZE.SMALL_NORMAL : CONST.AVATAR_SIZE.DEFAULT;
const icons = ReportUtils.getIcons(reportHeaderData, props.personalDetails);
const brickRoadIndicator = ReportUtils.hasReportNameError(props.report) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : '';
return (
@@ -169,8 +170,7 @@ function HeaderView(props) {
) : (
0;
const shouldDisplayThreadReplies = hasReplies && props.action.childCommenterCount && !ReportUtils.isThreadFirstChat(props.action, props.report.reportID);
- const oldestFourAccountIDs = lodashGet(props.action, 'childOldestFourAccountIDs', '').split(',');
+ const oldestFourAccountIDs = _.map(lodashGet(props.action, 'childOldestFourAccountIDs', '').split(','), (accountID) => Number(accountID));
const draftMessageRightAlign = props.draftMessage ? styles.chatItemReactionsDraftRight : {};
return (
diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js
index 3011dff69bf1..30a02336aa42 100644
--- a/src/pages/home/report/ReportActionItemSingle.js
+++ b/src/pages/home/report/ReportActionItemSingle.js
@@ -91,6 +91,7 @@ function ReportActionItemSingle(props) {
displayName = actorHint;
avatarSource = UserUtils.getAvatar(delegateDetails.avatar, props.action.delegateAccountID);
}
+ const icon = {source: avatarSource, type: isWorkspaceActor ? CONST.ICON_TYPE_WORKSPACE : CONST.ICON_TYPE_AVATAR, name: displayName, id: 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,
@@ -125,7 +126,7 @@ function ReportActionItemSingle(props) {
{props.shouldShowSubscriptAvatar ? (
diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js
index 59a5938ef923..1fbc14795997 100644
--- a/src/styles/StyleUtils.js
+++ b/src/styles/StyleUtils.js
@@ -43,6 +43,7 @@ const avatarBorderSizes = {
[CONST.AVATAR_SIZE.MEDIUM]: variables.componentBorderRadiusLarge,
[CONST.AVATAR_SIZE.LARGE]: variables.componentBorderRadiusLarge,
[CONST.AVATAR_SIZE.LARGE_BORDERED]: variables.componentBorderRadiusRounded,
+ [CONST.AVATAR_SIZE.SMALL_NORMAL]: variables.componentBorderRadiusMedium,
};
const avatarSizes = {
@@ -57,6 +58,7 @@ const avatarSizes = {
[CONST.AVATAR_SIZE.LARGE_BORDERED]: variables.avatarSizeLargeBordered,
[CONST.AVATAR_SIZE.HEADER]: variables.avatarSizeHeader,
[CONST.AVATAR_SIZE.MENTION_ICON]: variables.avatarSizeMentionIcon,
+ [CONST.AVATAR_SIZE.SMALL_NORMAL]: variables.avatarSizeSmallNormal,
};
const emptyAvatarStyles = {
diff --git a/src/styles/styles.js b/src/styles/styles.js
index dbea05a367c0..e60a7ee78fb5 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -1840,6 +1840,12 @@ const styles = {
right: -1,
},
+ secondAvatarSubscriptSmallNormal: {
+ position: 'absolute',
+ bottom: 0,
+ right: 0,
+ },
+
leftSideLargeAvatar: {
left: 15,
},
@@ -1913,6 +1919,11 @@ const styles = {
width: variables.avatarSizeNormal,
},
+ emptyAvatarSmallNormal: {
+ height: variables.avatarSizeSmallNormal,
+ width: variables.avatarSizeSmallNormal,
+ },
+
emptyAvatarSmall: {
height: variables.avatarSizeSmall,
width: variables.avatarSizeSmall,
@@ -3137,18 +3148,6 @@ const styles = {
zIndex: 2,
},
- textPill: {
- backgroundColor: themeColors.border,
- borderRadius: 10,
- overflow: 'hidden',
- paddingVertical: 2,
- flexShrink: 0,
- maxWidth: variables.badgeMaxWidth,
- fontSize: variables.fontSizeSmall,
- ...whiteSpace.pre,
- ...spacing.ph2,
- },
-
dropZoneTopInvisibleOverlay: {
position: 'absolute',
width: '100%',
diff --git a/src/styles/variables.js b/src/styles/variables.js
index 5313abc72fe4..a771aa95906e 100644
--- a/src/styles/variables.js
+++ b/src/styles/variables.js
@@ -29,15 +29,16 @@ export default {
componentBorderRadiusCard: 12,
componentBorderRadiusRounded: 24,
buttonBorderRadius: 100,
- avatarSizeLarge: 80,
- avatarSizeHeader: 40,
avatarSizeLargeBordered: 88,
+ avatarSizeLarge: 80,
avatarSizeMedium: 52,
+ avatarSizeHeader: 40,
avatarSizeNormal: 40,
+ avatarSizeSmallNormal: 32,
avatarSizeSmall: 28,
avatarSizeSmaller: 24,
- avatarSizeMidSubscript: 18,
avatarSizeSubscript: 20,
+ avatarSizeMidSubscript: 18,
avatarSizeMentionIcon: 16,
avatarSizeSmallSubscript: 14,
defaultAvatarPreviewSize: 360,