-
Notifications
You must be signed in to change notification settings - Fork 3k
/
EmojiReactionBubble.js
105 lines (90 loc) · 3.59 KB
/
EmojiReactionBubble.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import React from 'react';
import PropTypes from 'prop-types';
import styles from '../../styles/styles';
import Text from '../Text';
import * as StyleUtils from '../../styles/StyleUtils';
import PressableWithSecondaryInteraction from '../PressableWithSecondaryInteraction';
import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions';
import {withCurrentUserPersonalDetailsDefaultProps} from '../withCurrentUserPersonalDetails';
import CONST from '../../CONST';
const propTypes = {
/**
* The emoji codes to display in the bubble.
*/
emojiCodes: PropTypes.arrayOf(PropTypes.string).isRequired,
/**
* Called when the user presses on the reaction bubble.
*/
onPress: PropTypes.func.isRequired,
/**
* Called when the user long presses or right clicks
* on the reaction bubble.
*/
onReactionListOpen: PropTypes.func,
/**
* The number of reactions to display in the bubble.
*/
count: PropTypes.number,
/** Whether it is for context menu so we can modify its style */
isContextMenu: PropTypes.bool,
/**
* Returns true if the current account has reacted to the report action (with the given skin tone).
*/
hasUserReacted: PropTypes.bool,
/** We disable reacting with emojis on report actions that have errors */
shouldBlockReactions: PropTypes.bool,
...windowDimensionsPropTypes,
};
const defaultProps = {
count: 0,
onReactionListOpen: () => {},
isContextMenu: false,
shouldBlockReactions: false,
...withCurrentUserPersonalDetailsDefaultProps,
};
function EmojiReactionBubble(props) {
return (
<PressableWithSecondaryInteraction
style={({hovered, pressed}) => [
styles.emojiReactionBubble,
StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, props.hasUserReacted, props.isContextMenu),
props.shouldBlockReactions && styles.cursorDisabled,
]}
onPress={() => {
if (props.shouldBlockReactions) {
return;
}
props.onPress();
}}
onLongPress={props.onReactionListOpen}
onSecondaryInteraction={props.onReactionListOpen}
ref={props.forwardedRef}
enableLongPressWithHover={props.isSmallScreenWidth}
onMouseDown={(e) => {
// Allow text input blur when emoji reaction is right clicked
if (e && e.button === 2) {
return;
}
// Prevent text input blur when emoji reaction is left clicked
e.preventDefault();
}}
accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON}
accessibilityLabel={props.emojiCodes.join('')}
>
<Text style={[styles.emojiReactionBubbleText, styles.userSelectNone, StyleUtils.getEmojiReactionBubbleTextStyle(props.isContextMenu)]}>{props.emojiCodes.join('')}</Text>
{props.count > 0 && <Text style={[styles.reactionCounterText, styles.userSelectNone, StyleUtils.getEmojiReactionCounterTextStyle(props.hasUserReacted)]}>{props.count}</Text>}
</PressableWithSecondaryInteraction>
);
}
EmojiReactionBubble.propTypes = propTypes;
EmojiReactionBubble.defaultProps = defaultProps;
EmojiReactionBubble.displayName = 'EmojiReactionBubble';
export default withWindowDimensions(
React.forwardRef((props, ref) => (
<EmojiReactionBubble
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
forwardedRef={ref}
/>
)),
);