MM-22029 clear the text input as soon as possible (#4536)

* MM-22029 clear the text input as soon as possible

* Apply suggestions from code review

Co-authored-by: Miguel Alatzar <migbot@users.noreply.github.com>

Co-authored-by: Miguel Alatzar <migbot@users.noreply.github.com>
This commit is contained in:
Elias Nahum 2020-07-14 18:58:11 -04:00 committed by GitHub
parent b275e89636
commit 7db9c76a3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 108 additions and 110 deletions

View file

@ -132,62 +132,41 @@ export default class PostDraft extends PureComponent {
};
doSubmitMessage = () => {
if (this.input.current) {
const {createPost, currentUserId, channelId, files, handleClearFiles, rootId} = this.props;
const value = this.input.current.getValue() || '';
const postFiles = files.filter((f) => !f.failed);
const post = {
user_id: currentUserId,
channel_id: channelId,
root_id: rootId,
parent_id: rootId,
message: value,
const {createPost, currentUserId, channelId, files, handleClearFiles, rootId} = this.props;
const value = this.input.current.getValue();
const postFiles = files.filter((f) => !f.failed);
const post = {
user_id: currentUserId,
channel_id: channelId,
root_id: rootId,
parent_id: rootId,
message: value,
};
createPost(post, postFiles);
if (postFiles.length) {
handleClearFiles(channelId, rootId);
}
this.input.current.setValue('');
this.setState({sendingMessage: false});
this.input.current.changeDraft('');
if (Platform.OS === 'android') {
// Fixes the issue where Android predictive text would prepend suggestions to the post draft when messages
// are typed successively without blurring the input
const nextState = {
keyboardType: 'email-address',
};
createPost(post, postFiles);
const callback = () => this.setState({keyboardType: 'default'});
if (postFiles.length) {
handleClearFiles(channelId, rootId);
}
if (Platform.OS === 'ios') {
// On iOS, if the PostInput height increases from its
// initial height (due to a multiline post or a post whose
// message wraps, for example), then when the text is cleared
// the PostInput height decrease will be animated. This
// animation in conjunction with the PostList animation as it
// receives the newly created post is causing issues in the iOS
// PostList component as it fails to properly react to its content
// size changes. While a proper fix is determined for the PostList
// component, a small delay in triggering the height decrease
// animation gives the PostList enough time to first handle content
// size changes from the new post.
setTimeout(() => {
this.input.current.setValue('');
this.setState({sendingMessage: false});
}, 250);
} else {
this.input.current.setValue('');
this.setState({sendingMessage: false});
}
this.input.current.changeDraft('');
let callback;
if (Platform.OS === 'android') {
// Fixes the issue where Android predictive text would prepend suggestions to the post draft when messages
// are typed successively without blurring the input
const nextState = {
keyboardType: 'email-address',
};
callback = () => this.setState({keyboardType: 'default'});
this.setState(nextState, callback);
}
EventEmitter.emit('scroll-to-bottom');
this.setState(nextState, callback);
}
EventEmitter.emit('scroll-to-bottom');
};
getStatusFromSlashCommand = (message) => {
@ -237,52 +216,62 @@ export default class PostDraft extends PureComponent {
};
handleSendMessage = () => {
if (!this.isSendButtonEnabled()) {
if (!this.input.current) {
return;
}
this.setState({sendingMessage: true});
this.input.current.resetTextInput();
const {channelId, files, handleClearFailedFiles, rootId} = this.props;
const value = this.input.current?.getValue() || '';
requestAnimationFrame(() => {
const value = this.input.current.getValue();
if (!this.isSendButtonEnabled()) {
this.input.current.setValue(value);
return;
}
const isReactionMatch = value.match(IS_REACTION_REGEX);
if (isReactionMatch) {
const emoji = isReactionMatch[2];
this.sendReaction(emoji);
return;
}
this.setState({sendingMessage: true});
const hasFailedAttachments = files.some((f) => f.failed);
if (hasFailedAttachments) {
const {intl} = this.context;
const {channelId, files, handleClearFailedFiles, rootId} = this.props;
Alert.alert(
intl.formatMessage({
id: 'mobile.post_textbox.uploadFailedTitle',
defaultMessage: 'Attachment failure',
}),
intl.formatMessage({
id: 'mobile.post_textbox.uploadFailedDesc',
defaultMessage: 'Some attachments failed to upload to the server. Are you sure you want to post the message?',
}),
[{
text: intl.formatMessage({id: 'mobile.channel_info.alertNo', defaultMessage: 'No'}),
onPress: () => {
this.setState({sendingMessage: false});
},
}, {
text: intl.formatMessage({id: 'mobile.channel_info.alertYes', defaultMessage: 'Yes'}),
onPress: () => {
// Remove only failed files
handleClearFailedFiles(channelId, rootId);
this.sendMessage();
},
}],
);
} else {
this.sendMessage();
}
const isReactionMatch = value.match(IS_REACTION_REGEX);
if (isReactionMatch) {
const emoji = isReactionMatch[2];
this.sendReaction(emoji);
return;
}
const hasFailedAttachments = files.some((f) => f.failed);
if (hasFailedAttachments) {
const {intl} = this.context;
Alert.alert(
intl.formatMessage({
id: 'mobile.post_textbox.uploadFailedTitle',
defaultMessage: 'Attachment failure',
}),
intl.formatMessage({
id: 'mobile.post_textbox.uploadFailedDesc',
defaultMessage: 'Some attachments failed to upload to the server. Are you sure you want to post the message?',
}),
[{
text: intl.formatMessage({id: 'mobile.channel_info.alertNo', defaultMessage: 'No'}),
onPress: () => {
this.input.current.setValue(value);
this.setState({sendingMessage: false});
},
}, {
text: intl.formatMessage({id: 'mobile.channel_info.alertYes', defaultMessage: 'Yes'}),
onPress: () => {
// Remove only failed files
handleClearFailedFiles(channelId, rootId);
this.sendMessage();
},
}],
);
} else {
this.sendMessage();
}
});
};
handleUploadFiles = async (files) => {
@ -357,6 +346,7 @@ export default class PostDraft extends PureComponent {
this.setState({sendingMessage: false});
if (error) {
this.input.current.setValue(msg);
Alert.alert(
intl.formatMessage({
id: 'mobile.commands.error_title',
@ -367,24 +357,25 @@ export default class PostDraft extends PureComponent {
return;
}
if (this.input.current) {
this.input.current.setValue('');
this.input.current.changeDraft('');
}
this.input.current.setValue('');
this.input.current.changeDraft('');
};
sendMessage = () => {
const value = this.input.current?.getValue() || '';
const {enableConfirmNotificationsToChannel, membersCount, useChannelMentions} = this.props;
const notificationsToChannel = enableConfirmNotificationsToChannel && useChannelMentions;
const toAllOrChannel = this.textContainsAtAllAtChannel(value);
const value = this.input.current.getValue();
if (value.indexOf('/') === 0) {
this.sendCommand(value);
} else if (notificationsToChannel && membersCount > NOTIFY_ALL_MEMBERS && toAllOrChannel) {
this.showSendToAllOrChannelAlert(membersCount);
} else {
this.doSubmitMessage();
if (value) {
const {enableConfirmNotificationsToChannel, membersCount, useChannelMentions} = this.props;
const notificationsToChannel = enableConfirmNotificationsToChannel && useChannelMentions;
const toAllOrChannel = this.textContainsAtAllAtChannel(value);
if (value.indexOf('/') === 0) {
this.sendCommand(value);
} else if (notificationsToChannel && membersCount > NOTIFY_ALL_MEMBERS && toAllOrChannel) {
this.showSendToAllOrChannelAlert(membersCount, value);
} else {
this.doSubmitMessage();
}
}
};
@ -392,10 +383,8 @@ export default class PostDraft extends PureComponent {
const {addReactionToLatestPost, rootId} = this.props;
addReactionToLatestPost(emoji, rootId);
if (this.input.current) {
this.input.current.setValue('');
this.input.current.changeDraft('');
}
this.input.current.setValue('');
this.input.current.changeDraft('');
this.setState({sendingMessage: false});
};
@ -422,7 +411,7 @@ export default class PostDraft extends PureComponent {
);
};
showSendToAllOrChannelAlert = (membersCount) => {
showSendToAllOrChannelAlert = (membersCount, msg) => {
const {intl} = this.context;
const {channelTimezoneCount} = this.state;
const {isTimezoneEnabled} = this.props;
@ -468,6 +457,7 @@ export default class PostDraft extends PureComponent {
defaultMessage: 'Cancel',
}),
onPress: () => {
this.input.current.setValue(msg);
this.setState({sendingMessage: false});
},
},

View file

@ -265,6 +265,14 @@ export default class PostInput extends PureComponent {
});
};
resetTextInput = () => {
if (this.input.current) {
this.input.current.setNativeProps({
text: '',
});
}
}
setValue = (value, autocomplete = false) => {
this.value = value;
if (this.input.current) {