From d0f22b953540943f196af51f4ca26cb77fd561bd Mon Sep 17 00:00:00 2001 From: jczekalski Date: Tue, 18 Jul 2023 17:04:26 +0200 Subject: [PATCH 1/9] rewrite without spinning animation --- src/components/AvatarWithImagePicker.js | 292 +++++++++++------------- 1 file changed, 129 insertions(+), 163 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 86747640784a..a889ccce38a7 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import React from 'react'; +import React, {useCallback, useState} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; @@ -16,7 +16,7 @@ import OfflineWithFeedback from './OfflineWithFeedback'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; import variables from '../styles/variables'; import CONST from '../CONST'; -import SpinningIndicatorAnimation from '../styles/animation/SpinningIndicatorAnimation'; +// import SpinningIndicatorAnimation from '../styles/animation/SpinningIndicatorAnimation'; import Tooltip from './Tooltip'; import stylePropTypes from '../styles/stylePropTypes'; import * as FileUtils from '../libs/fileDownload/FileUtils'; @@ -51,7 +51,7 @@ const propTypes = { }).isRequired, /** Flag to see if image is being uploaded */ - isUploading: PropTypes.bool, + // isUploading: PropTypes.bool, /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), @@ -88,7 +88,7 @@ const defaultProps = { style: [], DefaultAvatar: () => {}, isUsingDefaultAvatar: false, - isUploading: false, + // isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, fallbackIcon: Expensicons.FallbackAvatar, type: CONST.ICON_TYPE_AVATAR, @@ -99,66 +99,39 @@ const defaultProps = { errors: null, }; -class AvatarWithImagePicker extends React.Component { - constructor(props) { - super(props); - this.animation = new SpinningIndicatorAnimation(); - this.hideErrorModal = this.hideErrorModal.bind(this); - this.showErrorModal = this.showErrorModal.bind(this); - this.isValidSize = this.isValidSize.bind(this); - this.showAvatarCropModal = this.showAvatarCropModal.bind(this); - this.hideAvatarCropModal = this.hideAvatarCropModal.bind(this); - this.state = { - isMenuVisible: false, - isErrorModalVisible: false, - errorModalPrompt: '', - errorModalTitle: '', - isAvatarCropModalOpen: false, - imageName: '', - imageUri: '', - imageType: '', - }; - } - - componentDidMount() { - if (!this.props.isUploading) { - return; - } - - this.animation.start(); - } - - componentDidUpdate(prevProps) { - if (!prevProps.isUploading && this.props.isUploading) { - this.animation.start(); - } else if (prevProps.isUploading && !this.props.isUploading) { - this.animation.stop(); - } - } +function AvatarWithImagePicker(props) { + const [isMenuVisible, setIsMenuVisible] = useState(false); + const [isErrorModalVisible, setIsErrorModalVisible] = useState(false); + const [errorModalPrompt, setErrorModalPrompt] = useState(''); + const [errorModalTitle, setErrorModalTitle] = useState(''); + const [isAvatarCropModalOpen, setIsAvatarCropModalOpen] = useState(false); + const [imageName, setImageName] = useState(''); + const [imageUri, setImageUri] = useState(''); + const [imageType, setImageType] = useState(''); - componentWillUnmount() { - this.animation.stop(); - } + const DefaultAvatar = props.DefaultAvatar; + const additionalStyles = _.isArray(props.style) ? props.style : [props.style]; /** * @param {String} title * @param {String} prompt */ - showErrorModal(title, prompt) { - this.setState({isErrorModalVisible: true, errorModalTitle: title, errorModalPrompt: prompt}); - } - - hideErrorModal() { - this.setState({isErrorModalVisible: false}); + function showErrorModal(title, prompt) { + setIsErrorModalVisible(true); + setErrorModalTitle(title); + setErrorModalPrompt(prompt); } + const hideErrorModal = useCallback(() => { + setIsErrorModalVisible(false); + }, []); /** * Check if the attachment extension is allowed. * * @param {Object} image * @returns {Boolean} */ - isValidExtension(image) { + function isValidExtension(image) { const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(image, 'name', '')); return _.contains(CONST.AVATAR_ALLOWED_EXTENSIONS, fileExtension.toLowerCase()); } @@ -169,7 +142,7 @@ class AvatarWithImagePicker extends React.Component { * @param {Object} image * @returns {Boolean} */ - isValidSize(image) { + function isValidSize(image) { return image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; } @@ -179,7 +152,7 @@ class AvatarWithImagePicker extends React.Component { * @param {Object} image * @returns {Promise} */ - isValidResolution(image) { + function isValidResolution(image) { return getImageResolution(image).then( (resolution) => resolution.height >= CONST.AVATAR_MIN_HEIGHT_PX && @@ -194,27 +167,27 @@ class AvatarWithImagePicker extends React.Component { * * @param {Object} image */ - showAvatarCropModal(image) { - if (!this.isValidExtension(image)) { - this.showErrorModal( - this.props.translate('avatarWithImagePicker.imageUploadFailed'), - this.props.translate('avatarWithImagePicker.notAllowedExtension', {allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS}), + function showAvatarCropModal(image) { + if (!isValidExtension(image)) { + showErrorModal( + props.translate('avatarWithImagePicker.imageUploadFailed'), + props.translate('avatarWithImagePicker.notAllowedExtension', {allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS}), ); return; } - if (!this.isValidSize(image)) { - this.showErrorModal( - this.props.translate('avatarWithImagePicker.imageUploadFailed'), - this.props.translate('avatarWithImagePicker.sizeExceeded', {maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024)}), + if (!isValidSize(image)) { + showErrorModal( + props.translate('avatarWithImagePicker.imageUploadFailed'), + props.translate('avatarWithImagePicker.sizeExceeded', {maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024)}), ); return; } - this.isValidResolution(image).then((isValidResolution) => { - if (!isValidResolution) { - this.showErrorModal( - this.props.translate('avatarWithImagePicker.imageUploadFailed'), - this.props.translate('avatarWithImagePicker.resolutionConstraints', { + isValidResolution(image).then((isValid) => { + if (!isValid) { + showErrorModal( + props.translate('avatarWithImagePicker.imageUploadFailed'), + props.translate('avatarWithImagePicker.resolutionConstraints', { minHeightInPx: CONST.AVATAR_MIN_HEIGHT_PX, minWidthInPx: CONST.AVATAR_MIN_WIDTH_PX, maxHeightInPx: CONST.AVATAR_MAX_HEIGHT_PX, @@ -224,18 +197,16 @@ class AvatarWithImagePicker extends React.Component { return; } - this.setState({ - isAvatarCropModalOpen: true, - imageUri: image.uri, - imageName: image.name, - imageType: image.type, - }); + setIsAvatarCropModalOpen(true); + setImageUri(image.uri); + setImageName(image.name); + setImageType(image.type); }); } - hideAvatarCropModal() { - this.setState({isAvatarCropModalOpen: false}); - } + const hideAvatarCropModal = useCallback(() => { + setIsAvatarCropModalOpen(false); + }, []); /** * Create menu items list for avatar menu @@ -243,115 +214,110 @@ class AvatarWithImagePicker extends React.Component { * @param {Function} openPicker * @returns {Array} */ - createMenuItems(openPicker) { + function createMenuItems(openPicker) { const menuItems = [ { icon: Expensicons.Upload, - text: this.props.translate('avatarWithImagePicker.uploadPhoto'), + text: props.translate('avatarWithImagePicker.uploadPhoto'), onSelected: () => { openPicker({ - onPicked: this.showAvatarCropModal, + onPicked: showAvatarCropModal, }); }, }, ]; // If current avatar isn't a default avatar, allow Remove Photo option - if (!this.props.isUsingDefaultAvatar) { + if (!props.isUsingDefaultAvatar) { menuItems.push({ icon: Expensicons.Trashcan, - text: this.props.translate('avatarWithImagePicker.removePhoto'), + text: props.translate('avatarWithImagePicker.removePhoto'), onSelected: () => { - this.props.onImageRemoved(); + props.onImageRemoved(); }, }); } return menuItems; } - render() { - const DefaultAvatar = this.props.DefaultAvatar; - const additionalStyles = _.isArray(this.props.style) ? this.props.style : [this.props.style]; - - return ( - - this.setState({isMenuVisible: true})} - accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} - accessibilityLabel={this.props.translate('avatarWithImagePicker.editImage')} - > - - - - - {this.props.source ? ( - - ) : ( - - )} - - - - - - {({openPicker}) => ( - <> - - - - - - this.setState({isMenuVisible: false})} - onItemSelected={() => this.setState({isMenuVisible: false})} - menuItems={this.createMenuItems(openPicker)} - anchorPosition={this.props.anchorPosition} - anchorAlignment={this.props.anchorAlignment} + return ( + + setIsMenuVisible(true)} + accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} + accessibilityLabel={props.translate('avatarWithImagePicker.editImage')} + > + + + + + {props.source ? ( + - - )} - - - - - - - ); - } + ) : ( + + )} + + + + + + {({openPicker}) => ( + <> + + + + + + setIsMenuVisible(false)} + onItemSelected={() => setIsMenuVisible(false)} + menuItems={createMenuItems(openPicker)} + anchorPosition={props.anchorPosition} + anchorAlignment={props.anchorAlignment} + /> + + )} + + + + + + + ); } AvatarWithImagePicker.propTypes = propTypes; From ced5538b675c00bda6fcf2be4e33493dca0d7ad1 Mon Sep 17 00:00:00 2001 From: jczekalski Date: Wed, 19 Jul 2023 12:38:07 +0200 Subject: [PATCH 2/9] remove unused animation and isUploading prop --- src/components/AvatarWithImagePicker.js | 5 -- src/pages/workspace/WorkspaceSettingsPage.js | 1 - .../animation/SpinningIndicatorAnimation.js | 89 ------------------- 3 files changed, 95 deletions(-) delete mode 100644 src/styles/animation/SpinningIndicatorAnimation.js diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index a889ccce38a7..42ca803353fb 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -16,7 +16,6 @@ import OfflineWithFeedback from './OfflineWithFeedback'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; import variables from '../styles/variables'; import CONST from '../CONST'; -// import SpinningIndicatorAnimation from '../styles/animation/SpinningIndicatorAnimation'; import Tooltip from './Tooltip'; import stylePropTypes from '../styles/stylePropTypes'; import * as FileUtils from '../libs/fileDownload/FileUtils'; @@ -50,9 +49,6 @@ const propTypes = { left: PropTypes.number, }).isRequired, - /** Flag to see if image is being uploaded */ - // isUploading: PropTypes.bool, - /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), @@ -88,7 +84,6 @@ const defaultProps = { style: [], DefaultAvatar: () => {}, isUsingDefaultAvatar: false, - // isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, fallbackIcon: Expensicons.FallbackAvatar, type: CONST.ICON_TYPE_AVATAR, diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 50875a17b735..ff65dd85c01b 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -99,7 +99,6 @@ function WorkspaceSettingsPage(props) { enabledWhenOffline > ( diff --git a/src/styles/animation/SpinningIndicatorAnimation.js b/src/styles/animation/SpinningIndicatorAnimation.js deleted file mode 100644 index 8e7fd0277221..000000000000 --- a/src/styles/animation/SpinningIndicatorAnimation.js +++ /dev/null @@ -1,89 +0,0 @@ -import {Animated, Easing} from 'react-native'; -import useNativeDriver from '../../libs/useNativeDriver'; - -class SpinningIndicatorAnimation { - constructor() { - this.rotate = new Animated.Value(0); - this.scale = new Animated.Value(1); - this.startRotation = this.startRotation.bind(this); - this.start = this.start.bind(this); - this.stop = this.stop.bind(this); - this.getSyncingStyles = this.getSyncingStyles.bind(this); - } - - /** - * Rotation animation for indicator in a loop - * - * @memberof AvatarWithImagePicker - */ - startRotation() { - this.rotate.setValue(0); - Animated.loop( - Animated.timing(this.rotate, { - toValue: 1, - duration: 2000, - easing: Easing.linear, - isInteraction: false, - - // Animated.loop does not work with `useNativeDriver: true` on Web - useNativeDriver, - }), - ).start(); - } - - /** - * Start Animation for Indicator - * - * @memberof AvatarWithImagePicker - */ - start() { - this.startRotation(); - Animated.spring(this.scale, { - toValue: 1.666, - tension: 1, - isInteraction: false, - useNativeDriver: true, - }).start(); - } - - /** - * Stop Animation for Indicator - * - * @memberof AvatarWithImagePicker - */ - stop() { - Animated.spring(this.scale, { - toValue: 1, - tension: 1, - isInteraction: false, - useNativeDriver: true, - }).start(() => { - this.rotate.resetAnimation(); - this.scale.resetAnimation(); - this.rotate.setValue(0); - }); - } - - /** - * Get Indicator Styles while animating - * - * @returns {Object} - */ - getSyncingStyles() { - return { - transform: [ - { - rotate: this.rotate.interpolate({ - inputRange: [0, 1], - outputRange: ['0deg', '-360deg'], - }), - }, - { - scale: this.scale, - }, - ], - }; - } -} - -export default SpinningIndicatorAnimation; From befc9c1fc6e57a5b9f234209a5f250275b13221f Mon Sep 17 00:00:00 2001 From: jczekalski Date: Wed, 19 Jul 2023 13:51:48 +0200 Subject: [PATCH 3/9] const instead of function --- src/components/AvatarWithImagePicker.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 42ca803353fb..eb090da52e22 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -111,11 +111,11 @@ function AvatarWithImagePicker(props) { * @param {String} title * @param {String} prompt */ - function showErrorModal(title, prompt) { + const showErrorModal = (title, prompt) => { setIsErrorModalVisible(true); setErrorModalTitle(title); setErrorModalPrompt(prompt); - } + }; const hideErrorModal = useCallback(() => { setIsErrorModalVisible(false); @@ -126,10 +126,10 @@ function AvatarWithImagePicker(props) { * @param {Object} image * @returns {Boolean} */ - function isValidExtension(image) { + const isValidExtension = (image) => { const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(image, 'name', '')); return _.contains(CONST.AVATAR_ALLOWED_EXTENSIONS, fileExtension.toLowerCase()); - } + }; /** * Check if the attachment size is less than allowed size. @@ -137,9 +137,7 @@ function AvatarWithImagePicker(props) { * @param {Object} image * @returns {Boolean} */ - function isValidSize(image) { - return image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; - } + const isValidSize = (image) => image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; /** * Check if the attachment resolution matches constraints. @@ -147,22 +145,21 @@ function AvatarWithImagePicker(props) { * @param {Object} image * @returns {Promise} */ - function isValidResolution(image) { - return getImageResolution(image).then( + const isValidResolution = (image) => + getImageResolution(image).then( (resolution) => resolution.height >= CONST.AVATAR_MIN_HEIGHT_PX && resolution.width >= CONST.AVATAR_MIN_WIDTH_PX && resolution.height <= CONST.AVATAR_MAX_HEIGHT_PX && resolution.width <= CONST.AVATAR_MAX_WIDTH_PX, ); - } /** * Validates if an image has a valid resolution and opens an avatar crop modal * * @param {Object} image */ - function showAvatarCropModal(image) { + const showAvatarCropModal = (image) => { if (!isValidExtension(image)) { showErrorModal( props.translate('avatarWithImagePicker.imageUploadFailed'), @@ -197,7 +194,7 @@ function AvatarWithImagePicker(props) { setImageName(image.name); setImageType(image.type); }); - } + }; const hideAvatarCropModal = useCallback(() => { setIsAvatarCropModalOpen(false); @@ -209,7 +206,7 @@ function AvatarWithImagePicker(props) { * @param {Function} openPicker * @returns {Array} */ - function createMenuItems(openPicker) { + const createMenuItems = (openPicker) => { const menuItems = [ { icon: Expensicons.Upload, @@ -233,7 +230,7 @@ function AvatarWithImagePicker(props) { }); } return menuItems; - } + }; return ( From e32a9fc29925f23c35c6affd4cb66a280cba0895 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 8 Aug 2023 16:21:42 +0200 Subject: [PATCH 4/9] Small improvements --- src/components/AvatarWithImagePicker.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 5bf5b8656a41..9dcf25c1f64d 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import React, {useCallback, useState} from 'react'; +import React, {useCallback, useState, useRef} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; @@ -50,11 +50,11 @@ const propTypes = { left: PropTypes.number, }).isRequired, - /** The anchor alignment of the menu */ + /** Where the popover should be positioned relative to the anchor points. */ anchorAlignment: PropTypes.shape({ - horizontal: PropTypes.number, - vertical: PropTypes.number, - }).isRequired, + horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), + vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), + }), /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), From a6a12476dda583df383579f53442dbad45498d99 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 8 Aug 2023 16:32:47 +0200 Subject: [PATCH 5/9] Remove default props --- src/components/AvatarWithImagePicker.js | 48 ++++++++----------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 9dcf25c1f64d..8d7e7324c1a6 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -54,7 +54,7 @@ const propTypes = { anchorAlignment: PropTypes.shape({ horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), - }), + }).isRequired, /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), @@ -82,40 +82,23 @@ const propTypes = { errors: PropTypes.object, }; -const defaultProps = { - source: '', - onImageSelected: () => {}, - onImageRemoved: () => {}, - style: [], - DefaultAvatar: () => {}, - isUsingDefaultAvatar: false, - size: CONST.AVATAR_SIZE.DEFAULT, - fallbackIcon: Expensicons.FallbackAvatar, - type: CONST.ICON_TYPE_AVATAR, - editorMaskImage: undefined, - errorRowStyles: [], - onErrorClose: () => {}, - pendingAction: null, - errors: null, -}; - function AvatarWithImagePicker({ + source = '', + onImageSelected = () => {}, + onImageRemoved = () => {}, + style = [], + DefaultAvatar = () => {}, + isUsingDefaultAvatar = false, + size = CONST.AVATAR_SIZE.DEFAULT, + fallbackIcon = Expensicons.FallbackAvatar, + type = CONST.ICON_TYPE_AVATAR, + editorMaskImage = undefined, + errorRowStyles = [], + onErrorClose = () => {}, + pendingAction = null, + errors = null, anchorPosition, anchorAlignment, - DefaultAvatar, - editorMaskImage, - errors, - fallbackIcon, - isUsingDefaultAvatar, - pendingAction, - size, - source, - style, - type, - errorRowStyles, - onImageRemoved, - onImageSelected, - onErrorClose, }) { const {translate} = useLocalize(); @@ -336,6 +319,5 @@ function AvatarWithImagePicker({ } AvatarWithImagePicker.propTypes = propTypes; -AvatarWithImagePicker.defaultProps = defaultProps; export default AvatarWithImagePicker; From e17d3ef3709d21a8329c28bbe1a9aa2ba5faa221 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 8 Aug 2023 16:33:57 +0200 Subject: [PATCH 6/9] Revert "Remove default props" This reverts commit a6a12476dda583df383579f53442dbad45498d99. --- src/components/AvatarWithImagePicker.js | 48 +++++++++++++++++-------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 8d7e7324c1a6..9dcf25c1f64d 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -54,7 +54,7 @@ const propTypes = { anchorAlignment: PropTypes.shape({ horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), - }).isRequired, + }), /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), @@ -82,23 +82,40 @@ const propTypes = { errors: PropTypes.object, }; +const defaultProps = { + source: '', + onImageSelected: () => {}, + onImageRemoved: () => {}, + style: [], + DefaultAvatar: () => {}, + isUsingDefaultAvatar: false, + size: CONST.AVATAR_SIZE.DEFAULT, + fallbackIcon: Expensicons.FallbackAvatar, + type: CONST.ICON_TYPE_AVATAR, + editorMaskImage: undefined, + errorRowStyles: [], + onErrorClose: () => {}, + pendingAction: null, + errors: null, +}; + function AvatarWithImagePicker({ - source = '', - onImageSelected = () => {}, - onImageRemoved = () => {}, - style = [], - DefaultAvatar = () => {}, - isUsingDefaultAvatar = false, - size = CONST.AVATAR_SIZE.DEFAULT, - fallbackIcon = Expensicons.FallbackAvatar, - type = CONST.ICON_TYPE_AVATAR, - editorMaskImage = undefined, - errorRowStyles = [], - onErrorClose = () => {}, - pendingAction = null, - errors = null, anchorPosition, anchorAlignment, + DefaultAvatar, + editorMaskImage, + errors, + fallbackIcon, + isUsingDefaultAvatar, + pendingAction, + size, + source, + style, + type, + errorRowStyles, + onImageRemoved, + onImageSelected, + onErrorClose, }) { const {translate} = useLocalize(); @@ -319,5 +336,6 @@ function AvatarWithImagePicker({ } AvatarWithImagePicker.propTypes = propTypes; +AvatarWithImagePicker.defaultProps = defaultProps; export default AvatarWithImagePicker; From 37a3287398c71b044f066b970877504e6fa78e67 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 8 Aug 2023 16:34:17 +0200 Subject: [PATCH 7/9] Make anchorAlignment required --- src/components/AvatarWithImagePicker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 9dcf25c1f64d..245b5930708f 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -54,7 +54,7 @@ const propTypes = { anchorAlignment: PropTypes.shape({ horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), - }), + }).isRequired, /** Size of Indicator */ size: PropTypes.oneOf([CONST.AVATAR_SIZE.LARGE, CONST.AVATAR_SIZE.DEFAULT]), From 3b2264cb4b332ba660ce65fce5312069cf7203f1 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 9 Aug 2023 10:13:13 +0200 Subject: [PATCH 8/9] Fix lint issues --- src/components/AvatarWithImagePicker.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 245b5930708f..c8e0b2ed97b8 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -133,11 +133,11 @@ function AvatarWithImagePicker({ /** * @param {String} error - * @param {Object} phraseParam + * @param {Object} phrase */ - const setError = (error, phraseParam) => { + const setError = (error, phrase) => { setValidationError(error); - setPhraseParam(phraseParam); + setPhraseParam(phrase); }; /** @@ -189,8 +189,8 @@ function AvatarWithImagePicker({ return; } - isValidResolution(image).then((isValidResolution) => { - if (!isValidResolution) { + isValidResolution(image).then((isValid) => { + if (!isValid) { setError('avatarWithImagePicker.resolutionConstraints', { minHeightInPx: CONST.AVATAR_MIN_HEIGHT_PX, minWidthInPx: CONST.AVATAR_MIN_WIDTH_PX, From c82c7194ac021a93181e48ce4729e8565a921295 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 9 Aug 2023 18:00:44 +0200 Subject: [PATCH 9/9] Add display name --- src/components/AvatarWithImagePicker.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index c8e0b2ed97b8..e3123210277c 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -337,5 +337,6 @@ function AvatarWithImagePicker({ AvatarWithImagePicker.propTypes = propTypes; AvatarWithImagePicker.defaultProps = defaultProps; +AvatarWithImagePicker.displayName = 'AvatarWithImagePicker'; export default AvatarWithImagePicker;