Enforce max file count and active send button (#1241)

* Enforce max file count and wait until all images finish loading

Replaced Text with FormattedText

Remove unnecessary Text import

Clean up post_textbox and file_upload_preview

* Fix localization string for mobile

* change MAX_IMAGE_COUNT to MAX_FILE_COUNT
This commit is contained in:
Chris Duarte 2017-12-14 10:19:31 -08:00 committed by enahum
parent 4dc39a088a
commit 00ce1e1842
4 changed files with 69 additions and 8 deletions

View file

@ -12,6 +12,7 @@ import {
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import FormattedText from 'app/components/formatted_text';
import FileAttachmentImage from 'app/components/file_attachment_list/file_attachment_image';
import FileAttachmentIcon from 'app/components/file_attachment_list/file_attachment_icon';
@ -31,7 +32,8 @@ export default class FileUploadPreview extends PureComponent {
inputHeight: PropTypes.number.isRequired,
rootId: PropTypes.string,
theme: PropTypes.object.isRequired,
filesUploadingForCurrentChannel: PropTypes.bool.isRequired
filesUploadingForCurrentChannel: PropTypes.bool.isRequired,
showFileMaxWarning: PropTypes.bool.isRequired
};
handleRetryFileUpload = (file) => {
@ -98,13 +100,20 @@ export default class FileUploadPreview extends PureComponent {
};
render() {
if (this.props.channelIsLoading || (!this.props.files.length && !this.props.filesUploadingForCurrentChannel)) {
const {
showFileMaxWarning,
channelIsLoading,
filesUploadingForCurrentChannel,
deviceHeight,
files
} = this.props;
if (channelIsLoading || (!files.length && !filesUploadingForCurrentChannel)) {
return null;
}
return (
<View>
<View style={[style.container, {height: this.props.deviceHeight}]}>
<View style={[style.container, {height: deviceHeight}]}>
<ScrollView
horizontal={true}
style={style.scrollView}
@ -112,6 +121,14 @@ export default class FileUploadPreview extends PureComponent {
>
{this.buildFilePreviews()}
</ScrollView>
{showFileMaxWarning && (
<FormattedText
style={style.warning}
id='mobile.file_upload.max_warning'
defaultMessage='Uploads limited to 5 files maximum.'
/>
)}
</View>
</View>
);
@ -186,5 +203,10 @@ const style = StyleSheet.create({
scrollViewContent: {
alignItems: 'flex-end',
marginLeft: 14
},
warning: {
color: 'white',
marginLeft: 14,
marginBottom: 12
}
});

View file

@ -17,7 +17,10 @@ class AttachmentButton extends PureComponent {
intl: intlShape.isRequired,
navigator: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
uploadFiles: PropTypes.func.isRequired
uploadFiles: PropTypes.func.isRequired,
fileCount: PropTypes.number,
maxFileCount: PropTypes.number.isRequired,
onShowFileMaxWarning: PropTypes.func.isRequired
};
attachFileFromCamera = () => {
@ -142,6 +145,13 @@ class AttachmentButton extends PureComponent {
}
showFileAttachmentOptions = () => {
const {fileCount, maxFileCount, onShowFileMaxWarning} = this.props;
if (fileCount === maxFileCount) {
onShowFileMaxWarning();
return;
}
this.props.blurTextBox();
const options = {
items: [{

View file

@ -18,6 +18,7 @@ import Typing from './components/typing';
const INITIAL_HEIGHT = Platform.OS === 'ios' ? 34 : 36;
const MAX_CONTENT_HEIGHT = 100;
const MAX_MESSAGE_LENGTH = 4000;
const MAX_FILE_COUNT = 5;
const IS_REACTION_REGEX = /(^\+:([^:\s]*):)$/i;
class PostTextbox extends PureComponent {
@ -62,7 +63,8 @@ class PostTextbox extends PureComponent {
contentHeight: INITIAL_HEIGHT,
inputWidth: null,
keyboardType: 'default',
value: props.value
value: props.value,
showFileMaxWarning: false
};
}
@ -100,7 +102,19 @@ class PostTextbox extends PureComponent {
const valueLength = value.trim().length;
if (files.length) {
return valueLength <= MAX_MESSAGE_LENGTH && uploadFileRequestStatus !== RequestStatus.STARTED;
const filesLoading = [];
const filesFailed = [];
files.forEach((file) => {
if (file.loading) {
filesLoading.push(file);
}
if (!file.failed) {
filesFailed.push(file);
}
});
const loadingComplete = filesLoading.length === 0;
const noneFailed = filesFailed.length > 0;
return valueLength <= MAX_MESSAGE_LENGTH && uploadFileRequestStatus !== RequestStatus.STARTED && noneFailed && loadingComplete;
}
return valueLength > 0 && valueLength <= MAX_MESSAGE_LENGTH;
@ -268,7 +282,7 @@ class PostTextbox extends PureComponent {
};
renderSendButton = () => {
const {theme, uploadFileRequestStatus} = this.props;
const {files, theme} = this.props;
const style = getStyleSheet(theme);
const icon = (
@ -280,7 +294,8 @@ class PostTextbox extends PureComponent {
);
let button = null;
if (uploadFileRequestStatus === RequestStatus.STARTED) {
const imagesLoading = files.filter((f) => f.loading).length > 0;
if (imagesLoading) {
button = (
<View style={style.sendButtonContainer}>
<View style={[style.sendButton, style.disableButton]}>
@ -368,6 +383,14 @@ class PostTextbox extends PureComponent {
this.changeDraft('');
};
onShowFileMaxWarning = () => {
this.setState({showFileMaxWarning: true}, () => {
setTimeout(() => {
this.setState({showFileMaxWarning: false});
}, 3000);
});
};
render() {
const {
canUploadFiles,
@ -379,6 +402,7 @@ class PostTextbox extends PureComponent {
rootId,
theme
} = this.props;
const {showFileMaxWarning} = this.state;
const style = getStyleSheet(theme);
const textInputHeight = Math.min(this.state.contentHeight, MAX_CONTENT_HEIGHT);
@ -400,6 +424,9 @@ class PostTextbox extends PureComponent {
blurTextBox={this.blur}
theme={theme}
navigator={navigator}
fileCount={files.length}
maxFileCount={MAX_FILE_COUNT}
onShowFileMaxWarning={this.onShowFileMaxWarning}
uploadFiles={this.handleUploadFiles}
/>
);
@ -421,6 +448,7 @@ class PostTextbox extends PureComponent {
files={files}
inputHeight={textInputHeight}
rootId={rootId}
showFileMaxWarning={showFileMaxWarning}
/>
<Autocomplete
ref={this.attachAutocomplete}

View file

@ -1999,6 +1999,7 @@
"mobile.file_upload.library": "Photo Library",
"mobile.file_upload.more": "More",
"mobile.file_upload.video": "Video Library",
"mobile.file_upload.max_warning": "Uploads limited to 5 files maximum.",
"mobile.help.title": "Help",
"mobile.image_preview.deleted_post_message": "This post and its files have been deleted. The previewer will now be closed.",
"mobile.image_preview.deleted_post_title": "Post Deleted",