Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
77e670f
feat: Moved EmojiPicker into a fresh component
mananjadhav Jan 2, 2022
fe803e7
fix: Temp removed EmojiUtils ref
mananjadhav Jan 2, 2022
9caf347
fix: Added getSkinToneEmoji to utils
mananjadhav Jan 2, 2022
4484bb2
fix: Added getSkinToneEmojiFromIndex as a separate lib
mananjadhav Jan 2, 2022
3be92ed
fix: Renamed components and updated refs
mananjadhav Jan 2, 2022
186bc14
fix: Updated refs for picker
mananjadhav Jan 2, 2022
a445cc7
fix: Added emoji selection function
mananjadhav Jan 2, 2022
33c8117
chore: Code cleanup
mananjadhav Jan 2, 2022
3b5f410
fix: Reordered function and fixed import typo
mananjadhav Jan 2, 2022
223d1bb
fix: Changed prop to optional
mananjadhav Jan 2, 2022
2c411ac
fix: Added EmojiPicker to the edit comment
mananjadhav Jan 2, 2022
8ec4008
fix: Corrected imports
mananjadhav Jan 2, 2022
48ceaf1
fix: Added background to EmojiPicker
mananjadhav Jan 2, 2022
fd76442
fix: Added props to Edit component
mananjadhav Jan 3, 2022
14d23c2
fix: Moved isBlockedFromConcierge to utils
mananjadhav Jan 3, 2022
e8000a5
fix: Added onBeforeShowEmojiPicker
mananjadhav Jan 3, 2022
8d88ad8
Merge branch 'main' of https://github.com/mananjadhav/App into feat/e…
mananjadhav Jan 8, 2022
0ca63c4
Merge branch 'main' of https://github.com/mananjadhav/App into feat/e…
mananjadhav Jan 24, 2022
43cdc7e
fix: Removed emoji code from edit mode
mananjadhav Jan 24, 2022
a870c0f
fix: Removed Emoji code from Edit Message
mananjadhav Jan 24, 2022
2e3f792
fix: Removed report object to rollback for edit mode
mananjadhav Jan 24, 2022
5199d9d
Merge branch 'main' of https://github.com/mananjadhav/App into feat/e…
mananjadhav Jan 30, 2022
f2e3d4d
fix: Removed extra space
mananjadhav Jan 31, 2022
0b84ee6
fix: comment style changes
mananjadhav Jan 31, 2022
1d497e1
fix: Added type checks and removed unwanted inits
mananjadhav Jan 31, 2022
3c33ca6
Merge branch 'main' of https://github.com/mananjadhav/App into feat/e…
mananjadhav Feb 4, 2022
b5bdb8c
Merge branch 'main' of https://github.com/mananjadhav/App into feat/e…
mananjadhav Feb 8, 2022
2e1c842
feat: Updated isBlockedFromConcierge function
mananjadhav Feb 8, 2022
a116525
feat: Removed isBlockedFromConcierge function from ReportUtils
mananjadhav Feb 8, 2022
9edf829
feat: Update references for isBlockedFromConcierge
mananjadhav Feb 8, 2022
25a6a89
feat: Added comment for chatIncludesConcierge
mananjadhav Feb 8, 2022
30e91db
feat: Updated jsdocs
mananjadhav Feb 8, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import {View, FlatList} from 'react-native';
import PropTypes from 'prop-types';
import _ from 'underscore';
import lodashGet from 'lodash/get';
import CONST from '../../../../CONST';
import styles from '../../../../styles/styles';
import * as StyleUtils from '../../../../styles/StyleUtils';
import themeColors from '../../../../styles/themes/default';
import emojis from '../../../../../assets/emojis';
import CONST from '../../../CONST';
import styles from '../../../styles/styles';
import * as StyleUtils from '../../../styles/StyleUtils';
import themeColors from '../../../styles/themes/default';
import emojis from '../../../../assets/emojis';
import EmojiPickerMenuItem from '../EmojiPickerMenuItem';
import Text from '../../../../components/Text';
import TextInputFocusable from '../../../../components/TextInputFocusable';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../../components/withWindowDimensions';
import withLocalize, {withLocalizePropTypes} from '../../../../components/withLocalize';
import compose from '../../../../libs/compose';
import getOperatingSystem from '../../../../libs/getOperatingSystem';
import Text from '../../Text';
import TextInputFocusable from '../../TextInputFocusable';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../withWindowDimensions';
import withLocalize, {withLocalizePropTypes} from '../../withLocalize';
import compose from '../../../libs/compose';
import getOperatingSystem from '../../../libs/getOperatingSystem';
import EmojiSkinToneList from '../EmojiSkinToneList';
import * as EmojiUtils from '../../../../libs/EmojiUtils';
import * as EmojiUtils from '../../../libs/EmojiUtils';

const propTypes = {
/** Function to add the selected emoji to the main compose text input */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, {Component} from 'react';
import {View, FlatList} from 'react-native';
import PropTypes from 'prop-types';
import compose from '../../../../libs/compose';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../../components/withWindowDimensions';
import CONST from '../../../../CONST';
import styles from '../../../../styles/styles';
import emojis from '../../../../../assets/emojis';
import compose from '../../../libs/compose';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../withWindowDimensions';
import CONST from '../../../CONST';
import styles from '../../../styles/styles';
import emojis from '../../../../assets/emojis';
import EmojiPickerMenuItem from '../EmojiPickerMenuItem';
import Text from '../../../../components/Text';
import withLocalize, {withLocalizePropTypes} from '../../../../components/withLocalize';
import Text from '../../Text';
import withLocalize, {withLocalizePropTypes} from '../../withLocalize';
import EmojiSkinToneList from '../EmojiSkinToneList';
import * as EmojiUtils from '../../../../libs/EmojiUtils';
import * as EmojiUtils from '../../../libs/EmojiUtils';

const propTypes = {
/** Function to add the selected emoji to the main compose text input */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import {Pressable} from 'react-native';
import styles from '../../../styles/styles';
import * as StyleUtils from '../../../styles/StyleUtils';
import getButtonState from '../../../libs/getButtonState';
import Hoverable from '../../../components/Hoverable';
import Text from '../../../components/Text';
import styles from '../../styles/styles';
import * as StyleUtils from '../../styles/StyleUtils';
import getButtonState from '../../libs/getButtonState';
import Hoverable from '../Hoverable';
import Text from '../Text';

const propTypes = {
/** The unicode that is used to display the emoji */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import _ from 'underscore';
import React, {Component} from 'react';
import {View, Pressable} from 'react-native';
import PropTypes from 'prop-types';
import styles from '../../../styles/styles';
import * as Emojis from '../../../../assets/emojis';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import Text from '../../../components/Text';
import getSkinToneEmojiFromIndex from './EmojiPickerMenu/getSkinToneEmojiFromIndex';
import styles from '../../styles/styles';
import * as Emojis from '../../../assets/emojis';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import Text from '../Text';
import EmojiPickerMenuItem from './EmojiPickerMenuItem';

import getSkinToneEmojiFromIndex from './getSkinToneEmojiFromIndex';

const propTypes = {

Expand Down Expand Up @@ -52,7 +51,7 @@ class EmojiSkinToneList extends Component {
render() {
const selectedEmoji = getSkinToneEmojiFromIndex(this.props.preferredSkinTone);
return (
<View style={[styles.flexRow, styles.p1, styles.ph4]}>
<View style={[styles.flexRow, styles.p1, styles.ph4, styles.emojiPickerContainer]}>
Comment thread
puneetlath marked this conversation as resolved.
{
!this.state.isSkinToneListVisible && (
<Pressable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'underscore';
import * as Emojis from '../../../../../assets/emojis';
import * as Emojis from '../../../assets/emojis';

/**
* Fetch the emoji code of selected skinTone
Expand Down
199 changes: 199 additions & 0 deletions src/components/EmojiPicker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import React from 'react';
import PropTypes from 'prop-types';
import {Pressable, Dimensions} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import compose from '../../libs/compose';
import Popover from '../Popover';
import Tooltip from '../Tooltip';
import Icon from '../Icon';
import ONYXKEYS from '../../ONYXKEYS';
import EmojiPickerMenu from './EmojiPickerMenu';
import * as StyleUtils from '../../styles/StyleUtils';
import * as Expensicons from '../Icon/Expensicons';
import * as User from '../../libs/actions/User';
import * as EmojiUtils from '../../libs/EmojiUtils';
import getButtonState from '../../libs/getButtonState';
import styles from '../../styles/styles';
import CONST from '../../CONST';
import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';

const propTypes = {
/** Flag to disable the emoji picker button */
isDisabled: PropTypes.bool,

/** Callback on emoji popover hide */
onModalHide: PropTypes.func,

/** Callback on before showing emoji picker */
onBeforeShowEmojiPicker: PropTypes.func,
Comment thread
puneetlath marked this conversation as resolved.

/** Callback on emoji selection */
onEmojiSelected: PropTypes.func.isRequired,
...windowDimensionsPropTypes,
...withLocalizePropTypes,
};

const defaultProps = {
isDisabled: false,
onModalHide: () => {},
onBeforeShowEmojiPicker: () => {},
};

class EmojiPicker extends React.Component {
constructor(props) {
super(props);

this.hideEmojiPicker = this.hideEmojiPicker.bind(this);
this.showEmojiPicker = this.showEmojiPicker.bind(this);
this.selectEmoji = this.selectEmoji.bind(this);
this.measureEmojiPopoverAnchorPosition = this.measureEmojiPopoverAnchorPosition.bind(this);
this.setPreferredSkinTone = this.setPreferredSkinTone.bind(this);
this.focusEmojiSearchInput = this.focusEmojiSearchInput.bind(this);

this.state = {
isEmojiPickerVisible: false,

// The horizontal and vertical position (relative to the window) where the emoji popover will display.
emojiPopoverAnchorPosition: {
horizontal: 0,
vertical: 0,
},
};
}

componentDidMount() {
this.emojiPopoverDimensionListener = Dimensions.addEventListener('change', this.measureEmojiPopoverAnchorPosition);
}

componentWillUnmount() {
if (!this.emojiPopoverDimensionListener) {
return;
}
this.emojiPopoverDimensionListener.remove();
}

/**
* Update preferredSkinTone and sync with Onyx, NVP.
* @param {Number|String} skinTone
*/
setPreferredSkinTone(skinTone) {
if (skinTone === this.props.preferredSkinTone) {
return;
}

User.setPreferredSkinTone(skinTone);
}

/**
* Callback for the emoji picker to add whatever emoji is chosen into the main input
*
* @param {String} emoji
* @param {Object} emojiObject
*/
selectEmoji(emoji, emojiObject) {
EmojiUtils.addToFrequentlyUsedEmojis(this.props.frequentlyUsedEmojis, emojiObject);
this.hideEmojiPicker();
this.props.onEmojiSelected(emoji);
}

hideEmojiPicker() {
this.setState({isEmojiPickerVisible: false});
}

showEmojiPicker() {
if (_.isFunction(this.props.onBeforeShowEmojiPicker)) {
this.props.onBeforeShowEmojiPicker();
}
this.setState({isEmojiPickerVisible: true});
}

measureEmojiPopoverAnchorPosition() {
if (!this.emojiPopoverAnchor) {
return;
}

this.emojiPopoverAnchor.measureInWindow((x, y, width) => this.setState({
emojiPopoverAnchorPosition: {horizontal: x + width, vertical: y},
}));
}

/**
* Focus the search input in the emoji picker.
*/
focusEmojiSearchInput() {
if (!this.emojiSearchInput) {
return;
}
this.emojiSearchInput.focus();
}

render() {
return (
<>
{

Comment thread
mananjadhav marked this conversation as resolved.
// There is no way to disable animations and they are really laggy, because there are so many
// emojis. The best alternative is to set it to 1ms so it just "pops" in and out
}
<Popover
isVisible={this.state.isEmojiPickerVisible}
onClose={this.hideEmojiPicker}
onModalShow={this.focusEmojiSearchInput}
onModalHide={this.props.onModalHide}
hideModalContentWhileAnimating
animationInTiming={1}
animationOutTiming={1}
anchorPosition={{
bottom: this.props.windowHeight - this.state.emojiPopoverAnchorPosition.vertical,
left: this.state.emojiPopoverAnchorPosition.horizontal - CONST.EMOJI_PICKER_SIZE,
}}
>
<EmojiPickerMenu
onEmojiSelected={this.selectEmoji}
ref={el => this.emojiSearchInput = el}
preferredSkinTone={this.props.preferredSkinTone}
updatePreferredSkinTone={this.setPreferredSkinTone}
frequentlyUsedEmojis={this.props.frequentlyUsedEmojis}
/>
</Popover>
<Pressable
style={({hovered, pressed}) => ([
styles.chatItemEmojiButton,
StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed)),
])}
ref={el => this.emojiPopoverAnchor = el}
onLayout={this.measureEmojiPopoverAnchorPosition}
onPress={this.showEmojiPicker}
disabled={this.props.isDisabled}
>
{({hovered, pressed}) => (
<Tooltip text={this.props.translate('reportActionCompose.emoji')}>
<Icon
src={Expensicons.Emoji}
fill={StyleUtils.getIconFillColor(getButtonState(hovered, pressed))}
/>
</Tooltip>
)}
</Pressable>
</>
);
}
}

EmojiPicker.propTypes = propTypes;
EmojiPicker.defaultProps = defaultProps;

export default compose(
withWindowDimensions,
withLocalize,
withOnyx({
preferredSkinTone: {
key: ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE,
},
frequentlyUsedEmojis: {
key: ONYXKEYS.FREQUENTLY_USED_EMOJIS,
},
}),
)(EmojiPicker);
1 change: 0 additions & 1 deletion src/libs/EmojiUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ function addToFrequentlyUsedEmojis(frequentlyUsedEmojis, newEmoji) {
User.setFrequentlyUsedEmojis(frequentEmojiList);
}


export {
isSingleEmoji,
getDynamicHeaderIndices,
Expand Down
19 changes: 12 additions & 7 deletions src/libs/actions/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import redirectToSignIn from './SignInRedirect';
import NameValuePair from './NameValuePair';
import Growl from '../Growl';
import * as Localize from '../Localize';
import getSkinToneEmojiFromIndex from '../../pages/home/report/EmojiPickerMenu/getSkinToneEmojiFromIndex';
import * as CloseAccountActions from './CloseAccount';
import * as Link from './Link';
import getSkinToneEmojiFromIndex from '../../components/EmojiPicker/getSkinToneEmojiFromIndex';

let sessionAuthToken = '';
let sessionEmail = '';
Expand Down Expand Up @@ -230,17 +230,22 @@ function validateLogin(accountID, validateCode) {
}

/**
* Checks if the expiresAt date of a user's ban is before right now
* Checks the blockedFromConcierge object to see if it has an expiresAt key,
* and if so whether the expiresAt date of a user's ban is before right now
*
* @param {String} expiresAt
* @returns {boolean}
* @param {Object} blockedFromConcierge
* @returns {Boolean}
*/
function isBlockedFromConcierge(expiresAt) {
if (!expiresAt) {
function isBlockedFromConcierge(blockedFromConcierge) {
if (_.isEmpty(blockedFromConcierge)) {
return false;
}

return moment().isBefore(moment(expiresAt), 'day');
if (!blockedFromConcierge.expiresAt) {
return false;
}

return moment().isBefore(moment(blockedFromConcierge.expiresAt), 'day');
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/libs/reportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,16 @@ function isConciergeChatReport(report) {
&& report.participants[0] === CONST.EMAIL.CONCIERGE;
}

/**
* Returns true if Concierge is one of the chat participants (1:1 as well as group chats)
* @param {Object} report
* @returns {Boolean}
*/
function chatIncludesConcierge(report) {
return report.participants
&& _.contains(report.participants, CONST.EMAIL.CONCIERGE);
}

Comment thread
mananjadhav marked this conversation as resolved.
/**
* Returns true if there is any automated expensify account in emails
* @param {Array} emails
Expand Down Expand Up @@ -246,4 +256,5 @@ export {
hasExpensifyEmails,
canShowReportRecipientLocalTime,
formatReportLastMessageText,
chatIncludesConcierge,
};
2 changes: 1 addition & 1 deletion src/pages/RequestCallPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class RequestCallPage extends Component {
}

render() {
const isBlockedFromConcierge = !_.isEmpty(this.props.blockedFromConcierge) && User.isBlockedFromConcierge(this.props.blockedFromConcierge.expiresAt);
const isBlockedFromConcierge = User.isBlockedFromConcierge(this.props.blockedFromConcierge);

return (
<ScreenWrapper>
Expand Down
Loading