[ICU-676] Make the app extensions follow the max file size that the server accepts (#1411)

* Android Share extension follows server config file size limit

* iOS Share extention follows config file size limit

* feedback review
This commit is contained in:
enahum 2018-02-07 18:02:38 -03:00 committed by GitHub
parent 439131578a
commit 509fe37f1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 53 deletions

View file

@ -6,6 +6,7 @@ import {lookupMimeType} from 'mattermost-redux/utils/file_utils';
import {DeviceTypes} from 'app/constants/';
const {DOCUMENTS_PATH, VIDEOS_PATH} = DeviceTypes;
const DEFAULT_SERVER_MAX_FILE_SIZE = 50 * 1024 * 1024;// 50 Mb
export function generateId() {
// Implementation taken from http://stackoverflow.com/a/2117523
@ -79,3 +80,7 @@ export function buildFileUploadData(file) {
export const encodeHeaderURIStringToUTF8 = (string) => {
return encodeURIComponent(string) + '"; filename*="utf-8\'\'' + encodeURIComponent(string);
};
export const getAllowedServerMaxFileSize = (config) => {
return config.MaxFileSize ? parseInt(config.MaxFileSize, 10) : DEFAULT_SERVER_MAX_FILE_SIZE;
};

View file

@ -2024,7 +2024,7 @@
"mobile.error_handler.title": "Unexpected error occurred",
"mobile.extension.authentication_required": "Authentication required: Please first login using the app.",
"mobile.extension.file_limit": "Sharing is limited to a maximum of 5 files.",
"mobile.extension.max_file_size": "File attachments shared in Mattermost must be less than 20 Mb.",
"mobile.extension.max_file_size": "File attachments shared in Mattermost must be less than {size}.",
"mobile.extension.permission": "Mattermost needs access to the device storage to share files.",
"mobile.extension.posting": "Posting...",
"mobile.extension.title": "Share in Mattermost",

View file

@ -18,9 +18,10 @@ import {
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import Video from 'react-native-video';
import LocalAuth from 'react-native-local-auth';
import RNFetchBlob from 'react-native-fetch-blob';
import {Preferences} from 'mattermost-redux/constants';
import {lookupMimeType} from 'mattermost-redux/utils/file_utils';
import {getFormattedFileSize, lookupMimeType} from 'mattermost-redux/utils/file_utils';
import PaperPlane from 'app/components/paper_plane';
import mattermostManaged from 'app/mattermost_managed';
@ -57,6 +58,7 @@ export default class ExtensionPost extends PureComponent {
static propTypes = {
channelId: PropTypes.string.isRequired,
currentUserId: PropTypes.string.isRequired,
maxFileSize: PropTypes.number.isRequired,
navigation: PropTypes.object.isRequired,
teamId: PropTypes.string.isRequired,
token: PropTypes.string,
@ -129,6 +131,7 @@ export default class ExtensionPost extends PureComponent {
files: [],
hasPermission: null,
teamId: props.teamId,
totalSize: 0,
value: ''
};
}
@ -261,6 +264,7 @@ export default class ExtensionPost extends PureComponent {
if (token && url) {
const text = [];
const files = [];
let totalSize = 0;
this.props.navigation.setParams({
post: this.onPost
@ -276,11 +280,14 @@ export default class ExtensionPost extends PureComponent {
const fullPath = item.value;
const filename = fullPath.replace(/^.*[\\/]/, '');
const extension = filename.split('.').pop();
const fileSize = await RNFetchBlob.fs.stat(fullPath);
totalSize += fileSize.size;
files.push({
extension,
filename,
fullPath,
mimeType: lookupMimeType(filename.toLowerCase()),
size: getFormattedFileSize(fileSize),
type: item.type
});
break;
@ -290,7 +297,7 @@ export default class ExtensionPost extends PureComponent {
const value = text.join('\n');
this.setState({files, value, hasPermission: true});
this.setState({files, value, hasPermission: true, totalSize});
}
};
@ -355,6 +362,20 @@ export default class ExtensionPost extends PureComponent {
);
};
renderErrorMessage = (message) => {
return (
<View
style={styles.flex}
>
<View style={styles.unauthenticatedContainer}>
<Text style={styles.unauthenticated}>
{message}
</Text>
</View>
</View>
);
};
renderFiles = () => {
const {files} = this.state;
@ -425,7 +446,7 @@ export default class ExtensionPost extends PureComponent {
numberOfLines={1}
style={styles.filename}
>
{file.filename}
{`${file.size} - ${file.filename}`}
</Text>
</View>
);
@ -446,40 +467,33 @@ export default class ExtensionPost extends PureComponent {
render() {
const {formatMessage} = this.context.intl;
const {token, url} = this.props;
const {hasPermission, files} = this.state;
const {maxFileSize, token, url} = this.props;
const {hasPermission, files, totalSize} = this.state;
if (token && url) {
if (hasPermission === false) {
const storage = formatMessage({
id: 'mobile.extension.permission',
defaultMessage: 'Mattermost needs access to the device storage to share files.'
});
return this.renderErrorMessage(storage);
} else if (files.length > 5) {
const fileCount = formatMessage({
id: 'mobile.extension.file_limit',
defaultMessage: 'Sharing is limited to a maximum of 5 files.'
});
return this.renderErrorMessage(fileCount);
} else if (totalSize > maxFileSize) {
const maxSize = formatMessage({
id: 'mobile.extension.max_file_size',
defaultMessage: 'File attachments shared in Mattermost must be less than {size}.'
}, {size: getFormattedFileSize({size: maxFileSize})});
return this.renderErrorMessage(maxSize);
}
if (hasPermission === false) {
return (
<View
style={styles.flex}
>
<View style={styles.unauthenticatedContainer}>
<Text style={styles.unauthenticated}>
{formatMessage({
id: 'mobile.extension.permission',
defaultMessage: 'Mattermost needs access to the device storage to share files.'
})}
</Text>
</View>
</View>
);
} else if (files.length > 5) {
return (
<View
style={styles.flex}
>
<View style={styles.unauthenticatedContainer}>
<Text style={styles.unauthenticated}>
{formatMessage({
id: 'mobile.extension.file_limit',
defaultMessage: 'Sharing is limited to a maximum of 5 files.'
})}
</Text>
</View>
</View>
);
} else if (token && url) {
return (
<View style={styles.container}>
<View style={styles.wrapper}>
@ -493,16 +507,12 @@ export default class ExtensionPost extends PureComponent {
);
}
return (
<View style={styles.unauthenticatedContainer}>
<Text style={styles.unauthenticated}>
{formatMessage({
id: 'mobile.extension.authentication_required',
defaultMessage: 'Authentication required: Please first login using the app.'
})}
</Text>
</View>
);
const loginNeeded = formatMessage({
id: 'mobile.extension.authentication_required',
defaultMessage: 'Authentication required: Please first login using the app.'
});
return this.renderErrorMessage(loginNeeded);
}
}

View file

@ -7,14 +7,18 @@ import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels'
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {getAllowedServerMaxFileSize} from 'app/utils/file';
import ExtensionPost from './extension_post';
function mapStateToProps(state) {
const {token, url} = state.entities.general.credentials;
const {config, credentials} = state.entities.general;
const {token, url} = credentials;
return {
channelId: getCurrentChannelId(state),
currentUserId: getCurrentUserId(state),
maxFileSize: getAllowedServerMaxFileSize(config),
teamId: getCurrentTeamId(state),
token,
url

View file

@ -24,7 +24,7 @@ import {Client4} from 'mattermost-redux/client';
import {getFormattedFileSize, lookupMimeType} from 'mattermost-redux/utils/file_utils';
import mattermostBucket from 'app/mattermost_bucket';
import {generateId} from 'app/utils/file';
import {generateId, getAllowedServerMaxFileSize} from 'app/utils/file';
import {wrapWithPreventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import Config from 'assets/config';
@ -258,7 +258,10 @@ export default class ExtensionPost extends PureComponent {
renderBody = (styles) => {
const {formatMessage} = this.context.intl;
const {authenticated, theme} = this.props;
const {error, sending, totalSize, value} = this.state;
const {entities, error, sending, totalSize, value} = this.state;
const {config} = entities.general;
const serverMaxFileSize = getAllowedServerMaxFileSize(config);
const maxSize = Math.min(MAX_FILE_SIZE, serverMaxFileSize);
if (sending) {
return (
@ -274,14 +277,14 @@ export default class ExtensionPost extends PureComponent {
);
}
if (totalSize >= MAX_FILE_SIZE) {
if (totalSize >= maxSize) {
return (
<View style={styles.unauthenticatedContainer}>
<Text style={styles.unauthenticated}>
{formatMessage({
id: 'mobile.extension.max_file_size',
defaultMessage: 'File attachments shared in Mattermost must be less than 20 Mb.'
})}
defaultMessage: 'File attachments shared in Mattermost must be less than {size}.'
}, {size: getFormattedFileSize({size: maxSize})})}
</Text>
</View>
);