diff --git a/assets/emojis.js b/assets/emojis.js index cf3270a78fe4..880cf7e32389 100644 --- a/assets/emojis.js +++ b/assets/emojis.js @@ -1,3 +1,12 @@ +import Smiley from './images/emoji.svg'; +import AnimalsAndNature from './images/emojiCategoryIcons/plant.svg'; +import FoodAndDrink from './images/emojiCategoryIcons/hamburger.svg'; +import TravelAndPlaces from './images/emojiCategoryIcons/plane.svg'; +import Activities from './images/emojiCategoryIcons/soccer-ball.svg'; +import Objects from './images/emojiCategoryIcons/light-bulb.svg'; +import Symbols from './images/emojiCategoryIcons/peace-sign.svg'; +import Flags from './images/emojiCategoryIcons/flag.svg'; + /* * This list is generated from the code here https://github.com/github/gemoji/blob/master/db/emoji.json * Each code is then converted to hex by replacing the "U+" with "0x" @@ -68,6 +77,7 @@ const emojis = [ { code: 'smileysAndEmotion', header: true, + icon: Smiley, }, { name: 'grinning', @@ -6965,6 +6975,7 @@ const emojis = [ { code: 'animalsAndNature', header: true, + icon: AnimalsAndNature, }, { name: 'monkey_face', @@ -8138,6 +8149,7 @@ const emojis = [ { code: 'foodAndDrink', header: true, + icon: FoodAndDrink, }, { name: 'grapes', @@ -9315,6 +9327,7 @@ const emojis = [ { code: 'travelAndPlaces', header: true, + icon: TravelAndPlaces, }, { name: 'earth_africa', @@ -11434,6 +11447,7 @@ const emojis = [ { code: 'activities', header: true, + icon: Activities, }, { name: 'jack_o_lantern', @@ -12271,6 +12285,7 @@ const emojis = [ { code: 'objects', header: true, + icon: Objects, }, { name: 'eyeglasses', @@ -14600,6 +14615,7 @@ const emojis = [ { code: 'symbols', header: true, + icon: Symbols, }, { name: 'atm', @@ -16590,6 +16606,7 @@ const emojis = [ { code: 'flags', header: true, + icon: Flags, }, { name: 'checkered_flag', diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index abab8400ad06..8a6ef79f5044 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -3,48 +3,33 @@ import PropTypes from 'prop-types'; import {View} from 'react-native'; import _ from 'underscore'; import styles from '../../styles/styles'; -import FrequentlyUsed from '../../../assets/images/history.svg'; -import Smiley from '../../../assets/images/emoji.svg'; -import AnimalsAndNature from '../../../assets/images/emojiCategoryIcons/plant.svg'; -import FoodAndDrink from '../../../assets/images/emojiCategoryIcons/hamburger.svg'; -import TravelAndPlaces from '../../../assets/images/emojiCategoryIcons/plane.svg'; -import Activities from '../../../assets/images/emojiCategoryIcons/soccer-ball.svg'; -import Objects from '../../../assets/images/emojiCategoryIcons/light-bulb.svg'; -import Symbols from '../../../assets/images/emojiCategoryIcons/peace-sign.svg'; -import Flags from '../../../assets/images/emojiCategoryIcons/flag.svg'; import CategoryShortcutButton from './CategoryShortcutButton'; -import getOperatingSystem from '../../libs/getOperatingSystem'; -import CONST from '../../CONST'; const propTypes = { /** The function to call when an emoji is selected */ onPress: PropTypes.func.isRequired, - /** The indices that the icons should link to */ - headerIndices: PropTypes.arrayOf(PropTypes.number).isRequired, + /** The emojis consisting emoji code and indices that the icons should link to */ + headerEmojis: PropTypes.arrayOf(PropTypes.shape({ + code: PropTypes.string.isRequired, + index: PropTypes.number.isRequired, + icon: PropTypes.func.isRequired, + })).isRequired, }; -const CategoryShortcutBar = (props) => { - const icons = [Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; +const CategoryShortcutBar = props => ( + + {_.map(props.headerEmojis, (headerEmoji, i) => ( + props.onPress(headerEmoji.index)} + key={`categoryShortcut${i}`} + code={headerEmoji.code} + /> + ))} + +); - // If the user has frequently used emojis, there will be 9 headers, otherwise there will be 8 - // Or for Windows OS there will be 8 headers, otherwise there will be 7 - if (props.headerIndices.length === 9 || (getOperatingSystem() === CONST.OS.WINDOWS && props.headerIndices.length === 8)) { - icons.unshift(FrequentlyUsed); - } - - return ( - - {_.map(props.headerIndices, (headerIndex, i) => ( - props.onPress(headerIndex)} - key={`categoryShortcut${i}`} - /> - ))} - - ); -}; CategoryShortcutBar.propTypes = propTypes; CategoryShortcutBar.displayName = 'CategoryShortcutBar'; diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 3b5d43f9b10d..2c5f061327ae 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -1,7 +1,9 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; -import {Pressable, View} from 'react-native'; +import {Pressable} from 'react-native'; import Icon from '../Icon'; +import Tooltip from '../Tooltip'; +import withLocalize, {withLocalizePropTypes} from '../withLocalize'; import variables from '../../styles/variables'; import styles from '../../styles/styles'; import * as StyleUtils from '../../styles/StyleUtils'; @@ -9,11 +11,16 @@ import getButtonState from '../../libs/getButtonState'; import themeColors from '../../styles/themes/default'; const propTypes = { + /** The emoji code of the category header */ + code: PropTypes.string.isRequired, + /** The icon representation of the category that this button links to */ icon: PropTypes.func.isRequired, /** The function to call when an emoji is selected */ onPress: PropTypes.func.isRequired, + + ...withLocalizePropTypes, }; class CategoryShortcutButton extends PureComponent { @@ -36,18 +43,22 @@ class CategoryShortcutButton extends PureComponent { this.state.isHighlighted && styles.emojiItemHighlighted, ])} > - + - + ); } } CategoryShortcutButton.propTypes = propTypes; -export default CategoryShortcutButton; +export default withLocalize(CategoryShortcutButton); diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 8c1665a7750b..c8dd15a4d373 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -64,13 +64,14 @@ class EmojiPickerMenu extends Component { ? EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis.slice(0, flagHeaderIndex), this.props.frequentlyUsedEmojis) : EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis, this.props.frequentlyUsedEmojis); - // This is the actual header index starting at the first emoji and counting each one - this.headerIndices = EmojiUtils.getHeaderIndices(this.emojis); + // Get the header emojis along with the code, index and icon. + // index is the actual header index starting at the first emoji and counting each one + this.headerEmojis = EmojiUtils.getHeaderEmojis(this.emojis); // This is the indices of each header's Row // The positions are static, and are calculated as index/numColumns (8 in our case) // This is because each row of 8 emojis counts as one index to the flatlist - this.headerRowIndices = _.map(this.headerIndices, headerIndex => Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW)); + this.headerRowIndices = _.map(this.headerEmojis, headerEmoji => Math.floor(headerEmoji.index / CONST.EMOJI_NUM_PER_ROW)); this.filterEmojis = _.debounce(this.filterEmojis.bind(this), 300); this.highlightAdjacentEmoji = this.highlightAdjacentEmoji.bind(this); @@ -491,7 +492,7 @@ class EmojiPickerMenu extends Component { )} {!isFiltered && ( )} diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index edf383eda1d8..39591b369b14 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -51,13 +51,14 @@ class EmojiPickerMenu extends Component { this.emojis = EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis, this.props.frequentlyUsedEmojis); - // This is the actual header index starting at the first emoji and counting each one - this.headerIndices = EmojiUtils.getHeaderIndices(this.emojis); + // Get the header emojis along with the code, index and icon. + // index is the actual header index starting at the first emoji and counting each one + this.headerEmojis = EmojiUtils.getHeaderEmojis(this.emojis); // This is the indices of each header's Row // The positions are static, and are calculated as index/numColumns (8 in our case) // This is because each row of 8 emojis counts as one index to the flatlist - this.headerRowIndices = _.map(this.headerIndices, headerIndex => Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW)); + this.headerRowIndices = _.map(this.headerEmojis, headerEmoji => Math.floor(headerEmoji.index / CONST.EMOJI_NUM_PER_ROW)); this.renderItem = this.renderItem.bind(this); this.isMobileLandscape = this.isMobileLandscape.bind(this); @@ -151,7 +152,7 @@ class EmojiPickerMenu extends Component { diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index bee46547a3e8..0e813076015a 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -5,6 +5,7 @@ import Str from 'expensify-common/lib/str'; import CONST from '../CONST'; import * as User from './actions/User'; import emojisTrie from './EmojiTrie'; +import FrequentlyUsed from '../../assets/images/history.svg'; /** * Get the unicode code of an emoji in base 16. @@ -82,17 +83,17 @@ function containsOnlyEmojis(message) { } /** - * Get the header indices based on the max emojis per row + * Get the header emojis with their code, icon and index * @param {Object[]} emojis - * @returns {Number[]} + * @returns {Object[]} */ -function getHeaderIndices(emojis) { +function getHeaderEmojis(emojis) { const headerIndices = []; _.each(emojis, (emoji, index) => { if (!emoji.header) { return; } - headerIndices.push(index); + headerIndices.push({code: emoji.code, index, icon: emoji.icon}); }); return headerIndices; } @@ -149,6 +150,7 @@ function mergeEmojisWithFrequentlyUsedEmojis(emojis, frequentlyUsedEmojis = []) let allEmojis = [{ header: true, code: 'frequentlyUsed', + icon: FrequentlyUsed, }]; allEmojis = allEmojis.concat(frequentlyUsedEmojis, emojis); @@ -246,7 +248,7 @@ function suggestEmojis(text, limit = 5) { } export { - getHeaderIndices, + getHeaderEmojis, mergeEmojisWithFrequentlyUsedEmojis, addToFrequentlyUsedEmojis, containsOnlyEmojis, diff --git a/src/styles/styles.js b/src/styles/styles.js index b99bad1cdcc0..9b9bae9ebe58 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1536,9 +1536,8 @@ const styles = { categoryShortcutButton: { flex: 1, borderRadius: 8, - paddingTop: 2, - paddingBottom: 2, height: CONST.EMOJI_PICKER_ITEM_HEIGHT, + alignItems: 'center', justifyContent: 'center', },