Properly handle max file size (#2248)

* Properly handle max file size

* Feedback review
This commit is contained in:
Elias Nahum 2018-10-11 14:11:05 -03:00
parent 5d9b8a7e06
commit b5b948e58f
No known key found for this signature in database
GPG key ID: E038DB71E0B61702
6 changed files with 71 additions and 9 deletions

View file

@ -10,6 +10,8 @@ import {
StyleSheet,
TouchableOpacity,
} from 'react-native';
import RNFetchBlob from 'rn-fetch-blob';
import Icon from 'react-native-vector-icons/Ionicons';
import {DocumentPicker} from 'react-native-document-picker';
import ImagePicker from 'react-native-image-picker';
@ -27,8 +29,10 @@ export default class AttachmentButton extends PureComponent {
children: PropTypes.node,
fileCount: PropTypes.number,
maxFileCount: PropTypes.number.isRequired,
maxFileSize: PropTypes.number.isRequired,
navigator: PropTypes.object.isRequired,
onShowFileMaxWarning: PropTypes.func,
onShowFileSizeWarning: PropTypes.func,
theme: PropTypes.object.isRequired,
uploadFiles: PropTypes.func.isRequired,
wrapper: PropTypes.bool,
@ -293,8 +297,19 @@ export default class AttachmentButton extends PureComponent {
return true;
};
uploadFiles = (images) => {
this.props.uploadFiles(images);
uploadFiles = async (files) => {
const file = files[0];
if (!file.fileSize | !file.fileName) {
const fileInfo = await RNFetchBlob.fs.stat(file.path);
file.fileSize = fileInfo.size;
file.fileName = fileInfo.filename;
}
if (file.fileSize > this.props.maxFileSize) {
this.props.onShowFileSizeWarning(file.fileName);
} else {
this.props.uploadFiles(files);
}
};
handleFileAttachmentOption = (action) => {

View file

@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import {
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
@ -20,6 +21,7 @@ export default class FileUploadPreview extends PureComponent {
deviceHeight: PropTypes.number.isRequired,
files: PropTypes.array.isRequired,
filesUploadingForCurrentChannel: PropTypes.bool.isRequired,
fileSizeWarning: PropTypes.string,
rootId: PropTypes.string,
showFileMaxWarning: PropTypes.bool.isRequired,
theme: PropTypes.object.isRequired,
@ -42,12 +44,17 @@ export default class FileUploadPreview extends PureComponent {
render() {
const {
showFileMaxWarning,
fileSizeWarning,
channelIsLoading,
filesUploadingForCurrentChannel,
deviceHeight,
files,
} = this.props;
if (channelIsLoading || (!files.length && !filesUploadingForCurrentChannel)) {
if (
!fileSizeWarning && !showFileMaxWarning &&
(channelIsLoading || (!files.length && !filesUploadingForCurrentChannel))
) {
return null;
}
@ -68,7 +75,11 @@ export default class FileUploadPreview extends PureComponent {
defaultMessage='Uploads limited to 5 files maximum.'
/>
)}
{Boolean(fileSizeWarning) &&
<Text style={style.warning}>
{fileSizeWarning}
</Text>
}
</View>
</View>
);

View file

@ -20,6 +20,7 @@ import {handleCommentDraftChanged, handleCommentDraftSelectionChanged} from 'app
import {userTyping} from 'app/actions/views/typing';
import {getCurrentChannelDraft, getThreadDraft} from 'app/selectors/views';
import {getChannelMembersForDm} from 'app/selectors/channel';
import {getAllowedServerMaxFileSize} from 'app/utils/file';
import PostTextbox from './post_textbox';
@ -53,6 +54,7 @@ function mapStateToProps(state, ownProps) {
userIsOutOfOffice,
deactivatedChannel,
files: currentDraft.files,
maxFileSize: getAllowedServerMaxFileSize(config),
maxMessageLength: (config && parseInt(config.MaxPostSize || 0, 10)) || MAX_MESSAGE_LENGTH,
theme: getTheme(state),
uploadFileRequestStatus: state.requests.files.uploadFiles.status,

View file

@ -8,6 +8,7 @@ import {intlShape} from 'react-intl';
import Button from 'react-native-button';
import {General, RequestStatus} from 'mattermost-redux/constants';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
import {getFormattedFileSize} from 'mattermost-redux/utils/file_utils';
import AttachmentButton from 'app/components/attachment_button';
import Autocomplete from 'app/components/autocomplete';
@ -51,6 +52,7 @@ export default class PostTextbox extends PureComponent {
currentUserId: PropTypes.string.isRequired,
deactivatedChannel: PropTypes.bool.isRequired,
files: PropTypes.array,
maxFileSize: PropTypes.number.isRequired,
maxMessageLength: PropTypes.number.isRequired,
navigator: PropTypes.object,
rootId: PropTypes.string,
@ -79,6 +81,7 @@ export default class PostTextbox extends PureComponent {
contentHeight: INITIAL_HEIGHT,
cursorPosition: 0,
keyboardType: 'default',
fileSizeWarning: null,
top: 0,
value: props.value,
showFileMaxWarning: false,
@ -458,6 +461,23 @@ export default class PostTextbox extends PureComponent {
});
};
onShowFileSizeWarning = (filename) => {
const {formatMessage} = this.context.intl;
const fileSizeWarning = formatMessage({
id: 'file_upload.fileAbove',
defaultMessage: 'File above {max}MB cannot be uploaded: {filename}',
}, {
max: getFormattedFileSize({size: this.props.maxFileSize}),
filename,
});
this.setState({fileSizeWarning}, () => {
setTimeout(() => {
this.setState({fileSizeWarning: null});
}, 3000);
});
};
onCloseChannelPress = () => {
const {onCloseChannel, channelTeamId} = this.props;
this.props.actions.selectPenultimateChannel(channelTeamId);
@ -502,6 +522,7 @@ export default class PostTextbox extends PureComponent {
channelIsReadOnly,
deactivatedChannel,
files,
maxFileSize,
navigator,
rootId,
theme,
@ -523,6 +544,7 @@ export default class PostTextbox extends PureComponent {
const {
contentHeight,
cursorPosition,
fileSizeWarning,
showFileMaxWarning,
top,
value,
@ -549,8 +571,10 @@ export default class PostTextbox extends PureComponent {
theme={theme}
navigator={navigator}
fileCount={files.length}
maxFileSize={maxFileSize}
maxFileCount={MAX_FILE_COUNT}
onShowFileMaxWarning={this.onShowFileMaxWarning}
onShowFileSizeWarning={this.onShowFileSizeWarning}
uploadFiles={this.handleUploadFiles}
/>
);
@ -564,6 +588,7 @@ export default class PostTextbox extends PureComponent {
<FileUploadPreview
channelId={channelId}
files={files}
fileSizeWarning={fileSizeWarning}
rootId={rootId}
showFileMaxWarning={showFileMaxWarning}
/>

View file

@ -69,6 +69,7 @@
"edit_post.save": "Save",
"error.team_not_found.title": "Team Not Found",
"file_attachment.download": "Download",
"file_upload.fileAbove": "File above {max}MB cannot be uploaded: {filename}",
"get_post_link_modal.title": "Copy Permalink",
"integrations.add": "Add",
"intro_messages.anyMember": " Any member can join and read this channel.",

View file

@ -24,7 +24,9 @@ import RNFetchBlob from 'rn-fetch-blob';
import {Preferences} from 'mattermost-redux/constants';
import {getFormattedFileSize, lookupMimeType} from 'mattermost-redux/utils/file_utils';
import Loading from 'app/components/loading';
import PaperPlane from 'app/components/paper_plane';
import {MAX_FILE_COUNT} from 'app/constants/post_textbox';
import mattermostManaged from 'app/mattermost_managed';
import {getExtensionFromMime} from 'app/utils/file';
import {emptyFunction} from 'app/utils/general';
@ -263,7 +265,7 @@ export default class ExtensionPost extends PureComponent {
};
loadData = async (items) => {
const {token, url} = this.props;
const {maxFileSize, token, url} = this.props;
if (token && url) {
const text = [];
const files = [];
@ -312,13 +314,13 @@ export default class ExtensionPost extends PureComponent {
const value = text.join('\n');
if (!error) {
if (!error && files.length <= MAX_FILE_COUNT && totalSize <= maxFileSize) {
this.props.navigation.setParams({
post: this.onPost,
});
}
this.setState({error, files, value, hasPermission: true, totalSize});
this.setState({error, files, value, hasPermission: true, totalSize, loaded: true});
}
};
@ -489,7 +491,13 @@ export default class ExtensionPost extends PureComponent {
render() {
const {formatMessage} = this.context.intl;
const {maxFileSize, token, url} = this.props;
const {error, hasPermission, files, totalSize} = this.state;
const {error, hasPermission, files, totalSize, loaded} = this.state;
if (!loaded) {
return (
<Loading/>
);
}
if (error) {
return this.renderErrorMessage(error);
@ -503,7 +511,7 @@ export default class ExtensionPost extends PureComponent {
});
return this.renderErrorMessage(storage);
} else if (files.length > 5) {
} else if (files.length > MAX_FILE_COUNT) {
const fileCount = formatMessage({
id: 'mobile.extension.file_limit',
defaultMessage: 'Sharing is limited to a maximum of 5 files.',