Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[No QA] [TS Migration] Migrate 'ImageWithSizeCalculation.js' component to TypeScript #30179

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/Image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ const ImageWithOnyx = React.memo(
imagePropsAreEqual,
);
ImageWithOnyx.resizeMode = RESIZE_MODES;

export {RESIZE_MODES};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pasyukevich Is there any reason we are exporting RESIZE_MODES from here again? why can't we use it from ./resizeModes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to keep approach that used before and have all that is needed for the component from one file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pasyukevich Files should be named after the component/function/constants they export, respecting the casing used for it. read more here

if there is no strong reason can we just use values from ./resizeModes everywhere? this will make it less confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

export default ImageWithOnyx;
1 change: 1 addition & 0 deletions src/components/Image/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ const ImageWithOnyx = withOnyx({
})(Image);
ImageWithOnyx.resizeMode = RESIZE_MODES;
ImageWithOnyx.resolveDimensions = resolveDimensions;
export {RESIZE_MODES};
export default ImageWithOnyx;
Original file line number Diff line number Diff line change
@@ -1,66 +1,57 @@
import _ from 'underscore';
import React, {useState, useRef, useEffect} from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import {View, ViewStyle, StyleProp} from 'react-native';
import delay from 'lodash/delay';
import {OnLoadEvent} from 'react-native-fast-image';
import Log from '../libs/Log';
import styles from '../styles/styles';
import FullscreenLoadingIndicator from './FullscreenLoadingIndicator';
import Image from './Image';
import Image, {RESIZE_MODES} from './Image';

const propTypes = {
type OnMeasure = (args: {width: number; height: number}) => void;

type ImageWithSizeCalculationProps = {
/** Url for image to display */
url: PropTypes.string.isRequired,
url: string;

/** Any additional styles to apply */
// eslint-disable-next-line react/forbid-prop-types
style: PropTypes.any,
style?: StyleProp<ViewStyle>;

/** Callback fired when the image has been measured. */
onMeasure: PropTypes.func,
onMeasure: OnMeasure;

/** Whether the image requires an authToken */
isAuthTokenRequired: PropTypes.bool,
};

const defaultProps = {
style: {},
onMeasure: () => {},
isAuthTokenRequired: false,
isAuthTokenRequired: boolean;
};

/**
* Preloads an image by getting the size and passing dimensions via callback.
* Image size must be provided by parent via width and height props. Useful for
* performing some calculation on a network image after fetching dimensions so
* it can be appropriately resized.
*
* @param {Object} props
* @returns {React.Component}
*
*/
function ImageWithSizeCalculation(props) {
const isLoadedRef = useRef(null);
function ImageWithSizeCalculation({url, style, onMeasure, isAuthTokenRequired}: ImageWithSizeCalculationProps) {
const isLoadedRef = useRef<boolean | null>(null);
const [isImageCached, setIsImageCached] = useState(true);
const [isLoading, setIsLoading] = useState(false);

const onError = () => {
Log.hmmm('Unable to fetch image to calculate size', {url: props.url});
Log.hmmm('Unable to fetch image to calculate size', {url});
};

const imageLoadedSuccessfully = (event) => {
const imageLoadedSuccessfully = (event: OnLoadEvent) => {
isLoadedRef.current = true;
props.onMeasure({
onMeasure({
width: event.nativeEvent.width,
height: event.nativeEvent.height,
});
};

/** Delay the loader to detect whether the image is being loaded from the cache or the internet. */
useEffect(() => {
if (isLoadedRef.current || !isLoading) {
if (isLoadedRef.current ?? !isLoading) {
return;
}
const timeout = _.delay(() => {
const timeout = delay(() => {
if (!isLoading || isLoadedRef.current) {
return;
}
Expand All @@ -70,14 +61,14 @@ function ImageWithSizeCalculation(props) {
}, [isLoading]);

return (
<View style={[styles.w100, styles.h100, props.style]}>
<View style={[styles.w100, styles.h100, style]}>
<Image
style={[styles.w100, styles.h100]}
source={{uri: props.url}}
isAuthTokenRequired={props.isAuthTokenRequired}
resizeMode={Image.resizeMode.cover}
source={{uri: url}}
isAuthTokenRequired={isAuthTokenRequired}
resizeMode={RESIZE_MODES.cover}
onLoadStart={() => {
if (isLoadedRef.current || isLoading) {
if (isLoadedRef.current ?? isLoading) {
return;
}
setIsLoading(true);
Expand All @@ -94,7 +85,5 @@ function ImageWithSizeCalculation(props) {
);
}

ImageWithSizeCalculation.propTypes = propTypes;
ImageWithSizeCalculation.defaultProps = defaultProps;
ImageWithSizeCalculation.displayName = 'ImageWithSizeCalculation';
export default React.memo(ImageWithSizeCalculation);
Loading