[FIX] Messagebox onChangeText issues (#1252)

* Stop ongoing debounces on messagebox unmount

* Immediately change send icon, but keep debouncing others

* Make CustomEmoji stateless function

* Fix mentions keyExtractor
This commit is contained in:
Diego Mello 2019-09-27 16:17:29 -03:00 committed by GitHub
parent d9f7ff836d
commit 3ee97881f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 42 deletions

View File

@ -2,20 +2,7 @@ import React from 'react';
import FastImage from 'react-native-fast-image'; import FastImage from 'react-native-fast-image';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default class CustomEmoji extends React.Component { const CustomEmoji = React.memo(({ baseUrl, emoji, style }) => (
static propTypes = {
baseUrl: PropTypes.string.isRequired,
emoji: PropTypes.object.isRequired,
style: PropTypes.any
}
shouldComponentUpdate() {
return false;
}
render() {
const { baseUrl, emoji, style } = this.props;
return (
<FastImage <FastImage
style={style} style={style}
source={{ source={{
@ -24,6 +11,16 @@ export default class CustomEmoji extends React.Component {
}} }}
resizeMode={FastImage.resizeMode.contain} resizeMode={FastImage.resizeMode.contain}
/> />
); ), (prevProps, nextProps) => {
} const prevEmoji = prevProps.emoji.content || prevProps.emoji.name;
} const nextEmoji = nextProps.emoji.content || nextProps.emoji.name;
return prevEmoji === nextEmoji;
});
CustomEmoji.propTypes = {
baseUrl: PropTypes.string.isRequired,
emoji: PropTypes.object.isRequired,
style: PropTypes.any
};
export default CustomEmoji;

View File

@ -224,12 +224,34 @@ class MessageBox extends Component {
componentWillUnmount() { componentWillUnmount() {
console.countReset(`${ this.constructor.name }.render calls`); console.countReset(`${ this.constructor.name }.render calls`);
if (this.onChangeText && this.onChangeText.stop) {
this.onChangeText.stop();
}
if (this.getUsers && this.getUsers.stop) {
this.getUsers.stop();
}
if (this.getRooms && this.getRooms.stop) {
this.getRooms.stop();
}
if (this.getEmojis && this.getEmojis.stop) {
this.getEmojis.stop();
}
if (this.getSlashCommands && this.getSlashCommands.stop) {
this.getSlashCommands.stop();
}
} }
onChangeText = debounce(async(text) => { onChangeText = (text) => {
const db = database.active;
const isTextEmpty = text.length === 0; const isTextEmpty = text.length === 0;
this.setShowSend(!isTextEmpty); this.setShowSend(!isTextEmpty);
this.debouncedOnChangeText(text);
}
// eslint-disable-next-line react/sort-comp
debouncedOnChangeText = debounce(async(text) => {
const db = database.active;
const isTextEmpty = text.length === 0;
// this.setShowSend(!isTextEmpty);
this.handleTyping(!isTextEmpty); this.handleTyping(!isTextEmpty);
this.setInput(text); this.setInput(text);
// matches if their is text that stats with '/' and group the command and params so we can use it "/command params" // matches if their is text that stats with '/' and group the command and params so we can use it "/command params"
@ -248,9 +270,10 @@ class MessageBox extends Component {
} }
if (!isTextEmpty) { if (!isTextEmpty) {
try {
const { start, end } = this.component._lastNativeSelection; const { start, end } = this.component._lastNativeSelection;
const cursor = Math.max(start, end); const cursor = Math.max(start, end);
const lastNativeText = this.component._lastNativeText; const lastNativeText = this.component._lastNativeText || '';
// matches if text either starts with '/' or have (@,#,:) then it groups whatever comes next of mention type // matches if text either starts with '/' or have (@,#,:) then it groups whatever comes next of mention type
const regexp = /(#|@|:|^\/)([a-z0-9._-]+)$/im; const regexp = /(#|@|:|^\/)([a-z0-9._-]+)$/im;
const result = lastNativeText.substr(0, cursor).match(regexp); const result = lastNativeText.substr(0, cursor).match(regexp);
@ -263,10 +286,13 @@ class MessageBox extends Component {
} }
const [, lastChar, name] = result; const [, lastChar, name] = result;
this.identifyMentionKeyword(name, lastChar); this.identifyMentionKeyword(name, lastChar);
} catch (e) {
log(e);
}
} else { } else {
this.stopTrackingMention(); this.stopTrackingMention();
} }
}, 100, true) }, 100)
onKeyboardResigned = () => { onKeyboardResigned = () => {
this.closeEmoji(); this.closeEmoji();
@ -339,10 +365,10 @@ class MessageBox extends Component {
getFixedMentions = (keyword) => { getFixedMentions = (keyword) => {
let result = []; let result = [];
if ('all'.indexOf(keyword) !== -1) { if ('all'.indexOf(keyword) !== -1) {
result = [{ _id: -1, username: 'all' }]; result = [{ id: -1, username: 'all' }];
} }
if ('here'.indexOf(keyword) !== -1) { if ('here'.indexOf(keyword) !== -1) {
result = [{ _id: -2, username: 'here' }, ...result]; result = [{ id: -2, username: 'here' }, ...result];
} }
return result; return result;
} }
@ -813,8 +839,9 @@ class MessageBox extends Component {
<FlatList <FlatList
style={styles.mentionList} style={styles.mentionList}
data={mentions} data={mentions}
extraData={mentions}
renderItem={this.renderMentionItem} renderItem={this.renderMentionItem}
keyExtractor={item => item._id || item.username || item.command || item} keyExtractor={item => item.id || item.username || item.command || item}
keyboardShouldPersistTaps='always' keyboardShouldPersistTaps='always'
/> />
</ScrollView> </ScrollView>