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 all 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
1 change: 1 addition & 0 deletions src/components/Image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ const ImageWithOnyx = React.memo(
imagePropsAreEqual,
);
ImageWithOnyx.resizeMode = RESIZE_MODES;

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 default ImageWithOnyx;
Original file line number Diff line number Diff line change
@@ -1,66 +1,58 @@
import PropTypes from 'prop-types';
import delay from 'lodash/delay';
import React, {useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import {StyleProp, View, ViewStyle} from 'react-native';
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 RESIZE_MODES from './Image/resizeModes';

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 +62,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 +86,5 @@ function ImageWithSizeCalculation(props) {
);
}

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