From eb2782158dab2d5ae96862885433988a3ee8912c Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 15:25:29 -0700 Subject: [PATCH 01/54] Add new method to get the static header positions --- .../EmojiPicker/EmojiPickerMenu/index.js | 1 + src/libs/EmojiUtils.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 924d81a2bf37..6f4ed04aa722 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -70,6 +70,7 @@ class EmojiPickerMenu extends Component { // 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 this.unfilteredHeaderIndices = EmojiUtils.getDynamicHeaderIndices(allEmojis); + this.headerIndices = EmojiUtils.getHeaderIndices(allEmojis); // If we're on Windows, don't display the flag emojis (the last category), // since Windows doesn't support them (and only displays country codes instead) diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index d6ed8875e998..5e25d4b8bc33 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -97,6 +97,22 @@ function getDynamicHeaderIndices(emojis) { return headerIndices; } +/** + * Get the header indices based on the max emojis per row + * @param {Object[]} emojis + * @returns {Number[]} + */ +function getHeaderIndices(emojis) { + const headerIndices = []; + _.each(emojis, (emoji, index) => { + if (!emoji.header) { + return; + } + headerIndices.push(index); + }); + return headerIndices; +} + /** * Get number of empty spaces to be filled to get equal emojis for every row * @param {Number} emojiCount @@ -247,6 +263,7 @@ function suggestEmojis(text, limit = 5) { export { getDynamicHeaderIndices, + getHeaderIndices, mergeEmojisWithFrequentlyUsedEmojis, addToFrequentlyUsedEmojis, containsOnlyEmojis, From cbadcc71055b7651371ea52fffd6af2889442d6a Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 15:26:16 -0700 Subject: [PATCH 02/54] Add new method to scroll to headers --- .../EmojiPicker/EmojiPickerMenu/index.js | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 6f4ed04aa722..ad69b9950128 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {View, FlatList} from 'react-native'; +import {View, FlatList, Pressable} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; @@ -20,6 +20,7 @@ import getOperatingSystem from '../../../libs/getOperatingSystem'; import * as User from '../../../libs/actions/User'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; +import getButtonState from "../../../libs/getButtonState"; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -340,6 +341,22 @@ class EmojiPickerMenu extends Component { } } + scrollToHeader() { + // If there are headers in the emoji array, so we need to offset by their heights as well + let numHeaders = 0; + if (this.state.filteredEmojis.length === this.emojis.length) { + numHeaders = _.filter(this.unfilteredHeaderIndices, i => this.state.highlightedIndex > i * this.numColumns).length; + } + + // Calculate the scroll offset at the top of the desired category + // add 1 to number of headers so that we scroll to the top of the header row instead of the bottom + // subtract new number of headers to get rid of those rows + const numEmojiRows = Math.floor(this.state.highlightedIndex / this.numColumns) - (numHeaders + 1); + + const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); + this.emojiList.scrollToOffset({offset: testoffset, animated: false}); + } + /** * Calculates the required scroll offset (aka distance from top) and scrolls the FlatList to the highlighted emoji * if any portion of it falls outside of the window. @@ -472,6 +489,47 @@ class EmojiPickerMenu extends Component { style={[styles.emojiPickerContainer, StyleUtils.getEmojiPickerStyle(this.props.isSmallScreenWidth)]} pointerEvents={this.state.arePointerEventsDisabled ? 'none' : 'auto'} > + + this.setState({highlightedIndex: this.headerIndices[0]}, this.scrollToHeader)} + > + + Recent + + + this.setState({highlightedIndex: this.headerIndices[1]}, this.scrollToHeader)} + > + + Smiley + + + this.setState({highlightedIndex: this.headerIndices[2]}, this.scrollToHeader)} + > + + People + + + this.setState({highlightedIndex: this.headerIndices[3]}, this.scrollToHeader)} + > + + Animals + + + this.setState({highlightedIndex: this.headerIndices[4]}, this.scrollToHeader)} + > + + Food + + + {!this.props.isSmallScreenWidth && ( Date: Tue, 24 Jan 2023 15:27:00 -0700 Subject: [PATCH 03/54] Remove unused import --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index ad69b9950128..15a13b2a5c4f 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -20,7 +20,6 @@ import getOperatingSystem from '../../../libs/getOperatingSystem'; import * as User from '../../../libs/actions/User'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; -import getButtonState from "../../../libs/getButtonState"; const propTypes = { /** Function to add the selected emoji to the main compose text input */ From 22e3e00d949d914a024efcc598f51cfd0f6612ec Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 15:40:56 -0700 Subject: [PATCH 04/54] Pass the index instead of setting the highlighted index --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 15a13b2a5c4f..e6b0a863edf9 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -340,17 +340,17 @@ class EmojiPickerMenu extends Component { } } - scrollToHeader() { + scrollToHeader(headerIndex) { // If there are headers in the emoji array, so we need to offset by their heights as well let numHeaders = 0; if (this.state.filteredEmojis.length === this.emojis.length) { - numHeaders = _.filter(this.unfilteredHeaderIndices, i => this.state.highlightedIndex > i * this.numColumns).length; + numHeaders = _.filter(this.unfilteredHeaderIndices, i => headerIndex > i * this.numColumns).length; } // Calculate the scroll offset at the top of the desired category // add 1 to number of headers so that we scroll to the top of the header row instead of the bottom // subtract new number of headers to get rid of those rows - const numEmojiRows = Math.floor(this.state.highlightedIndex / this.numColumns) - (numHeaders + 1); + const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); this.emojiList.scrollToOffset({offset: testoffset, animated: false}); From 95d0392131d6d9896281002a1ed1b831b5f26f2a Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 15:58:29 -0700 Subject: [PATCH 05/54] Add new button component for category shortcuts --- .../EmojiPicker/CategoryShortcutButton.js | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/components/EmojiPicker/CategoryShortcutButton.js diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js new file mode 100644 index 000000000000..27a309ed9f43 --- /dev/null +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -0,0 +1,54 @@ +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 Text from '../Text'; + +const propTypes = { + /** The unicode that is used to display the emoji */ + emoji: PropTypes.string.isRequired, + + /** The function to call when an emoji is selected */ + onPress: PropTypes.func.isRequired, + + /** Handles what to do when we hover over this item with our cursor */ + onHoverIn: PropTypes.func, + + /** Handles what to do when the hover is out */ + onHoverOut: PropTypes.func, + + /** Whether this menu item is currently highlighted or not */ + isHighlighted: PropTypes.bool, + + /** Whether the emoji is highlighted by the keyboard/mouse */ + isUsingKeyboardMovement: PropTypes.bool, +}; + +const CategoryShortcutButton = props => ( + props.onPress(props.emoji)} + onHoverIn={props.onHoverIn} + onHoverOut={props.onHoverOut} + style={({pressed}) => ([ + StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), + props.isHighlighted && styles.emojiItemHighlighted, + styles.emojiItem, + ])} + > + + {props.emoji} + + + +); +CategoryShortcutButton.propTypes = propTypes; +CategoryShortcutButton.displayName = 'CategoryShortcutButton'; +CategoryShortcutButton.defaultProps = { + isHighlighted: false, + onHoverIn: () => {}, + onHoverOut: () => {}, +}; + +export default CategoryShortcutButton; From a8245d22c411b5c116460eb3be24db467393a3d7 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 15:59:04 -0700 Subject: [PATCH 06/54] Dynamically generate the category buttons using a map --- .../EmojiPicker/EmojiPickerMenu/index.js | 47 ++++--------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index e6b0a863edf9..85d53421148a 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -20,6 +20,8 @@ import getOperatingSystem from '../../../libs/getOperatingSystem'; import * as User from '../../../libs/actions/User'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; +import CategoryShortcutButton from "../CategoryShortcutButton"; +import MenuItem from "../../MenuItem"; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -489,45 +491,12 @@ class EmojiPickerMenu extends Component { pointerEvents={this.state.arePointerEventsDisabled ? 'none' : 'auto'} > - this.setState({highlightedIndex: this.headerIndices[0]}, this.scrollToHeader)} - > - - Recent - - - this.setState({highlightedIndex: this.headerIndices[1]}, this.scrollToHeader)} - > - - Smiley - - - this.setState({highlightedIndex: this.headerIndices[2]}, this.scrollToHeader)} - > - - People - - - this.setState({highlightedIndex: this.headerIndices[3]}, this.scrollToHeader)} - > - - Animals - - - this.setState({highlightedIndex: this.headerIndices[4]}, this.scrollToHeader)} - > - - Food - - + {_.map(this.headerIndices, headerIndex => ( + this.scrollToHeader(headerIndex)} + /> + ))} {!this.props.isSmallScreenWidth && ( From d62361848d892b94a82cc60d92eadd9c6d66eb79 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 15:59:45 -0700 Subject: [PATCH 07/54] Add new style to fix width --- src/components/EmojiPicker/CategoryShortcutButton.js | 2 +- src/styles/styles.js | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 27a309ed9f43..97ce598123b7 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -34,7 +34,7 @@ const CategoryShortcutButton = props => ( style={({pressed}) => ([ StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), props.isHighlighted && styles.emojiItemHighlighted, - styles.emojiItem, + styles.categoryShortcutButton, ])} > diff --git a/src/styles/styles.js b/src/styles/styles.js index 71fed02015b4..0849b1c28046 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1512,6 +1512,15 @@ const styles = { borderRadius: variables.buttonBorderRadius, }, + categoryShortcutButton: { + width: '10%', + textAlign: 'center', + borderRadius: 8, + paddingTop: 2, + paddingBottom: 2, + height: CONST.EMOJI_PICKER_ITEM_HEIGHT, + }, + chatItemEmojiButton: { alignSelf: 'flex-end', borderRadius: variables.buttonBorderRadius, From f9656fe4c46f5e5ba1ba87e195d6abe29245cbcf Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 16:00:36 -0700 Subject: [PATCH 08/54] Remove unused prop and import --- src/components/EmojiPicker/CategoryShortcutButton.js | 3 --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 97ce598123b7..5195da4133cd 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -21,9 +21,6 @@ const propTypes = { /** Whether this menu item is currently highlighted or not */ isHighlighted: PropTypes.bool, - - /** Whether the emoji is highlighted by the keyboard/mouse */ - isUsingKeyboardMovement: PropTypes.bool, }; const CategoryShortcutButton = props => ( diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 85d53421148a..2ae8e937a7f8 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -20,8 +20,7 @@ import getOperatingSystem from '../../../libs/getOperatingSystem'; import * as User from '../../../libs/actions/User'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; -import CategoryShortcutButton from "../CategoryShortcutButton"; -import MenuItem from "../../MenuItem"; +import CategoryShortcutButton from '../CategoryShortcutButton'; const propTypes = { /** Function to add the selected emoji to the main compose text input */ From ba1935905bbfc61b54bd288ade2a511f9e987a94 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 16:09:44 -0700 Subject: [PATCH 09/54] Remove unused import --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 2ae8e937a7f8..81729750d73d 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {View, FlatList, Pressable} from 'react-native'; +import {View, FlatList} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; From 3747de0b4ae7193414e31eb464b230a081d1b3d2 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 16:15:00 -0700 Subject: [PATCH 10/54] Add category shortcuts to mobile --- .../EmojiPickerMenu/index.native.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 754ed20fd766..094b5dc6bf0e 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -14,6 +14,8 @@ import withLocalize, {withLocalizePropTypes} from '../../withLocalize'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; import * as User from '../../../libs/actions/User'; +import _ from "underscore/underscore-node.mjs"; +import CategoryShortcutButton from "../CategoryShortcutButton"; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -43,6 +45,9 @@ class EmojiPickerMenu extends Component { constructor(props) { super(props); + // Ref for emoji FlatList + this.emojiList = undefined; + // This is the number of columns in each row of the picker. // Because of how flatList implements these rows, each row is an index rather than each element // For this reason to make headers work, we need to have the header be the only rendered element in its row @@ -56,10 +61,12 @@ class EmojiPickerMenu extends Component { // 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 this.unfilteredHeaderIndices = EmojiUtils.getDynamicHeaderIndices(this.emojis); + this.headerIndices = EmojiUtils.getHeaderIndices(this.emojis); this.renderItem = this.renderItem.bind(this); this.isMobileLandscape = this.isMobileLandscape.bind(this); this.updatePreferredSkinTone = this.updatePreferredSkinTone.bind(this); + this.scrollToHeader = this.scrollToHeader.bind(this); } /** @@ -91,6 +98,22 @@ class EmojiPickerMenu extends Component { User.updatePreferredSkinTone(skinTone); } + scrollToHeader(headerIndex) { + // If there are headers in the emoji array, so we need to offset by their heights as well + let numHeaders = 0; + if (this.state.filteredEmojis.length === this.emojis.length) { + numHeaders = _.filter(this.unfilteredHeaderIndices, i => headerIndex > i * this.numColumns).length; + } + + // Calculate the scroll offset at the top of the desired category + // add 1 to number of headers so that we scroll to the top of the header row instead of the bottom + // subtract new number of headers to get rid of those rows + const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); + + const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); + this.emojiList.scrollToOffset({offset: testoffset, animated: false}); + } + /** * Given an emoji item object, render a component based on its type. * Items with the code "SPACER" return nothing and are used to fill rows up to 8 @@ -128,7 +151,16 @@ class EmojiPickerMenu extends Component { render() { return ( + + {_.map(this.headerIndices, headerIndex => ( + this.scrollToHeader(headerIndex)} + /> + ))} + this.emojiList = el} data={this.emojis} renderItem={this.renderItem} keyExtractor={item => (`emoji_picker_${item.code}`)} From 00cfdd2f7e02be8db10badfef7a173d7deadcc09 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 16:29:13 -0700 Subject: [PATCH 11/54] Always set the numHeaders because there is no filtering on native --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 094b5dc6bf0e..003904212095 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -100,10 +100,7 @@ class EmojiPickerMenu extends Component { scrollToHeader(headerIndex) { // If there are headers in the emoji array, so we need to offset by their heights as well - let numHeaders = 0; - if (this.state.filteredEmojis.length === this.emojis.length) { - numHeaders = _.filter(this.unfilteredHeaderIndices, i => headerIndex > i * this.numColumns).length; - } + const numHeaders = _.filter(this.unfilteredHeaderIndices, i => headerIndex > i * this.numColumns).length; // Calculate the scroll offset at the top of the desired category // add 1 to number of headers so that we scroll to the top of the header row instead of the bottom From 5acbb380e6c4eb3520cca0d3372971bb1329d076 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 24 Jan 2023 17:15:36 -0700 Subject: [PATCH 12/54] Style --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 003904212095..bf9ac71bcfc3 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -2,6 +2,7 @@ import React, {Component} from 'react'; import {View, FlatList} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; +import _ from 'underscore/underscore-node.mjs'; import compose from '../../../libs/compose'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../withWindowDimensions'; import CONST from '../../../CONST'; @@ -14,8 +15,7 @@ import withLocalize, {withLocalizePropTypes} from '../../withLocalize'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; import * as User from '../../../libs/actions/User'; -import _ from "underscore/underscore-node.mjs"; -import CategoryShortcutButton from "../CategoryShortcutButton"; +import CategoryShortcutButton from '../CategoryShortcutButton'; const propTypes = { /** Function to add the selected emoji to the main compose text input */ From 72569181a215d4c739d390c960bbedff02785bd4 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Wed, 25 Jan 2023 07:53:31 -0700 Subject: [PATCH 13/54] Add getItemLayout to prevent laggy scrolling when using category picker --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index bf9ac71bcfc3..498c73476273 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -67,6 +67,7 @@ class EmojiPickerMenu extends Component { this.isMobileLandscape = this.isMobileLandscape.bind(this); this.updatePreferredSkinTone = this.updatePreferredSkinTone.bind(this); this.scrollToHeader = this.scrollToHeader.bind(this); + this.getItemLayout = this.getItemLayout.bind(this); } /** @@ -98,6 +99,10 @@ class EmojiPickerMenu extends Component { User.updatePreferredSkinTone(skinTone); } + getItemLayout(data, index) { + return {length: CONST.EMOJI_PICKER_ITEM_HEIGHT, offset: CONST.EMOJI_PICKER_ITEM_HEIGHT * index, index}; + } + scrollToHeader(headerIndex) { // If there are headers in the emoji array, so we need to offset by their heights as well const numHeaders = _.filter(this.unfilteredHeaderIndices, i => headerIndex > i * this.numColumns).length; @@ -167,6 +172,7 @@ class EmojiPickerMenu extends Component { this.isMobileLandscape() && styles.emojiPickerListLandscape, ]} stickyHeaderIndices={this.unfilteredHeaderIndices} + getItemLayout={this.getItemLayout} /> Date: Wed, 25 Jan 2023 08:11:10 -0700 Subject: [PATCH 14/54] Add emoji category icons --- .../images/emojiCategoryIcons/add-emoji.svg | 25 +++++++++++++++++++ assets/images/emojiCategoryIcons/calendar.svg | 16 ++++++++++++ assets/images/emojiCategoryIcons/car.svg | 15 +++++++++++ assets/images/emojiCategoryIcons/flag.svg | 7 ++++++ .../images/emojiCategoryIcons/hamburger.svg | 8 ++++++ assets/images/emojiCategoryIcons/heart.svg | 7 ++++++ .../images/emojiCategoryIcons/light-bulb.svg | 12 +++++++++ .../images/emojiCategoryIcons/peace-sign.svg | 11 ++++++++ assets/images/emojiCategoryIcons/plane.svg | 8 ++++++ assets/images/emojiCategoryIcons/plant.svg | 8 ++++++ .../images/emojiCategoryIcons/soccer-ball.svg | 11 ++++++++ 11 files changed, 128 insertions(+) create mode 100644 assets/images/emojiCategoryIcons/add-emoji.svg create mode 100644 assets/images/emojiCategoryIcons/calendar.svg create mode 100644 assets/images/emojiCategoryIcons/car.svg create mode 100644 assets/images/emojiCategoryIcons/flag.svg create mode 100644 assets/images/emojiCategoryIcons/hamburger.svg create mode 100644 assets/images/emojiCategoryIcons/heart.svg create mode 100644 assets/images/emojiCategoryIcons/light-bulb.svg create mode 100644 assets/images/emojiCategoryIcons/peace-sign.svg create mode 100644 assets/images/emojiCategoryIcons/plane.svg create mode 100644 assets/images/emojiCategoryIcons/plant.svg create mode 100644 assets/images/emojiCategoryIcons/soccer-ball.svg diff --git a/assets/images/emojiCategoryIcons/add-emoji.svg b/assets/images/emojiCategoryIcons/add-emoji.svg new file mode 100644 index 000000000000..5cec67508e4b --- /dev/null +++ b/assets/images/emojiCategoryIcons/add-emoji.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/images/emojiCategoryIcons/calendar.svg b/assets/images/emojiCategoryIcons/calendar.svg new file mode 100644 index 000000000000..18885029a7c8 --- /dev/null +++ b/assets/images/emojiCategoryIcons/calendar.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/assets/images/emojiCategoryIcons/car.svg b/assets/images/emojiCategoryIcons/car.svg new file mode 100644 index 000000000000..e5cde58b2615 --- /dev/null +++ b/assets/images/emojiCategoryIcons/car.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/assets/images/emojiCategoryIcons/flag.svg b/assets/images/emojiCategoryIcons/flag.svg new file mode 100644 index 000000000000..e72787c3665b --- /dev/null +++ b/assets/images/emojiCategoryIcons/flag.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/assets/images/emojiCategoryIcons/hamburger.svg b/assets/images/emojiCategoryIcons/hamburger.svg new file mode 100644 index 000000000000..52945988effc --- /dev/null +++ b/assets/images/emojiCategoryIcons/hamburger.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/assets/images/emojiCategoryIcons/heart.svg b/assets/images/emojiCategoryIcons/heart.svg new file mode 100644 index 000000000000..95e73f329cfa --- /dev/null +++ b/assets/images/emojiCategoryIcons/heart.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/assets/images/emojiCategoryIcons/light-bulb.svg b/assets/images/emojiCategoryIcons/light-bulb.svg new file mode 100644 index 000000000000..0e6a33c041df --- /dev/null +++ b/assets/images/emojiCategoryIcons/light-bulb.svg @@ -0,0 +1,12 @@ + + + + + + + diff --git a/assets/images/emojiCategoryIcons/peace-sign.svg b/assets/images/emojiCategoryIcons/peace-sign.svg new file mode 100644 index 000000000000..ab76642fc48d --- /dev/null +++ b/assets/images/emojiCategoryIcons/peace-sign.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/assets/images/emojiCategoryIcons/plane.svg b/assets/images/emojiCategoryIcons/plane.svg new file mode 100644 index 000000000000..17aca931f8a3 --- /dev/null +++ b/assets/images/emojiCategoryIcons/plane.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/assets/images/emojiCategoryIcons/plant.svg b/assets/images/emojiCategoryIcons/plant.svg new file mode 100644 index 000000000000..a17ed231e1df --- /dev/null +++ b/assets/images/emojiCategoryIcons/plant.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/assets/images/emojiCategoryIcons/soccer-ball.svg b/assets/images/emojiCategoryIcons/soccer-ball.svg new file mode 100644 index 000000000000..40fa05516a11 --- /dev/null +++ b/assets/images/emojiCategoryIcons/soccer-ball.svg @@ -0,0 +1,11 @@ + + + + + + + From e3bf8a40704db5c00c70be5d78c012fed7031070 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Wed, 25 Jan 2023 09:09:21 -0700 Subject: [PATCH 15/54] Remove people and body header to combine the sections --- assets/emojis.js | 4 ---- src/components/EmojiPicker/CategoryShortcutBar.js | 0 2 files changed, 4 deletions(-) create mode 100644 src/components/EmojiPicker/CategoryShortcutBar.js diff --git a/assets/emojis.js b/assets/emojis.js index 6fe6ddf0f06a..358be42555f8 100644 --- a/assets/emojis.js +++ b/assets/emojis.js @@ -1728,10 +1728,6 @@ const emojis = [ 'sleep', ], }, - { - code: 'peopleAndBody', - header: true, - }, { name: 'wave', code: '👋', diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js new file mode 100644 index 000000000000..e69de29bb2d1 From cc8bf960b09b556520f37deb0fe420349cda9cff Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 10:57:22 -0700 Subject: [PATCH 16/54] Add new category shortcut bar component --- .../EmojiPicker/CategoryShortcutBar.js | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index e69de29bb2d1..19a61ef677e4 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -0,0 +1,57 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {Pressable, View} from 'react-native'; +import styles from '../../styles/styles'; +import * as StyleUtils from '../../styles/StyleUtils'; +import getButtonState from '../../libs/getButtonState'; +import Text from '../Text'; +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 _ from "underscore/underscore-node.mjs"; +import CategoryShortcutButton from "./CategoryShortcutButton"; + +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, + + /** Handles what to do when we hover over this item with our cursor */ + onHoverIn: PropTypes.func, + + /** Handles what to do when the hover is out */ + onHoverOut: PropTypes.func, +}; + +const CategoryShortcutBar = (props) => { + const icons = [Smiley, Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; + + return ( + + {_.map(props.headerIndices, (headerIndex, i) => ( + props.onPress(headerIndex)} + onHoverIn={props.onHoverIn} + onHoverOut={props.onHoverOut} + key={`categoryShortcut${i}`} + /> + ))} + + ); +}; +CategoryShortcutBar.propTypes = propTypes; +CategoryShortcutBar.displayName = 'CategoryShortcutBar'; +CategoryShortcutBar.defaultProps = { + onHoverIn: () => {}, + onHoverOut: () => {}, +}; + +export default CategoryShortcutBar; From 27ae4e8f0edffcbd94a2af56da8b2f6634a43a2e Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 10:58:19 -0700 Subject: [PATCH 17/54] Use image so that we can display svg --- .../EmojiPicker/CategoryShortcutButton.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 5195da4133cd..3d52a11a234f 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {Pressable} from 'react-native'; +import {Image, Pressable} from 'react-native'; import styles from '../../styles/styles'; import * as StyleUtils from '../../styles/StyleUtils'; import getButtonState from '../../libs/getButtonState'; @@ -8,7 +8,7 @@ import Text from '../Text'; const propTypes = { /** The unicode that is used to display the emoji */ - emoji: PropTypes.string.isRequired, + emoji: PropTypes.func.isRequired, /** The function to call when an emoji is selected */ onPress: PropTypes.func.isRequired, @@ -25,7 +25,7 @@ const propTypes = { const CategoryShortcutButton = props => ( props.onPress(props.emoji)} + onPress={props.onPress} onHoverIn={props.onHoverIn} onHoverOut={props.onHoverOut} style={({pressed}) => ([ @@ -34,9 +34,10 @@ const CategoryShortcutButton = props => ( styles.categoryShortcutButton, ])} > - - {props.emoji} - + ); From 2fbf3f7847509b404af41316e5ea489e96017c6b Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 10:59:03 -0700 Subject: [PATCH 18/54] Add new style so the icon fills its container and has the correct color --- src/components/EmojiPicker/CategoryShortcutButton.js | 2 +- src/styles/styles.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 3d52a11a234f..9ffb432b1a3e 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -35,7 +35,7 @@ const CategoryShortcutButton = props => ( ])} > diff --git a/src/styles/styles.js b/src/styles/styles.js index 6c8d73fcc000..2d778f2025da 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1521,6 +1521,12 @@ const styles = { height: CONST.EMOJI_PICKER_ITEM_HEIGHT, }, + categoryShortcutIcon: { + width: '100%', + height: '100%', + backgroundColor: themeColors.icon, + }, + chatItemEmojiButton: { alignSelf: 'flex-end', borderRadius: variables.buttonBorderRadius, From a6d65da16669dbed548d23ef4c087924e4d7dd48 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 10:59:54 -0700 Subject: [PATCH 19/54] Use report history icon for recent emojis --- src/components/EmojiPicker/CategoryShortcutBar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 19a61ef677e4..358b0a75b7f6 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -13,6 +13,7 @@ import Activities from '../../../assets/images/emojiCategoryIcons/soccer-ball.sv 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 Recent from '../../../assets/images/history.svg'; import _ from "underscore/underscore-node.mjs"; import CategoryShortcutButton from "./CategoryShortcutButton"; @@ -31,7 +32,7 @@ const propTypes = { }; const CategoryShortcutBar = (props) => { - const icons = [Smiley, Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; + const icons = [Recent, Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; return ( From 37e583b94b855ef64b96b305d7b8be842842ae99 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 11:16:02 -0700 Subject: [PATCH 20/54] Use CategoryShortcutBar instead of directly mapping --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 81729750d73d..ebbd837b6469 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -21,6 +21,7 @@ import * as User from '../../../libs/actions/User'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; import CategoryShortcutButton from '../CategoryShortcutButton'; +import CategoryShortcutBar from "../CategoryShortcutBar"; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -489,14 +490,10 @@ class EmojiPickerMenu extends Component { style={[styles.emojiPickerContainer, StyleUtils.getEmojiPickerStyle(this.props.isSmallScreenWidth)]} pointerEvents={this.state.arePointerEventsDisabled ? 'none' : 'auto'} > - - {_.map(this.headerIndices, headerIndex => ( - this.scrollToHeader(headerIndex)} - /> - ))} - + {!this.props.isSmallScreenWidth && ( Date: Thu, 26 Jan 2023 11:37:57 -0700 Subject: [PATCH 21/54] Use icon instead of image to render svg --- .../EmojiPicker/CategoryShortcutButton.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 9ffb432b1a3e..de9571c4d79c 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -1,7 +1,9 @@ import React from 'react'; +import Icon from '../Icon'; import PropTypes from 'prop-types'; -import {Image, Pressable} from 'react-native'; +import {Image, Pressable, View} from 'react-native'; import styles from '../../styles/styles'; +import colors from '../../styles/colors'; import * as StyleUtils from '../../styles/StyleUtils'; import getButtonState from '../../libs/getButtonState'; import Text from '../Text'; @@ -34,10 +36,12 @@ const CategoryShortcutButton = props => ( styles.categoryShortcutButton, ])} > - + + + ); From eee5a591b2116c891be618fea7433d6cc362e635 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 11:38:22 -0700 Subject: [PATCH 22/54] Update width for 9 icons instead of 10 --- src/styles/styles.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index 2d778f2025da..8be53bd0ba52 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1513,7 +1513,7 @@ const styles = { }, categoryShortcutButton: { - width: '10%', + width: '11.11%', textAlign: 'center', borderRadius: 8, paddingTop: 2, From d5721c48e28563857dadddb1770a608f3367b8b0 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 11:47:15 -0700 Subject: [PATCH 23/54] Fix icon size and styles --- src/components/EmojiPicker/CategoryShortcutButton.js | 3 +++ src/styles/styles.js | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index de9571c4d79c..c82890020627 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -1,6 +1,7 @@ import React from 'react'; import Icon from '../Icon'; import PropTypes from 'prop-types'; +import variables from '../../styles/variables'; import {Image, Pressable, View} from 'react-native'; import styles from '../../styles/styles'; import colors from '../../styles/colors'; @@ -40,6 +41,8 @@ const CategoryShortcutButton = props => ( diff --git a/src/styles/styles.js b/src/styles/styles.js index 8be53bd0ba52..d45aff742051 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1514,19 +1514,12 @@ const styles = { categoryShortcutButton: { width: '11.11%', - textAlign: 'center', borderRadius: 8, paddingTop: 2, paddingBottom: 2, height: CONST.EMOJI_PICKER_ITEM_HEIGHT, }, - categoryShortcutIcon: { - width: '100%', - height: '100%', - backgroundColor: themeColors.icon, - }, - chatItemEmojiButton: { alignSelf: 'flex-end', borderRadius: variables.buttonBorderRadius, From 2d786e4c2598300f4f3d5a1df97f25c49f4e2e22 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Thu, 26 Jan 2023 11:52:56 -0700 Subject: [PATCH 24/54] Fix gap between search bar and categories --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index ebbd837b6469..20f7d111f81e 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -495,7 +495,7 @@ class EmojiPickerMenu extends Component { onPress={this.scrollToHeader} /> {!this.props.isSmallScreenWidth && ( - + Date: Thu, 26 Jan 2023 11:55:33 -0700 Subject: [PATCH 25/54] Style and removing unused imports --- src/components/EmojiPicker/CategoryShortcutBar.js | 9 +++------ src/components/EmojiPicker/CategoryShortcutButton.js | 5 ++--- src/components/EmojiPicker/EmojiPickerMenu/index.js | 5 ++--- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 358b0a75b7f6..fc924de2d93c 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -1,10 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {Pressable, View} from 'react-native'; +import {View} from 'react-native'; +import _ from 'underscore/underscore-node.mjs'; import styles from '../../styles/styles'; -import * as StyleUtils from '../../styles/StyleUtils'; -import getButtonState from '../../libs/getButtonState'; -import Text from '../Text'; import Smiley from '../../../assets/images/emoji.svg'; import AnimalsAndNature from '../../../assets/images/emojiCategoryIcons/plant.svg'; import FoodAndDrink from '../../../assets/images/emojiCategoryIcons/hamburger.svg'; @@ -14,8 +12,7 @@ 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 Recent from '../../../assets/images/history.svg'; -import _ from "underscore/underscore-node.mjs"; -import CategoryShortcutButton from "./CategoryShortcutButton"; +import CategoryShortcutButton from './CategoryShortcutButton'; const propTypes = { /** The function to call when an emoji is selected */ diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index c82890020627..9f74a458c815 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -1,13 +1,12 @@ import React from 'react'; -import Icon from '../Icon'; import PropTypes from 'prop-types'; +import {Pressable, View} from 'react-native'; +import Icon from '../Icon'; import variables from '../../styles/variables'; -import {Image, Pressable, View} from 'react-native'; import styles from '../../styles/styles'; import colors from '../../styles/colors'; import * as StyleUtils from '../../styles/StyleUtils'; import getButtonState from '../../libs/getButtonState'; -import Text from '../Text'; const propTypes = { /** The unicode that is used to display the emoji */ diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 20f7d111f81e..f538ec8e66af 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -20,8 +20,7 @@ import getOperatingSystem from '../../../libs/getOperatingSystem'; import * as User from '../../../libs/actions/User'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; -import CategoryShortcutButton from '../CategoryShortcutButton'; -import CategoryShortcutBar from "../CategoryShortcutBar"; +import CategoryShortcutBar from '../CategoryShortcutBar'; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -495,7 +494,7 @@ class EmojiPickerMenu extends Component { onPress={this.scrollToHeader} /> {!this.props.isSmallScreenWidth && ( - + Date: Thu, 26 Jan 2023 12:09:59 -0700 Subject: [PATCH 26/54] Update style to have padding on search bar instead of button to fix highlighting --- src/components/EmojiPicker/CategoryShortcutBar.js | 4 ++-- src/components/EmojiPicker/EmojiPickerMenu/index.js | 3 ++- src/styles/utilities/spacing.js | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index fc924de2d93c..32844a17d90f 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import {View} from 'react-native'; import _ from 'underscore/underscore-node.mjs'; import styles from '../../styles/styles'; +import Recent 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'; @@ -11,7 +12,6 @@ import Activities from '../../../assets/images/emojiCategoryIcons/soccer-ball.sv 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 Recent from '../../../assets/images/history.svg'; import CategoryShortcutButton from './CategoryShortcutButton'; const propTypes = { @@ -32,7 +32,7 @@ const CategoryShortcutBar = (props) => { const icons = [Recent, Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; return ( - + {_.map(props.headerIndices, (headerIndex, i) => ( {!this.props.isSmallScreenWidth && ( - + Date: Thu, 26 Jan 2023 13:16:08 -0700 Subject: [PATCH 27/54] Refactor CategoryShortcutButton to have state --- .../EmojiPicker/CategoryShortcutBar.js | 12 +-- .../EmojiPicker/CategoryShortcutButton.js | 76 +++++++++---------- .../EmojiPicker/EmojiPickerMenu/index.js | 2 +- src/styles/styles.js | 1 + 4 files changed, 40 insertions(+), 51 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 32844a17d90f..7eca871f8102 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -20,25 +20,17 @@ const propTypes = { /** The indices that the icons should link to */ headerIndices: PropTypes.arrayOf(PropTypes.number).isRequired, - - /** Handles what to do when we hover over this item with our cursor */ - onHoverIn: PropTypes.func, - - /** Handles what to do when the hover is out */ - onHoverOut: PropTypes.func, }; const CategoryShortcutBar = (props) => { const icons = [Recent, Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; return ( - + {_.map(props.headerIndices, (headerIndex, i) => ( props.onPress(headerIndex)} - onHoverIn={props.onHoverIn} - onHoverOut={props.onHoverOut} key={`categoryShortcut${i}`} /> ))} diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 9f74a458c815..c9238eba69e0 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -1,6 +1,6 @@ -import React from 'react'; +import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; -import {Pressable, View} from 'react-native'; +import {Animated, Pressable, View} from 'react-native'; import Icon from '../Icon'; import variables from '../../styles/variables'; import styles from '../../styles/styles'; @@ -9,50 +9,46 @@ import * as StyleUtils from '../../styles/StyleUtils'; import getButtonState from '../../libs/getButtonState'; const propTypes = { - /** The unicode that is used to display the emoji */ - emoji: PropTypes.func.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, - - /** Handles what to do when we hover over this item with our cursor */ - onHoverIn: PropTypes.func, - - /** Handles what to do when the hover is out */ - onHoverOut: PropTypes.func, - - /** Whether this menu item is currently highlighted or not */ - isHighlighted: PropTypes.bool, }; -const CategoryShortcutButton = props => ( - ([ - StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), - props.isHighlighted && styles.emojiItemHighlighted, - styles.categoryShortcutButton, - ])} - > - - - - - -); +class CategoryShortcutButton extends PureComponent { + constructor(props) { + super(props); + this.state = { + isHighlighted: false, + }; + } + + render() { + return ( + this.setState({isHighlighted: true})} + onHoverOut={() => this.setState({isHighlighted: false})} + style={({pressed}) => ([ + StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), + styles.categoryShortcutButton, + this.state.isHighlighted && styles.emojiItemHighlighted, + ])} + > + + + + + ); + } +} CategoryShortcutButton.propTypes = propTypes; CategoryShortcutButton.displayName = 'CategoryShortcutButton'; -CategoryShortcutButton.defaultProps = { - isHighlighted: false, - onHoverIn: () => {}, - onHoverOut: () => {}, -}; export default CategoryShortcutButton; diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index c5e233ce2920..5ebbf9eaa081 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -495,7 +495,7 @@ class EmojiPickerMenu extends Component { onPress={this.scrollToHeader} /> {!this.props.isSmallScreenWidth && ( - + Date: Thu, 26 Jan 2023 14:31:23 -0700 Subject: [PATCH 28/54] Use CategoryShortcutBar instead of manually mapping --- .../EmojiPickerMenu/index.native.js | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 498c73476273..55f04af88610 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -16,6 +16,7 @@ import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; import * as User from '../../../libs/actions/User'; import CategoryShortcutButton from '../CategoryShortcutButton'; +import CategoryShortcutBar from "../CategoryShortcutBar"; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -70,6 +71,10 @@ class EmojiPickerMenu extends Component { this.getItemLayout = this.getItemLayout.bind(this); } + getItemLayout(data, index) { + return {length: CONST.EMOJI_PICKER_ITEM_HEIGHT, offset: CONST.EMOJI_PICKER_ITEM_HEIGHT * index, index}; + } + /** * @param {String} emoji * @param {Object} emojiObject @@ -99,13 +104,9 @@ class EmojiPickerMenu extends Component { User.updatePreferredSkinTone(skinTone); } - getItemLayout(data, index) { - return {length: CONST.EMOJI_PICKER_ITEM_HEIGHT, offset: CONST.EMOJI_PICKER_ITEM_HEIGHT * index, index}; - } - scrollToHeader(headerIndex) { // If there are headers in the emoji array, so we need to offset by their heights as well - const numHeaders = _.filter(this.unfilteredHeaderIndices, i => headerIndex > i * this.numColumns).length; + const numHeaders = _.filter(this.headerIndices, i => headerIndex > i * this.numColumns).length; // Calculate the scroll offset at the top of the desired category // add 1 to number of headers so that we scroll to the top of the header row instead of the bottom @@ -113,7 +114,7 @@ class EmojiPickerMenu extends Component { const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); - this.emojiList.scrollToOffset({offset: testoffset, animated: false}); + this.emojiList.scrollToOffset({offset: testoffset, animated: true}); } /** @@ -153,13 +154,11 @@ class EmojiPickerMenu extends Component { render() { return ( - - {_.map(this.headerIndices, headerIndex => ( - this.scrollToHeader(headerIndex)} - /> - ))} + + this.emojiList = el} From 22801a107b88d13aecbc86215fae0ef279ade0b7 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Fri, 27 Jan 2023 08:34:10 -0700 Subject: [PATCH 29/54] Fix lint issues --- src/components/EmojiPicker/CategoryShortcutBar.js | 4 ---- src/components/EmojiPicker/CategoryShortcutButton.js | 3 +-- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 3 +-- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 7eca871f8102..1872e9154c95 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -39,9 +39,5 @@ const CategoryShortcutBar = (props) => { }; CategoryShortcutBar.propTypes = propTypes; CategoryShortcutBar.displayName = 'CategoryShortcutBar'; -CategoryShortcutBar.defaultProps = { - onHoverIn: () => {}, - onHoverOut: () => {}, -}; export default CategoryShortcutBar; diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index c9238eba69e0..e92aad8bed08 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -1,6 +1,6 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; -import {Animated, Pressable, View} from 'react-native'; +import {Pressable, View} from 'react-native'; import Icon from '../Icon'; import variables from '../../styles/variables'; import styles from '../../styles/styles'; @@ -49,6 +49,5 @@ class CategoryShortcutButton extends PureComponent { } } CategoryShortcutButton.propTypes = propTypes; -CategoryShortcutButton.displayName = 'CategoryShortcutButton'; export default CategoryShortcutButton; diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 55f04af88610..01af97154a23 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -15,8 +15,7 @@ import withLocalize, {withLocalizePropTypes} from '../../withLocalize'; import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; import * as User from '../../../libs/actions/User'; -import CategoryShortcutButton from '../CategoryShortcutButton'; -import CategoryShortcutBar from "../CategoryShortcutBar"; +import CategoryShortcutBar from '../CategoryShortcutBar'; const propTypes = { /** Function to add the selected emoji to the main compose text input */ From 818ce376ee5db54bf1f6c4f73c51db9fadf44c1f Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Fri, 27 Jan 2023 11:16:27 -0700 Subject: [PATCH 30/54] Use scrollToIndex and show scrollbar --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 3 ++- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 5ebbf9eaa081..a2a05ebb497a 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -354,8 +354,9 @@ class EmojiPickerMenu extends Component { // subtract new number of headers to get rid of those rows const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); + const test = Math.floor(headerIndex / 8); const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); - this.emojiList.scrollToOffset({offset: testoffset, animated: false}); + this.emojiList.scrollToIndex({index: test, animated: false}); } /** diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 01af97154a23..e7633ff84ed8 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -112,8 +112,10 @@ class EmojiPickerMenu extends Component { // subtract new number of headers to get rid of those rows const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); + const test = Math.floor(headerIndex / 8); const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); - this.emojiList.scrollToOffset({offset: testoffset, animated: true}); + this.emojiList.flashScrollIndicators(); + this.emojiList.scrollToIndex({index: test, animated: true}); } /** @@ -171,6 +173,7 @@ class EmojiPickerMenu extends Component { ]} stickyHeaderIndices={this.unfilteredHeaderIndices} getItemLayout={this.getItemLayout} + showsVerticalScrollIndicator /> Date: Mon, 30 Jan 2023 07:59:17 -0700 Subject: [PATCH 31/54] Try offset using release build --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index e7633ff84ed8..5f3c679ca50f 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -115,7 +115,7 @@ class EmojiPickerMenu extends Component { const test = Math.floor(headerIndex / 8); const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); this.emojiList.flashScrollIndicators(); - this.emojiList.scrollToIndex({index: test, animated: true}); + this.emojiList.scrollToOffset({offset: testoffset, animated: true}); } /** From 275f8eab7805b11c901fe1e2340afd015eb8cb08 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Mon, 30 Jan 2023 09:04:51 -0700 Subject: [PATCH 32/54] Try release build with animation off --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 5f3c679ca50f..6f8827e736ad 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -115,7 +115,7 @@ class EmojiPickerMenu extends Component { const test = Math.floor(headerIndex / 8); const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); this.emojiList.flashScrollIndicators(); - this.emojiList.scrollToOffset({offset: testoffset, animated: true}); + this.emojiList.scrollToOffset({offset: testoffset, animated: false}); } /** From 1e78bd42dc8ec72a1a0cb8d156288584491027ad Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 10:03:11 -0700 Subject: [PATCH 33/54] Clean up test variables --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 5 ++--- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 92c4b5921248..4f856f851092 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -354,9 +354,8 @@ class EmojiPickerMenu extends Component { // subtract new number of headers to get rid of those rows const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); - const test = Math.floor(headerIndex / 8); - const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); - this.emojiList.scrollToIndex({index: test, animated: false}); + const calculatedOffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); + this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); } /** diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index d0390c860491..bd75bd51f723 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -112,10 +112,9 @@ class EmojiPickerMenu extends Component { // subtract new number of headers to get rid of those rows const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); - const test = Math.floor(headerIndex / 8); - const testoffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); + const calculatedOffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); this.emojiList.flashScrollIndicators(); - this.emojiList.scrollToOffset({offset: testoffset, animated: false}); + this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); } /** From 3bdb62c00831549b653deb2e503a6816c73241e1 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 10:09:54 -0700 Subject: [PATCH 34/54] Further simplify scroll logic --- .../EmojiPicker/EmojiPickerMenu/index.js | 14 ++------------ .../EmojiPicker/EmojiPickerMenu/index.native.js | 10 +--------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 4f856f851092..1d3c5e08d070 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -343,18 +343,8 @@ class EmojiPickerMenu extends Component { } scrollToHeader(headerIndex) { - // If there are headers in the emoji array, so we need to offset by their heights as well - let numHeaders = 0; - if (this.state.filteredEmojis.length === this.emojis.length) { - numHeaders = _.filter(this.unfilteredHeaderIndices, i => headerIndex > i * this.numColumns).length; - } - - // Calculate the scroll offset at the top of the desired category - // add 1 to number of headers so that we scroll to the top of the header row instead of the bottom - // subtract new number of headers to get rid of those rows - const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); - - const calculatedOffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); + const calculatedOffset = Math.floor(headerIndex / this.numColumns) * CONST.EMOJI_PICKER_HEADER_HEIGHT; + this.emojiList.flashScrollIndicators(); this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); } diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index bd75bd51f723..c8eb96daa7a2 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -104,15 +104,7 @@ class EmojiPickerMenu extends Component { } scrollToHeader(headerIndex) { - // If there are headers in the emoji array, so we need to offset by their heights as well - const numHeaders = _.filter(this.headerIndices, i => headerIndex > i * this.numColumns).length; - - // Calculate the scroll offset at the top of the desired category - // add 1 to number of headers so that we scroll to the top of the header row instead of the bottom - // subtract new number of headers to get rid of those rows - const numEmojiRows = Math.floor(headerIndex / this.numColumns) - (numHeaders + 1); - - const calculatedOffset = ((numEmojiRows) * CONST.EMOJI_PICKER_ITEM_HEIGHT) + (CONST.EMOJI_PICKER_HEADER_HEIGHT * (numHeaders + 1)); + const calculatedOffset = Math.floor(headerIndex / this.numColumns) * CONST.EMOJI_PICKER_HEADER_HEIGHT; this.emojiList.flashScrollIndicators(); this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); } From f97ef7d86252967e8d5a829782c6851d95bb4abd Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 10:37:45 -0700 Subject: [PATCH 35/54] Chagne label styles --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 2 +- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 1d3c5e08d070..c7ee58fd3695 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -448,7 +448,7 @@ class EmojiPickerMenu extends Component { if (header) { return ( - + {this.props.translate(`emojiPicker.headers.${code}`)} diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index c8eb96daa7a2..64868299024a 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -126,7 +126,7 @@ class EmojiPickerMenu extends Component { if (item.header) { return ( - + {this.props.translate(`emojiPicker.headers.${item.code}`)} From a5a55bb4c014a81cb15809ca83114b39973f6169 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 10:52:25 -0700 Subject: [PATCH 36/54] Use TextInput instead of Composer --- src/components/EmojiPicker/CategoryShortcutBar.js | 2 +- src/components/EmojiPicker/EmojiPickerMenu/index.js | 9 +++------ .../EmojiPicker/EmojiPickerMenu/index.native.js | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 1872e9154c95..09022014bd04 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -26,7 +26,7 @@ const CategoryShortcutBar = (props) => { const icons = [Recent, Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; return ( - + {_.map(props.headerIndices, (headerIndex, i) => ( {!this.props.isSmallScreenWidth && ( - this.searchInput = el} autoFocus diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 64868299024a..d34299313f17 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -2,7 +2,6 @@ import React, {Component} from 'react'; import {View, FlatList} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; -import _ from 'underscore/underscore-node.mjs'; import compose from '../../../libs/compose'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../withWindowDimensions'; import CONST from '../../../CONST'; From 83a3a7ab28106ccce52c144764d4e52de4dfde30 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 11:26:25 -0700 Subject: [PATCH 37/54] Simplify scroll logic since all elements are the same size --- .../EmojiPicker/EmojiPickerMenu/index.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 6795e048d619..186b01565883 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -354,19 +354,11 @@ class EmojiPickerMenu extends Component { * Doing this because scrollToIndex doesn't work as expected. */ scrollToHighlightedIndex() { - // If there are headers in the emoji array, so we need to offset by their heights as well - let numHeaders = 0; - if (this.state.filteredEmojis.length === this.emojis.length) { - numHeaders = _.filter(this.unfilteredHeaderIndices, i => this.state.highlightedIndex > i * this.numColumns).length; - } - - // Calculate the scroll offset at the bottom of the currently highlighted emoji - // (subtract numHeaders because the highlightedIndex includes them, and add 1 to include the current row) - const numEmojiRows = (Math.floor(this.state.highlightedIndex / this.numColumns) - numHeaders) + 1; + // Calculate the number of rows above the current row, then add 1 to include the current row + const numRows = Math.floor(this.state.highlightedIndex / this.numColumns) + 1; // The scroll offsets at the top and bottom of the highlighted emoji - const offsetAtEmojiBottom = ((numHeaders) * CONST.EMOJI_PICKER_HEADER_HEIGHT) - + (numEmojiRows * CONST.EMOJI_PICKER_ITEM_HEIGHT); + const offsetAtEmojiBottom = numRows * CONST.EMOJI_PICKER_HEADER_HEIGHT; const offsetAtEmojiTop = offsetAtEmojiBottom - CONST.EMOJI_PICKER_ITEM_HEIGHT; // Scroll to fit the entire highlighted emoji into the window if we need to From 338477af2c37aa2babf370b6ba834c2f34808064 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 11:27:15 -0700 Subject: [PATCH 38/54] Change size to account for only showing 8 rows of emojis instead of 9 due to category picker --- src/CONST.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 2a62850e6cec..e182b3902366 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -509,9 +509,9 @@ const CONST = { ADD_PAYMENT_MENU_POSITION_X: 356, EMOJI_PICKER_SIZE: { WIDTH: 320, - HEIGHT: 390, + HEIGHT: 392, }, - NON_NATIVE_EMOJI_PICKER_LIST_HEIGHT: 288, + NON_NATIVE_EMOJI_PICKER_LIST_HEIGHT: 256, EMOJI_PICKER_ITEM_HEIGHT: 32, EMOJI_PICKER_HEADER_HEIGHT: 32, COMPOSER_MAX_HEIGHT: 125, From 0e26ea18cc88e10256d891b9a5c32abbed35cb4c Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 11:33:53 -0700 Subject: [PATCH 39/54] Remove unused import --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 186b01565883..17fff503c958 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -8,7 +8,6 @@ import CONST from '../../../CONST'; import ONYXKEYS from '../../../ONYXKEYS'; 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 '../../Text'; From aefc70e157a702f92791fa2767d10f9386c585f2 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 12:53:47 -0700 Subject: [PATCH 40/54] Remove getDynamicHeaderIndices since it was confusing and can ge calculated from the normal header indices --- .../EmojiPicker/EmojiPickerMenu/index.js | 16 +++++++++------- .../EmojiPicker/EmojiPickerMenu/index.native.js | 12 +++++++----- src/libs/EmojiUtils.js | 17 ----------------- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 17fff503c958..25b5e30c8d4d 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -66,16 +66,18 @@ class EmojiPickerMenu extends Component { const allEmojis = EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis, this.props.frequentlyUsedEmojis); - // This is the indices of each category of emojis - // 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 - this.unfilteredHeaderIndices = EmojiUtils.getDynamicHeaderIndices(allEmojis); + // This is the actual header index starting at the first emoji and counting each one this.headerIndices = EmojiUtils.getHeaderIndices(allEmojis); + // 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 / this.numColumns)); + // If we're on Windows, don't display the flag emojis (the last category), // since Windows doesn't support them (and only displays country codes instead) this.emojis = getOperatingSystem() === CONST.OS.WINDOWS - ? allEmojis.slice(0, this.unfilteredHeaderIndices.pop() * this.numColumns) + ? allEmojis.slice(0, this.headerRowIndices.pop() * this.numColumns) : allEmojis; this.filterEmojis = _.debounce(this.filterEmojis.bind(this), 300); @@ -96,7 +98,7 @@ class EmojiPickerMenu extends Component { this.state = { filteredEmojis: this.emojis, - headerIndices: this.unfilteredHeaderIndices, + headerIndices: this.headerRowIndices, highlightedIndex: -1, arePointerEventsDisabled: false, selection: { @@ -388,7 +390,7 @@ class EmojiPickerMenu extends Component { // There are no headers when searching, so we need to re-make them sticky when there is no search term this.setState({ filteredEmojis: this.emojis, - headerIndices: this.unfilteredHeaderIndices, + headerIndices: this.headerRowIndices, highlightedIndex: -1, }); this.setFirstNonHeaderIndex(this.emojis); diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index d34299313f17..2b50e8f00bc1 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -56,12 +56,14 @@ class EmojiPickerMenu extends Component { this.emojis = EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis, this.props.frequentlyUsedEmojis); - // This is the indices of each category of emojis - // 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 - this.unfilteredHeaderIndices = EmojiUtils.getDynamicHeaderIndices(this.emojis); + // This is the actual header index starting at the first emoji and counting each one this.headerIndices = EmojiUtils.getHeaderIndices(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 / this.numColumns)); + this.renderItem = this.renderItem.bind(this); this.isMobileLandscape = this.isMobileLandscape.bind(this); this.updatePreferredSkinTone = this.updatePreferredSkinTone.bind(this); @@ -163,7 +165,7 @@ class EmojiPickerMenu extends Component { styles.emojiPickerList, this.isMobileLandscape() && styles.emojiPickerListLandscape, ]} - stickyHeaderIndices={this.unfilteredHeaderIndices} + stickyHeaderIndices={this.headerRowIndices} getItemLayout={this.getItemLayout} showsVerticalScrollIndicator /> diff --git a/src/libs/EmojiUtils.js b/src/libs/EmojiUtils.js index 5e25d4b8bc33..6f3583b70c0a 100644 --- a/src/libs/EmojiUtils.js +++ b/src/libs/EmojiUtils.js @@ -81,22 +81,6 @@ function containsOnlyEmojis(message) { return codes.length === messageCodes.length; } -/** - * Get the header indices based on the max emojis per row - * @param {Object[]} emojis - * @returns {Number[]} - */ -function getDynamicHeaderIndices(emojis) { - const headerIndices = []; - _.each(emojis, (emoji, index) => { - if (!emoji.header) { - return; - } - headerIndices.push(Math.floor(index / CONST.EMOJI_NUM_PER_ROW)); - }); - return headerIndices; -} - /** * Get the header indices based on the max emojis per row * @param {Object[]} emojis @@ -262,7 +246,6 @@ function suggestEmojis(text, limit = 5) { } export { - getDynamicHeaderIndices, getHeaderIndices, mergeEmojisWithFrequentlyUsedEmojis, addToFrequentlyUsedEmojis, From f988963b49063b2e81fbd5f4a46680c83674d070 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 12:56:41 -0700 Subject: [PATCH 41/54] Remove this.numColumns since it is just copying a const --- src/CONST.js | 5 ++++ .../EmojiPicker/EmojiPickerMenu/index.js | 25 +++++++------------ .../EmojiPickerMenu/index.native.js | 13 +++------- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index e182b3902366..6164b4db7252 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -463,6 +463,11 @@ const CONST = { EMOJI_SPACER: 'SPACER', + // This is the number of columns in each row of the picker. + // Because of how flatList implements these rows, each row is an index rather than each element + // For this reason to make headers work, we need to have the header be the only rendered element in its row + // If this number is changed, emojis.js will need to be updated to have the proper number of spacer elements + // around each header. EMOJI_NUM_PER_ROW: 8, EMOJI_FREQUENT_ROW_COUNT: 3, diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 25b5e30c8d4d..901c15566ba7 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -57,13 +57,6 @@ class EmojiPickerMenu extends Component { // Ref for emoji FlatList this.emojiList = undefined; - // This is the number of columns in each row of the picker. - // Because of how flatList implements these rows, each row is an index rather than each element - // For this reason to make headers work, we need to have the header be the only rendered element in its row - // If this number is changed, emojis.js will need to be updated to have the proper number of spacer elements - // around each header. - this.numColumns = CONST.EMOJI_NUM_PER_ROW; - const allEmojis = EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis, this.props.frequentlyUsedEmojis); // This is the actual header index starting at the first emoji and counting each one @@ -72,12 +65,12 @@ class EmojiPickerMenu extends Component { // 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 / this.numColumns)); + this.headerRowIndices = _.map(this.headerIndices, (headerIndex) => Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW)); // If we're on Windows, don't display the flag emojis (the last category), // since Windows doesn't support them (and only displays country codes instead) this.emojis = getOperatingSystem() === CONST.OS.WINDOWS - ? allEmojis.slice(0, this.headerRowIndices.pop() * this.numColumns) + ? allEmojis.slice(0, this.headerRowIndices.pop() * CONST.EMOJI_NUM_PER_ROW) : allEmojis; this.filterEmojis = _.debounce(this.filterEmojis.bind(this), 300); @@ -305,8 +298,8 @@ class EmojiPickerMenu extends Component { switch (arrowKey) { case 'ArrowDown': move( - this.numColumns, - () => this.state.highlightedIndex + this.numColumns > this.state.filteredEmojis.length - 1, + CONST.EMOJI_NUM_PER_ROW, + () => this.state.highlightedIndex + CONST.EMOJI_NUM_PER_ROW > this.state.filteredEmojis.length - 1, ); break; case 'ArrowLeft': @@ -323,8 +316,8 @@ class EmojiPickerMenu extends Component { break; case 'ArrowUp': move( - -this.numColumns, - () => this.state.highlightedIndex - this.numColumns < this.firstNonHeaderIndex, + -CONST.EMOJI_NUM_PER_ROW, + () => this.state.highlightedIndex - CONST.EMOJI_NUM_PER_ROW < this.firstNonHeaderIndex, () => { // Reaching start of the list, arrow up set the focus to searchInput. this.focusInputWithTextSelect(); @@ -344,7 +337,7 @@ class EmojiPickerMenu extends Component { } scrollToHeader(headerIndex) { - const calculatedOffset = Math.floor(headerIndex / this.numColumns) * CONST.EMOJI_PICKER_HEADER_HEIGHT; + const calculatedOffset = Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW) * CONST.EMOJI_PICKER_HEADER_HEIGHT; this.emojiList.flashScrollIndicators(); this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); } @@ -356,7 +349,7 @@ class EmojiPickerMenu extends Component { */ scrollToHighlightedIndex() { // Calculate the number of rows above the current row, then add 1 to include the current row - const numRows = Math.floor(this.state.highlightedIndex / this.numColumns) + 1; + const numRows = Math.floor(this.state.highlightedIndex / CONST.EMOJI_NUM_PER_ROW) + 1; // The scroll offsets at the top and bottom of the highlighted emoji const offsetAtEmojiBottom = numRows * CONST.EMOJI_PICKER_HEADER_HEIGHT; @@ -515,7 +508,7 @@ class EmojiPickerMenu extends Component { data={this.state.filteredEmojis} renderItem={this.renderItem} keyExtractor={item => `emoji_picker_${item.code}`} - numColumns={this.numColumns} + numColumns={CONST.EMOJI_NUM_PER_ROW} style={[ styles.emojiPickerList, this.isMobileLandscape() && styles.emojiPickerListLandscape, diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 2b50e8f00bc1..e8e5cc356a57 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -47,13 +47,6 @@ class EmojiPickerMenu extends Component { // Ref for emoji FlatList this.emojiList = undefined; - // This is the number of columns in each row of the picker. - // Because of how flatList implements these rows, each row is an index rather than each element - // For this reason to make headers work, we need to have the header be the only rendered element in its row - // If this number is changed, emojis.js will need to be updated to have the proper number of spacer elements - // around each header. - this.numColumns = CONST.EMOJI_NUM_PER_ROW; - this.emojis = EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis, this.props.frequentlyUsedEmojis); // This is the actual header index starting at the first emoji and counting each one @@ -62,7 +55,7 @@ class EmojiPickerMenu extends Component { // 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 / this.numColumns)); + this.headerRowIndices = _.map(this.headerIndices, (headerIndex) => Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW)); this.renderItem = this.renderItem.bind(this); this.isMobileLandscape = this.isMobileLandscape.bind(this); @@ -105,7 +98,7 @@ class EmojiPickerMenu extends Component { } scrollToHeader(headerIndex) { - const calculatedOffset = Math.floor(headerIndex / this.numColumns) * CONST.EMOJI_PICKER_HEADER_HEIGHT; + const calculatedOffset = Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW) * CONST.EMOJI_PICKER_HEADER_HEIGHT; this.emojiList.flashScrollIndicators(); this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); } @@ -160,7 +153,7 @@ class EmojiPickerMenu extends Component { data={this.emojis} renderItem={this.renderItem} keyExtractor={item => (`emoji_picker_${item.code}`)} - numColumns={this.numColumns} + numColumns={CONST.EMOJI_NUM_PER_ROW} style={[ styles.emojiPickerList, this.isMobileLandscape() && styles.emojiPickerListLandscape, From e96267596cdab3ee5dfc75225e258a545c256b67 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 13:01:56 -0700 Subject: [PATCH 42/54] Add underscore import to prevent crash --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index e8e5cc356a57..65a90af86089 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -2,6 +2,7 @@ import React, {Component} from 'react'; import {View, FlatList} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; +import _ from 'underscore'; import compose from '../../../libs/compose'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../withWindowDimensions'; import CONST from '../../../CONST'; From ee08bffd6182f7c00595352b652e52dadfcdcfaa Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 13:04:54 -0700 Subject: [PATCH 43/54] remove old unused header style --- src/styles/styles.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index be814c4533a8..d8e6cf5a983f 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1467,13 +1467,6 @@ const styles = { width: '100%', }, - emojiHeaderStyle: { - fontFamily: fontFamily.EXP_NEUE_BOLD, - fontWeight: fontWeightBold, - color: themeColors.heading, - fontSize: variables.fontSizeSmall, - }, - emojiSkinToneTitle: { backgroundColor: themeColors.componentBG, width: '100%', From 6e9fa29b8fdfd55e8cac9405fb561838269f02f4 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 13:12:48 -0700 Subject: [PATCH 44/54] Style --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 2 +- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 901c15566ba7..a3ebca869985 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -65,7 +65,7 @@ class EmojiPickerMenu extends Component { // 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.headerIndices, headerIndex => Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW)); // If we're on Windows, don't display the flag emojis (the last category), // since Windows doesn't support them (and only displays country codes instead) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 65a90af86089..8b2c23fa2ef8 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -56,7 +56,7 @@ class EmojiPickerMenu extends Component { // 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.headerIndices, headerIndex => Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW)); this.renderItem = this.renderItem.bind(this); this.isMobileLandscape = this.isMobileLandscape.bind(this); From db31731e6ca12b2a582f27e7ab76f030883cc39f Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 17:24:50 -0700 Subject: [PATCH 45/54] Don't use .mjs --- src/components/EmojiPicker/CategoryShortcutBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 09022014bd04..900c9a0c5678 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {View} from 'react-native'; -import _ from 'underscore/underscore-node.mjs'; +import _ from 'underscore'; import styles from '../../styles/styles'; import Recent from '../../../assets/images/history.svg'; import Smiley from '../../../assets/images/emoji.svg'; From ed4acf94b159c28444bf6d927b3a56caf92b7313 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Tue, 31 Jan 2023 17:44:37 -0700 Subject: [PATCH 46/54] Change icons to gray --- src/components/EmojiPicker/CategoryShortcutButton.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index e92aad8bed08..76118d3d65c8 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -38,7 +38,7 @@ class CategoryShortcutButton extends PureComponent { > Date: Thu, 2 Feb 2023 11:33:29 -0700 Subject: [PATCH 47/54] Only show the correct 8 icons when there is no frequently used category --- src/components/EmojiPicker/CategoryShortcutBar.js | 12 ++++++++++-- src/components/EmojiPicker/CategoryShortcutButton.js | 5 +++++ src/styles/styles.js | 9 ++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 900c9a0c5678..5ac6a34fe3c3 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import {View} from 'react-native'; import _ from 'underscore'; import styles from '../../styles/styles'; -import Recent from '../../../assets/images/history.svg'; +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'; @@ -23,7 +23,14 @@ const propTypes = { }; const CategoryShortcutBar = (props) => { - const icons = [Recent, Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; + // If the user has frequently used emojis, there will be 9 headers, otherwise there will be 8 + const hasFrequentlyUsedEmojis = props.headerIndices.length === 9; + const icons = [Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; + + // If the user has a frequently used category, push the icon + if (hasFrequentlyUsedEmojis) { + icons.unshift(FrequentlyUsed); + } return ( @@ -32,6 +39,7 @@ const CategoryShortcutBar = (props) => { icon={icons[i]} onPress={() => props.onPress(headerIndex)} key={`categoryShortcut${i}`} + widthStyle={hasFrequentlyUsedEmojis ? styles.categoryShortcutButtonWithFrequentlyUsed : styles.categoryShortcutButtonWithoutFrequentlyUsed} /> ))} diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 76118d3d65c8..177178d9c8b6 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -14,6 +14,10 @@ const propTypes = { /** The function to call when an emoji is selected */ onPress: PropTypes.func.isRequired, + + /** The width of the button based on whether there are 8 or 9 buttons */ + // eslint-disable-next-line react/forbid-prop-types + widthStyle: PropTypes.object.isRequired, }; class CategoryShortcutButton extends PureComponent { @@ -34,6 +38,7 @@ class CategoryShortcutButton extends PureComponent { StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), styles.categoryShortcutButton, this.state.isHighlighted && styles.emojiItemHighlighted, + this.props.widthStyle, ])} > diff --git a/src/styles/styles.js b/src/styles/styles.js index 127cc3667d48..8812b2d807b6 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1502,7 +1502,6 @@ const styles = { }, categoryShortcutButton: { - width: '11.11%', borderRadius: 8, paddingTop: 2, paddingBottom: 2, @@ -1510,6 +1509,14 @@ const styles = { justifyContent: 'center', }, + categoryShortcutButtonWithFrequentlyUsed: { + width: '11.11%', + }, + + categoryShortcutButtonWithoutFrequentlyUsed: { + width: '12.5%', + }, + chatItemEmojiButton: { alignSelf: 'flex-end', borderRadius: variables.buttonBorderRadius, From d7510d2f5fe665ba2b347b8edaa83aee3884df42 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Fri, 3 Feb 2023 09:15:11 -0700 Subject: [PATCH 48/54] Use flex instead of static widths --- src/components/EmojiPicker/CategoryShortcutBar.js | 9 ++++----- src/components/EmojiPicker/CategoryShortcutButton.js | 5 ----- .../EmojiPicker/EmojiPickerMenu/index.native.js | 2 +- src/styles/styles.js | 9 +-------- 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index 5ac6a34fe3c3..fff955da8561 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -23,12 +23,12 @@ const propTypes = { }; const CategoryShortcutBar = (props) => { - // If the user has frequently used emojis, there will be 9 headers, otherwise there will be 8 - const hasFrequentlyUsedEmojis = props.headerIndices.length === 9; + + const icons = [Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; - // If the user has a frequently used category, push the icon - if (hasFrequentlyUsedEmojis) { + // If the user has frequently used emojis, there will be 9 headers, otherwise there will be 8 + if (props.headerIndices.length === 9) { icons.unshift(FrequentlyUsed); } @@ -39,7 +39,6 @@ const CategoryShortcutBar = (props) => { icon={icons[i]} onPress={() => props.onPress(headerIndex)} key={`categoryShortcut${i}`} - widthStyle={hasFrequentlyUsedEmojis ? styles.categoryShortcutButtonWithFrequentlyUsed : styles.categoryShortcutButtonWithoutFrequentlyUsed} /> ))} diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 177178d9c8b6..76118d3d65c8 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -14,10 +14,6 @@ const propTypes = { /** The function to call when an emoji is selected */ onPress: PropTypes.func.isRequired, - - /** The width of the button based on whether there are 8 or 9 buttons */ - // eslint-disable-next-line react/forbid-prop-types - widthStyle: PropTypes.object.isRequired, }; class CategoryShortcutButton extends PureComponent { @@ -38,7 +34,6 @@ class CategoryShortcutButton extends PureComponent { StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), styles.categoryShortcutButton, this.state.isHighlighted && styles.emojiItemHighlighted, - this.props.widthStyle, ])} > diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 8b2c23fa2ef8..01065bce9c65 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -143,7 +143,7 @@ class EmojiPickerMenu extends Component { render() { return ( - + Date: Fri, 3 Feb 2023 09:24:05 -0700 Subject: [PATCH 49/54] Style --- src/components/EmojiPicker/CategoryShortcutBar.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutBar.js b/src/components/EmojiPicker/CategoryShortcutBar.js index fff955da8561..0114df692850 100644 --- a/src/components/EmojiPicker/CategoryShortcutBar.js +++ b/src/components/EmojiPicker/CategoryShortcutBar.js @@ -23,8 +23,6 @@ const propTypes = { }; const CategoryShortcutBar = (props) => { - - const icons = [Smiley, AnimalsAndNature, FoodAndDrink, TravelAndPlaces, Activities, Objects, Symbols, Flags]; // If the user has frequently used emojis, there will be 9 headers, otherwise there will be 8 From 7c59ca12ff671f06002853f5556110c90fee5a80 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Fri, 10 Feb 2023 11:00:41 -0700 Subject: [PATCH 50/54] Update color to match other icons --- src/components/EmojiPicker/CategoryShortcutButton.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index 76118d3d65c8..3b5d43f9b10d 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -4,9 +4,9 @@ import {Pressable, View} from 'react-native'; import Icon from '../Icon'; import variables from '../../styles/variables'; import styles from '../../styles/styles'; -import colors from '../../styles/colors'; import * as StyleUtils from '../../styles/StyleUtils'; import getButtonState from '../../libs/getButtonState'; +import themeColors from '../../styles/themes/default'; const propTypes = { /** The icon representation of the category that this button links to */ @@ -38,7 +38,7 @@ class CategoryShortcutButton extends PureComponent { > Date: Fri, 10 Feb 2023 13:09:47 -0700 Subject: [PATCH 51/54] Use reanimated to fix momentum scroll issue --- .../EmojiPicker/EmojiPickerMenu/index.native.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 01065bce9c65..6f765ee4e1b2 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {View, FlatList} from 'react-native'; +import {View, findNodeHandle} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; @@ -16,6 +16,7 @@ import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; import * as User from '../../../libs/actions/User'; import CategoryShortcutBar from '../CategoryShortcutBar'; +import Animated, {runOnUI, _scrollTo} from 'react-native-reanimated'; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -101,7 +102,11 @@ class EmojiPickerMenu extends Component { scrollToHeader(headerIndex) { const calculatedOffset = Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW) * CONST.EMOJI_PICKER_HEADER_HEIGHT; this.emojiList.flashScrollIndicators(); - this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); + const node = findNodeHandle(this.emojiList); + runOnUI(() => { + 'worklet'; + _scrollTo(node, 0, calculatedOffset, true); + })(); } /** @@ -149,7 +154,7 @@ class EmojiPickerMenu extends Component { onPress={this.scrollToHeader} /> - this.emojiList = el} data={this.emojis} renderItem={this.renderItem} From 06e150b8bf20c8bd0048b9de46d27440dffb6316 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Fri, 10 Feb 2023 13:25:20 -0700 Subject: [PATCH 52/54] Animate scrolling to match native --- src/components/EmojiPicker/EmojiPickerMenu/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index a3ebca869985..810fc49040d7 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -339,7 +339,7 @@ class EmojiPickerMenu extends Component { scrollToHeader(headerIndex) { const calculatedOffset = Math.floor(headerIndex / CONST.EMOJI_NUM_PER_ROW) * CONST.EMOJI_PICKER_HEADER_HEIGHT; this.emojiList.flashScrollIndicators(); - this.emojiList.scrollToOffset({offset: calculatedOffset, animated: false}); + this.emojiList.scrollToOffset({offset: calculatedOffset, animated: true}); } /** From 29fc3a9c9d0eb2f5b6b9cf6c7e9931a68aff50f2 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Fri, 10 Feb 2023 13:26:04 -0700 Subject: [PATCH 53/54] Style --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 6f765ee4e1b2..b2e6248f3893 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -4,6 +4,7 @@ import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; import compose from '../../../libs/compose'; +import Animated, {runOnUI, _scrollTo} from 'react-native-reanimated'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../withWindowDimensions'; import CONST from '../../../CONST'; import ONYXKEYS from '../../../ONYXKEYS'; @@ -16,7 +17,6 @@ import EmojiSkinToneList from '../EmojiSkinToneList'; import * as EmojiUtils from '../../../libs/EmojiUtils'; import * as User from '../../../libs/actions/User'; import CategoryShortcutBar from '../CategoryShortcutBar'; -import Animated, {runOnUI, _scrollTo} from 'react-native-reanimated'; const propTypes = { /** Function to add the selected emoji to the main compose text input */ @@ -105,6 +105,7 @@ class EmojiPickerMenu extends Component { const node = findNodeHandle(this.emojiList); runOnUI(() => { 'worklet'; + _scrollTo(node, 0, calculatedOffset, true); })(); } From cf8ae6ad8ae37abcaa8e2f9d71957f97111f6391 Mon Sep 17 00:00:00 2001 From: Brandon Stites Date: Fri, 10 Feb 2023 13:31:25 -0700 Subject: [PATCH 54/54] Style --- src/components/EmojiPicker/EmojiPickerMenu/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index b2e6248f3893..edf383eda1d8 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -3,8 +3,8 @@ import {View, findNodeHandle} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; -import compose from '../../../libs/compose'; import Animated, {runOnUI, _scrollTo} from 'react-native-reanimated'; +import compose from '../../../libs/compose'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../withWindowDimensions'; import CONST from '../../../CONST'; import ONYXKEYS from '../../../ONYXKEYS';