From 0faeb535b9a7dd2a95992b5f3299ead78072c38d Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Wed, 14 Aug 2019 11:29:55 -0400 Subject: [PATCH] MM-17425/MM-17683 Disable Send button when sending post (#3099) * MM-17425/MM-17683 Disable Send button when sending post * Update snapshot and add tests --- .../__snapshots__/post_textbox.test.js.snap | 2 +- .../post_textbox/post_textbox.test.js | 72 +++++++++++++++++++ .../post_textbox/post_textbox_base.js | 63 ++++++++-------- assets/base/i18n/en.json | 3 - 4 files changed, 107 insertions(+), 33 deletions(-) diff --git a/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap b/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap index fb98aa48d..cc3dabb9d 100644 --- a/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap +++ b/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap @@ -101,7 +101,7 @@ exports[`PostTextBox should match, full snapshot 1`] = ` visible={false} > { assert.equal(containsAtChannel, data.result, data.text); } }); + + describe('send button', () => { + test('should initially disable and hide the send button', () => { + const wrapper = shallowWithIntl( + + ); + + expect(wrapper.find(Fade).prop('visible')).toBe(false); + expect(wrapper.find(SendButton).prop('disabled')).toBe(true); + }); + + test('should show a disabled send button when uploading a file', () => { + const props = { + ...baseProps, + files: [{loading: true}], + }; + + const wrapper = shallowWithIntl( + + ); + + expect(wrapper.find(Fade).prop('visible')).toBe(true); + expect(wrapper.find(SendButton).prop('disabled')).toBe(true); + }); + + test('should show an enabled send button after uploading a file', () => { + const props = { + ...baseProps, + files: [{loading: false}], + }; + + const wrapper = shallowWithIntl( + + ); + + expect(wrapper.find(Fade).prop('visible')).toBe(true); + expect(wrapper.find(SendButton).prop('disabled')).toBe(false); + }); + + test('should show an enabled send button with a message', () => { + const props = { + ...baseProps, + value: 'test', + }; + + const wrapper = shallowWithIntl( + + ); + + expect(wrapper.find(Fade).prop('visible')).toBe(true); + expect(wrapper.find(SendButton).prop('disabled')).toBe(false); + }); + + test('should show a disabled send button while sending the message', () => { + const props = { + ...baseProps, + value: 'test', + }; + + const wrapper = shallowWithIntl( + + ); + + wrapper.setState({sendingMessage: true}); + + expect(wrapper.find(Fade).prop('visible')).toBe(true); + expect(wrapper.find(SendButton).prop('disabled')).toBe(true); + }); + }); }); diff --git a/app/components/post_textbox/post_textbox_base.js b/app/components/post_textbox/post_textbox_base.js index 8a26972e4..1c5c5f0c2 100644 --- a/app/components/post_textbox/post_textbox_base.js +++ b/app/components/post_textbox/post_textbox_base.js @@ -296,10 +296,12 @@ export default class PostTextBoxBase extends PureComponent { }; handleSendMessage = () => { - if (!this.canSend()) { + if (!this.isSendButtonEnabled()) { return; } + this.setState({sendingMessage: true}); + const {actions, channelId, files, rootId} = this.props; const {value} = this.state; @@ -325,6 +327,9 @@ export default class PostTextBoxBase extends PureComponent { }), [{ 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: () => { @@ -406,37 +411,23 @@ export default class PostTextBoxBase extends PureComponent { return this.canSend() || this.isFileLoading(); } + isSendButtonEnabled() { + return this.canSend() && !this.isFileLoading() && !this.state.sendingMessage; + } + sendMessage = () => { - const {files} = this.props; - const {intl} = this.context; const {value} = this.state; - if (files.length === 0 && !value) { - Alert.alert( - intl.formatMessage({ - id: 'mobile.post_textbox.empty.title', - defaultMessage: 'Empty Message', - }), - intl.formatMessage({ - id: 'mobile.post_textbox.empty.message', - defaultMessage: 'You are trying to send an empty message.\nPlease make sure you have a message or at least one attached file.', - }), - [{ - text: intl.formatMessage({id: 'mobile.post_textbox.empty.ok', defaultMessage: 'OK'}), - }], - ); - } else { - const currentMembersCount = this.props.currentChannelMembersCount; - const notificationsToChannel = this.props.enableConfirmNotificationsToChannel; - const toAllorChannel = this.textContainsAtAllAtChannel(value); + const currentMembersCount = this.props.currentChannelMembersCount; + const notificationsToChannel = this.props.enableConfirmNotificationsToChannel; + const toAllOrChannel = this.textContainsAtAllAtChannel(value); - if (value.indexOf('/') === 0) { - this.sendCommand(value); - } else if (notificationsToChannel && currentMembersCount > NOTIFY_ALL_MEMBERS && toAllorChannel) { - this.showSendToAllOrChannelAlert(currentMembersCount); - } else { - this.doSubmitMessage(); - } + if (value.indexOf('/') === 0) { + this.sendCommand(value); + } else if (notificationsToChannel && currentMembersCount > NOTIFY_ALL_MEMBERS && toAllOrChannel) { + this.showSendToAllOrChannelAlert(currentMembersCount); + } else { + this.doSubmitMessage(); } }; @@ -490,6 +481,9 @@ export default class PostTextBoxBase extends PureComponent { id: 'mobile.post_textbox.entire_channel.cancel', defaultMessage: 'Cancel', }), + onPress: () => { + this.setState({sendingMessage: false}); + }, }, { text: intl.formatMessage({ @@ -534,9 +528,11 @@ export default class PostTextBoxBase extends PureComponent { // size changes from the new post. setTimeout(() => { this.handleTextChange(''); + this.setState({sendingMessage: false}); }, 250); } else { this.handleTextChange(''); + this.setState({sendingMessage: false}); } this.changeDraft(''); @@ -586,6 +582,7 @@ export default class PostTextBoxBase extends PureComponent { const status = this.getStatusFromSlashCommand(msg); if (userIsOutOfOffice && this.isStatusSlashCommand(status)) { confirmOutOfOfficeDisabled(intl, status, this.updateStatus); + this.setState({sendingMessage: false}); return; } @@ -602,13 +599,21 @@ export default class PostTextBoxBase extends PureComponent { error.message ); } + + this.handleTextChange(''); + this.changeDraft(''); + + this.setState({sendingMessage: false}); }; sendReaction = (emoji) => { const {actions, rootId} = this.props; actions.addReactionToLatestPost(emoji, rootId); + this.handleTextChange(''); this.changeDraft(''); + + this.setState({sendingMessage: false}); }; onShowFileMaxWarning = () => { @@ -720,7 +725,7 @@ export default class PostTextBoxBase extends PureComponent { /> diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json index 682c8450d..0cb0bc216 100644 --- a/assets/base/i18n/en.json +++ b/assets/base/i18n/en.json @@ -353,9 +353,6 @@ "mobile.post_pre_header.flagged": "Flagged", "mobile.post_pre_header.pinned": "Pinned", "mobile.post_pre_header.pinned_flagged": "Pinned and Flagged", - "mobile.post_textbox.empty.message": "You are trying to send an empty message.\nPlease make sure you have a message or at least one attached file.", - "mobile.post_textbox.empty.ok": "OK", - "mobile.post_textbox.empty.title": "Empty Message", "mobile.post_textbox.entire_channel.cancel": "Cancel", "mobile.post_textbox.entire_channel.confirm": "Confirm", "mobile.post_textbox.entire_channel.message": "By using @all or @channel you are about to send notifications to {totalMembers} people. Are you sure you want to do this?",