[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:
parent
d9f7ff836d
commit
3ee97881f3
|
@ -2,28 +2,25 @@ 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 = {
|
<FastImage
|
||||||
baseUrl: PropTypes.string.isRequired,
|
style={style}
|
||||||
emoji: PropTypes.object.isRequired,
|
source={{
|
||||||
style: PropTypes.any
|
uri: `${ baseUrl }/emoji-custom/${ encodeURIComponent(emoji.content || emoji.name) }.${ emoji.extension }`,
|
||||||
}
|
priority: FastImage.priority.high
|
||||||
|
}}
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
shouldComponentUpdate() {
|
CustomEmoji.propTypes = {
|
||||||
return false;
|
baseUrl: PropTypes.string.isRequired,
|
||||||
}
|
emoji: PropTypes.object.isRequired,
|
||||||
|
style: PropTypes.any
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
export default CustomEmoji;
|
||||||
const { baseUrl, emoji, style } = this.props;
|
|
||||||
return (
|
|
||||||
<FastImage
|
|
||||||
style={style}
|
|
||||||
source={{
|
|
||||||
uri: `${ baseUrl }/emoji-custom/${ encodeURIComponent(emoji.content || emoji.name) }.${ emoji.extension }`,
|
|
||||||
priority: FastImage.priority.high
|
|
||||||
}}
|
|
||||||
resizeMode={FastImage.resizeMode.contain}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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,25 +270,29 @@ class MessageBox extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTextEmpty) {
|
if (!isTextEmpty) {
|
||||||
const { start, end } = this.component._lastNativeSelection;
|
try {
|
||||||
const cursor = Math.max(start, end);
|
const { start, end } = this.component._lastNativeSelection;
|
||||||
const lastNativeText = this.component._lastNativeText;
|
const cursor = Math.max(start, end);
|
||||||
// matches if text either starts with '/' or have (@,#,:) then it groups whatever comes next of mention type
|
const lastNativeText = this.component._lastNativeText || '';
|
||||||
const regexp = /(#|@|:|^\/)([a-z0-9._-]+)$/im;
|
// matches if text either starts with '/' or have (@,#,:) then it groups whatever comes next of mention type
|
||||||
const result = lastNativeText.substr(0, cursor).match(regexp);
|
const regexp = /(#|@|:|^\/)([a-z0-9._-]+)$/im;
|
||||||
if (!result) {
|
const result = lastNativeText.substr(0, cursor).match(regexp);
|
||||||
const slash = lastNativeText.match(/^\/$/); // matches only '/' in input
|
if (!result) {
|
||||||
if (slash) {
|
const slash = lastNativeText.match(/^\/$/); // matches only '/' in input
|
||||||
return this.identifyMentionKeyword('', MENTIONS_TRACKING_TYPE_COMMANDS);
|
if (slash) {
|
||||||
|
return this.identifyMentionKeyword('', MENTIONS_TRACKING_TYPE_COMMANDS);
|
||||||
|
}
|
||||||
|
return this.stopTrackingMention();
|
||||||
}
|
}
|
||||||
return this.stopTrackingMention();
|
const [, lastChar, name] = result;
|
||||||
|
this.identifyMentionKeyword(name, lastChar);
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
}
|
}
|
||||||
const [, lastChar, name] = result;
|
|
||||||
this.identifyMentionKeyword(name, lastChar);
|
|
||||||
} 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>
|
||||||
|
|
Loading…
Reference in New Issue