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

feat: add/remove reaction #15210

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
80333cb
wip: render quick reactions in context menu
hannojg Feb 15, 2023
071b88f
wip: adjustments for web
hannojg Feb 15, 2023
a984a0b
add actions for adding and removing reactions
hannojg Feb 15, 2023
f96b73b
wip: add reaction when using quick reactions
hannojg Feb 15, 2023
a164fa1
render emoji reactions underneath a message
hannojg Feb 15, 2023
f0926c1
TEMP: REMOVE ME once accountID on personal details is live
hannojg Feb 15, 2023
318931f
change from `login` to `accountID`
hannojg Feb 15, 2023
549bcbe
wip: adding / removing
hannojg Feb 15, 2023
c7de8cd
change: when removing reactions, remove the whole emoji object
hannojg Feb 16, 2023
7281f82
cleanup code
hannojg Feb 16, 2023
7907fd2
show AddReactionBubble in the row of reactions as well
hannojg Feb 16, 2023
71220c0
implemented toggling reactions when selecting the same again
hannojg Feb 16, 2023
44909ab
close context menu when open emoji picker or selected emoji
hannojg Feb 16, 2023
8042b9b
fix emoji picker being wrong positioned
hannojg Feb 16, 2023
483b119
wip: mini menu
hannojg Feb 16, 2023
20d463c
wip: mini menu adding add reaction icon
hannojg Feb 16, 2023
99bfb91
fix: mini menu open picker wrong positioned + was closing
hannojg Feb 16, 2023
2f61782
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Feb 16, 2023
85357b1
fix: open emoji picker on mobile
hannojg Feb 17, 2023
4c07ba2
clean up
hannojg Feb 17, 2023
e064297
rename and document functions
hannojg Feb 19, 2023
52a9135
pick the preferred skin tone
hannojg Feb 19, 2023
c8c450c
updated JSDocs
hannojg Feb 19, 2023
bf7d78e
updated JSDocs
hannojg Feb 19, 2023
f874ea5
updated JSDocs
hannojg Feb 19, 2023
267338e
remove todos
hannojg Feb 19, 2023
b09e44d
apply suggestions from design doc
hannojg Feb 19, 2023
1b8041f
apply suggestions from design doc
hannojg Feb 19, 2023
33c0554
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Feb 19, 2023
8675022
fix tests
hannojg Feb 19, 2023
57082d6
fix: pas emoji object directly
hannojg Feb 20, 2023
28f80d3
refactor: pass ref optional as arg
hannojg Feb 20, 2023
ba6970e
fix: pass anchor position for emoji picker as well to fix issue with …
hannojg Feb 20, 2023
f2e407c
apply suggestions from code review
hannojg Feb 20, 2023
97c8d08
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Feb 28, 2023
3b24a03
enable API calls
hannojg Feb 28, 2023
f4c94d8
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 4, 2023
8bc100b
fix issue where reactions won't re-render
hannojg Mar 5, 2023
e9ba4f5
temp fix toggling reactions is broken
hannojg Mar 5, 2023
55834f6
fix removing reactions causing artefacts
hannojg Mar 5, 2023
1cb6d60
fix regression where mini menu items weren't displaying correctly
hannojg Mar 5, 2023
516ef3a
fix: don't remove reactions when editing a message
hannojg Mar 5, 2023
adb6e7d
expose hasAccountIDReacted
hannojg Mar 6, 2023
debe8ad
apply code suggestion
hannojg Mar 6, 2023
8ed9e99
Update src/libs/actions/Report.js
hannojg Mar 6, 2023
d8fa085
apply code suggestion
hannojg Mar 6, 2023
da0e536
apply code suggestion
hannojg Mar 6, 2023
5b2c512
apply code suggestion
hannojg Mar 6, 2023
5842cf7
apply code suggestion
hannojg Mar 6, 2023
952fe98
remove unnecessary requestLayoutAnimation
hannojg Mar 6, 2023
dd48b96
added translations
hannojg Mar 6, 2023
c7c3411
match text
hannojg Mar 6, 2023
db1026a
reflect preferred skin tone in the rest of the UI
hannojg Mar 6, 2023
5e7e7c1
fixed bug where mini context menu wouldn't close
hannojg Mar 6, 2023
b73de4b
fix: make emojis in quick reaction unselectable
hannojg Mar 6, 2023
5db0b1f
fix: immediately remove reaction bar when no reactions are present an…
hannojg Mar 6, 2023
231fb63
fix tests
hannojg Mar 6, 2023
96d55ae
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 6, 2023
662c8ef
fix warning
hannojg Mar 6, 2023
f45dfeb
suppress eslint warning
hannojg Mar 6, 2023
91dc75f
remove unused default props
hannojg Mar 6, 2023
5a62b43
remove focusable prop as not needed on web
hannojg Mar 6, 2023
1e5c971
add tooltip
hannojg Mar 6, 2023
cd93903
fix key issue
hannojg Mar 6, 2023
6520062
fix focusable prop
hannojg Mar 7, 2023
d63a77b
rename to openContextMenu and shouldKeepOpen
hannojg Mar 7, 2023
e332259
Revert "TEMP: REMOVE ME once accountID on personal details is live"
hannojg Mar 7, 2023
effd5f4
add container styles back
hannojg Mar 7, 2023
840e381
Merge branch 'main' of github.com:margelo/expensify-app-fork into han…
hannojg Mar 7, 2023
dd5b07c
skip reactions for IOU messages for now
hannojg Mar 7, 2023
7af1573
fix focus on AddReactionBubble
hannojg Mar 8, 2023
baa93cc
fix safari selection bug
hannojg Mar 8, 2023
9b8e1ac
fix adding multiple times the same reaction
hannojg Mar 8, 2023
9e3596f
check specifically for undefined
hannojg Mar 8, 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
5 changes: 5 additions & 0 deletions assets/images/add-reaction.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,32 @@ const CONST = {
MAKE_REQUEST_WITH_SIDE_EFFECTS: 'makeRequestWithSideEffects',
},

QUICK_REACTIONS: [
{
name: '+1',
code: '👍',
types: [
'👍🏿',
'👍🏾',
'👍🏽',
'👍🏼',
'👍🏻',
],
},
{
name: 'heart',
code: '❤️',
},
{
name: 'joy',
code: '😂',
},
{
name: 'fire',
code: '🔥',
},
],

TFA_CODE_LENGTH: 6,
CHAT_ATTACHMENT_TOKEN_KEY: 'X-Chat-Attachment-Token',

Expand Down
77 changes: 77 additions & 0 deletions src/components/BaseMiniContextMenuItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {Pressable, View} from 'react-native';
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'underscore';
import styles from '../styles/styles';
import * as StyleUtils from '../styles/StyleUtils';
import getButtonState from '../libs/getButtonState';
import variables from '../styles/variables';
import Tooltip from './Tooltip';

const propTypes = {
/**
* Text to display when hovering the menu item
*/
tooltipText: PropTypes.string.isRequired,

/**
* Callback to fire on press
*/
onPress: PropTypes.func.isRequired,

/**
* The children to display within the menu item
*/
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired,

/**
* Whether the button should be in the active state
*/
isDelayButtonStateComplete: PropTypes.bool,

/**
* A ref to forward to the Pressable
*/
innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
};

const defaultProps = {
isDelayButtonStateComplete: true,
innerRef: () => {},
};

/**
* Component that renders a mini context menu item with a
* pressable. Also renders a tooltip when hovering the item.
* @param {Object} props
stitesExpensify marked this conversation as resolved.
Show resolved Hide resolved
* @returns {JSX.Element}
*/
const BaseMiniContextMenuItem = props => (
<Tooltip text={props.tooltipText}>
<Pressable
ref={props.innerRef}
focusable
onPress={props.onPress}
accessibilityLabel={props.tooltipText}
Copy link
Contributor

Choose a reason for hiding this comment

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

Coming from #33547, we should add prop role={CONST.ROLE.BUTTON} if the Pressable is a button/icon button to avoid text selection issue on double click.

style={
({hovered, pressed}) => [
styles.reportActionContextMenuMiniButton,
StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, props.isDelayButtonStateComplete)),
]
}
>
{pressableState => (
<View style={[StyleUtils.getWidthAndHeightStyle(variables.iconSizeNormal), styles.alignItemsCenter, styles.justifyContentCenter]}>
{_.isFunction(props.children) ? props.children(pressableState) : props.children}
</View>
)}
</Pressable>
</Tooltip>
);

BaseMiniContextMenuItem.propTypes = propTypes;
BaseMiniContextMenuItem.defaultProps = defaultProps;
BaseMiniContextMenuItem.displayName = 'BaseMiniContextMenuItem';

// eslint-disable-next-line react/jsx-props-no-spreading
export default React.forwardRef((props, ref) => <BaseMiniContextMenuItem {...props} innerRef={ref} />);
40 changes: 14 additions & 26 deletions src/components/ContextMenuItem.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {Pressable, View} from 'react-native';
import MenuItem from './MenuItem';
import Tooltip from './Tooltip';
import Icon from './Icon';
import styles from '../styles/styles';
import * as StyleUtils from '../styles/StyleUtils';
import getButtonState from '../libs/getButtonState';
import withDelayToggleButtonState, {withDelayToggleButtonStatePropTypes} from './withDelayToggleButtonState';
import variables from '../styles/variables';
import BaseMiniContextMenuItem from './BaseMiniContextMenuItem';

const propTypes = {
/** Icon Component */
Expand Down Expand Up @@ -75,29 +73,19 @@ class ContextMenuItem extends Component {
return (
this.props.isMini
? (
<Tooltip text={text}>
<Pressable
focusable
accessibilityLabel={text}
onPress={this.triggerPressAndUpdateSuccess}
style={
({hovered, pressed}) => [
styles.reportActionContextMenuMiniButton,
StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, this.props.isDelayButtonStateComplete)),
]
}
>
{({hovered, pressed}) => (
<View style={[StyleUtils.getWidthAndHeightStyle(variables.iconSizeNormal), styles.alignItemsCenter, styles.justifyContentCenter]}>
<Icon
small
src={icon}
fill={StyleUtils.getIconFillColor(getButtonState(hovered, pressed, this.props.isDelayButtonStateComplete))}
/>
</View>
)}
</Pressable>
</Tooltip>
<BaseMiniContextMenuItem
tooltipText={text}
onPress={this.triggerPressAndUpdateSuccess}
isDelayButtonStateComplete={this.props.isDelayButtonStateComplete}
>
{({hovered, pressed}) => (
<Icon
small
src={icon}
fill={StyleUtils.getIconFillColor(getButtonState(hovered, pressed, this.props.isDelayButtonStateComplete))}
/>
)}
</BaseMiniContextMenuItem>
) : (
<MenuItem
title={text}
Expand Down
24 changes: 16 additions & 8 deletions src/components/EmojiPicker/EmojiPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import EmojiPickerMenu from './EmojiPickerMenu';
import CONST from '../../CONST';
import PopoverWithMeasuredContent from '../PopoverWithMeasuredContent';

const DEFAULT_ANCHOR_ORIGIN = {
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
};

class EmojiPicker extends React.Component {
constructor(props) {
super(props);
Expand All @@ -27,6 +32,8 @@ class EmojiPicker extends React.Component {
horizontal: 0,
vertical: 0,
},

emojiPopoverAnchorOrigin: DEFAULT_ANCHOR_ORIGIN,
};
}

Expand Down Expand Up @@ -54,8 +61,9 @@ class EmojiPicker extends React.Component {
* Callback for the emoji picker to add whatever emoji is chosen into the main input
*
* @param {String} emoji
* @param {Object} emojiObject
*/
selectEmoji(emoji) {
selectEmoji(emoji, emojiObject) {
// Prevent fast click / multiple emoji selection;
// The first click will hide the emoji picker by calling the hideEmojiPicker() function
// and in that function the emojiPopoverAnchor prop to will be set to null (synchronously)
Expand All @@ -66,7 +74,7 @@ class EmojiPicker extends React.Component {

this.hideEmojiPicker();
if (_.isFunction(this.onEmojiSelected)) {
this.onEmojiSelected(emoji);
this.onEmojiSelected(emoji, emojiObject);
}
}

Expand All @@ -81,8 +89,10 @@ class EmojiPicker extends React.Component {
* @param {Function} [onModalHide=() => {}] - Run a callback when Modal hides.
* @param {Function} [onEmojiSelected=() => {}] - Run a callback when Emoji selected.
* @param {Element} emojiPopoverAnchor - Element to which Popover is anchored
* @param {Object} [anchorOrigin=DEFAULT_ANCHOR_ORIGIN] - Anchor origin for Popover
* @param {Function} [onWillShow=() => {}] - Run a callback when Popover will show
*/
showEmojiPicker(onModalHide, onEmojiSelected, emojiPopoverAnchor) {
showEmojiPicker(onModalHide, onEmojiSelected, emojiPopoverAnchor, anchorOrigin, onWillShow = () => {}) {
this.onModalHide = onModalHide;
this.onEmojiSelected = onEmojiSelected;
this.emojiPopoverAnchor = emojiPopoverAnchor;
Expand All @@ -93,7 +103,8 @@ class EmojiPicker extends React.Component {
}

this.measureEmojiPopoverAnchorPosition().then((emojiPopoverAnchorPosition) => {
this.setState({isEmojiPickerVisible: true, emojiPopoverAnchorPosition});
onWillShow();
this.setState({isEmojiPickerVisible: true, emojiPopoverAnchorPosition, emojiPopoverAnchorOrigin: anchorOrigin || DEFAULT_ANCHOR_ORIGIN});
});
}

Expand Down Expand Up @@ -157,10 +168,7 @@ class EmojiPicker extends React.Component {
width: CONST.EMOJI_PICKER_SIZE.WIDTH,
height: CONST.EMOJI_PICKER_SIZE.HEIGHT,
}}
anchorOrigin={{
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
}}
anchorOrigin={this.state.emojiPopoverAnchorOrigin}
measureContent={this.measureContent}
>
<EmojiPickerMenu
Expand Down
2 changes: 1 addition & 1 deletion src/components/EmojiPicker/EmojiPickerMenu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class EmojiPickerMenu extends Component {
*/
addToFrequentAndSelectEmoji(emoji, emojiObject) {
EmojiUtils.addToFrequentlyUsedEmojis(this.props.frequentlyUsedEmojis, emojiObject);
this.props.onEmojiSelected(emoji);
this.props.onEmojiSelected(emoji, emojiObject);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class EmojiPickerMenu extends Component {
*/
addToFrequentAndSelectEmoji(emoji, emojiObject) {
EmojiUtils.addToFrequentlyUsedEmojis(this.props.frequentlyUsedEmojis, emojiObject);
this.props.onEmojiSelected(emoji);
this.props.onEmojiSelected(emoji, emojiObject);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ import Facebook from '../../../assets/images/social-facebook.svg';
import Podcast from '../../../assets/images/social-podcast.svg';
import Linkedin from '../../../assets/images/social-linkedin.svg';
import Instagram from '../../../assets/images/social-instagram.svg';
import AddReaction from '../../../assets/images/add-reaction.svg';

export {
ActiveRoomAvatar,
AddReaction,
AdminRoomAvatar,
Android,
AnnounceRoomAvatar,
Expand Down
Loading
Loading