From 25fa661c3a7ce5d8c92d4022e4d136ac2bbb8ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Sun, 24 Apr 2022 11:27:11 +0300 Subject: [PATCH 001/172] small images for scaling problem fixed --- src/components/ImageView/index.js | 22 +++++++++------------- src/components/ImageView/index.native.js | 4 ++-- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 2017962b5e83..b2c08aef615c 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -48,12 +48,12 @@ class ImageView extends PureComponent { } componentDidMount() { - if (this.canUseTouchScreen) { - return; - } Image.getSize(this.props.url, (width, height) => { this.setImageRegion(width, height); }); + if (this.canUseTouchScreen) { + return; + } document.addEventListener('mousemove', this.trackMovement.bind(this)); } @@ -129,22 +129,16 @@ class ImageView extends PureComponent { * @param {Number} imageHeight */ setImageRegion(imageWidth, imageHeight) { - let width = imageWidth; - let height = imageHeight; + const width = imageWidth; + const height = imageHeight; const containerHeight = this.state.containerHeight; const containerWidth = this.state.containerWidth; // return if image not loaded yet - if (imageHeight <= 0 || containerHeight <= 0) { + if (imageHeight <= 0) { return; } - // Fit the image to container size if image small than container. - const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth); - if (aspectRatio > 1) { - width *= (aspectRatio); - height *= (aspectRatio); - } let imgLeft = (this.props.windowWidth - width) / 2; let imgRight = ((this.props.windowWidth - width) / 2) + width; let imgTop = (this.props.windowHeight - height) / 2; @@ -243,7 +237,9 @@ class ImageView extends PureComponent { if (this.canUseTouchScreen) { return ( this.scrollableRef = el} style={[styles.imageViewContainer, styles.overflowHidden]} + onLayout={this.onContainerLayoutChanged} > = 1 ? 'center' : 'contain'} onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} /> diff --git a/src/components/ImageView/index.native.js b/src/components/ImageView/index.native.js index f851246e56ef..135fb241a3dd 100644 --- a/src/components/ImageView/index.native.js +++ b/src/components/ImageView/index.native.js @@ -78,8 +78,8 @@ class ImageView extends PureComponent { // Resize small images to fit the screen. Else resize the smaller dimension to avoid resize issue on Android - https://github.com/Expensify/App/pull/7660#issuecomment-1071622163 if (imageHeight < containerHeight && imageWidth < containerWidth) { - imageHeight *= aspectRatio; - imageWidth *= aspectRatio; + // imageHeight *= aspectRatio; + // imageWidth *= aspectRatio; } else if (imageHeight > imageWidth) { imageHeight *= aspectRatio; } else { From d2715fca3dde37ab1b7b45e988d3af42304c60e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Mon, 25 Apr 2022 21:41:13 +0300 Subject: [PATCH 002/172] Unnecessary lines deleted --- src/components/ImageView/index.native.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/components/ImageView/index.native.js b/src/components/ImageView/index.native.js index 135fb241a3dd..3539dc846fbc 100644 --- a/src/components/ImageView/index.native.js +++ b/src/components/ImageView/index.native.js @@ -76,13 +76,9 @@ class ImageView extends PureComponent { const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth); - // Resize small images to fit the screen. Else resize the smaller dimension to avoid resize issue on Android - https://github.com/Expensify/App/pull/7660#issuecomment-1071622163 - if (imageHeight < containerHeight && imageWidth < containerWidth) { - // imageHeight *= aspectRatio; - // imageWidth *= aspectRatio; - } else if (imageHeight > imageWidth) { + if ((imageHeight > containerHeight || imageWidth > containerWidth) && imageHeight > imageWidth) { imageHeight *= aspectRatio; - } else { + } else if (imageHeight > containerHeight || imageWidth > containerWidth) { imageWidth *= aspectRatio; } From 184e4caa92c1a81c8d649a67e0b610deace59f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Tue, 26 Apr 2022 23:45:44 +0300 Subject: [PATCH 003/172] Unnecessary conditions and callbacks deleted --- src/components/ImageView/index.js | 15 ++++----------- src/components/ImageView/index.native.js | 4 ++-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index b2c08aef615c..908b9550d4fe 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -48,12 +48,12 @@ class ImageView extends PureComponent { } componentDidMount() { - Image.getSize(this.props.url, (width, height) => { - this.setImageRegion(width, height); - }); if (this.canUseTouchScreen) { return; } + Image.getSize(this.props.url, (width, height) => { + this.setImageRegion(width, height); + }); document.addEventListener('mousemove', this.trackMovement.bind(this)); } @@ -134,11 +134,6 @@ class ImageView extends PureComponent { const containerHeight = this.state.containerHeight; const containerWidth = this.state.containerWidth; - // return if image not loaded yet - if (imageHeight <= 0) { - return; - } - let imgLeft = (this.props.windowWidth - width) / 2; let imgRight = ((this.props.windowWidth - width) / 2) + width; let imgTop = (this.props.windowHeight - height) / 2; @@ -237,9 +232,7 @@ class ImageView extends PureComponent { if (this.canUseTouchScreen) { return ( this.scrollableRef = el} style={[styles.imageViewContainer, styles.overflowHidden]} - onLayout={this.onContainerLayoutChanged} > = 1 ? 'center' : 'contain'} + resizeMode="center" onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} /> diff --git a/src/components/ImageView/index.native.js b/src/components/ImageView/index.native.js index 3539dc846fbc..eaada91d37a9 100644 --- a/src/components/ImageView/index.native.js +++ b/src/components/ImageView/index.native.js @@ -76,9 +76,9 @@ class ImageView extends PureComponent { const aspectRatio = Math.min(containerHeight / imageHeight, containerWidth / imageWidth); - if ((imageHeight > containerHeight || imageWidth > containerWidth) && imageHeight > imageWidth) { + if (imageHeight > imageWidth) { imageHeight *= aspectRatio; - } else if (imageHeight > containerHeight || imageWidth > containerWidth) { + } else { imageWidth *= aspectRatio; } From 71be3ee3b2f6a4c311d13b1bb66a9197f1eed648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Sat, 30 Apr 2022 12:31:43 +0300 Subject: [PATCH 004/172] in setImageRegion function imageHeight condition added --- src/components/ImageView/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 908b9550d4fe..2f8e23a060eb 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -134,6 +134,11 @@ class ImageView extends PureComponent { const containerHeight = this.state.containerHeight; const containerWidth = this.state.containerWidth; + // return if image not loaded yet + if (imageHeight <= 0) { + return; + } + let imgLeft = (this.props.windowWidth - width) / 2; let imgRight = ((this.props.windowWidth - width) / 2) + width; let imgTop = (this.props.windowHeight - height) / 2; From 2bc6fa65d08e2ed7864c05395a47cadf5beb6345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Sat, 14 May 2022 00:03:30 +0300 Subject: [PATCH 005/172] reverted change --- src/components/ImageView/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 2f8e23a060eb..f02db45a9616 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -135,7 +135,7 @@ class ImageView extends PureComponent { const containerWidth = this.state.containerWidth; // return if image not loaded yet - if (imageHeight <= 0) { + if (imageHeight <= 0 && containerHeight <= 0) { return; } From fe81aaa6d98cd3e1719139ca50f4ac4691bbd898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Sun, 22 May 2022 21:14:06 +0300 Subject: [PATCH 006/172] removed thumbnail from native code when loading, condition has been added again after merge. --- src/components/ImageView/index.js | 15 +++++++-------- src/components/ImageView/index.native.js | 8 -------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 521fb3868d1f..ede7f55f76eb 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -125,18 +125,17 @@ class ImageView extends PureComponent { * @param {Number} imageHeight */ setImageRegion(imageWidth, imageHeight) { - if (imageHeight <= 0) { - return; - } const containerHeight = this.state.containerHeight; const containerWidth = this.state.containerWidth; - const width = imageWidth; - const height = imageHeight; - const newZoomScale = Math.min(containerWidth / width, containerHeight / height); + + if (imageHeight <= 0 || containerHeight <= 0) { + return; + } + const newZoomScale = Math.min(containerWidth / imageWidth, containerHeight / imageHeight); this.setState({ - imgWidth: width, - imgHeight: height, + imgWidth: imageWidth, + imgHeight: imageHeight, zoomScale: newZoomScale, }); } diff --git a/src/components/ImageView/index.native.js b/src/components/ImageView/index.native.js index b7f5dff0af36..cf763b7a00fc 100644 --- a/src/components/ImageView/index.native.js +++ b/src/components/ImageView/index.native.js @@ -8,7 +8,6 @@ import ImageZoom from 'react-native-image-pan-zoom'; import ImageSize from 'react-native-image-size'; import _ from 'underscore'; import styles from '../../styles/styles'; -import * as StyleUtils from '../../styles/StyleUtils'; import variables from '../../styles/variables'; import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions'; import FullscreenLoadingIndicator from '../FullscreenLoadingIndicator'; @@ -29,8 +28,6 @@ class ImageView extends PureComponent { this.state = { isLoading: false, - thumbnailWidth: 100, - thumbnailHeight: 100, imageWidth: undefined, imageHeight: undefined, interactionPromise: undefined, @@ -138,11 +135,6 @@ class ImageView extends PureComponent { }); }} > - From b05db83a445ad43b785af7cc69d83d8d03b956bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Tue, 24 May 2022 23:06:11 +0300 Subject: [PATCH 007/172] setScale method added. --- src/components/ImageView/index.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index ede7f55f76eb..1386fceb9f30 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -67,11 +67,11 @@ class ImageView extends PureComponent { const {width, height} = e.nativeEvent.layout; const imageWidth = this.state.imgWidth; const imageHeight = this.state.imgHeight; - const scale = imageHeight && imageWidth ? Math.min(width / imageWidth, height / imageHeight) : 0; + + this.setScale(width, height, imageWidth, imageHeight); this.setState({ containerHeight: height, containerWidth: width, - zoomScale: scale, }); } @@ -120,7 +120,7 @@ class ImageView extends PureComponent { } /** - * When open image, set image width, height and zoomScale. + * When open image, set image width, height. * @param {Number} imageWidth * @param {Number} imageHeight */ @@ -128,18 +128,32 @@ class ImageView extends PureComponent { const containerHeight = this.state.containerHeight; const containerWidth = this.state.containerWidth; - if (imageHeight <= 0 || containerHeight <= 0) { + if (imageHeight <= 0) { return; } - const newZoomScale = Math.min(containerWidth / imageWidth, containerHeight / imageHeight); + this.setScale(containerWidth, containerHeight, imageWidth, imageHeight); this.setState({ imgWidth: imageWidth, imgHeight: imageHeight, - zoomScale: newZoomScale, }); } + /** + * When image and container have width calculate and set the zoomScale. + * @param {Number} containerWidth + * @param {Number} containerHeight + * @param {Number} imageWidth + * @param {Number} imageHeight + */ + setScale(containerWidth, containerHeight, imageWidth, imageHeight) { + if (!containerWidth || !imageWidth) { + return; + } + const newZoomScale = Math.min(containerWidth / imageWidth, containerHeight / imageHeight); + this.setState({zoomScale: newZoomScale}); + } + /** * Convert touch point to zoomed point * @param {Boolean} x x point when click zoom From aee1d1e06ec6f10fee5f3d31947bda2544f34020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Wed, 25 May 2022 00:17:47 +0300 Subject: [PATCH 008/172] Removed unnecessary variable assignments. --- src/components/ImageView/index.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 1386fceb9f30..1183d27995a3 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -65,10 +65,7 @@ class ImageView extends PureComponent { */ onContainerLayoutChanged(e) { const {width, height} = e.nativeEvent.layout; - const imageWidth = this.state.imgWidth; - const imageHeight = this.state.imgHeight; - - this.setScale(width, height, imageWidth, imageHeight); + this.setScale(width, height, this.state.imgWidth, this.state.imgHeight); this.setState({ containerHeight: height, containerWidth: width, @@ -125,14 +122,11 @@ class ImageView extends PureComponent { * @param {Number} imageHeight */ setImageRegion(imageWidth, imageHeight) { - const containerHeight = this.state.containerHeight; - const containerWidth = this.state.containerWidth; - if (imageHeight <= 0) { return; } - this.setScale(containerWidth, containerHeight, imageWidth, imageHeight); + this.setScale(this.state.containerWidth, this.state.containerHeight, imageWidth, imageHeight); this.setState({ imgWidth: imageWidth, imgHeight: imageHeight, @@ -140,7 +134,6 @@ class ImageView extends PureComponent { } /** - * When image and container have width calculate and set the zoomScale. * @param {Number} containerWidth * @param {Number} containerHeight * @param {Number} imageWidth From 5aa5749230f1b50e50860fc30b9d15e0349e6259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Tue, 31 May 2022 22:50:38 +0300 Subject: [PATCH 009/172] zoomScale calculation on mWeb added and when loading images doesnt show now --- src/components/ImageView/index.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 1183d27995a3..3e6effd4c84b 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -43,12 +43,12 @@ class ImageView extends PureComponent { } componentDidMount() { - if (this.canUseTouchScreen) { - return; - } Image.getSize(this.props.url, (width, height) => { this.setImageRegion(width, height); }); + if (this.canUseTouchScreen) { + return; + } document.addEventListener('mousemove', this.trackMovement.bind(this)); } @@ -203,14 +203,15 @@ class ImageView extends PureComponent { return ( 1 ? 'center' : 'contain'} // For big dimension images 'contain' works much effective onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} /> @@ -246,10 +247,10 @@ class ImageView extends PureComponent { > Date: Tue, 31 May 2022 22:52:45 +0300 Subject: [PATCH 010/172] typo fixed --- src/components/ImageView/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 3e6effd4c84b..59b2ca35bf8b 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -210,7 +210,7 @@ class ImageView extends PureComponent { style={this.state.zoomScale === 0 ? undefined : [ styles.w100, styles.h100, - ]} // Hide image until zoomScale scale calculated + ]} // Hide image until zoomScale calculated resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'} // For big dimension images 'contain' works much effective onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} @@ -250,7 +250,7 @@ class ImageView extends PureComponent { style={this.state.zoomScale === 0 ? undefined : [ styles.h100, styles.w100, - ]} // Hide image until zoomScale scale calculated + ]} // Hide image until zoomScale calculated resizeMode="contain" onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} From ee96405bee37c1062379ca56898063e1aa8eda0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Sat, 4 Jun 2022 10:31:46 +0300 Subject: [PATCH 011/172] comment changed --- src/components/ImageView/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 59b2ca35bf8b..5fbd1b7da653 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -211,7 +211,7 @@ class ImageView extends PureComponent { styles.w100, styles.h100, ]} // Hide image until zoomScale calculated - resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'} // For big dimension images 'contain' works much effective + resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'} // For big dimension images 'center' makes resizing the view. There is no sizing with 'contain'. onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} /> From eb3d169e57ab22d236bf3eac64622b65b7df22f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Metehan=20=C3=96zyurt?= Date: Fri, 17 Jun 2022 22:10:34 +0300 Subject: [PATCH 012/172] comments became more understandable. --- src/components/ImageView/index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 5fbd1b7da653..6b83da58dc27 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -210,8 +210,11 @@ class ImageView extends PureComponent { style={this.state.zoomScale === 0 ? undefined : [ styles.w100, styles.h100, - ]} // Hide image until zoomScale calculated - resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'} // For big dimension images 'center' makes resizing the view. There is no sizing with 'contain'. + ]} // Hide image until zoomScale calculated to prevent showing preview with wrong dimensions. + resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'} // When Image dimensions are lower + // than the container boundary(zoomscale <= 1), use `contain` to render the image with natural dimensions. + // Both `center` and `contain` keeps the image centered on both x and y axis. + onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} /> @@ -250,7 +253,7 @@ class ImageView extends PureComponent { style={this.state.zoomScale === 0 ? undefined : [ styles.h100, styles.w100, - ]} // Hide image until zoomScale calculated + ]} // Hide image until zoomScale calculated to prevent showing preview with wrong dimensions. resizeMode="contain" onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} From 18798c36665f0534a8966dad487b3023feebe1b3 Mon Sep 17 00:00:00 2001 From: sahil Date: Mon, 20 Jun 2022 17:11:47 +0530 Subject: [PATCH 013/172] add specific error messages --- src/pages/EnablePayments/AdditionalDetailsStep.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js index 4ba70e297843..f8d78120ae3f 100644 --- a/src/pages/EnablePayments/AdditionalDetailsStep.js +++ b/src/pages/EnablePayments/AdditionalDetailsStep.js @@ -106,6 +106,18 @@ class AdditionalDetailsStep extends React.Component { 'ssn', ]; + this.errorTranslationKeys = { + legalFirstName: 'bankAccount.error.firstName', + legalLastName: 'bankAccount.error.lastName', + addressStreet: 'bankAccount.error.addressStreet', + addressCity: 'bankAccount.error.addressCity', + addressState: 'bankAccount.error.addressState', + addressZip: 'bankAccount.error.zipCode', + phoneNumber: 'bankAccount.error.phoneNumber', + dob: 'bankAccount.error.dob', + ssn: 'bankAccount.error.ssnLast4', + }; + this.fieldNameTranslationKeys = { legalFirstName: 'additionalDetailsStep.legalFirstNameLabel', legalLastName: 'additionalDetailsStep.legalLastNameLabel', @@ -141,7 +153,7 @@ class AdditionalDetailsStep extends React.Component { return ''; } - return `${this.props.translate(this.fieldNameTranslationKeys[fieldName])} ${this.props.translate('common.isRequiredField')}.`; + return this.props.translate(this.errorTranslationKeys[fieldName]); } /** From 5945666ccfaf05977b80df8e7077116d050bc7f7 Mon Sep 17 00:00:00 2001 From: sahil Date: Mon, 20 Jun 2022 18:25:54 +0530 Subject: [PATCH 014/172] show error when the user isn't 18 --- .../EnablePayments/AdditionalDetailsStep.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js index f8d78120ae3f..006e8bd3383c 100644 --- a/src/pages/EnablePayments/AdditionalDetailsStep.js +++ b/src/pages/EnablePayments/AdditionalDetailsStep.js @@ -115,6 +115,7 @@ class AdditionalDetailsStep extends React.Component { addressZip: 'bankAccount.error.zipCode', phoneNumber: 'bankAccount.error.phoneNumber', dob: 'bankAccount.error.dob', + age: 'bankAccount.error.age', ssn: 'bankAccount.error.ssnLast4', }; @@ -176,6 +177,10 @@ class AdditionalDetailsStep extends React.Component { errors.dob = true; } + if (!ValidationUtils.meetsAgeRequirements(this.props.walletAdditionalDetailsDraft.dob)) { + errors.age = true; + } + if (!ValidationUtils.isValidAddress(this.props.walletAdditionalDetailsDraft.addressStreet)) { errors.addressStreet = true; } @@ -213,6 +218,16 @@ class AdditionalDetailsStep extends React.Component { }); } + /** + * Clear both errors associated with dob, and set the new value. + * + * @param {String} value + */ + clearDateErrorsAndSetValue(value) { + this.formHelper.clearErrors(this.props, ['dob', 'age']); + Wallet.updateAdditionalDetailsDraft({dob: value}); + } + /** * @param {String} fieldName * @param {String} value @@ -339,10 +354,10 @@ class AdditionalDetailsStep extends React.Component { this.clearErrorAndSetValue('dob', val)} + onInputChange={val => this.clearDateErrorsAndSetValue(val)} defaultValue={this.props.walletAdditionalDetailsDraft.dob || ''} placeholder={this.props.translate('common.dob')} - errorText={this.getErrorText('dob')} + errorText={this.getErrorText('dob') || this.getErrorText('age')} maximumDate={new Date()} /> Date: Mon, 20 Jun 2022 22:01:49 +0300 Subject: [PATCH 015/172] Comments moved before prop. --- src/components/ImageView/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 6b83da58dc27..9da52d9993cb 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -211,10 +211,10 @@ class ImageView extends PureComponent { styles.w100, styles.h100, ]} // Hide image until zoomScale calculated to prevent showing preview with wrong dimensions. - resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'} // When Image dimensions are lower - // than the container boundary(zoomscale <= 1), use `contain` to render the image with natural dimensions. - // Both `center` and `contain` keeps the image centered on both x and y axis. + // When Image dimensions are lower than the container boundary(zoomscale <= 1), use `contain` to render the image with natural dimensions. + // Both `center` and `contain` keeps the image centered on both x and y axis. + resizeMode={this.state.zoomScale > 1 ? 'center' : 'contain'} onLoadStart={this.imageLoadingStart} onLoadEnd={this.imageLoadingEnd} /> From fa4989410355cecd1a8a7372b8f2f1f1b14c7da9 Mon Sep 17 00:00:00 2001 From: madmax330 Date: Wed, 22 Jun 2022 12:59:46 +0400 Subject: [PATCH 016/172] Refactor markasunread --- src/libs/actions/Report.js | 44 ++++++++++++++++--- .../report/ContextMenu/ContextMenuActions.js | 2 +- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index f529931b5c80..fbd061f48789 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -118,6 +118,21 @@ function getUnreadActionCount(report) { return Math.max(0, unreadActionCount); } +/** + * Returns the number of unread actions for a reportID + * + * @param {Number} reportID + * @param {Number} sequenceNumber + * @returns {Number} + */ +function getUnreadActionCountFromSequenceNumber(reportID, sequenceNumber) { + const reportMaxSequenceNumber = reportMaxSequenceNumbers[reportID]; + + // Determine the number of unread actions by deducting the last read sequence from the total. If, for some reason, + // the last read sequence is higher than the actual last sequence, let's just assume all actions are read + return Math.max(reportMaxSequenceNumber - sequenceNumber - ReportActions.getDeletedCommentsCount(reportID, sequenceNumber), 0); +} + /** * @param {Object} report * @return {String[]} @@ -411,15 +426,10 @@ function setLocalIOUReportData(iouReportObject) { */ function setLocalLastRead(reportID, lastReadSequenceNumber) { lastReadSequenceNumbers[reportID] = lastReadSequenceNumber; - const reportMaxSequenceNumber = reportMaxSequenceNumbers[reportID]; - - // Determine the number of unread actions by deducting the last read sequence from the total. If, for some reason, - // the last read sequence is higher than the actual last sequence, let's just assume all actions are read - const unreadActionCount = Math.max(reportMaxSequenceNumber - lastReadSequenceNumber - ReportActions.getDeletedCommentsCount(reportID, lastReadSequenceNumber), 0); // Update the report optimistically. Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, { - unreadActionCount, + unreadActionCount: getUnreadActionCountFromSequenceNumber(reportID, lastReadSequenceNumber), lastVisitedTimestamp: Date.now(), }); } @@ -1111,6 +1121,27 @@ function updateLastReadActionID(reportID, sequenceNumber, manuallyMarked = false }); } +function markCommentAsUnread(reportID, sequenceNumber) { + API.write('MarkCommentAsUnread', + { + markAsUnread: true, + reportID, + sequenceNumber, + }, + { + optimisticData: [{ + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: { + lastVisitedTimestamp: Date.now(), + unreadActionCount: getUnreadActionCountFromSequenceNumber(reportID, sequenceNumber), + }, + }], + successData: [], + failureData: [], + }); +} + /** * Toggles the pinned state of the report. * @@ -1546,4 +1577,5 @@ export { renameReport, getLastReadSequenceNumber, setIsComposerFullSize, + markCommentAsUnread, }; diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index c06d0fea408b..2419e9d6e7b7 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -131,7 +131,7 @@ export default [ successIcon: Expensicons.Checkmark, shouldShow: type => type === CONTEXT_MENU_TYPES.REPORT_ACTION, onPress: (closePopover, {reportAction, reportID}) => { - Report.updateLastReadActionID(reportID, reportAction.sequenceNumber, true); + Report.markCommentAsUnread(reportID, reportAction.sequenceNumber); Report.setNewMarkerPosition(reportID, reportAction.sequenceNumber); if (closePopover) { hideContextMenu(true, ReportActionComposeFocusManager.focus); From 52cb17c834e1800b33d7c5d87605a1c46ea6e481 Mon Sep 17 00:00:00 2001 From: madmax330 Date: Thu, 23 Jun 2022 11:23:00 +0400 Subject: [PATCH 017/172] Read newest action --- src/libs/actions/Report.js | 34 +++++++++++++++++++++- src/pages/home/report/ReportActionsView.js | 6 ++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index fbd061f48789..3ded4aadb45d 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1121,10 +1121,41 @@ function updateLastReadActionID(reportID, sequenceNumber, manuallyMarked = false }); } +/** + * Marks the new report actions as read + * + * @param {Number} reportID + */ +function readNewestAction(reportID) { + const sequenceNumber = reportMaxSequenceNumbers[reportID]; + API.write('ReadNewestAction', + { + reportID, + sequenceNumber, + }, + { + optimisticData: [{ + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: { + lastVisitedTimestamp: Date.now(), + unreadActionCount: getUnreadActionCountFromSequenceNumber(reportID, sequenceNumber), + }, + }], + successData: [], + failureData: [], + }); +} + +/** + * Sets the last read comment on a report + * + * @param {Number} reportID + * @param {Number} sequenceNumber + */ function markCommentAsUnread(reportID, sequenceNumber) { API.write('MarkCommentAsUnread', { - markAsUnread: true, reportID, sequenceNumber, }, @@ -1578,4 +1609,5 @@ export { getLastReadSequenceNumber, setIsComposerFullSize, markCommentAsUnread, + readNewestAction, }; diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 1e919028393f..d51b36c3b6c9 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -242,14 +242,14 @@ class ReportActionsView extends React.Component { // When the last action changes, record the max action // This will make the NEW marker line go away if you receive comments in the same chat you're looking at if (shouldRecordMaxAction) { - Report.updateLastReadActionID(this.props.reportID); + Report.readNewestAction(this.props.reportID); } } // Update the new marker position and last read action when we are closing the sidebar or moving from a small to large screen size if (shouldRecordMaxAction && reportBecomeVisible) { this.updateNewMarkerPosition(this.props.report.unreadActionCount); - Report.updateLastReadActionID(this.props.reportID); + Report.readNewestAction(this.props.reportID); } } @@ -301,7 +301,7 @@ class ReportActionsView extends React.Component { */ scrollToBottomAndUpdateLastRead() { ReportScrollManager.scrollToBottom(); - Report.updateLastReadActionID(this.props.reportID); + Report.readNewestAction(this.props.reportID); } /** From abc97ab19a5c7ace5ac8ef7031a671bd94d081a1 Mon Sep 17 00:00:00 2001 From: sahil Date: Tue, 28 Jun 2022 21:05:23 +0530 Subject: [PATCH 018/172] add specific error for full ssn --- src/languages/en.js | 1 + src/languages/es.js | 1 + .../EnablePayments/AdditionalDetailsStep.js | 21 ++++++++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 02bf873c3a9d..286efb47fd66 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -607,6 +607,7 @@ export default { legalMiddleNameLabel: 'Legal middle name', legalLastNameLabel: 'Legal last name', selectAnswer: 'You need to select a response to proceed.', + ssnFull9Error: 'Please enter a valid 9 digit SSN', needSSNFull9: 'We\'re having trouble verifying your SSN. Please enter the full 9 digits of your SSN.', weCouldNotVerify: 'We could not verify', pleaseFixIt: 'Please fix this information before continuing.', diff --git a/src/languages/es.js b/src/languages/es.js index d7751c630de9..e2326ad8840c 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -607,6 +607,7 @@ export default { legalMiddleNameLabel: 'Segundo nombre legal', legalLastNameLabel: 'Apellido legal', selectAnswer: 'Selecciona una respuesta.', + ssnFull9Error: 'Por favor escribe los 9 dígitos de un SSN válido', needSSNFull9: 'Estamos teniendo problemas para verificar su SSN. Ingresa los 9 dígitos del SSN.', weCouldNotVerify: 'No pudimos verificar', pleaseFixIt: 'Corrije esta información antes de continuar.', diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js index 006e8bd3383c..7d9dbcfe706d 100644 --- a/src/pages/EnablePayments/AdditionalDetailsStep.js +++ b/src/pages/EnablePayments/AdditionalDetailsStep.js @@ -117,6 +117,7 @@ class AdditionalDetailsStep extends React.Component { dob: 'bankAccount.error.dob', age: 'bankAccount.error.age', ssn: 'bankAccount.error.ssnLast4', + ssnFull9: 'additionalDetailsStep.ssnFull9Error', }; this.fieldNameTranslationKeys = { @@ -189,7 +190,11 @@ class AdditionalDetailsStep extends React.Component { errors.phoneNumber = true; } - if (!ValidationUtils.isValidSSNLastFour(this.props.walletAdditionalDetailsDraft.ssn) && !ValidationUtils.isValidSSNFullNine(this.props.walletAdditionalDetailsDraft.ssn)) { + if (this.props.walletAdditionalDetails.shouldAskForFullSSN) { + if (!ValidationUtils.isValidSSNFullNine(this.props.walletAdditionalDetailsDraft.ssn)) { + errors.ssnFull9 = true; + } + } else if (!ValidationUtils.isValidSSNLastFour(this.props.walletAdditionalDetailsDraft.ssn)) { errors.ssn = true; } @@ -228,6 +233,16 @@ class AdditionalDetailsStep extends React.Component { Wallet.updateAdditionalDetailsDraft({dob: value}); } + /** + * Clear ssn and ssnFull9 error and set the new value + * + * @param {String} value + */ + clearSSNErrorAndSetValue(value) { + this.formHelper.clearErrors(this.props, ['ssn', 'ssnFull9']); + Wallet.updateAdditionalDetailsDraft({ssn: value}); + } + /** * @param {String} fieldName * @param {String} value @@ -363,9 +378,9 @@ class AdditionalDetailsStep extends React.Component { this.clearErrorAndSetValue('ssn', val)} + onChangeText={val => this.clearSSNErrorAndSetValue(val)} value={this.props.walletAdditionalDetailsDraft.ssn || ''} - errorText={this.getErrorText('ssn')} + errorText={this.getErrorText('ssnFull9') || this.getErrorText('ssn')} maxLength={shouldAskForFullSSN ? 9 : 4} keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD} /> From 35454e16eeb88cdf066a8ca552d475772efc9dda Mon Sep 17 00:00:00 2001 From: sahil Date: Tue, 28 Jun 2022 22:17:00 +0530 Subject: [PATCH 019/172] handle undefined value for phone number --- src/libs/ValidationUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ValidationUtils.js b/src/libs/ValidationUtils.js index 74545181286e..a562df509c82 100644 --- a/src/libs/ValidationUtils.js +++ b/src/libs/ValidationUtils.js @@ -256,7 +256,7 @@ function validateIdentity(identity) { * @param {Boolean} [isCountryCodeOptional] * @returns {Boolean} */ -function isValidUSPhone(phoneNumber, isCountryCodeOptional) { +function isValidUSPhone(phoneNumber = '', isCountryCodeOptional) { // Remove non alphanumeric characters from the phone number const sanitizedPhone = phoneNumber.replace(CONST.REGEX.NON_ALPHA_NUMERIC, ''); const isUsPhone = isCountryCodeOptional From 6d4f537bbdb16774de6ae8025905fd8a2a193c92 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Tue, 28 Jun 2022 20:29:18 +0200 Subject: [PATCH 020/172] Use new API endpoint LogOut --- src/libs/actions/Session/index.js | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index 1cde31b65674..a17e425fb680 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -21,6 +21,7 @@ import * as ValidationUtils from '../../ValidationUtils'; import * as Authentication from '../../Authentication'; import * as ErrorUtils from '../../ErrorUtils'; import * as Welcome from '../Welcome'; +import * as API from '../../API'; let credentials = {}; Onyx.connect({ @@ -72,25 +73,32 @@ function createAccount(login) { */ function signOut() { Log.info('Flushing logs before signing out', true, {}, true); + Timing.clearData(); + if (credentials && credentials.autoGeneratedLogin) { - // Clean up the login that we created - DeprecatedAPI.DeleteLogin({ + const optimisticData = [ + { + onyxMethod: 'set', + key: ONYXKEYS.SESSION, + value: null, + }, + { + onyxMethod: 'set', + key: ONYXKEYS.CREDENTIALS, + value: null, + } + ]; + API.write('LogOut', { partnerUserID: credentials.autoGeneratedLogin, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, shouldRetry: false, - }) - .then((response) => { - if (response.jsonCode === CONST.JSON_CODE.SUCCESS) { - return; - } - - Onyx.merge(ONYXKEYS.SESSION, {error: response.message}); - }); + }, {optimisticData}); + return; } + Onyx.set(ONYXKEYS.SESSION, null); Onyx.set(ONYXKEYS.CREDENTIALS, null); - Timing.clearData(); } function signOutAndRedirectToSignIn() { From d3af1643928826310184b64204ebea260280666f Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Tue, 28 Jun 2022 20:54:13 +0200 Subject: [PATCH 021/172] Add missing comma --- src/libs/actions/Session/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index a17e425fb680..094fb7417868 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -86,7 +86,7 @@ function signOut() { onyxMethod: 'set', key: ONYXKEYS.CREDENTIALS, value: null, - } + }, ]; API.write('LogOut', { partnerUserID: credentials.autoGeneratedLogin, From f16573a1099fc5fafe926f92d216020cfccfd95d Mon Sep 17 00:00:00 2001 From: madmax330 Date: Wed, 29 Jun 2022 14:57:34 +0400 Subject: [PATCH 022/172] add openreport --- package-lock.json | 2 +- src/libs/actions/Report.js | 18 ++++++++++++++++++ src/pages/home/report/ReportActionsView.js | 6 ++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f76fac6dd5b..6104d3d3a6b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25270,7 +25270,7 @@ "good-listener": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", "requires": { "delegate": "^3.1.2" } diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 3ded4aadb45d..a35874fdd88c 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1121,6 +1121,23 @@ function updateLastReadActionID(reportID, sequenceNumber, manuallyMarked = false }); } +/** + * Gets all the report actions and updates the last read message + * + * @param {Number} reportID + */ +function openReport(reportID) { + API.write('OpenReport', + { + reportID, + }, + { + optimisticData: [], + successData: [], + failureData: [], + }); +} + /** * Marks the new report actions as read * @@ -1610,4 +1627,5 @@ export { setIsComposerFullSize, markCommentAsUnread, readNewestAction, + openReport, }; diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index d51b36c3b6c9..0f771d05cbc0 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -125,7 +125,7 @@ class ReportActionsView extends React.Component { return; } - Report.updateLastReadActionID(this.props.reportID); + Report.openReport(this.props.reportID); }); // If the reportID is not found then we have either not loaded this chat or the user is unable to access it. @@ -145,6 +145,7 @@ class ReportActionsView extends React.Component { this.updateNewMarkerAndMarkReadOnce(); } + Report.openReport(); this.fetchData(); } @@ -201,6 +202,7 @@ class ReportActionsView extends React.Component { componentDidUpdate(prevProps) { if (prevProps.network.isOffline && !this.props.network.isOffline) { + Report.openReport(); this.fetchData(); } @@ -353,7 +355,7 @@ class ReportActionsView extends React.Component { // Only mark as read if the report is open if (!this.props.isDrawerOpen) { - Report.updateLastReadActionID(this.props.reportID); + Report.readNewestAction(this.props.reportID); } } From 06fb754bb679509b2fccc45406dda10e4f3fdf81 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Wed, 29 Jun 2022 13:26:05 +0200 Subject: [PATCH 023/172] Remove whitespace --- src/libs/actions/Session/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index 094fb7417868..988bd61abd42 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -87,7 +87,7 @@ function signOut() { key: ONYXKEYS.CREDENTIALS, value: null, }, - ]; + ]; API.write('LogOut', { partnerUserID: credentials.autoGeneratedLogin, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, From c32335f901b6e97b5bfc364232e97a5fbb24d8b3 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Wed, 29 Jun 2022 13:26:20 +0200 Subject: [PATCH 024/172] Prevent auth attempt if no creds stored --- src/libs/Authentication.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libs/Authentication.js b/src/libs/Authentication.js index cd32c958eb25..dc982eda9886 100644 --- a/src/libs/Authentication.js +++ b/src/libs/Authentication.js @@ -58,10 +58,19 @@ function Authenticate(parameters) { * @returns {Promise} */ function reauthenticate(command = '') { + const credentials = NetworkStore.getCredentials(); + + // Hack to prevent Authenticate.reauthenticate from being called after calling new LogOut command + // LogOut used to have `shouldRetry: false` which prevented this in the old middleware, but now + // shouldRetry is hard coded to `true` in `API.write` + if (!credentials) { + NetworkStore.setIsAuthenticating(false); + return; + } + // Prevent any more requests from being processed while authentication happens NetworkStore.setIsAuthenticating(true); - const credentials = NetworkStore.getCredentials(); return Authenticate({ useExpensifyLogin: false, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, From c7fdd605b402a3b64db52e82bb3c9ef218dd48af Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Wed, 29 Jun 2022 14:54:57 +0200 Subject: [PATCH 025/172] Reset authenticate code --- src/libs/Authentication.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/libs/Authentication.js b/src/libs/Authentication.js index dc982eda9886..cd32c958eb25 100644 --- a/src/libs/Authentication.js +++ b/src/libs/Authentication.js @@ -58,19 +58,10 @@ function Authenticate(parameters) { * @returns {Promise} */ function reauthenticate(command = '') { - const credentials = NetworkStore.getCredentials(); - - // Hack to prevent Authenticate.reauthenticate from being called after calling new LogOut command - // LogOut used to have `shouldRetry: false` which prevented this in the old middleware, but now - // shouldRetry is hard coded to `true` in `API.write` - if (!credentials) { - NetworkStore.setIsAuthenticating(false); - return; - } - // Prevent any more requests from being processed while authentication happens NetworkStore.setIsAuthenticating(true); + const credentials = NetworkStore.getCredentials(); return Authenticate({ useExpensifyLogin: false, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, From c71ee2441f63787eb4918638b2fdee375ac632d1 Mon Sep 17 00:00:00 2001 From: Alex Beaman Date: Wed, 29 Jun 2022 14:55:24 +0200 Subject: [PATCH 026/172] Send authToken with command --- src/libs/actions/Session/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index 988bd61abd42..bc9b85dc0b76 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -22,6 +22,7 @@ import * as Authentication from '../../Authentication'; import * as ErrorUtils from '../../ErrorUtils'; import * as Welcome from '../Welcome'; import * as API from '../../API'; +import * as NetworkStore from '../../Network/NetworkStore'; let credentials = {}; Onyx.connect({ @@ -89,6 +90,8 @@ function signOut() { }, ]; API.write('LogOut', { + // Send current authToken because we will immediately clear it once triggering this command + authToken: NetworkStore.getAuthToken(), partnerUserID: credentials.autoGeneratedLogin, partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, From dda655e70ddb126c3d3f903a9ef05c992a3b6912 Mon Sep 17 00:00:00 2001 From: madmax330 Date: Wed, 29 Jun 2022 17:37:19 +0400 Subject: [PATCH 027/172] polish + style --- src/libs/actions/Report.js | 17 +++++++++++++---- src/pages/home/report/ReportActionsView.js | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index d3f9965ea673..5a926b44e41c 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -120,9 +120,9 @@ function getUnreadActionCount(report) { /** * Returns the number of unread actions for a reportID - * - * @param {Number} reportID - * @param {Number} sequenceNumber + * + * @param {Number} reportID + * @param {Number} sequenceNumber * @returns {Number} */ function getUnreadActionCountFromSequenceNumber(reportID, sequenceNumber) { @@ -1125,12 +1125,21 @@ function updateLastReadActionID(reportID, sequenceNumber, manuallyMarked = false * @param {Number} reportID */ function openReport(reportID) { + const sequenceNumber = reportMaxSequenceNumbers[reportID]; API.write('OpenReport', { reportID, + sequenceNumber, }, { - optimisticData: [], + optimisticData: [{ + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: { + lastVisitedTimestamp: Date.now(), + unreadActionCount: getUnreadActionCountFromSequenceNumber(reportID, sequenceNumber), + }, + }], successData: [], failureData: [], }); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 0f771d05cbc0..6b74ab01cd4a 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -145,7 +145,7 @@ class ReportActionsView extends React.Component { this.updateNewMarkerAndMarkReadOnce(); } - Report.openReport(); + Report.openReport(this.props.reportID); this.fetchData(); } @@ -202,7 +202,7 @@ class ReportActionsView extends React.Component { componentDidUpdate(prevProps) { if (prevProps.network.isOffline && !this.props.network.isOffline) { - Report.openReport(); + Report.openReport(this.props.reportID); this.fetchData(); } From df64eae9afa7b43c044f3e97a0d2c96145bac888 Mon Sep 17 00:00:00 2001 From: madmax330 Date: Wed, 29 Jun 2022 17:42:32 +0400 Subject: [PATCH 028/172] revert package lock --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 32a3f6516362..7173d498089c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25087,7 +25087,7 @@ "good-listener": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", "requires": { "delegate": "^3.1.2" } From 1de5f7a1d4be1d90b30c6ae17990f162652e938a Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 30 Jun 2022 17:04:38 -0300 Subject: [PATCH 029/172] using new API for preferred locale --- src/libs/actions/App.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 06596e9003ca..63f5ccbf9fe8 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -4,6 +4,7 @@ import lodashGet from 'lodash/get'; import Str from 'expensify-common/lib/str'; import ONYXKEYS from '../../ONYXKEYS'; import * as DeprecatedAPI from '../deprecatedAPI'; +import * as API from '../API'; import CONST from '../../CONST'; import Log from '../Log'; import Performance from '../Performance'; @@ -52,10 +53,24 @@ function setCurrentURL(url) { * @param {String} locale */ function setLocale(locale) { - if (currentUserAccountID) { - DeprecatedAPI.PreferredLocale_Update({name: 'preferredLocale', value: locale}); + // If user is not signed in, change just locally. + if (!currentUserAccountID) { + Onyx.merge(ONYXKEYS.NVP_PREFERRED_LOCALE, locale); + return; } - Onyx.merge(ONYXKEYS.NVP_PREFERRED_LOCALE, locale); + + // Optimistically change preferred locale + const optimisticData = [ + { + onyxMethod: 'merge', + key: ONYXKEYS.NVP_PREFERRED_LOCALE, + value: locale, + }, + ]; + + API.write('UpdatePreferredLocale', { + value: locale, + }, {optimisticData}); } function getLocale() { From 99ff7406c0ad74083539181f384686e051f2dde6 Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Thu, 30 Jun 2022 23:42:04 +0200 Subject: [PATCH 030/172] Removing the Venmo payment option --- src/components/ButtonWithMenu.js | 2 +- src/components/SettlementButton.js | 56 ------------------------------ src/libs/actions/IOU.js | 17 +-------- src/pages/iou/IOUDetailsModal.js | 9 ----- src/pages/iou/IOUModal.js | 1 - 5 files changed, 2 insertions(+), 83 deletions(-) diff --git a/src/components/ButtonWithMenu.js b/src/components/ButtonWithMenu.js index e9fafa75095e..5e20ce5c2c1c 100644 --- a/src/components/ButtonWithMenu.js +++ b/src/components/ButtonWithMenu.js @@ -21,7 +21,7 @@ const propTypes = { isDisabled: PropTypes.bool, /** Menu options to display */ - /** e.g. [{text: 'Pay with Expensify', icon: Wallet}, {text: 'PayPal', icon: PayPal}, {text: 'Venmo', icon: Venmo}] */ + /** e.g. [{text: 'Pay with Expensify', icon: Wallet}, {text: 'PayPal', icon: PayPal}] */ options: PropTypes.arrayOf(PropTypes.shape({ value: PropTypes.string.isRequired, text: PropTypes.string.isRequired, diff --git a/src/components/SettlementButton.js b/src/components/SettlementButton.js index 2997d2cadc60..5c31191dbce2 100644 --- a/src/components/SettlementButton.js +++ b/src/components/SettlementButton.js @@ -24,15 +24,11 @@ const propTypes = { /** Should we show paypal option */ shouldShowPaypal: PropTypes.bool, - /** Associated phone login for the person we are sending money to */ - recipientPhoneNumber: PropTypes.string, - ...withLocalizePropTypes, }; const defaultProps = { currency: CONST.CURRENCY.USD, - recipientPhoneNumber: '', shouldShowPaypal: false, }; @@ -64,63 +60,11 @@ class SettlementButton extends React.Component { value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE, }); - // Venmo requires an async call to the native layer to determine availability and will be added as an option if available. - this.checkVenmoAvailabilityPromise = null; - this.state = { buttonOptions, }; } - componentDidMount() { - this.addVenmoPaymentOptionToMenu(); - } - - componentWillUnmount() { - if (!this.checkVenmoAvailabilityPromise) { - return; - } - - this.checkVenmoAvailabilityPromise.cancel(); - this.checkVenmoAvailabilityPromise = null; - } - - /** - * @returns {Boolean} - */ - doesRecipientHaveValidPhoneLogin() { - return this.props.recipientPhoneNumber && ValidationUtils.isValidUSPhone(this.props.recipientPhoneNumber); - } - - /** - * Adds Venmo, if available, as the second option in the menu of payment options - */ - addVenmoPaymentOptionToMenu() { - if (this.props.currency !== CONST.CURRENCY.USD || !this.doesRecipientHaveValidPhoneLogin()) { - return; - } - - this.checkVenmoAvailabilityPromise = makeCancellablePromise(isAppInstalled('venmo')); - this.checkVenmoAvailabilityPromise - .promise - .then((isVenmoInstalled) => { - if (!isVenmoInstalled) { - return; - } - - this.setState(prevState => ({ - buttonOptions: [...prevState.buttonOptions.slice(0, 1), - { - text: this.props.translate('iou.settleVenmo'), - icon: Expensicons.Venmo, - value: CONST.IOU.PAYMENT_TYPE.VENMO, - }, - ...prevState.buttonOptions.slice(1), - ], - })); - }); - } - render() { return ( { diff --git a/src/pages/iou/IOUDetailsModal.js b/src/pages/iou/IOUDetailsModal.js index bd406810dc73..0835558d4423 100644 --- a/src/pages/iou/IOUDetailsModal.js +++ b/src/pages/iou/IOUDetailsModal.js @@ -91,13 +91,6 @@ class IOUDetailsModal extends Component { this.fetchData(); } - /** - * @returns {String} - */ - getSubmitterPhoneNumber() { - return _.first(lodashGet(this.props, 'iouReport.submitterPhoneNumbers', [])) || ''; - } - fetchData() { Report.fetchIOUReportByID(this.props.route.params.iouReportID, this.props.route.params.chatReportID, true); } @@ -113,7 +106,6 @@ class IOUDetailsModal extends Component { amount: this.props.iouReport.total, currency: this.props.iouReport.currency, requestorPayPalMeAddress: this.props.iouReport.submitterPayPalMeAddress, - requestorPhoneNumber: this.getSubmitterPhoneNumber(), }); } @@ -148,7 +140,6 @@ class IOUDetailsModal extends Component { this.performIOUPayment(paymentMethodType)} - recipientPhoneNumber={this.getSubmitterPhoneNumber()} shouldShowPaypal={Boolean(lodashGet(this.props, 'iouReport.submitterPayPalMeAddress'))} currency={lodashGet(this.props, 'iouReport.currency')} enablePaymentsRoute={ROUTES.IOU_DETAILS_ENABLE_PAYMENTS} diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 561b8a328364..7a187fd56d77 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -302,7 +302,6 @@ class IOUModal extends Component { amount, currency, requestorPayPalMeAddress: this.state.participants[0].payPalMeAddress, - requestorPhoneNumber: this.state.participants[0].phoneNumber, comment, newIOUReportDetails, }) From 35b93ad5ccfd851894d06a00301aca8cfa6c3b97 Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Thu, 30 Jun 2022 23:47:48 +0200 Subject: [PATCH 031/172] Removing other mentions of Venmo --- src/components/IOUConfirmationList.js | 1 - src/languages/en.js | 1 - src/languages/es.js | 1 - src/stories/ButtonWithDropdown.stories.js | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 96b26834f616..6f14ab005268 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -370,7 +370,6 @@ class IOUConfirmationList extends Component { isLoading={isLoading} onPress={this.confirm} shouldShowPaypal={Boolean(recipient.payPalMeAddress)} - recipientPhoneNumber={recipient.phoneNumber} enablePaymentsRoute={ROUTES.IOU_SEND_ENABLE_PAYMENTS} addBankAccountRoute={ROUTES.IOU_SEND_ADD_BANK_ACCOUNT} addDebitCardRoute={ROUTES.IOU_SEND_ADD_DEBIT_CARD} diff --git a/src/languages/en.js b/src/languages/en.js index 02bf873c3a9d..4f1579aafaf5 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -228,7 +228,6 @@ export default { settleExpensify: 'Pay with Expensify', settleElsewhere: 'I\'ll settle up elsewhere', settlePaypalMe: 'Pay with PayPal.me', - settleVenmo: 'Pay with Venmo', request: ({amount}) => `Request ${amount}`, youowe: ({owner}) => `You owe ${owner}`, youpaid: ({owner}) => `You paid ${owner}`, diff --git a/src/languages/es.js b/src/languages/es.js index d7751c630de9..fc4f6671b249 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -228,7 +228,6 @@ export default { settleExpensify: 'Pagar con Expensify', settleElsewhere: 'Voy a pagar de otra forma', settlePaypalMe: 'Pagar con PayPal.me', - settleVenmo: 'Pagar con Venmo', request: ({amount}) => `Solicitar ${amount}`, youowe: ({owner}) => `Le debes a ${owner}`, youpaid: ({owner}) => `Le pagaste a ${owner}`, diff --git a/src/stories/ButtonWithDropdown.stories.js b/src/stories/ButtonWithDropdown.stories.js index 5007649ed87f..9073a77e43b4 100644 --- a/src/stories/ButtonWithDropdown.stories.js +++ b/src/stories/ButtonWithDropdown.stories.js @@ -18,7 +18,7 @@ const Template = args => ; // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args const Default = Template.bind({}); Default.args = { - buttonText: 'Pay with Venmo', + buttonText: 'Pay with PayPal.me', }; export default story; From 4af229f7e6bcd9ab59addbc0b0577741659ef3a2 Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Fri, 1 Jul 2022 00:06:39 +0200 Subject: [PATCH 032/172] Remove the Venmo query from Android manifesto --- android/app/src/main/AndroidManifest.xml | 9 --------- src/components/SettlementButton.js | 3 --- 2 files changed, 12 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 912aa6d5a9b0..a5d23081f6f2 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,15 +7,6 @@ - - - - - - - - Date: Thu, 30 Jun 2022 16:53:37 -0700 Subject: [PATCH 033/172] Use new AuthenticatePusher NewDot Optimized API commands --- src/ONYXKEYS.js | 3 +++ src/libs/PusherConnectionManager.js | 16 ++++++++++++- src/libs/actions/Session/index.js | 37 +++-------------------------- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 1f47b414ee23..33d325c935a7 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -196,4 +196,7 @@ export default { FORMS: { ADD_DEBIT_CARD_FORM: 'addDebitCardForm', }, + + // Pusher token + PUSHER_AUTHORIZATION: 'pusherAuthorization', }; diff --git a/src/libs/PusherConnectionManager.js b/src/libs/PusherConnectionManager.js index 7c4b685c90c0..7585800cafc4 100644 --- a/src/libs/PusherConnectionManager.js +++ b/src/libs/PusherConnectionManager.js @@ -1,8 +1,21 @@ import lodashGet from 'lodash/get'; +import Onyx from 'react-native-onyx'; import * as Pusher from './Pusher/pusher'; import * as Session from './actions/Session'; import Log from './Log'; import CONST from '../CONST'; +import ONYXKEYS from '../ONYXKEYS'; + +let authorizerCallback; +Onyx.connect({ + key: ONYXKEYS.PUSHER_AUTHORIZATION, + callback: (authorizationData) => { + if (!authorizerCallback) { + return; + } + authorizerCallback(authorizationData.error, authorizationData.token); + }, +}); function init() { /** @@ -13,7 +26,8 @@ function init() { */ Pusher.registerCustomAuthorizer(channel => ({ authorize: (socketID, callback) => { - Session.authenticatePusher(socketID, channel.name, callback); + authorizerCallback = callback; + Session.authenticatePusher(socketID, channel.name); }, })); diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index 1cde31b65674..46fbef5f6863 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -21,6 +21,7 @@ import * as ValidationUtils from '../../ValidationUtils'; import * as Authentication from '../../Authentication'; import * as ErrorUtils from '../../ErrorUtils'; import * as Welcome from '../Welcome'; +import * as API from '../../API'; let credentials = {}; Onyx.connect({ @@ -444,47 +445,15 @@ const reauthenticatePusher = _.throttle(() => { }); }, 5000, {trailing: false}); -/** - * @param {String} socketID - * @param {String} channelName - * @param {Function} callback - */ function authenticatePusher(socketID, channelName, callback) { Log.info('[PusherAuthorizer] Attempting to authorize Pusher', false, {channelName}); - DeprecatedAPI.Push_Authenticate({ + API.read('AuthenticatePusher', { socket_id: socketID, channel_name: channelName, shouldRetry: false, forceNetworkRequest: true, - }) - .then((response) => { - if (response.jsonCode === CONST.JSON_CODE.NOT_AUTHENTICATED) { - Log.hmmm('[PusherAuthorizer] Unable to authenticate Pusher because authToken is expired'); - callback(new Error('Pusher failed to authenticate because authToken is expired'), {auth: ''}); - - // Attempt to refresh the authToken then reconnect to Pusher - reauthenticatePusher(); - return; - } - - if (response.jsonCode !== CONST.JSON_CODE.SUCCESS) { - Log.hmmm('[PusherAuthorizer] Unable to authenticate Pusher for reason other than expired session'); - callback(new Error(`Pusher failed to authenticate because code: ${response.jsonCode} message: ${response.message}`), {auth: ''}); - return; - } - - Log.info( - '[PusherAuthorizer] Pusher authenticated successfully', - false, - {channelName}, - ); - callback(null, response); - }) - .catch((error) => { - Log.hmmm('[PusherAuthorizer] Unhandled error: ', {channelName, error}); - callback(new Error('Push_Authenticate request failed'), {auth: ''}); - }); + }); } /** From c8dddd74ffcfac5ae864b0debc4233a818f0f927 Mon Sep 17 00:00:00 2001 From: Kosuke Tseng Date: Thu, 30 Jun 2022 21:36:18 -0700 Subject: [PATCH 034/172] Add new wrapper --- src/components/FormAlertWrapper.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/components/FormAlertWrapper.js diff --git a/src/components/FormAlertWrapper.js b/src/components/FormAlertWrapper.js new file mode 100644 index 000000000000..8853b5437190 --- /dev/null +++ b/src/components/FormAlertWrapper.js @@ -0,0 +1,28 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {View} from 'react-native'; +import compose from '../libs/compose'; +import styles from '../styles/styles'; + +const propTypes = { + /** Styles for container element */ + containerStyles: PropTypes.arrayOf(PropTypes.object), +}; + +const defaultProps = { + containerStyles: [], +}; + +const FormAlertWrapper = (props) => { + return ( + + + ); +}; + +FormAlertWrapper.propTypes = propTypes; +FormAlertWrapper.defaultProps = defaultProps; +FormAlertWrapper.displayName = 'FormAlertWrapper'; + +export default compose( +)(FormAlertWrapper); From 16ac2c40918e067a7863206154321a5f2a9ae090 Mon Sep 17 00:00:00 2001 From: Kosuke Tseng Date: Thu, 30 Jun 2022 23:25:27 -0700 Subject: [PATCH 035/172] Add isDisabled --- src/components/ButtonWithDropdown.js | 4 ++++ src/components/ButtonWithMenu.js | 1 + 2 files changed, 5 insertions(+) diff --git a/src/components/ButtonWithDropdown.js b/src/components/ButtonWithDropdown.js index e4eb23502741..8e02a04350e5 100644 --- a/src/components/ButtonWithDropdown.js +++ b/src/components/ButtonWithDropdown.js @@ -17,6 +17,9 @@ const propTypes = { /** Callback to execute when the dropdown element is pressed */ onDropdownPress: PropTypes.func, + /** Should this button be disabled? */ + isDisabled: PropTypes.bool, + /** Whether we should show a loading state for the main button */ isLoading: PropTypes.bool, }; @@ -24,6 +27,7 @@ const propTypes = { const defaultProps = { onButtonPress: () => {}, onDropdownPress: () => {}, + isDisabled: false, isLoading: false, }; diff --git a/src/components/ButtonWithMenu.js b/src/components/ButtonWithMenu.js index e9fafa75095e..e8c5e2590d31 100644 --- a/src/components/ButtonWithMenu.js +++ b/src/components/ButtonWithMenu.js @@ -59,6 +59,7 @@ class ButtonWithMenu extends PureComponent { {this.props.options.length > 1 ? ( this.props.onPress(event, this.state.selectedItem.value)} onDropdownPress={() => { From 9b64a6ba61dc51b36fb7935493e19bce56dc2ae9 Mon Sep 17 00:00:00 2001 From: Kosuke Tseng Date: Thu, 30 Jun 2022 23:30:21 -0700 Subject: [PATCH 036/172] Add wrapper functionality --- src/components/FormAlertWrapper.js | 81 +++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/src/components/FormAlertWrapper.js b/src/components/FormAlertWrapper.js index 8853b5437190..4a683f4066f4 100644 --- a/src/components/FormAlertWrapper.js +++ b/src/components/FormAlertWrapper.js @@ -1,21 +1,96 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import _ from 'underscore'; import {View} from 'react-native'; +import PropTypes from 'prop-types'; +import React from 'react'; +import {withNetwork} from './OnyxProvider'; +import Icon from './Icon'; +import * as Expensicons from './Icon/Expensicons'; +import RenderHTML from './RenderHTML'; +import TextLink from './TextLink'; +import Text from './Text'; +import colors from '../styles/colors'; import compose from '../libs/compose'; +import networkPropTypes from './networkPropTypes'; import styles from '../styles/styles'; +import withLocalize, {withLocalizePropTypes} from './withLocalize'; const propTypes = { + /** Children to wrap */ + children: PropTypes.node.isRequired, + /** Styles for container element */ containerStyles: PropTypes.arrayOf(PropTypes.object), + + /** Whether to show the alert text */ + isAlertVisible: PropTypes.bool.isRequired, + + /** Whether message is in html format */ + isMessageHtml: PropTypes.bool, + + /** Error message to display above button */ + message: PropTypes.string, + + /** Props to detect online status */ + network: networkPropTypes.isRequired, + + ...withLocalizePropTypes, }; const defaultProps = { containerStyles: [], + isMessageHtml: false, + message: '', }; const FormAlertWrapper = (props) => { + function getAlertPrompt() { + let error = ''; + + if (!_.isEmpty(props.message)) { + if (props.isMessageHtml) { + error = ( + ${props.message}`} /> + ); + } else { + error = ( + {props.message} + ); + } + } else { + error = ( + <> + + {`${props.translate('common.please')} `} + + + {props.translate('common.fixTheErrors')} + + + {` ${props.translate('common.inTheFormBeforeContinuing')}.`} + + + ); + } + + return ( + + {error} + + ); + } + return ( + {props.isAlertVisible && ( + + + {getAlertPrompt()} + + )} + {props.children(props.network.isOffline)} ); }; @@ -25,4 +100,6 @@ FormAlertWrapper.defaultProps = defaultProps; FormAlertWrapper.displayName = 'FormAlertWrapper'; export default compose( + withLocalize, + withNetwork(), )(FormAlertWrapper); From 2b56a4111fd29e94e4e12e07ce98bcf72a7f7ae8 Mon Sep 17 00:00:00 2001 From: Kosuke Tseng Date: Thu, 30 Jun 2022 23:39:58 -0700 Subject: [PATCH 037/172] Add offline indicator --- src/components/FormAlertWrapper.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/FormAlertWrapper.js b/src/components/FormAlertWrapper.js index 4a683f4066f4..c10ff159ee8f 100644 --- a/src/components/FormAlertWrapper.js +++ b/src/components/FormAlertWrapper.js @@ -10,6 +10,7 @@ import TextLink from './TextLink'; import Text from './Text'; import colors from '../styles/colors'; import compose from '../libs/compose'; +import OfflineIndicator from './OfflineIndicator'; import networkPropTypes from './networkPropTypes'; import styles from '../styles/styles'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; @@ -91,6 +92,7 @@ const FormAlertWrapper = (props) => { )} {props.children(props.network.isOffline)} + {props.network.isOffline && ()} ); }; From 6d31ea57c75b6fd624b24955437e2b2fbd7dfa4b Mon Sep 17 00:00:00 2001 From: Kosuke Tseng Date: Thu, 30 Jun 2022 23:40:19 -0700 Subject: [PATCH 038/172] Add it to Payment page for example --- .../settings/Payments/PaymentMethodList.js | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/pages/settings/Payments/PaymentMethodList.js b/src/pages/settings/Payments/PaymentMethodList.js index 9f1ddd25ea33..4374aa24f4ff 100644 --- a/src/pages/settings/Payments/PaymentMethodList.js +++ b/src/pages/settings/Payments/PaymentMethodList.js @@ -15,6 +15,7 @@ import CONST from '../../../CONST'; import * as Expensicons from '../../../components/Icon/Expensicons'; import bankAccountPropTypes from '../../../components/bankAccountPropTypes'; import * as PaymentUtils from '../../../libs/PaymentUtils'; +import FormAlertWrapper from '../../../components/FormAlertWrapper'; const MENU_ITEM = 'menuItem'; const BUTTON = 'button'; @@ -210,17 +211,23 @@ class PaymentMethodList extends Component { } if (item.type === BUTTON) { return ( -