[MM-26077] Emoji autocomplete fixes (#4512)
* Use 0 height over null and move fuse * Deconstruct props * Update app/components/autocomplete/emoji_suggestion/emoji_suggestion.js Co-authored-by: Elias Nahum <nahumhbl@gmail.com> * Update app/components/autocomplete/emoji_suggestion/emoji_suggestion.js * Update snapshot Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
parent
92e7adc852
commit
2ccf2dc716
4 changed files with 73 additions and 34 deletions
|
|
@ -1,6 +1,45 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/autocomplete/emoji_suggestion should match snapshot 1`] = `null`;
|
||||
exports[`components/autocomplete/emoji_suggestion should match snapshot 1`] = `
|
||||
<FlatList
|
||||
ItemSeparatorComponent={[Function]}
|
||||
data={Array []}
|
||||
disableVirtualization={false}
|
||||
extraData={
|
||||
Object {
|
||||
"active": false,
|
||||
"dataSource": Array [],
|
||||
}
|
||||
}
|
||||
horizontal={false}
|
||||
initialListSize={10}
|
||||
initialNumToRender={10}
|
||||
keyExtractor={[Function]}
|
||||
keyboardShouldPersistTaps="always"
|
||||
maxToRenderPerBatch={10}
|
||||
nestedScrollEnabled={false}
|
||||
numColumns={1}
|
||||
onEndReachedThreshold={2}
|
||||
pageSize={10}
|
||||
removeClippedSubviews={false}
|
||||
renderItem={[Function]}
|
||||
scrollEventThrottle={50}
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
},
|
||||
Object {
|
||||
"height": 0,
|
||||
"maxHeight": undefined,
|
||||
},
|
||||
]
|
||||
}
|
||||
updateCellsBatchingPeriod={50}
|
||||
windowSize={21}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`components/autocomplete/emoji_suggestion should match snapshot 2`] = `
|
||||
<FlatList
|
||||
|
|
@ -3047,6 +3086,7 @@ exports[`components/autocomplete/emoji_suggestion should match snapshot 2`] = `
|
|||
"flex": 1,
|
||||
},
|
||||
Object {
|
||||
"height": undefined,
|
||||
"maxHeight": undefined,
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
import AutocompleteDivider from '@components/autocomplete/autocomplete_divider';
|
||||
import Emoji from '@components/emoji';
|
||||
|
|
@ -19,6 +20,16 @@ import {makeStyleSheetFromTheme} from '@utils/theme';
|
|||
|
||||
const EMOJI_REGEX = /(^|\s|^\+|^-)(:([^:\s]*))$/i;
|
||||
const EMOJI_REGEX_WITHOUT_PREFIX = /\B(:([^:\s]*))$/i;
|
||||
const FUSE_OPTIONS = {
|
||||
shouldSort: false,
|
||||
threshold: 0.3,
|
||||
location: 0,
|
||||
distance: 10,
|
||||
includeMatches: true,
|
||||
findAllMatches: true,
|
||||
};
|
||||
|
||||
let fuse;
|
||||
|
||||
export default class EmojiSuggestion extends PureComponent {
|
||||
static propTypes = {
|
||||
|
|
@ -29,7 +40,6 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
cursorPosition: PropTypes.number,
|
||||
customEmojisEnabled: PropTypes.bool,
|
||||
emojis: PropTypes.array.isRequired,
|
||||
fuse: PropTypes.object.isRequired,
|
||||
isSearch: PropTypes.bool,
|
||||
maxListHeight: PropTypes.number,
|
||||
theme: PropTypes.object.isRequired,
|
||||
|
|
@ -43,6 +53,7 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
static defaultProps = {
|
||||
defaultChannel: {},
|
||||
value: '',
|
||||
emojis: [],
|
||||
};
|
||||
|
||||
state = {
|
||||
|
|
@ -54,14 +65,21 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
super(props);
|
||||
|
||||
this.matchTerm = '';
|
||||
this.listRef = React.createRef();
|
||||
fuse = new Fuse(props.emojis, FUSE_OPTIONS);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.props.isSearch) {
|
||||
componentDidUpdate(prevProps) {
|
||||
const {isSearch, emojis, cursorPosition, value} = this.props;
|
||||
|
||||
if (isSearch) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {cursorPosition, value} = this.props;
|
||||
if (emojis.join('') !== prevProps.emojis.join('')) {
|
||||
fuse = new Fuse(emojis, FUSE_OPTIONS);
|
||||
}
|
||||
|
||||
const match = value.substring(0, cursorPosition).match(EMOJI_REGEX);
|
||||
|
||||
if (!match || this.state.emojiComplete) {
|
||||
|
|
@ -162,7 +180,7 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
}
|
||||
|
||||
searchEmojis = (searchTerm) => {
|
||||
const {emojis, fuse} = this.props;
|
||||
const {emojis} = this.props;
|
||||
|
||||
let sorter = compareEmojis;
|
||||
if (searchTerm.trim().length) {
|
||||
|
|
@ -198,18 +216,23 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
render() {
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
|
||||
let height;
|
||||
if (!this.state.active) {
|
||||
// If we are not in an active state return null so nothing is rendered
|
||||
// other components are not blocked.
|
||||
return null;
|
||||
// If we are not in an active state set a height of 0 so nothing is rendered
|
||||
// and other components are not blocked.
|
||||
height = 0;
|
||||
if (this.listRef.current) {
|
||||
this.listRef.current.scrollToOffset({offset: 0});
|
||||
}
|
||||
}
|
||||
|
||||
const style = getStyleFromTheme(theme);
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
ref={this.listRef}
|
||||
keyboardShouldPersistTaps='always'
|
||||
style={[style.listView, {maxHeight: maxListHeight}]}
|
||||
style={[style.listView, {maxHeight: maxListHeight, height}]}
|
||||
extraData={this.state}
|
||||
data={this.state.dataSource}
|
||||
keyExtractor={this.keyExtractor}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
import Preferences from '@mm-redux/constants/preferences';
|
||||
import {selectEmojisByName} from '@selectors/emojis';
|
||||
|
|
@ -21,15 +20,6 @@ describe('components/autocomplete/emoji_suggestion', () => {
|
|||
},
|
||||
};
|
||||
const emojis = selectEmojisByName(state);
|
||||
const options = {
|
||||
shouldSort: false,
|
||||
threshold: 0.3,
|
||||
location: 0,
|
||||
distance: 10,
|
||||
includeMatches: true,
|
||||
findAllMatches: true,
|
||||
};
|
||||
const fuse = new Fuse(emojis, options);
|
||||
const baseProps = {
|
||||
actions: {
|
||||
addReactionToLatestPost: jest.fn(),
|
||||
|
|
@ -38,7 +28,6 @@ describe('components/autocomplete/emoji_suggestion', () => {
|
|||
cursorPosition: 0,
|
||||
customEmojisEnabled: false,
|
||||
emojis,
|
||||
fuse,
|
||||
isSearch: false,
|
||||
theme: Preferences.THEMES.default,
|
||||
onChangeText: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
import {addReactionToLatestPost} from '@actions/views/emoji';
|
||||
import {autocompleteCustomEmojis} from '@mm-redux/actions/emojis';
|
||||
|
|
@ -15,20 +14,8 @@ import EmojiSuggestion from './emoji_suggestion';
|
|||
|
||||
function mapStateToProps(state) {
|
||||
const emojis = selectEmojisByName(state);
|
||||
const options = {
|
||||
shouldSort: false,
|
||||
threshold: 0.3,
|
||||
location: 0,
|
||||
distance: 10,
|
||||
includeMatches: true,
|
||||
findAllMatches: true,
|
||||
};
|
||||
|
||||
const list = emojis.length ? emojis : [];
|
||||
const fuse = new Fuse(list, options);
|
||||
|
||||
return {
|
||||
fuse,
|
||||
emojis,
|
||||
customEmojisEnabled: getConfig(state).EnableCustomEmoji === 'true',
|
||||
theme: getTheme(state),
|
||||
|
|
|
|||
Loading…
Reference in a new issue