From 1519e28afc76e2c1d97627eb29e7e95c3fbab255 Mon Sep 17 00:00:00 2001 From: Peter Velkov Date: Thu, 23 Feb 2023 12:34:02 +0200 Subject: [PATCH 1/4] Revert "Merge pull request #9995 from b1tjoy/fix/9183-prevent-avatar-icon-from-flicker" This reverts commit 92186e50db3d37064a07d0a5c9ddcf81df39d3ad, reversing changes made to 99def939e2cdbbccdfb4fc42255faabbf76ef38b. --- src/components/Avatar.js | 8 +------- src/libs/getAvatarDefaultSource/index.js | 7 ------- src/libs/getAvatarDefaultSource/index.native.js | 5 ----- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/libs/getAvatarDefaultSource/index.js delete mode 100644 src/libs/getAvatarDefaultSource/index.native.js diff --git a/src/components/Avatar.js b/src/components/Avatar.js index ed05a78d18c4..687ed8d4f5c4 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -8,7 +8,6 @@ import themeColors from '../styles/themes/default'; import CONST from '../CONST'; import * as StyleUtils from '../styles/StyleUtils'; import * as Expensicons from './Icon/Expensicons'; -import getAvatarDefaultSource from '../libs/getAvatarDefaultSource'; import Image from './Image'; import {withNetwork} from './OnyxProvider'; import networkPropTypes from './networkPropTypes'; @@ -119,12 +118,7 @@ class Avatar extends PureComponent { ) : ( - this.setState({imageError: true})} - /> + this.setState({imageError: true})} /> )} ); diff --git a/src/libs/getAvatarDefaultSource/index.js b/src/libs/getAvatarDefaultSource/index.js deleted file mode 100644 index 54c2a7d04b01..000000000000 --- a/src/libs/getAvatarDefaultSource/index.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Avatar icon flickers when message is sent for the first time, return and set the source as - * defaultSource prop of image to prevent avatar icon from flicker when running on Web/Desktop - * @param {String|Function} source The source of avatar image - * @return {Object} The image source - */ -export default source => ({uri: source}); diff --git a/src/libs/getAvatarDefaultSource/index.native.js b/src/libs/getAvatarDefaultSource/index.native.js deleted file mode 100644 index 1c1c79caf151..000000000000 --- a/src/libs/getAvatarDefaultSource/index.native.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Avatar icon does not flicker when running on Native, return and set undefined as defaultSource prop of image - * @return {Object} undefined - */ -export default () => undefined; From 4c5341372819eaa85704800dd22a6dcbc0562b0d Mon Sep 17 00:00:00 2001 From: Peter Velkov Date: Sat, 4 Mar 2023 19:46:48 +0200 Subject: [PATCH 2/4] Update Image to not render briefly with `undefined` source --- src/components/Image/index.js | 39 +++++++++++++++-------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/components/Image/index.js b/src/components/Image/index.js index 0b42f3ee25d7..0e2555972274 100644 --- a/src/components/Image/index.js +++ b/src/components/Image/index.js @@ -2,42 +2,28 @@ import React from 'react'; import {Image as RNImage} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; -import _ from 'underscore'; import ONYXKEYS from '../../ONYXKEYS'; import {defaultProps, imagePropTypes} from './imagePropTypes'; import RESIZE_MODES from './resizeModes'; class Image extends React.Component { - constructor(props) { - super(props); - - this.debouncedConfigureImageSource = _.debounce(this.configureImageSource, 220); - - this.state = { - imageSource: undefined, - }; - } - componentDidMount() { - this.debouncedConfigureImageSource(); + this.configureOnLoad(); } componentDidUpdate(prevProps) { - if (prevProps.source.uri === this.props.source.uri) { + if (prevProps.source === this.props.source) { return; } - - this.debouncedConfigureImageSource.cancel(); - this.debouncedConfigureImageSource(); + this.configureOnLoad(); } /** * Check if the image source is a URL - if so the `encryptedAuthToken` is appended - * to the source. The natural image dimensions can then be retrieved using this source - * and as a result the `onLoad` event needs to be maunually invoked to return these dimensions + * to the source. + * @returns {Object} - the configured image source */ - configureImageSource() { - this.props.onLoadStart(); + getImageSource() { const source = this.props.source; let imageSource = source; if (this.props.isAuthTokenRequired) { @@ -47,14 +33,22 @@ class Image extends React.Component { const authToken = lodashGet(this.props, 'session.encryptedAuthToken', null); imageSource = {uri: `${source.uri}?encryptedAuthToken=${encodeURIComponent(authToken)}`}; } - this.setState({imageSource}); + return imageSource; + } + + /** + * The natural image dimensions are retrieved using the updated source + * and as a result the `onLoad` event needs to be manually invoked to return these dimensions + */ + configureOnLoad() { // If an onLoad callback was specified then manually call it and pass // the natural image dimensions to match the native API if (this.props.onLoad == null) { return; } + const imageSource = this.getImageSource(); RNImage.getSize(imageSource.uri, (width, height) => { this.props.onLoad({nativeEvent: {width, height}}); }); @@ -63,9 +57,10 @@ class Image extends React.Component { render() { // eslint-disable-next-line const { source, onLoad, ...rest } = this.props; + const imageSource = this.getImageSource(); // eslint-disable-next-line - return ; + return ; } } From 9bb4ac7c0e394c490800ee13b777ac3f5542325d Mon Sep 17 00:00:00 2001 From: Peter Velkov Date: Mon, 6 Mar 2023 15:25:28 +0200 Subject: [PATCH 3/4] Image - omit props that shouldn't be forwarded --- src/components/Image/index.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/Image/index.js b/src/components/Image/index.js index 0e2555972274..43b3d112c19e 100644 --- a/src/components/Image/index.js +++ b/src/components/Image/index.js @@ -2,6 +2,7 @@ import React from 'react'; import {Image as RNImage} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; +import _ from 'underscore'; import ONYXKEYS from '../../ONYXKEYS'; import {defaultProps, imagePropTypes} from './imagePropTypes'; import RESIZE_MODES from './resizeModes'; @@ -55,12 +56,12 @@ class Image extends React.Component { } render() { - // eslint-disable-next-line - const { source, onLoad, ...rest } = this.props; - const imageSource = this.getImageSource(); + // Omit the props which the underlying RNImage won't use + const forwardedProps = _.omit(this.props, ['source', 'onLoad', 'session', 'isAuthTokenRequired']); + const source = this.getImageSource(); - // eslint-disable-next-line - return ; + // eslint-disable-next-line react/jsx-props-no-spreading + return ; } } From c4abb46b0799568a1b0a1a9fb7f1049376bb2832 Mon Sep 17 00:00:00 2001 From: Peter Velkov Date: Thu, 23 Mar 2023 20:12:36 +0200 Subject: [PATCH 4/4] Use @expensify/react-native-web v0.18.15 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d83093d1f5d..1528ae678a2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@expensify/react-native-web": "0.18.12", + "@expensify/react-native-web": "0.18.15", "@formatjs/intl-getcanonicallocales": "^1.5.8", "@formatjs/intl-locale": "^2.4.21", "@formatjs/intl-numberformat": "^6.2.5", @@ -2468,9 +2468,9 @@ "dev": true }, "node_modules/@expensify/react-native-web": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@expensify/react-native-web/-/react-native-web-0.18.12.tgz", - "integrity": "sha512-0+4XdDTNM2/XsURL++qJyBrrmpsm/mgZ+z1QgPahBkS85DxHvUkj4fwFidN8kkONz5yn2URfr6PxVqAQ0dpETg==", + "version": "0.18.15", + "resolved": "https://registry.npmjs.org/@expensify/react-native-web/-/react-native-web-0.18.15.tgz", + "integrity": "sha512-xE3WdGKY4SRLfIrimUlgP78ZsDaWy3g+KIO8mpxTm9zCXeX/sgEYs6QvhFghgEhhp7Y1bLH9LWTKiZy9LZM8EA==", "dependencies": { "@babel/runtime": "^7.18.6", "create-react-class": "^15.7.0", @@ -46538,9 +46538,9 @@ } }, "@expensify/react-native-web": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@expensify/react-native-web/-/react-native-web-0.18.12.tgz", - "integrity": "sha512-0+4XdDTNM2/XsURL++qJyBrrmpsm/mgZ+z1QgPahBkS85DxHvUkj4fwFidN8kkONz5yn2URfr6PxVqAQ0dpETg==", + "version": "0.18.15", + "resolved": "https://registry.npmjs.org/@expensify/react-native-web/-/react-native-web-0.18.15.tgz", + "integrity": "sha512-xE3WdGKY4SRLfIrimUlgP78ZsDaWy3g+KIO8mpxTm9zCXeX/sgEYs6QvhFghgEhhp7Y1bLH9LWTKiZy9LZM8EA==", "requires": { "@babel/runtime": "^7.18.6", "create-react-class": "^15.7.0", diff --git a/package.json b/package.json index c7d117b580e0..085b2e95dad4 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "test:e2e": "node tests/e2e/testRunner.js --development" }, "dependencies": { - "@expensify/react-native-web": "0.18.12", + "@expensify/react-native-web": "0.18.15", "@formatjs/intl-getcanonicallocales": "^1.5.8", "@formatjs/intl-locale": "^2.4.21", "@formatjs/intl-numberformat": "^6.2.5",