diff --git a/src/CONST.js b/src/CONST.js index fd9d9e473c5..f6454ddcc0f 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -4,6 +4,7 @@ const NEW_EXPENSIFY_URL = 'https://new.expensify.com'; const CONST = { // 50 megabytes in bytes API_MAX_ATTACHMENT_SIZE: 52428800, + AVATAR_MAX_ATTACHMENT_SIZE: 3145728, APP_DOWNLOAD_LINKS: { ANDROID: 'https://play.google.com/store/apps/details?id=com.expensify.chat', IOS: 'https://apps.apple.com/us/app/expensify-cash/id1530278510', diff --git a/src/components/AttachmentPicker/index.native.js b/src/components/AttachmentPicker/index.native.js index 0ad9a6e6bd3..bba7a600579 100644 --- a/src/components/AttachmentPicker/index.native.js +++ b/src/components/AttachmentPicker/index.native.js @@ -65,7 +65,7 @@ function getDataForUpload(fileData) { name: fileData.fileName || fileData.name || 'chat_attachment', type: fileData.type, uri: fileData.uri, - size: fileData.size, + size: fileData.fileSize || fileData.size, }; } diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index bae0c55a46f..9bbdd7064e3 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -4,6 +4,7 @@ import { Pressable, View, Animated, StyleSheet, } from 'react-native'; import PropTypes from 'prop-types'; +import lodashGet from 'lodash/get'; import Avatar from './Avatar'; import Icon from './Icon'; import PopoverMenu from './PopoverMenu'; @@ -13,6 +14,7 @@ import { import styles from '../styles/styles'; import themeColors from '../styles/themes/default'; import AttachmentPicker from './AttachmentPicker'; +import ConfirmModal from './ConfirmModal'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; import variables from '../styles/variables'; import CONST from '../CONST'; @@ -51,7 +53,7 @@ const propTypes = { isUploading: PropTypes.bool, /** Size of Indicator */ - size: PropTypes.string, + size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), ...withLocalizePropTypes, }; @@ -71,8 +73,11 @@ class AvatarWithImagePicker extends React.Component { constructor(props) { super(props); this.animation = new SpinningIndicatorAnimation(); + this.setUploadLimitModalVisibility = this.setUploadLimitModalVisibility.bind(this); + this.isValidSize = this.isValidSize.bind(this); this.state = { isMenuVisible: false, + isMaxUploadSizeModalOpen: false, }; } @@ -94,6 +99,23 @@ class AvatarWithImagePicker extends React.Component { this.animation.stop(); } + /** + * Toggle max upload limit modal's visibility + * @param {Boolean} isVisible + */ + setUploadLimitModalVisibility(isVisible) { + this.setState({isMaxUploadSizeModalOpen: isVisible}); + } + + /** + * Check if the attachment size is less than allowed size. + * @param {Object} image + * @returns {Boolean} + */ + isValidSize(image) { + return image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; + } + /** * Create menu items list for avatar menu * @@ -107,7 +129,13 @@ class AvatarWithImagePicker extends React.Component { text: this.props.translate('avatarWithImagePicker.uploadPhoto'), onSelected: () => { openPicker({ - onPicked: this.props.onImageSelected, + onPicked: (image) => { + if (!this.isValidSize(image)) { + this.setUploadLimitModalVisibility(true); + return; + } + this.props.onImageSelected(image); + }, }); }, }, @@ -203,6 +231,15 @@ class AvatarWithImagePicker extends React.Component { + this.setUploadLimitModalVisibility(false)} + onCancel={() => this.setUploadLimitModalVisibility(false)} + isVisible={this.state.isMaxUploadSizeModalOpen} + prompt={this.props.translate('avatarWithImagePicker.sizeExceeded', {maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024)})} + confirmText={this.props.translate('common.close')} + shouldShowCancelButton={false} + /> ); } diff --git a/src/languages/en.js b/src/languages/en.js index 5054ff760f7..a2dc23741ca 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -216,6 +216,8 @@ export default { uploadPhoto: 'Upload photo', removePhoto: 'Remove photo', editImage: 'Edit photo', + imageUploadFailed: 'Image upload failed', + sizeExceeded: ({maxUploadSizeInMB}) => `The selected image exceeds the maximum upload size of ${maxUploadSizeInMB}MB.`, }, profilePage: { profile: 'Profile', diff --git a/src/languages/es.js b/src/languages/es.js index fc26fb8e87c..b6e13a9861c 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -216,6 +216,8 @@ export default { uploadPhoto: 'Subir foto', removePhoto: 'Eliminar foto', editImage: 'Editar foto', + imageUploadFailed: 'Error al cargar la imagen', + sizeExceeded: ({maxUploadSizeInMB}) => `La imagen supera el tamaño máximo de ${maxUploadSizeInMB}MB.`, }, profilePage: { profile: 'Perfil',