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:
parent
4dc39a088a
commit
00ce1e1842
4 changed files with 69 additions and 8 deletions
|
|
@ -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
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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: [{
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue