From c59b47d41d31d93751ec6c32f0f90f46b77b4c19 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 28 Sep 2023 14:59:58 +0200 Subject: [PATCH 01/65] updated to function componenet --- ios/Podfile.lock | 6 +- src/components/AvatarWithImagePicker.js | 289 ++++++++++-------------- 2 files changed, 123 insertions(+), 172 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ba53d939e46c..747efb5f2fa7 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -783,7 +783,7 @@ PODS: - React-Core - RNReactNativeHapticFeedback (1.14.0): - React-Core - - RNReanimated (3.5.4): + - RNReanimated (3.4.0): - DoubleConversion - FBLazyVector - glog @@ -1298,7 +1298,7 @@ SPEC CHECKSUMS: rnmapbox-maps: 6f638ec002aa6e906a6f766d69cd45f968d98e64 RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c - RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 + RNReanimated: 020859659f64be2d30849a1fe88c821a7c3e0cbf RNScreens: d037903436160a4b039d32606668350d2a808806 RNSVG: ed492aaf3af9ca01bc945f7a149d76d62e73ec82 SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d @@ -1311,4 +1311,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 2daf34c870819a933f3fefe426801d54b2ff2a14 -COCOAPODS: 1.12.1 +COCOAPODS: 1.13.0 diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index a44d1841bbb6..4459ad892877 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,6 +1,6 @@ import _ from 'underscore'; -import React from 'react'; -import {View} from 'react-native'; +import React, { useState, useRef, useEffect } from 'react'; +import { View } from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import Avatar from './Avatar'; @@ -116,166 +116,118 @@ const defaultProps = { originalFileName: '', }; -class AvatarWithImagePicker extends React.Component { - constructor(props) { - super(props); - this.animation = new SpinningIndicatorAnimation(); - this.setError = this.setError.bind(this); - this.isValidSize = this.isValidSize.bind(this); - this.showAvatarCropModal = this.showAvatarCropModal.bind(this); - this.hideAvatarCropModal = this.hideAvatarCropModal.bind(this); - this.state = { - isMenuVisible: false, - validationError: null, - phraseParam: {}, - isAvatarCropModalOpen: false, - imageName: '', - imageUri: '', - imageType: '', +function AvatarWithImagePicker(props) { + const animation = new SpinningIndicatorAnimation(); + const [isMenuVisible, setIsMenuVisible] = useState(false); + const [validationError, setValidationError] = useState(null); + const [phraseParam, setPhraseParam] = useState({}); + const [isAvatarCropModalOpen, setIsAvatarCropModalOpen] = useState(false); + const [imageName, setImageName] = useState(''); + const [imageUri, setImageUri] = useState(''); + const [imageType, setImageType] = useState(''); + const anchorRef = useRef(); + + useEffect(() => { + if (props.isUploading) { + animation.start(); + } + + return () => { + animation.stop(); }; - this.anchorRef = React.createRef(); - } + }, [props.isUploading]); - componentDidMount() { - if (!this.props.isUploading) { - return; + useEffect(() => { + if (!props.isFocused) { + setError(null, {}); } + }, [props.isFocused]); - this.animation.start(); - } + const setError = (error, phraseParam) => { + setValidationError(error); + setPhraseParam(phraseParam); + }; - componentDidUpdate(prevProps) { - if (!prevProps.isFocused && this.props.isFocused) { - this.setError(null, {}); - } - if (!prevProps.isUploading && this.props.isUploading) { - this.animation.start(); - } else if (prevProps.isUploading && !this.props.isUploading) { - this.animation.stop(); - } - } - - componentWillUnmount() { - this.animation.stop(); - } - - /** - * @param {String} error - * @param {Object} phraseParam - */ - setError(error, phraseParam) { - this.setState({validationError: error, phraseParam}); - } - - /** - * Check if the attachment extension is allowed. - * - * @param {Object} image - * @returns {Boolean} - */ - isValidExtension(image) { - const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(image, 'name', '')); + 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. - * - * @param {Object} image - * @returns {Boolean} - */ - isValidSize(image) { + }; + + const isValidSize = (image) => { return image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; - } - - /** - * Check if the attachment resolution matches constraints. - * - * @param {Object} image - * @returns {Promise} - */ - isValidResolution(image) { - return 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 - */ - showAvatarCropModal(image) { - if (!this.isValidExtension(image)) { - this.setError('avatarWithImagePicker.notAllowedExtension', {allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS}); + }; + + const isValidResolution = async (image) => { + const resolution = await getImageResolution(image); + return 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; + }; + + const showAvatarCropModal = async (image) => { + if (!isValidExtension(image)) { + setError('avatarWithImagePicker.notAllowedExtension', { allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS }); return; } - if (!this.isValidSize(image)) { - this.setError('avatarWithImagePicker.sizeExceeded', {maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024)}); + if (!isValidSize(image)) { + setError('avatarWithImagePicker.sizeExceeded', { maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024) }); return; } - this.isValidResolution(image).then((isValidResolution) => { - if (!isValidResolution) { - this.setError('avatarWithImagePicker.resolutionConstraints', { - minHeightInPx: CONST.AVATAR_MIN_HEIGHT_PX, - minWidthInPx: CONST.AVATAR_MIN_WIDTH_PX, - maxHeightInPx: CONST.AVATAR_MAX_HEIGHT_PX, - maxWidthInPx: CONST.AVATAR_MAX_WIDTH_PX, - }); - return; - } - - this.setState({ - isAvatarCropModalOpen: true, - validationError: null, - phraseParam: {}, - isMenuVisible: false, - imageUri: image.uri, - imageName: image.name, - imageType: image.type, + const isValidRes = await isValidResolution(image); + if (!isValidRes) { + setError('avatarWithImagePicker.resolutionConstraints', { + minHeightInPx: CONST.AVATAR_MIN_HEIGHT_PX, + minWidthInPx: CONST.AVATAR_MIN_WIDTH_PX, + maxHeightInPx: CONST.AVATAR_MAX_HEIGHT_PX, + maxWidthInPx: CONST.AVATAR_MAX_WIDTH_PX, }); - }); - } - - hideAvatarCropModal() { - this.setState({isAvatarCropModalOpen: false}); - } - - render() { - const DefaultAvatar = this.props.DefaultAvatar; - const additionalStyles = _.isArray(this.props.style) ? this.props.style : [this.props.style]; + return; + } - return ( - - + setIsAvatarCropModalOpen(true); + setValidationError(null); + setPhraseParam({}); + setIsMenuVisible(false); + setImageUri(image.uri); + setImageName(image.name); + setImageType(image.type); + }; + + const hideAvatarCropModal = () => { + setIsAvatarCropModalOpen(false); + }; + + const DefaultAvatar = props.DefaultAvatar; + const additionalStyles = _.isArray(props.style) ? props.style : [props.style]; + + return ( + + - + this.setState((prev) => ({isMenuVisible: !prev.isMenuVisible}))} + onPress={() => setIsMenuVisible(prev => !prev)} accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} - accessibilityLabel={this.props.translate('avatarWithImagePicker.editImage')} - disabled={this.state.isAvatarCropModalOpen} - ref={this.anchorRef} + accessibilityLabel={props.translate('avatarWithImagePicker.editImage')} + disabled={isAvatarCropModalOpen} + ref={anchorRef} > - {this.props.source ? ( + {props.source ? ( ) : ( @@ -293,10 +245,10 @@ class AvatarWithImagePicker extends React.Component { {({show}) => ( @@ -304,55 +256,55 @@ class AvatarWithImagePicker extends React.Component { const menuItems = [ { icon: Expensicons.Upload, - text: this.props.translate('avatarWithImagePicker.uploadPhoto'), + text: props.translate('avatarWithImagePicker.uploadPhoto'), onSelected: () => { if (Browser.isSafari()) { return; } 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.setError(null, {}); - this.props.onImageRemoved(); + setError(null, {}); + props.onImageRemoved(); }, }); menuItems.push({ icon: Expensicons.Eye, - text: this.props.translate('avatarWithImagePicker.viewPhoto'), + text: props.translate('avatarWithImagePicker.viewPhoto'), onSelected: () => show(), }); } return ( this.setState({isMenuVisible: false})} + isVisible={isMenuVisible} + onClose={() => setIsMenuVisible(false)} onItemSelected={(item, index) => { - this.setState({isMenuVisible: false}); + setIsMenuVisible(false); // In order for the file picker to open dynamically, the click // function must be called from within a event handler that was initiated // by the user on Safari. if (index === 0 && Browser.isSafari()) { openPicker({ - onPicked: this.showAvatarCropModal, + onPicked: showAvatarCropModal, }); } }} menuItems={menuItems} - anchorPosition={this.props.anchorPosition} + anchorPosition={props.anchorPosition} withoutOverlay - anchorRef={this.anchorRef} - anchorAlignment={this.props.anchorAlignment} + anchorRef={anchorRef} + anchorAlignment={props.anchorAlignment} /> ); }} @@ -360,25 +312,24 @@ class AvatarWithImagePicker extends React.Component { )} - {this.state.validationError && ( + {validationError && ( )} - - ); - } + + ); } AvatarWithImagePicker.propTypes = propTypes; From 453eeedae5b2ff00209ff911331e6c698871ad18 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Tue, 3 Oct 2023 11:37:16 +0200 Subject: [PATCH 02/65] updates --- src/components/AvatarWithImagePicker.js | 93 +++++++++++++++---------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 4459ad892877..f20c4f4cfb55 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,6 +1,6 @@ import _ from 'underscore'; -import React, { useState, useRef, useEffect } from 'react'; -import { View } from 'react-native'; +import React, {useState, useRef, useEffect} from 'react'; +import {View} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import Avatar from './Avatar'; @@ -116,8 +116,31 @@ const defaultProps = { originalFileName: '', }; -function AvatarWithImagePicker(props) { - const animation = new SpinningIndicatorAnimation(); +function AvatarWithImagePicker({ + isUploading, + isFocused, + DefaultAvatar, + style, + pendingAction, + errors, + errorRowStyles, + onErrorClose, + translate, + source, + fallbackIcon, + size, + type, + headerTitle, + previewSource, + originalFileName, + isUsingDefaultAvatar, + onImageRemoved, + anchorPosition, + anchorAlignment, + onImageSelected, + editorMaskImage }) { + + const animation = useRef(new SpinningIndicatorAnimation()).current; const [isMenuVisible, setIsMenuVisible] = useState(false); const [validationError, setValidationError] = useState(null); const [phraseParam, setPhraseParam] = useState({}); @@ -128,20 +151,21 @@ function AvatarWithImagePicker(props) { const anchorRef = useRef(); useEffect(() => { - if (props.isUploading) { + if (isUploading) { animation.start(); } return () => { animation.stop(); }; - }, [props.isUploading]); + }, [isUploading]); useEffect(() => { - if (!props.isFocused) { + // check if the component is no longer focused, then reset the error. + if (!isFocused) { setError(null, {}); } - }, [props.isFocused]); + }, [isFocused]); const setError = (error, phraseParam) => { setValidationError(error); @@ -199,35 +223,34 @@ function AvatarWithImagePicker(props) { setIsAvatarCropModalOpen(false); }; - const DefaultAvatar = props.DefaultAvatar; - const additionalStyles = _.isArray(props.style) ? props.style : [props.style]; + const additionalStyles = _.isArray(style) ? style : [style]; return ( - + setIsMenuVisible(prev => !prev)} accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} - accessibilityLabel={props.translate('avatarWithImagePicker.editImage')} + accessibilityLabel={translate('avatarWithImagePicker.editImage')} disabled={isAvatarCropModalOpen} ref={anchorRef} > - {props.source ? ( + {source ? ( ) : ( @@ -245,10 +268,10 @@ function AvatarWithImagePicker(props) { {({show}) => ( @@ -256,7 +279,7 @@ function AvatarWithImagePicker(props) { const menuItems = [ { icon: Expensicons.Upload, - text: props.translate('avatarWithImagePicker.uploadPhoto'), + text: translate('avatarWithImagePicker.uploadPhoto'), onSelected: () => { if (Browser.isSafari()) { return; @@ -269,19 +292,19 @@ function AvatarWithImagePicker(props) { ]; // If current avatar isn't a default avatar, allow Remove Photo option - if (!props.isUsingDefaultAvatar) { + if (!isUsingDefaultAvatar) { menuItems.push({ icon: Expensicons.Trashcan, - text: props.translate('avatarWithImagePicker.removePhoto'), + text: translate('avatarWithImagePicker.removePhoto'), onSelected: () => { setError(null, {}); - props.onImageRemoved(); + onImageRemoved(); }, }); menuItems.push({ icon: Expensicons.Eye, - text: props.translate('avatarWithImagePicker.viewPhoto'), + text: translate('avatarWithImagePicker.viewPhoto'), onSelected: () => show(), }); } @@ -301,10 +324,10 @@ function AvatarWithImagePicker(props) { } }} menuItems={menuItems} - anchorPosition={props.anchorPosition} + anchorPosition={anchorPosition} withoutOverlay anchorRef={anchorRef} - anchorAlignment={props.anchorAlignment} + anchorAlignment={anchorAlignment} /> ); }} @@ -315,18 +338,18 @@ function AvatarWithImagePicker(props) { {validationError && ( )} ); From 1b2a6e24df4a6623c2d4c23f738ba65be11890d6 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Tue, 3 Oct 2023 11:54:44 +0200 Subject: [PATCH 03/65] comments --- src/components/AvatarWithImagePicker.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index f20c4f4cfb55..7a0156cb89ee 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -172,15 +172,33 @@ function AvatarWithImagePicker({ setPhraseParam(phraseParam); }; + /** + * Check if the attachment extension is allowed. + * + * @param {Object} image + * @returns {Boolean} + */ 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. + * + * @param {Object} image + * @returns {Boolean} + */ const isValidSize = (image) => { return image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; }; + /** + * Check if the attachment resolution matches constraints. + * + * @param {Object} image + * @returns {Promise} + */ const isValidResolution = async (image) => { const resolution = await getImageResolution(image); return resolution.height >= CONST.AVATAR_MIN_HEIGHT_PX && @@ -189,6 +207,11 @@ function AvatarWithImagePicker({ resolution.width <= CONST.AVATAR_MAX_WIDTH_PX; }; + /** + * Validates if an image has a valid resolution and opens an avatar crop modal + * + * @param {Object} image + */ const showAvatarCropModal = async (image) => { if (!isValidExtension(image)) { setError('avatarWithImagePicker.notAllowedExtension', { allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS }); From 559c7ae8e087c5d4661cba4a771f7161a198e3f6 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Tue, 3 Oct 2023 14:29:22 +0200 Subject: [PATCH 04/65] pr updates --- src/components/AvatarWithImagePicker.js | 114 +++++++++++++++--------- 1 file changed, 70 insertions(+), 44 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 7a0156cb89ee..55767268162c 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -12,7 +12,7 @@ import themeColors from '../styles/themes/default'; import AttachmentPicker from './AttachmentPicker'; import AvatarCropModal from './AvatarCropModal/AvatarCropModal'; import OfflineWithFeedback from './OfflineWithFeedback'; -import withLocalize, {withLocalizePropTypes} from './withLocalize'; +import useLocalize from '../hooks/useLocalize'; import variables from '../styles/variables'; import CONST from '../CONST'; import SpinningIndicatorAnimation from '../styles/animation/SpinningIndicatorAnimation'; @@ -91,7 +91,6 @@ const propTypes = { /** File name of the avatar */ originalFileName: PropTypes.string, - ...withLocalizePropTypes, ...withNavigationFocusPropTypes, }; @@ -114,6 +113,7 @@ const defaultProps = { headerTitle: '', previewSource: '', originalFileName: '', + displayName: `AvatarWithImagePicker`, }; function AvatarWithImagePicker({ @@ -125,7 +125,6 @@ function AvatarWithImagePicker({ errors, errorRowStyles, onErrorClose, - translate, source, fallbackIcon, size, @@ -142,13 +141,18 @@ function AvatarWithImagePicker({ const animation = useRef(new SpinningIndicatorAnimation()).current; const [isMenuVisible, setIsMenuVisible] = useState(false); - const [validationError, setValidationError] = useState(null); - const [phraseParam, setPhraseParam] = useState({}); + const [errorData, setErrorData] = useState({ + validationError: null, + phraseParam: {}, + }); const [isAvatarCropModalOpen, setIsAvatarCropModalOpen] = useState(false); - const [imageName, setImageName] = useState(''); - const [imageUri, setImageUri] = useState(''); - const [imageType, setImageType] = useState(''); + const [imageData, setImageData] = useState({ + uri: '', + name: '', + type: '' + }); const anchorRef = useRef(); + const {translate} = useLocalize(); useEffect(() => { if (isUploading) { @@ -167,9 +171,15 @@ function AvatarWithImagePicker({ } }, [isFocused]); + /** + * @param {String} error + * @param {Object} phraseParam + */ const setError = (error, phraseParam) => { - setValidationError(error); - setPhraseParam(phraseParam); + setErrorData({ + validationError: error, + phraseParam: phraseParam, + }); }; /** @@ -212,35 +222,51 @@ function AvatarWithImagePicker({ * * @param {Object} image */ - const showAvatarCropModal = async (image) => { - if (!isValidExtension(image)) { - setError('avatarWithImagePicker.notAllowedExtension', { allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS }); - return; - } - if (!isValidSize(image)) { - setError('avatarWithImagePicker.sizeExceeded', { maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024) }); - return; - } - - const isValidRes = await isValidResolution(image); - if (!isValidRes) { - setError('avatarWithImagePicker.resolutionConstraints', { - minHeightInPx: CONST.AVATAR_MIN_HEIGHT_PX, - minWidthInPx: CONST.AVATAR_MIN_WIDTH_PX, - maxHeightInPx: CONST.AVATAR_MAX_HEIGHT_PX, - maxWidthInPx: CONST.AVATAR_MAX_WIDTH_PX, + function showAvatarCropModal(image) { + const handleResolutionValidation = (isValidRes) => { + if (!isValidRes) { + setError('avatarWithImagePicker.resolutionConstraints', { + minHeightInPx: CONST.AVATAR_MIN_HEIGHT_PX, + minWidthInPx: CONST.AVATAR_MIN_WIDTH_PX, + maxHeightInPx: CONST.AVATAR_MAX_HEIGHT_PX, + maxWidthInPx: CONST.AVATAR_MAX_WIDTH_PX, + }); + return; + } + + setIsAvatarCropModalOpen(true); + setError(null, {}); + setIsMenuVisible(false); + setImageData({ + uri: image.uri, + name: image.name, + type: image.type }); - return; - } - - setIsAvatarCropModalOpen(true); - setValidationError(null); - setPhraseParam({}); - setIsMenuVisible(false); - setImageUri(image.uri); - setImageName(image.name); - setImageType(image.type); - }; + }; + + return new Promise((resolve, reject) => { + if (!isValidExtension(image)) { + setError('avatarWithImagePicker.notAllowedExtension', { + allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS + }); + reject(new Error('Invalid extension')); + } + + if (!isValidSize(image)) { + setError('avatarWithImagePicker.sizeExceeded', { + maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024) + }); + reject(new Error('Invalid size')); + } + + resolve(image); + }) + .then(isValidResolution) + .then(handleResolutionValidation) + .catch(err => { + console.error("Error in showAvatarCropModal:", err); + }); + } const hideAvatarCropModal = () => { setIsAvatarCropModalOpen(false); @@ -358,10 +384,10 @@ function AvatarWithImagePicker({ )} - {validationError && ( + {errorData.validationError && ( )} @@ -369,9 +395,9 @@ function AvatarWithImagePicker({ onClose={hideAvatarCropModal} isVisible={isAvatarCropModalOpen} onSave={onImageSelected} - imageUri={imageUri} - imageName={imageName} - imageType={imageType} + imageUri={imageData.uri} + imageName={imageData.name} + imageType={imageData.type} maskImage={editorMaskImage} /> @@ -381,4 +407,4 @@ function AvatarWithImagePicker({ AvatarWithImagePicker.propTypes = propTypes; AvatarWithImagePicker.defaultProps = defaultProps; -export default compose(withLocalize, withNavigationFocus)(AvatarWithImagePicker); +export default withNavigationFocus(AvatarWithImagePicker); \ No newline at end of file From d1bf47c67a2787b8e2ac1d29be584638a74b8223 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 5 Oct 2023 06:37:50 +0200 Subject: [PATCH 05/65] remove podfile.lock --- ios/Podfile.lock | 1314 ---------------------------------------------- 1 file changed, 1314 deletions(-) delete mode 100644 ios/Podfile.lock diff --git a/ios/Podfile.lock b/ios/Podfile.lock deleted file mode 100644 index 747efb5f2fa7..000000000000 --- a/ios/Podfile.lock +++ /dev/null @@ -1,1314 +0,0 @@ -PODS: - - Airship (16.11.3): - - Airship/Automation (= 16.11.3) - - Airship/Basement (= 16.11.3) - - Airship/Core (= 16.11.3) - - Airship/ExtendedActions (= 16.11.3) - - Airship/MessageCenter (= 16.11.3) - - Airship/Automation (16.11.3): - - Airship/Core - - Airship/Basement (16.11.3) - - Airship/Core (16.11.3): - - Airship/Basement - - Airship/ExtendedActions (16.11.3): - - Airship/Core - - Airship/MessageCenter (16.11.3): - - Airship/Core - - Airship/PreferenceCenter (16.11.3): - - Airship/Core - - AirshipFrameworkProxy (2.0.8): - - Airship (= 16.11.3) - - Airship/MessageCenter (= 16.11.3) - - Airship/PreferenceCenter (= 16.11.3) - - AppAuth (1.6.2): - - AppAuth/Core (= 1.6.2) - - AppAuth/ExternalUserAgent (= 1.6.2) - - AppAuth/Core (1.6.2) - - AppAuth/ExternalUserAgent (1.6.2): - - AppAuth/Core - - boost (1.76.0) - - BVLinearGradient (2.8.1): - - React-Core - - CocoaAsyncSocket (7.6.5) - - DoubleConversion (1.1.6) - - FBLazyVector (0.72.4) - - FBReactNativeSpec (0.72.4): - - RCT-Folly (= 2021.07.22.00) - - RCTRequired (= 0.72.4) - - RCTTypeSafety (= 0.72.4) - - React-Core (= 0.72.4) - - React-jsi (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - Firebase/Analytics (8.8.0): - - Firebase/Core - - Firebase/Core (8.8.0): - - Firebase/CoreOnly - - FirebaseAnalytics (~> 8.8.0) - - Firebase/CoreOnly (8.8.0): - - FirebaseCore (= 8.8.0) - - Firebase/Crashlytics (8.8.0): - - Firebase/CoreOnly - - FirebaseCrashlytics (~> 8.8.0) - - Firebase/Performance (8.8.0): - - Firebase/CoreOnly - - FirebasePerformance (~> 8.8.0) - - FirebaseABTesting (8.15.0): - - FirebaseCore (~> 8.0) - - FirebaseAnalytics (8.8.0): - - FirebaseAnalytics/AdIdSupport (= 8.8.0) - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.4) - - GoogleUtilities/MethodSwizzler (~> 7.4) - - GoogleUtilities/Network (~> 7.4) - - "GoogleUtilities/NSData+zlib (~> 7.4)" - - nanopb (~> 2.30908.0) - - FirebaseAnalytics/AdIdSupport (8.8.0): - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) - - GoogleAppMeasurement (= 8.8.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.4) - - GoogleUtilities/MethodSwizzler (~> 7.4) - - GoogleUtilities/Network (~> 7.4) - - "GoogleUtilities/NSData+zlib (~> 7.4)" - - nanopb (~> 2.30908.0) - - FirebaseCore (8.8.0): - - FirebaseCoreDiagnostics (~> 8.0) - - GoogleUtilities/Environment (~> 7.4) - - GoogleUtilities/Logger (~> 7.4) - - FirebaseCoreDiagnostics (8.15.0): - - GoogleDataTransport (~> 9.1) - - GoogleUtilities/Environment (~> 7.7) - - GoogleUtilities/Logger (~> 7.7) - - nanopb (~> 2.30908.0) - - FirebaseCrashlytics (8.8.0): - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) - - GoogleDataTransport (~> 9.0) - - GoogleUtilities/Environment (~> 7.4) - - nanopb (~> 2.30908.0) - - PromisesObjC (< 3.0, >= 1.2) - - FirebaseInstallations (8.15.0): - - FirebaseCore (~> 8.0) - - GoogleUtilities/Environment (~> 7.7) - - GoogleUtilities/UserDefaults (~> 7.7) - - PromisesObjC (< 3.0, >= 1.2) - - FirebasePerformance (8.8.0): - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) - - FirebaseRemoteConfig (~> 8.0) - - GoogleDataTransport (~> 9.0) - - GoogleUtilities/Environment (~> 7.4) - - GoogleUtilities/ISASwizzler (~> 7.4) - - GoogleUtilities/MethodSwizzler (~> 7.4) - - nanopb (~> 2.30908.0) - - FirebaseRemoteConfig (8.15.0): - - FirebaseABTesting (~> 8.0) - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) - - GoogleUtilities/Environment (~> 7.7) - - "GoogleUtilities/NSData+zlib (~> 7.7)" - - Flipper (0.182.0): - - Flipper-Folly (~> 2.6) - - Flipper-Boost-iOSX (1.76.0.1.11) - - Flipper-DoubleConversion (3.2.0.1) - - Flipper-Fmt (7.1.7) - - Flipper-Folly (2.6.10): - - Flipper-Boost-iOSX - - Flipper-DoubleConversion - - Flipper-Fmt (= 7.1.7) - - Flipper-Glog - - libevent (~> 2.1.12) - - OpenSSL-Universal (= 1.1.1100) - - Flipper-Glog (0.5.0.5) - - Flipper-PeerTalk (0.0.4) - - FlipperKit (0.182.0): - - FlipperKit/Core (= 0.182.0) - - FlipperKit/Core (0.182.0): - - Flipper (~> 0.182.0) - - FlipperKit/CppBridge - - FlipperKit/FBCxxFollyDynamicConvert - - FlipperKit/FBDefines - - FlipperKit/FKPortForwarding - - SocketRocket (~> 0.6.0) - - FlipperKit/CppBridge (0.182.0): - - Flipper (~> 0.182.0) - - FlipperKit/FBCxxFollyDynamicConvert (0.182.0): - - Flipper-Folly (~> 2.6) - - FlipperKit/FBDefines (0.182.0) - - FlipperKit/FKPortForwarding (0.182.0): - - CocoaAsyncSocket (~> 7.6) - - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitHighlightOverlay (0.182.0) - - FlipperKit/FlipperKitLayoutHelpers (0.182.0): - - FlipperKit/Core - - FlipperKit/FlipperKitHighlightOverlay - - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutIOSDescriptors (0.182.0): - - FlipperKit/Core - - FlipperKit/FlipperKitHighlightOverlay - - FlipperKit/FlipperKitLayoutHelpers - - YogaKit (~> 1.18) - - FlipperKit/FlipperKitLayoutPlugin (0.182.0): - - FlipperKit/Core - - FlipperKit/FlipperKitHighlightOverlay - - FlipperKit/FlipperKitLayoutHelpers - - FlipperKit/FlipperKitLayoutIOSDescriptors - - FlipperKit/FlipperKitLayoutTextSearchable - - YogaKit (~> 1.18) - - FlipperKit/FlipperKitLayoutTextSearchable (0.182.0) - - FlipperKit/FlipperKitNetworkPlugin (0.182.0): - - FlipperKit/Core - - FlipperKit/FlipperKitReactPlugin (0.182.0): - - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.182.0): - - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.182.0): - - FlipperKit/Core - - FlipperKit/FlipperKitNetworkPlugin - - fmt (6.2.1) - - glog (0.3.5) - - GoogleAppMeasurement (8.8.0): - - GoogleAppMeasurement/AdIdSupport (= 8.8.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.4) - - GoogleUtilities/MethodSwizzler (~> 7.4) - - GoogleUtilities/Network (~> 7.4) - - "GoogleUtilities/NSData+zlib (~> 7.4)" - - nanopb (~> 2.30908.0) - - GoogleAppMeasurement/AdIdSupport (8.8.0): - - GoogleAppMeasurement/WithoutAdIdSupport (= 8.8.0) - - GoogleUtilities/AppDelegateSwizzler (~> 7.4) - - GoogleUtilities/MethodSwizzler (~> 7.4) - - GoogleUtilities/Network (~> 7.4) - - "GoogleUtilities/NSData+zlib (~> 7.4)" - - nanopb (~> 2.30908.0) - - GoogleAppMeasurement/WithoutAdIdSupport (8.8.0): - - GoogleUtilities/AppDelegateSwizzler (~> 7.4) - - GoogleUtilities/MethodSwizzler (~> 7.4) - - GoogleUtilities/Network (~> 7.4) - - "GoogleUtilities/NSData+zlib (~> 7.4)" - - nanopb (~> 2.30908.0) - - GoogleDataTransport (9.2.3): - - GoogleUtilities/Environment (~> 7.7) - - nanopb (< 2.30910.0, >= 2.30908.0) - - PromisesObjC (< 3.0, >= 1.2) - - GoogleSignIn (7.0.0): - - AppAuth (~> 1.5) - - GTMAppAuth (< 3.0, >= 1.3) - - GTMSessionFetcher/Core (< 4.0, >= 1.1) - - GoogleUtilities/AppDelegateSwizzler (7.11.1): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (7.11.1): - - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/ISASwizzler (7.11.1) - - GoogleUtilities/Logger (7.11.1): - - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (7.11.1): - - GoogleUtilities/Logger - - GoogleUtilities/Network (7.11.1): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (7.11.1)" - - GoogleUtilities/Reachability (7.11.1): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (7.11.1): - - GoogleUtilities/Logger - - GTMAppAuth (2.0.0): - - AppAuth/Core (~> 1.6) - - GTMSessionFetcher/Core (< 4.0, >= 1.5) - - GTMSessionFetcher/Core (3.1.1) - - hermes-engine (0.72.4): - - hermes-engine/Pre-built (= 0.72.4) - - hermes-engine/Pre-built (0.72.4) - - libevent (2.1.12) - - libwebp (1.2.4): - - libwebp/demux (= 1.2.4) - - libwebp/mux (= 1.2.4) - - libwebp/webp (= 1.2.4) - - libwebp/demux (1.2.4): - - libwebp/webp - - libwebp/mux (1.2.4): - - libwebp/demux - - libwebp/webp (1.2.4) - - lottie-ios (3.4.4) - - lottie-react-native (5.1.6): - - lottie-ios (~> 3.4.0) - - React-Core - - MapboxCommon (23.6.0) - - MapboxCoreMaps (10.14.0): - - MapboxCommon (~> 23.6) - - MapboxMaps (10.14.0): - - MapboxCommon (= 23.6.0) - - MapboxCoreMaps (= 10.14.0) - - MapboxMobileEvents (= 1.0.10) - - Turf (~> 2.0) - - MapboxMobileEvents (1.0.10) - - nanopb (2.30908.0): - - nanopb/decode (= 2.30908.0) - - nanopb/encode (= 2.30908.0) - - nanopb/decode (2.30908.0) - - nanopb/encode (2.30908.0) - - Onfido (27.4.0) - - onfido-react-native-sdk (7.4.0): - - Onfido (= 27.4.0) - - React - - OpenSSL-Universal (1.1.1100) - - Permission-Camera (3.6.1): - - RNPermissions - - Permission-LocationAccuracy (3.6.1): - - RNPermissions - - Permission-LocationAlways (3.6.1): - - RNPermissions - - Permission-LocationWhenInUse (3.6.1): - - RNPermissions - - Plaid (4.1.0) - - PromisesObjC (2.2.0) - - RCT-Folly (2021.07.22.00): - - boost - - DoubleConversion - - fmt (~> 6.2.1) - - glog - - RCT-Folly/Default (= 2021.07.22.00) - - RCT-Folly/Default (2021.07.22.00): - - boost - - DoubleConversion - - fmt (~> 6.2.1) - - glog - - RCT-Folly/Futures (2021.07.22.00): - - boost - - DoubleConversion - - fmt (~> 6.2.1) - - glog - - libevent - - RCTRequired (0.72.4) - - RCTTypeSafety (0.72.4): - - FBLazyVector (= 0.72.4) - - RCTRequired (= 0.72.4) - - React-Core (= 0.72.4) - - React (0.72.4): - - React-Core (= 0.72.4) - - React-Core/DevSupport (= 0.72.4) - - React-Core/RCTWebSocket (= 0.72.4) - - React-RCTActionSheet (= 0.72.4) - - React-RCTAnimation (= 0.72.4) - - React-RCTBlob (= 0.72.4) - - React-RCTImage (= 0.72.4) - - React-RCTLinking (= 0.72.4) - - React-RCTNetwork (= 0.72.4) - - React-RCTSettings (= 0.72.4) - - React-RCTText (= 0.72.4) - - React-RCTVibration (= 0.72.4) - - React-callinvoker (0.72.4) - - React-Codegen (0.72.4): - - DoubleConversion - - FBReactNativeSpec - - glog - - hermes-engine - - RCT-Folly - - RCTRequired - - RCTTypeSafety - - React-Core - - React-jsi - - React-jsiexecutor - - React-NativeModulesApple - - React-rncore - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - React-Core (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.72.4) - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/CoreModulesHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/Default (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/DevSupport (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.72.4) - - React-Core/RCTWebSocket (= 0.72.4) - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-jsinspector (= 0.72.4) - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTActionSheetHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTAnimationHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTBlobHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTImageHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTLinkingHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTNetworkHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTSettingsHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTTextHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTVibrationHeaders (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-Core/RCTWebSocket (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.72.4) - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-perflogger - - React-runtimeexecutor - - React-utils - - SocketRocket (= 0.6.1) - - Yoga - - React-CoreModules (0.72.4): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.4) - - React-Codegen (= 0.72.4) - - React-Core/CoreModulesHeaders (= 0.72.4) - - React-jsi (= 0.72.4) - - React-RCTBlob - - React-RCTImage (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - SocketRocket (= 0.6.1) - - React-cxxreact (0.72.4): - - boost (= 1.76.0) - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.72.4) - - React-debug (= 0.72.4) - - React-jsi (= 0.72.4) - - React-jsinspector (= 0.72.4) - - React-logger (= 0.72.4) - - React-perflogger (= 0.72.4) - - React-runtimeexecutor (= 0.72.4) - - React-debug (0.72.4) - - React-hermes (0.72.4): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - RCT-Folly/Futures (= 2021.07.22.00) - - React-cxxreact (= 0.72.4) - - React-jsi - - React-jsiexecutor (= 0.72.4) - - React-jsinspector (= 0.72.4) - - React-perflogger (= 0.72.4) - - React-jsi (0.72.4): - - boost (= 1.76.0) - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-jsiexecutor (0.72.4): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-cxxreact (= 0.72.4) - - React-jsi (= 0.72.4) - - React-perflogger (= 0.72.4) - - React-jsinspector (0.72.4) - - React-logger (0.72.4): - - glog - - react-native-airship (15.2.6): - - AirshipFrameworkProxy (= 2.0.8) - - React-Core - - react-native-blob-util (0.17.3): - - React-Core - - react-native-cameraroll (5.4.0): - - React-Core - - react-native-config (1.4.6): - - react-native-config/App (= 1.4.6) - - react-native-config/App (1.4.6): - - React-Core - - react-native-document-picker (8.1.1): - - React-Core - - react-native-flipper (0.159.0): - - React-Core - - react-native-image-manipulator (1.0.5): - - React - - react-native-image-picker (5.1.0): - - React-Core - - react-native-key-command (1.0.1): - - React-Core - - react-native-netinfo (9.3.10): - - React-Core - - react-native-pager-view (6.2.0): - - React-Core - - react-native-pdf (6.7.1): - - React-Core - - react-native-performance (5.1.0): - - React-Core - - react-native-plaid-link-sdk (10.0.0): - - Plaid (~> 4.1.0) - - React-Core - - react-native-quick-sqlite (8.0.0-beta.2): - - React - - React-callinvoker - - React-Core - - react-native-render-html (6.3.1): - - React-Core - - react-native-safe-area-context (4.4.1): - - RCT-Folly - - RCTRequired - - RCTTypeSafety - - React-Core - - ReactCommon/turbomodule/core - - react-native-view-shot (3.6.0): - - React-Core - - react-native-webview (11.23.0): - - React-Core - - React-NativeModulesApple (0.72.4): - - hermes-engine - - React-callinvoker - - React-Core - - React-cxxreact - - React-jsi - - React-runtimeexecutor - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - React-perflogger (0.72.4) - - React-RCTActionSheet (0.72.4): - - React-Core/RCTActionSheetHeaders (= 0.72.4) - - React-RCTAnimation (0.72.4): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.4) - - React-Codegen (= 0.72.4) - - React-Core/RCTAnimationHeaders (= 0.72.4) - - React-jsi (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - React-RCTAppDelegate (0.72.4): - - RCT-Folly - - RCTRequired - - RCTTypeSafety - - React-Core - - React-CoreModules - - React-hermes - - React-NativeModulesApple - - React-RCTImage - - React-RCTNetwork - - React-runtimescheduler - - ReactCommon/turbomodule/core - - React-RCTBlob (0.72.4): - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.72.4) - - React-Core/RCTBlobHeaders (= 0.72.4) - - React-Core/RCTWebSocket (= 0.72.4) - - React-jsi (= 0.72.4) - - React-RCTNetwork (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - React-RCTImage (0.72.4): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.4) - - React-Codegen (= 0.72.4) - - React-Core/RCTImageHeaders (= 0.72.4) - - React-jsi (= 0.72.4) - - React-RCTNetwork (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - React-RCTLinking (0.72.4): - - React-Codegen (= 0.72.4) - - React-Core/RCTLinkingHeaders (= 0.72.4) - - React-jsi (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - React-RCTNetwork (0.72.4): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.4) - - React-Codegen (= 0.72.4) - - React-Core/RCTNetworkHeaders (= 0.72.4) - - React-jsi (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - React-RCTSettings (0.72.4): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.4) - - React-Codegen (= 0.72.4) - - React-Core/RCTSettingsHeaders (= 0.72.4) - - React-jsi (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - React-RCTText (0.72.4): - - React-Core/RCTTextHeaders (= 0.72.4) - - React-RCTVibration (0.72.4): - - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.72.4) - - React-Core/RCTVibrationHeaders (= 0.72.4) - - React-jsi (= 0.72.4) - - ReactCommon/turbomodule/core (= 0.72.4) - - React-rncore (0.72.4) - - React-runtimeexecutor (0.72.4): - - React-jsi (= 0.72.4) - - React-runtimescheduler (0.72.4): - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-callinvoker - - React-debug - - React-jsi - - React-runtimeexecutor - - React-utils (0.72.4): - - glog - - RCT-Folly (= 2021.07.22.00) - - React-debug - - ReactCommon/turbomodule/bridging (0.72.4): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.72.4) - - React-cxxreact (= 0.72.4) - - React-jsi (= 0.72.4) - - React-logger (= 0.72.4) - - React-perflogger (= 0.72.4) - - ReactCommon/turbomodule/core (0.72.4): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.72.4) - - React-cxxreact (= 0.72.4) - - React-jsi (= 0.72.4) - - React-logger (= 0.72.4) - - React-perflogger (= 0.72.4) - - RNAppleAuthentication (2.2.2): - - React-Core - - RNCAsyncStorage (1.17.11): - - React-Core - - RNCClipboard (1.5.1): - - React-Core - - RNCPicker (2.4.4): - - React-Core - - RNDateTimePicker (3.5.2): - - React-Core - - RNDeviceInfo (10.3.0): - - React-Core - - RNDevMenu (4.1.1): - - React-Core - - React-Core/DevSupport - - React-RCTNetwork - - RNFastImage (8.6.3): - - React-Core - - SDWebImage (~> 5.11.1) - - SDWebImageWebPCoder (~> 0.8.4) - - RNFBAnalytics (12.9.3): - - Firebase/Analytics (= 8.8.0) - - React-Core - - RNFBApp - - RNFBApp (12.9.3): - - Firebase/CoreOnly (= 8.8.0) - - React-Core - - RNFBCrashlytics (12.9.3): - - Firebase/Crashlytics (= 8.8.0) - - React-Core - - RNFBApp - - RNFBPerf (12.9.3): - - Firebase/Performance (= 8.8.0) - - React-Core - - RNFBApp - - RNFS (2.20.0): - - React-Core - - RNGestureHandler (2.12.0): - - React-Core - - RNGoogleSignin (10.0.1): - - GoogleSignIn (~> 7.0) - - React-Core - - RNLocalize (2.2.6): - - React-Core - - rnmapbox-maps (10.0.11): - - MapboxMaps (~> 10.14.0) - - React - - React-Core - - rnmapbox-maps/DynamicLibrary (= 10.0.11) - - Turf - - rnmapbox-maps/DynamicLibrary (10.0.11): - - MapboxMaps (~> 10.14.0) - - React - - React-Core - - Turf - - RNPermissions (3.6.1): - - React-Core - - RNReactNativeHapticFeedback (1.14.0): - - React-Core - - RNReanimated (3.4.0): - - DoubleConversion - - FBLazyVector - - glog - - hermes-engine - - RCT-Folly - - RCTRequired - - RCTTypeSafety - - React-callinvoker - - React-Core - - React-Core/DevSupport - - React-Core/RCTWebSocket - - React-CoreModules - - React-cxxreact - - React-hermes - - React-jsi - - React-jsiexecutor - - React-jsinspector - - React-RCTActionSheet - - React-RCTAnimation - - React-RCTAppDelegate - - React-RCTBlob - - React-RCTImage - - React-RCTLinking - - React-RCTNetwork - - React-RCTSettings - - React-RCTText - - ReactCommon/turbomodule/core - - Yoga - - RNScreens (3.21.0): - - React-Core - - React-RCTImage - - RNSVG (13.13.0): - - React-Core - - SDWebImage (5.11.1): - - SDWebImage/Core (= 5.11.1) - - SDWebImage/Core (5.11.1) - - SDWebImageWebPCoder (0.8.5): - - libwebp (~> 1.0) - - SDWebImage/Core (~> 5.10) - - SocketRocket (0.6.1) - - Turf (2.6.1) - - VisionCamera (2.15.4): - - React - - React-callinvoker - - React-Core - - Yoga (1.14.0) - - YogaKit (1.18.1): - - Yoga (~> 1.14) - -DEPENDENCIES: - - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) - - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - - Flipper (= 0.182.0) - - Flipper-Boost-iOSX (= 1.76.0.1.11) - - Flipper-DoubleConversion (= 3.2.0.1) - - Flipper-Fmt (= 7.1.7) - - Flipper-Folly (= 2.6.10) - - Flipper-Glog (= 0.5.0.5) - - Flipper-PeerTalk (= 0.0.4) - - FlipperKit (= 0.182.0) - - FlipperKit/Core (= 0.182.0) - - FlipperKit/CppBridge (= 0.182.0) - - FlipperKit/FBCxxFollyDynamicConvert (= 0.182.0) - - FlipperKit/FBDefines (= 0.182.0) - - FlipperKit/FKPortForwarding (= 0.182.0) - - FlipperKit/FlipperKitHighlightOverlay (= 0.182.0) - - FlipperKit/FlipperKitLayoutPlugin (= 0.182.0) - - FlipperKit/FlipperKitLayoutTextSearchable (= 0.182.0) - - FlipperKit/FlipperKitNetworkPlugin (= 0.182.0) - - FlipperKit/FlipperKitReactPlugin (= 0.182.0) - - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.182.0) - - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) - - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - - libevent (~> 2.1.12) - - lottie-react-native (from `../node_modules/lottie-react-native`) - - "onfido-react-native-sdk (from `../node_modules/@onfido/react-native-sdk`)" - - OpenSSL-Universal (= 1.1.1100) - - Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`) - - Permission-LocationAccuracy (from `../node_modules/react-native-permissions/ios/LocationAccuracy`) - - Permission-LocationAlways (from `../node_modules/react-native-permissions/ios/LocationAlways`) - - Permission-LocationWhenInUse (from `../node_modules/react-native-permissions/ios/LocationWhenInUse`) - - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - - React (from `../node_modules/react-native/`) - - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) - - React-Codegen (from `build/generated/ios`) - - React-Core (from `../node_modules/react-native/`) - - React-Core/DevSupport (from `../node_modules/react-native/`) - - React-Core/RCTWebSocket (from `../node_modules/react-native/`) - - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) - - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) - - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) - - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) - - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - - React-logger (from `../node_modules/react-native/ReactCommon/logger`) - - "react-native-airship (from `../node_modules/@ua/react-native-airship`)" - - react-native-blob-util (from `../node_modules/react-native-blob-util`) - - "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)" - - react-native-config (from `../node_modules/react-native-config`) - - react-native-document-picker (from `../node_modules/react-native-document-picker`) - - react-native-flipper (from `../node_modules/react-native-flipper`) - - "react-native-image-manipulator (from `../node_modules/@oguzhnatly/react-native-image-manipulator`)" - - react-native-image-picker (from `../node_modules/react-native-image-picker`) - - react-native-key-command (from `../node_modules/react-native-key-command`) - - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - - react-native-pager-view (from `../node_modules/react-native-pager-view`) - - react-native-pdf (from `../node_modules/react-native-pdf`) - - react-native-performance (from `../node_modules/react-native-performance`) - - react-native-plaid-link-sdk (from `../node_modules/react-native-plaid-link-sdk`) - - react-native-quick-sqlite (from `../node_modules/react-native-quick-sqlite`) - - react-native-render-html (from `../node_modules/react-native-render-html`) - - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - - react-native-view-shot (from `../node_modules/react-native-view-shot`) - - react-native-webview (from `../node_modules/react-native-webview`) - - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) - - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) - - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) - - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) - - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) - - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) - - React-RCTText (from `../node_modules/react-native/Libraries/Text`) - - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - - React-rncore (from `../node_modules/react-native/ReactCommon`) - - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) - - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) - - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - - "RNAppleAuthentication (from `../node_modules/@invertase/react-native-apple-authentication`)" - - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - - "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)" - - "RNCPicker (from `../node_modules/@react-native-picker/picker`)" - - "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)" - - RNDeviceInfo (from `../node_modules/react-native-device-info`) - - RNDevMenu (from `../node_modules/react-native-dev-menu`) - - RNFastImage (from `../node_modules/react-native-fast-image`) - - "RNFBAnalytics (from `../node_modules/@react-native-firebase/analytics`)" - - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" - - "RNFBCrashlytics (from `../node_modules/@react-native-firebase/crashlytics`)" - - "RNFBPerf (from `../node_modules/@react-native-firebase/perf`)" - - RNFS (from `../node_modules/react-native-fs`) - - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - - "RNGoogleSignin (from `../node_modules/@react-native-google-signin/google-signin`)" - - RNLocalize (from `../node_modules/react-native-localize`) - - "rnmapbox-maps (from `../node_modules/@rnmapbox/maps`)" - - RNPermissions (from `../node_modules/react-native-permissions`) - - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) - - RNReanimated (from `../node_modules/react-native-reanimated`) - - RNScreens (from `../node_modules/react-native-screens`) - - RNSVG (from `../node_modules/react-native-svg`) - - VisionCamera (from `../node_modules/react-native-vision-camera`) - - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) - -SPEC REPOS: - trunk: - - Airship - - AirshipFrameworkProxy - - AppAuth - - CocoaAsyncSocket - - Firebase - - FirebaseABTesting - - FirebaseAnalytics - - FirebaseCore - - FirebaseCoreDiagnostics - - FirebaseCrashlytics - - FirebaseInstallations - - FirebasePerformance - - FirebaseRemoteConfig - - Flipper - - Flipper-Boost-iOSX - - Flipper-DoubleConversion - - Flipper-Fmt - - Flipper-Folly - - Flipper-Glog - - Flipper-PeerTalk - - FlipperKit - - fmt - - GoogleAppMeasurement - - GoogleDataTransport - - GoogleSignIn - - GoogleUtilities - - GTMAppAuth - - GTMSessionFetcher - - libevent - - libwebp - - lottie-ios - - MapboxCommon - - MapboxCoreMaps - - MapboxMaps - - MapboxMobileEvents - - nanopb - - Onfido - - OpenSSL-Universal - - Plaid - - PromisesObjC - - SDWebImage - - SDWebImageWebPCoder - - SocketRocket - - Turf - - YogaKit - -EXTERNAL SOURCES: - boost: - :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" - BVLinearGradient: - :path: "../node_modules/react-native-linear-gradient" - DoubleConversion: - :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" - FBLazyVector: - :path: "../node_modules/react-native/Libraries/FBLazyVector" - FBReactNativeSpec: - :path: "../node_modules/react-native/React/FBReactNativeSpec" - glog: - :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" - hermes-engine: - :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" - :tag: hermes-2023-08-07-RNv0.72.4-813b2def12bc9df02654b3e3653ae4a68d0572e0 - lottie-react-native: - :path: "../node_modules/lottie-react-native" - onfido-react-native-sdk: - :path: "../node_modules/@onfido/react-native-sdk" - Permission-Camera: - :path: "../node_modules/react-native-permissions/ios/Camera" - Permission-LocationAccuracy: - :path: "../node_modules/react-native-permissions/ios/LocationAccuracy" - Permission-LocationAlways: - :path: "../node_modules/react-native-permissions/ios/LocationAlways" - Permission-LocationWhenInUse: - :path: "../node_modules/react-native-permissions/ios/LocationWhenInUse" - RCT-Folly: - :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" - RCTRequired: - :path: "../node_modules/react-native/Libraries/RCTRequired" - RCTTypeSafety: - :path: "../node_modules/react-native/Libraries/TypeSafety" - React: - :path: "../node_modules/react-native/" - React-callinvoker: - :path: "../node_modules/react-native/ReactCommon/callinvoker" - React-Codegen: - :path: build/generated/ios - React-Core: - :path: "../node_modules/react-native/" - React-CoreModules: - :path: "../node_modules/react-native/React/CoreModules" - React-cxxreact: - :path: "../node_modules/react-native/ReactCommon/cxxreact" - React-debug: - :path: "../node_modules/react-native/ReactCommon/react/debug" - React-hermes: - :path: "../node_modules/react-native/ReactCommon/hermes" - React-jsi: - :path: "../node_modules/react-native/ReactCommon/jsi" - React-jsiexecutor: - :path: "../node_modules/react-native/ReactCommon/jsiexecutor" - React-jsinspector: - :path: "../node_modules/react-native/ReactCommon/jsinspector" - React-logger: - :path: "../node_modules/react-native/ReactCommon/logger" - react-native-airship: - :path: "../node_modules/@ua/react-native-airship" - react-native-blob-util: - :path: "../node_modules/react-native-blob-util" - react-native-cameraroll: - :path: "../node_modules/@react-native-camera-roll/camera-roll" - react-native-config: - :path: "../node_modules/react-native-config" - react-native-document-picker: - :path: "../node_modules/react-native-document-picker" - react-native-flipper: - :path: "../node_modules/react-native-flipper" - react-native-image-manipulator: - :path: "../node_modules/@oguzhnatly/react-native-image-manipulator" - react-native-image-picker: - :path: "../node_modules/react-native-image-picker" - react-native-key-command: - :path: "../node_modules/react-native-key-command" - react-native-netinfo: - :path: "../node_modules/@react-native-community/netinfo" - react-native-pager-view: - :path: "../node_modules/react-native-pager-view" - react-native-pdf: - :path: "../node_modules/react-native-pdf" - react-native-performance: - :path: "../node_modules/react-native-performance" - react-native-plaid-link-sdk: - :path: "../node_modules/react-native-plaid-link-sdk" - react-native-quick-sqlite: - :path: "../node_modules/react-native-quick-sqlite" - react-native-render-html: - :path: "../node_modules/react-native-render-html" - react-native-safe-area-context: - :path: "../node_modules/react-native-safe-area-context" - react-native-view-shot: - :path: "../node_modules/react-native-view-shot" - react-native-webview: - :path: "../node_modules/react-native-webview" - React-NativeModulesApple: - :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" - React-perflogger: - :path: "../node_modules/react-native/ReactCommon/reactperflogger" - React-RCTActionSheet: - :path: "../node_modules/react-native/Libraries/ActionSheetIOS" - React-RCTAnimation: - :path: "../node_modules/react-native/Libraries/NativeAnimation" - React-RCTAppDelegate: - :path: "../node_modules/react-native/Libraries/AppDelegate" - React-RCTBlob: - :path: "../node_modules/react-native/Libraries/Blob" - React-RCTImage: - :path: "../node_modules/react-native/Libraries/Image" - React-RCTLinking: - :path: "../node_modules/react-native/Libraries/LinkingIOS" - React-RCTNetwork: - :path: "../node_modules/react-native/Libraries/Network" - React-RCTSettings: - :path: "../node_modules/react-native/Libraries/Settings" - React-RCTText: - :path: "../node_modules/react-native/Libraries/Text" - React-RCTVibration: - :path: "../node_modules/react-native/Libraries/Vibration" - React-rncore: - :path: "../node_modules/react-native/ReactCommon" - React-runtimeexecutor: - :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" - React-runtimescheduler: - :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" - React-utils: - :path: "../node_modules/react-native/ReactCommon/react/utils" - ReactCommon: - :path: "../node_modules/react-native/ReactCommon" - RNAppleAuthentication: - :path: "../node_modules/@invertase/react-native-apple-authentication" - RNCAsyncStorage: - :path: "../node_modules/@react-native-async-storage/async-storage" - RNCClipboard: - :path: "../node_modules/@react-native-community/clipboard" - RNCPicker: - :path: "../node_modules/@react-native-picker/picker" - RNDateTimePicker: - :path: "../node_modules/@react-native-community/datetimepicker" - RNDeviceInfo: - :path: "../node_modules/react-native-device-info" - RNDevMenu: - :path: "../node_modules/react-native-dev-menu" - RNFastImage: - :path: "../node_modules/react-native-fast-image" - RNFBAnalytics: - :path: "../node_modules/@react-native-firebase/analytics" - RNFBApp: - :path: "../node_modules/@react-native-firebase/app" - RNFBCrashlytics: - :path: "../node_modules/@react-native-firebase/crashlytics" - RNFBPerf: - :path: "../node_modules/@react-native-firebase/perf" - RNFS: - :path: "../node_modules/react-native-fs" - RNGestureHandler: - :path: "../node_modules/react-native-gesture-handler" - RNGoogleSignin: - :path: "../node_modules/@react-native-google-signin/google-signin" - RNLocalize: - :path: "../node_modules/react-native-localize" - rnmapbox-maps: - :path: "../node_modules/@rnmapbox/maps" - RNPermissions: - :path: "../node_modules/react-native-permissions" - RNReactNativeHapticFeedback: - :path: "../node_modules/react-native-haptic-feedback" - RNReanimated: - :path: "../node_modules/react-native-reanimated" - RNScreens: - :path: "../node_modules/react-native-screens" - RNSVG: - :path: "../node_modules/react-native-svg" - VisionCamera: - :path: "../node_modules/react-native-vision-camera" - Yoga: - :path: "../node_modules/react-native/ReactCommon/yoga" - -SPEC CHECKSUMS: - Airship: c70eed50e429f97f5adb285423c7291fb7a032ae - AirshipFrameworkProxy: 7bc4130c668c6c98e2d4c60fe4c9eb61a999be99 - AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570 - boost: 57d2868c099736d80fcd648bf211b4431e51a558 - BVLinearGradient: 421743791a59d259aec53f4c58793aad031da2ca - CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 - FBLazyVector: 5d4a3b7f411219a45a6d952f77d2c0a6c9989da5 - FBReactNativeSpec: 3fc2d478e1c4b08276f9dd9128f80ec6d5d85c1f - Firebase: 629510f1a9ddb235f3a7c5c8ceb23ba887f0f814 - FirebaseABTesting: 10cbce8db9985ae2e3847ea44e9947dd18f94e10 - FirebaseAnalytics: 5506ea8b867d8423485a84b4cd612d279f7b0b8a - FirebaseCore: 98b29e3828f0a53651c363937a7f7d92a19f1ba2 - FirebaseCoreDiagnostics: 92e07a649aeb66352b319d43bdd2ee3942af84cb - FirebaseCrashlytics: 3660c045c8e45cc4276110562a0ef44cf43c8157 - FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd - FirebasePerformance: 0c01a7a496657d7cea86d40c0b1725259d164c6c - FirebaseRemoteConfig: 2d6e2cfdb49af79535c8af8a80a4a5009038ec2b - Flipper: 6edb735e6c3e332975d1b17956bcc584eccf5818 - Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c - Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 - Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b - Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 - Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 - Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - FlipperKit: 2efad7007d6745a3f95e4034d547be637f89d3f6 - fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - GoogleAppMeasurement: 5ba1164e3c844ba84272555e916d0a6d3d977e91 - GoogleDataTransport: f0308f5905a745f94fb91fea9c6cbaf3831cb1bd - GoogleSignIn: b232380cf495a429b8095d3178a8d5855b42e842 - GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749 - GTMAppAuth: 99fb010047ba3973b7026e45393f51f27ab965ae - GTMSessionFetcher: e8647203b65cee28c5f73d0f473d096653945e72 - hermes-engine: 81191603c4eaa01f5e4ae5737a9efcf64756c7b2 - libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 - libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef - lottie-ios: 8f97d3271e155c2d688875c29cd3c74908aef5f8 - lottie-react-native: 8f9d4be452e23f6e5ca0fdc11669dc99ab52be81 - MapboxCommon: 4a0251dd470ee37e7fadda8e285c01921a5e1eb0 - MapboxCoreMaps: eb07203bbb0b1509395db5ab89cd3ad6c2e3c04c - MapboxMaps: af50ec61a7eb3b032c3f7962c6bd671d93d2a209 - MapboxMobileEvents: de50b3a4de180dd129c326e09cd12c8adaaa46d6 - nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 - Onfido: e36f284b865adcf99d9c905590a64ac09d4a576b - onfido-react-native-sdk: 4ecde1a97435dcff9f00a878e3f8d1eb14fabbdc - OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c - Permission-Camera: bf6791b17c7f614b6826019fcfdcc286d3a107f6 - Permission-LocationAccuracy: 76df17de5c6b8bc2eee34e61ee92cdd7a864c73d - Permission-LocationAlways: 8d99b025c9f73c696e0cdb367e42525f2e9a26f2 - Permission-LocationWhenInUse: 3ba99e45c852763f730eabecec2870c2382b7bd4 - Plaid: 7d340abeadb46c7aa1a91f896c5b22395a31fcf2 - PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef - RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 - RCTRequired: c0569ecc035894e4a68baecb30fe6a7ea6e399f9 - RCTTypeSafety: e90354072c21236e0bcf1699011e39acd25fea2f - React: a1be3c6dc0a6e949ccd3e659781aa47bbae1868f - React-callinvoker: 1020b33f6cb1a1824f9ca2a86609fbce2a73c6ed - React-Codegen: a0a26badf098d4a779acda922caf74f6ecabed28 - React-Core: 52075b80f10c26f62219d7b5d13d7d8089f027b3 - React-CoreModules: 21abab85d7ad9038ce2b1c33d39e3baaf7dc9244 - React-cxxreact: 4ad1cc861e32fb533dad6ff7a4ea25680fa1c994 - React-debug: 17366a3d5c5d2f5fc04f09101a4af38cb42b54ae - React-hermes: 37377d0a56aa0cf55c65248271866ce3268cde3f - React-jsi: 6de8b0ccc6b765b58e4eee9ee38049dbeaf5c221 - React-jsiexecutor: c7f826e40fa9cab5d37cab6130b1af237332b594 - React-jsinspector: aaed4cf551c4a1c98092436518c2d267b13a673f - React-logger: da1ebe05ae06eb6db4b162202faeafac4b435e77 - react-native-airship: 5d19f4ba303481cf4101ff9dee9249ef6a8a6b64 - react-native-blob-util: 99f4d79189252f597fe0d810c57a3733b1b1dea6 - react-native-cameraroll: 8ffb0af7a5e5de225fd667610e2979fc1f0c2151 - react-native-config: 7cd105e71d903104e8919261480858940a6b9c0e - react-native-document-picker: f68191637788994baed5f57d12994aa32cf8bf88 - react-native-flipper: dc5290261fbeeb2faec1bdc57ae6dd8d562e1de4 - react-native-image-manipulator: c48f64221cfcd46e9eec53619c4c0374f3328a56 - react-native-image-picker: c33d4e79f0a14a2b66e5065e14946ae63749660b - react-native-key-command: c2645ec01eb1fa664606c09480c05cb4220ef67b - react-native-netinfo: ccbe1085dffd16592791d550189772e13bf479e2 - react-native-pager-view: 0ccb8bf60e2ebd38b1f3669fa3650ecce81db2df - react-native-pdf: 7c0e91ada997bac8bac3bb5bea5b6b81f5a3caae - react-native-performance: cef2b618d47b277fb5c3280b81a3aad1e72f2886 - react-native-plaid-link-sdk: 9eb0f71dad94b3bdde649c7a384cba93024af46c - react-native-quick-sqlite: bcc7a7a250a40222f18913a97cd356bf82d0a6c4 - react-native-render-html: 96c979fe7452a0a41559685d2f83b12b93edac8c - react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a - react-native-view-shot: 705f999ac2a24e4e6c909c0ca65c732ed33ca2ff - react-native-webview: e771bc375f789ebfa02a26939a57dbc6fa897336 - React-NativeModulesApple: edb5ace14f73f4969df6e7b1f3e41bef0012740f - React-perflogger: 496a1a3dc6737f964107cb3ddae7f9e265ddda58 - React-RCTActionSheet: 02904b932b50e680f4e26e7a686b33ebf7ef3c00 - React-RCTAnimation: 88feaf0a85648fb8fd497ce749829774910276d6 - React-RCTAppDelegate: 5792ac0f0feccb584765fdd7aa81ea320c4d9b0b - React-RCTBlob: 0dbc9e2a13d241b37d46b53e54630cbad1f0e141 - React-RCTImage: b111645ab901f8e59fc68fbe31f5731bdbeef087 - React-RCTLinking: 3d719727b4c098aad3588aa3559361ee0579f5de - React-RCTNetwork: b44d3580be05d74556ba4efbf53570f17e38f734 - React-RCTSettings: c0c54b330442c29874cd4dae6e94190dc11a6f6f - React-RCTText: 9b9f5589d9b649d7246c3f336e116496df28cfe6 - React-RCTVibration: 691c67f3beaf1d084ceed5eb5c1dddd9afa8591e - React-rncore: 142268f6c92e296dc079aadda3fade778562f9e4 - React-runtimeexecutor: d465ba0c47ef3ed8281143f59605cacc2244d5c7 - React-runtimescheduler: 4941cc1b3cf08b792fbf666342c9fc95f1969035 - React-utils: b79f2411931f9d3ea5781404dcbb2fa8a837e13a - ReactCommon: 4b2bdcb50a3543e1c2b2849ad44533686610826d - RNAppleAuthentication: 0571c08da8c327ae2afc0261b48b4a515b0286a6 - RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 - RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495 - RNCPicker: 0b65be85fe7954fbb2062ef079e3d1cde252d888 - RNDateTimePicker: 7658208086d86d09e1627b5c34ba0cf237c60140 - RNDeviceInfo: 4701f0bf2a06b34654745053db0ce4cb0c53ada7 - RNDevMenu: 72807568fe4188bd4c40ce32675d82434b43c45d - RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8 - RNFBAnalytics: f76bfa164ac235b00505deb9fc1776634056898c - RNFBApp: 729c0666395b1953198dc4a1ec6deb8fbe1c302e - RNFBCrashlytics: 2061ca863e8e2fa1aae9b12477d7dfa8e88ca0f9 - RNFBPerf: 389914cda4000fe0d996a752532a591132cbf3f9 - RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 - RNGestureHandler: dec4645026e7401a0899f2846d864403478ff6a5 - RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0 - RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 - rnmapbox-maps: 6f638ec002aa6e906a6f766d69cd45f968d98e64 - RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c - RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c - RNReanimated: 020859659f64be2d30849a1fe88c821a7c3e0cbf - RNScreens: d037903436160a4b039d32606668350d2a808806 - RNSVG: ed492aaf3af9ca01bc945f7a149d76d62e73ec82 - SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d - SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d - SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - Turf: 469ce2c3d22e5e8e4818d5a3b254699a5c89efa4 - VisionCamera: d3ec8883417a6a4a0e3a6ba37d81d22db7611601 - Yoga: 3efc43e0d48686ce2e8c60f99d4e6bd349aff981 - YogaKit: f782866e155069a2cca2517aafea43200b01fd5a - -PODFILE CHECKSUM: 2daf34c870819a933f3fefe426801d54b2ff2a14 - -COCOAPODS: 1.13.0 From ed26edbc45a9c3dc0f36f9b9b328abf9b6f2c433 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 5 Oct 2023 06:58:11 +0200 Subject: [PATCH 06/65] updates pr --- src/components/AvatarWithImagePicker.js | 125 +++++++++++++----------- 1 file changed, 70 insertions(+), 55 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 55767268162c..156c08254a95 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -274,6 +274,42 @@ function AvatarWithImagePicker({ const additionalStyles = _.isArray(style) ? style : [style]; + /** + * Create menu items list for avatar menu + * + * @param {Function} openPicker + * @returns {Array} + */ + const createMenuItems = (openPicker) => { + const menuItems = [ + { + icon: Expensicons.Upload, + text: translate('avatarWithImagePicker.uploadPhoto'), + onSelected: () => { + if (Browser.isSafari()) { + return; + } + openPicker({ + onPicked: showAvatarCropModal, + }); + }, + }, + ]; + + // If current avatar isn't a default avatar, allow Remove Photo option + if (!isUsingDefaultAvatar) { + menuItems.push({ + icon: Expensicons.Trashcan, + text: translate('avatarWithImagePicker.removePhoto'), + onSelected: () => { + setError(null, {}); + onImageRemoved(); + }, + }); + } + return menuItems; + }; + return ( @@ -323,64 +359,43 @@ function AvatarWithImagePicker({ fallbackSource={fallbackIcon} > {({show}) => ( - - {({openPicker}) => { - const menuItems = [ - { - icon: Expensicons.Upload, - text: translate('avatarWithImagePicker.uploadPhoto'), - onSelected: () => { - if (Browser.isSafari()) { - return; - } + + {({openPicker}) => { + const menuItems = createMenuItems(openPicker); + + // If the current avatar isn't a default avatar, allow the "View Photo" option + if (!isUsingDefaultAvatar) { + menuItems.push({ + icon: Expensicons.Eye, + text: translate('avatarWithImagePicker.viewPhoto'), + onSelected: show, + }); + } + + return ( + setIsMenuVisible(false)} + onItemSelected={(item, index) => { + setIsMenuVisible(false); + // In order for the file picker to open dynamically, the click + // function must be called from within an event handler that was initiated + // by the user on Safari. + if (index === 0 && Browser.isSafari()) { openPicker({ onPicked: showAvatarCropModal, }); - }, - }, - ]; - - // If current avatar isn't a default avatar, allow Remove Photo option - if (!isUsingDefaultAvatar) { - menuItems.push({ - icon: Expensicons.Trashcan, - text: translate('avatarWithImagePicker.removePhoto'), - onSelected: () => { - setError(null, {}); - onImageRemoved(); - }, - }); - - menuItems.push({ - icon: Expensicons.Eye, - text: translate('avatarWithImagePicker.viewPhoto'), - onSelected: () => show(), - }); - } - return ( - setIsMenuVisible(false)} - onItemSelected={(item, index) => { - setIsMenuVisible(false); - // In order for the file picker to open dynamically, the click - // function must be called from within a event handler that was initiated - // by the user on Safari. - if (index === 0 && Browser.isSafari()) { - openPicker({ - onPicked: showAvatarCropModal, - }); - } - }} - menuItems={menuItems} - anchorPosition={anchorPosition} - withoutOverlay - anchorRef={anchorRef} - anchorAlignment={anchorAlignment} - /> - ); - }} - + } + }} + menuItems={menuItems} + anchorPosition={anchorPosition} + withoutOverlay + anchorRef={anchorRef} + anchorAlignment={anchorAlignment} + /> + ); + }} + )} From 23645f8d4ed53e075f01715831cd80f161e09c98 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 5 Oct 2023 09:40:31 +0200 Subject: [PATCH 07/65] restore podfile.lock --- ios/Podfile.lock | 1314 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1314 insertions(+) create mode 100644 ios/Podfile.lock diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 000000000000..51b9f6af0e21 --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,1314 @@ +PODS: + - Airship (16.11.3): + - Airship/Automation (= 16.11.3) + - Airship/Basement (= 16.11.3) + - Airship/Core (= 16.11.3) + - Airship/ExtendedActions (= 16.11.3) + - Airship/MessageCenter (= 16.11.3) + - Airship/Automation (16.11.3): + - Airship/Core + - Airship/Basement (16.11.3) + - Airship/Core (16.11.3): + - Airship/Basement + - Airship/ExtendedActions (16.11.3): + - Airship/Core + - Airship/MessageCenter (16.11.3): + - Airship/Core + - Airship/PreferenceCenter (16.11.3): + - Airship/Core + - AirshipFrameworkProxy (2.0.8): + - Airship (= 16.11.3) + - Airship/MessageCenter (= 16.11.3) + - Airship/PreferenceCenter (= 16.11.3) + - AppAuth (1.6.2): + - AppAuth/Core (= 1.6.2) + - AppAuth/ExternalUserAgent (= 1.6.2) + - AppAuth/Core (1.6.2) + - AppAuth/ExternalUserAgent (1.6.2): + - AppAuth/Core + - boost (1.76.0) + - BVLinearGradient (2.8.1): + - React-Core + - CocoaAsyncSocket (7.6.5) + - DoubleConversion (1.1.6) + - FBLazyVector (0.72.4) + - FBReactNativeSpec (0.72.4): + - RCT-Folly (= 2021.07.22.00) + - RCTRequired (= 0.72.4) + - RCTTypeSafety (= 0.72.4) + - React-Core (= 0.72.4) + - React-jsi (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - Firebase/Analytics (8.8.0): + - Firebase/Core + - Firebase/Core (8.8.0): + - Firebase/CoreOnly + - FirebaseAnalytics (~> 8.8.0) + - Firebase/CoreOnly (8.8.0): + - FirebaseCore (= 8.8.0) + - Firebase/Crashlytics (8.8.0): + - Firebase/CoreOnly + - FirebaseCrashlytics (~> 8.8.0) + - Firebase/Performance (8.8.0): + - Firebase/CoreOnly + - FirebasePerformance (~> 8.8.0) + - FirebaseABTesting (8.15.0): + - FirebaseCore (~> 8.0) + - FirebaseAnalytics (8.8.0): + - FirebaseAnalytics/AdIdSupport (= 8.8.0) + - FirebaseCore (~> 8.0) + - FirebaseInstallations (~> 8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.4) + - GoogleUtilities/MethodSwizzler (~> 7.4) + - GoogleUtilities/Network (~> 7.4) + - "GoogleUtilities/NSData+zlib (~> 7.4)" + - nanopb (~> 2.30908.0) + - FirebaseAnalytics/AdIdSupport (8.8.0): + - FirebaseCore (~> 8.0) + - FirebaseInstallations (~> 8.0) + - GoogleAppMeasurement (= 8.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.4) + - GoogleUtilities/MethodSwizzler (~> 7.4) + - GoogleUtilities/Network (~> 7.4) + - "GoogleUtilities/NSData+zlib (~> 7.4)" + - nanopb (~> 2.30908.0) + - FirebaseCore (8.8.0): + - FirebaseCoreDiagnostics (~> 8.0) + - GoogleUtilities/Environment (~> 7.4) + - GoogleUtilities/Logger (~> 7.4) + - FirebaseCoreDiagnostics (8.15.0): + - GoogleDataTransport (~> 9.1) + - GoogleUtilities/Environment (~> 7.7) + - GoogleUtilities/Logger (~> 7.7) + - nanopb (~> 2.30908.0) + - FirebaseCrashlytics (8.8.0): + - FirebaseCore (~> 8.0) + - FirebaseInstallations (~> 8.0) + - GoogleDataTransport (~> 9.0) + - GoogleUtilities/Environment (~> 7.4) + - nanopb (~> 2.30908.0) + - PromisesObjC (< 3.0, >= 1.2) + - FirebaseInstallations (8.15.0): + - FirebaseCore (~> 8.0) + - GoogleUtilities/Environment (~> 7.7) + - GoogleUtilities/UserDefaults (~> 7.7) + - PromisesObjC (< 3.0, >= 1.2) + - FirebasePerformance (8.8.0): + - FirebaseCore (~> 8.0) + - FirebaseInstallations (~> 8.0) + - FirebaseRemoteConfig (~> 8.0) + - GoogleDataTransport (~> 9.0) + - GoogleUtilities/Environment (~> 7.4) + - GoogleUtilities/ISASwizzler (~> 7.4) + - GoogleUtilities/MethodSwizzler (~> 7.4) + - nanopb (~> 2.30908.0) + - FirebaseRemoteConfig (8.15.0): + - FirebaseABTesting (~> 8.0) + - FirebaseCore (~> 8.0) + - FirebaseInstallations (~> 8.0) + - GoogleUtilities/Environment (~> 7.7) + - "GoogleUtilities/NSData+zlib (~> 7.7)" + - Flipper (0.182.0): + - Flipper-Folly (~> 2.6) + - Flipper-Boost-iOSX (1.76.0.1.11) + - Flipper-DoubleConversion (3.2.0.1) + - Flipper-Fmt (7.1.7) + - Flipper-Folly (2.6.10): + - Flipper-Boost-iOSX + - Flipper-DoubleConversion + - Flipper-Fmt (= 7.1.7) + - Flipper-Glog + - libevent (~> 2.1.12) + - OpenSSL-Universal (= 1.1.1100) + - Flipper-Glog (0.5.0.5) + - Flipper-PeerTalk (0.0.4) + - FlipperKit (0.182.0): + - FlipperKit/Core (= 0.182.0) + - FlipperKit/Core (0.182.0): + - Flipper (~> 0.182.0) + - FlipperKit/CppBridge + - FlipperKit/FBCxxFollyDynamicConvert + - FlipperKit/FBDefines + - FlipperKit/FKPortForwarding + - SocketRocket (~> 0.6.0) + - FlipperKit/CppBridge (0.182.0): + - Flipper (~> 0.182.0) + - FlipperKit/FBCxxFollyDynamicConvert (0.182.0): + - Flipper-Folly (~> 2.6) + - FlipperKit/FBDefines (0.182.0) + - FlipperKit/FKPortForwarding (0.182.0): + - CocoaAsyncSocket (~> 7.6) + - Flipper-PeerTalk (~> 0.0.4) + - FlipperKit/FlipperKitHighlightOverlay (0.182.0) + - FlipperKit/FlipperKitLayoutHelpers (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitHighlightOverlay + - FlipperKit/FlipperKitLayoutTextSearchable + - FlipperKit/FlipperKitLayoutIOSDescriptors (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitHighlightOverlay + - FlipperKit/FlipperKitLayoutHelpers + - YogaKit (~> 1.18) + - FlipperKit/FlipperKitLayoutPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitHighlightOverlay + - FlipperKit/FlipperKitLayoutHelpers + - FlipperKit/FlipperKitLayoutIOSDescriptors + - FlipperKit/FlipperKitLayoutTextSearchable + - YogaKit (~> 1.18) + - FlipperKit/FlipperKitLayoutTextSearchable (0.182.0) + - FlipperKit/FlipperKitNetworkPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitReactPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitUserDefaultsPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/SKIOSNetworkPlugin (0.182.0): + - FlipperKit/Core + - FlipperKit/FlipperKitNetworkPlugin + - fmt (6.2.1) + - glog (0.3.5) + - GoogleAppMeasurement (8.8.0): + - GoogleAppMeasurement/AdIdSupport (= 8.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.4) + - GoogleUtilities/MethodSwizzler (~> 7.4) + - GoogleUtilities/Network (~> 7.4) + - "GoogleUtilities/NSData+zlib (~> 7.4)" + - nanopb (~> 2.30908.0) + - GoogleAppMeasurement/AdIdSupport (8.8.0): + - GoogleAppMeasurement/WithoutAdIdSupport (= 8.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.4) + - GoogleUtilities/MethodSwizzler (~> 7.4) + - GoogleUtilities/Network (~> 7.4) + - "GoogleUtilities/NSData+zlib (~> 7.4)" + - nanopb (~> 2.30908.0) + - GoogleAppMeasurement/WithoutAdIdSupport (8.8.0): + - GoogleUtilities/AppDelegateSwizzler (~> 7.4) + - GoogleUtilities/MethodSwizzler (~> 7.4) + - GoogleUtilities/Network (~> 7.4) + - "GoogleUtilities/NSData+zlib (~> 7.4)" + - nanopb (~> 2.30908.0) + - GoogleDataTransport (9.2.3): + - GoogleUtilities/Environment (~> 7.7) + - nanopb (< 2.30910.0, >= 2.30908.0) + - PromisesObjC (< 3.0, >= 1.2) + - GoogleSignIn (7.0.0): + - AppAuth (~> 1.5) + - GTMAppAuth (< 3.0, >= 1.3) + - GTMSessionFetcher/Core (< 4.0, >= 1.1) + - GoogleUtilities/AppDelegateSwizzler (7.11.1): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (7.11.1): + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/ISASwizzler (7.11.1) + - GoogleUtilities/Logger (7.11.1): + - GoogleUtilities/Environment + - GoogleUtilities/MethodSwizzler (7.11.1): + - GoogleUtilities/Logger + - GoogleUtilities/Network (7.11.1): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (7.11.1)" + - GoogleUtilities/Reachability (7.11.1): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (7.11.1): + - GoogleUtilities/Logger + - GTMAppAuth (2.0.0): + - AppAuth/Core (~> 1.6) + - GTMSessionFetcher/Core (< 4.0, >= 1.5) + - GTMSessionFetcher/Core (3.1.1) + - hermes-engine (0.72.4): + - hermes-engine/Pre-built (= 0.72.4) + - hermes-engine/Pre-built (0.72.4) + - libevent (2.1.12) + - libwebp (1.2.4): + - libwebp/demux (= 1.2.4) + - libwebp/mux (= 1.2.4) + - libwebp/webp (= 1.2.4) + - libwebp/demux (1.2.4): + - libwebp/webp + - libwebp/mux (1.2.4): + - libwebp/demux + - libwebp/webp (1.2.4) + - lottie-ios (3.4.4) + - lottie-react-native (5.1.6): + - lottie-ios (~> 3.4.0) + - React-Core + - MapboxCommon (23.6.0) + - MapboxCoreMaps (10.14.0): + - MapboxCommon (~> 23.6) + - MapboxMaps (10.14.0): + - MapboxCommon (= 23.6.0) + - MapboxCoreMaps (= 10.14.0) + - MapboxMobileEvents (= 1.0.10) + - Turf (~> 2.0) + - MapboxMobileEvents (1.0.10) + - nanopb (2.30908.0): + - nanopb/decode (= 2.30908.0) + - nanopb/encode (= 2.30908.0) + - nanopb/decode (2.30908.0) + - nanopb/encode (2.30908.0) + - Onfido (27.4.0) + - onfido-react-native-sdk (7.4.0): + - Onfido (= 27.4.0) + - React + - OpenSSL-Universal (1.1.1100) + - Permission-Camera (3.6.1): + - RNPermissions + - Permission-LocationAccuracy (3.6.1): + - RNPermissions + - Permission-LocationAlways (3.6.1): + - RNPermissions + - Permission-LocationWhenInUse (3.6.1): + - RNPermissions + - Plaid (4.1.0) + - PromisesObjC (2.2.0) + - RCT-Folly (2021.07.22.00): + - boost + - DoubleConversion + - fmt (~> 6.2.1) + - glog + - RCT-Folly/Default (= 2021.07.22.00) + - RCT-Folly/Default (2021.07.22.00): + - boost + - DoubleConversion + - fmt (~> 6.2.1) + - glog + - RCT-Folly/Futures (2021.07.22.00): + - boost + - DoubleConversion + - fmt (~> 6.2.1) + - glog + - libevent + - RCTRequired (0.72.4) + - RCTTypeSafety (0.72.4): + - FBLazyVector (= 0.72.4) + - RCTRequired (= 0.72.4) + - React-Core (= 0.72.4) + - React (0.72.4): + - React-Core (= 0.72.4) + - React-Core/DevSupport (= 0.72.4) + - React-Core/RCTWebSocket (= 0.72.4) + - React-RCTActionSheet (= 0.72.4) + - React-RCTAnimation (= 0.72.4) + - React-RCTBlob (= 0.72.4) + - React-RCTImage (= 0.72.4) + - React-RCTLinking (= 0.72.4) + - React-RCTNetwork (= 0.72.4) + - React-RCTSettings (= 0.72.4) + - React-RCTText (= 0.72.4) + - React-RCTVibration (= 0.72.4) + - React-callinvoker (0.72.4) + - React-Codegen (0.72.4): + - DoubleConversion + - FBReactNativeSpec + - glog + - hermes-engine + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - React-jsi + - React-jsiexecutor + - React-NativeModulesApple + - React-rncore + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - React-Core (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.72.4) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/CoreModulesHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/Default (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/DevSupport (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.72.4) + - React-Core/RCTWebSocket (= 0.72.4) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector (= 0.72.4) + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTActionSheetHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTAnimationHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTBlobHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTImageHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTLinkingHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTNetworkHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTSettingsHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTTextHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTVibrationHeaders (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-Core/RCTWebSocket (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.72.4) + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-perflogger + - React-runtimeexecutor + - React-utils + - SocketRocket (= 0.6.1) + - Yoga + - React-CoreModules (0.72.4): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.4) + - React-Codegen (= 0.72.4) + - React-Core/CoreModulesHeaders (= 0.72.4) + - React-jsi (= 0.72.4) + - React-RCTBlob + - React-RCTImage (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - SocketRocket (= 0.6.1) + - React-cxxreact (0.72.4): + - boost (= 1.76.0) + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.72.4) + - React-debug (= 0.72.4) + - React-jsi (= 0.72.4) + - React-jsinspector (= 0.72.4) + - React-logger (= 0.72.4) + - React-perflogger (= 0.72.4) + - React-runtimeexecutor (= 0.72.4) + - React-debug (0.72.4) + - React-hermes (0.72.4): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - RCT-Folly/Futures (= 2021.07.22.00) + - React-cxxreact (= 0.72.4) + - React-jsi + - React-jsiexecutor (= 0.72.4) + - React-jsinspector (= 0.72.4) + - React-perflogger (= 0.72.4) + - React-jsi (0.72.4): + - boost (= 1.76.0) + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-jsiexecutor (0.72.4): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-cxxreact (= 0.72.4) + - React-jsi (= 0.72.4) + - React-perflogger (= 0.72.4) + - React-jsinspector (0.72.4) + - React-logger (0.72.4): + - glog + - react-native-airship (15.2.6): + - AirshipFrameworkProxy (= 2.0.8) + - React-Core + - react-native-blob-util (0.17.3): + - React-Core + - react-native-cameraroll (5.4.0): + - React-Core + - react-native-config (1.4.6): + - react-native-config/App (= 1.4.6) + - react-native-config/App (1.4.6): + - React-Core + - react-native-document-picker (8.1.1): + - React-Core + - react-native-flipper (0.159.0): + - React-Core + - react-native-image-manipulator (1.0.5): + - React + - react-native-image-picker (5.1.0): + - React-Core + - react-native-key-command (1.0.1): + - React-Core + - react-native-netinfo (9.3.10): + - React-Core + - react-native-pager-view (6.2.0): + - React-Core + - react-native-pdf (6.7.1): + - React-Core + - react-native-performance (5.1.0): + - React-Core + - react-native-plaid-link-sdk (10.0.0): + - Plaid (~> 4.1.0) + - React-Core + - react-native-quick-sqlite (8.0.0-beta.2): + - React + - React-callinvoker + - React-Core + - react-native-render-html (6.3.1): + - React-Core + - react-native-safe-area-context (4.4.1): + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - ReactCommon/turbomodule/core + - react-native-view-shot (3.6.0): + - React-Core + - react-native-webview (11.23.0): + - React-Core + - React-NativeModulesApple (0.72.4): + - hermes-engine + - React-callinvoker + - React-Core + - React-cxxreact + - React-jsi + - React-runtimeexecutor + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - React-perflogger (0.72.4) + - React-RCTActionSheet (0.72.4): + - React-Core/RCTActionSheetHeaders (= 0.72.4) + - React-RCTAnimation (0.72.4): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.4) + - React-Codegen (= 0.72.4) + - React-Core/RCTAnimationHeaders (= 0.72.4) + - React-jsi (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - React-RCTAppDelegate (0.72.4): + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - React-CoreModules + - React-hermes + - React-NativeModulesApple + - React-RCTImage + - React-RCTNetwork + - React-runtimescheduler + - ReactCommon/turbomodule/core + - React-RCTBlob (0.72.4): + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-Codegen (= 0.72.4) + - React-Core/RCTBlobHeaders (= 0.72.4) + - React-Core/RCTWebSocket (= 0.72.4) + - React-jsi (= 0.72.4) + - React-RCTNetwork (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - React-RCTImage (0.72.4): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.4) + - React-Codegen (= 0.72.4) + - React-Core/RCTImageHeaders (= 0.72.4) + - React-jsi (= 0.72.4) + - React-RCTNetwork (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - React-RCTLinking (0.72.4): + - React-Codegen (= 0.72.4) + - React-Core/RCTLinkingHeaders (= 0.72.4) + - React-jsi (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - React-RCTNetwork (0.72.4): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.4) + - React-Codegen (= 0.72.4) + - React-Core/RCTNetworkHeaders (= 0.72.4) + - React-jsi (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - React-RCTSettings (0.72.4): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.4) + - React-Codegen (= 0.72.4) + - React-Core/RCTSettingsHeaders (= 0.72.4) + - React-jsi (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - React-RCTText (0.72.4): + - React-Core/RCTTextHeaders (= 0.72.4) + - React-RCTVibration (0.72.4): + - RCT-Folly (= 2021.07.22.00) + - React-Codegen (= 0.72.4) + - React-Core/RCTVibrationHeaders (= 0.72.4) + - React-jsi (= 0.72.4) + - ReactCommon/turbomodule/core (= 0.72.4) + - React-rncore (0.72.4) + - React-runtimeexecutor (0.72.4): + - React-jsi (= 0.72.4) + - React-runtimescheduler (0.72.4): + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker + - React-debug + - React-jsi + - React-runtimeexecutor + - React-utils (0.72.4): + - glog + - RCT-Folly (= 2021.07.22.00) + - React-debug + - ReactCommon/turbomodule/bridging (0.72.4): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.72.4) + - React-cxxreact (= 0.72.4) + - React-jsi (= 0.72.4) + - React-logger (= 0.72.4) + - React-perflogger (= 0.72.4) + - ReactCommon/turbomodule/core (0.72.4): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.72.4) + - React-cxxreact (= 0.72.4) + - React-jsi (= 0.72.4) + - React-logger (= 0.72.4) + - React-perflogger (= 0.72.4) + - RNAppleAuthentication (2.2.2): + - React-Core + - RNCAsyncStorage (1.17.11): + - React-Core + - RNCClipboard (1.5.1): + - React-Core + - RNCPicker (2.4.4): + - React-Core + - RNDateTimePicker (3.5.2): + - React-Core + - RNDeviceInfo (10.3.0): + - React-Core + - RNDevMenu (4.1.1): + - React-Core + - React-Core/DevSupport + - React-RCTNetwork + - RNFastImage (8.6.3): + - React-Core + - SDWebImage (~> 5.11.1) + - SDWebImageWebPCoder (~> 0.8.4) + - RNFBAnalytics (12.9.3): + - Firebase/Analytics (= 8.8.0) + - React-Core + - RNFBApp + - RNFBApp (12.9.3): + - Firebase/CoreOnly (= 8.8.0) + - React-Core + - RNFBCrashlytics (12.9.3): + - Firebase/Crashlytics (= 8.8.0) + - React-Core + - RNFBApp + - RNFBPerf (12.9.3): + - Firebase/Performance (= 8.8.0) + - React-Core + - RNFBApp + - RNFS (2.20.0): + - React-Core + - RNGestureHandler (2.12.0): + - React-Core + - RNGoogleSignin (10.0.1): + - GoogleSignIn (~> 7.0) + - React-Core + - RNLocalize (2.2.6): + - React-Core + - rnmapbox-maps (10.0.11): + - MapboxMaps (~> 10.14.0) + - React + - React-Core + - rnmapbox-maps/DynamicLibrary (= 10.0.11) + - Turf + - rnmapbox-maps/DynamicLibrary (10.0.11): + - MapboxMaps (~> 10.14.0) + - React + - React-Core + - Turf + - RNPermissions (3.6.1): + - React-Core + - RNReactNativeHapticFeedback (1.14.0): + - React-Core + - RNReanimated (3.4.0): + - DoubleConversion + - FBLazyVector + - glog + - hermes-engine + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-Core/DevSupport + - React-Core/RCTWebSocket + - React-CoreModules + - React-cxxreact + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector + - React-RCTActionSheet + - React-RCTAnimation + - React-RCTAppDelegate + - React-RCTBlob + - React-RCTImage + - React-RCTLinking + - React-RCTNetwork + - React-RCTSettings + - React-RCTText + - ReactCommon/turbomodule/core + - Yoga + - RNScreens (3.21.0): + - React-Core + - React-RCTImage + - RNSVG (13.13.0): + - React-Core + - SDWebImage (5.11.1): + - SDWebImage/Core (= 5.11.1) + - SDWebImage/Core (5.11.1) + - SDWebImageWebPCoder (0.8.5): + - libwebp (~> 1.0) + - SDWebImage/Core (~> 5.10) + - SocketRocket (0.6.1) + - Turf (2.6.1) + - VisionCamera (2.15.4): + - React + - React-callinvoker + - React-Core + - Yoga (1.14.0) + - YogaKit (1.18.1): + - Yoga (~> 1.14) + +DEPENDENCIES: + - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) + - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) + - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) + - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) + - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) + - Flipper (= 0.182.0) + - Flipper-Boost-iOSX (= 1.76.0.1.11) + - Flipper-DoubleConversion (= 3.2.0.1) + - Flipper-Fmt (= 7.1.7) + - Flipper-Folly (= 2.6.10) + - Flipper-Glog (= 0.5.0.5) + - Flipper-PeerTalk (= 0.0.4) + - FlipperKit (= 0.182.0) + - FlipperKit/Core (= 0.182.0) + - FlipperKit/CppBridge (= 0.182.0) + - FlipperKit/FBCxxFollyDynamicConvert (= 0.182.0) + - FlipperKit/FBDefines (= 0.182.0) + - FlipperKit/FKPortForwarding (= 0.182.0) + - FlipperKit/FlipperKitHighlightOverlay (= 0.182.0) + - FlipperKit/FlipperKitLayoutPlugin (= 0.182.0) + - FlipperKit/FlipperKitLayoutTextSearchable (= 0.182.0) + - FlipperKit/FlipperKitNetworkPlugin (= 0.182.0) + - FlipperKit/FlipperKitReactPlugin (= 0.182.0) + - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.182.0) + - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) + - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) + - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - libevent (~> 2.1.12) + - lottie-react-native (from `../node_modules/lottie-react-native`) + - "onfido-react-native-sdk (from `../node_modules/@onfido/react-native-sdk`)" + - OpenSSL-Universal (= 1.1.1100) + - Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`) + - Permission-LocationAccuracy (from `../node_modules/react-native-permissions/ios/LocationAccuracy`) + - Permission-LocationAlways (from `../node_modules/react-native-permissions/ios/LocationAlways`) + - Permission-LocationWhenInUse (from `../node_modules/react-native-permissions/ios/LocationWhenInUse`) + - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) + - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) + - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) + - React (from `../node_modules/react-native/`) + - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) + - React-Codegen (from `build/generated/ios`) + - React-Core (from `../node_modules/react-native/`) + - React-Core/DevSupport (from `../node_modules/react-native/`) + - React-Core/RCTWebSocket (from `../node_modules/react-native/`) + - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) + - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) + - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) + - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) + - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) + - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) + - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) + - React-logger (from `../node_modules/react-native/ReactCommon/logger`) + - "react-native-airship (from `../node_modules/@ua/react-native-airship`)" + - react-native-blob-util (from `../node_modules/react-native-blob-util`) + - "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)" + - react-native-config (from `../node_modules/react-native-config`) + - react-native-document-picker (from `../node_modules/react-native-document-picker`) + - react-native-flipper (from `../node_modules/react-native-flipper`) + - "react-native-image-manipulator (from `../node_modules/@oguzhnatly/react-native-image-manipulator`)" + - react-native-image-picker (from `../node_modules/react-native-image-picker`) + - react-native-key-command (from `../node_modules/react-native-key-command`) + - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" + - react-native-pager-view (from `../node_modules/react-native-pager-view`) + - react-native-pdf (from `../node_modules/react-native-pdf`) + - react-native-performance (from `../node_modules/react-native-performance`) + - react-native-plaid-link-sdk (from `../node_modules/react-native-plaid-link-sdk`) + - react-native-quick-sqlite (from `../node_modules/react-native-quick-sqlite`) + - react-native-render-html (from `../node_modules/react-native-render-html`) + - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) + - react-native-view-shot (from `../node_modules/react-native-view-shot`) + - react-native-webview (from `../node_modules/react-native-webview`) + - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) + - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) + - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) + - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) + - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) + - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) + - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) + - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) + - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) + - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) + - React-RCTText (from `../node_modules/react-native/Libraries/Text`) + - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) + - React-rncore (from `../node_modules/react-native/ReactCommon`) + - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) + - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) + - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) + - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - "RNAppleAuthentication (from `../node_modules/@invertase/react-native-apple-authentication`)" + - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" + - "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)" + - "RNCPicker (from `../node_modules/@react-native-picker/picker`)" + - "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)" + - RNDeviceInfo (from `../node_modules/react-native-device-info`) + - RNDevMenu (from `../node_modules/react-native-dev-menu`) + - RNFastImage (from `../node_modules/react-native-fast-image`) + - "RNFBAnalytics (from `../node_modules/@react-native-firebase/analytics`)" + - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" + - "RNFBCrashlytics (from `../node_modules/@react-native-firebase/crashlytics`)" + - "RNFBPerf (from `../node_modules/@react-native-firebase/perf`)" + - RNFS (from `../node_modules/react-native-fs`) + - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - "RNGoogleSignin (from `../node_modules/@react-native-google-signin/google-signin`)" + - RNLocalize (from `../node_modules/react-native-localize`) + - "rnmapbox-maps (from `../node_modules/@rnmapbox/maps`)" + - RNPermissions (from `../node_modules/react-native-permissions`) + - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) + - RNReanimated (from `../node_modules/react-native-reanimated`) + - RNScreens (from `../node_modules/react-native-screens`) + - RNSVG (from `../node_modules/react-native-svg`) + - VisionCamera (from `../node_modules/react-native-vision-camera`) + - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) + +SPEC REPOS: + trunk: + - Airship + - AirshipFrameworkProxy + - AppAuth + - CocoaAsyncSocket + - Firebase + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreDiagnostics + - FirebaseCrashlytics + - FirebaseInstallations + - FirebasePerformance + - FirebaseRemoteConfig + - Flipper + - Flipper-Boost-iOSX + - Flipper-DoubleConversion + - Flipper-Fmt + - Flipper-Folly + - Flipper-Glog + - Flipper-PeerTalk + - FlipperKit + - fmt + - GoogleAppMeasurement + - GoogleDataTransport + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher + - libevent + - libwebp + - lottie-ios + - MapboxCommon + - MapboxCoreMaps + - MapboxMaps + - MapboxMobileEvents + - nanopb + - Onfido + - OpenSSL-Universal + - Plaid + - PromisesObjC + - SDWebImage + - SDWebImageWebPCoder + - SocketRocket + - Turf + - YogaKit + +EXTERNAL SOURCES: + boost: + :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" + BVLinearGradient: + :path: "../node_modules/react-native-linear-gradient" + DoubleConversion: + :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" + FBLazyVector: + :path: "../node_modules/react-native/Libraries/FBLazyVector" + FBReactNativeSpec: + :path: "../node_modules/react-native/React/FBReactNativeSpec" + glog: + :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" + hermes-engine: + :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" + :tag: hermes-2023-08-07-RNv0.72.4-813b2def12bc9df02654b3e3653ae4a68d0572e0 + lottie-react-native: + :path: "../node_modules/lottie-react-native" + onfido-react-native-sdk: + :path: "../node_modules/@onfido/react-native-sdk" + Permission-Camera: + :path: "../node_modules/react-native-permissions/ios/Camera" + Permission-LocationAccuracy: + :path: "../node_modules/react-native-permissions/ios/LocationAccuracy" + Permission-LocationAlways: + :path: "../node_modules/react-native-permissions/ios/LocationAlways" + Permission-LocationWhenInUse: + :path: "../node_modules/react-native-permissions/ios/LocationWhenInUse" + RCT-Folly: + :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" + RCTRequired: + :path: "../node_modules/react-native/Libraries/RCTRequired" + RCTTypeSafety: + :path: "../node_modules/react-native/Libraries/TypeSafety" + React: + :path: "../node_modules/react-native/" + React-callinvoker: + :path: "../node_modules/react-native/ReactCommon/callinvoker" + React-Codegen: + :path: build/generated/ios + React-Core: + :path: "../node_modules/react-native/" + React-CoreModules: + :path: "../node_modules/react-native/React/CoreModules" + React-cxxreact: + :path: "../node_modules/react-native/ReactCommon/cxxreact" + React-debug: + :path: "../node_modules/react-native/ReactCommon/react/debug" + React-hermes: + :path: "../node_modules/react-native/ReactCommon/hermes" + React-jsi: + :path: "../node_modules/react-native/ReactCommon/jsi" + React-jsiexecutor: + :path: "../node_modules/react-native/ReactCommon/jsiexecutor" + React-jsinspector: + :path: "../node_modules/react-native/ReactCommon/jsinspector" + React-logger: + :path: "../node_modules/react-native/ReactCommon/logger" + react-native-airship: + :path: "../node_modules/@ua/react-native-airship" + react-native-blob-util: + :path: "../node_modules/react-native-blob-util" + react-native-cameraroll: + :path: "../node_modules/@react-native-camera-roll/camera-roll" + react-native-config: + :path: "../node_modules/react-native-config" + react-native-document-picker: + :path: "../node_modules/react-native-document-picker" + react-native-flipper: + :path: "../node_modules/react-native-flipper" + react-native-image-manipulator: + :path: "../node_modules/@oguzhnatly/react-native-image-manipulator" + react-native-image-picker: + :path: "../node_modules/react-native-image-picker" + react-native-key-command: + :path: "../node_modules/react-native-key-command" + react-native-netinfo: + :path: "../node_modules/@react-native-community/netinfo" + react-native-pager-view: + :path: "../node_modules/react-native-pager-view" + react-native-pdf: + :path: "../node_modules/react-native-pdf" + react-native-performance: + :path: "../node_modules/react-native-performance" + react-native-plaid-link-sdk: + :path: "../node_modules/react-native-plaid-link-sdk" + react-native-quick-sqlite: + :path: "../node_modules/react-native-quick-sqlite" + react-native-render-html: + :path: "../node_modules/react-native-render-html" + react-native-safe-area-context: + :path: "../node_modules/react-native-safe-area-context" + react-native-view-shot: + :path: "../node_modules/react-native-view-shot" + react-native-webview: + :path: "../node_modules/react-native-webview" + React-NativeModulesApple: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" + React-perflogger: + :path: "../node_modules/react-native/ReactCommon/reactperflogger" + React-RCTActionSheet: + :path: "../node_modules/react-native/Libraries/ActionSheetIOS" + React-RCTAnimation: + :path: "../node_modules/react-native/Libraries/NativeAnimation" + React-RCTAppDelegate: + :path: "../node_modules/react-native/Libraries/AppDelegate" + React-RCTBlob: + :path: "../node_modules/react-native/Libraries/Blob" + React-RCTImage: + :path: "../node_modules/react-native/Libraries/Image" + React-RCTLinking: + :path: "../node_modules/react-native/Libraries/LinkingIOS" + React-RCTNetwork: + :path: "../node_modules/react-native/Libraries/Network" + React-RCTSettings: + :path: "../node_modules/react-native/Libraries/Settings" + React-RCTText: + :path: "../node_modules/react-native/Libraries/Text" + React-RCTVibration: + :path: "../node_modules/react-native/Libraries/Vibration" + React-rncore: + :path: "../node_modules/react-native/ReactCommon" + React-runtimeexecutor: + :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" + React-runtimescheduler: + :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" + React-utils: + :path: "../node_modules/react-native/ReactCommon/react/utils" + ReactCommon: + :path: "../node_modules/react-native/ReactCommon" + RNAppleAuthentication: + :path: "../node_modules/@invertase/react-native-apple-authentication" + RNCAsyncStorage: + :path: "../node_modules/@react-native-async-storage/async-storage" + RNCClipboard: + :path: "../node_modules/@react-native-community/clipboard" + RNCPicker: + :path: "../node_modules/@react-native-picker/picker" + RNDateTimePicker: + :path: "../node_modules/@react-native-community/datetimepicker" + RNDeviceInfo: + :path: "../node_modules/react-native-device-info" + RNDevMenu: + :path: "../node_modules/react-native-dev-menu" + RNFastImage: + :path: "../node_modules/react-native-fast-image" + RNFBAnalytics: + :path: "../node_modules/@react-native-firebase/analytics" + RNFBApp: + :path: "../node_modules/@react-native-firebase/app" + RNFBCrashlytics: + :path: "../node_modules/@react-native-firebase/crashlytics" + RNFBPerf: + :path: "../node_modules/@react-native-firebase/perf" + RNFS: + :path: "../node_modules/react-native-fs" + RNGestureHandler: + :path: "../node_modules/react-native-gesture-handler" + RNGoogleSignin: + :path: "../node_modules/@react-native-google-signin/google-signin" + RNLocalize: + :path: "../node_modules/react-native-localize" + rnmapbox-maps: + :path: "../node_modules/@rnmapbox/maps" + RNPermissions: + :path: "../node_modules/react-native-permissions" + RNReactNativeHapticFeedback: + :path: "../node_modules/react-native-haptic-feedback" + RNReanimated: + :path: "../node_modules/react-native-reanimated" + RNScreens: + :path: "../node_modules/react-native-screens" + RNSVG: + :path: "../node_modules/react-native-svg" + VisionCamera: + :path: "../node_modules/react-native-vision-camera" + Yoga: + :path: "../node_modules/react-native/ReactCommon/yoga" + +SPEC CHECKSUMS: + Airship: c70eed50e429f97f5adb285423c7291fb7a032ae + AirshipFrameworkProxy: 7bc4130c668c6c98e2d4c60fe4c9eb61a999be99 + AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570 + boost: 57d2868c099736d80fcd648bf211b4431e51a558 + BVLinearGradient: 421743791a59d259aec53f4c58793aad031da2ca + CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 + DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 + FBLazyVector: 5d4a3b7f411219a45a6d952f77d2c0a6c9989da5 + FBReactNativeSpec: 3fc2d478e1c4b08276f9dd9128f80ec6d5d85c1f + Firebase: 629510f1a9ddb235f3a7c5c8ceb23ba887f0f814 + FirebaseABTesting: 10cbce8db9985ae2e3847ea44e9947dd18f94e10 + FirebaseAnalytics: 5506ea8b867d8423485a84b4cd612d279f7b0b8a + FirebaseCore: 98b29e3828f0a53651c363937a7f7d92a19f1ba2 + FirebaseCoreDiagnostics: 92e07a649aeb66352b319d43bdd2ee3942af84cb + FirebaseCrashlytics: 3660c045c8e45cc4276110562a0ef44cf43c8157 + FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd + FirebasePerformance: 0c01a7a496657d7cea86d40c0b1725259d164c6c + FirebaseRemoteConfig: 2d6e2cfdb49af79535c8af8a80a4a5009038ec2b + Flipper: 6edb735e6c3e332975d1b17956bcc584eccf5818 + Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c + Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 + Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b + Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 + Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 + Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 + FlipperKit: 2efad7007d6745a3f95e4034d547be637f89d3f6 + fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 + glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b + GoogleAppMeasurement: 5ba1164e3c844ba84272555e916d0a6d3d977e91 + GoogleDataTransport: f0308f5905a745f94fb91fea9c6cbaf3831cb1bd + GoogleSignIn: b232380cf495a429b8095d3178a8d5855b42e842 + GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749 + GTMAppAuth: 99fb010047ba3973b7026e45393f51f27ab965ae + GTMSessionFetcher: e8647203b65cee28c5f73d0f473d096653945e72 + hermes-engine: 81191603c4eaa01f5e4ae5737a9efcf64756c7b2 + libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 + libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef + lottie-ios: 8f97d3271e155c2d688875c29cd3c74908aef5f8 + lottie-react-native: 8f9d4be452e23f6e5ca0fdc11669dc99ab52be81 + MapboxCommon: 4a0251dd470ee37e7fadda8e285c01921a5e1eb0 + MapboxCoreMaps: eb07203bbb0b1509395db5ab89cd3ad6c2e3c04c + MapboxMaps: af50ec61a7eb3b032c3f7962c6bd671d93d2a209 + MapboxMobileEvents: de50b3a4de180dd129c326e09cd12c8adaaa46d6 + nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 + Onfido: e36f284b865adcf99d9c905590a64ac09d4a576b + onfido-react-native-sdk: 4ecde1a97435dcff9f00a878e3f8d1eb14fabbdc + OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c + Permission-Camera: bf6791b17c7f614b6826019fcfdcc286d3a107f6 + Permission-LocationAccuracy: 76df17de5c6b8bc2eee34e61ee92cdd7a864c73d + Permission-LocationAlways: 8d99b025c9f73c696e0cdb367e42525f2e9a26f2 + Permission-LocationWhenInUse: 3ba99e45c852763f730eabecec2870c2382b7bd4 + Plaid: 7d340abeadb46c7aa1a91f896c5b22395a31fcf2 + PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef + RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 + RCTRequired: c0569ecc035894e4a68baecb30fe6a7ea6e399f9 + RCTTypeSafety: e90354072c21236e0bcf1699011e39acd25fea2f + React: a1be3c6dc0a6e949ccd3e659781aa47bbae1868f + React-callinvoker: 1020b33f6cb1a1824f9ca2a86609fbce2a73c6ed + React-Codegen: a0a26badf098d4a779acda922caf74f6ecabed28 + React-Core: 52075b80f10c26f62219d7b5d13d7d8089f027b3 + React-CoreModules: 21abab85d7ad9038ce2b1c33d39e3baaf7dc9244 + React-cxxreact: 4ad1cc861e32fb533dad6ff7a4ea25680fa1c994 + React-debug: 17366a3d5c5d2f5fc04f09101a4af38cb42b54ae + React-hermes: 37377d0a56aa0cf55c65248271866ce3268cde3f + React-jsi: 6de8b0ccc6b765b58e4eee9ee38049dbeaf5c221 + React-jsiexecutor: c7f826e40fa9cab5d37cab6130b1af237332b594 + React-jsinspector: aaed4cf551c4a1c98092436518c2d267b13a673f + React-logger: da1ebe05ae06eb6db4b162202faeafac4b435e77 + react-native-airship: 5d19f4ba303481cf4101ff9dee9249ef6a8a6b64 + react-native-blob-util: 99f4d79189252f597fe0d810c57a3733b1b1dea6 + react-native-cameraroll: 8ffb0af7a5e5de225fd667610e2979fc1f0c2151 + react-native-config: 7cd105e71d903104e8919261480858940a6b9c0e + react-native-document-picker: f68191637788994baed5f57d12994aa32cf8bf88 + react-native-flipper: dc5290261fbeeb2faec1bdc57ae6dd8d562e1de4 + react-native-image-manipulator: c48f64221cfcd46e9eec53619c4c0374f3328a56 + react-native-image-picker: c33d4e79f0a14a2b66e5065e14946ae63749660b + react-native-key-command: c2645ec01eb1fa664606c09480c05cb4220ef67b + react-native-netinfo: ccbe1085dffd16592791d550189772e13bf479e2 + react-native-pager-view: 0ccb8bf60e2ebd38b1f3669fa3650ecce81db2df + react-native-pdf: 7c0e91ada997bac8bac3bb5bea5b6b81f5a3caae + react-native-performance: cef2b618d47b277fb5c3280b81a3aad1e72f2886 + react-native-plaid-link-sdk: 9eb0f71dad94b3bdde649c7a384cba93024af46c + react-native-quick-sqlite: bcc7a7a250a40222f18913a97cd356bf82d0a6c4 + react-native-render-html: 96c979fe7452a0a41559685d2f83b12b93edac8c + react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a + react-native-view-shot: 705f999ac2a24e4e6c909c0ca65c732ed33ca2ff + react-native-webview: e771bc375f789ebfa02a26939a57dbc6fa897336 + React-NativeModulesApple: edb5ace14f73f4969df6e7b1f3e41bef0012740f + React-perflogger: 496a1a3dc6737f964107cb3ddae7f9e265ddda58 + React-RCTActionSheet: 02904b932b50e680f4e26e7a686b33ebf7ef3c00 + React-RCTAnimation: 88feaf0a85648fb8fd497ce749829774910276d6 + React-RCTAppDelegate: 5792ac0f0feccb584765fdd7aa81ea320c4d9b0b + React-RCTBlob: 0dbc9e2a13d241b37d46b53e54630cbad1f0e141 + React-RCTImage: b111645ab901f8e59fc68fbe31f5731bdbeef087 + React-RCTLinking: 3d719727b4c098aad3588aa3559361ee0579f5de + React-RCTNetwork: b44d3580be05d74556ba4efbf53570f17e38f734 + React-RCTSettings: c0c54b330442c29874cd4dae6e94190dc11a6f6f + React-RCTText: 9b9f5589d9b649d7246c3f336e116496df28cfe6 + React-RCTVibration: 691c67f3beaf1d084ceed5eb5c1dddd9afa8591e + React-rncore: 142268f6c92e296dc079aadda3fade778562f9e4 + React-runtimeexecutor: d465ba0c47ef3ed8281143f59605cacc2244d5c7 + React-runtimescheduler: 4941cc1b3cf08b792fbf666342c9fc95f1969035 + React-utils: b79f2411931f9d3ea5781404dcbb2fa8a837e13a + ReactCommon: 4b2bdcb50a3543e1c2b2849ad44533686610826d + RNAppleAuthentication: 0571c08da8c327ae2afc0261b48b4a515b0286a6 + RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 + RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495 + RNCPicker: 0b65be85fe7954fbb2062ef079e3d1cde252d888 + RNDateTimePicker: 7658208086d86d09e1627b5c34ba0cf237c60140 + RNDeviceInfo: 4701f0bf2a06b34654745053db0ce4cb0c53ada7 + RNDevMenu: 72807568fe4188bd4c40ce32675d82434b43c45d + RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8 + RNFBAnalytics: f76bfa164ac235b00505deb9fc1776634056898c + RNFBApp: 729c0666395b1953198dc4a1ec6deb8fbe1c302e + RNFBCrashlytics: 2061ca863e8e2fa1aae9b12477d7dfa8e88ca0f9 + RNFBPerf: 389914cda4000fe0d996a752532a591132cbf3f9 + RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 + RNGestureHandler: dec4645026e7401a0899f2846d864403478ff6a5 + RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0 + RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 + rnmapbox-maps: 6f638ec002aa6e906a6f766d69cd45f968d98e64 + RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c + RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c + RNReanimated: 020859659f64be2d30849a1fe88c821a7c3e0cbf + RNScreens: d037903436160a4b039d32606668350d2a808806 + RNSVG: ed492aaf3af9ca01bc945f7a149d76d62e73ec82 + SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d + SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d + SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 + Turf: 469ce2c3d22e5e8e4818d5a3b254699a5c89efa4 + VisionCamera: d3ec8883417a6a4a0e3a6ba37d81d22db7611601 + Yoga: 3efc43e0d48686ce2e8c60f99d4e6bd349aff981 + YogaKit: f782866e155069a2cca2517aafea43200b01fd5a + +PODFILE CHECKSUM: 2daf34c870819a933f3fefe426801d54b2ff2a14 + +COCOAPODS: 1.12.1 From 39bd03a80919b9411113987b3219803ee27cb2da Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 5 Oct 2023 09:44:32 +0200 Subject: [PATCH 08/65] podfile.lock update content --- ios/Podfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 51b9f6af0e21..f157e8d0558a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -783,7 +783,7 @@ PODS: - React-Core - RNReactNativeHapticFeedback (1.14.0): - React-Core - - RNReanimated (3.4.0): + - RNReanimated (3.5.4): - DoubleConversion - FBLazyVector - glog @@ -1298,7 +1298,7 @@ SPEC CHECKSUMS: rnmapbox-maps: 6f638ec002aa6e906a6f766d69cd45f968d98e64 RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c - RNReanimated: 020859659f64be2d30849a1fe88c821a7c3e0cbf + RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 RNScreens: d037903436160a4b039d32606668350d2a808806 RNSVG: ed492aaf3af9ca01bc945f7a149d76d62e73ec82 SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d @@ -1311,4 +1311,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 2daf34c870819a933f3fefe426801d54b2ff2a14 -COCOAPODS: 1.12.1 +COCOAPODS: 1.12.1 \ No newline at end of file From c9cb983370a591f5c141edbca2a1c78850697c75 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 5 Oct 2023 11:00:39 +0200 Subject: [PATCH 09/65] podfile.lock empty space missing --- ios/Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f157e8d0558a..ba53d939e46c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1311,4 +1311,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 2daf34c870819a933f3fefe426801d54b2ff2a14 -COCOAPODS: 1.12.1 \ No newline at end of file +COCOAPODS: 1.12.1 From 5bc5c7684049d05889882e44af6f27f8d9444133 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Fri, 6 Oct 2023 07:09:14 +0200 Subject: [PATCH 10/65] Update src/components/AvatarWithImagePicker.js Co-authored-by: Eugene Voloshchak --- src/components/AvatarWithImagePicker.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 156c08254a95..c7523cdef942 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -137,7 +137,8 @@ function AvatarWithImagePicker({ anchorPosition, anchorAlignment, onImageSelected, - editorMaskImage }) { + editorMaskImage, +}) { const animation = useRef(new SpinningIndicatorAnimation()).current; const [isMenuVisible, setIsMenuVisible] = useState(false); From 06cd120a850b3c88eba752c02d513234dda00570 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Fri, 6 Oct 2023 07:17:06 +0200 Subject: [PATCH 11/65] pr updates --- src/components/AvatarWithImagePicker.js | 68 ++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index c7523cdef942..8360e323d4ce 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -275,45 +275,45 @@ function AvatarWithImagePicker({ const additionalStyles = _.isArray(style) ? style : [style]; - /** + /** * Create menu items list for avatar menu * * @param {Function} openPicker * @returns {Array} */ - const createMenuItems = (openPicker) => { - const menuItems = [ - { - icon: Expensicons.Upload, - text: translate('avatarWithImagePicker.uploadPhoto'), - onSelected: () => { - if (Browser.isSafari()) { - return; - } - openPicker({ - onPicked: showAvatarCropModal, - }); - }, - }, - ]; + const createMenuItems = (openPicker) => { + const menuItems = [ + { + icon: Expensicons.Upload, + text: translate('avatarWithImagePicker.uploadPhoto'), + onSelected: () => { + if (Browser.isSafari()) { + return; + } + openPicker({ + onPicked: showAvatarCropModal, + }); + }, + }, + ]; - // If current avatar isn't a default avatar, allow Remove Photo option - if (!isUsingDefaultAvatar) { - menuItems.push({ - icon: Expensicons.Trashcan, - text: translate('avatarWithImagePicker.removePhoto'), - onSelected: () => { - setError(null, {}); - onImageRemoved(); - }, - }); - } - return menuItems; - }; + // If current avatar isn't a default avatar, allow Remove Photo option + if (!isUsingDefaultAvatar) { + menuItems.push({ + icon: Expensicons.Trashcan, + text: translate('avatarWithImagePicker.removePhoto'), + onSelected: () => { + setError(null, {}); + onImageRemoved(); + }, + }); + } + return menuItems; + }; return ( - + - {({show}) => ( - - {({openPicker}) => { + {({show}) => ( + + {({openPicker}) => { const menuItems = createMenuItems(openPicker); // If the current avatar isn't a default avatar, allow the "View Photo" option @@ -423,4 +423,4 @@ function AvatarWithImagePicker({ AvatarWithImagePicker.propTypes = propTypes; AvatarWithImagePicker.defaultProps = defaultProps; -export default withNavigationFocus(AvatarWithImagePicker); \ No newline at end of file +export default withNavigationFocus(AvatarWithImagePicker); From 9159c3e9bba07b57462c3cad06d3b3817fe89215 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Fri, 6 Oct 2023 12:23:12 +0200 Subject: [PATCH 12/65] updates --- ios/Podfile.lock | 2 +- src/components/AvatarWithImagePicker.js | 58 +++++++------------------ 2 files changed, 17 insertions(+), 43 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ba53d939e46c..f157e8d0558a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1311,4 +1311,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 2daf34c870819a933f3fefe426801d54b2ff2a14 -COCOAPODS: 1.12.1 +COCOAPODS: 1.12.1 \ No newline at end of file diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 8360e323d4ce..bf14e9afb770 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -15,7 +15,6 @@ import OfflineWithFeedback from './OfflineWithFeedback'; import useLocalize from '../hooks/useLocalize'; 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'; @@ -113,7 +112,6 @@ const defaultProps = { headerTitle: '', previewSource: '', originalFileName: '', - displayName: `AvatarWithImagePicker`, }; function AvatarWithImagePicker({ @@ -140,7 +138,6 @@ function AvatarWithImagePicker({ editorMaskImage, }) { - const animation = useRef(new SpinningIndicatorAnimation()).current; const [isMenuVisible, setIsMenuVisible] = useState(false); const [errorData, setErrorData] = useState({ validationError: null, @@ -155,16 +152,6 @@ function AvatarWithImagePicker({ const anchorRef = useRef(); const {translate} = useLocalize(); - useEffect(() => { - if (isUploading) { - animation.start(); - } - - return () => { - animation.stop(); - }; - }, [isUploading]); - useEffect(() => { // check if the component is no longer focused, then reset the error. if (!isFocused) { @@ -190,7 +177,7 @@ function AvatarWithImagePicker({ * @returns {Boolean} */ const isValidExtension = (image) => { - const { fileExtension } = FileUtils.splitExtensionFromFileName(lodashGet(image, 'name', '')); + const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(image, 'name', '')); return _.contains(CONST.AVATAR_ALLOWED_EXTENSIONS, fileExtension.toLowerCase()); }; @@ -223,9 +210,18 @@ function AvatarWithImagePicker({ * * @param {Object} image */ - function showAvatarCropModal(image) { - const handleResolutionValidation = (isValidRes) => { - if (!isValidRes) { + const showAvatarCropModal = (image) => { + if (!isValidExtension(image)) { + setError('avatarWithImagePicker.notAllowedExtension', {allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS}); + return; + } + if (!isValidSize(image)) { + setError('avatarWithImagePicker.sizeExceeded', {maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024)}); + return; + } + + isValidResolution(image).then((isValid) => { + if (!isValid) { setError('avatarWithImagePicker.resolutionConstraints', { minHeightInPx: CONST.AVATAR_MIN_HEIGHT_PX, minWidthInPx: CONST.AVATAR_MIN_WIDTH_PX, @@ -234,7 +230,7 @@ function AvatarWithImagePicker({ }); return; } - + setIsAvatarCropModalOpen(true); setError(null, {}); setIsMenuVisible(false); @@ -243,31 +239,8 @@ function AvatarWithImagePicker({ name: image.name, type: image.type }); - }; - - return new Promise((resolve, reject) => { - if (!isValidExtension(image)) { - setError('avatarWithImagePicker.notAllowedExtension', { - allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS - }); - reject(new Error('Invalid extension')); - } - - if (!isValidSize(image)) { - setError('avatarWithImagePicker.sizeExceeded', { - maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024) - }); - reject(new Error('Invalid size')); - } - - resolve(image); - }) - .then(isValidResolution) - .then(handleResolutionValidation) - .catch(err => { - console.error("Error in showAvatarCropModal:", err); }); - } + }; const hideAvatarCropModal = () => { setIsAvatarCropModalOpen(false); @@ -422,5 +395,6 @@ function AvatarWithImagePicker({ AvatarWithImagePicker.propTypes = propTypes; AvatarWithImagePicker.defaultProps = defaultProps; +AvatarWithImagePicker.displayName = 'AvatarWithImagePicker'; export default withNavigationFocus(AvatarWithImagePicker); From f2427743df8ed7d74fd2db1b32514d53a774f7e9 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Mon, 9 Oct 2023 09:57:36 +0200 Subject: [PATCH 13/65] lint updates --- src/components/AvatarWithImagePicker.js | 261 ++++++++++++------------ 1 file changed, 131 insertions(+), 130 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index bf14e9afb770..743bf93acadf 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,6 +1,6 @@ import _ from 'underscore'; -import React, {useState, useRef, useEffect} from 'react'; -import {View} from 'react-native'; +import React, { useState, useRef, useEffect } from 'react'; +import { View } from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import Avatar from './Avatar'; @@ -23,8 +23,7 @@ import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import AttachmentModal from './AttachmentModal'; import DotIndicatorMessage from './DotIndicatorMessage'; import * as Browser from '../libs/Browser'; -import withNavigationFocus, {withNavigationFocusPropTypes} from './withNavigationFocus'; -import compose from '../libs/compose'; +import withNavigationFocus, { withNavigationFocusPropTypes } from './withNavigationFocus'; const propTypes = { /** Avatar source to display */ @@ -95,10 +94,10 @@ const propTypes = { const defaultProps = { source: '', - onImageSelected: () => {}, - onImageRemoved: () => {}, + onImageSelected: () => { }, + onImageRemoved: () => { }, style: [], - DefaultAvatar: () => {}, + DefaultAvatar: () => { }, isUsingDefaultAvatar: false, isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, @@ -106,7 +105,7 @@ const defaultProps = { type: CONST.ICON_TYPE_AVATAR, editorMaskImage: undefined, errorRowStyles: [], - onErrorClose: () => {}, + onErrorClose: () => { }, pendingAction: null, errors: null, headerTitle: '', @@ -114,35 +113,33 @@ const defaultProps = { originalFileName: '', }; -function AvatarWithImagePicker({ - isUploading, - isFocused, - DefaultAvatar, - style, - pendingAction, - errors, - errorRowStyles, - onErrorClose, - source, - fallbackIcon, - size, - type, - headerTitle, - previewSource, - originalFileName, - isUsingDefaultAvatar, - onImageRemoved, - anchorPosition, - anchorAlignment, - onImageSelected, +function AvatarWithImagePicker({ + isFocused, + DefaultAvatar, + style, + pendingAction, + errors, + errorRowStyles, + onErrorClose, + source, + fallbackIcon, + size, + type, + headerTitle, + previewSource, + originalFileName, + isUsingDefaultAvatar, + onImageRemoved, + anchorPosition, + anchorAlignment, + onImageSelected, editorMaskImage, }) { - const [isMenuVisible, setIsMenuVisible] = useState(false); const [errorData, setErrorData] = useState({ validationError: null, phraseParam: {}, - }); + }); const [isAvatarCropModalOpen, setIsAvatarCropModalOpen] = useState(false); const [imageData, setImageData] = useState({ uri: '', @@ -150,13 +147,16 @@ function AvatarWithImagePicker({ type: '' }); const anchorRef = useRef(); - const {translate} = useLocalize(); - + const { translate } = useLocalize(); + useEffect(() => { - // check if the component is no longer focused, then reset the error. - if (!isFocused) { - setError(null, {}); + // If the component is still focused, don't proceed further. + if (isFocused) { + return; } + + // Reset the error if the component is no longer focused. + setError(null, {}); }, [isFocused]); /** @@ -166,7 +166,7 @@ function AvatarWithImagePicker({ const setError = (error, phraseParam) => { setErrorData({ validationError: error, - phraseParam: phraseParam, + phraseParam, }); }; @@ -177,19 +177,17 @@ function AvatarWithImagePicker({ * @returns {Boolean} */ const isValidExtension = (image) => { - const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(image, 'name', '')); + 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. - * - * @param {Object} image - * @returns {Boolean} - */ - const isValidSize = (image) => { - return image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; - }; + /** + * Check if the attachment size is less than allowed size. + * + * @param {Object} image + * @returns {Boolean} + */ + const isValidSize = (image) => image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; /** * Check if the attachment resolution matches constraints. @@ -197,13 +195,16 @@ function AvatarWithImagePicker({ * @param {Object} image * @returns {Promise} */ - const isValidResolution = async (image) => { - const resolution = await getImageResolution(image); - return 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; + const isValidResolution = (image) => { + return getImageResolution(image) + .then(({ height, width }) => + height >= CONST.AVATAR_MIN_HEIGHT_PX && + width >= CONST.AVATAR_MIN_WIDTH_PX && + height <= CONST.AVATAR_MAX_HEIGHT_PX && + width <= CONST.AVATAR_MAX_WIDTH_PX + ); }; + /** * Validates if an image has a valid resolution and opens an avatar crop modal @@ -212,11 +213,11 @@ function AvatarWithImagePicker({ */ const showAvatarCropModal = (image) => { if (!isValidExtension(image)) { - setError('avatarWithImagePicker.notAllowedExtension', {allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS}); + setError('avatarWithImagePicker.notAllowedExtension', { allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS }); return; } if (!isValidSize(image)) { - setError('avatarWithImagePicker.sizeExceeded', {maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024)}); + setError('avatarWithImagePicker.sizeExceeded', { maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024) }); return; } @@ -262,14 +263,14 @@ function AvatarWithImagePicker({ onSelected: () => { if (Browser.isSafari()) { return; - } + } openPicker({ onPicked: showAvatarCropModal, - }); - }, - }, + }); + }, + }, ]; - + // If current avatar isn't a default avatar, allow Remove Photo option if (!isUsingDefaultAvatar) { menuItems.push({ @@ -278,65 +279,65 @@ function AvatarWithImagePicker({ onSelected: () => { setError(null, {}); onImageRemoved(); - }, - }); + }, + }); } return menuItems; - }; - + }; + return ( - - - setIsMenuVisible(prev => !prev)} - accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} - accessibilityLabel={translate('avatarWithImagePicker.editImage')} - disabled={isAvatarCropModalOpen} - ref={anchorRef} - > - - {source ? ( - - ) : ( - - )} - - - + + setIsMenuVisible(prev => !prev)} + accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} + accessibilityLabel={translate('avatarWithImagePicker.editImage')} + disabled={isAvatarCropModalOpen} + ref={anchorRef} + > + + {source ? ( + - - - - - - {({show}) => ( + ) : ( + + )} + + + + + + + + + {({ show }) => ( - {({openPicker}) => { + {({ openPicker }) => { const menuItems = createMenuItems(openPicker); - + // If the current avatar isn't a default avatar, allow the "View Photo" option if (!isUsingDefaultAvatar) { menuItems.push({ @@ -345,7 +346,7 @@ function AvatarWithImagePicker({ onSelected: show, }); } - + return ( - )} - - - {errorData.validationError && ( - - )} - + + {errorData.validationError && ( + + )} + ); } From 379c274a9e72d40f834f32a72ea1d665ab570e91 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Tue, 10 Oct 2023 08:40:03 +0200 Subject: [PATCH 14/65] pr empty sapces fix --- src/components/AvatarWithImagePicker.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 743bf93acadf..93c90008d34c 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,6 +1,6 @@ import _ from 'underscore'; -import React, { useState, useRef, useEffect } from 'react'; -import { View } from 'react-native'; +import React, {useState, useRef, useEffect} from 'react'; +import {View} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import Avatar from './Avatar'; @@ -23,7 +23,7 @@ import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import AttachmentModal from './AttachmentModal'; import DotIndicatorMessage from './DotIndicatorMessage'; import * as Browser from '../libs/Browser'; -import withNavigationFocus, { withNavigationFocusPropTypes } from './withNavigationFocus'; +import withNavigationFocus, {withNavigationFocusPropTypes} from './withNavigationFocus'; const propTypes = { /** Avatar source to display */ @@ -94,10 +94,10 @@ const propTypes = { const defaultProps = { source: '', - onImageSelected: () => { }, - onImageRemoved: () => { }, + onImageSelected: () => {}, + onImageRemoved: () => {}, style: [], - DefaultAvatar: () => { }, + DefaultAvatar: () => {}, isUsingDefaultAvatar: false, isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, @@ -105,7 +105,7 @@ const defaultProps = { type: CONST.ICON_TYPE_AVATAR, editorMaskImage: undefined, errorRowStyles: [], - onErrorClose: () => { }, + onErrorClose: () => {}, pendingAction: null, errors: null, headerTitle: '', @@ -147,7 +147,7 @@ function AvatarWithImagePicker({ type: '' }); const anchorRef = useRef(); - const { translate } = useLocalize(); + const {translate} = useLocalize(); useEffect(() => { // If the component is still focused, don't proceed further. From 09b694380c6cec4f03a21b3bc5621aab32e15667 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Tue, 10 Oct 2023 14:27:06 +0200 Subject: [PATCH 15/65] lint fix --- src/components/AvatarWithImagePicker.js | 45 +++++++++++-------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 93c90008d34c..01522a09fe75 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -52,9 +52,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]), @@ -99,7 +96,6 @@ const defaultProps = { style: [], DefaultAvatar: () => {}, isUsingDefaultAvatar: false, - isUploading: false, size: CONST.AVATAR_SIZE.DEFAULT, fallbackIcon: Expensicons.FallbackAvatar, type: CONST.ICON_TYPE_AVATAR, @@ -148,9 +144,19 @@ function AvatarWithImagePicker({ }); const anchorRef = useRef(); const {translate} = useLocalize(); + + /** + * @param {String} error + * @param {Object} phraseParam + */ + const setError = (error, phraseParam) => { + setErrorData({ + validationError: error, + phraseParam, + }); + }; useEffect(() => { - // If the component is still focused, don't proceed further. if (isFocused) { return; } @@ -159,17 +165,6 @@ function AvatarWithImagePicker({ setError(null, {}); }, [isFocused]); - /** - * @param {String} error - * @param {Object} phraseParam - */ - const setError = (error, phraseParam) => { - setErrorData({ - validationError: error, - phraseParam, - }); - }; - /** * Check if the attachment extension is allowed. * @@ -195,16 +190,14 @@ function AvatarWithImagePicker({ * @param {Object} image * @returns {Promise} */ - const isValidResolution = (image) => { - return getImageResolution(image) - .then(({ height, width }) => - height >= CONST.AVATAR_MIN_HEIGHT_PX && - width >= CONST.AVATAR_MIN_WIDTH_PX && - height <= CONST.AVATAR_MAX_HEIGHT_PX && - width <= CONST.AVATAR_MAX_WIDTH_PX - ); - }; - + const isValidResolution = (image) => + getImageResolution(image) + .then(({ height, width }) => + height >= CONST.AVATAR_MIN_HEIGHT_PX && + width >= CONST.AVATAR_MIN_WIDTH_PX && + height <= CONST.AVATAR_MAX_HEIGHT_PX && + width <= CONST.AVATAR_MAX_WIDTH_PX + ); /** * Validates if an image has a valid resolution and opens an avatar crop modal From 2ad7c4df4f7420e66acacd550da508f31713de56 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 12 Oct 2023 08:14:32 +0200 Subject: [PATCH 16/65] remove SpinningIndicatorAnimation file --- .../animation/SpinningIndicatorAnimation.js | 89 ------------------- 1 file changed, 89 deletions(-) delete mode 100644 src/styles/animation/SpinningIndicatorAnimation.js diff --git a/src/styles/animation/SpinningIndicatorAnimation.js b/src/styles/animation/SpinningIndicatorAnimation.js deleted file mode 100644 index 29044f0d127a..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, - }).start(); - } - - /** - * Stop Animation for Indicator - * - * @memberof AvatarWithImagePicker - */ - stop() { - Animated.spring(this.scale, { - toValue: 1, - tension: 1, - isInteraction: false, - useNativeDriver, - }).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 a8e5213f4ee6ab96e395ef08b908cb2a0efb7235 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Mon, 23 Oct 2023 13:10:48 +0200 Subject: [PATCH 17/65] prettier --- src/components/AvatarWithImagePicker.js | 50 ++++++++++++------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 01522a09fe75..dea7404937de 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -140,27 +140,27 @@ function AvatarWithImagePicker({ const [imageData, setImageData] = useState({ uri: '', name: '', - type: '' + type: '', }); const anchorRef = useRef(); const {translate} = useLocalize(); - /** + /** * @param {String} error * @param {Object} phraseParam */ - const setError = (error, phraseParam) => { + const setError = (error, phraseParam) => { setErrorData({ - validationError: error, - phraseParam, + validationError: error, + phraseParam, }); }; - + useEffect(() => { if (isFocused) { return; } - + // Reset the error if the component is no longer focused. setError(null, {}); }, [isFocused]); @@ -172,16 +172,16 @@ function AvatarWithImagePicker({ * @returns {Boolean} */ const isValidExtension = (image) => { - const { fileExtension } = FileUtils.splitExtensionFromFileName(lodashGet(image, 'name', '')); + 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. - * - * @param {Object} image - * @returns {Boolean} - */ + * Check if the attachment size is less than allowed size. + * + * @param {Object} image + * @returns {Boolean} + */ const isValidSize = (image) => image && lodashGet(image, 'size', 0) < CONST.AVATAR_MAX_ATTACHMENT_SIZE; /** @@ -190,13 +190,9 @@ function AvatarWithImagePicker({ * @param {Object} image * @returns {Promise} */ - const isValidResolution = (image) => - getImageResolution(image) - .then(({ height, width }) => - height >= CONST.AVATAR_MIN_HEIGHT_PX && - width >= CONST.AVATAR_MIN_WIDTH_PX && - height <= CONST.AVATAR_MAX_HEIGHT_PX && - width <= CONST.AVATAR_MAX_WIDTH_PX + const isValidResolution = (image) => + getImageResolution(image).then( + ({height, width}) => height >= CONST.AVATAR_MIN_HEIGHT_PX && width >= CONST.AVATAR_MIN_WIDTH_PX && height <= CONST.AVATAR_MAX_HEIGHT_PX && width <= CONST.AVATAR_MAX_WIDTH_PX, ); /** @@ -206,11 +202,11 @@ function AvatarWithImagePicker({ */ const showAvatarCropModal = (image) => { if (!isValidExtension(image)) { - setError('avatarWithImagePicker.notAllowedExtension', { allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS }); + setError('avatarWithImagePicker.notAllowedExtension', {allowedExtensions: CONST.AVATAR_ALLOWED_EXTENSIONS}); return; } if (!isValidSize(image)) { - setError('avatarWithImagePicker.sizeExceeded', { maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024) }); + setError('avatarWithImagePicker.sizeExceeded', {maxUploadSizeInMB: CONST.AVATAR_MAX_ATTACHMENT_SIZE / (1024 * 1024)}); return; } @@ -231,7 +227,7 @@ function AvatarWithImagePicker({ setImageData({ uri: image.uri, name: image.name, - type: image.type + type: image.type, }); }); }; @@ -289,7 +285,7 @@ function AvatarWithImagePicker({ > setIsMenuVisible(prev => !prev)} + onPress={() => setIsMenuVisible((prev) => !prev)} accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} accessibilityLabel={translate('avatarWithImagePicker.editImage')} disabled={isAvatarCropModalOpen} @@ -326,9 +322,9 @@ function AvatarWithImagePicker({ originalFileName={originalFileName} fallbackSource={fallbackIcon} > - {({ show }) => ( + {({show}) => ( - {({ openPicker }) => { + {({openPicker}) => { const menuItems = createMenuItems(openPicker); // If the current avatar isn't a default avatar, allow the "View Photo" option @@ -370,7 +366,7 @@ function AvatarWithImagePicker({ {errorData.validationError && ( )} From 458716e4f9138d1936816016d71d6dd5f8bf43bd Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Mon, 23 Oct 2023 13:40:45 +0200 Subject: [PATCH 18/65] restore podfile.lock from main --- ios/Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f41c2880563b..cb120bca2b88 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1293,4 +1293,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: ff769666b7221c15936ebc5576a8c8e467dc6879 -COCOAPODS: 1.12.1 \ No newline at end of file +COCOAPODS: 1.12.1 From 183d38383dcde6c6009493ccf0dce1ce208475fc Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Wed, 25 Oct 2023 13:36:55 +0200 Subject: [PATCH 19/65] pr comments --- src/components/AvatarWithImagePicker.js | 57 +++++++------------- src/pages/workspace/WorkspaceSettingsPage.js | 1 - 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 2876dede626d..ce0f2849e58d 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -92,47 +92,27 @@ const propTypes = { ...withNavigationFocusPropTypes, }; -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, - headerTitle: '', - previewSource: '', - originalFileName: '', -}; - function AvatarWithImagePicker({ isFocused, - DefaultAvatar, - style, - pendingAction, - errors, - errorRowStyles, - onErrorClose, - source, - fallbackIcon, - size, - type, - headerTitle, - previewSource, - originalFileName, - isUsingDefaultAvatar, - onImageRemoved, + DefaultAvatar = () => {}, + style = [], + pendingAction = null, + errors = null, + errorRowStyles = [], + onErrorClose = () => {}, + source = '', + fallbackIcon = Expensicons.FallbackAvatar, + size = CONST.AVATAR_SIZE.DEFAULT, + type = CONST.ICON_TYPE_AVATAR, + headerTitle = '', + previewSource = '', + originalFileName = '', + isUsingDefaultAvatar = false, + onImageRemoved = () => {}, anchorPosition, anchorAlignment, - onImageSelected, - editorMaskImage, + onImageSelected = () => {}, + editorMaskImage = undefined }) { const [isMenuVisible, setIsMenuVisible] = useState(false); const [errorData, setErrorData] = useState({ @@ -278,7 +258,7 @@ function AvatarWithImagePicker({ }; return ( - + ( From 796940ffb6d1a37a841363acc2da848d21cdbb5a Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Wed, 25 Oct 2023 14:26:40 +0200 Subject: [PATCH 20/65] updates - linter and PR comments --- src/components/AvatarWithImagePicker.js | 57 ++++++++++++++++--------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index ce0f2849e58d..006337fc8999 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -92,27 +92,47 @@ const propTypes = { ...withNavigationFocusPropTypes, }; +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, + headerTitle: '', + previewSource: '', + originalFileName: '', +}; + function AvatarWithImagePicker({ isFocused, - DefaultAvatar = () => {}, - style = [], - pendingAction = null, - errors = null, - errorRowStyles = [], - onErrorClose = () => {}, - source = '', - fallbackIcon = Expensicons.FallbackAvatar, - size = CONST.AVATAR_SIZE.DEFAULT, - type = CONST.ICON_TYPE_AVATAR, - headerTitle = '', - previewSource = '', - originalFileName = '', - isUsingDefaultAvatar = false, - onImageRemoved = () => {}, + DefaultAvatar, + style, + pendingAction, + errors, + errorRowStyles, + onErrorClose, + source, + fallbackIcon, + size, + type, + headerTitle, + previewSource, + originalFileName, + isUsingDefaultAvatar, + onImageRemoved, anchorPosition, anchorAlignment, - onImageSelected = () => {}, - editorMaskImage = undefined + onImageSelected, + editorMaskImage, }) { const [isMenuVisible, setIsMenuVisible] = useState(false); const [errorData, setErrorData] = useState({ @@ -219,8 +239,6 @@ function AvatarWithImagePicker({ setIsAvatarCropModalOpen(false); }; - const additionalStyles = _.isArray(style) ? style : [style]; - /** * Create menu items list for avatar menu * @@ -367,6 +385,7 @@ function AvatarWithImagePicker({ } AvatarWithImagePicker.propTypes = propTypes; +AvatarWithImagePicker.defaultProps = defaultProps; AvatarWithImagePicker.displayName = 'AvatarWithImagePicker'; export default withNavigationFocus(AvatarWithImagePicker); From 10e65433c158dd5701f72c7f24a7b699ac1ddaf3 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Fri, 27 Oct 2023 06:46:29 +0200 Subject: [PATCH 21/65] updates PR --- src/components/AvatarWithImagePicker.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 006337fc8999..4e85bba8ce9c 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,6 +1,6 @@ import _ from 'underscore'; import React, {useState, useRef, useEffect} from 'react'; -import {View} from 'react-native'; +import {View, StyleSheet} from 'react-native'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import Avatar from './Avatar'; @@ -86,9 +86,6 @@ const propTypes = { /** File name of the avatar */ originalFileName: PropTypes.string, - /** Whether navigation is focused */ - isFocused: PropTypes.bool.isRequired, - ...withNavigationFocusPropTypes, }; From 6be9864c80d1a4837069964c7a08057ab73c9a2e Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Fri, 27 Oct 2023 13:40:03 +0200 Subject: [PATCH 22/65] keep isFocused --- src/components/AvatarWithImagePicker.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 4e85bba8ce9c..0ef696072efd 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -23,7 +23,7 @@ import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import AttachmentModal from './AttachmentModal'; import DotIndicatorMessage from './DotIndicatorMessage'; import * as Browser from '../libs/Browser'; -import withNavigationFocus, {withNavigationFocusPropTypes} from './withNavigationFocus'; +import withNavigationFocus from './withNavigationFocus'; const propTypes = { /** Avatar source to display */ @@ -86,7 +86,8 @@ const propTypes = { /** File name of the avatar */ originalFileName: PropTypes.string, - ...withNavigationFocusPropTypes, + /** Whether navigation is focused */ + isFocused: PropTypes.bool.isRequired, }; const defaultProps = { From 66b2c82a9390a98123e513119e12643f1a9100cb Mon Sep 17 00:00:00 2001 From: tienifr Date: Sun, 29 Oct 2023 18:15:02 +0700 Subject: [PATCH 23/65] fix: 29378 Distance - Search is open in background on distance image preview --- src/components/Modal/BaseModal.js | 8 +++++--- src/libs/actions/Modal.ts | 34 +++++++++++++++++++------------ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index 6ed3b16c676d..b3e5b26b64ed 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -59,6 +59,8 @@ function BaseModal({ const isVisibleRef = useRef(isVisible); const wasVisible = usePrevious(isVisible); + const onCloseKey = useRef(Modal.getAvailableKey()); + /** * Hides modal * @param {Boolean} [callHideCallback=true] Should we call the onModalHide callback @@ -84,10 +86,10 @@ function BaseModal({ if (isVisible) { Modal.willAlertModalBecomeVisible(true); // To handle closing any modal already visible when this modal is mounted, i.e. PopoverReportActionContextMenu - Modal.setCloseModal(onClose); + Modal.setCloseModal(onCloseKey.current, onClose); } else if (wasVisible && !isVisible) { Modal.willAlertModalBecomeVisible(false); - Modal.setCloseModal(null); + Modal.setCloseModal(onCloseKey.current, null); } }, [isVisible, wasVisible, onClose]); @@ -100,7 +102,7 @@ function BaseModal({ hideModal(true); Modal.willAlertModalBecomeVisible(false); // To prevent closing any modal already unmounted when this modal still remains as visible state - Modal.setCloseModal(null); + Modal.setCloseModal(onCloseKey.current, null); }, // eslint-disable-next-line react-hooks/exhaustive-deps [], diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index 5114d5c1f42f..431142adfb20 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -1,30 +1,38 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; -let closeModal: (isNavigating: boolean) => void; +const closeModals: Record void)> = {}; +let count = 0; + +// let closeModal: (isNavigating: boolean) => void; let onModalClose: null | (() => void); +/** + * Get the available key that we can store the onClose callback into it + */ +function getAvailableKey() { + return count++; +} + /** * Allows other parts of the app to call modal close function */ -function setCloseModal(onClose: () => void) { - closeModal = onClose; +function setCloseModal(key: number, onClose: () => void) { + closeModals[key] = onClose; } /** * Close modal in other parts of the app */ function close(onModalCloseCallback: () => void, isNavigating = true) { - if (!closeModal) { - // If modal is already closed, no need to wait for modal close. So immediately call callback. - if (onModalCloseCallback) { - onModalCloseCallback(); - } - onModalClose = null; - return; - } onModalClose = onModalCloseCallback; - closeModal(isNavigating); + const reversalOnCloses = Object.values(closeModals).reverse(); + reversalOnCloses.forEach((onClose) => { + if (typeof onClose !== 'function') { + return; + } + onClose(isNavigating); + }); } function onModalDidClose() { @@ -50,4 +58,4 @@ function willAlertModalBecomeVisible(isVisible: boolean) { Onyx.merge(ONYXKEYS.MODAL, {willAlertModalBecomeVisible: isVisible}); } -export {setCloseModal, close, onModalDidClose, setModalVisibility, willAlertModalBecomeVisible}; +export {setCloseModal, close, onModalDidClose, setModalVisibility, willAlertModalBecomeVisible, getAvailableKey}; From f5d3c0ed3d06f556a9be7ea9ae377654c9196956 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Mon, 30 Oct 2023 07:39:05 +0100 Subject: [PATCH 24/65] merge lint issues --- src/components/AvatarWithImagePicker.js | 37 +++++++++++++------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index cf3a53c2e329..e45d624766f7 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,37 +1,28 @@ import _ from 'underscore'; import React, {useState, useRef, useEffect} from 'react'; import {View, StyleSheet} from 'react-native'; +import * as Browser from '@libs/Browser'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; +import styles from '@styles/styles'; +import themeColors from '@styles/themes/default'; +import useLocalize from '@hooks/useLocalize'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; +import stylePropTypes from '@styles/stylePropTypes'; +import * as FileUtils from '@libs/fileDownload/FileUtils'; +import getImageResolution from '@libs/fileDownload/getImageResolution'; import Avatar from './Avatar'; import Icon from './Icon'; import PopoverMenu from './PopoverMenu'; import * as Expensicons from './Icon/Expensicons'; -import styles from '../styles/styles'; -import themeColors from '../styles/themes/default'; import AttachmentPicker from './AttachmentPicker'; import AvatarCropModal from './AvatarCropModal/AvatarCropModal'; import OfflineWithFeedback from './OfflineWithFeedback'; -import useLocalize from '../hooks/useLocalize'; -import variables from '../styles/variables'; -import CONST from '../CONST'; import Tooltip from './Tooltip'; -import stylePropTypes from '../styles/stylePropTypes'; -import * as FileUtils from '../libs/fileDownload/FileUtils'; -import getImageResolution from '../libs/fileDownload/getImageResolution'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; -import * as Browser from '@libs/Browser'; import AttachmentModal from './AttachmentModal'; -import AttachmentPicker from './AttachmentPicker'; -import Avatar from './Avatar'; -import AvatarCropModal from './AvatarCropModal/AvatarCropModal'; import DotIndicatorMessage from './DotIndicatorMessage'; -import Icon from './Icon'; -import * as Expensicons from './Icon/Expensicons'; -import OfflineWithFeedback from './OfflineWithFeedback'; -import PopoverMenu from './PopoverMenu'; -import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; -import Tooltip from './Tooltip/PopoverAnchorTooltip'; import withNavigationFocus from './withNavigationFocus'; const propTypes = { @@ -97,6 +88,12 @@ const propTypes = { /** Whether navigation is focused */ isFocused: PropTypes.bool.isRequired, + + /** Where the popover should be positioned relative to the anchor points. */ + anchorAlignment: PropTypes.shape({ + horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), + vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), + }), }; const defaultProps = { @@ -117,6 +114,10 @@ const defaultProps = { headerTitle: '', previewSource: '', originalFileName: '', + anchorAlignment: { + horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, + vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP, + }, }; function AvatarWithImagePicker({ From 1370aea6bd1c22b39192650e308cf647e6e28ce7 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Tue, 31 Oct 2023 06:18:22 +0100 Subject: [PATCH 25/65] linter prettier fix --- src/components/AvatarWithImagePicker.js | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index e45d624766f7..209a6d45abbc 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -1,28 +1,28 @@ +import lodashGet from 'lodash/get'; +import PropTypes from 'prop-types'; +import React, {useEffect, useRef, useState} from 'react'; +import {StyleSheet, View} from 'react-native'; import _ from 'underscore'; -import React, {useState, useRef, useEffect} from 'react'; -import {View, StyleSheet} from 'react-native'; +import useLocalize from '@hooks/useLocalize'; import * as Browser from '@libs/Browser'; -import PropTypes from 'prop-types'; -import lodashGet from 'lodash/get'; +import * as FileUtils from '@libs/fileDownload/FileUtils'; +import getImageResolution from '@libs/fileDownload/getImageResolution'; +import stylePropTypes from '@styles/stylePropTypes'; import styles from '@styles/styles'; import themeColors from '@styles/themes/default'; -import useLocalize from '@hooks/useLocalize'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import stylePropTypes from '@styles/stylePropTypes'; -import * as FileUtils from '@libs/fileDownload/FileUtils'; -import getImageResolution from '@libs/fileDownload/getImageResolution'; +import AttachmentModal from './AttachmentModal'; +import AttachmentPicker from './AttachmentPicker'; import Avatar from './Avatar'; +import AvatarCropModal from './AvatarCropModal/AvatarCropModal'; +import DotIndicatorMessage from './DotIndicatorMessage'; import Icon from './Icon'; -import PopoverMenu from './PopoverMenu'; import * as Expensicons from './Icon/Expensicons'; -import AttachmentPicker from './AttachmentPicker'; -import AvatarCropModal from './AvatarCropModal/AvatarCropModal'; import OfflineWithFeedback from './OfflineWithFeedback'; -import Tooltip from './Tooltip'; +import PopoverMenu from './PopoverMenu'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; -import AttachmentModal from './AttachmentModal'; -import DotIndicatorMessage from './DotIndicatorMessage'; +import Tooltip from './Tooltip'; import withNavigationFocus from './withNavigationFocus'; const propTypes = { @@ -115,7 +115,7 @@ const defaultProps = { previewSource: '', originalFileName: '', anchorAlignment: { - horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, + horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP, }, }; From a342b162be83e198420409ae57f393ceabb44230 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 1 Nov 2023 16:34:42 +0700 Subject: [PATCH 26/65] refactor --- src/components/PopoverWithoutOverlay/index.js | 8 +++++--- src/libs/actions/Modal.ts | 16 ++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 43156cd11827..243543231ef3 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useRef} from 'react'; import {View} from 'react-native'; import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; import {defaultProps, propTypes} from '@components/Popover/popoverPropTypes'; @@ -11,6 +11,8 @@ import * as Modal from '@userActions/Modal'; function Popover(props) { const {onOpen, close} = React.useContext(PopoverContext); + const onCloseKey = useRef(Modal.getAvailableKey()); + const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = getModalStyles( 'popover', { @@ -30,8 +32,8 @@ function Popover(props) { ref: props.withoutOverlayRef, close: props.onClose, anchorRef: props.anchorRef, - onCloseCallback: () => Modal.setCloseModal(null), - onOpenCallback: () => Modal.setCloseModal(() => props.onClose(props.anchorRef)), + onCloseCallback: () => Modal.setCloseModal(onCloseKey, null), + onOpenCallback: () => Modal.setCloseModal(onCloseKey, () => props.onClose(props.anchorRef)), }); } else { props.onModalHide(); diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index 431142adfb20..b466423d537b 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -4,7 +4,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; const closeModals: Record void)> = {}; let count = 0; -// let closeModal: (isNavigating: boolean) => void; let onModalClose: null | (() => void); /** @@ -26,13 +25,14 @@ function setCloseModal(key: number, onClose: () => void) { */ function close(onModalCloseCallback: () => void, isNavigating = true) { onModalClose = onModalCloseCallback; - const reversalOnCloses = Object.values(closeModals).reverse(); - reversalOnCloses.forEach((onClose) => { - if (typeof onClose !== 'function') { - return; - } - onClose(isNavigating); - }); + Object.values(closeModals) + .reverse() + .forEach((onClose) => { + if (typeof onClose !== 'function') { + return; + } + onClose(isNavigating); + }); } function onModalDidClose() { From 443c37ce4a28e6b07ac043dbd9c81a9b20eb5fb1 Mon Sep 17 00:00:00 2001 From: Bartosz Grajdek Date: Sun, 5 Nov 2023 14:21:20 +0100 Subject: [PATCH 27/65] Rename environmentBadge --- src/components/{EnvironmentBadge.js => EnvironmentBadge.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/components/{EnvironmentBadge.js => EnvironmentBadge.tsx} (100%) diff --git a/src/components/EnvironmentBadge.js b/src/components/EnvironmentBadge.tsx similarity index 100% rename from src/components/EnvironmentBadge.js rename to src/components/EnvironmentBadge.tsx From a0139714bf02e4c5f31031e615656fd0565f99fb Mon Sep 17 00:00:00 2001 From: Bartosz Grajdek Date: Sun, 5 Nov 2023 14:25:13 +0100 Subject: [PATCH 28/65] Migrate EnvironmentBadge to TS --- src/components/EnvironmentBadge.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/EnvironmentBadge.tsx b/src/components/EnvironmentBadge.tsx index a9236fc50abe..02d92e0bf0f9 100644 --- a/src/components/EnvironmentBadge.tsx +++ b/src/components/EnvironmentBadge.tsx @@ -17,7 +17,7 @@ function EnvironmentBadge() { const {environment} = useEnvironment(); // If we are on production, don't show any badge - if (environment === CONST.ENVIRONMENT.PRODUCTION) { + if (environment === CONST.ENVIRONMENT.PRODUCTION || environment === undefined) { return null; } From c4de4c4e8d70790d84a1afa280cee6b37d258835 Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Mon, 6 Nov 2023 08:59:14 +0100 Subject: [PATCH 29/65] retrieve animation --- src/components/AvatarWithImagePicker.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 209a6d45abbc..4153882dc7ad 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -24,6 +24,7 @@ import PopoverMenu from './PopoverMenu'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Tooltip from './Tooltip'; import withNavigationFocus from './withNavigationFocus'; +import SpinningIndicatorAnimation from '@styles/animation/SpinningIndicatorAnimation'; const propTypes = { /** Avatar source to display */ @@ -155,6 +156,18 @@ function AvatarWithImagePicker({ }); const anchorRef = useRef(); const {translate} = useLocalize(); + const animationRef = useRef(null); + + useEffect(() => { + animationRef.current = new SpinningIndicatorAnimation(); + animationRef.current.start(); + + return () => { + if (animationRef.current) { + animationRef.current.stop(); + } + }; + }, []); // The empty array ensures this effect only runs once /** * @param {String} error From 50df7a9ebb4c0566138a36b35ee0e4e41c0c4347 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 7 Nov 2023 15:36:57 +0700 Subject: [PATCH 30/65] change to use list --- src/components/Modal/BaseModal.js | 9 +++--- src/components/PopoverWithoutOverlay/index.js | 9 ++++-- src/libs/actions/Modal.ts | 32 +++++++++---------- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index b3e5b26b64ed..74a8a2ff7120 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -59,7 +59,7 @@ function BaseModal({ const isVisibleRef = useRef(isVisible); const wasVisible = usePrevious(isVisible); - const onCloseKey = useRef(Modal.getAvailableKey()); + const removeOnClose = useRef(() => {}); /** * Hides modal @@ -86,10 +86,11 @@ function BaseModal({ if (isVisible) { Modal.willAlertModalBecomeVisible(true); // To handle closing any modal already visible when this modal is mounted, i.e. PopoverReportActionContextMenu - Modal.setCloseModal(onCloseKey.current, onClose); + removeOnClose.current(); + removeOnClose.current = Modal.setCloseModal(onClose); } else if (wasVisible && !isVisible) { Modal.willAlertModalBecomeVisible(false); - Modal.setCloseModal(onCloseKey.current, null); + removeOnClose.current(); } }, [isVisible, wasVisible, onClose]); @@ -102,7 +103,7 @@ function BaseModal({ hideModal(true); Modal.willAlertModalBecomeVisible(false); // To prevent closing any modal already unmounted when this modal still remains as visible state - Modal.setCloseModal(onCloseKey.current, null); + removeOnClose.current(); }, // eslint-disable-next-line react-hooks/exhaustive-deps [], diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 243543231ef3..94d15bc5b0a2 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -11,7 +11,7 @@ import * as Modal from '@userActions/Modal'; function Popover(props) { const {onOpen, close} = React.useContext(PopoverContext); - const onCloseKey = useRef(Modal.getAvailableKey()); + const removeOnClose = useRef(() => {}); const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = getModalStyles( 'popover', @@ -32,8 +32,11 @@ function Popover(props) { ref: props.withoutOverlayRef, close: props.onClose, anchorRef: props.anchorRef, - onCloseCallback: () => Modal.setCloseModal(onCloseKey, null), - onOpenCallback: () => Modal.setCloseModal(onCloseKey, () => props.onClose(props.anchorRef)), + onCloseCallback: removeOnClose.current, + onOpenCallback: () => { + removeOnClose.current(); + removeOnClose.current = Modal.setCloseModal(() => props.onClose(props.anchorRef)); + }, }); } else { props.onModalHide(); diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index b466423d537b..e02063ff1750 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -1,23 +1,27 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; -const closeModals: Record void)> = {}; -let count = 0; +const closeModals: Array<(isNavigating: boolean) => void> = []; let onModalClose: null | (() => void); /** - * Get the available key that we can store the onClose callback into it + * Remove onClose function in list */ -function getAvailableKey() { - return count++; +function removeCloseModal(onClose: () => void) { + const index = closeModals.findIndex((o) => o === onClose); + if (index === -1) { + return; + } + closeModals.splice(index, 1); } /** * Allows other parts of the app to call modal close function */ -function setCloseModal(key: number, onClose: () => void) { - closeModals[key] = onClose; +function setCloseModal(onClose: () => void) { + closeModals.push(onClose); + return () => removeCloseModal(onClose); } /** @@ -25,14 +29,10 @@ function setCloseModal(key: number, onClose: () => void) { */ function close(onModalCloseCallback: () => void, isNavigating = true) { onModalClose = onModalCloseCallback; - Object.values(closeModals) - .reverse() - .forEach((onClose) => { - if (typeof onClose !== 'function') { - return; - } - onClose(isNavigating); - }); + const reverseCloseModals = [...closeModals].reverse(); + reverseCloseModals.forEach((onClose) => { + onClose(isNavigating); + }); } function onModalDidClose() { @@ -58,4 +58,4 @@ function willAlertModalBecomeVisible(isVisible: boolean) { Onyx.merge(ONYXKEYS.MODAL, {willAlertModalBecomeVisible: isVisible}); } -export {setCloseModal, close, onModalDidClose, setModalVisibility, willAlertModalBecomeVisible, getAvailableKey}; +export {setCloseModal, close, onModalDidClose, setModalVisibility, willAlertModalBecomeVisible}; From ab389fba5139bd98023b77a8da92da7a73af4155 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 8 Nov 2023 11:31:07 +0700 Subject: [PATCH 31/65] clean code --- src/components/Modal/BaseModal.js | 12 +++++++----- src/libs/actions/Modal.ts | 23 +++++++++++------------ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index 7a13d2254969..4154dd933a2c 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -59,7 +59,7 @@ function BaseModal({ const isVisibleRef = useRef(isVisible); const wasVisible = usePrevious(isVisible); - const removeOnClose = useRef(() => {}); + const removeOnCloseListener = useRef(() => {}); /** * Hides modal @@ -86,12 +86,14 @@ function BaseModal({ if (isVisible) { Modal.willAlertModalBecomeVisible(true); // To handle closing any modal already visible when this modal is mounted, i.e. PopoverReportActionContextMenu - removeOnClose.current(); - removeOnClose.current = Modal.setCloseModal(onClose); + removeOnCloseListener.current = Modal.setCloseModal(onClose); } else if (wasVisible && !isVisible) { Modal.willAlertModalBecomeVisible(false); - removeOnClose.current(); } + + return () => { + removeOnCloseListener.current(); + }; }, [isVisible, wasVisible, onClose]); useEffect( @@ -103,7 +105,7 @@ function BaseModal({ hideModal(true); Modal.willAlertModalBecomeVisible(false); // To prevent closing any modal already unmounted when this modal still remains as visible state - removeOnClose.current(); + removeOnCloseListener.current(); }, // eslint-disable-next-line react-hooks/exhaustive-deps [], diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index e02063ff1750..15447bf84ade 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -5,29 +5,28 @@ const closeModals: Array<(isNavigating: boolean) => void> = []; let onModalClose: null | (() => void); -/** - * Remove onClose function in list - */ -function removeCloseModal(onClose: () => void) { - const index = closeModals.findIndex((o) => o === onClose); - if (index === -1) { - return; - } - closeModals.splice(index, 1); -} - /** * Allows other parts of the app to call modal close function */ function setCloseModal(onClose: () => void) { closeModals.push(onClose); - return () => removeCloseModal(onClose); + return () => { + const index = closeModals.indexOf(onClose); + if (index === -1) { + return; + } + closeModals.splice(index, 1); + }; } /** * Close modal in other parts of the app */ function close(onModalCloseCallback: () => void, isNavigating = true) { + if (closeModals.length === 0) { + onModalCloseCallback(); + return; + } onModalClose = onModalCloseCallback; const reverseCloseModals = [...closeModals].reverse(); reverseCloseModals.forEach((onClose) => { From d81596b79dd8719bfee550fb5ff85dee738cf4d9 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 8 Nov 2023 11:33:59 +0700 Subject: [PATCH 32/65] prevent duplicate --- src/libs/actions/Modal.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index 15447bf84ade..6981959c160a 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -9,7 +9,9 @@ let onModalClose: null | (() => void); * Allows other parts of the app to call modal close function */ function setCloseModal(onClose: () => void) { - closeModals.push(onClose); + if (!closeModals.includes(onClose)) { + closeModals.push(onClose); + } return () => { const index = closeModals.indexOf(onClose); if (index === -1) { From 0d06719e69288ff8b3e35b79761c04a1728e193b Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Wed, 8 Nov 2023 07:19:36 +0100 Subject: [PATCH 33/65] delete SpinningIndicatorAnimation --- src/components/AvatarWithImagePicker.js | 13 --- .../animation/SpinningIndicatorAnimation.js | 89 ------------------- 2 files changed, 102 deletions(-) delete mode 100644 src/styles/animation/SpinningIndicatorAnimation.js diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 4153882dc7ad..209a6d45abbc 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -24,7 +24,6 @@ import PopoverMenu from './PopoverMenu'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Tooltip from './Tooltip'; import withNavigationFocus from './withNavigationFocus'; -import SpinningIndicatorAnimation from '@styles/animation/SpinningIndicatorAnimation'; const propTypes = { /** Avatar source to display */ @@ -156,18 +155,6 @@ function AvatarWithImagePicker({ }); const anchorRef = useRef(); const {translate} = useLocalize(); - const animationRef = useRef(null); - - useEffect(() => { - animationRef.current = new SpinningIndicatorAnimation(); - animationRef.current.start(); - - return () => { - if (animationRef.current) { - animationRef.current.stop(); - } - }; - }, []); // The empty array ensures this effect only runs once /** * @param {String} error diff --git a/src/styles/animation/SpinningIndicatorAnimation.js b/src/styles/animation/SpinningIndicatorAnimation.js deleted file mode 100644 index 1ae4b1518325..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, - }).start(); - } - - /** - * Stop Animation for Indicator - * - * @memberof AvatarWithImagePicker - */ - stop() { - Animated.spring(this.scale, { - toValue: 1, - tension: 1, - isInteraction: false, - useNativeDriver, - }).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 f58d0ba62e4f9a8d7bc66253ed355bfe0d0b84e9 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 9 Nov 2023 15:28:52 +0700 Subject: [PATCH 34/65] clean code --- src/components/Modal/BaseModal.js | 12 ++++++------ src/components/PopoverWithoutOverlay/index.js | 16 +++++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index 4154dd933a2c..b57fad3a8d49 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -59,8 +59,6 @@ function BaseModal({ const isVisibleRef = useRef(isVisible); const wasVisible = usePrevious(isVisible); - const removeOnCloseListener = useRef(() => {}); - /** * Hides modal * @param {Boolean} [callHideCallback=true] Should we call the onModalHide callback @@ -83,16 +81,20 @@ function BaseModal({ useEffect(() => { isVisibleRef.current = isVisible; + let removeOnCloseListener; if (isVisible) { Modal.willAlertModalBecomeVisible(true); // To handle closing any modal already visible when this modal is mounted, i.e. PopoverReportActionContextMenu - removeOnCloseListener.current = Modal.setCloseModal(onClose); + removeOnCloseListener = Modal.setCloseModal(onClose); } else if (wasVisible && !isVisible) { Modal.willAlertModalBecomeVisible(false); } return () => { - removeOnCloseListener.current(); + if (!removeOnCloseListener) { + return; + } + removeOnCloseListener(); }; }, [isVisible, wasVisible, onClose]); @@ -104,8 +106,6 @@ function BaseModal({ } hideModal(true); Modal.willAlertModalBecomeVisible(false); - // To prevent closing any modal already unmounted when this modal still remains as visible state - removeOnCloseListener.current(); }, // eslint-disable-next-line react-hooks/exhaustive-deps [], diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 94d15bc5b0a2..b7ba41116daa 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -1,4 +1,4 @@ -import React, {useRef} from 'react'; +import React from 'react'; import {View} from 'react-native'; import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; import {defaultProps, propTypes} from '@components/Popover/popoverPropTypes'; @@ -11,7 +11,6 @@ import * as Modal from '@userActions/Modal'; function Popover(props) { const {onOpen, close} = React.useContext(PopoverContext); - const removeOnClose = useRef(() => {}); const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = getModalStyles( 'popover', @@ -26,18 +25,15 @@ function Popover(props) { ); React.useEffect(() => { + let removeOnClose; if (props.isVisible) { props.onModalShow(); onOpen({ ref: props.withoutOverlayRef, close: props.onClose, anchorRef: props.anchorRef, - onCloseCallback: removeOnClose.current, - onOpenCallback: () => { - removeOnClose.current(); - removeOnClose.current = Modal.setCloseModal(() => props.onClose(props.anchorRef)); - }, }); + removeOnClose = Modal.setCloseModal(() => props.onClose(props.anchorRef)); } else { props.onModalHide(); close(props.anchorRef); @@ -45,6 +41,12 @@ function Popover(props) { } Modal.willAlertModalBecomeVisible(props.isVisible); + return () => { + if (!removeOnClose) { + return; + } + removeOnClose(); + }; // We want this effect to run strictly ONLY when isVisible prop changes // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.isVisible]); From fe992ab2dedb92f572aba47eac55d3b5c6e5793a Mon Sep 17 00:00:00 2001 From: keisyrzk Date: Thu, 9 Nov 2023 10:59:09 +0100 Subject: [PATCH 35/65] Update src/components/AvatarWithImagePicker.js Co-authored-by: Eugene Voloshchak --- 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 209a6d45abbc..93f4f5470b3d 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -332,7 +332,7 @@ function AvatarWithImagePicker({ fallbackSource={fallbackIcon} > {({show}) => ( - + {({openPicker}) => { const menuItems = createMenuItems(openPicker); From 2196a48ed2e32a435605631f262f34a9c680dd86 Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Tue, 14 Nov 2023 00:26:27 +0300 Subject: [PATCH 36/65] ADD: Transaction Drafts Collection Key --- src/ONYXKEYS.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index fa72a99b5fa2..c9e87cdb99fc 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -261,6 +261,9 @@ const ONYXKEYS = { REPORT_USER_IS_LEAVING_ROOM: 'reportUserIsLeavingRoom_', SECURITY_GROUP: 'securityGroup_', TRANSACTION: 'transactions_', + + // Holds temporary transactions used during the creation and edit flow + TRANSACTION_DRAFT: 'transactionsDraft_', SPLIT_TRANSACTION_DRAFT: 'splitTransactionDraft_', PRIVATE_NOTES_DRAFT: 'privateNotesDraft_', NEXT_STEP: 'reportNextStep_', From 1ebb2897f4bf2347845bd10c91d7c51d02fc0d64 Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Tue, 14 Nov 2023 00:59:56 +0300 Subject: [PATCH 37/65] FIX: Changing transcation backup onyx collection to the transaction drafts onyx collection --- src/libs/actions/IOU.js | 4 ++-- src/libs/actions/TransactionEdit.js | 6 +++--- src/pages/EditRequestDistancePage.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index aa07f0e7ca34..8487a8a2b5c7 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -787,10 +787,10 @@ function updateDistanceRequest(transactionID, transactionThreadReportID, transac }); if (_.has(transactionChanges, 'waypoints')) { - // Delete the backup transaction when editing waypoints when the server responds successfully and there are no errors + // Delete the draft transaction when editing waypoints when the server responds successfully and there are no errors successData.push({ onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}-backup`, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, value: null, }); } diff --git a/src/libs/actions/TransactionEdit.js b/src/libs/actions/TransactionEdit.js index 78a271f0f8cd..2cb79ac387bd 100644 --- a/src/libs/actions/TransactionEdit.js +++ b/src/libs/actions/TransactionEdit.js @@ -11,7 +11,7 @@ function createBackupTransaction(transaction) { ...transaction, }; // Use set so that it will always fully overwrite any backup transaction that could have existed before - Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}-backup`, newTransaction); + Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`, newTransaction); } /** @@ -19,12 +19,12 @@ function createBackupTransaction(transaction) { * @param {String} transactionID */ function removeBackupTransaction(transactionID) { - Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}-backup`, null); + Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, null); } function restoreOriginalTransactionFromBackup(transactionID) { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}-backup`, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, callback: (backupTransaction) => { Onyx.disconnect(connectionID); diff --git a/src/pages/EditRequestDistancePage.js b/src/pages/EditRequestDistancePage.js index 0fca8aee4be9..e857f30db032 100644 --- a/src/pages/EditRequestDistancePage.js +++ b/src/pages/EditRequestDistancePage.js @@ -140,6 +140,6 @@ export default withOnyx({ key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, }, transactionBackup: { - key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}-backup`, + key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${props.transactionID}`, }, })(EditRequestDistancePage); From 9aadfef916a8fbd1fa77da1e238c50d9f2f8b777 Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Tue, 14 Nov 2023 01:47:02 +0300 Subject: [PATCH 38/65] ADD: Migration promise --- .../TransactionBackupsToCollection.js | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/libs/migrations/TransactionBackupsToCollection.js diff --git a/src/libs/migrations/TransactionBackupsToCollection.js b/src/libs/migrations/TransactionBackupsToCollection.js new file mode 100644 index 000000000000..4a43449f4798 --- /dev/null +++ b/src/libs/migrations/TransactionBackupsToCollection.js @@ -0,0 +1,77 @@ +import Onyx from 'react-native-onyx'; +import _ from 'underscore'; +import Log from '@libs/Log'; +import ONYXKEYS from '@src/ONYXKEYS'; + +// This migration moves all the transaction backups stored in the main transactions collection (ONYXKEYS.COLLECTION.TRANSACTION) +// to a reserved collection which only stores draft transactions (ONYXKEYS.COLLECTION.TRANSACTION_DRAFT). +// The main purpose of this migration is that there is a possibility of transactions backups not getting filtered +// by most functions which need use all transactions. Eg: getAllReportTransactions (src/libs/TransactionUtils.ts) +// One problem which arose from having duplicate transactions in the collection is that for every distance request +// which have their waypoints updated offline, we expect the ReportPreview component to display the default image of a pending map. +// However, due to the presence of a transaction backup, an extra unexpected image of the previous map will be displayed. +// The problem was further discussed in this PR -> https://github.com/Expensify/App/pull/30232#issuecomment-1781101722 +export default function () { + return new Promise((resolve) => { + const outerConnectionID = Onyx.connect({ + key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, + waitForCollectionCallback: true, + callback: (draftTransactions) => { + Onyx.disconnect(outerConnectionID); + + // Check if transaction backups were already moved + if (draftTransactions) { + Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because migration already happen`); + return resolve(); + } + + const innerConnectionID = Onyx.connect({ + key: ONYXKEYS.COLLECTION.TRANSACTION, + waitForCollectionCallback: true, + callback: (transactions) => { + Onyx.disconnect(innerConnectionID); + + // Check if there are any transactions. + if (!transactions) { + Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions in the main transactions collection`); + return resolve(); + } + + const onyxData = _.reduce( + _.keys(transactions), + (result, transactionKey) => { + if (!transactionKey.endsWith('-backup')) { + return result; + } + return { + ...result, + + // We create all the transaction backups to the draft transactions collection + [`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactions[transactionKey].transactionID}`]: transactions[transactionKey], + + // We delete the transaction backups stored the main transactions collection + [transactionKey]: null, + }; + }, + {}, + ); + + // Check if there are any available transaction backups to move + if (!onyxData) { + Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups in the main transactions collection`); + return resolve(); + } + + // Moving the transaction backups from the main transactions collection to the draft transactions collection + Onyx.multiSet(onyxData).then(() => { + Log.info( + `[Migrate Onyx] TransactionBackupsToCollection migration: successfully moved all transaction backups from the main transactions collection to the draft transactions collection`, + ); + resolve(); + }); + }, + }); + }, + }); + }); +} From 5c66d43807908271a00bd3da90281982a433d360 Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Tue, 14 Nov 2023 01:49:31 +0300 Subject: [PATCH 39/65] ADD: TransactionsBackupsToCollection migration promise into the migrations execution queue --- src/libs/migrateOnyx.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/migrateOnyx.js b/src/libs/migrateOnyx.js index b65670819418..5daba3686208 100644 --- a/src/libs/migrateOnyx.js +++ b/src/libs/migrateOnyx.js @@ -3,6 +3,7 @@ import Log from './Log'; import KeyReportActionsDraftByReportActionID from './migrations/KeyReportActionsDraftByReportActionID'; import PersonalDetailsByAccountID from './migrations/PersonalDetailsByAccountID'; import RenameReceiptFilename from './migrations/RenameReceiptFilename'; +import TransactionBackupsToCollection from './migrations/TransactionBackupsToCollection'; export default function () { const startTime = Date.now(); @@ -10,7 +11,7 @@ export default function () { return new Promise((resolve) => { // Add all migrations to an array so they are executed in order - const migrationPromises = [PersonalDetailsByAccountID, RenameReceiptFilename, KeyReportActionsDraftByReportActionID]; + const migrationPromises = [PersonalDetailsByAccountID, RenameReceiptFilename, KeyReportActionsDraftByReportActionID, TransactionBackupsToCollection]; // Reduce all promises down to a single promise. All promises run in a linear fashion, waiting for the // previous promise to finish before moving onto the next one. From 26909ba5a71cde844f282a2e01fce75429fcbf41 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 14 Nov 2023 14:13:28 +0700 Subject: [PATCH 40/65] update optimistic data --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index aa07f0e7ca34..4d0580624a6a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -2425,7 +2425,7 @@ function getSendMoneyParams(report, amount, currency, comment, paymentMethodType function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMethodType) { const optimisticIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( CONST.IOU.REPORT_ACTION_TYPE.PAY, - iouReport.total, + iouReport.total * -1, iouReport.currency, '', [recipient], From f215d31f3f6d46a568a693ad0b5c8da798926773 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 14 Nov 2023 12:26:28 +0100 Subject: [PATCH 41/65] fix: restore role instead of accesbilityRole to prevent crash on android --- 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 93f4f5470b3d..340fc9dfedbf 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -295,7 +295,7 @@ function AvatarWithImagePicker({ setIsMenuVisible((prev) => !prev)} - accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} + role={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} accessibilityLabel={translate('avatarWithImagePicker.editImage')} disabled={isAvatarCropModalOpen} ref={anchorRef} From a8027b715def8c1f7a30a333511609e1726fc71e Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Wed, 15 Nov 2023 00:17:17 +0300 Subject: [PATCH 42/65] REFACTOR: Changing connection variable names and removing draft transactions collection check --- .../TransactionBackupsToCollection.js | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.js b/src/libs/migrations/TransactionBackupsToCollection.js index 4a43449f4798..11a77039107a 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.js +++ b/src/libs/migrations/TransactionBackupsToCollection.js @@ -13,54 +13,48 @@ import ONYXKEYS from '@src/ONYXKEYS'; // The problem was further discussed in this PR -> https://github.com/Expensify/App/pull/30232#issuecomment-1781101722 export default function () { return new Promise((resolve) => { - const outerConnectionID = Onyx.connect({ + const transactionConnectionID = Onyx.connect({ key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, waitForCollectionCallback: true, - callback: (draftTransactions) => { - Onyx.disconnect(outerConnectionID); + callback: (transactions) => { + Onyx.disconnect(transactionConnectionID); - // Check if transaction backups were already moved - if (draftTransactions) { - Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because migration already happen`); + // Check if there are any transactions. + if (!transactions) { + Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions in the main transactions collection`); return resolve(); } - const innerConnectionID = Onyx.connect({ - key: ONYXKEYS.COLLECTION.TRANSACTION, - waitForCollectionCallback: true, - callback: (transactions) => { - Onyx.disconnect(innerConnectionID); - - // Check if there are any transactions. - if (!transactions) { - Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions in the main transactions collection`); - return resolve(); + const onyxData = _.reduce( + _.keys(transactions), + (result, transactionKey) => { + if (!transactionKey.endsWith('-backup')) { + return result; } + return { + ...result, - const onyxData = _.reduce( - _.keys(transactions), - (result, transactionKey) => { - if (!transactionKey.endsWith('-backup')) { - return result; - } - return { - ...result, + // We create all the transaction backups to the draft transactions collection + [`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactions[transactionKey].transactionID}`]: transactions[transactionKey], - // We create all the transaction backups to the draft transactions collection - [`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactions[transactionKey].transactionID}`]: transactions[transactionKey], + // We delete the transaction backups stored the main transactions collection + [transactionKey]: null, + }; + }, + {}, + ); - // We delete the transaction backups stored the main transactions collection - [transactionKey]: null, - }; - }, - {}, - ); + // Check if there are any available transaction backups to move + if (!onyxData) { + Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups in the main transactions collection`); + return resolve(); + } - // Check if there are any available transaction backups to move - if (!onyxData) { - Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups in the main transactions collection`); - return resolve(); - } + const transactionDraftConnectionID = Onyx.connect({ + key: ONYXKEYS.COLLECTION.TRANSACTION, + waitForCollectionCallback: true, + callback: () => { + Onyx.disconnect(transactionDraftConnectionID); // Moving the transaction backups from the main transactions collection to the draft transactions collection Onyx.multiSet(onyxData).then(() => { From 300d39c2144684a6cb5afa6a46f1523de5dabcde Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Wed, 15 Nov 2023 00:24:33 +0300 Subject: [PATCH 43/65] FIX: onyx collection key switch --- src/libs/migrations/TransactionBackupsToCollection.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.js b/src/libs/migrations/TransactionBackupsToCollection.js index 11a77039107a..074ace0a4796 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.js +++ b/src/libs/migrations/TransactionBackupsToCollection.js @@ -14,7 +14,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; export default function () { return new Promise((resolve) => { const transactionConnectionID = Onyx.connect({ - key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, + key: ONYXKEYS.COLLECTION.TRANSACTION, waitForCollectionCallback: true, callback: (transactions) => { Onyx.disconnect(transactionConnectionID); @@ -51,7 +51,7 @@ export default function () { } const transactionDraftConnectionID = Onyx.connect({ - key: ONYXKEYS.COLLECTION.TRANSACTION, + key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, waitForCollectionCallback: true, callback: () => { Onyx.disconnect(transactionDraftConnectionID); From 045a0434e534fe7a0cd22f103fa5a54732f6afe5 Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Wed, 15 Nov 2023 00:33:02 +0300 Subject: [PATCH 44/65] REFACTOR: removing unnecessary draft transaction connection --- .../TransactionBackupsToCollection.js | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.js b/src/libs/migrations/TransactionBackupsToCollection.js index 074ace0a4796..e32df1876ba2 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.js +++ b/src/libs/migrations/TransactionBackupsToCollection.js @@ -50,20 +50,12 @@ export default function () { return resolve(); } - const transactionDraftConnectionID = Onyx.connect({ - key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, - waitForCollectionCallback: true, - callback: () => { - Onyx.disconnect(transactionDraftConnectionID); - - // Moving the transaction backups from the main transactions collection to the draft transactions collection - Onyx.multiSet(onyxData).then(() => { - Log.info( - `[Migrate Onyx] TransactionBackupsToCollection migration: successfully moved all transaction backups from the main transactions collection to the draft transactions collection`, - ); - resolve(); - }); - }, + // Moving the transaction backups from the main transactions collection to the draft transactions collection + Onyx.multiSet(onyxData).then(() => { + Log.info( + `[Migrate Onyx] TransactionBackupsToCollection migration: successfully moved all transaction backups from the main transactions collection to the draft transactions collection`, + ); + resolve(); }); }, }); From 6fafef5131171281702b00a807707667b3df9e0f Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 15 Nov 2023 11:20:48 +0700 Subject: [PATCH 45/65] update UTs --- tests/actions/IOUTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js index 1c258f6e0f37..ad73a026ff08 100644 --- a/tests/actions/IOUTest.js +++ b/tests/actions/IOUTest.js @@ -1757,7 +1757,7 @@ describe('actions/IOU', () => { }), ]), originalMessage: expect.objectContaining({ - amount, + amount: amount * -1, paymentType: CONST.IOU.PAYMENT_TYPE.VBBA, type: 'pay', }), From 2f0e1ee00ee0d3c31c548bb273e6f16e69c8874d Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 17 Nov 2023 11:54:42 +0700 Subject: [PATCH 46/65] add type check --- src/components/Modal/BaseModal.tsx | 2 +- src/components/PopoverWithoutOverlay/index.js | 1 - src/libs/actions/Modal.ts | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 7cd71d410604..54a178db1cdd 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -72,7 +72,7 @@ function BaseModal( useEffect(() => { isVisibleRef.current = isVisible; - let removeOnCloseListener; + let removeOnCloseListener: () => void; if (isVisible) { Modal.willAlertModalBecomeVisible(true); // To handle closing any modal already visible when this modal is mounted, i.e. PopoverReportActionContextMenu diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index d568f974c4f6..8b9dd4ac7a61 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -12,7 +12,6 @@ import * as Modal from '@userActions/Modal'; function Popover(props) { const styles = useThemeStyles(); const {onOpen, close} = React.useContext(PopoverContext); - const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = getModalStyles( 'popover', { diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index 6981959c160a..e1e73d425281 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -30,8 +30,7 @@ function close(onModalCloseCallback: () => void, isNavigating = true) { return; } onModalClose = onModalCloseCallback; - const reverseCloseModals = [...closeModals].reverse(); - reverseCloseModals.forEach((onClose) => { + [...closeModals].reverse().forEach((onClose) => { onClose(isNavigating); }); } From ae87c9a822484264b9e3e1b17d41f5116b6b297e Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Sat, 18 Nov 2023 03:06:30 +0300 Subject: [PATCH 47/65] ADD: Wrote the javacript migration file, TransactionBackupsToCollection.js, to typescript --- .../TransactionBackupsToCollection.js | 63 ------------------ .../TransactionBackupsToCollection.ts | 64 +++++++++++++++++++ 2 files changed, 64 insertions(+), 63 deletions(-) delete mode 100644 src/libs/migrations/TransactionBackupsToCollection.js create mode 100644 src/libs/migrations/TransactionBackupsToCollection.ts diff --git a/src/libs/migrations/TransactionBackupsToCollection.js b/src/libs/migrations/TransactionBackupsToCollection.js deleted file mode 100644 index e32df1876ba2..000000000000 --- a/src/libs/migrations/TransactionBackupsToCollection.js +++ /dev/null @@ -1,63 +0,0 @@ -import Onyx from 'react-native-onyx'; -import _ from 'underscore'; -import Log from '@libs/Log'; -import ONYXKEYS from '@src/ONYXKEYS'; - -// This migration moves all the transaction backups stored in the main transactions collection (ONYXKEYS.COLLECTION.TRANSACTION) -// to a reserved collection which only stores draft transactions (ONYXKEYS.COLLECTION.TRANSACTION_DRAFT). -// The main purpose of this migration is that there is a possibility of transactions backups not getting filtered -// by most functions which need use all transactions. Eg: getAllReportTransactions (src/libs/TransactionUtils.ts) -// One problem which arose from having duplicate transactions in the collection is that for every distance request -// which have their waypoints updated offline, we expect the ReportPreview component to display the default image of a pending map. -// However, due to the presence of a transaction backup, an extra unexpected image of the previous map will be displayed. -// The problem was further discussed in this PR -> https://github.com/Expensify/App/pull/30232#issuecomment-1781101722 -export default function () { - return new Promise((resolve) => { - const transactionConnectionID = Onyx.connect({ - key: ONYXKEYS.COLLECTION.TRANSACTION, - waitForCollectionCallback: true, - callback: (transactions) => { - Onyx.disconnect(transactionConnectionID); - - // Check if there are any transactions. - if (!transactions) { - Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions in the main transactions collection`); - return resolve(); - } - - const onyxData = _.reduce( - _.keys(transactions), - (result, transactionKey) => { - if (!transactionKey.endsWith('-backup')) { - return result; - } - return { - ...result, - - // We create all the transaction backups to the draft transactions collection - [`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactions[transactionKey].transactionID}`]: transactions[transactionKey], - - // We delete the transaction backups stored the main transactions collection - [transactionKey]: null, - }; - }, - {}, - ); - - // Check if there are any available transaction backups to move - if (!onyxData) { - Log.info(`[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups in the main transactions collection`); - return resolve(); - } - - // Moving the transaction backups from the main transactions collection to the draft transactions collection - Onyx.multiSet(onyxData).then(() => { - Log.info( - `[Migrate Onyx] TransactionBackupsToCollection migration: successfully moved all transaction backups from the main transactions collection to the draft transactions collection`, - ); - resolve(); - }); - }, - }); - }); -} diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts new file mode 100644 index 000000000000..6d042c536e7c --- /dev/null +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -0,0 +1,64 @@ +import isEmpty from 'lodash/isEmpty'; +import Onyx, {OnyxCollection} from 'react-native-onyx'; +import Log from '@libs/Log'; +import ONYXKEYS from '@src/ONYXKEYS'; +import {Transaction} from '@src/types/onyx'; + +/** + * This migration moves all the transaction backups stored in the transaction collection, ONYXKEYS.COLLECTION.TRANSACTION, + * to a reserved collection which only stores draft transactions, ONYXKEYS.COLLECTION.TRANSACTION_DRAFT. + * The purpose of the migration is that there is a possibility of transaction backups are not filtered from + * by most functions when all transactions are fetched. Eg: getAllReportTransactions (src/libs/TransactionUtils.ts) + * One problem which arose from storing transaction backups with the other transactions is that for every distance request + * which have their waypoints updated offline, we expect the ReportPreview component to display the default image of a pending map. + * However, due to the presence of the transaction backup, the previous map image will be displayed alongside the current pending map. + * The problem was further discussed in this PR -> https://github.com/Expensify/App/pull/30232#issuecomment-178110172 + */ +export default function (): Promise { + return new Promise((resolve) => { + const connectionID = Onyx.connect({ + key: ONYXKEYS.COLLECTION.TRANSACTION, + waitForCollectionCallback: true, + callback: (transactions: OnyxCollection) => { + Onyx.disconnect(connectionID); + + // Check if transaction collection is empty + if (isEmpty(transactions) || !transactions) { + Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions'); + return resolve; + } + const onyxData: OnyxCollection = {}; + + // Find all the transaction backups available + Object.keys(transactions).forEach((transactionOnyxKey: string) => { + const transaction: Transaction | null = transactions[transactionOnyxKey]; + + // Check if transaction is a backup + if (!transactionOnyxKey.endsWith('-backup') || !transaction) { + return; + } + + // Create the transaction backup in the draft transaction collection + onyxData[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`] = transaction; + + // Delete the transaction backup stored the transaction collection + onyxData[transactionOnyxKey] = null; + }); + + // Check if any transaction backups were found + if (isEmpty(onyxData)) { + Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups'); + return; + } + + // eslint-disable-next-line no-console + console.info(onyxData); + + Onyx.multiSet(onyxData as Partial<{string: [Transaction | null]}>).then(() => { + Log.info('[Migrate Onyx] TransactionBackupsToCollection migration: Moved the transaction backups to the draft transaction collection'); + resolve(); + }); + }, + }); + }); +} From b989b9d20c74ec58108f8d06f3c70172c91ebbde Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Sun, 19 Nov 2023 00:52:57 +0300 Subject: [PATCH 48/65] Fix: Return resolve promise and removing console log while improve comments --- .../TransactionBackupsToCollection.ts | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index 6d042c536e7c..b5519692cc91 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.ts +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -6,13 +6,13 @@ import {Transaction} from '@src/types/onyx'; /** * This migration moves all the transaction backups stored in the transaction collection, ONYXKEYS.COLLECTION.TRANSACTION, - * to a reserved collection which only stores draft transactions, ONYXKEYS.COLLECTION.TRANSACTION_DRAFT. - * The purpose of the migration is that there is a possibility of transaction backups are not filtered from + * to a reserved collection that only stores draft transactions, ONYXKEYS.COLLECTION.TRANSACTION_DRAFT. + * The purpose of the migration is that there is a possibility that transaction backups are not filtered from * by most functions when all transactions are fetched. Eg: getAllReportTransactions (src/libs/TransactionUtils.ts) - * One problem which arose from storing transaction backups with the other transactions is that for every distance request + * One problem that arose from storing transaction backups with the other transactions is that for every distance request * which have their waypoints updated offline, we expect the ReportPreview component to display the default image of a pending map. * However, due to the presence of the transaction backup, the previous map image will be displayed alongside the current pending map. - * The problem was further discussed in this PR -> https://github.com/Expensify/App/pull/30232#issuecomment-178110172 + * The problem was further discussed in this PR. https://github.com/Expensify/App/pull/30232#issuecomment-178110172 */ export default function (): Promise { return new Promise((resolve) => { @@ -22,38 +22,35 @@ export default function (): Promise { callback: (transactions: OnyxCollection) => { Onyx.disconnect(connectionID); - // Check if transaction collection is empty + // Determine whether or not any transactions were found if (isEmpty(transactions) || !transactions) { Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions'); - return resolve; + return resolve(); } const onyxData: OnyxCollection = {}; // Find all the transaction backups available Object.keys(transactions).forEach((transactionOnyxKey: string) => { const transaction: Transaction | null = transactions[transactionOnyxKey]; - - // Check if transaction is a backup + + // Determine whether or not the transaction is a backup if (!transactionOnyxKey.endsWith('-backup') || !transaction) { - return; - } - - // Create the transaction backup in the draft transaction collection - onyxData[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`] = transaction; - // Delete the transaction backup stored the transaction collection - onyxData[transactionOnyxKey] = null; + // Create the transaction backup in the draft transaction collection + onyxData[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`] = transaction; + + // Delete the transaction backup stored in the transaction collection + onyxData[transactionOnyxKey] = null; + } }); - // Check if any transaction backups were found + // Determine whether or not any transaction backups were found if (isEmpty(onyxData)) { Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups'); - return; + return resolve(); } - // eslint-disable-next-line no-console - console.info(onyxData); - + // Move the transaction backups to the draft transaction collection Onyx.multiSet(onyxData as Partial<{string: [Transaction | null]}>).then(() => { Log.info('[Migrate Onyx] TransactionBackupsToCollection migration: Moved the transaction backups to the draft transaction collection'); resolve(); From dde30a1d3bded05925e1aebc69a81b66738b5a2f Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Sun, 19 Nov 2023 01:29:08 +0300 Subject: [PATCH 49/65] FMT: Typescript checks --- src/libs/migrations/TransactionBackupsToCollection.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index b5519692cc91..4b3fa24fd38c 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.ts +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -32,13 +32,12 @@ export default function (): Promise { // Find all the transaction backups available Object.keys(transactions).forEach((transactionOnyxKey: string) => { const transaction: Transaction | null = transactions[transactionOnyxKey]; - + // Determine whether or not the transaction is a backup if (!transactionOnyxKey.endsWith('-backup') || !transaction) { - // Create the transaction backup in the draft transaction collection onyxData[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`] = transaction; - + // Delete the transaction backup stored in the transaction collection onyxData[transactionOnyxKey] = null; } From aa307498694afb52cbd30b3b7b2833c707166cfc Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Sun, 19 Nov 2023 02:01:19 +0300 Subject: [PATCH 50/65] REFACTOR: Transaction null handler --- src/libs/migrations/TransactionBackupsToCollection.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index 4b3fa24fd38c..59ec11a985d6 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.ts +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -27,14 +27,16 @@ export default function (): Promise { Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions'); return resolve(); } + const onyxData: OnyxCollection = {}; // Find all the transaction backups available Object.keys(transactions).forEach((transactionOnyxKey: string) => { const transaction: Transaction | null = transactions[transactionOnyxKey]; - // Determine whether or not the transaction is a backup - if (!transactionOnyxKey.endsWith('-backup') || !transaction) { + // Determine whether the transaction is a backup + if (transactionOnyxKey.endsWith('-backup') && transaction) { + // Create the transaction backup in the draft transaction collection onyxData[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`] = transaction; @@ -43,7 +45,7 @@ export default function (): Promise { } }); - // Determine whether or not any transaction backups were found + // Determine whether any transaction backups were found if (isEmpty(onyxData)) { Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups'); return resolve(); From ad495ca6abc73ad879bdeccec1ee5d47881c5cdd Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Sun, 19 Nov 2023 02:11:39 +0300 Subject: [PATCH 51/65] FMT: lint --- src/libs/migrations/TransactionBackupsToCollection.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index 59ec11a985d6..64925ae1a286 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.ts +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -27,7 +27,7 @@ export default function (): Promise { Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions'); return resolve(); } - + const onyxData: OnyxCollection = {}; // Find all the transaction backups available @@ -36,7 +36,6 @@ export default function (): Promise { // Determine whether the transaction is a backup if (transactionOnyxKey.endsWith('-backup') && transaction) { - // Create the transaction backup in the draft transaction collection onyxData[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`] = transaction; From 80310c6639fd291eae5896b42c37ae50161d2744 Mon Sep 17 00:00:00 2001 From: Antony Kithinzi Date: Sun, 19 Nov 2023 05:00:51 +0300 Subject: [PATCH 52/65] FMT: Grammar corrections --- src/libs/migrations/TransactionBackupsToCollection.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index 64925ae1a286..b0566c95894f 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.ts +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -7,8 +7,8 @@ import {Transaction} from '@src/types/onyx'; /** * This migration moves all the transaction backups stored in the transaction collection, ONYXKEYS.COLLECTION.TRANSACTION, * to a reserved collection that only stores draft transactions, ONYXKEYS.COLLECTION.TRANSACTION_DRAFT. - * The purpose of the migration is that there is a possibility that transaction backups are not filtered from - * by most functions when all transactions are fetched. Eg: getAllReportTransactions (src/libs/TransactionUtils.ts) + * The purpose of the migration is that there is a possibility that transaction backups are not filtered + * by most functions when all transactions are fetched, e.g, getAllReportTransactions (src/libs/TransactionUtils.ts) * One problem that arose from storing transaction backups with the other transactions is that for every distance request * which have their waypoints updated offline, we expect the ReportPreview component to display the default image of a pending map. * However, due to the presence of the transaction backup, the previous map image will be displayed alongside the current pending map. From eb6d7e020e70afff420f8d2488f8fde512e58e44 Mon Sep 17 00:00:00 2001 From: Bartosz Grajdek Date: Sun, 19 Nov 2023 15:58:01 +0100 Subject: [PATCH 53/65] fix: resolve merge conflicts --- src/components/Badge.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 22c056dfdfc4..575646f7dd9c 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -29,7 +29,7 @@ type BadgeProps = { textStyles?: StyleProp; /** Callback to be called on onPress */ - onPress: (event?: GestureResponderEvent | KeyboardEvent) => void; + onPress?: (event?: GestureResponderEvent | KeyboardEvent) => void; }; function Badge({success = false, error = false, pressable = false, text, environment = CONST.ENVIRONMENT.DEV, badgeStyles, textStyles, onPress = () => {}}: BadgeProps) { From 977fbf26fc3ddeb26ed96db566b01c14834dc475 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Fri, 17 Nov 2023 13:23:22 +0100 Subject: [PATCH 54/65] [TS migration] Migrate 'ParentNavigationSubtitle.js' component to TypeScript --- ...btitle.js => ParentNavigationSubtitle.tsx} | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) rename src/components/{ParentNavigationSubtitle.js => ParentNavigationSubtitle.tsx} (65%) diff --git a/src/components/ParentNavigationSubtitle.js b/src/components/ParentNavigationSubtitle.tsx similarity index 65% rename from src/components/ParentNavigationSubtitle.js rename to src/components/ParentNavigationSubtitle.tsx index 0ce6582fe86d..e65a8617a996 100644 --- a/src/components/ParentNavigationSubtitle.js +++ b/src/components/ParentNavigationSubtitle.tsx @@ -1,49 +1,38 @@ -import PropTypes from 'prop-types'; import React from 'react'; +import {StyleProp, ViewStyle} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import Navigation from '@libs/Navigation/Navigation'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; +import {ParentNavigationSummaryParams} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Text from './Text'; -const propTypes = { - parentNavigationSubtitleData: PropTypes.shape({ - // Title of root report room - rootReportName: PropTypes.string, - - // Name of workspace, if any - workspaceName: PropTypes.string, - }).isRequired, +type ParentNavigationSubtitleProps = { + parentNavigationSubtitleData: ParentNavigationSummaryParams; /** parent Report ID */ - parentReportID: PropTypes.string, + parentReportID?: string; /** PressableWithoutFeedack additional styles */ - // eslint-disable-next-line react/forbid-prop-types - pressableStyles: PropTypes.arrayOf(PropTypes.object), -}; - -const defaultProps = { - parentReportID: '', - pressableStyles: [], + pressableStyles?: StyleProp; }; -function ParentNavigationSubtitle(props) { +function ParentNavigationSubtitle({parentNavigationSubtitleData, parentReportID = '', pressableStyles}: ParentNavigationSubtitleProps) { const styles = useThemeStyles(); - const {workspaceName, rootReportName} = props.parentNavigationSubtitleData; + const {workspaceName, rootReportName} = parentNavigationSubtitleData; const {translate} = useLocalize(); return ( { - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(props.parentReportID)); + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(parentReportID)); }} accessibilityLabel={translate('threads.parentNavigationSummary', {rootReportName, workspaceName})} role={CONST.ACCESSIBILITY_ROLE.LINK} - style={[...props.pressableStyles]} + style={pressableStyles} > Date: Mon, 20 Nov 2023 23:11:11 +0300 Subject: [PATCH 55/65] REFACTOR: Replacing third party function, isEmpty, for TS native functions to imporve performance. Also, edited file description and comments to improve clarity, conciseness and grammar --- .../TransactionBackupsToCollection.ts | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index b0566c95894f..ddaa691b8d47 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.ts +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -1,17 +1,14 @@ -import isEmpty from 'lodash/isEmpty'; import Onyx, {OnyxCollection} from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; import {Transaction} from '@src/types/onyx'; /** - * This migration moves all the transaction backups stored in the transaction collection, ONYXKEYS.COLLECTION.TRANSACTION, - * to a reserved collection that only stores draft transactions, ONYXKEYS.COLLECTION.TRANSACTION_DRAFT. - * The purpose of the migration is that there is a possibility that transaction backups are not filtered - * by most functions when all transactions are fetched, e.g, getAllReportTransactions (src/libs/TransactionUtils.ts) - * One problem that arose from storing transaction backups with the other transactions is that for every distance request - * which have their waypoints updated offline, we expect the ReportPreview component to display the default image of a pending map. - * However, due to the presence of the transaction backup, the previous map image will be displayed alongside the current pending map. + * This migration moves all the transaction backups stored in the transaction collection, ONYXKEYS.COLLECTION.TRANSACTION, to a reserved collection that only + * stores draft transactions, ONYXKEYS.COLLECTION.TRANSACTION_DRAFT. The purpose of the migration is that there is a possibility that transaction backups are + * not filtered by most functions, e.g, getAllReportTransactions (src/libs/TransactionUtils.ts). One problem that arose from storing transaction backups with + * the other transactions is that for every distance request which have their waypoints updated offline, we expect the ReportPreview component to display the + * default image of a pending map. However, due to the presence of the transaction backup, the previous map image will be displayed alongside the pending map. * The problem was further discussed in this PR. https://github.com/Expensify/App/pull/30232#issuecomment-178110172 */ export default function (): Promise { @@ -22,8 +19,8 @@ export default function (): Promise { callback: (transactions: OnyxCollection) => { Onyx.disconnect(connectionID); - // Determine whether or not any transactions were found - if (isEmpty(transactions) || !transactions) { + // Determine whether any transactions were stored + if (!transactions || Object.keys(transactions).length === 0) { Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transactions'); return resolve(); } @@ -34,7 +31,7 @@ export default function (): Promise { Object.keys(transactions).forEach((transactionOnyxKey: string) => { const transaction: Transaction | null = transactions[transactionOnyxKey]; - // Determine whether the transaction is a backup + // Determine whether or not the transaction is a backup if (transactionOnyxKey.endsWith('-backup') && transaction) { // Create the transaction backup in the draft transaction collection onyxData[`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`] = transaction; @@ -44,15 +41,15 @@ export default function (): Promise { } }); - // Determine whether any transaction backups were found - if (isEmpty(onyxData)) { + // Determine whether any transaction backups are found + if (Object.keys(onyxData).length === 0) { Log.info('[Migrate Onyx] Skipped TransactionBackupsToCollection migration because there are no transaction backups'); return resolve(); } // Move the transaction backups to the draft transaction collection Onyx.multiSet(onyxData as Partial<{string: [Transaction | null]}>).then(() => { - Log.info('[Migrate Onyx] TransactionBackupsToCollection migration: Moved the transaction backups to the draft transaction collection'); + Log.info('[Migrate Onyx] TransactionBackupsToCollection migration: Successfully moved all the transaction backups to the draft transaction collection'); resolve(); }); }, From ac7a0c5f3ca1269bfa76585bffa692a1fe5e678c Mon Sep 17 00:00:00 2001 From: Shawn Erquhart Date: Mon, 20 Nov 2023 20:12:46 -0500 Subject: [PATCH 56/65] fix: ensure composer not full size when onyx state missing --- src/libs/actions/Report.js | 3 +++ src/pages/home/ReportScreen.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 5d42ccaf9e74..e5023de9183d 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -2002,6 +2002,9 @@ function openReportFromDeepLink(url, isAuthenticated) { Session.waitForUserSignIn().then(() => { Navigation.waitForProtectedRoutes().then(() => { const route = ReportUtils.getRouteFromLink(url); + if (!route) { + return; + } if (route === ROUTES.CONCIERGE) { navigateToConciergeChat(true); return; diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 09d147b05f69..bf924e744c50 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -128,7 +128,7 @@ const defaultProps = { */ function getReportID(route) { // // The reportID is used inside a collection key and should not be empty, as an empty reportID will result in the entire collection being returned. - return String(lodashGet(route, 'params.reportID', null)); + return String(lodashGet(route, 'params.reportID') || 0); } function ReportScreen({ From 36c3c239e82cf1eb3b8b2dd253ae944df3cae395 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 21 Nov 2023 09:47:50 +0700 Subject: [PATCH 57/65] using negative sign --- src/libs/actions/IOU.js | 2 +- tests/actions/IOUTest.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 4d0580624a6a..fd16dd0c5eab 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -2425,7 +2425,7 @@ function getSendMoneyParams(report, amount, currency, comment, paymentMethodType function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMethodType) { const optimisticIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( CONST.IOU.REPORT_ACTION_TYPE.PAY, - iouReport.total * -1, + -iouReport.total, iouReport.currency, '', [recipient], diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js index ad73a026ff08..ed916a7d6fe2 100644 --- a/tests/actions/IOUTest.js +++ b/tests/actions/IOUTest.js @@ -1757,7 +1757,7 @@ describe('actions/IOU', () => { }), ]), originalMessage: expect.objectContaining({ - amount: amount * -1, + amount: -amount, paymentType: CONST.IOU.PAYMENT_TYPE.VBBA, type: 'pay', }), From 281a940cfa1fd0c4286d3f1cb95acadc4ec736fc Mon Sep 17 00:00:00 2001 From: Shawn Erquhart Date: Tue, 21 Nov 2023 09:12:43 -0500 Subject: [PATCH 58/65] drop deeplink handler early return for empty routes --- src/libs/actions/Report.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index e5023de9183d..5d42ccaf9e74 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -2002,9 +2002,6 @@ function openReportFromDeepLink(url, isAuthenticated) { Session.waitForUserSignIn().then(() => { Navigation.waitForProtectedRoutes().then(() => { const route = ReportUtils.getRouteFromLink(url); - if (!route) { - return; - } if (route === ROUTES.CONCIERGE) { navigateToConciergeChat(true); return; From eef89c99cfa596048146e20d458df5942f144dfd Mon Sep 17 00:00:00 2001 From: Situ Chandra Shil <108292595+situchan@users.noreply.github.com> Date: Tue, 21 Nov 2023 22:02:11 +0600 Subject: [PATCH 59/65] Revert "Migrate LHNOptionsList to Flashlist" --- .../LHNOptionsList/LHNOptionsList.js | 45 ++++++++++++++----- src/pages/home/sidebar/SidebarLinks.js | 27 +++++------ src/styles/styles.ts | 1 + tests/perf-test/SidebarLinks.perf-test.js | 6 +-- 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 0d300c5e2179..5e77947187e9 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -1,8 +1,7 @@ -import {FlashList} from '@shopify/flash-list'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import React, {useCallback} from 'react'; -import {View} from 'react-native'; +import {FlatList, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import participantPropTypes from '@components/participantPropTypes'; @@ -12,7 +11,6 @@ import compose from '@libs/compose'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; -import stylePropTypes from '@styles/stylePropTypes'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -21,10 +19,12 @@ import OptionRowLHNData from './OptionRowLHNData'; const propTypes = { /** Wrapper style for the section list */ - style: stylePropTypes, + // eslint-disable-next-line react/forbid-prop-types + style: PropTypes.arrayOf(PropTypes.object), /** Extra styles for the section list container */ - contentContainerStyles: stylePropTypes.isRequired, + // eslint-disable-next-line react/forbid-prop-types + contentContainerStyles: PropTypes.arrayOf(PropTypes.object).isRequired, /** Sections for the section list */ data: PropTypes.arrayOf(PropTypes.string).isRequired, @@ -80,7 +80,7 @@ const defaultProps = { ...withCurrentReportIDDefaultProps, }; -const keyExtractor = (item) => `report_${item}`; +const keyExtractor = (item) => item; function LHNOptionsList({ style, @@ -99,6 +99,28 @@ function LHNOptionsList({ currentReportID, }) { const styles = useThemeStyles(); + /** + * This function is used to compute the layout of any given item in our list. Since we know that each item will have the exact same height, this is a performance optimization + * so that the heights can be determined before the options are rendered. Otherwise, the heights are determined when each option is rendering and it causes a lot of overhead on large + * lists. + * + * @param {Array} itemData - This is the same as the data we pass into the component + * @param {Number} index the current item's index in the set of data + * + * @returns {Object} + */ + const getItemLayout = useCallback( + (itemData, index) => { + const optionHeight = optionMode === CONST.OPTION_MODE.COMPACT ? variables.optionRowHeightCompact : variables.optionRowHeight; + return { + length: optionHeight, + offset: index * optionHeight, + index, + }; + }, + [optionMode], + ); + /** * Function which renders a row in the list * @@ -142,17 +164,20 @@ function LHNOptionsList({ return ( - ); diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index a59dc81aad54..5e69be266342 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -1,7 +1,7 @@ /* eslint-disable rulesdir/onyx-props-must-have-default */ import PropTypes from 'prop-types'; import React, {useCallback, useEffect, useRef} from 'react'; -import {InteractionManager, StyleSheet, View} from 'react-native'; +import {InteractionManager, View} from 'react-native'; import _ from 'underscore'; import LogoComponent from '@assets/images/expensify-wordmark.svg'; import Header from '@components/Header'; @@ -177,21 +177,16 @@ function SidebarLinks({onLinkClick, insets, optionListItems, isLoading, priority - - - {isLoading && ( - - - - )} - + + + {isLoading && } ); } diff --git a/src/styles/styles.ts b/src/styles/styles.ts index c1b78a224eb3..e597f0ec874e 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -1367,6 +1367,7 @@ const styles = (theme: ThemeColors) => }, sidebarListContainer: { + scrollbarWidth: 'none', paddingBottom: 4, }, diff --git a/tests/perf-test/SidebarLinks.perf-test.js b/tests/perf-test/SidebarLinks.perf-test.js index 5601c588bb93..f6819d40a48f 100644 --- a/tests/perf-test/SidebarLinks.perf-test.js +++ b/tests/perf-test/SidebarLinks.perf-test.js @@ -105,9 +105,9 @@ test('should scroll and click some of the items', () => { expect(lhnOptionsList).toBeDefined(); fireEvent.scroll(lhnOptionsList, eventData); - // find elements that are currently visible in the viewport - const button1 = await screen.findByTestId('7'); - const button2 = await screen.findByTestId('8'); + + const button1 = await screen.findByTestId('1'); + const button2 = await screen.findByTestId('2'); fireEvent.press(button1); fireEvent.press(button2); }; From ef759316908a5b2579dd7a78f1c66f53f0eddec1 Mon Sep 17 00:00:00 2001 From: Shawn Erquhart Date: Tue, 21 Nov 2023 11:52:37 -0500 Subject: [PATCH 60/65] improve getReportID() solution comment --- src/pages/home/ReportScreen.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index bf924e744c50..7b58e0172870 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -127,7 +127,11 @@ const defaultProps = { * @returns {String} */ function getReportID(route) { - // // The reportID is used inside a collection key and should not be empty, as an empty reportID will result in the entire collection being returned. + // The report ID is used in an onyx key. If it's an empty string, onyx will return + // a collection instead of an individual report. + // We can't use the default value functionality of `lodash.get()` because it only + // provides a default value on `undefined`, and will return an empty string. + // Placing the default value outside of `lodash.get()` is intentional. return String(lodashGet(route, 'params.reportID') || 0); } From a13e6da3aa2a58b4a19d52a9d46d570da95cd4bd Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 21 Nov 2023 09:54:31 -0700 Subject: [PATCH 61/65] Fix escaping in DeployBlocker --- .github/workflows/deployBlocker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployBlocker.yml b/.github/workflows/deployBlocker.yml index b55354b95571..50fb9df68b33 100644 --- a/.github/workflows/deployBlocker.yml +++ b/.github/workflows/deployBlocker.yml @@ -32,7 +32,7 @@ jobs: channel: '#expensify-open-source', attachments: [{ color: "#DB4545", - text: '💥 We have found a New Expensify Deploy Blocker, if you have any idea which PR could be causing this, please comment in the issue: <${{ github.event.issue.html_url }}|${{ toJSON(github.event.issue.title) }}>', + text: '💥 We have found a New Expensify Deploy Blocker, if you have any idea which PR could be causing this, please comment in the issue: <${{ github.event.issue.html_url }}|${{ github.event.issue.title }}>'.replace(/[&<>"']/g, function(m) { return {'&': '&', '<': '<', '>': '>', '"': '"', "'": '''}[m]; }), }] } env: From 9ba22969b6d54146fd92f14d296ebf93fc3d71cd Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 21 Nov 2023 09:56:02 -0700 Subject: [PATCH 62/65] Add escaping for vertical bar --- .github/workflows/deployBlocker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployBlocker.yml b/.github/workflows/deployBlocker.yml index 50fb9df68b33..d118b3fee252 100644 --- a/.github/workflows/deployBlocker.yml +++ b/.github/workflows/deployBlocker.yml @@ -32,7 +32,7 @@ jobs: channel: '#expensify-open-source', attachments: [{ color: "#DB4545", - text: '💥 We have found a New Expensify Deploy Blocker, if you have any idea which PR could be causing this, please comment in the issue: <${{ github.event.issue.html_url }}|${{ github.event.issue.title }}>'.replace(/[&<>"']/g, function(m) { return {'&': '&', '<': '<', '>': '>', '"': '"', "'": '''}[m]; }), + text: '💥 We have found a New Expensify Deploy Blocker, if you have any idea which PR could be causing this, please comment in the issue: <${{ github.event.issue.html_url }}|${{ github.event.issue.title }}>'.replace(/[&<>"'|]/g, function(m) { return {'&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '|': '|'}[m]; }), }] } env: From a7c92af6688ed498cbf2b07e30ea0c8469fe7124 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Tue, 21 Nov 2023 16:56:31 +0000 Subject: [PATCH 63/65] Update version to 1.4.1-8 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index c538ddb6ca52..a2d613202650 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -91,8 +91,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001040107 - versionName "1.4.1-7" + versionCode 1001040108 + versionName "1.4.1-8" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 25d3f8c4a3c3..0bd37af34846 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.1.7 + 1.4.1.8 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 3d9e32ca6d05..79de06844987 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.1.7 + 1.4.1.8 diff --git a/package-lock.json b/package-lock.json index 124570368227..1263b7282f77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.1-7", + "version": "1.4.1-8", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.1-7", + "version": "1.4.1-8", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index fde0eed5d910..21fc98829381 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.1-7", + "version": "1.4.1-8", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 3e34f9fcd5925d5b6b12018e9d6fc9f39ba94765 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 21 Nov 2023 09:57:33 -0700 Subject: [PATCH 64/65] Use regular github.token for creating the deploy checklist --- .github/workflows/createDeployChecklist.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/createDeployChecklist.yml b/.github/workflows/createDeployChecklist.yml index dde65f5a1503..9a1cac41ed69 100644 --- a/.github/workflows/createDeployChecklist.yml +++ b/.github/workflows/createDeployChecklist.yml @@ -14,15 +14,7 @@ jobs: - name: Setup Node uses: ./.github/actions/composite/setupNode - - name: Set up git for OSBotify - id: setupGitForOSBotify - uses: ./.github/actions/composite/setupGitForOSBotifyApp - with: - GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} - OS_BOTIFY_APP_ID: ${{ secrets.OS_BOTIFY_APP_ID }} - OS_BOTIFY_PRIVATE_KEY: ${{ secrets.OS_BOTIFY_PRIVATE_KEY }} - - name: Create or update deploy checklist uses: ./.github/actions/javascript/createOrUpdateStagingDeploy with: - GITHUB_TOKEN: ${{ steps.setupGitForOSBotify.outputs.OS_BOTIFY_API_TOKEN }} + GITHUB_TOKEN: ${{ github.token }} From 733f5ac0bffa44133c1436e3523e2701aa570439 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Tue, 21 Nov 2023 16:58:16 +0000 Subject: [PATCH 65/65] Update version to 1.4.1-9 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index a2d613202650..e344d2198c9f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -91,8 +91,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001040108 - versionName "1.4.1-8" + versionCode 1001040109 + versionName "1.4.1-9" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 0bd37af34846..71bc6755acf6 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.1.8 + 1.4.1.9 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 79de06844987..f3f807f675de 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.1.8 + 1.4.1.9 diff --git a/package-lock.json b/package-lock.json index 1263b7282f77..16ae3c7db542 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.1-8", + "version": "1.4.1-9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.1-8", + "version": "1.4.1-9", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 21fc98829381..fce7849357e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.1-8", + "version": "1.4.1-9", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",