Skip to content

Commit

Permalink
Merge pull request #15671 from margelo/hanno/feat-tolltip-reaction-se…
Browse files Browse the repository at this point in the history
…nders

[web/desktop] feat: tooltip reaction senders
  • Loading branch information
luacmartins authored Mar 14, 2023
2 parents d59bc07 + 03d4169 commit ad1e244
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 22 deletions.
48 changes: 31 additions & 17 deletions src/components/Reactions/EmojiReactionBubble.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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
Expand All @@ -59,31 +63,41 @@ const defaultProps = {
const EmojiReactionBubble = (props) => {
const hasUserReacted = Report.hasAccountIDReacted(props.currentUserPersonalDetails.accountID, props.reactionUsers);
return (
<Pressable
style={({hovered, pressed}) => [
styles.emojiReactionBubble,
StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, hasUserReacted, props.sizeScale),
]}
onPress={props.onPress}
onLongPress={props.onReactionListOpen}
<Tooltip
renderTooltipContent={() => (
<ReactionTooltipContent
emojiName={props.emojiName}
emojiCodes={props.emojiCodes}
accountIDs={props.reactionUsers}
/>
)}
>
<Text style={[
styles.emojiReactionText,
StyleUtils.getEmojiReactionTextStyle(props.sizeScale),
]}
<Pressable
style={({hovered, pressed}) => [
styles.emojiReactionBubble,
StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, hasUserReacted, props.sizeScale),
]}
onPress={props.onPress}
onLongPress={props.onReactionListOpen}
>
{props.emojiCodes.join('')}
</Text>
{props.count > 0 && (
<Text style={[
styles.emojiReactionText,
StyleUtils.getEmojiReactionTextStyle(props.sizeScale),
]}
>
{props.emojiCodes.join('')}
</Text>
{props.count > 0 && (
<Text style={[
styles.reactionCounterText,
StyleUtils.getEmojiReactionCounterTextStyle(hasUserReacted, props.sizeScale),
]}
>
{props.count}
</Text>
)}
</Pressable>
)}
</Pressable>
</Tooltip>
);
};

Expand Down
77 changes: 77 additions & 0 deletions src/components/Reactions/ReactionTooltipContent.js
Original file line number Diff line number Diff line change
@@ -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 (
<View style={[styles.alignItemsCenter, styles.ph2]}>
<View style={styles.flexRow}>
{_.map(props.emojiCodes, emojiCode => (
<Text
key={emojiCode}
style={styles.reactionEmojiTitle}
>
{emojiCode}
</Text>
))}
</View>

<Text style={[
styles.mt1,
styles.textMicroBold,
styles.textReactionSenders,
]}
>
{namesString}
</Text>

<Text style={[
styles.textMicro,
styles.fontColorReactionLabel,
]}
>
{`reacted with :${props.emojiName}:`}
</Text>
</View>
);
};

ReactionTooltipContent.propTypes = propTypes;
ReactionTooltipContent.defaultProps = withCurrentUserPersonalDetails;
ReactionTooltipContent.displayName = 'ReactionTooltipContent';
export default React.memo(compose(
withPersonalDetails(),
withLocalize,
)(ReactionTooltipContent));
6 changes: 1 addition & 5 deletions src/components/Reactions/ReportActionItemReactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ const ReportActionItemReactions = (props) => {
<View style={[styles.flexRow, styles.flexWrap]}>
{_.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);

Expand Down
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.`,
Expand Down
43 changes: 43 additions & 0 deletions src/libs/PersonalDetailsUtils.js
Original file line number Diff line number Diff line change
@@ -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<string>} 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,
};
5 changes: 5 additions & 0 deletions src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,10 @@ function toggleEmojiReaction(reportID, reportAction, emoji, paramSkinTone = pref
return addEmojiReaction(reportID, reportAction, emoji, skinTone);
}

function getCurrentUserAccountID() {
return currentUserAccountID;
}

export {
addComment,
addAttachment,
Expand Down Expand Up @@ -1401,4 +1405,5 @@ export {
removeEmojiReaction,
toggleEmojiReaction,
hasAccountIDReacted,
getCurrentUserAccountID,
};
5 changes: 5 additions & 0 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2996,6 +2996,11 @@ const styles = {
lineHeight: variables.iconSizeXLarge,
},

textReactionSenders: {
color: themeColors.dark,
...wordBreak.breakWord,
},

quickReactionsContainer: {
gap: 12,
flexDirection: 'row',
Expand Down
1 change: 1 addition & 0 deletions src/styles/themes/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const darkTheme = {
successPressed: colors.greenPressed,
transparent: colors.transparent,
midtone: colors.green700,
dark: colors.midnight,

// Additional keys
overlay: colors.greenHighlightBackground,
Expand Down

0 comments on commit ad1e244

Please sign in to comment.