diff --git a/src/components/Reactions/EmojiReactionBubble.js b/src/components/Reactions/EmojiReactionBubble.js
index 6066bf0a8199..0b1694dbe0cf 100644
--- a/src/components/Reactions/EmojiReactionBubble.js
+++ b/src/components/Reactions/EmojiReactionBubble.js
@@ -9,8 +9,12 @@ import withCurrentUserPersonalDetails, {
withCurrentUserPersonalDetailsPropTypes,
} from '../withCurrentUserPersonalDetails';
import * as Report from '../../libs/actions/Report';
+import Tooltip from '../Tooltip';
+import ReactionTooltipContent from './ReactionTooltipContent';
const propTypes = {
+ emojiName: PropTypes.string.isRequired,
+
/**
* The emoji codes to display in the bubble.
*/
@@ -35,7 +39,7 @@ const propTypes = {
/**
* The account ids of the users who reacted.
*/
- reactionUsers: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
+ reactionUsers: PropTypes.arrayOf(PropTypes.string),
/**
* The default size of the reaction bubble is defined
@@ -59,22 +63,31 @@ const defaultProps = {
const EmojiReactionBubble = (props) => {
const hasUserReacted = Report.hasAccountIDReacted(props.currentUserPersonalDetails.accountID, props.reactionUsers);
return (
- [
- styles.emojiReactionBubble,
- StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, hasUserReacted, props.sizeScale),
- ]}
- onPress={props.onPress}
- onLongPress={props.onReactionListOpen}
+ (
+
+ )}
>
- [
+ styles.emojiReactionBubble,
+ StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, hasUserReacted, props.sizeScale),
+ ]}
+ onPress={props.onPress}
+ onLongPress={props.onReactionListOpen}
>
- {props.emojiCodes.join('')}
-
- {props.count > 0 && (
+
+ {props.emojiCodes.join('')}
+
+ {props.count > 0 && (
{
>
{props.count}
- )}
-
+ )}
+
+
);
};
diff --git a/src/components/Reactions/ReactionTooltipContent.js b/src/components/Reactions/ReactionTooltipContent.js
new file mode 100644
index 000000000000..5a190eee863b
--- /dev/null
+++ b/src/components/Reactions/ReactionTooltipContent.js
@@ -0,0 +1,77 @@
+import React from 'react';
+import {View} from 'react-native';
+import PropTypes from 'prop-types';
+import _ from 'underscore';
+import styles from '../../styles/styles';
+import {withPersonalDetails} from '../OnyxProvider';
+import * as PersonalDetailsUtils from '../../libs/PersonalDetailsUtils';
+import Text from '../Text';
+import withCurrentUserPersonalDetails, {
+ withCurrentUserPersonalDetailsPropTypes,
+} from '../withCurrentUserPersonalDetails';
+import compose from '../../libs/compose';
+import withLocalize from '../withLocalize';
+
+const propTypes = {
+ /**
+ * A list of emoji codes to display in the tooltip.
+ */
+ emojiCodes: PropTypes.arrayOf(PropTypes.string).isRequired,
+
+ /**
+ * The name of the emoji to display in the tooltip.
+ */
+ emojiName: PropTypes.string.isRequired,
+
+ /**
+ * A list of account IDs to display in the tooltip.
+ */
+ accountIDs: PropTypes.arrayOf(PropTypes.string).isRequired,
+
+ ...withCurrentUserPersonalDetailsPropTypes,
+};
+
+const ReactionTooltipContent = (props) => {
+ const users = PersonalDetailsUtils.getPersonalDetailsByIDs(props.accountIDs, true);
+ const namesString = _.filter(_.map(users, user => user && user.displayName), n => n).join(', ');
+
+ return (
+
+
+ {_.map(props.emojiCodes, emojiCode => (
+
+ {emojiCode}
+
+ ))}
+
+
+
+ {namesString}
+
+
+
+ {`reacted with :${props.emojiName}:`}
+
+
+ );
+};
+
+ReactionTooltipContent.propTypes = propTypes;
+ReactionTooltipContent.defaultProps = withCurrentUserPersonalDetails;
+ReactionTooltipContent.displayName = 'ReactionTooltipContent';
+export default React.memo(compose(
+ withPersonalDetails(),
+ withLocalize,
+)(ReactionTooltipContent));
diff --git a/src/components/Reactions/ReportActionItemReactions.js b/src/components/Reactions/ReportActionItemReactions.js
index bfc67e95c1df..cbac72accf5f 100644
--- a/src/components/Reactions/ReportActionItemReactions.js
+++ b/src/components/Reactions/ReportActionItemReactions.js
@@ -59,11 +59,7 @@ const ReportActionItemReactions = (props) => {
{_.map(reactionsWithCount, (reaction) => {
const reactionCount = reaction.users.length;
- if (reactionCount === 0) {
- return null;
- }
-
- const reactionUsers = _.map(reaction.users, sender => sender.accountID);
+ const reactionUsers = _.map(reaction.users, sender => sender.accountID.toString());
const emoji = _.find(emojis, e => e.name === reaction.emoji);
const emojiCodes = getUniqueEmojiCodes(emoji, reaction.users);
diff --git a/src/languages/en.js b/src/languages/en.js
index 83de58b70b24..209f0f70fa1e 100755
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -115,6 +115,7 @@ export default {
enterManually: 'Enter it manually',
message: 'Message ',
leaveRoom: 'Leave room',
+ you: 'You',
your: 'your',
conciergeHelp: 'Please reach out to Concierge for help.',
maxParticipantsReached: ({count}) => `You've selected the maximum number (${count}) of participants.`,
diff --git a/src/languages/es.js b/src/languages/es.js
index d2305eb4ca2a..89679622b719 100644
--- a/src/languages/es.js
+++ b/src/languages/es.js
@@ -114,6 +114,7 @@ export default {
enterManually: 'Ingresar manualmente',
message: 'Chatear con ',
leaveRoom: 'Salir de la sala de chat',
+ you: 'Tú',
your: 'tu',
conciergeHelp: 'Por favor contacta con Concierge para obtener ayuda.',
maxParticipantsReached: ({count}) => `Has seleccionado el número máximo (${count}) de participantes.`,
diff --git a/src/libs/PersonalDetailsUtils.js b/src/libs/PersonalDetailsUtils.js
new file mode 100644
index 000000000000..8307e3587005
--- /dev/null
+++ b/src/libs/PersonalDetailsUtils.js
@@ -0,0 +1,43 @@
+import Onyx from 'react-native-onyx';
+import _ from 'underscore';
+import ONYXKEYS from '../ONYXKEYS';
+import * as Report from './actions/Report';
+import * as Localize from './Localize';
+
+let personalDetails = [];
+Onyx.connect({
+ key: ONYXKEYS.PERSONAL_DETAILS,
+ callback: val => personalDetails = _.values(val),
+});
+
+/**
+ * Given a list of account IDs (as string) it will return an array of personal details objects.
+ * @param {Array} accountIDs - Array of accountIDs
+ * @param {boolean} shouldChangeUserDisplayName - It will replace the current user's personal detail object's displayName with 'You'.
+ * @returns {Array} - Array of personal detail objects
+ */
+function getPersonalDetailsByIDs(accountIDs, shouldChangeUserDisplayName = false) {
+ const result = [];
+ const currentAccountID = Report.getCurrentUserAccountID();
+ _.each(personalDetails, (detail) => {
+ for (let i = 0; i < accountIDs.length; i++) {
+ if (detail.accountID === accountIDs[i]) {
+ if (shouldChangeUserDisplayName && currentAccountID.toString() === detail.accountID) {
+ result[i] = {
+ ...detail,
+ displayName: Localize.translateLocal('common.you'),
+ };
+ } else {
+ result[i] = detail;
+ }
+ break;
+ }
+ }
+ });
+ return result;
+}
+
+export {
+ // eslint-disable-next-line import/prefer-default-export
+ getPersonalDetailsByIDs,
+};
diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index c4549b6cc121..563816d396c1 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -1366,6 +1366,10 @@ function toggleEmojiReaction(reportID, reportAction, emoji, paramSkinTone = pref
return addEmojiReaction(reportID, reportAction, emoji, skinTone);
}
+function getCurrentUserAccountID() {
+ return currentUserAccountID;
+}
+
export {
addComment,
addAttachment,
@@ -1401,4 +1405,5 @@ export {
removeEmojiReaction,
toggleEmojiReaction,
hasAccountIDReacted,
+ getCurrentUserAccountID,
};
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 64245fcde07a..841c02f5b11d 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -2996,6 +2996,11 @@ const styles = {
lineHeight: variables.iconSizeXLarge,
},
+ textReactionSenders: {
+ color: themeColors.dark,
+ ...wordBreak.breakWord,
+ },
+
quickReactionsContainer: {
gap: 12,
flexDirection: 'row',
diff --git a/src/styles/themes/default.js b/src/styles/themes/default.js
index 97a3da5d500d..baa0e18e57d9 100644
--- a/src/styles/themes/default.js
+++ b/src/styles/themes/default.js
@@ -29,6 +29,7 @@ const darkTheme = {
successPressed: colors.greenPressed,
transparent: colors.transparent,
midtone: colors.green700,
+ dark: colors.midnight,
// Additional keys
overlay: colors.greenHighlightBackground,