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

[web/desktop] feat: tooltip reaction senders #15671

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
02eca70
Merge branch 'hanno/change-tooltip-accept-generic-content' of github.…
hannojg Mar 5, 2023
9dd9e31
implementation
hannojg Mar 5, 2023
d736530
jsdoc comments
hannojg Mar 6, 2023
55b852f
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 8, 2023
06d798b
Merge branch 'hanno/feat-add-remove-reactions' of github.com:margelo/…
hannojg Mar 8, 2023
705dd64
fix reactioneers names not showing up
hannojg Mar 8, 2023
3a3682a
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 8, 2023
7642ae9
fix emoji preview
hannojg Mar 8, 2023
4e4bc97
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 9, 2023
135d106
change to PersonalDetailsUtils with correct implementation
hannojg Mar 9, 2023
e28f7bf
Update src/components/Reactions/ReportActionItemReactions.js
hannojg Mar 10, 2023
79300e1
chain
hannojg Mar 10, 2023
76d6187
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 13, 2023
f58a89c
add null handling
hannojg Mar 13, 2023
e207e9e
display user's display name as "you"
hannojg Mar 13, 2023
af656ec
fix flickering
hannojg Mar 14, 2023
ae248ef
Update src/libs/PersonalDetailsUtils.js
hannojg Mar 14, 2023
2b49362
Update src/libs/PersonalDetailsUtils.js
hannojg Mar 14, 2023
511c2f7
Update src/components/Reactions/ReactionTooltipContent.js
hannojg Mar 14, 2023
0b8eb80
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 14, 2023
03d4169
only current account id needs to get stringified
hannojg Mar 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(', ');
stitesExpensify marked this conversation as resolved.
Show resolved Hide resolved

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