Fix paste files with multiple instances of post textbox (#3302)

This commit is contained in:
Elias Nahum 2019-09-25 12:03:15 +03:00 committed by Saturnino Abril
parent 0b044b62a5
commit 218e104010
6 changed files with 64 additions and 38 deletions

View file

@ -7,11 +7,12 @@ import assert from 'assert';
import {shallowWithIntl} from 'test/intl-test-helper';
import Preferences from 'mattermost-redux/constants/preferences';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
import Fade from 'app/components/fade';
import SendButton from 'app/components/send_button';
import PasteableTextInput from 'app/components/pasteable_text_input';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
import EphemeralStore from 'app/store/ephemeral_store';
import PostTextbox from './post_textbox.ios';
@ -62,6 +63,7 @@ describe('PostTextBox', () => {
cursorPositionEvent: '',
valueEvent: '',
isLandscape: false,
screenId: 'NavigationScreen1',
};
test('should match, full snapshot', () => {
@ -343,6 +345,7 @@ describe('PostTextBox', () => {
test('should show error dialog if error occured', () => {
jest.spyOn(Alert, 'alert').mockReturnValue(null);
const wrapper = shallowWithIntl(<PostTextbox {...baseProps}/>);
EphemeralStore.addNavigationComponentId('NavigationScreen1');
wrapper.find(PasteableTextInput).first().simulate('paste', {error: 'some error'}, []);
expect(Alert.alert).toHaveBeenCalled();
});
@ -350,6 +353,7 @@ describe('PostTextBox', () => {
test('should show file max warning and not uploading', () => {
jest.spyOn(EventEmitter, 'emit').mockReturnValue(null);
const wrapper = shallowWithIntl(<PostTextbox {...baseProps}/>);
EphemeralStore.addNavigationComponentId('NavigationScreen1');
wrapper.find(PasteableTextInput).first().simulate('paste', null, [
{
fileSize: 1000,
@ -414,6 +418,7 @@ describe('PostTextBox', () => {
test('should upload images', () => {
const wrapper = shallowWithIntl(<PostTextbox {...baseProps}/>);
EphemeralStore.addNavigationComponentId('NavigationScreen1');
wrapper.find(PasteableTextInput).first().simulate('paste', null, [
{
fileSize: 1000,
@ -424,6 +429,20 @@ describe('PostTextBox', () => {
]);
expect(baseProps.actions.initUploadFiles).toHaveBeenCalled();
});
test('should NOT upload images when not the top most screen', () => {
const wrapper = shallowWithIntl(<PostTextbox {...baseProps}/>);
EphemeralStore.addNavigationComponentId('NavigationScreen2');
wrapper.find(PasteableTextInput).first().simulate('paste', null, [
{
fileSize: 1000,
fileName: 'fileName.png',
type: 'images/png',
url: 'path/to/image',
},
]);
expect(baseProps.actions.initUploadFiles).not.toHaveBeenCalled();
});
});
});

View file

@ -24,11 +24,12 @@ import AttachmentButton from 'app/components/attachment_button';
import Fade from 'app/components/fade';
import FormattedMarkdownText from 'app/components/formatted_markdown_text';
import FormattedText from 'app/components/formatted_text';
import SendButton from 'app/components/send_button';
import PasteableTextInput from 'app/components/pasteable_text_input';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import SendButton from 'app/components/send_button';
import {INSERT_TO_COMMENT, INSERT_TO_DRAFT, IS_REACTION_REGEX, MAX_CONTENT_HEIGHT, MAX_FILE_COUNT} from 'app/constants/post_textbox';
import {NOTIFY_ALL_MEMBERS} from 'app/constants/view';
import EphemeralStore from 'app/store/ephemeral_store';
import {t} from 'app/utils/i18n';
import {confirmOutOfOfficeDisabled} from 'app/utils/status';
import {
@ -36,7 +37,6 @@ import {
makeStyleSheetFromTheme,
getKeyboardAppearanceFromTheme,
} from 'app/utils/theme';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
const {RNTextInputReset} = NativeModules;
@ -83,6 +83,7 @@ export default class PostTextBoxBase extends PureComponent {
isTimezoneEnabled: PropTypes.bool,
currentChannel: PropTypes.object,
isLandscape: PropTypes.bool.isRequired,
screenId: PropTypes.string.isRequired,
};
static defaultProps = {
@ -412,19 +413,19 @@ export default class PostTextBoxBase extends PureComponent {
this.props.actions.initUploadFiles(images, this.props.rootId);
};
isFileLoading() {
isFileLoading = () => {
const {files} = this.props;
return files.some((file) => file.loading);
}
};
isSendButtonVisible() {
isSendButtonVisible = () => {
return this.canSend() || this.isFileLoading();
}
};
isSendButtonEnabled() {
isSendButtonEnabled = () => {
return this.canSend() && !this.isFileLoading() && !this.state.sendingMessage;
}
};
sendMessage = () => {
const {value} = this.state;
@ -445,7 +446,7 @@ export default class PostTextBoxBase extends PureComponent {
textContainsAtAllAtChannel = (text) => {
const textWithoutCode = text.replace(/(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)| *(`{3,}|~{3,})[ .]*(\S+)? *\n([\s\S]*?\s*)\3 *(?:\n+|$)/g, '');
return (/\B@(all|channel)\b/i).test(textWithoutCode);
}
};
showSendToAllOrChannelAlert = (currentMembersCount) => {
const {intl} = this.context;
@ -505,7 +506,7 @@ export default class PostTextBoxBase extends PureComponent {
},
],
);
}
};
doSubmitMessage = () => {
const {actions, currentUserId, channelId, files, rootId} = this.props;
@ -562,7 +563,7 @@ export default class PostTextBoxBase extends PureComponent {
}
EventEmitter.emit('scroll-to-bottom');
}
};
getStatusFromSlashCommand = (message) => {
const tokens = message.split(' ');
@ -704,29 +705,31 @@ export default class PostTextBoxBase extends PureComponent {
},
]
);
}
};
handlePasteImages = (error, images) => {
if (error) {
this.showPasteImageErrorDialog();
return;
}
if (this.props.screenId === EphemeralStore.getNavigationTopComponentId()) {
if (error) {
this.showPasteImageErrorDialog();
return;
}
const {maxFileSize, files} = this.props;
const availableCount = MAX_FILE_COUNT - files.length;
if (images.length > availableCount) {
this.onShowFileMaxWarning();
return;
}
const {maxFileSize, files} = this.props;
const availableCount = MAX_FILE_COUNT - files.length;
if (images.length > availableCount) {
this.onShowFileMaxWarning();
return;
}
const largeImage = images.find((image) => image.fileSize > maxFileSize);
if (largeImage) {
this.onShowFileSizeWarning(largeImage.fileName);
return;
}
const largeImage = images.find((image) => image.fileSize > maxFileSize);
if (largeImage) {
this.onShowFileSizeWarning(largeImage.fileName);
return;
}
this.handleUploadFiles(images);
}
this.handleUploadFiles(images);
}
};
renderDeactivatedChannel = () => {
const {intl} = this.context;
@ -740,7 +743,7 @@ export default class PostTextBoxBase extends PureComponent {
})}
</Text>
);
}
};
renderTextBox = () => {
const {intl} = this.context;

View file

@ -37,6 +37,7 @@ export default class ChannelAndroid extends ChannelBase {
</View>
<PostTextbox
ref={this.postTextbox}
screenId={this.props.componentId}
/>
</KeyboardLayout>
<ChannelLoader

View file

@ -80,6 +80,7 @@ export default class ChannelIOS extends ChannelBase {
cursorPositionEvent={CHANNEL_POST_TEXTBOX_CURSOR_CHANGE}
valueEvent={CHANNEL_POST_TEXTBOX_VALUE_CHANGE}
ref={this.postTextbox}
screenId={this.props.componentId}
/>
</KeyboardTrackingView>
</React.Fragment>

View file

@ -44,10 +44,11 @@ export default class ThreadAndroid extends ThreadBase {
postTextBox = (
<PostTextbox
channelIsArchived={channelIsArchived}
rootId={rootId}
channelId={channelId}
channelIsArchived={channelIsArchived}
onCloseChannel={this.onCloseChannel}
rootId={rootId}
screenId={this.props.componentId}
/>
);
} else {

View file

@ -72,12 +72,13 @@ export default class ThreadIOS extends ThreadBase {
accessoriesContainerID={ACCESSORIES_CONTAINER_NATIVE_ID}
>
<PostTextbox
ref={this.postTextbox}
channelIsArchived={channelIsArchived}
rootId={rootId}
channelId={channelId}
onCloseChannel={this.onCloseChannel}
channelIsArchived={channelIsArchived}
cursorPositionEvent={THREAD_POST_TEXTBOX_CURSOR_CHANGE}
onCloseChannel={this.onCloseChannel}
ref={this.postTextbox}
rootId={rootId}
screenId={this.props.componentId}
valueEvent={THREAD_POST_TEXTBOX_VALUE_CHANGE}
/>
</KeyboardTrackingView>